Search in sources :

Example 1 with SSLSocketFactory

use of javax.net.ssl.SSLSocketFactory in project jetty.project by eclipse.

the class ConnectHandlerSSLTest method wrapSocket.

private SSLSocket wrapSocket(Socket socket) throws Exception {
    SSLContext sslContext = sslContextFactory.getSslContext();
    SSLSocketFactory socketFactory = sslContext.getSocketFactory();
    SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true);
    sslSocket.setUseClientMode(true);
    sslSocket.startHandshake();
    return sslSocket;
}
Also used : SSLSocket(javax.net.ssl.SSLSocket) SSLContext(javax.net.ssl.SSLContext) SSLSocketFactory(javax.net.ssl.SSLSocketFactory)

Example 2 with SSLSocketFactory

use of javax.net.ssl.SSLSocketFactory in project jetty.project by eclipse.

the class SslContextFactoryReloadTest method testReloadWhileServing.

@Test
public void testReloadWhileServing() throws Exception {
    start(new EchoHandler());
    Scheduler scheduler = new ScheduledExecutorScheduler();
    scheduler.start();
    try {
        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        ctx.init(null, SslContextFactory.TRUST_ALL_CERTS, null);
        SSLSocketFactory socketFactory = ctx.getSocketFactory();
        // Perform 4 reloads while connections are being served.
        AtomicInteger reloads = new AtomicInteger(4);
        long reloadPeriod = 500;
        AtomicBoolean running = new AtomicBoolean(true);
        scheduler.schedule(new Runnable() {

            @Override
            public void run() {
                if (reloads.decrementAndGet() == 0) {
                    running.set(false);
                } else {
                    try {
                        sslContextFactory.reload(sslContextFactory -> {
                            if (sslContextFactory.getKeyStorePath().endsWith(KEYSTORE_1))
                                sslContextFactory.setKeyStorePath(KEYSTORE_2);
                            else
                                sslContextFactory.setKeyStorePath(KEYSTORE_1);
                        });
                        scheduler.schedule(this, reloadPeriod, TimeUnit.MILLISECONDS);
                    } catch (Exception x) {
                        running.set(false);
                        reloads.set(-1);
                    }
                }
            }
        }, reloadPeriod, TimeUnit.MILLISECONDS);
        byte[] content = new byte[16 * 1024];
        while (running.get()) {
            try (SSLSocket client = (SSLSocket) socketFactory.createSocket("localhost", connector.getLocalPort())) {
                // We need to invalidate the session every time we open a new SSLSocket.
                // This is because when the client uses session resumption, it caches
                // the server certificates and then checks that it is the same during
                // a new TLS handshake. If the SslContextFactory is reloaded during the
                // TLS handshake, the client will see the new certificate and blow up.
                // Note that browsers can handle this case better: they will just not
                // use session resumption and fallback to the normal TLS handshake.
                client.getSession().invalidate();
                String request1 = "" + "POST / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Length: " + content.length + "\r\n" + "\r\n";
                OutputStream outputStream = client.getOutputStream();
                outputStream.write(request1.getBytes(StandardCharsets.UTF_8));
                outputStream.write(content);
                outputStream.flush();
                InputStream inputStream = client.getInputStream();
                HttpTester.Response response1 = HttpTester.parseResponse(HttpTester.from(inputStream));
                Assert.assertNotNull(response1);
                Assert.assertThat(response1.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
                String request2 = "" + "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n" + "\r\n";
                outputStream.write(request2.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
                HttpTester.Response response2 = HttpTester.parseResponse(HttpTester.from(inputStream));
                Assert.assertNotNull(response2);
                Assert.assertThat(response2.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
            }
        }
        Assert.assertEquals(0, reloads.get());
    } finally {
        scheduler.stop();
    }
}
Also used : Request(org.eclipse.jetty.server.Request) HttpTester(org.eclipse.jetty.http.HttpTester) Handler(org.eclipse.jetty.server.Handler) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) SslConnectionFactory(org.eclipse.jetty.server.SslConnectionFactory) SSLContext(javax.net.ssl.SSLContext) ServletException(javax.servlet.ServletException) AbstractHandler(org.eclipse.jetty.server.handler.AbstractHandler) SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) HttpVersion(org.eclipse.jetty.http.HttpVersion) Scheduler(org.eclipse.jetty.util.thread.Scheduler) SSLSocket(javax.net.ssl.SSLSocket) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SecureRequestCustomizer(org.eclipse.jetty.server.SecureRequestCustomizer) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) After(org.junit.After) HttpStatus(org.eclipse.jetty.http.HttpStatus) Server(org.eclipse.jetty.server.Server) OutputStream(java.io.OutputStream) HttpServletResponse(javax.servlet.http.HttpServletResponse) ScheduledExecutorScheduler(org.eclipse.jetty.util.thread.ScheduledExecutorScheduler) Matchers(org.hamcrest.Matchers) IOException(java.io.IOException) Test(org.junit.Test) IO(org.eclipse.jetty.util.IO) StandardCharsets(java.nio.charset.StandardCharsets) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) TimeUnit(java.util.concurrent.TimeUnit) HttpMethod(org.eclipse.jetty.http.HttpMethod) ServerConnector(org.eclipse.jetty.server.ServerConnector) Assert(org.junit.Assert) InputStream(java.io.InputStream) Scheduler(org.eclipse.jetty.util.thread.Scheduler) ScheduledExecutorScheduler(org.eclipse.jetty.util.thread.ScheduledExecutorScheduler) InputStream(java.io.InputStream) SSLSocket(javax.net.ssl.SSLSocket) OutputStream(java.io.OutputStream) ScheduledExecutorScheduler(org.eclipse.jetty.util.thread.ScheduledExecutorScheduler) SSLContext(javax.net.ssl.SSLContext) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) HttpTester(org.eclipse.jetty.http.HttpTester) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) Test(org.junit.Test)

