Skip to content

Commit

Permalink
Merge branch '3.0.x' into 3.1.x
Browse files Browse the repository at this point in the history
Closes gh-37422
  • Loading branch information
mhalbritter committed Sep 15, 2023
2 parents d653515 + 5be826d commit ed4b6aa
Show file tree
Hide file tree
Showing 50 changed files with 532 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
Expand All @@ -47,26 +47,28 @@
*/
final class PrivateKeyParser {

private static final String PKCS1_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";
private static final String PKCS1_RSA_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

private static final String PKCS1_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String PKCS1_RSA_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String PKCS8_HEADER = "-+BEGIN\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

private static final String PKCS8_FOOTER = "-+END\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String EC_HEADER = "-+BEGIN\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";
private static final String SEC1_EC_HEADER = "-+BEGIN\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

private static final String EC_FOOTER = "-+END\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String SEC1_EC_FOOTER = "-+END\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)";

private static final List<PemParser> PEM_PARSERS;
static {
List<PemParser> parsers = new ArrayList<>();
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PrivateKeyParser::createKeySpecForPkcs1, "RSA"));
parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PrivateKeyParser::createKeySpecForEc, "EC"));
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "EC", "DSA", "Ed25519"));
parsers
.add(new PemParser(PKCS1_RSA_HEADER, PKCS1_RSA_FOOTER, PrivateKeyParser::createKeySpecForPkcs1Rsa, "RSA"));
parsers.add(new PemParser(SEC1_EC_HEADER, SEC1_EC_FOOTER, PrivateKeyParser::createKeySpecForSec1Ec, "EC"));
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "RSASSA-PSS", "EC",
"DSA", "EdDSA", "XDH"));
PEM_PARSERS = Collections.unmodifiableList(parsers);
}

Expand All @@ -88,11 +90,11 @@ final class PrivateKeyParser {
private PrivateKeyParser() {
}

private static PKCS8EncodedKeySpec createKeySpecForPkcs1(byte[] bytes) {
private static PKCS8EncodedKeySpec createKeySpecForPkcs1Rsa(byte[] bytes) {
return createKeySpecForAlgorithm(bytes, RSA_ALGORITHM, null);
}

private static PKCS8EncodedKeySpec createKeySpecForEc(byte[] bytes) {
private static PKCS8EncodedKeySpec createKeySpecForSec1Ec(byte[] bytes) {
DerElement ecPrivateKey = DerElement.of(bytes);
Assert.state(ecPrivateKey.isType(ValueType.ENCODED, TagType.SEQUENCE),
"Key spec should be an ASN.1 encoded sequence");
Expand Down Expand Up @@ -194,21 +196,16 @@ private static byte[] decodeBase64(String content) {
}

private PrivateKey parse(byte[] bytes) {
try {
PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes);
for (String algorithm : this.algorithms) {
PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes);
for (String algorithm : this.algorithms) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
try {
return keyFactory.generatePrivate(keySpec);
}
catch (InvalidKeySpecException ex) {
}
return keyFactory.generatePrivate(keySpec);
}
catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
}
return null;
}
catch (GeneralSecurityException ex) {
throw new IllegalArgumentException("Unexpected key format", ex);
}
return null;
}

}
Expand Down Expand Up @@ -296,7 +293,7 @@ static final class DerElement {

private final long tagType;

private ByteBuffer contents;
private final ByteBuffer contents;

private DerElement(ByteBuffer bytes) {
byte b = bytes.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
Expand Down Expand Up @@ -52,9 +53,9 @@
*/
final class PemPrivateKeyParser {

private static final String PKCS1_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";
private static final String PKCS1_RSA_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

private static final String PKCS1_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String PKCS1_RSA_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String PKCS8_HEADER = "-+BEGIN\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

Expand All @@ -64,9 +65,9 @@ final class PemPrivateKeyParser {

private static final String PKCS8_ENCRYPTED_FOOTER = "-+END\\s+ENCRYPTED\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String EC_HEADER = "-+BEGIN\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";
private static final String SEC1_EC_HEADER = "-+BEGIN\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";

private static final String EC_FOOTER = "-+END\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String SEC1_EC_FOOTER = "-+END\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+";

private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)";

Expand All @@ -75,12 +76,13 @@ final class PemPrivateKeyParser {
private static final List<PemParser> PEM_PARSERS;
static {
List<PemParser> parsers = new ArrayList<>();
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PemPrivateKeyParser::createKeySpecForPkcs1, "RSA"));
parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PemPrivateKeyParser::createKeySpecForEc, "EC"));
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PemPrivateKeyParser::createKeySpecForPkcs8, "RSA", "EC",
"DSA", "Ed25519"));
parsers.add(new PemParser(PKCS1_RSA_HEADER, PKCS1_RSA_FOOTER, PemPrivateKeyParser::createKeySpecForPkcs1Rsa,
"RSA"));
parsers.add(new PemParser(SEC1_EC_HEADER, SEC1_EC_FOOTER, PemPrivateKeyParser::createKeySpecForSec1Ec, "EC"));
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PemPrivateKeyParser::createKeySpecForPkcs8, "RSA",
"RSASSA-PSS", "EC", "DSA", "EdDSA", "XDH"));
parsers.add(new PemParser(PKCS8_ENCRYPTED_HEADER, PKCS8_ENCRYPTED_FOOTER,
PemPrivateKeyParser::createKeySpecForPkcs8Encrypted, "RSA", "EC", "DSA", "Ed25519"));
PemPrivateKeyParser::createKeySpecForPkcs8Encrypted, "RSA", "RSASSA-PSS", "EC", "DSA", "EdDSA", "XDH"));
PEM_PARSERS = Collections.unmodifiableList(parsers);
}

Expand All @@ -102,11 +104,11 @@ final class PemPrivateKeyParser {
private PemPrivateKeyParser() {
}

private static PKCS8EncodedKeySpec createKeySpecForPkcs1(byte[] bytes, String password) {
private static PKCS8EncodedKeySpec createKeySpecForPkcs1Rsa(byte[] bytes, String password) {
return createKeySpecForAlgorithm(bytes, RSA_ALGORITHM, null);
}

private static PKCS8EncodedKeySpec createKeySpecForEc(byte[] bytes, String password) {
private static PKCS8EncodedKeySpec createKeySpecForSec1Ec(byte[] bytes, String password) {
DerElement ecPrivateKey = DerElement.of(bytes);
Assert.state(ecPrivateKey.isType(ValueType.ENCODED, TagType.SEQUENCE),
"Key spec should be an ASN.1 encoded sequence");
Expand Down Expand Up @@ -228,21 +230,16 @@ private static byte[] decodeBase64(String content) {
}

private PrivateKey parse(byte[] bytes, String password) {
try {
PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes, password);
for (String algorithm : this.algorithms) {
PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes, password);
for (String algorithm : this.algorithms) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
try {
return keyFactory.generatePrivate(keySpec);
}
catch (InvalidKeySpecException ex) {
}
return keyFactory.generatePrivate(keySpec);
}
catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
}
return null;
}
catch (GeneralSecurityException ex) {
throw new IllegalArgumentException("Unexpected key format", ex);
}
return null;
}

}
Expand Down Expand Up @@ -330,7 +327,7 @@ static final class DerElement {

private final long tagType;

private ByteBuffer contents;
private final ByteBuffer contents;

private DerElement(ByteBuffer bytes) {
byte b = bytes.get();
Expand Down
Loading

0 comments on commit ed4b6aa

Please sign in to comment.