commit
8a1f6d4f32
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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-----
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MC4CAQAwBQYDK2VwBCIEIC29RnMVTcyqXEAIO1b/6p7RdbM6TiqvnztVQ4IxYxUh
|
||||
-----END PRIVATE KEY-----
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -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-----
|
||||
|
|
@ -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-----
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue