[External] : Re: PEM API github repo
Anthony Scarpino
anthony.scarpino at oracle.com
Tue May 28 16:48:33 UTC 2024
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.75 at gmail.com
> <mailto:karl.scheibelhofer.75 at gmail.com>> wrote:
>
> Hi Tony,
>
> find my replies inline...
>
> On Mon, Mar 11, 2024 at 6:13 AM Anthony Scarpino
> <anthony.scarpino at oracle.com <mailto:anthony.scarpino at oracle.com>>
> wrote:
> >
> >
> >
> > On Mar 9, 2024, at 8:09 AM, Karl Scheibelhofer
> <karl.scheibelhofer.75 at gmail.com
> <mailto:karl.scheibelhofer.75 at 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
>
> ...
>
More information about the security-dev
mailing list