| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.client; |
| |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.TimeUnit; |
| |
| import org.eclipse.jetty.http.HttpScheme; |
| import org.eclipse.jetty.server.Handler; |
| import org.eclipse.jetty.server.Server; |
| import org.eclipse.jetty.server.ServerConnector; |
| import org.eclipse.jetty.util.ssl.SslContextFactory; |
| import org.eclipse.jetty.util.thread.QueuedThreadPool; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| public class HttpClientTLSTest |
| { |
| private Server server; |
| private ServerConnector connector; |
| private HttpClient client; |
| |
| private void startServer(SslContextFactory sslContextFactory, Handler handler) throws Exception |
| { |
| QueuedThreadPool serverThreads = new QueuedThreadPool(); |
| serverThreads.setName("server"); |
| server = new Server(serverThreads); |
| |
| connector = new ServerConnector(server, sslContextFactory); |
| server.addConnector(connector); |
| |
| server.setHandler(handler); |
| server.start(); |
| } |
| |
| private void startClient(SslContextFactory sslContextFactory) throws Exception |
| { |
| QueuedThreadPool clientThreads = new QueuedThreadPool(); |
| clientThreads.setName("client"); |
| client = new HttpClient(sslContextFactory); |
| client.setExecutor(clientThreads); |
| client.start(); |
| } |
| |
| private SslContextFactory createSslContextFactory() |
| { |
| SslContextFactory sslContextFactory = new SslContextFactory(); |
| sslContextFactory.setEndpointIdentificationAlgorithm(""); |
| sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); |
| sslContextFactory.setKeyStorePassword("storepwd"); |
| sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); |
| sslContextFactory.setTrustStorePassword("storepwd"); |
| return sslContextFactory; |
| } |
| |
| @After |
| public void dispose() throws Exception |
| { |
| if (client != null) |
| client.stop(); |
| if (server != null) |
| server.stop(); |
| } |
| |
| @Test |
| public void testNoCommonTLSProtocol() throws Exception |
| { |
| SslContextFactory serverTLSFactory = createSslContextFactory(); |
| serverTLSFactory.setIncludeProtocols("TLSv1.2"); |
| startServer(serverTLSFactory, new EmptyServerHandler()); |
| |
| SslContextFactory clientTLSFactory = createSslContextFactory(); |
| clientTLSFactory.setIncludeProtocols("TLSv1.1"); |
| startClient(clientTLSFactory); |
| |
| try |
| { |
| client.newRequest("localhost", connector.getLocalPort()) |
| .scheme(HttpScheme.HTTPS.asString()) |
| .timeout(5, TimeUnit.SECONDS) |
| .send(); |
| Assert.fail(); |
| } |
| catch (ExecutionException x) |
| { |
| // Expected. |
| } |
| } |
| |
| @Test |
| public void testNoCommonTLSCiphers() throws Exception |
| { |
| SslContextFactory serverTLSFactory = createSslContextFactory(); |
| serverTLSFactory.setIncludeCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA"); |
| startServer(serverTLSFactory, new EmptyServerHandler()); |
| |
| SslContextFactory clientTLSFactory = createSslContextFactory(); |
| clientTLSFactory.setExcludeCipherSuites(".*_SHA$"); |
| startClient(clientTLSFactory); |
| |
| try |
| { |
| client.newRequest("localhost", connector.getLocalPort()) |
| .scheme(HttpScheme.HTTPS.asString()) |
| .timeout(5, TimeUnit.SECONDS) |
| .send(); |
| Assert.fail(); |
| } |
| catch (ExecutionException x) |
| { |
| // Expected. |
| } |
| } |
| |
| @Test |
| public void testMismatchBetweenTLSProtocolAndTLSCiphersOnServer() throws Exception |
| { |
| SslContextFactory serverTLSFactory = createSslContextFactory(); |
| // TLS 1.1 protocol, but only TLS 1.2 ciphers. |
| serverTLSFactory.setIncludeProtocols("TLSv1.1"); |
| serverTLSFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); |
| startServer(serverTLSFactory, new EmptyServerHandler()); |
| |
| SslContextFactory clientTLSFactory = createSslContextFactory(); |
| startClient(clientTLSFactory); |
| |
| try |
| { |
| client.newRequest("localhost", connector.getLocalPort()) |
| .scheme(HttpScheme.HTTPS.asString()) |
| .timeout(5, TimeUnit.SECONDS) |
| .send(); |
| Assert.fail(); |
| } |
| catch (ExecutionException x) |
| { |
| // Expected. |
| } |
| } |
| |
| @Test |
| public void testMismatchBetweenTLSProtocolAndTLSCiphersOnClient() throws Exception |
| { |
| SslContextFactory serverTLSFactory = createSslContextFactory(); |
| startServer(serverTLSFactory, new EmptyServerHandler()); |
| |
| SslContextFactory clientTLSFactory = createSslContextFactory(); |
| // TLS 1.1 protocol, but only TLS 1.2 ciphers. |
| clientTLSFactory.setIncludeProtocols("TLSv1.1"); |
| clientTLSFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); |
| startClient(clientTLSFactory); |
| |
| try |
| { |
| client.newRequest("localhost", connector.getLocalPort()) |
| .scheme(HttpScheme.HTTPS.asString()) |
| .timeout(5, TimeUnit.SECONDS) |
| .send(); |
| Assert.fail(); |
| } |
| catch (ExecutionException x) |
| { |
| // Expected. |
| } |
| } |
| } |