Merge branch '3.2.x'
Closes gh-39159
This commit is contained in:
@@ -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;
|
||||
@@ -57,21 +59,30 @@ public final class WebServerSslBundle implements SslBundle {
|
||||
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());
|
||||
PemSslStoreDetails trustStoreDetails = new PemSslStoreDetails(ssl.getTrustStoreType(),
|
||||
ssl.getTrustCertificate(), ssl.getTrustCertificatePrivateKey());
|
||||
return new PemSslStoreBundle(keyStoreDetails, trustStoreDetails);
|
||||
return new PemSslStoreBundle(keyStoreDetails, null);
|
||||
}
|
||||
|
||||
private static SslStoreBundle createJksStoreBundle(Ssl ssl) {
|
||||
private static SslStoreBundle createPemTrustStoreBundle(Ssl ssl) {
|
||||
PemSslStoreDetails trustStoreDetails = new PemSslStoreDetails(ssl.getTrustStoreType(),
|
||||
ssl.getTrustCertificate(), ssl.getTrustCertificatePrivateKey())
|
||||
.withAlias(ssl.getKeyAlias());
|
||||
return new PemSslStoreBundle(null, trustStoreDetails);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -132,22 +143,79 @@ public final class WebServerSslBundle implements SslBundle {
|
||||
}
|
||||
|
||||
private static SslStoreBundle createStoreBundle(Ssl ssl) {
|
||||
if (hasCertificateProperties(ssl)) {
|
||||
return createPemStoreBundle(ssl);
|
||||
}
|
||||
if (hasJavaKeyStoreProperties(ssl)) {
|
||||
return createJksStoreBundle(ssl);
|
||||
}
|
||||
throw new IllegalStateException("SSL is enabled but no trust material is configured");
|
||||
KeyStore keyStore = createKeyStore(ssl);
|
||||
KeyStore trustStore = createTrustStore(ssl);
|
||||
return new WebServerSslStoreBundle(keyStore, trustStore, ssl.getKeyStorePassword());
|
||||
}
|
||||
|
||||
private static boolean hasCertificateProperties(Ssl ssl) {
|
||||
private static KeyStore createKeyStore(Ssl ssl) {
|
||||
if (hasPemKeyStoreProperties(ssl)) {
|
||||
return createPemKeyStoreBundle(ssl).getKeyStore();
|
||||
}
|
||||
else if (hasJksKeyStoreProperties(ssl)) {
|
||||
return createJksKeyStoreBundle(ssl).getKeyStore();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -88,6 +88,25 @@ class WebServerSslBundleTests {
|
||||
.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();
|
||||
@@ -115,6 +134,61 @@ class WebServerSslBundleTests {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user