diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java index 5f43e6c902..895e0948b4 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java @@ -40,6 +40,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import org.apache.hc.client5.http.config.TlsConfig; import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.http.ssl.HostnameVerificationPolicy; @@ -50,6 +51,7 @@ import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.impl.bootstrap.HttpServer; import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap; +import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.io.CloseMode; import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.TrustStrategy; @@ -359,6 +361,52 @@ private void testWeakCipherDisabledByDefault(final String cipherSuite) throws Ex } } + @Test + void testTlsConfigSupportedProtocolsAndCipherSuites() throws Exception { + // @formatter:off + this.server = ServerBootstrap.bootstrap() + .setLocalAddress(InetAddress.getLoopbackAddress()) + .setSslContext(SSLTestContexts.createServerSSLContext()) + .setSslSetupHandler(sslParameters -> sslParameters.setProtocols(new String[] {"TLSv1.2"})) + .setRequestRouter((r, c) -> null) + .create(); + // @formatter:on + this.server.start(); + + final HttpClientContext context = HttpClientContext.create(); + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( + SSLTestContexts.createClientSSLContext()); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + + final TlsConfig tls13Only = TlsConfig.custom() + .setSupportedProtocols(TLS.V_1_3) + .build(); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + Assertions.assertThrows(IOException.class, () -> + tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), + tls13Only, + context)); + } + + final String cipherSuite = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + final TlsConfig singleCipherSuite = TlsConfig.custom() + .setSupportedCipherSuites(cipherSuite) + .build(); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), + singleCipherSuite, + context)) { + Assertions.assertEquals(cipherSuite, sslSocket.getSession().getCipherSuite()); + } + } + } + @Test void testHostnameVerificationClient() throws Exception { // @formatter:off diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java index 0aba6a75ae..40fde1b6fd 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java @@ -224,14 +224,21 @@ private void executeHandshake( final SSLSocket upgradedSocket, final String target, final Object attachment) throws IOException { + final TlsConfig tlsConfig = attachment instanceof TlsConfig ? (TlsConfig) attachment : TlsConfig.DEFAULT; final SSLParameters sslParameters = upgradedSocket.getSSLParameters(); + final String[] supportedProtocols = tlsConfig.getSupportedProtocols(); if (supportedProtocols != null) { sslParameters.setProtocols(supportedProtocols); + } else if (this.supportedProtocols != null) { + sslParameters.setProtocols(this.supportedProtocols); } else { sslParameters.setProtocols(TLS.excludeWeak(upgradedSocket.getEnabledProtocols())); } + final String[] supportedCipherSuites = tlsConfig.getSupportedCipherSuites(); if (supportedCipherSuites != null) { sslParameters.setCipherSuites(supportedCipherSuites); + } else if (this.supportedCipherSuites != null) { + sslParameters.setCipherSuites(this.supportedCipherSuites); } else { sslParameters.setCipherSuites(TlsCiphers.excludeWeak(upgradedSocket.getEnabledCipherSuites())); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java index c06127cb4b..14b8ba0193 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java @@ -304,13 +304,19 @@ private void executeHandshake( final Object attachment, final HttpContext context) throws IOException { final TlsConfig tlsConfig = attachment instanceof TlsConfig ? (TlsConfig) attachment : TlsConfig.DEFAULT; + final String[] supportedProtocols = tlsConfig.getSupportedProtocols(); if (supportedProtocols != null) { sslsock.setEnabledProtocols(supportedProtocols); + } else if (this.supportedProtocols != null) { + sslsock.setEnabledProtocols(this.supportedProtocols); } else { sslsock.setEnabledProtocols(TLS.excludeWeak(sslsock.getEnabledProtocols())); } + final String[] supportedCipherSuites = tlsConfig.getSupportedCipherSuites(); if (supportedCipherSuites != null) { sslsock.setEnabledCipherSuites(supportedCipherSuites); + } else if (this.supportedCipherSuites != null) { + sslsock.setEnabledCipherSuites(this.supportedCipherSuites); } else { sslsock.setEnabledCipherSuites(TlsCiphers.excludeWeak(sslsock.getEnabledCipherSuites())); }