diff --git a/src/main/java/examples/NetExamples.java b/src/main/java/examples/NetExamples.java old mode 100644 new mode 100755 index fad4236746b..817c0e33b00 --- a/src/main/java/examples/NetExamples.java +++ b/src/main/java/examples/NetExamples.java @@ -507,12 +507,15 @@ public void example44(Vertx vertx, JksOptions keyStoreOptions) { NetServer server = vertx.createNetServer(options); } + /** + * The default protocols are defined in {@link io.vertx.core.net.TCPSSLOptions#DEFAULT_ENABLED_SECURE_TRANSPORT_PROTOCOLS}, but you can change them. + */ public void example45(Vertx vertx, JksOptions keyStoreOptions) { NetServerOptions options = new NetServerOptions(). setSsl(true). setKeyStoreOptions(keyStoreOptions). - addEnabledSecureTransportProtocol("TLSv1.1"). - addEnabledSecureTransportProtocol("TLSv1.2"); + removeEnabledSecureTransportProtocol("TLSv1"). + addEnabledSecureTransportProtocol("TLSv1.3"); NetServer server = vertx.createNetServer(options); } diff --git a/src/main/java/io/vertx/core/http/HttpClientOptions.java b/src/main/java/io/vertx/core/http/HttpClientOptions.java old mode 100644 new mode 100755 index ca2ca65d996..7846fe51786 --- a/src/main/java/io/vertx/core/http/HttpClientOptions.java +++ b/src/main/java/io/vertx/core/http/HttpClientOptions.java @@ -391,6 +391,11 @@ public HttpClientOptions addEnabledSecureTransportProtocol(final String protocol return this; } + @Override + public HttpClientOptions removeEnabledSecureTransportProtocol(String protocol) { + return (HttpClientOptions) super.removeEnabledSecureTransportProtocol(protocol); + } + @Override public HttpClientOptions setTcpFastOpen(boolean tcpFastOpen) { return (HttpClientOptions) super.setTcpFastOpen(tcpFastOpen); diff --git a/src/main/java/io/vertx/core/http/HttpServerOptions.java b/src/main/java/io/vertx/core/http/HttpServerOptions.java old mode 100644 new mode 100755 index 1c2f0e77327..00bc833a8fe --- a/src/main/java/io/vertx/core/http/HttpServerOptions.java +++ b/src/main/java/io/vertx/core/http/HttpServerOptions.java @@ -323,6 +323,11 @@ public HttpServerOptions addEnabledSecureTransportProtocol(final String protocol return this; } + @Override + public HttpServerOptions removeEnabledSecureTransportProtocol(String protocol) { + return (HttpServerOptions) super.removeEnabledSecureTransportProtocol(protocol); + } + @Override public HttpServerOptions setTcpFastOpen(boolean tcpFastOpen) { return (HttpServerOptions) super.setTcpFastOpen(tcpFastOpen); diff --git a/src/main/java/io/vertx/core/net/ClientOptionsBase.java b/src/main/java/io/vertx/core/net/ClientOptionsBase.java old mode 100644 new mode 100755 index f048e876978..35360592b8c --- a/src/main/java/io/vertx/core/net/ClientOptionsBase.java +++ b/src/main/java/io/vertx/core/net/ClientOptionsBase.java @@ -336,6 +336,11 @@ public ClientOptionsBase addEnabledSecureTransportProtocol(String protocol) { return (ClientOptionsBase) super.addEnabledSecureTransportProtocol(protocol); } + @Override + public ClientOptionsBase removeEnabledSecureTransportProtocol(String protocol) { + return (ClientOptionsBase) super.removeEnabledSecureTransportProtocol(protocol); + } + @Override public ClientOptionsBase setTcpFastOpen(boolean tcpFastOpen) { return (ClientOptionsBase) super.setTcpFastOpen(tcpFastOpen); diff --git a/src/main/java/io/vertx/core/net/NetClientOptions.java b/src/main/java/io/vertx/core/net/NetClientOptions.java old mode 100644 new mode 100755 index a26487f60ef..5e0102033e2 --- a/src/main/java/io/vertx/core/net/NetClientOptions.java +++ b/src/main/java/io/vertx/core/net/NetClientOptions.java @@ -204,6 +204,11 @@ public NetClientOptions addEnabledSecureTransportProtocol(final String protocol) return this; } + @Override + public NetClientOptions removeEnabledSecureTransportProtocol(String protocol) { + return (NetClientOptions) super.removeEnabledSecureTransportProtocol(protocol); + } + @Override public NetClientOptions setUseAlpn(boolean useAlpn) { return (NetClientOptions) super.setUseAlpn(useAlpn); diff --git a/src/main/java/io/vertx/core/net/NetServerOptions.java b/src/main/java/io/vertx/core/net/NetServerOptions.java old mode 100644 new mode 100755 index f04c821ac92..cb43d72a958 --- a/src/main/java/io/vertx/core/net/NetServerOptions.java +++ b/src/main/java/io/vertx/core/net/NetServerOptions.java @@ -245,6 +245,11 @@ public NetServerOptions addEnabledSecureTransportProtocol(final String protocol) return this; } + @Override + public NetServerOptions removeEnabledSecureTransportProtocol(String protocol) { + return (NetServerOptions) super.removeEnabledSecureTransportProtocol(protocol); + } + @Override public NetServerOptions setTcpFastOpen(boolean tcpFastOpen) { return (NetServerOptions) super.setTcpFastOpen(tcpFastOpen); diff --git a/src/main/java/io/vertx/core/net/TCPSSLOptions.java b/src/main/java/io/vertx/core/net/TCPSSLOptions.java old mode 100644 new mode 100755 index 3bd59260576..b46a3743a83 --- a/src/main/java/io/vertx/core/net/TCPSSLOptions.java +++ b/src/main/java/io/vertx/core/net/TCPSSLOptions.java @@ -66,6 +66,13 @@ public abstract class TCPSSLOptions extends NetworkOptions { */ public static final SSLEngineOptions DEFAULT_SSL_ENGINE = null; + /** + * The default ENABLED_SECURE_TRANSPORT_PROTOCOLS value = { "SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2" } + * + * SSLv3 is NOT enabled due to POODLE vulnerability http://en.wikipedia.org/wiki/POODLE + */ + public static final String[] DEFAULT_ENABLED_SECURE_TRANSPORT_PROTOCOLS = {"SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2"}; + /** * The default TCP_FASTOPEN value = false */ @@ -89,12 +96,12 @@ public abstract class TCPSSLOptions extends NetworkOptions { private boolean ssl; private KeyCertOptions keyCertOptions; private TrustOptions trustOptions; - private Set enabledCipherSuites = new LinkedHashSet<>(); + private Set enabledCipherSuites; private ArrayList crlPaths; private ArrayList crlValues; private boolean useAlpn; private SSLEngineOptions sslEngineOptions; - private Set enabledSecureTransportProtocols = new LinkedHashSet<>(); + private Set enabledSecureTransportProtocols; private boolean tcpFastOpen; private boolean tcpCork; private boolean tcpQuickAck; @@ -141,6 +148,7 @@ public TCPSSLOptions(TCPSSLOptions other) { public TCPSSLOptions(JsonObject json) { super(json); init(); + enabledSecureTransportProtocols.clear(); TCPSSLOptionsConverter.fromJson(json ,this); } @@ -162,10 +170,12 @@ private void init() { usePooledBuffers = DEFAULT_USE_POOLED_BUFFERS; idleTimeout = DEFAULT_IDLE_TIMEOUT; ssl = DEFAULT_SSL; + enabledCipherSuites = new LinkedHashSet<>(); crlPaths = new ArrayList<>(); crlValues = new ArrayList<>(); useAlpn = DEFAULT_USE_ALPN; sslEngineOptions = DEFAULT_SSL_ENGINE; + enabledSecureTransportProtocols = new LinkedHashSet<>(Arrays.asList(DEFAULT_ENABLED_SECURE_TRANSPORT_PROTOCOLS)); tcpFastOpen = DEFAULT_TCP_FAST_OPEN; tcpCork = DEFAULT_TCP_CORK; tcpQuickAck = DEFAULT_TCP_QUICKACK; @@ -555,7 +565,7 @@ public TCPSSLOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptio /** * Add an enabled SSL/TLS protocols, appended to the ordered protocols. * - * @param protocol the SSL/TLS protocol do enabled + * @param protocol the SSL/TLS protocol to enable * @return a reference to this, so the API can be used fluently */ public TCPSSLOptions addEnabledSecureTransportProtocol(String protocol) { @@ -563,6 +573,17 @@ public TCPSSLOptions addEnabledSecureTransportProtocol(String protocol) { return this; } + /** + * Removes an enabled SSL/TLS protocol from the ordered protocols. + * + * @param protocol the SSL/TLS protocol to disable + * @return a reference to this, so the API can be used fluently + */ + public TCPSSLOptions removeEnabledSecureTransportProtocol(String protocol) { + enabledSecureTransportProtocols.remove(protocol); + return this; + } + /** * @return wether {@code TCP_FASTOPEN} option is enabled */ @@ -619,7 +640,7 @@ public TCPSSLOptions setTcpQuickAck(boolean tcpQuickAck) { * @return the enabled protocols */ public Set getEnabledSecureTransportProtocols() { - return enabledSecureTransportProtocols; + return new LinkedHashSet<>(enabledSecureTransportProtocols); } @Override diff --git a/src/main/java/io/vertx/core/net/impl/SSLHelper.java b/src/main/java/io/vertx/core/net/impl/SSLHelper.java old mode 100644 new mode 100755 index 42cf751e5fb..51b1583d73e --- a/src/main/java/io/vertx/core/net/impl/SSLHelper.java +++ b/src/main/java/io/vertx/core/net/impl/SSLHelper.java @@ -119,9 +119,6 @@ public static SSLEngineOptions resolveEngineOptions(TCPSSLOptions options) { private static final Logger log = LoggerFactory.getLogger(SSLHelper.class); - // Make sure SSLv3 is NOT enabled due to POODLE vulnerability http://en.wikipedia.org/wiki/POODLE - private static final String[] DEFAULT_ENABLED_PROTOCOLS = {"SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2"}; - private boolean ssl; private boolean sni; private KeyCertOptions keyCertOptions; @@ -411,13 +408,10 @@ public void configureEngine(SSLEngine engine, String serverName) { engine.setEnabledCipherSuites(toUse); } engine.setUseClientMode(client); - Set protocols = new LinkedHashSet<>(Arrays.asList(DEFAULT_ENABLED_PROTOCOLS)); - protocols.retainAll(Arrays.asList(engine.getEnabledProtocols())); - if (enabledProtocols != null && !enabledProtocols.isEmpty() && !protocols.isEmpty()) { - protocols.retainAll(enabledProtocols); - if (protocols.isEmpty()) { - log.warn("no SSL/TLS protocols are enabled due to configuration restrictions"); - } + Set protocols = new LinkedHashSet<>(enabledProtocols); + protocols.retainAll(Arrays.asList(engine.getSupportedProtocols())); + if (protocols.isEmpty()) { + log.warn("no SSL/TLS protocols are enabled due to configuration restrictions"); } engine.setEnabledProtocols(protocols.toArray(new String[protocols.size()])); if (!client) { diff --git a/src/test/java/io/vertx/test/core/HttpTLSTest.java b/src/test/java/io/vertx/test/core/HttpTLSTest.java old mode 100644 new mode 100755 index 3dd52fa31c7..883473b5399 --- a/src/test/java/io/vertx/test/core/HttpTLSTest.java +++ b/src/test/java/io/vertx/test/core/HttpTLSTest.java @@ -295,7 +295,7 @@ public void testTLSInvalidProtocolVersion() throws Exception { @Test // Specify some non matching TLS protocols public void testTLSNonMatchingProtocolVersions() throws Exception { - testTLS(Cert.NONE, Trust.NONE, Cert.SERVER_JKS, Trust.NONE).clientTrustAll().serverEnabledSecureTransportProtocol(new String[]{"TLSv1.2"}).clientEnabledSecureTransportProtocol(new String[]{"SSLv2Hello"}).fail(); + testTLS(Cert.NONE, Trust.NONE, Cert.SERVER_JKS, Trust.NONE).clientTrustAll().serverEnabledSecureTransportProtocol(new String[]{"TLSv1.2"}).clientEnabledSecureTransportProtocol(new String[]{"SSLv2Hello", "TLSv1.1"}).fail(); } @Test @@ -1051,8 +1051,11 @@ TLSTest run(boolean shouldPass) { for (String suite: clientEnabledCipherSuites) { options.addEnabledCipherSuite(suite); } - for (String protocols: clientEnabledSecureTransportProtocol) { - options.addEnabledSecureTransportProtocol(protocols); + if(clientEnabledSecureTransportProtocol.length > 0) { + options.getEnabledSecureTransportProtocols().forEach(options::removeEnabledSecureTransportProtocol); + } + for (String protocol : clientEnabledSecureTransportProtocol) { + options.addEnabledSecureTransportProtocol(protocol); } if (proxyType != null) { ProxyOptions proxyOptions; @@ -1085,8 +1088,11 @@ TLSTest run(boolean shouldPass) { for (String suite: serverEnabledCipherSuites) { serverOptions.addEnabledCipherSuite(suite); } - for (String protocols: serverEnabledSecureTransportProtocol) { - serverOptions.addEnabledSecureTransportProtocol(protocols); + if(serverEnabledSecureTransportProtocol.length > 0) { + serverOptions.getEnabledSecureTransportProtocols().forEach(serverOptions::removeEnabledSecureTransportProtocol); + } + for (String protocol : serverEnabledSecureTransportProtocol) { + serverOptions.addEnabledSecureTransportProtocol(protocol); } server = createHttpServer(serverOptions.setPort(4043)); server.connectionHandler(conn -> complete()); diff --git a/src/test/java/io/vertx/test/core/NetTest.java b/src/test/java/io/vertx/test/core/NetTest.java old mode 100644 new mode 100755 index ae6871ebf87..6a689bd4b0c --- a/src/test/java/io/vertx/test/core/NetTest.java +++ b/src/test/java/io/vertx/test/core/NetTest.java @@ -1553,6 +1553,9 @@ void run(boolean shouldPass) { for (String suite: enabledCipherSuites) { options.addEnabledCipherSuite(suite); } + if(enabledSecureTransportProtocols.length > 0) { + options.getEnabledSecureTransportProtocols().forEach(options::removeEnabledSecureTransportProtocol); + } for (String protocol : enabledSecureTransportProtocols) { options.addEnabledSecureTransportProtocol(protocol); } @@ -1619,6 +1622,9 @@ void run(boolean shouldPass) { for (String suite: enabledCipherSuites) { clientOptions.addEnabledCipherSuite(suite); } + if(enabledSecureTransportProtocols.length > 0) { + clientOptions.getEnabledSecureTransportProtocols().forEach(clientOptions::removeEnabledSecureTransportProtocol); + } for (String protocol : enabledSecureTransportProtocols) { clientOptions.addEnabledSecureTransportProtocol(protocol); } diff --git a/src/test/java/io/vertx/test/core/SSLHelperTest.java b/src/test/java/io/vertx/test/core/SSLHelperTest.java old mode 100644 new mode 100755 index 7857c0844c8..dabb3c64282 --- a/src/test/java/io/vertx/test/core/SSLHelperTest.java +++ b/src/test/java/io/vertx/test/core/SSLHelperTest.java @@ -114,19 +114,17 @@ public void testPreserveEnabledCipherSuitesOrder() throws Exception { @Test public void testPreserveEnabledSecureTransportProtocolOrder() throws Exception { - String[] protocols = {"SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2"}; HttpServerOptions options = new HttpServerOptions(); - for (String protocol : protocols) { - options.addEnabledSecureTransportProtocol(protocol); - } - assertEquals(new ArrayList<>(options.getEnabledSecureTransportProtocols()), Arrays.asList(protocols)); - assertEquals(new ArrayList<>(new HttpServerOptions(options).getEnabledSecureTransportProtocols()), Arrays.asList(protocols)); + List expectedProtocols = new ArrayList<>(options.getEnabledSecureTransportProtocols()); + + options.removeEnabledSecureTransportProtocol("TLSv1"); + options.addEnabledSecureTransportProtocol("SSLv3"); + expectedProtocols.remove("TLSv1"); + expectedProtocols.add("SSLv3"); + + assertEquals(new ArrayList<>(options.getEnabledSecureTransportProtocols()), expectedProtocols); + assertEquals(new ArrayList<>(new HttpServerOptions(options).getEnabledSecureTransportProtocols()), expectedProtocols); JsonObject json = options.toJson(); - assertEquals(new ArrayList<>(new HttpServerOptions(json).getEnabledSecureTransportProtocols()), Arrays.asList(protocols)); - SSLHelper helper = new SSLHelper(options, Cert.SERVER_JKS.get(), null); - List engineProtocols = Arrays.asList(helper.createEngine((VertxInternal) vertx).getEnabledProtocols()); - List expectedProtocols = new ArrayList<>(Arrays.asList(protocols)); - expectedProtocols.retainAll(engineProtocols); - assertEquals(engineProtocols, expectedProtocols); + assertEquals(new ArrayList<>(new HttpServerOptions(json).getEnabledSecureTransportProtocols()), expectedProtocols); } }