Example 3 with SSLSocketFactory

use of javax.net.ssl.SSLSocketFactory in project jetty.project by eclipse.

the class SslContextFactoryReloadTest method testReload.

@Test
public void testReload() throws Exception {
    start(new EchoHandler());
    SSLContext ctx = SSLContext.getInstance("TLSv1.2");
    ctx.init(null, SslContextFactory.TRUST_ALL_CERTS, null);
    SSLSocketFactory socketFactory = ctx.getSocketFactory();
    try (SSLSocket client1 = (SSLSocket) socketFactory.createSocket("localhost", connector.getLocalPort())) {
        String serverDN1 = client1.getSession().getPeerPrincipal().getName();
        Assert.assertThat(serverDN1, Matchers.startsWith("CN=localhost1"));
        String request = "" + "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
        OutputStream output1 = client1.getOutputStream();
        output1.write(request.getBytes(StandardCharsets.UTF_8));
        output1.flush();
        HttpTester.Response response1 = HttpTester.parseResponse(HttpTester.from(client1.getInputStream()));
        Assert.assertNotNull(response1);
        Assert.assertThat(response1.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
        // Reconfigure SslContextFactory.
        sslContextFactory.reload(sslContextFactory -> {
            sslContextFactory.setKeyStorePath(KEYSTORE_2);
            sslContextFactory.setKeyStorePassword("storepwd");
        });
        // New connection should use the new keystore.
        try (SSLSocket client2 = (SSLSocket) socketFactory.createSocket("localhost", connector.getLocalPort())) {
            String serverDN2 = client2.getSession().getPeerPrincipal().getName();
            Assert.assertThat(serverDN2, Matchers.startsWith("CN=localhost2"));
            OutputStream output2 = client1.getOutputStream();
            output2.write(request.getBytes(StandardCharsets.UTF_8));
            output2.flush();
            HttpTester.Response response2 = HttpTester.parseResponse(HttpTester.from(client1.getInputStream()));
            Assert.assertNotNull(response2);
            Assert.assertThat(response2.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
        }
        // Must still be possible to make requests with the first connection.
        output1.write(request.getBytes(StandardCharsets.UTF_8));
        output1.flush();
        response1 = HttpTester.parseResponse(HttpTester.from(client1.getInputStream()));
        Assert.assertNotNull(response1);
        Assert.assertThat(response1.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
    }
}
Also used : SSLSocket(javax.net.ssl.SSLSocket) OutputStream(java.io.OutputStream) SSLContext(javax.net.ssl.SSLContext) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) HttpTester(org.eclipse.jetty.http.HttpTester) Test(org.junit.Test)

Example 4 with SSLSocketFactory

use of javax.net.ssl.SSLSocketFactory in project jetty.project by eclipse.

the class SniSslConnectionFactoryTest method testSameConnectionRequestsForManyWildDomains.

@Test
public void testSameConnectionRequestsForManyWildDomains() throws Exception {
    SslContextFactory clientContextFactory = new SslContextFactory(true);
    clientContextFactory.start();
    SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
    try (SSLSocket sslSocket = (SSLSocket) factory.createSocket("127.0.0.1", _port)) {
        SNIHostName serverName = new SNIHostName("www.domain.com");
        SSLParameters params = sslSocket.getSSLParameters();
        params.setServerNames(Collections.singletonList(serverName));
        sslSocket.setSSLParameters(params);
        sslSocket.startHandshake();
        String request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: www.domain.com\r\n" + "\r\n";
        OutputStream output = sslSocket.getOutputStream();
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        InputStream input = sslSocket.getInputStream();
        String response = response(input);
        Assert.assertTrue(response.startsWith("HTTP/1.1 200 "));
        // Now, on the same socket, send a request for a different valid domain.
        request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: assets.domain.com\r\n" + "\r\n";
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = response(input);
        Assert.assertTrue(response.startsWith("HTTP/1.1 200 "));
        // Now make a request for an invalid domain for this connection.
        request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n";
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = response(input);
        Assert.assertTrue(response.startsWith("HTTP/1.1 400 "));
        Assert.assertThat(response, Matchers.containsString("Host does not match SNI"));
    } finally {
        clientContextFactory.stop();
    }
}
Also used : SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) SSLParameters(javax.net.ssl.SSLParameters) SNIHostName(javax.net.ssl.SNIHostName) InputStream(java.io.InputStream) SSLSocket(javax.net.ssl.SSLSocket) OutputStream(java.io.OutputStream) Matchers.containsString(org.hamcrest.Matchers.containsString) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) Test(org.junit.Test)

