From 766ccd753b83bbaedea0f56e854c886a9875704f Mon Sep 17 00:00:00 2001 From: Pedro Costa Date: Mon, 21 Dec 2015 17:23:55 +0000 Subject: [PATCH 1/2] Make TLS protocols and cipher suites configurable via the environemnt Closes gh-4823 --- .../boot/context/embedded/Ssl.java | 13 ++++ .../JettyEmbeddedServletContainerFactory.java | 6 ++ ...TomcatEmbeddedServletContainerFactory.java | 8 ++ ...dertowEmbeddedServletContainerFactory.java | 12 ++- ...tEmbeddedServletContainerFactoryTests.java | 41 +++++++++- ...yEmbeddedServletContainerFactoryTests.java | 50 +++++++++++++ ...tEmbeddedServletContainerFactoryTests.java | 75 +++++++++++++++++++ ...wEmbeddedServletContainerFactoryTests.java | 32 ++++++++ 8 files changed, 231 insertions(+), 6 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java index acf2535433e..ed22a715791 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java @@ -41,6 +41,11 @@ public class Ssl { */ private String[] ciphers; + /** + * Supported SSL protocols. + */ + private String[] protocols; + /** * Alias that identifies the key in the key store. */ @@ -208,6 +213,14 @@ public class Ssl { this.protocol = protocol; } + public String[] getProtocols() { + return this.protocols; + } + + public void setProtocols(String[] protocols) { + this.protocols = protocols; + } + /** * Client authentication types. */ diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index 21eaef66f2a..24b6d5adf34 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -207,7 +207,13 @@ public class JettyEmbeddedServletContainerFactory * @param ssl the ssl details. */ protected void configureSsl(SslContextFactory factory, Ssl ssl) { + //Set the default TLS protocol factory.setProtocol(ssl.getProtocol()); + + //Assign the supported protocols, if provided + if (ssl.getProtocols() != null) { + factory.setIncludeProtocols(ssl.getProtocols()); + } configureSslClientAuth(factory, ssl); configureSslPasswords(factory, ssl); factory.setCertAlias(ssl.getKeyAlias()); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index 0ee888b4dd8..e72ab2df118 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -315,7 +315,15 @@ public class TomcatEmbeddedServletContainerFactory */ protected void configureSsl(AbstractHttp11JsseProtocol protocol, Ssl ssl) { protocol.setSSLEnabled(true); + //Set the default TLS protocol protocol.setSslProtocol(ssl.getProtocol()); + + //Assign the supported protocols, if provided + if (ssl.getProtocols() != null) { + String protocols = StringUtils.arrayToCommaDelimitedString(ssl.getProtocols()); + protocol.setProperty("sslEnabledProtocols", protocols); + } + configureSslClientAuth(protocol, ssl); protocol.setKeystorePass(ssl.getKeyStorePassword()); protocol.setKeyPass(ssl.getKeyPassword()); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java index e3a3e2ff4a4..abb6d93bf15 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java @@ -62,6 +62,7 @@ import io.undertow.servlet.handlers.DefaultServlet; import io.undertow.servlet.util.ImmediateInstanceFactory; import org.xnio.OptionMap; import org.xnio.Options; +import org.xnio.Sequence; import org.xnio.SslClientAuthMode; import org.xnio.Xnio; import org.xnio.XnioWorker; @@ -257,8 +258,15 @@ public class UndertowEmbeddedServletContainerFactory SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol()); sslContext.init(getKeyManagers(), getTrustManagers(), null); builder.addHttpsListener(port, getListenAddress(), sslContext); - builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, - getSslClientAuthMode(ssl)); + builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, getSslClientAuthMode(ssl)); + + //Configure the supported TLS protocols and Cipher suites + if (ssl.getProtocols() != null) { + builder.setSocketOption(Options.SSL_ENABLED_PROTOCOLS, Sequence.of(ssl.getProtocols())); + } + if (ssl.getCiphers() != null) { + builder.setSocketOption(Options.SSL_ENABLED_CIPHER_SUITES, Sequence.of(ssl.getCiphers())); + } } catch (NoSuchAlgorithmException ex) { throw new IllegalStateException(ex); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index 892ce92e2d2..15dc5a73c30 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -404,7 +404,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { AbstractEmbeddedServletContainerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.NEED, null, "classpath:test.p12", - "classpath:test.p12")); + "classpath:test.p12", null, null)); this.container = factory.getEmbeddedServletContainer(); this.container.start(); KeyStore keyStore = KeyStore.getInstance("pkcs12"); @@ -428,7 +428,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { AbstractEmbeddedServletContainerFactory factory = getFactory(); addTestTxtFile(factory); factory.setSsl(getSsl(ClientAuth.NEED, "password", "classpath:test.jks", - "classpath:test.jks")); + "classpath:test.jks", null, null)); this.container = factory.getEmbeddedServletContainer(); this.container.start(); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); @@ -526,11 +526,11 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { } private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore) { - return getSsl(clientAuth, keyPassword, keyStore, null); + return getSsl(clientAuth, keyPassword, keyStore, null, null, null); } private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore, - String trustStore) { + String trustStore, String[] protocols, String[] ciphers) { Ssl ssl = new Ssl(); ssl.setClientAuth(clientAuth); if (keyPassword != null) { @@ -546,9 +546,42 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { ssl.setTrustStorePassword("secret"); ssl.setTrustStoreType(getStoreType(trustStore)); } + if (ciphers != null) { + ssl.setCiphers(ciphers); + } + if (protocols != null) { + ssl.setProtocols(protocols); + } return ssl; } + /** + * @see + * SunJSSE supported Cipher Suites + */ + protected void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, + String[] ciphers) throws Exception { + AbstractEmbeddedServletContainerFactory factory = getFactory(); + factory.setSsl(getSsl(null, "password", "src/test/resources/test.jks", null, + protocols, ciphers)); + this.container = factory.getEmbeddedServletContainer( + new ServletRegistrationBean(new ExampleServlet(true, false), "/hello")); + this.container.start(); + + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + new SSLContextBuilder() + .loadTrustMaterial(null, new TrustSelfSignedStrategy()).build()); + + HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory) + .build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( + httpClient); + + assertThat(getResponse(getLocalUrl("https", "/hello"), requestFactory)) + .contains("scheme=https"); + } + private String getStoreType(String keyStore) { return (keyStore.endsWith(".p12") ? "pkcs12" : null); } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java index 72b8e7ded28..56854e1804f 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java @@ -152,6 +152,56 @@ public class JettyEmbeddedServletContainerFactoryTests }); } + @Test + public void sslEnabledMultiProtocolsConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("src/test/resources/test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setKeyPassword("password"); + ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); + ssl.setProtocols(new String[]{ "TLSv1.1", "TLSv1.2" }); + + JettyEmbeddedServletContainerFactory factory = getFactory(); + factory.setSsl(ssl); + + this.container = factory.getEmbeddedServletContainer(); + this.container.start(); + + JettyEmbeddedServletContainer jettyContainer = (JettyEmbeddedServletContainer) this.container; + ServerConnector connector = (ServerConnector) jettyContainer.getServer() + .getConnectors()[0]; + SslConnectionFactory connectionFactory = connector + .getConnectionFactory(SslConnectionFactory.class); + + assertThat(connectionFactory.getSslContextFactory().getIncludeProtocols()) + .isEqualTo(new String[] { "TLSv1.1", "TLSv1.2" }); + } + + @Test + public void sslEnabledProtocolsConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("src/test/resources/test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setKeyPassword("password"); + ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); + ssl.setProtocols(new String[]{ "TLSv1.1" }); + + JettyEmbeddedServletContainerFactory factory = getFactory(); + factory.setSsl(ssl); + + this.container = factory.getEmbeddedServletContainer(); + this.container.start(); + + JettyEmbeddedServletContainer jettyContainer = (JettyEmbeddedServletContainer) this.container; + ServerConnector connector = (ServerConnector) jettyContainer.getServer() + .getConnectors()[0]; + SslConnectionFactory connectionFactory = connector + .getConnectionFactory(SslConnectionFactory.class); + + assertThat(connectionFactory.getSslContextFactory().getIncludeProtocols()) + .isEqualTo(new String[] { "TLSv1.1" }); + } + private void assertTimeout(JettyEmbeddedServletContainerFactory factory, int expected) { this.container = factory.getEmbeddedServletContainer(); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java index 18d2f0c04f8..b0a5a13654f 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.context.embedded.tomcat; import java.io.File; +import java.io.IOException; import java.nio.charset.Charset; import java.util.Arrays; import java.util.HashMap; @@ -41,11 +42,13 @@ import org.mockito.InOrder; import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests; +import org.springframework.boot.context.embedded.EmbeddedServletContainerException; import org.springframework.boot.context.embedded.Ssl; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; @@ -260,6 +263,78 @@ public class TomcatEmbeddedServletContainerFactoryTests assertThat(jsseProtocol.getCiphers()).isEqualTo("ALPHA,BRAVO,CHARLIE"); } + @Test + public void sslEnabledMultipleProtocolsConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setProtocols(new String[]{ "TLSv1.1", "TLSv1.2" }); + ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); + + TomcatEmbeddedServletContainerFactory factory = getFactory(); + factory.setSsl(ssl); + + this.container = factory + .getEmbeddedServletContainer(sessionServletRegistration()); + Tomcat tomcat = ((TomcatEmbeddedServletContainer) this.container).getTomcat(); + Connector connector = tomcat.getConnector(); + + AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector + .getProtocolHandler(); + assertThat(jsseProtocol.getSslProtocol()).isEqualTo("TLS"); + assertThat(jsseProtocol.getProperty("sslEnabledProtocols")) + .isEqualTo("TLSv1.1,TLSv1.2"); + } + + @Test + public void sslEnabledProtocolsConfiguration() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyStore("test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setProtocols(new String[]{"TLSv1.2"}); + ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); + + TomcatEmbeddedServletContainerFactory factory = getFactory(); + factory.setSsl(ssl); + + this.container = factory + .getEmbeddedServletContainer(sessionServletRegistration()); + Tomcat tomcat = ((TomcatEmbeddedServletContainer) this.container).getTomcat(); + Connector connector = tomcat.getConnector(); + + AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector + .getProtocolHandler(); + assertThat(jsseProtocol.getSslProtocol()).isEqualTo("TLS"); + assertThat(jsseProtocol.getProperty("sslEnabledProtocols")).isEqualTo("TLSv1.2"); + } + + @Test + public void primaryConnectorPortClashThrowsIllegalStateException() + throws InterruptedException, IOException { + final int port = SocketUtils.findAvailableTcpPort(40000); + + doWithBlockedPort(port, new Runnable() { + + @Override + public void run() { + TomcatEmbeddedServletContainerFactory factory = getFactory(); + factory.setPort(port); + + try { + TomcatEmbeddedServletContainerFactoryTests.this.container = factory + .getEmbeddedServletContainer(); + TomcatEmbeddedServletContainerFactoryTests.this.container.start(); + fail(); + } + catch (EmbeddedServletContainerException ex) { + // Ignore + } + } + + }); + + } + @Override protected void addConnector(int port, AbstractEmbeddedServletContainerFactory factory) { diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java index a42d7e31238..a1f93ec099a 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java @@ -26,6 +26,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import javax.net.ssl.SSLHandshakeException; + import io.undertow.Undertow.Builder; import io.undertow.servlet.api.DeploymentInfo; import io.undertow.servlet.api.DeploymentManager; @@ -201,6 +203,36 @@ public class UndertowEmbeddedServletContainerFactoryTests }); } + @Test(expected = SSLHandshakeException.class) + public void sslRestrictedProtocolsEmptyCipherFailure() throws Exception { + testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, + new String[] { "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" }); + } + + @Test(expected = SSLHandshakeException.class) + public void sslRestrictedProtocolsECDHETLS1Failure() throws Exception { + testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1" }, + new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" }); + } + + @Test + public void sslRestrictedProtocolsECDHESuccess() throws Exception { + testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, + new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" }); + } + + @Test + public void sslRestrictedProtocolsRSATLS12Success() throws Exception { + testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.2" }, + new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA256" }); + } + + @Test(expected = SSLHandshakeException.class) + public void sslRestrictedProtocolsRSATLS11Failure() throws Exception { + testRestrictedSSLProtocolsAndCipherSuites(new String[] { "TLSv1.1" }, + new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA256" }); + } + @Override protected Object getJspServlet() { return null; // Undertow does not support JSPs From 742df6b63ba3eddb91970f6054d64190574971da Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 19 Feb 2016 16:54:11 +0000 Subject: [PATCH 2/2] Polish contribution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the new property to enabledProtocols to align more closely with Undertow and Tomcat’s underlying configuration setting. Closes gh-2109 --- .../boot/context/embedded/Ssl.java | 20 +++++++++---------- .../JettyEmbeddedServletContainerFactory.java | 9 +++------ ...TomcatEmbeddedServletContainerFactory.java | 15 +++++--------- ...dertowEmbeddedServletContainerFactory.java | 13 ++++++------ ...tEmbeddedServletContainerFactoryTests.java | 11 +++------- ...yEmbeddedServletContainerFactoryTests.java | 4 ++-- ...tEmbeddedServletContainerFactoryTests.java | 4 ++-- 7 files changed, 32 insertions(+), 44 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java index ed22a715791..9b363a6e618 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java @@ -42,9 +42,9 @@ public class Ssl { private String[] ciphers; /** - * Supported SSL protocols. + * Enabled SSL protocols. */ - private String[] protocols; + private String[] enabledProtocols; /** * Alias that identifies the key in the key store. @@ -173,6 +173,14 @@ public class Ssl { this.keyStoreProvider = keyStoreProvider; } + public String[] getEnabledProtocols() { + return this.enabledProtocols; + } + + public void setEnabledProtocols(String[] enabledProtocols) { + this.enabledProtocols = enabledProtocols; + } + public String getTrustStore() { return this.trustStore; } @@ -213,14 +221,6 @@ public class Ssl { this.protocol = protocol; } - public String[] getProtocols() { - return this.protocols; - } - - public void setProtocols(String[] protocols) { - this.protocols = protocols; - } - /** * Client authentication types. */ diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index 24b6d5adf34..c5de3778d69 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -207,13 +207,7 @@ public class JettyEmbeddedServletContainerFactory * @param ssl the ssl details. */ protected void configureSsl(SslContextFactory factory, Ssl ssl) { - //Set the default TLS protocol factory.setProtocol(ssl.getProtocol()); - - //Assign the supported protocols, if provided - if (ssl.getProtocols() != null) { - factory.setIncludeProtocols(ssl.getProtocols()); - } configureSslClientAuth(factory, ssl); configureSslPasswords(factory, ssl); factory.setCertAlias(ssl.getKeyAlias()); @@ -221,6 +215,9 @@ public class JettyEmbeddedServletContainerFactory if (ssl.getCiphers() != null) { factory.setIncludeCipherSuites(ssl.getCiphers()); } + if (ssl.getEnabledProtocols() != null) { + factory.setIncludeProtocols(ssl.getEnabledProtocols()); + } configureSslTrustStore(factory, ssl); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index e72ab2df118..6292dffbb35 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -315,22 +315,17 @@ public class TomcatEmbeddedServletContainerFactory */ protected void configureSsl(AbstractHttp11JsseProtocol protocol, Ssl ssl) { protocol.setSSLEnabled(true); - //Set the default TLS protocol protocol.setSslProtocol(ssl.getProtocol()); - - //Assign the supported protocols, if provided - if (ssl.getProtocols() != null) { - String protocols = StringUtils.arrayToCommaDelimitedString(ssl.getProtocols()); - protocol.setProperty("sslEnabledProtocols", protocols); - } - configureSslClientAuth(protocol, ssl); protocol.setKeystorePass(ssl.getKeyStorePassword()); protocol.setKeyPass(ssl.getKeyPassword()); protocol.setKeyAlias(ssl.getKeyAlias()); configureSslKeyStore(protocol, ssl); - String ciphers = StringUtils.arrayToCommaDelimitedString(ssl.getCiphers()); - protocol.setCiphers(ciphers); + protocol.setCiphers(StringUtils.arrayToCommaDelimitedString(ssl.getCiphers())); + if (ssl.getEnabledProtocols() != null) { + protocol.setProperty("sslEnabledProtocols", + StringUtils.arrayToCommaDelimitedString(ssl.getEnabledProtocols())); + } configureSslTrustStore(protocol, ssl); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java index abb6d93bf15..05b97dd36f8 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java @@ -258,14 +258,15 @@ public class UndertowEmbeddedServletContainerFactory SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol()); sslContext.init(getKeyManagers(), getTrustManagers(), null); builder.addHttpsListener(port, getListenAddress(), sslContext); - builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, getSslClientAuthMode(ssl)); - - //Configure the supported TLS protocols and Cipher suites - if (ssl.getProtocols() != null) { - builder.setSocketOption(Options.SSL_ENABLED_PROTOCOLS, Sequence.of(ssl.getProtocols())); + builder.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, + getSslClientAuthMode(ssl)); + if (ssl.getEnabledProtocols() != null) { + builder.setSocketOption(Options.SSL_ENABLED_PROTOCOLS, + Sequence.of(ssl.getEnabledProtocols())); } if (ssl.getCiphers() != null) { - builder.setSocketOption(Options.SSL_ENABLED_CIPHER_SUITES, Sequence.of(ssl.getCiphers())); + builder.setSocketOption(Options.SSL_ENABLED_CIPHER_SUITES, + Sequence.of(ssl.getCiphers())); } } catch (NoSuchAlgorithmException ex) { diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index 15dc5a73c30..88ed56ebcd7 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -530,7 +530,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { } private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore, - String trustStore, String[] protocols, String[] ciphers) { + String trustStore, String[] supportedProtocols, String[] ciphers) { Ssl ssl = new Ssl(); ssl.setClientAuth(clientAuth); if (keyPassword != null) { @@ -549,17 +549,12 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { if (ciphers != null) { ssl.setCiphers(ciphers); } - if (protocols != null) { - ssl.setProtocols(protocols); + if (supportedProtocols != null) { + ssl.setEnabledProtocols(supportedProtocols); } return ssl; } - /** - * @see - * SunJSSE supported Cipher Suites - */ protected void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, String[] ciphers) throws Exception { AbstractEmbeddedServletContainerFactory factory = getFactory(); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java index 56854e1804f..94799c0fb5c 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactoryTests.java @@ -159,7 +159,7 @@ public class JettyEmbeddedServletContainerFactoryTests ssl.setKeyStorePassword("secret"); ssl.setKeyPassword("password"); ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); - ssl.setProtocols(new String[]{ "TLSv1.1", "TLSv1.2" }); + ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); JettyEmbeddedServletContainerFactory factory = getFactory(); factory.setSsl(ssl); @@ -184,7 +184,7 @@ public class JettyEmbeddedServletContainerFactoryTests ssl.setKeyStorePassword("secret"); ssl.setKeyPassword("password"); ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); - ssl.setProtocols(new String[]{ "TLSv1.1" }); + ssl.setEnabledProtocols(new String[] { "TLSv1.1" }); JettyEmbeddedServletContainerFactory factory = getFactory(); factory.setSsl(ssl); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java index b0a5a13654f..857e5385b3d 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactoryTests.java @@ -268,7 +268,7 @@ public class TomcatEmbeddedServletContainerFactoryTests Ssl ssl = new Ssl(); ssl.setKeyStore("test.jks"); ssl.setKeyStorePassword("secret"); - ssl.setProtocols(new String[]{ "TLSv1.1", "TLSv1.2" }); + ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); TomcatEmbeddedServletContainerFactory factory = getFactory(); @@ -291,7 +291,7 @@ public class TomcatEmbeddedServletContainerFactoryTests Ssl ssl = new Ssl(); ssl.setKeyStore("test.jks"); ssl.setKeyStorePassword("secret"); - ssl.setProtocols(new String[]{"TLSv1.2"}); + ssl.setEnabledProtocols(new String[] { "TLSv1.2" }); ssl.setCiphers(new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "BRAVO" }); TomcatEmbeddedServletContainerFactory factory = getFactory();