-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8360564: Implement JEP 524: PEM Encodings of Cryptographic Objects (Second Preview) #27147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
4ecddcb
Rename PEMRecord to PEM
ascarpino 9603f75
Merge branch 'master' into pem26
ascarpino cdda7f1
Initial
ascarpino 0e3d6bd
Merge branch 'master' into pem26
ascarpino fd56e8e
doc and code updates
ascarpino 73c3963
Merge branch 'master' into pem26
ascarpino b3e0200
doc and code updates
ascarpino 7ffe6ad
simplify
ascarpino c493fa0
fix test
ascarpino b2d0def
rework test & commented out code.
ascarpino b425fb9
Merge branch 'master' into pem26
ascarpino 24be35c
review comments and bug fixes
ascarpino e13bff4
missed some decoder comments
ascarpino dadce4b
update preview
ascarpino db913c3
major doc update, change to encrypt()
ascarpino 3e183c5
updates
ascarpino 27d4fe4
doc updates, zeroing, fix unencrypted keypair encoding, exception mods
ascarpino 2e9332b
fix non-pbe
ascarpino 45f30dd
more doc updates and zeroing
ascarpino 682bfa1
docs
ascarpino e08d062
EKPI has a lot of @link's
ascarpino 4bf48dd
more docs, remove runtimeexception
ascarpino e1405c0
minor doc updates, fix some bugs, PEM set to 26
ascarpino 563363f
Merge branch 'master' into pem26
ascarpino 0d95043
mistakes
ascarpino 5cba4d9
remove PEMRecord import
ascarpino 2ee3e7a
Merge branch 'master' into pem26
ascarpino File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ascarpino marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| /* | ||
| * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. | ||
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| * | ||
| * This code is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU General Public License version 2 only, as | ||
| * published by the Free Software Foundation. Oracle designates this | ||
| * particular file as subject to the "Classpath" exception as provided | ||
| * by Oracle in the LICENSE file that accompanied this code. | ||
| * | ||
| * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| * version 2 for more details (a copy is included in the LICENSE file that | ||
| * accompanied this code). | ||
| * | ||
| * You should have received a copy of the GNU General Public License version | ||
| * 2 along with this work; if not, write to the Free Software Foundation, | ||
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| * | ||
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| * or visit www.oracle.com if you need additional information or have any | ||
| * questions. | ||
| */ | ||
|
|
||
| package java.security; | ||
|
|
||
| import jdk.internal.javac.PreviewFeature; | ||
|
|
||
| import sun.security.util.Pem; | ||
|
|
||
| import java.io.InputStream; | ||
| import java.util.Base64; | ||
| import java.util.Objects; | ||
|
|
||
| /** | ||
| * {@code PEM} is a {@link DEREncodable} that represents Privacy-Enhanced | ||
| * Mail (PEM) data by its type and Base64-encoded content. | ||
| * | ||
| * <p> The {@link PEMDecoder#decode(String)} and | ||
| * {@link PEMDecoder#decode(InputStream)} methods return a {@code PEM} object | ||
| * when the data type cannot be represented by a cryptographic object. | ||
| * If you need access to the leading data of a PEM text, or want to | ||
| * handle the text content directly, use the decoding methods | ||
| * {@link PEMDecoder#decode(String, Class)} or | ||
| * {@link PEMDecoder#decode(InputStream, Class)} with {@code PEM.class} as an | ||
| * argument type. | ||
| * | ||
| * <p> A {@code PEM} object can be encoded back to its textual format by calling | ||
| * {@link #toString()} or by using the encode methods in {@link PEMEncoder}. | ||
| * | ||
| * <p> When constructing a {@code PEM} instance, both {@code type} and | ||
| * {@code content} must not be {@code null}. | ||
| * | ||
| * <p>No validation is performed during instantiation to ensure that | ||
| * {@code type} conforms to RFC 7468 or other legacy formats, that | ||
| * {@code content} is valid Base64 data, or that {@code content} matches the | ||
| * {@code type}. | ||
| * <p> Common {@code type} values include, but are not limited to: | ||
| * CERTIFICATE, CERTIFICATE REQUEST, ATTRIBUTE CERTIFICATE, X509 CRL, PKCS7, | ||
| * CMS, PRIVATE KEY, ENCRYPTED PRIVATE KEY, and PUBLIC KEY. | ||
| * | ||
| * <p> {@code leadingData} is {@code null} if there is no data preceding the PEM | ||
| * header during decoding. {@code leadingData} can be useful for reading | ||
| * metadata that accompanies the PEM data. Because the value may represent a large | ||
| * amount of data, it is not defensively copied by the constructor, and the | ||
| * {@link #leadingData()} method does not return a clone. Modification of the | ||
| * passed-in or returned array changes the value stored in this record. | ||
| * | ||
| * @param type the type identifier from the PEM header, without PEM syntax | ||
| * labels; for example, for a public key, {@code type} would be | ||
| * "PUBLIC KEY" | ||
| * @param content the Base64-encoded data, excluding the PEM header and footer | ||
| * @param leadingData any non-PEM data that precedes the PEM header during | ||
| * decoding. This value may be {@code null}. | ||
| * | ||
| * @spec https://www.rfc-editor.org/info/rfc7468 | ||
| * RFC 7468: Textual Encodings of PKIX, PKCS, and CMS Structures | ||
| * | ||
| * @see PEMDecoder | ||
| * @see PEMEncoder | ||
| * | ||
| * @since 26 | ||
| */ | ||
| @PreviewFeature(feature = PreviewFeature.Feature.PEM_API) | ||
| public record PEM(String type, String content, byte[] leadingData) | ||
| implements DEREncodable { | ||
|
|
||
| /** | ||
| * Creates a {@code PEM} instance with the specified parameters. | ||
| * | ||
| * @param type the PEM type identifier | ||
| * @param content the Base64-encoded data, excluding the PEM header and footer | ||
| * @param leadingData any non-PEM data read during the decoding process | ||
| * before the PEM header. This value may be {@code null}. | ||
| * @throws IllegalArgumentException if {@code type} is incorrectly formatted | ||
| * @throws NullPointerException if {@code type} or {@code content} is {@code null} | ||
| */ | ||
| public PEM { | ||
| Objects.requireNonNull(type, "\"type\" cannot be null."); | ||
| Objects.requireNonNull(content, "\"content\" cannot be null."); | ||
|
|
||
| // With no validity checking on `type`, the constructor accept anything | ||
| // including lowercase. The onus is on the caller. | ||
| if (type.startsWith("-") || type.startsWith("BEGIN ") || | ||
| type.startsWith("END ")) { | ||
| throw new IllegalArgumentException("PEM syntax labels found. " + | ||
| "Only the PEM type identifier is allowed."); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Creates a {@code PEM} instance with the specified type and content. This | ||
| * constructor sets {@code leadingData} to {@code null}. | ||
| * | ||
| * @param type the PEM type identifier | ||
ascarpino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * @param content the Base64-encoded data, excluding the PEM header and footer | ||
| * @throws IllegalArgumentException if {@code type} is incorrectly formatted | ||
| * @throws NullPointerException if {@code type} or {@code content} is {@code null} | ||
| */ | ||
| public PEM(String type, String content) { | ||
| this(type, content, null); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the PEM formatted string containing the {@code type} and | ||
| * Base64-encoded {@code content}. {@code leadingData} is not included. | ||
| * | ||
| * @return the PEM text representation | ||
| */ | ||
| @Override | ||
| final public String toString() { | ||
| return Pem.pemEncoded(this); | ||
| } | ||
|
|
||
| /** | ||
| * Returns a Base64-decoded byte array of {@code content}, using | ||
| * {@link Base64#getMimeDecoder()}. | ||
| * | ||
| * @return a decoded byte array | ||
| * @throws IllegalArgumentException if decoding fails | ||
| */ | ||
| final public byte[] decode() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method doesn't seem to be covered by the tests. I have created a ticket to add this https://bugs.openjdk.org/browse/JDK-8371574. |
||
| return Base64.getMimeDecoder().decode(content); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.