Skip to content

Commit

Permalink
Merge branch '3.2.x'
Browse files Browse the repository at this point in the history
Closes gh-39159
  • Loading branch information
scottfrederick committed Jan 16, 2024
2 parents 8cdec2d + 90564d7 commit a7463c0
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.boot.web.server;

import java.security.KeyStore;

import org.springframework.boot.ssl.NoSuchSslBundleException;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundleKey;
Expand Down Expand Up @@ -57,21 +59,30 @@ private WebServerSslBundle(SslStoreBundle stores, String keyPassword, Ssl ssl) {
this.managers = SslManagerBundle.from(this.stores, this.key);
}

private static SslStoreBundle createPemStoreBundle(Ssl ssl) {
private static SslStoreBundle createPemKeyStoreBundle(Ssl ssl) {
PemSslStoreDetails keyStoreDetails = new PemSslStoreDetails(ssl.getKeyStoreType(), ssl.getCertificate(),
ssl.getCertificatePrivateKey())
.withAlias(ssl.getKeyAlias());
return new PemSslStoreBundle(keyStoreDetails, null);
}

private static SslStoreBundle createPemTrustStoreBundle(Ssl ssl) {
PemSslStoreDetails trustStoreDetails = new PemSslStoreDetails(ssl.getTrustStoreType(),
ssl.getTrustCertificate(), ssl.getTrustCertificatePrivateKey());
return new PemSslStoreBundle(keyStoreDetails, trustStoreDetails);
ssl.getTrustCertificate(), ssl.getTrustCertificatePrivateKey())
.withAlias(ssl.getKeyAlias());
return new PemSslStoreBundle(null, trustStoreDetails);
}

private static SslStoreBundle createJksStoreBundle(Ssl ssl) {
private static SslStoreBundle createJksKeyStoreBundle(Ssl ssl) {
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails(ssl.getKeyStoreType(), ssl.getKeyStoreProvider(),
ssl.getKeyStore(), ssl.getKeyStorePassword());
return new JksSslStoreBundle(keyStoreDetails, null);
}

private static SslStoreBundle createJksTrustStoreBundle(Ssl ssl) {
JksSslStoreDetails trustStoreDetails = new JksSslStoreDetails(ssl.getTrustStoreType(),
ssl.getTrustStoreProvider(), ssl.getTrustStore(), ssl.getTrustStorePassword());
return new JksSslStoreBundle(keyStoreDetails, trustStoreDetails);
return new JksSslStoreBundle(null, trustStoreDetails);
}

@Override
Expand Down Expand Up @@ -132,22 +143,79 @@ public static SslBundle get(Ssl ssl, SslBundles sslBundles) throws NoSuchSslBund
}

