Hi,

PEM didn't make JDK 23 as there were further comments about the API. It hasn't been updated because of that. Hopefully in June I will be updating the github repo.

Tony

On 5/18/24 3:55 AM, Karl Scheibelhofer wrote:
Hi Tony,

today, I had a look at the recent sources of the PEM API implementation - i.e. https://github.com/ascarpino/jdk/commits/pem <https://urldefense.com/v3/__https://github.com/ascarpino/jdk/commits/pem__;!!ACWV5N9M2RV99hQ!KryKT5MjRlHpyEwcDJR5vP5ST53pFGfYJ80ocGPInq5HkglLO0076V7QKD8hckW5TqF_ZNc1b1mNq6Si7vCKEwRx8XUKiQCF$>

It seems that the PEM API Tests are out of sync. They fail with

JT Harness : Tests that failed
java/security/PEM/PEMDecoderTest.java: Testing PEM decodings
java/security/PEM/PEMEncoderTest.java: Testing PEM decoding

I wanted to update the PEM keystore implementation to the latest code base. Can you tell about the planned next steps?

Regards, Karl

On Sat, Mar 16, 2024 at 10:36 AM Karl Scheibelhofer <karl.scheibelhofer...@gmail.com <mailto:karl.scheibelhofer...@gmail.com>> wrote:

    Hi Tony,

    find my replies inline...

    On Mon, Mar 11, 2024 at 6:13 AM Anthony Scarpino
    <anthony.scarp...@oracle.com <mailto:anthony.scarp...@oracle.com>>
    wrote:
     >
     >
     >
     > On Mar 9, 2024, at 8:09 AM, Karl Scheibelhofer
    <karl.scheibelhofer...@gmail.com
    <mailto:karl.scheibelhofer...@gmail.com>> wrote:
     >
     > 
     > ... try again from from my subscribed mail account...
     >
     >> Hi Tony,
     >>
     >> in my jdk fork, I created a branch named pem-feedback-karl.
     >>
     >> https://github.com/KarlScheibelhofer/jdk/tree/pem-feedback-karl
    
<https://urldefense.com/v3/__https://github.com/KarlScheibelhofer/jdk/tree/pem-feedback-karl__;!!ACWV5N9M2RV99hQ!KryKT5MjRlHpyEwcDJR5vP5ST53pFGfYJ80ocGPInq5HkglLO0076V7QKD8hckW5TqF_ZNc1b1mNq6Si7vCKEwRx8QAJkEvq$>
     >>
     >> It is based on the pem branch of your jdk fork.
     >> In this pem-feedback-karl branch, I did some cleanup without
    changing
     >> the API. Your tests pass as before.
     >>
     >> My original pem-keystore implementation for the SUN provider is
    in this branch
     >>
     >> https://github.com/KarlScheibelhofer/jdk/tree/pem-keystore
    
<https://urldefense.com/v3/__https://github.com/KarlScheibelhofer/jdk/tree/pem-keystore__;!!ACWV5N9M2RV99hQ!KryKT5MjRlHpyEwcDJR5vP5ST53pFGfYJ80ocGPInq5HkglLO0076V7QKD8hckW5TqF_ZNc1b1mNq6Si7vCKEwRx8evoXyho$>
     >>
     >> It did not use the PEM API.
     >>
     >> In the branch
     >>
     >>
    https://github.com/KarlScheibelhofer/jdk/tree/pem-keystore-pem-api
    
<https://urldefense.com/v3/__https://github.com/KarlScheibelhofer/jdk/tree/pem-keystore-pem-api__;!!ACWV5N9M2RV99hQ!KryKT5MjRlHpyEwcDJR5vP5ST53pFGfYJ80ocGPInq5HkglLO0076V7QKD8hckW5TqF_ZNc1b1mNq6Si7vCKEwRx8ZydhYWH$>
     >>
     >> I modified the PEM keystore implementation to use the PEMDecoder
    and PEMEncoder.
     >> To make it pass all tests, I had to fix some issues with the PEM
    api:
     >>
     >> * fix missing line-breaks when encoding certificates (and CRLs)
     >> * use uniform line length for PEM encoding keys and certificates
     >
     >
     > It sounds like I did my repo update to use MimeEncoder after you
    had pulled the changes.

    In which repo can i see the version using MimeEncoder that you
    mentioned? i can't find this in
    https://github.com/ascarpino/jdk/commits/pem
    
