Skip to content

Commit

Permalink
Merge branch '2.7.x'
Browse files Browse the repository at this point in the history
Closes gh-33433
  • Loading branch information
mhalbritter committed Dec 1, 2022
2 parents bf2bc44 + ad2b130 commit a4779b7
Show file tree
Hide file tree
Showing 17 changed files with 732 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
* @author Brian Clozel
* @author Olivier Lamy
* @author Chris Bono
* @author Cyril Dangerville
*/
class SslServerCustomizer implements JettyServerCustomizer {

Expand Down Expand Up @@ -220,16 +221,24 @@ private void configureSslPasswords(SslContextFactory.Server factory, Ssl ssl) {
}

private void configureSslKeyStore(SslContextFactory.Server factory, Ssl ssl) {
try {
URL url = ResourceUtils.getURL(ssl.getKeyStore());
factory.setKeyStoreResource(Resource.newResource(url));
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + ssl.getKeyStore() + "'", ex);
String keystoreType = (ssl.getKeyStoreType() != null) ? ssl.getKeyStoreType() : "JKS";
String keystoreLocation = ssl.getKeyStore();
if (keystoreType.equalsIgnoreCase("PKCS11")) {
if (keystoreLocation != null && !keystoreLocation.isEmpty()) {
throw new IllegalArgumentException("Input keystore location is not valid for keystore type 'PKCS11': '"
+ keystoreLocation + "'. Must be undefined / null.");
}
}
if (ssl.getKeyStoreType() != null) {
factory.setKeyStoreType(ssl.getKeyStoreType());
else {
try {
URL url = ResourceUtils.getURL(keystoreLocation);
factory.setKeyStoreResource(Resource.newResource(url));
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + keystoreLocation + "'", ex);
}
}
factory.setKeyStoreType(keystoreType);
if (ssl.getKeyStoreProvider() != null) {
factory.setKeyStoreProvider(ssl.getKeyStoreProvider());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
* @author Brian Clozel
* @author Raheela Aslam
* @author Chris Bono
* @author Cyril Dangerville
* @since 2.0.0
* @deprecated this class is meant for Spring Boot internal use only.
*/
Expand Down Expand Up @@ -171,17 +172,25 @@ private KeyStore loadTrustStore(String type, String provider, String resource, S
private KeyStore loadStore(String type, String provider, String resource, String password) throws Exception {
type = (type != null) ? type : "JKS";
KeyStore store = (provider != null) ? KeyStore.getInstance(type, provider) : KeyStore.getInstance(type);
try {
URL url = ResourceUtils.getURL(resource);
try (InputStream stream = url.openStream()) {
store.load(stream, (password != null) ? password.toCharArray() : null);
if (type.equalsIgnoreCase("PKCS11")) {
if (resource != null && !resource.isEmpty()) {
throw new IllegalArgumentException("Input keystore location is not valid for keystore type 'PKCS11': '"
+ resource + "'. Must be undefined / null.");
}
return store;
store.load(null, (password != null) ? password.toCharArray() : null);
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + resource + "'", ex);
else {
try {
URL url = ResourceUtils.getURL(resource);
try (InputStream stream = url.openStream()) {
store.load(stream, (password != null) ? password.toCharArray() : null);
}
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + resource + "'", ex);
}
}

return store;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* @author Brian Clozel
* @author Andy Wilkinson
* @author Scott Frederick
* @author Cyril Dangerville
*/
class SslConnectorCustomizer implements TomcatConnectorCustomizer {

Expand Down Expand Up @@ -139,15 +140,23 @@ protected void configureSslStoreProvider(AbstractHttp11JsseProtocol<?> protocol,
}

private void configureSslKeyStore(SSLHostConfigCertificate certificate, Ssl ssl) {
try {
certificate.setCertificateKeystoreFile(ResourceUtils.getURL(ssl.getKeyStore()).toString());
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + ssl.getKeyStore() + "'", ex);
String keystoreType = (ssl.getKeyStoreType() != null) ? ssl.getKeyStoreType() : "JKS";
String keystoreLocation = ssl.getKeyStore();
if (keystoreType.equalsIgnoreCase("PKCS11")) {
if (keystoreLocation != null && !keystoreLocation.isEmpty()) {
throw new IllegalArgumentException("Input keystore location is not valid for keystore type 'PKCS11': '"
+ keystoreLocation + "'. Must be undefined / null.");
}
}
if (ssl.getKeyStoreType() != null) {
certificate.setCertificateKeystoreType(ssl.getKeyStoreType());
else {
try {
certificate.setCertificateKeystoreFile(ResourceUtils.getURL(keystoreLocation).toString());
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + keystoreLocation + "'", ex);
}
}
certificate.setCertificateKeystoreType(keystoreType);
if (ssl.getKeyStoreProvider() != null) {
certificate.setCertificateKeystoreProvider(ssl.getKeyStoreProvider());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
*
* @author Brian Clozel
* @author Raheela Aslam
* @author Cyril Dangerville
*/
class SslBuilderCustomizer implements UndertowBuilderCustomizer {

Expand Down Expand Up @@ -180,16 +181,26 @@ private KeyStore loadTrustStore(String type, String provider, String resource, S
private KeyStore loadStore(String type, String provider, String resource, String password) throws Exception {
type = (type != null) ? type : "JKS";
KeyStore store = (provider != null) ? KeyStore.getInstance(type, provider) : KeyStore.getInstance(type);
try {
URL url = ResourceUtils.getURL(resource);
try (InputStream stream = url.openStream()) {
store.load(stream, (password != null) ? password.toCharArray() : null);
if (type.equalsIgnoreCase("PKCS11")) {
if (resource != null && !resource.isEmpty()) {
throw new IllegalArgumentException("Input keystore location is not valid for keystore type 'PKCS11': '"
+ resource + "'. Must be undefined / null.");
}
return store;
store.load(null, (password != null) ? password.toCharArray() : null);
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + resource + "'", ex);
else {
try {
URL url = ResourceUtils.getURL(resource);
try (InputStream stream = url.openStream()) {
store.load(stream, (password != null) ? password.toCharArray() : null);
}
}
catch (Exception ex) {
throw new WebServerException("Could not load key store '" + resource + "'", ex);
}
}

return store;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.springframework.boot.web.embedded.jetty;

import java.net.InetSocketAddress;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -27,24 +29,47 @@
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;

import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.boot.web.embedded.netty.MockPkcs11SecurityProvider;
import org.springframework.boot.web.server.Http2;
import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.WebServerException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatNoException;

/**
* Tests for {@link SslServerCustomizer}.
*
* @author Andy Wilkinson
* @author Cyril Dangerville
*/
class SslServerCustomizerTests {

private static final Provider PKCS11_PROVIDER = new MockPkcs11SecurityProvider();

@BeforeAll
static void beforeAllTests() {
/*
* Add the mock Java security provider for PKCS#11-related unit tests.
*
*/
Security.addProvider(PKCS11_PROVIDER);
}

@AfterAll
static void afterAllTests() {
// Remove the provider previously added in setup()
Security.removeProvider(PKCS11_PROVIDER.getName());
}

@Test
@SuppressWarnings("rawtypes")
void whenHttp2IsNotEnabledServerConnectorHasSslAndHttpConnectionFactories() {
Expand Down Expand Up @@ -82,8 +107,11 @@ void alpnConnectionFactoryHasNullDefaultProtocolToAllowNegotiationToHttp11() {
assertThat(((ALPNServerConnectionFactory) factories.get(1)).getDefaultProtocol()).isNull();
}

/**
* Null/undefined keystore is invalid unless keystore type is PKCS11.
*/
@Test
void configureSslWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() {
void configureSslWhenSslIsEnabledWithNoKeyStoreAndNotPkcs11ThrowsWebServerException() {
Ssl ssl = new Ssl();
SslServerCustomizer customizer = new SslServerCustomizer(null, ssl, null, null);
assertThatExceptionOfType(Exception.class)
Expand All @@ -94,6 +122,33 @@ void configureSslWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() {
});
}

/**
* No keystore path should be defined if keystore type is PKCS#11.
*/
@Test
void configureSslWhenSslIsEnabledWithPkcs11AndKeyStoreThrowsIllegalArgumentException() {
Ssl ssl = new Ssl();
ssl.setKeyStoreType("PKCS11");
ssl.setKeyStoreProvider(PKCS11_PROVIDER.getName());
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyPassword("password");
SslServerCustomizer customizer = new SslServerCustomizer(null, ssl, null, null);
assertThatIllegalArgumentException()
.isThrownBy(() -> customizer.configureSsl(new SslContextFactory.Server(), ssl, null))
.withMessageContaining("Input keystore location is not valid for keystore type 'PKCS11'");
}

@Test
void customizeWhenSslIsEnabledWithPkcs11AndKeyStoreProvider() {
Ssl ssl = new Ssl();
ssl.setKeyStoreType("PKCS11");
ssl.setKeyStoreProvider(PKCS11_PROVIDER.getName());
ssl.setKeyStorePassword("1234");
SslServerCustomizer customizer = new SslServerCustomizer(null, ssl, null, null);
// Loading the KeyManagerFactory should be successful
assertThatNoException().isThrownBy(() -> customizer.configureSsl(new SslContextFactory.Server(), ssl, null));
}

private Server createCustomizedServer() {
return createCustomizedServer(new Http2());
}
Expand Down
Loading

0 comments on commit a4779b7

Please sign in to comment.