Example 5 with SSLSocketFactory

use of javax.net.ssl.SSLSocketFactory in project jetty.project by eclipse.

the class SniSslConnectionFactoryTest method testSameConnectionRequestsForManyDomains.

@Test
public void testSameConnectionRequestsForManyDomains() throws Exception {
    SslContextFactory clientContextFactory = new SslContextFactory(true);
    clientContextFactory.start();
    SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
    try (SSLSocket sslSocket = (SSLSocket) factory.createSocket("127.0.0.1", _port)) {
        SNIHostName serverName = new SNIHostName("m.san.com");
        SSLParameters params = sslSocket.getSSLParameters();
        params.setServerNames(Collections.singletonList(serverName));
        sslSocket.setSSLParameters(params);
        sslSocket.startHandshake();
        // The first request binds the socket to an alias.
        String request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: m.san.com\r\n" + "\r\n";
        OutputStream output = sslSocket.getOutputStream();
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        InputStream input = sslSocket.getInputStream();
        String response = response(input);
        Assert.assertTrue(response.startsWith("HTTP/1.1 200 "));
        // Same socket, send a request for a different domain but same alias.
        request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: www.san.com\r\n" + "\r\n";
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = response(input);
        Assert.assertTrue(response.startsWith("HTTP/1.1 200 "));
        // Same socket, send a request for a different domain but different alias.
        request = "" + "GET /ctx/path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n";
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = response(input);
        assertThat(response, startsWith("HTTP/1.1 400 "));
        assertThat(response, containsString("Host does not match SNI"));
    } finally {
        clientContextFactory.stop();
    }
}
Also used : SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) SSLParameters(javax.net.ssl.SSLParameters) SNIHostName(javax.net.ssl.SNIHostName) InputStream(java.io.InputStream) SSLSocket(javax.net.ssl.SSLSocket) OutputStream(java.io.OutputStream) Matchers.containsString(org.hamcrest.Matchers.containsString) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) Test(org.junit.Test)

Aggregations

SSLSocketFactory (javax.net.ssl.SSLSocketFactory)402 SSLContext (javax.net.ssl.SSLContext)149 SSLSocket (javax.net.ssl.SSLSocket)134 IOException (java.io.IOException)106 X509TrustManager (javax.net.ssl.X509TrustManager)68 Socket (java.net.Socket)63 TrustManager (javax.net.ssl.TrustManager)55 HostnameVerifier (javax.net.ssl.HostnameVerifier)48 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)47 HttpsURLConnection (javax.net.ssl.HttpsURLConnection)47 Test (org.junit.Test)46 KeyManagementException (java.security.KeyManagementException)44 URL (java.net.URL)41 CertificateException (java.security.cert.CertificateException)39 OkHttpClient (okhttp3.OkHttpClient)39 OutputStream (java.io.OutputStream)35 InputStream (java.io.InputStream)34 X509Certificate (java.security.cert.X509Certificate)33 InetSocketAddress (java.net.InetSocketAddress)29 SSLSession (javax.net.ssl.SSLSession)29