Revert "Allow PemPrivateKeyParser to parse multiple keys"

This reverts commit 32e6ce210e.

Closes gh-37999
This commit is contained in:
Phillip Webb
2023-10-23 18:32:12 -07:00
parent a9469d9c8e
commit 2ac69160c7
4 changed files with 35 additions and 35 deletions

View File

@@ -52,11 +52,7 @@ final class PemContent {
return PemCertificateParser.parse(this.text);
}
List<PrivateKey> getPrivateKeys() {
return PemPrivateKeyParser.parse(this.text);
}
List<PrivateKey> getPrivateKeys(String password) {
PrivateKey getPrivateKeys(String password) {
return PemPrivateKeyParser.parse(this.text, password);
}

View File

@@ -69,10 +69,6 @@ final class PemPrivateKeyParser {
private static final String SEC1_EC_FOOTER = "-+END\\s+EC\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String PKCS1_DSA_HEADER = "-+BEGIN\\s+DSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+";
private static final String PKCS1_DSA_FOOTER = "-+END\\s+DSA\\s+PRIVATE\\s+KEY[^-]*-+";
private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)";
public static final int BASE64_TEXT_GROUP = 1;
@@ -87,9 +83,6 @@ final class PemPrivateKeyParser {
"RSASSA-PSS", "EC", "DSA", "EdDSA", "XDH"));
parsers.add(new PemParser(PKCS8_ENCRYPTED_HEADER, PKCS8_ENCRYPTED_FOOTER,
PemPrivateKeyParser::createKeySpecForPkcs8Encrypted, "RSA", "RSASSA-PSS", "EC", "DSA", "EdDSA", "XDH"));
parsers.add(new PemParser(PKCS1_DSA_HEADER, PKCS1_DSA_FOOTER, (bytes, password) -> {
throw new IllegalStateException("Unsupported private key format");
}));
PEM_PARSERS = Collections.unmodifiableList(parsers);
}
@@ -179,7 +172,7 @@ final class PemPrivateKeyParser {
* @param text the text to parse
* @return the parsed private key
*/
static List<PrivateKey> parse(String text) {
static PrivateKey parse(String text) {
return parse(text, null);
}
@@ -190,23 +183,22 @@ final class PemPrivateKeyParser {
* @param password the password used to decrypt an encrypted private key
* @return the parsed private key
*/
static List<PrivateKey> parse(String text, String password) {
static PrivateKey parse(String text, String password) {
if (text == null) {
return null;
}
List<PrivateKey> keys = new ArrayList<>();
try {
for (PemParser pemParser : PEM_PARSERS) {
PrivateKey privateKey = pemParser.parse(text, password);
if (privateKey != null) {
keys.add(privateKey);
return privateKey;
}
}
throw new IllegalStateException("Unrecognized private key format");
}
catch (Exception ex) {
throw new IllegalStateException("Error loading private key file: " + ex.getMessage(), ex);
}
return List.copyOf(keys);
}
/**
@@ -247,7 +239,7 @@ final class PemPrivateKeyParser {
catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
}
}
throw new IllegalStateException("Unrecognized private key format");
return null;
}
}

View File

@@ -155,9 +155,7 @@ public class PemSslStoreBundle implements SslStoreBundle {
if (pemContent == null) {
return null;
}
List<PrivateKey> privateKeys = pemContent.getPrivateKeys(details.privateKeyPassword());
Assert.state(!CollectionUtils.isEmpty(privateKeys), "Loaded private keys are empty");
return privateKeys.get(0);
return pemContent.getPrivateKeys(details.privateKeyPassword());
}
private static X509Certificate[] loadCertificates(PemSslStoreDetails details) {

View File

@@ -28,7 +28,6 @@ import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ObjectUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@@ -51,7 +50,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseTraditionalPkcs8(String file, String algorithm) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/pkcs8/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs8/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo(algorithm);
@@ -64,7 +63,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseTraditionalPkcs1(String file, String algorithm) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/pkcs1/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs1/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo(algorithm);
@@ -78,11 +77,11 @@ class PemPrivateKeyParserTests {
// @formatter:on
void shouldNotParseUnsupportedTraditionalPkcs1(String file) {
assertThatIllegalStateException()
.isThrownBy(() -> parse(read("org/springframework/boot/web/server/pkcs1/" + file)))
.isThrownBy(() -> PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs1/" + file)))
.withMessageContaining("Error loading private key file")
.withCauseInstanceOf(IllegalStateException.class)
.havingCause()
.withMessageContaining("Unsupported private key format");
.withMessageContaining("Unrecognized private key format");
}
@ParameterizedTest
@@ -101,7 +100,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseEcPkcs8(String file, String curveName, String oid) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/pkcs8/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs8/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo("EC");
@@ -136,7 +135,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseEdDsaPkcs8(String file) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/pkcs8/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs8/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo("EdDSA");
@@ -150,7 +149,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseXdhPkcs8(String file) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/pkcs8/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs8/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo("XDH");
@@ -172,7 +171,7 @@ class PemPrivateKeyParserTests {
})
// @formatter:on
void shouldParseEcSec1(String file, String curveName, String oid) throws IOException {
PrivateKey privateKey = parse(read("org/springframework/boot/web/server/sec1/" + file));
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/sec1/" + file));
assertThat(privateKey).isNotNull();
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo("EC");
@@ -200,8 +199,8 @@ class PemPrivateKeyParserTests {
}
@Test
void parseWithNonKeyTextWillReturnEmptyArray() throws Exception {
assertThat(PemPrivateKeyParser.parse(read("test-banner.txt"))).isEmpty();
void parseWithNonKeyTextWillThrowException() {
assertThatIllegalStateException().isThrownBy(() -> PemPrivateKeyParser.parse(read("test-banner.txt")));
}
@ParameterizedTest
@@ -219,10 +218,16 @@ class PemPrivateKeyParserTests {
// openssl pkcs8 -topk8 -in <input file> -out <output file> -v2 <algorithm>
// -passout pass:test
// where <algorithm> is aes128 or aes256
<<<<<<< HEAD
String content = read("org/springframework/boot/web/server/pkcs8/" + file);
List<PrivateKey> privateKeys = PemPrivateKeyParser.parse(content, "test");
assertThat(privateKeys).isNotEmpty();
PrivateKey privateKey = privateKeys.get(0);
=======
PrivateKey privateKey = PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs8/" + file),
"test");
assertThat(privateKey).isNotNull();
>>>>>>> parent of 32e6ce210e1 (Allow PemPrivateKeyParser to parse multiple keys)
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
assertThat(privateKey.getAlgorithm()).isEqualTo(algorithm);
}
@@ -251,18 +256,21 @@ class PemPrivateKeyParserTests {
}
@Test
void shouldNotParseEncryptedSec1() throws Exception {
void shouldNotParseEncryptedSec1() {
// created with:
// openssl ecparam -genkey -name prime256v1 | openssl ec -aes-128-cbc -out
// prime256v1-aes-128-cbc.key
assertThat(PemPrivateKeyParser
.parse(read("org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key"), "test")).isEmpty();
assertThatIllegalStateException()
.isThrownBy(() -> PemPrivateKeyParser
.parse(read("org/springframework/boot/web/server/sec1/prime256v1-aes-128-cbc.key"), "test"))
.withMessageContaining("Unrecognized private key format");
}
@Test
void shouldNotParseEncryptedPkcs1() throws Exception {
// created with:
// openssl genrsa -aes-256-cbc -out rsa-aes-256-cbc.key
<<<<<<< HEAD
assertThat(PemPrivateKeyParser.parse(read("org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key"),
"test"))
.isEmpty();
@@ -271,6 +279,12 @@ class PemPrivateKeyParserTests {
private PrivateKey parse(String key) {
List<PrivateKey> keys = PemPrivateKeyParser.parse(key);
return (!ObjectUtils.isEmpty(keys)) ? keys.get(0) : null;
=======
assertThatIllegalStateException()
.isThrownBy(() -> PemPrivateKeyParser
.parse(read("org/springframework/boot/web/server/pkcs1/rsa-aes-256-cbc.key"), "test"))
.withMessageContaining("Unrecognized private key format");
>>>>>>> parent of 32e6ce210e1 (Allow PemPrivateKeyParser to parse multiple keys)
}
private String read(String path) throws IOException {