diff --git a/docs/source/manual/configuration.rst b/docs/source/manual/configuration.rst index 43266048e9f..1aae0feaefa 100644 --- a/docs/source/manual/configuration.rst +++ b/docs/source/manual/configuration.rst @@ -470,8 +470,8 @@ validatePeers false Whether or not implemented. supportedProtocols (none) A list of protocols (e.g., ``SSLv3``, ``TLSv1``) which are supported. All other protocols will be refused. -excludedProtocols ["SSLv2Hello", "SSLv3", A list of protocols (e.g., ``SSLv3``, ``TLSv1``) which are excluded. These - "TLSv1", "TLSv1.1"] protocols will be refused. +excludedProtocols ["SSL.*", "TLSv1", "TLSv1\\.1"] A list of protocols (e.g., ``SSLv3``, ``TLSv1``) which are excluded. These + protocols will be refused. supportedCipherSuites (none) A list of cipher suites (e.g., ``TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256``) which are supported. All other cipher suites will be refused. excludedCipherSuites (none) A list of cipher suites (e.g., ``TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256``) which diff --git a/dropwizard-jetty/src/main/java/io/dropwizard/jetty/HttpsConnectorFactory.java b/dropwizard-jetty/src/main/java/io/dropwizard/jetty/HttpsConnectorFactory.java index 1aa01291e97..85852bc0591 100644 --- a/dropwizard-jetty/src/main/java/io/dropwizard/jetty/HttpsConnectorFactory.java +++ b/dropwizard-jetty/src/main/java/io/dropwizard/jetty/HttpsConnectorFactory.java @@ -182,7 +182,7 @@ * * * {@code excludedProtocols} - * ["SSLv3", "TLSv1", "TLSv1.1"] + * ["SSL.*", "TLSv1", "TLSv1\.1"] * * A list of protocols (e.g., {@code SSLv3}, {@code TLSv1}) which are excluded. These * protocols will be refused. @@ -287,7 +287,7 @@ public class HttpsConnectorFactory extends HttpConnectorFactory { private List supportedProtocols; @Nullable - private List excludedProtocols = Arrays.asList("SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1"); + private List excludedProtocols = Arrays.asList("SSL.*", "TLSv1", "TLSv1\\.1"); @Nullable private List supportedCipherSuites; diff --git a/dropwizard-jetty/src/test/java/io/dropwizard/jetty/HttpsConnectorFactoryTest.java b/dropwizard-jetty/src/test/java/io/dropwizard/jetty/HttpsConnectorFactoryTest.java index c64b7cc63a1..014efca45ab 100644 --- a/dropwizard-jetty/src/test/java/io/dropwizard/jetty/HttpsConnectorFactoryTest.java +++ b/dropwizard-jetty/src/test/java/io/dropwizard/jetty/HttpsConnectorFactoryTest.java @@ -90,20 +90,51 @@ void testParsingConfiguration() throws Exception { } @Test - void testSupportedProtocols() { - List supportedProtocols = Arrays.asList("SSLv3", "TLS1"); + void testSupportedProtocols() throws Exception { + List supportedProtocols = Arrays.asList("SSLv3", "TLSv1"); HttpsConnectorFactory factory = new HttpsConnectorFactory(); factory.setKeyStorePassword("password"); // necessary to avoid a prompt for a password factory.setSupportedProtocols(supportedProtocols); + factory.setExcludedProtocols(Collections.emptyList()); SslContextFactory sslContextFactory = factory.configureSslContextFactory(new SslContextFactory.Server()); assertThat(Arrays.asList(sslContextFactory.getIncludeProtocols())).isEqualTo(supportedProtocols); + + sslContextFactory.start(); + try { + assertThat(sslContextFactory.newSSLEngine().getEnabledProtocols()) + .containsExactlyElementsOf(supportedProtocols); + } finally { + sslContextFactory.stop(); + } + } + + @Test + void testSupportedProtocolsWithWildcards() throws Exception { + List supportedProtocols = Arrays.asList("SSL.*", "TLSv1\\.[01]"); + + HttpsConnectorFactory factory = new HttpsConnectorFactory(); + factory.setKeyStorePassword("password"); // necessary to avoid a prompt for a password + factory.setSupportedProtocols(supportedProtocols); + factory.setExcludedProtocols(Collections.emptyList()); + + SslContextFactory sslContextFactory = factory.configureSslContextFactory(new SslContextFactory.Server()); + assertThat(Arrays.asList(sslContextFactory.getIncludeProtocols())).isEqualTo(supportedProtocols); + + sslContextFactory.start(); + try { + assertThat(sslContextFactory.newSSLEngine().getEnabledProtocols()) + .contains("SSLv3", "TLSv1.1") + .doesNotContain("TLSv1.2", "TLSv1.3"); + } finally { + sslContextFactory.stop(); + } } @Test - void testExcludedProtocols() { - List excludedProtocols = Arrays.asList("SSLv3", "TLS1"); + void testExcludedProtocols() throws Exception { + List excludedProtocols = Arrays.asList("SSLv3", "TLSv1"); HttpsConnectorFactory factory = new HttpsConnectorFactory(); factory.setKeyStorePassword("password"); // necessary to avoid a prompt for a password @@ -111,6 +142,37 @@ void testExcludedProtocols() { SslContextFactory sslContextFactory = factory.configureSslContextFactory(new SslContextFactory.Server()); assertThat(Arrays.asList(sslContextFactory.getExcludeProtocols())).isEqualTo(excludedProtocols); + + sslContextFactory.start(); + try { + assertThat(sslContextFactory.newSSLEngine().getEnabledProtocols()) + .contains("TLSv1.1", "TLSv1.2") + .doesNotContain("SSLv3", "TLSv1"); + } finally { + sslContextFactory.stop(); + } + } + + @Test + void testExcludedProtocolsWithWildcards() throws Exception { + List excludedProtocols = Arrays.asList("SSL.*", "TLSv1(\\.[01])?"); + + HttpsConnectorFactory factory = new HttpsConnectorFactory(); + factory.setKeyStorePassword("password"); // necessary to avoid a prompt for a password + factory.setExcludedProtocols(excludedProtocols); + + SslContextFactory sslContextFactory = factory.configureSslContextFactory(new SslContextFactory.Server()); + assertThat(Arrays.asList(sslContextFactory.getExcludeProtocols())).isEqualTo(excludedProtocols); + + sslContextFactory.start(); + try { + assertThat(sslContextFactory.newSSLEngine().getEnabledProtocols()) + .contains("TLSv1.2") + .allSatisfy(protocol -> assertThat(protocol).doesNotStartWith("SSL")) + .doesNotContain("TLSv1"); + } finally { + sslContextFactory.stop(); + } } @Test @@ -125,7 +187,8 @@ void testDefaultExcludedProtocols() throws Exception { try { assertThat(sslContextFactory.newSSLEngine().getEnabledProtocols()) .doesNotContainAnyElementsOf(factory.getExcludedProtocols()) - .allSatisfy(protocol -> assertThat(protocol).doesNotStartWith("SSL")); + .allSatisfy(protocol -> assertThat(protocol).doesNotStartWith("SSL")) + .doesNotContain("TLSv1", "TLSv1.1"); } finally { sslContextFactory.stop(); }