<https://urldefense.com/v3/__https://github.com/ascarpino/jdk/commits/pem__;!!ACWV5N9M2RV99hQ!KryKT5MjRlHpyEwcDJR5vP5ST53pFGfYJ80ocGPInq5HkglLO0076V7QKD8hckW5TqF_ZNc1b1mNq6Si7vCKEwRx8XUKiQCF$>

     >
     >> During this work, I took some notes regarding the PEM api:
     >>
     >> * Consider decoupling the raw PEM encoding and decoding from
    SecurityObject.
     >>   This would make the API usable for general purpose PEM
    encoding and
     >> decoding, not just for keys and certificates, as it is now.
     >
     >
     > There has been discussions about adding a generic PEM object that
    would have methods to return the header, footer, and PEM text,
    instead of processing into a class or KeySpec. Is there something
    more “general purpose” you had it mind?

    In addition to header, footer and PEM text, for my keystore
    implementation, I would need the preceding PEM explanatory text lines,
    i.e. the lines before the header line

     >
     >> * For this PEM keystore implementation it is essential to parse the
     >> preceding explanatory text lines.
     >>   The PEM decoder should support this.
     >>   As it is now, the keystore implementation must parse the PEM
    objects
     >> itself, including reading PEM header and footer lines.
     >>   Having to handle half the work in the application diminishes the
     >> value of the PEMDecoder.
     >>   It only delegates the decoding of certificates and keys to the
    PEMDecoder.
     >>
     >> * PEMDecoder should be able to handle or pass through unknown PEM
     >> objects gracefully.
     >>   Otherwise the application has to check the PEM labels in advance
     >> itself, which does not make sense.
     >
     >
     > So do you not have a structured data file?  I expected the
    application would parse its own metadata, then when the structured
    code got to a PEM tag, it would pass the InputStream to PEMDecoder.
     >
     > I am concerned about a generic PEM object storing an unknown
    amount of application metadata and returning it back.  I feel
    handling non-PEM should be in the scope of the encoder/decoder.


    No, there is no structured data file. Just a PEM file which contains
    multiple PEM objects, typically certificates and private keys. It is
    common practice to have related certificates and keys in a single
    file. The explanatory text lines contain the name of the key, because
    this is the place specified in PEM RFC to hold meta information like
    this. To enable implementing a consistent Java Keystore with PEM
    format, I see this necessary. At least, I found no other way for
    handling key alias names as required  by Java Keystore. If you know
    another way, please let me know.

    The files that my keystore implementation reads and writes are just
    completely PEM format, from first to last line.

     >
     >>
     >> * Though supporting InputStream/OutputStream for reading and writing
     >> makes sense,
     >>   supporting Reader/Writer feels even more essential for robust
     >> support for all character encodings.
     >>   Multi-Byte character encodings won't work with
    InputStream/OutputStream.
     >
     >
     > A Reader will read ahead, buffering the input data.  I saw this
    when I had `decode(Reader)` in the API.  It would return the first
    PEM object, but the read pointer was at the end of the file, missing
    the remaining PEM objects.

    An application or a Keystore implementation gets a stream providing
    multiple concatenated PEM objects that are in this keystore object. It
    needs to get all the PEM objects handing in that stream, i.e. in
    essence hand in the input stream and get out a list of pem objects
    containing certificates, keys and their names.

     >
     > Is the multi-byte characters for the keystore metadata?  I don’t
    see how this affects Base64.

    Try feeding in a UTF-16 encoded PEM file. I guess it won't work with
    InputStream. Because the current implementation expects one character
    in each byte.

     >
     >>
     >> * The standard line separator for PEM is "\r\n".
     >>   For PEM files stored in a typical linux file system, "\n" is
     >> typically used, however.
     >>   See the output of openssl, for example.
     >>   Because there are still several command line utilities that do not
     >> work well with "\r\n" line breaks.
     >>   Supporting a different line-separator than "\r\n" is a good
    idea in
     >> my opinion.
     >>   Base64.getMimeEncoder also supports selecting a custom line
    separator.
     >
     >
     > The standards I saw says the line separator is “\r\n”.  I realize
    decoders have to be more flexible because many may not follow the
    line separators or cut-n-paste removes them.  I think having a
    configurable line separator for encoding is likely to create more
    incompatibility rather than lessen for cross-platform and using with
    other applications.

    Yes, the PEM standard say"\r\n". But widely used tools like openssl
    produce "\n". In practice, this is just the better solution. It goes
    better with most other tools and version control.
    I would opt for "\r\n" by default, but provide an option for "\n" only.
    There must be a reason why Base64.getMimeEncoder supports custom line
    separators.

     >
     >>
     >> * The PEMEncoder encodes the predefined SecurityObjects only.
     >>   There is no way to use it to PEM encoded any other type of object.
     >>   Consider opening a path to generic use.
     >
     >
     > The generic PEM object I mentioned previously I think fits this
    case.  It would still be a SecurityObject as I don’t see value in
    passing in any object.

    I will have a look at it. Can you provide a link to your implementation?

     >
     >>
     >> * If an application has a DER encoded certificate, it has to decode
     >> and parse the certificate before
     >>   it can encode it using PEMEncoder.
     >>   This is inconvenient.
     >
     >
     > Yeah, there isn’t an EncodedKeySpec equivalent.  I’d have to
    think if there is an easy way to do this without causing more
    problems.  Given the purpose is going between Java Objects and PEM,
    accepting random data isn’t a goal.  Maybe something that can be
    addressed with a generic PEM object.

    As a fallback simply allow passing in a byte[] that is base64 encoded,
    i.e. the result of Certificate.getEncoded().

    Thank you!

    Karl

    ...

Reply via email to