private static SslStoreBundle createStoreBundle(Ssl ssl) {
if (hasCertificateProperties(ssl)) {
return createPemStoreBundle(ssl);
KeyStore keyStore = createKeyStore(ssl);
KeyStore trustStore = createTrustStore(ssl);
return new WebServerSslStoreBundle(keyStore, trustStore, ssl.getKeyStorePassword());
}

private static KeyStore createKeyStore(Ssl ssl) {
if (hasPemKeyStoreProperties(ssl)) {
return createPemKeyStoreBundle(ssl).getKeyStore();
}
if (hasJavaKeyStoreProperties(ssl)) {
return createJksStoreBundle(ssl);
else if (hasJksKeyStoreProperties(ssl)) {
return createJksKeyStoreBundle(ssl).getKeyStore();
}
throw new IllegalStateException("SSL is enabled but no trust material is configured");
return null;
}

private static boolean hasCertificateProperties(Ssl ssl) {
private static KeyStore createTrustStore(Ssl ssl) {
if (hasPemTrustStoreProperties(ssl)) {
return createPemTrustStoreBundle(ssl).getTrustStore();
}
else if (hasJksTrustStoreProperties(ssl)) {
return createJksTrustStoreBundle(ssl).getTrustStore();
}
return null;
}

private static boolean hasPemKeyStoreProperties(Ssl ssl) {
return Ssl.isEnabled(ssl) && ssl.getCertificate() != null && ssl.getCertificatePrivateKey() != null;
}

private static boolean hasJavaKeyStoreProperties(Ssl ssl) {
return Ssl.isEnabled(ssl) && ssl.getKeyStore() != null
|| (ssl.getKeyStoreType() != null && ssl.getKeyStoreType().equals("PKCS11"));
private static boolean hasPemTrustStoreProperties(Ssl ssl) {
return Ssl.isEnabled(ssl) && ssl.getTrustCertificate() != null;
}

private static boolean hasJksKeyStoreProperties(Ssl ssl) {
return Ssl.isEnabled(ssl) && (ssl.getKeyStore() != null
|| (ssl.getKeyStoreType() != null && ssl.getKeyStoreType().equals("PKCS11")));
}

private static boolean hasJksTrustStoreProperties(Ssl ssl) {
return Ssl.isEnabled(ssl) && (ssl.getTrustStore() != null
|| (ssl.getTrustStoreType() != null && ssl.getTrustStoreType().equals("PKCS11")));
}

private static final class WebServerSslStoreBundle implements SslStoreBundle {

private final KeyStore keyStore;

private final KeyStore trustStore;

private final String keyStorePassword;

private WebServerSslStoreBundle(KeyStore keyStore, KeyStore trustStore, String keyStorePassword) {
Assert.state(keyStore != null || trustStore != null, "SSL is enabled but no trust material is configured");
this.keyStore = keyStore;
this.trustStore = trustStore;
this.keyStorePassword = keyStorePassword;
}

@Override
public KeyStore getKeyStore() {
return this.keyStore;
}

@Override
public KeyStore getTrustStore() {
return this.trustStore;
}

@Override
public String getKeyStorePassword() {
return this.keyStorePassword;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ void whenFromJksPropertiesWithPkcs11StoreType() {
.withMessageContaining("must be empty or null for PKCS11 hardware key stores");
}

@Test
void whenFromPkcs11Properties() {
Ssl ssl = new Ssl();
ssl.setKeyStoreType("PKCS11");
ssl.setKeyStoreProvider(MockPkcs11SecurityProvider.NAME);
ssl.setTrustStoreType("PKCS11");
ssl.setTrustStoreProvider(MockPkcs11SecurityProvider.NAME);
ssl.setKeyPassword("password");
ssl.setClientAuth(Ssl.ClientAuth.NONE);
SslBundle bundle = WebServerSslBundle.get(ssl);
assertThat(bundle).isNotNull();
assertThat(bundle.getProtocol()).isEqualTo("TLS");
SslBundleKey key = bundle.getKey();
assertThat(key.getPassword()).isEqualTo("password");
SslStoreBundle stores = bundle.getStores();
assertThat(stores.getKeyStore()).isNotNull();
assertThat(stores.getTrustStore()).isNotNull();
}

@Test
void whenFromPemProperties() {
Ssl ssl = new Ssl();
Expand Down Expand Up @@ -115,6 +134,61 @@ void whenFromPemProperties() {
assertThat(options.getEnabledProtocols()).containsExactly("TLSv1.1", "TLSv1.2");
}

@Test
void whenPemKeyStoreAndJksTrustStoreProperties() {
Ssl ssl = new Ssl();
ssl.setCertificate("classpath:test-cert.pem");
ssl.setCertificatePrivateKey("classpath:test-key.pem");
ssl.setKeyStoreType("PKCS12");
ssl.setKeyPassword("password");
ssl.setTrustStore("classpath:test.p12");
ssl.setTrustStorePassword("secret");
ssl.setTrustStoreType("PKCS12");
ssl.setClientAuth(Ssl.ClientAuth.NONE);
ssl.setCiphers(new String[] { "ONE", "TWO", "THREE" });
ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" });
ssl.setProtocol("TLSv1.1");
SslBundle bundle = WebServerSslBundle.get(ssl);
assertThat(bundle).isNotNull();
SslBundleKey key = bundle.getKey();
assertThat(key.getAlias()).isNull();
assertThat(key.getPassword()).isEqualTo("password");
SslStoreBundle stores = bundle.getStores();
assertThat(stores.getKeyStorePassword()).isNull();
assertThat(stores.getKeyStore()).isNotNull();
assertThat(stores.getTrustStore()).isNotNull();
SslOptions options = bundle.getOptions();
assertThat(options.getCiphers()).containsExactly("ONE", "TWO", "THREE");
assertThat(options.getEnabledProtocols()).containsExactly("TLSv1.1", "TLSv1.2");
}

@Test
void whenJksKeyStoreAndPemTrustStoreProperties() {
Ssl ssl = new Ssl();
ssl.setKeyStore("classpath:test.p12");
ssl.setKeyStoreType("PKCS12");
ssl.setKeyPassword("password");
ssl.setTrustCertificate("classpath:test-cert-chain.pem");
ssl.setTrustStorePassword("secret");
ssl.setTrustStoreType("PKCS12");
ssl.setClientAuth(Ssl.ClientAuth.NONE);
ssl.setCiphers(new String[] { "ONE", "TWO", "THREE" });
ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" });
ssl.setProtocol("TLSv1.1");
SslBundle bundle = WebServerSslBundle.get(ssl);
assertThat(bundle).isNotNull();
SslBundleKey key = bundle.getKey();
assertThat(key.getAlias()).isNull();
assertThat(key.getPassword()).isEqualTo("password");
SslStoreBundle stores = bundle.getStores();
assertThat(stores.getKeyStorePassword()).isNull();
assertThat(stores.getKeyStore()).isNotNull();
assertThat(stores.getTrustStore()).isNotNull();
SslOptions options = bundle.getOptions();
assertThat(options.getCiphers()).containsExactly("ONE", "TWO", "THREE");
assertThat(options.getEnabledProtocols()).containsExactly("TLSv1.1", "TLSv1.2");
}

@Test
void whenMissingPropertiesThrowsException() {
Ssl ssl = new Ssl();
Expand Down

0 comments on commit a7463c0

Please sign in to comment.