diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java index 1f010f21b0..a4b2961141 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java @@ -296,6 +296,11 @@ public abstract class ReferenceCountedOpenSslContext extends SslContext implemen int options = SSLContext.getOptions(ctx) | SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | + // Disable TLSv1 and TLSv1.1 by default as these are not considered secure anymore + // and the JDK is doing the same: + // https://www.oracle.com/java/technologies/javase/8u291-relnotes.html + SSL.SSL_OP_NO_TLSv1 | + SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_CIPHER_SERVER_PREFERENCE | diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java index a87f2a61fe..71849042cc 100644 --- a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java @@ -38,6 +38,7 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLParameters; import javax.net.ssl.X509ExtendedKeyManager; import java.net.Socket; @@ -72,6 +73,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @RunWith(Parameterized.class) @@ -1388,6 +1390,59 @@ public class OpenSslEngineTest extends SSLEngineTest { super.testSessionLocalWhenNonMutualWithoutKeyManager(); } + @Test + public void testDefaultTLS1NotAcceptedByDefaultServer() throws Exception { + testDefaultTLS1NotAcceptedByDefault(null, PROTOCOL_TLS_V1); + } + + @Test + public void testDefaultTLS11NotAcceptedByDefaultServer() throws Exception { + testDefaultTLS1NotAcceptedByDefault(null, PROTOCOL_TLS_V1_1); + } + + @Test + public void testDefaultTLS1NotAcceptedByDefaultClient() throws Exception { + testDefaultTLS1NotAcceptedByDefault(PROTOCOL_TLS_V1, null); + } + + @Test + public void testDefaultTLS11NotAcceptedByDefaultClient() throws Exception { + testDefaultTLS1NotAcceptedByDefault(PROTOCOL_TLS_V1_1, null); + } + + private void testDefaultTLS1NotAcceptedByDefault(String clientProtocol, String serverProtocol) throws Exception { + SslContextBuilder clientCtxBuilder = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .sslProvider(sslClientProvider()) + .sslContextProvider(clientSslContextProvider()); + if (clientProtocol != null) { + clientCtxBuilder.protocols(clientProtocol); + } + clientSslCtx = wrapContext(clientCtxBuilder.build()); + SelfSignedCertificate ssc = new SelfSignedCertificate(); + + SslContextBuilder serverCtxBuilder = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .sslProvider(sslServerProvider()) + .sslContextProvider(serverSslContextProvider()); + if (serverProtocol != null) { + serverCtxBuilder.protocols(serverProtocol); + } + serverSslCtx = wrapContext(serverCtxBuilder.build()); + SSLEngine client = wrapEngine(clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT)); + SSLEngine server = wrapEngine(serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT)); + + try { + handshake(client, server); + fail(); + } catch (SSLHandshakeException expected) { + // expected + } finally { + cleanupClientSslEngine(client); + cleanupServerSslEngine(server); + ssc.delete(); + } + } + @Override protected SslProvider sslClientProvider() { return SslProvider.OPENSSL;