Merge branch '3.1.x'

Closes gh-37335
This commit is contained in:
Moritz Halbritter 2023-09-11 16:50:44 +02:00
commit 8a1f6d4f32
13 changed files with 187 additions and 91 deletions

View File

@ -16,6 +16,9 @@
package org.springframework.boot.autoconfigure.ssl;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Set;
import org.junit.jupiter.api.Test;
@ -28,36 +31,42 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link PropertiesSslBundle}.
*
* @author Scott Frederick
* @author Moritz Halbritter
*/
class PropertiesSslBundleTests {
@Test
void pemPropertiesAreMappedToSslBundle() {
void pemPropertiesAreMappedToSslBundle() throws Exception {
PemSslBundleProperties properties = new PemSslBundleProperties();
properties.getKey().setAlias("alias");
properties.getKey().setPassword("secret");
properties.getOptions().setCiphers(Set.of("cipher1", "cipher2", "cipher3"));
properties.getOptions().setEnabledProtocols(Set.of("protocol1", "protocol2"));
properties.getKeystore().setCertificate("cert1.pem");
properties.getKeystore().setPrivateKey("key1.pem");
properties.getKeystore().setPrivateKeyPassword("keysecret1");
properties.getKeystore().setCertificate("classpath:org/springframework/boot/autoconfigure/ssl/rsa-cert.pem");
properties.getKeystore().setPrivateKey("classpath:org/springframework/boot/autoconfigure/ssl/rsa-key.pem");
properties.getKeystore().setPrivateKeyPassword(null);
properties.getKeystore().setType("PKCS12");
properties.getTruststore().setCertificate("cert2.pem");
properties.getTruststore().setPrivateKey("key2.pem");
properties.getTruststore().setPrivateKeyPassword("keysecret2");
properties.getTruststore().setType("JKS");
properties.getTruststore()
.setCertificate("classpath:org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem");
properties.getTruststore()
.setPrivateKey("classpath:org/springframework/boot/autoconfigure/ssl/ed25519-key.pem");
properties.getTruststore().setPrivateKeyPassword("secret");
properties.getTruststore().setType("PKCS12");
SslBundle sslBundle = PropertiesSslBundle.get(properties);
assertThat(sslBundle.getKey().getAlias()).isEqualTo("alias");
assertThat(sslBundle.getKey().getPassword()).isEqualTo("secret");
assertThat(sslBundle.getOptions().getCiphers()).containsExactlyInAnyOrder("cipher1", "cipher2", "cipher3");
assertThat(sslBundle.getOptions().getEnabledProtocols()).containsExactlyInAnyOrder("protocol1", "protocol2");
assertThat(sslBundle.getStores()).isNotNull();
assertThat(sslBundle.getStores()).extracting("keyStoreDetails")
.extracting("certificate", "privateKey", "privateKeyPassword", "type")
.containsExactly("cert1.pem", "key1.pem", "keysecret1", "PKCS12");
assertThat(sslBundle.getStores()).extracting("trustStoreDetails")
.extracting("certificate", "privateKey", "privateKeyPassword", "type")
.containsExactly("cert2.pem", "key2.pem", "keysecret2", "JKS");
Certificate certificate = sslBundle.getStores().getKeyStore().getCertificate("alias");
assertThat(certificate).isNotNull();
assertThat(certificate.getType()).isEqualTo("X.509");
Key key = sslBundle.getStores().getKeyStore().getKey("alias", null);
assertThat(key).isNotNull();
assertThat(key.getAlgorithm()).isEqualTo("RSA");
certificate = sslBundle.getStores().getTrustStore().getCertificate("alias");
assertThat(certificate).isNotNull();
assertThat(certificate.getType()).isEqualTo("X.509");
}
@Test
@ -67,14 +76,14 @@ class PropertiesSslBundleTests {
properties.getKey().setPassword("secret");
properties.getOptions().setCiphers(Set.of("cipher1", "cipher2", "cipher3"));
properties.getOptions().setEnabledProtocols(Set.of("protocol1", "protocol2"));
properties.getKeystore().setLocation("cert1.p12");
properties.getKeystore().setPassword("secret1");
properties.getKeystore().setProvider("provider1");
properties.getKeystore().setPassword("secret");
properties.getKeystore().setProvider("SUN");
properties.getKeystore().setType("JKS");
properties.getTruststore().setLocation("cert2.jks");
properties.getTruststore().setPassword("secret2");
properties.getTruststore().setProvider("provider2");
properties.getKeystore().setLocation("classpath:org/springframework/boot/autoconfigure/ssl/keystore.jks");
properties.getTruststore().setPassword("secret");
properties.getTruststore().setProvider("SUN");
properties.getTruststore().setType("PKCS12");
properties.getTruststore().setLocation("classpath:org/springframework/boot/autoconfigure/ssl/keystore.pkcs12");
SslBundle sslBundle = PropertiesSslBundle.get(properties);
assertThat(sslBundle.getKey().getAlias()).isEqualTo("alias");
assertThat(sslBundle.getKey().getPassword()).isEqualTo("secret");
@ -83,10 +92,11 @@ class PropertiesSslBundleTests {
assertThat(sslBundle.getStores()).isNotNull();
assertThat(sslBundle.getStores()).extracting("keyStoreDetails")
.extracting("location", "password", "provider", "type")
.containsExactly("cert1.p12", "secret1", "provider1", "JKS");
assertThat(sslBundle.getStores()).extracting("trustStoreDetails")
.extracting("location", "password", "provider", "type")
.containsExactly("cert2.jks", "secret2", "provider2", "PKCS12");
.containsExactly("classpath:org/springframework/boot/autoconfigure/ssl/keystore.jks", "secret", "SUN",
"JKS");
KeyStore trustStore = sslBundle.getStores().getTrustStore();
assertThat(trustStore.getType()).isEqualTo("PKCS12");
assertThat(trustStore.getProvider().getName()).isEqualTo("SUN");
}
}

View File

@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Scott Frederick
* @author Phillip Webb
* @author Moritz Halbritter
*/
class SslAutoConfigurationTests {
@ -54,18 +55,28 @@ class SslAutoConfigurationTests {
List<String> propertyValues = new ArrayList<>();
propertyValues.add("spring.ssl.bundle.pem.first.key.alias=alias1");
propertyValues.add("spring.ssl.bundle.pem.first.key.password=secret1");
propertyValues.add("spring.ssl.bundle.pem.first.keystore.certificate=cert1.pem");
propertyValues.add("spring.ssl.bundle.pem.first.keystore.private-key=key1.pem");
propertyValues.add("spring.ssl.bundle.pem.first.keystore.type=JKS");
propertyValues.add(
"spring.ssl.bundle.pem.first.keystore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/rsa-cert.pem");
propertyValues.add(
"spring.ssl.bundle.pem.first.keystore.private-key=classpath:org/springframework/boot/autoconfigure/ssl/rsa-key.pem");
propertyValues.add("spring.ssl.bundle.pem.first.keystore.type=PKCS12");
propertyValues.add("spring.ssl.bundle.pem.first.truststore.type=PKCS12");
propertyValues.add(
"spring.ssl.bundle.pem.first.truststore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/rsa-cert.pem");
propertyValues.add(
"spring.ssl.bundle.pem.first.truststore.private-key=classpath:org/springframework/boot/autoconfigure/ssl/rsa-key.pem");
propertyValues.add("spring.ssl.bundle.pem.second.key.alias=alias2");
propertyValues.add("spring.ssl.bundle.pem.second.key.password=secret2");
propertyValues.add("spring.ssl.bundle.pem.second.keystore.certificate=cert2.pem");
propertyValues.add("spring.ssl.bundle.pem.second.keystore.private-key=key2.pem");
propertyValues.add(
"spring.ssl.bundle.pem.second.keystore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem");
propertyValues.add(
"spring.ssl.bundle.pem.second.keystore.private-key=classpath:org/springframework/boot/autoconfigure/ssl/ed25519-key.pem");
propertyValues.add("spring.ssl.bundle.pem.second.keystore.type=PKCS12");
propertyValues.add("spring.ssl.bundle.pem.second.truststore.certificate=ca.pem");
propertyValues.add("spring.ssl.bundle.pem.second.truststore.private-key=ca-key.pem");
propertyValues.add("spring.ssl.bundle.pem.second.truststore.type=JKS");
propertyValues.add(
"spring.ssl.bundle.pem.second.truststore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem");
propertyValues.add(
"spring.ssl.bundle.pem.second.truststore.private-key=classpath:org/springframework/boot/autoconfigure/ssl/ed25519-key.pem");
propertyValues.add("spring.ssl.bundle.pem.second.truststore.type=PKCS12");
this.contextRunner.withPropertyValues(propertyValues.toArray(String[]::new)).run((context) -> {
assertThat(context).hasSingleBean(SslBundles.class);
SslBundles bundles = context.getBean(SslBundles.class);
@ -75,16 +86,16 @@ class SslAutoConfigurationTests {
assertThat(first.getManagers()).isNotNull();
assertThat(first.getKey().getAlias()).isEqualTo("alias1");
assertThat(first.getKey().getPassword()).isEqualTo("secret1");
assertThat(first.getStores()).extracting("keyStoreDetails").extracting("type").isEqualTo("JKS");
assertThat(first.getStores()).extracting("trustStoreDetails").extracting("type").isEqualTo("PKCS12");
assertThat(first.getStores().getKeyStore().getType()).isEqualTo("PKCS12");
assertThat(first.getStores().getTrustStore().getType()).isEqualTo("PKCS12");
SslBundle second = bundles.getBundle("second");
assertThat(second).isNotNull();
assertThat(second.getStores()).isNotNull();
assertThat(second.getManagers()).isNotNull();
assertThat(second.getKey().getAlias()).isEqualTo("alias2");
assertThat(second.getKey().getPassword()).isEqualTo("secret2");
assertThat(second.getStores()).extracting("keyStoreDetails").extracting("type").isEqualTo("PKCS12");
assertThat(second.getStores()).extracting("trustStoreDetails").extracting("type").isEqualTo("JKS");
assertThat(second.getStores().getKeyStore().getType()).isEqualTo("PKCS12");
assertThat(second.getStores().getTrustStore().getType()).isEqualTo("PKCS12");
});
}
@ -93,7 +104,13 @@ class SslAutoConfigurationTests {
List<String> propertyValues = new ArrayList<>();
propertyValues.add("custom.ssl.key.alias=alias1");
propertyValues.add("custom.ssl.key.password=secret1");
propertyValues.add("custom.ssl.keystore.type=JKS");
propertyValues
.add("custom.ssl.keystore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/rsa-cert.pem");
propertyValues.add(
"custom.ssl.keystore.keystore.private-key=classpath:org/springframework/boot/autoconfigure/ssl/rsa-key.pem");
propertyValues
.add("custom.ssl.truststore.certificate=classpath:org/springframework/boot/autoconfigure/ssl/rsa-cert.pem");
propertyValues.add("custom.ssl.keystore.type=PKCS12");
propertyValues.add("custom.ssl.truststore.type=PKCS12");
this.contextRunner.withUserConfiguration(CustomSslBundleConfiguration.class)
.withPropertyValues(propertyValues.toArray(String[]::new))
@ -106,8 +123,8 @@ class SslAutoConfigurationTests {
assertThat(first.getManagers()).isNotNull();
assertThat(first.getKey().getAlias()).isEqualTo("alias1");
assertThat(first.getKey().getPassword()).isEqualTo("secret1");
assertThat(first.getStores()).extracting("keyStoreDetails").extracting("type").isEqualTo("JKS");
assertThat(first.getStores()).extracting("trustStoreDetails").extracting("type").isEqualTo("PKCS12");
assertThat(first.getStores().getKeyStore().getType()).isEqualTo("PKCS12");
assertThat(first.getStores().getTrustStore().getType()).isEqualTo("PKCS12");
});
}

View File

@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIICCzCCAb2gAwIBAgIUZbDi7G5czH+Yi0k2EMWxdf00XagwBQYDK2VwMHsxCzAJ
BgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1l
MRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25O
YW1lMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjMwOTExMTIxNDMwWhcNMzMwOTA4
MTIxNDMwWjB7MQswCQYDVQQGEwJYWDESMBAGA1UECAwJU3RhdGVOYW1lMREwDwYD
VQQHDAhDaXR5TmFtZTEUMBIGA1UECgwLQ29tcGFueU5hbWUxGzAZBgNVBAsMEkNv
bXBhbnlTZWN0aW9uTmFtZTESMBAGA1UEAwwJbG9jYWxob3N0MCowBQYDK2VwAyEA
Q/DDA4BSgZ+Hx0DUxtIRjVjN+OcxXVURwAWc3Gt9GUyjUzBRMB0GA1UdDgQWBBSv
EdpoaBMBoxgO96GFbf03k07DSTAfBgNVHSMEGDAWgBSvEdpoaBMBoxgO96GFbf03
k07DSTAPBgNVHRMBAf8EBTADAQH/MAUGAytlcANBAHMXDkGd57d4F4cRk/8UjhxD
7OtRBZfdfznSvlhJIMNfH5q0zbC2eO3hWCB3Hrn/vIeswGP8Ov4AJ6eXeX44BQM=
-----END CERTIFICATE-----

View File

@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIC29RnMVTcyqXEAIO1b/6p7RdbM6TiqvnztVQ4IxYxUh
-----END PRIVATE KEY-----

View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIUNM5QQv8IzVQsgSmmdPQNaqyzWs4wDQYJKoZIhvcNAQEL
BQAwezELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCVN0YXRlTmFtZTERMA8GA1UEBwwI
Q2l0eU5hbWUxFDASBgNVBAoMC0NvbXBhbnlOYW1lMRswGQYDVQQLDBJDb21wYW55
U2VjdGlvbk5hbWUxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMzA5MTExMjExNTha
Fw0zMzA5MDgxMjExNThaMHsxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5h
bWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkG
A1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfdkeEiCk+5mpXUhJ1FLmOCx6/
jAHHaDxZ8hIpyp/c4ZAqFX5uamP08jL056kRKL4RRoUamNWdt0dgpHqds/84pb+3
OlCVjnFvzGVrvRwdrrQA2mda0BDm2Qnb0r9IhZr7tBpursbDsIC1U6zk1iwrbiO3
hu0/9uXlMWt49nccTDOpTtuhYUPEA3+NQFqUCwHrd8H9j+BQD5lf4RhoE6krDdV1
JD8qOns+uD6IKn0xfyPHmy8LD0mM5Rch6J13TZnH1yeFT8Y0ZnAPuwXHO5BNw504
3Kt/das3NvV+4Qq0qQ08NFK+vmoooP11uIcZb8gUaMgmRINL4P3TOhyA1ueXAgMB
AAGjUzBRMB0GA1UdDgQWBBRHYz8OjqU/4JZMegJaN/jQbdj4MjAfBgNVHSMEGDAW
gBRHYz8OjqU/4JZMegJaN/jQbdj4MjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQBr9zqlNx7Mr1ordGfhk+xFrDtyBnk1vXbwVdnog66REqpPLH+K
MfCKdj6wFoPa8ZjPb4VYFp2DvMxVXtFMzqGfLjYJPqefEzQCleOcA5aiE/ENIaaD
ybYh99V5CsFAqyKuHLBFEzeYJ028SR3QsCISom0k/Fh6y2IwHJJEHykjqJKvL4bb
V0IJjcmYjEZbTvpjFKznvaFiOUv+8L7jHQ1/Yf+9c3C8gSjdUfv88m17pqYXd+Ds
HEmfmNNjht130UyjNCITmLVXyy5p35vWmdf95U3uEbJSnNVtXH8qRmN9oK9mUpDb
ngX6JBJI7fw7tXoqWSLHNiBODM88fUlQSho8
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfdkeEiCk+5mpX
UhJ1FLmOCx6/jAHHaDxZ8hIpyp/c4ZAqFX5uamP08jL056kRKL4RRoUamNWdt0dg
pHqds/84pb+3OlCVjnFvzGVrvRwdrrQA2mda0BDm2Qnb0r9IhZr7tBpursbDsIC1
U6zk1iwrbiO3hu0/9uXlMWt49nccTDOpTtuhYUPEA3+NQFqUCwHrd8H9j+BQD5lf
4RhoE6krDdV1JD8qOns+uD6IKn0xfyPHmy8LD0mM5Rch6J13TZnH1yeFT8Y0ZnAP
uwXHO5BNw5043Kt/das3NvV+4Qq0qQ08NFK+vmoooP11uIcZb8gUaMgmRINL4P3T
OhyA1ueXAgMBAAECggEAPK1LqmULWMlhdoeeyVlQ//lAQn+6X4/MwycG/UsCSJC2
BCV4nfgyv853UFRkM0jPBhDQ7h1wz1ohuWbs11xaBcqgKE7ywe3ZQULD5tqnO64y
BU8V2+rnO4gjpbdMHQLlxdgy5KHxtR3Q4+6Kj+rlFMOMqLWZSmke8na7H+SczzGf
+dZO4LRTbjGmFdUidehovm2icSM8OdU2w3FHlFRu2NBsTHGeAhRw86Yw24KfJp4R
GSDQIBdwp1wCs5w7w4zPjxS7Zi+Uwspyq31KDJwyfK2O1WLI05bQ6FLqVRD/xy+Y
b4WCse1O08SYWze2No915LB07sokgmomr3//bOwuEQKBgQDPBrPQXokn0BoTlgsa
JohgWzQ5P9u/2WY+u2SG/xgNEx0s+lk/AmAH80wsBJ68FV6z5Non7TzD7xCsf2HJ
3cP/EHl2ngTctz/eqpCcS5UPZBHmay60q6WKIkH/3ml7c0UhlqSqS3EDVyEe05hk
msWAN+fV4ajVlhWgiUZRVdxMpwKBgQDFLyPBOEn6zLOHfkQWcibVf8s2LTe76R/S
8Gk3jbk5mimR3vNm0L/rHqGwl75rOuFiFOHVkfuY9Dawaht0QnagjayT5hDqr6aD
s5Chyoy9qpXnfnqOgk6rQZqj+/ODkjqEkBdRCKWvCVnDIi3Au2kS3QIc4iTsGrBW
ygZdbxM7kQKBgEuzS7T5nHVuZtqaltytElkJgIMekqAIQpbVtuCWDplZT+XOdSvR
FoRRtpyx48kql0J4gDzxRrLui85Hld5WtQBjacax6V07tKMbA13jVVIXaWQz9RQj
X5ivBisljLSTZcfuaa/LfjuWdIntHWBMJ8PGrYNLzIytIKNfDtNW7gMpAoGAIRZQ
5JpCZ7Azq9e3KyEKfSbNfZDG2mQ679Vhgm3ol87TjOOhai47FgP008IStMGTkja4
0nKFilvoVV/orXB9oWFEhSjEy+yff1gBO/TV+vmF3+tsOz+IXdpLTZr4eKpv4VCg
aPuPebiS9Fhm3wFTl1O4iAo2cdvknRuXR9RcoNECgYADksGk1lJGW5kMIMJ+6os+
CJdGnJiX7XsnM0VzkagswnqDe03SqkJuFOmIp96eitxLT4EfB+585pYQRSy2fyJX
WR2AAnC7oqUcQFkgDt9WBZAazI6aLXYO+trRoGKuWynGM8mjetr5C75g0auj4lsN
rGiie2UnjshJ67FrG4kZoA==
-----END PRIVATE KEY-----

View File

@ -35,13 +35,16 @@ import org.springframework.util.StringUtils;
*
* @author Scott Frederick
* @author Phillip Webb
* @author Moritz Halbritter
* @since 3.1.0
*/
public class JksSslStoreBundle implements SslStoreBundle {
private final JksSslStoreDetails keyStoreDetails;
private final JksSslStoreDetails trustStoreDetails;
private final KeyStore keyStore;
private final KeyStore trustStore;
/**
* Create a new {@link JksSslStoreBundle} instance.
@ -50,12 +53,13 @@ public class JksSslStoreBundle implements SslStoreBundle {
*/
public JksSslStoreBundle(JksSslStoreDetails keyStoreDetails, JksSslStoreDetails trustStoreDetails) {
this.keyStoreDetails = keyStoreDetails;
this.trustStoreDetails = trustStoreDetails;
this.keyStore = createKeyStore("key", this.keyStoreDetails);
this.trustStore = createKeyStore("trust", trustStoreDetails);
}
@Override
public KeyStore getKeyStore() {
return createKeyStore("key", this.keyStoreDetails);
return this.keyStore;
}
@Override
@ -65,7 +69,7 @@ public class JksSslStoreBundle implements SslStoreBundle {
@Override
public KeyStore getTrustStore() {
return createKeyStore("trust", this.trustStoreDetails);
return this.trustStore;
}
private KeyStore createKeyStore(String name, JksSslStoreDetails details) {

View File

@ -30,19 +30,16 @@ import org.springframework.util.StringUtils;
*
* @author Scott Frederick
* @author Phillip Webb
* @author Moritz Halbritter
* @since 3.1.0
*/
public class PemSslStoreBundle implements SslStoreBundle {
private static final String DEFAULT_KEY_ALIAS = "ssl";
private final PemSslStoreDetails keyStoreDetails;
private final KeyStore keyStore;
private final PemSslStoreDetails trustStoreDetails;
private final String keyAlias;
private final String keyPassword;
private final KeyStore trustStore;
/**
* Create a new {@link PemSslStoreBundle} instance.
@ -74,15 +71,13 @@ public class PemSslStoreBundle implements SslStoreBundle {
*/
public PemSslStoreBundle(PemSslStoreDetails keyStoreDetails, PemSslStoreDetails trustStoreDetails, String keyAlias,
String keyPassword) {
this.keyAlias = keyAlias;
this.keyStoreDetails = keyStoreDetails;
this.trustStoreDetails = trustStoreDetails;
this.keyPassword = keyPassword;
this.keyStore = createKeyStore("key", keyStoreDetails, keyAlias, keyPassword);
this.trustStore = createKeyStore("trust", trustStoreDetails, keyAlias, keyPassword);
}
@Override
public KeyStore getKeyStore() {
return createKeyStore("key", this.keyStoreDetails);
return this.keyStore;
}
@Override
@ -92,10 +87,10 @@ public class PemSslStoreBundle implements SslStoreBundle {
@Override
public KeyStore getTrustStore() {
return createKeyStore("trust", this.trustStoreDetails);
return this.trustStore;
}
private KeyStore createKeyStore(String name, PemSslStoreDetails details) {
private KeyStore createKeyStore(String name, PemSslStoreDetails details, String alias, String keyPassword) {
if (details == null || details.isEmpty()) {
return null;
}
@ -108,7 +103,7 @@ public class PemSslStoreBundle implements SslStoreBundle {
String privateKeyContent = PemContent.load(details.privateKey());
X509Certificate[] certificates = PemCertificateParser.parse(certificateContent);
PrivateKey privateKey = PemPrivateKeyParser.parse(privateKeyContent, details.privateKeyPassword());
addCertificates(store, certificates, privateKey);
addCertificates(store, certificates, privateKey, (alias != null) ? alias : DEFAULT_KEY_ALIAS, keyPassword);
return store;
}
catch (Exception ex) {
@ -116,11 +111,10 @@ public class PemSslStoreBundle implements SslStoreBundle {
}
}
private void addCertificates(KeyStore keyStore, X509Certificate[] certificates, PrivateKey privateKey)
throws KeyStoreException {
String alias = (this.keyAlias != null) ? this.keyAlias : DEFAULT_KEY_ALIAS;
private void addCertificates(KeyStore keyStore, X509Certificate[] certificates, PrivateKey privateKey, String alias,
String keyPassword) throws KeyStoreException {
if (privateKey != null) {
keyStore.setKeyEntry(alias, privateKey, (this.keyPassword != null) ? this.keyPassword.toCharArray() : null,
keyStore.setKeyEntry(alias, privateKey, (keyPassword != null) ? keyPassword.toCharArray() : null,
certificates);
}
else {

View File

@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*
* @author Scott Frederick
* @author Phillip Webb
* @author Moritz Halbritter
*/
@MockPkcs11Security
class JksSslStoreBundleTests {
@ -58,10 +59,11 @@ class JksSslStoreBundleTests {
@Test
void whenTypePKCS11AndLocationThrowsException() {
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("PKCS11", null, "test.jks", null);
JksSslStoreDetails trustStoreDetails = null;
JksSslStoreBundle bundle = new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
assertThatIllegalStateException().isThrownBy(bundle::getKeyStore)
assertThatIllegalStateException().isThrownBy(() -> {
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("PKCS11", null, "test.jks", null);
JksSslStoreDetails trustStoreDetails = null;
new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
})
.withMessageContaining(
"Unable to create key store: Location is 'test.jks', but must be empty or null for PKCS11 hardware key stores");
}
@ -102,22 +104,22 @@ class JksSslStoreBundleTests {
@Test
void whenHasKeyStoreProvider() {
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails(null, "com.example.KeyStoreProvider",
"classpath:test.jks", "secret");
JksSslStoreDetails trustStoreDetails = null;
JksSslStoreBundle bundle = new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
assertThatIllegalStateException().isThrownBy(bundle::getKeyStore)
.withMessageContaining("com.example.KeyStoreProvider");
assertThatIllegalStateException().isThrownBy(() -> {
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails(null, "com.example.KeyStoreProvider",
"classpath:test.jks", "secret");
JksSslStoreDetails trustStoreDetails = null;
new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
}).withMessageContaining("com.example.KeyStoreProvider");
}
@Test
void whenHasTrustStoreProvider() {
JksSslStoreDetails keyStoreDetails = null;
JksSslStoreDetails trustStoreDetails = new JksSslStoreDetails(null, "com.example.KeyStoreProvider",
"classpath:test.jks", "secret");
JksSslStoreBundle bundle = new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
assertThatIllegalStateException().isThrownBy(bundle::getTrustStore)
.withMessageContaining("com.example.KeyStoreProvider");
assertThatIllegalStateException().isThrownBy(() -> {
JksSslStoreDetails keyStoreDetails = null;
JksSslStoreDetails trustStoreDetails = new JksSslStoreDetails(null, "com.example.KeyStoreProvider",
"classpath:test.jks", "secret");
new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
}).withMessageContaining("com.example.KeyStoreProvider");
}
private Consumer<KeyStore> storeContainingCertAndKey(String keyAlias, String keyPassword) {

View File

@ -67,14 +67,12 @@ class SslConnectorCustomizerTests {
private Tomcat tomcat;
private Connector connector;
@BeforeEach
void setup() {
this.tomcat = new Tomcat();
this.connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
this.connector.setPort(0);
this.tomcat.setConnector(this.connector);
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(0);
this.tomcat.setConnector(connector);
}
@AfterEach
@ -207,10 +205,11 @@ class SslConnectorCustomizerTests {
ssl.setKeyStoreProvider(MockPkcs11SecurityProvider.NAME);
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyPassword("password");
SslConnectorCustomizer customizer = new SslConnectorCustomizer(ssl.getClientAuth(),
WebServerSslBundle.get(ssl));
assertThatIllegalStateException().isThrownBy(() -> customizer.customize(this.tomcat.getConnector()))
.withMessageContaining("must be empty or null for PKCS11 hardware key stores");
assertThatIllegalStateException().isThrownBy(() -> {
SslConnectorCustomizer customizer = new SslConnectorCustomizer(ssl.getClientAuth(),
WebServerSslBundle.get(ssl));
customizer.customize(this.tomcat.getConnector());
}).withMessageContaining("must be empty or null for PKCS11 hardware key stores");
}
@Test

View File

@ -25,6 +25,8 @@ import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundleKey;
import org.springframework.boot.ssl.SslOptions;
import org.springframework.boot.ssl.SslStoreBundle;
import org.springframework.boot.web.embedded.test.MockPkcs11Security;
import org.springframework.boot.web.embedded.test.MockPkcs11SecurityProvider;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
@ -38,7 +40,9 @@ import static org.mockito.Mockito.mock;
*
* @author Scott Frederick
* @author Phillip Webb
* @author Moritz Halbritter
*/
@MockPkcs11Security
class WebServerSslBundleTests {
@Test
@ -82,14 +86,13 @@ class WebServerSslBundleTests {
@Test
void whenFromJksPropertiesWithPkcs11StoreType() {
Ssl ssl = new Ssl();
ssl.setKeyStorePassword("secret");
ssl.setKeyStoreType("PKCS11");
ssl.setKeyStoreProvider(MockPkcs11SecurityProvider.NAME);
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyPassword("password");
ssl.setClientAuth(Ssl.ClientAuth.NONE);
SslBundle bundle = WebServerSslBundle.get(ssl);
assertThat(bundle).isNotNull();
assertThat(bundle.getStores().getKeyStorePassword()).isEqualTo("secret");
assertThat(bundle.getKey().getPassword()).isEqualTo("password");
assertThatIllegalStateException().isThrownBy(() -> WebServerSslBundle.get(ssl))
.withMessageContaining("must be empty or null for PKCS11 hardware key stores");
}
@Test