diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundleTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundleTests.java index 43c00ac56b2a..1b745328310a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundleTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundleTests.java @@ -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 @@ * 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 @@ void jksPropertiesAreMappedToSslBundle() { 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 @@ void jksPropertiesAreMappedToSslBundle() { 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"); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslAutoConfigurationTests.java index 5717fedfbdfd..06cbc412829b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslAutoConfigurationTests.java @@ -38,6 +38,7 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ class SslAutoConfigurationTests { @@ -54,18 +55,28 @@ void sslBundlesCreatedWithCertificates() { List 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 @@ void sslBundlesCreatedWithCertificates() { 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 @@ void sslBundlesCreatedWithCustomSslBundle() { List 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 @@ void sslBundlesCreatedWithCustomSslBundle() { 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"); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem new file mode 100644 index 000000000000..9f566ceceed6 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-cert.pem @@ -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----- diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-key.pem b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-key.pem new file mode 100644 index 000000000000..b32bf9e97330 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/ed25519-key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIC29RnMVTcyqXEAIO1b/6p7RdbM6TiqvnztVQ4IxYxUh +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.jks b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.jks new file mode 100644 index 000000000000..4e5e1399aee4 Binary files /dev/null and b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.jks differ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.pkcs12 b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.pkcs12 new file mode 100644 index 000000000000..8c9a6ffa62f4 Binary files /dev/null and b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/keystore.pkcs12 differ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-cert.pem b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-cert.pem new file mode 100644 index 000000000000..a92d2cca7fd5 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-cert.pem @@ -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----- diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-key.pem b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-key.pem new file mode 100644 index 000000000000..895b7763f499 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/ssl/rsa-key.pem @@ -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----- diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/jks/JksSslStoreBundle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/jks/JksSslStoreBundle.java index 8deb079a5c61..ef0b924ffb2d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/jks/JksSslStoreBundle.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/jks/JksSslStoreBundle.java @@ -35,13 +35,16 @@ * * @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 String getKeyStorePassword() { @Override public KeyStore getTrustStore() { - return createKeyStore("trust", this.trustStoreDetails); + return this.trustStore; } private KeyStore createKeyStore(String name, JksSslStoreDetails details) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java index 83f6146fce8e..250030766905 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java @@ -30,19 +30,16 @@ * * @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 PemSslStoreBundle(PemSslStoreDetails keyStoreDetails, PemSslStoreDetails */ 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 String getKeyStorePassword() { @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 @@ private KeyStore createKeyStore(String name, PemSslStoreDetails details) { 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 @@ private KeyStore createKeyStore(String name, PemSslStoreDetails details) { } } - 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 { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/jks/JksSslStoreBundleTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/jks/JksSslStoreBundleTests.java index 87b0f972e233..159e98c45654 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/jks/JksSslStoreBundleTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/jks/JksSslStoreBundleTests.java @@ -32,6 +32,7 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ @MockPkcs11Security class JksSslStoreBundleTests { @@ -58,10 +59,11 @@ void whenStoresHaveNoValues() { @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 @@ void whenHasTrustStoreType() { @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 storeContainingCertAndKey(String keyAlias, String keyPassword) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java index 058d2dd6e525..53b05891a7fd 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java @@ -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 @@ void customizeWhenSslIsEnabledWithPkcs11AndKeyStoreThrowsException() { 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 diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java index 9d6c0a1d6fb6..c6a22a22fa8e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/WebServerSslBundleTests.java @@ -25,6 +25,8 @@ 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 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ +@MockPkcs11Security class WebServerSslBundleTests { @Test @@ -82,14 +86,13 @@ void whenFromJksProperties() { @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