1bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/*
2bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project
3bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
4bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * you may not use this file except in compliance with the License.
6bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * You may obtain a copy of the License at
7bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
8bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom *
10bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * See the License for the specific language governing permissions and
14bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * limitations under the License.
15bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */
16bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.javax.net.ssl;
18bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
196882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstromimport java.util.concurrent.Callable;
204ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstromimport java.util.concurrent.ExecutionException;
216882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstromimport java.util.concurrent.ExecutorService;
226882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstromimport java.util.concurrent.Executors;
236882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstromimport java.util.concurrent.Future;
244ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstromimport java.util.concurrent.TimeUnit;
254557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSocket;
266882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom
27bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/**
28bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * TestSSLSocketPair is a convenience class for other tests that want
29bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * a pair of connected and handshaked client and server SSLSockets for
30bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * testing.
31bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */
32bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrompublic final class TestSSLSocketPair {
33bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final TestSSLContext c;
34bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final SSLSocket server;
35bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    public final SSLSocket client;
36bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
37bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    private TestSSLSocketPair (TestSSLContext c,
38bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                               SSLSocket server,
39bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                               SSLSocket client) {
40bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.c = c;
41bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.server = server;
42bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        this.client = client;
43bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
44bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
45f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom    public void close() {
46f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
47f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        try {
48f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            server.close();
49f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            client.close();
50f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        } catch (Exception e) {
51f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            throw new RuntimeException(e);
52f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        }
53f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom    }
54f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
55bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    /**
5617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom     * based on test_SSLSocket_startHandshake
57bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     */
5817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public static TestSSLSocketPair create () {
59bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
60204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        SSLSocket[] sockets = connect(c, null, null);
61bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        return new TestSSLSocketPair(c, sockets[0], sockets[1]);
62bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
63bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
64bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    /**
65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * Create a new connected server/client socket pair within a
66204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom     * existing SSLContext. Optionally specify clientCipherSuites to
67204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom     * allow forcing new SSLSession to test SSLSessionContext
68204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom     * caching. Optionally specify serverCipherSuites for testing
69204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom     * cipher suite negotiation.
70bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     */
716882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom    public static SSLSocket[] connect (final TestSSLContext context,
72204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                                       final String[] clientCipherSuites,
73204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                                       final String[] serverCipherSuites) {
74bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        try {
756882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            final SSLSocket client = (SSLSocket)
766882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                context.clientContext.getSocketFactory().createSocket(context.host, context.port);
776882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            final SSLSocket server = (SSLSocket) context.serverSocket.accept();
786882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom
796882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            ExecutorService executor = Executors.newFixedThreadPool(2);
806882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            Future s = executor.submit(new Callable<Void>() {
816882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                    public Void call() throws Exception {
826882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        if (serverCipherSuites != null) {
836882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                            server.setEnabledCipherSuites(serverCipherSuites);
846882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        }
856882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        server.startHandshake();
866882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        return null;
876882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                    }
886882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                });
896882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            Future c = executor.submit(new Callable<Void>() {
906882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                    public Void call() throws Exception {
916882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        if (clientCipherSuites != null) {
926882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                            client.setEnabledCipherSuites(clientCipherSuites);
93bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                        }
946882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        client.startHandshake();
956882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                        return null;
96bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                    }
97bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                });
986882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            executor.shutdown();
996882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom
1004ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            // catch client and server exceptions separately so we can
1014ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            // potentially log both.
1024ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            Exception serverException;
1034ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            try {
1044ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                s.get(30, TimeUnit.SECONDS);
1054ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                serverException = null;
1064ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            } catch (Exception e) {
1074ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                serverException = e;
1084ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                e.printStackTrace();
1094ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            }
1104ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            Exception clientException;
1114ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            try {
1124ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                c.get(30, TimeUnit.SECONDS);
1134ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                clientException = null;
1144ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            } catch (Exception e) {
1154ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                clientException = e;
1164ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                e.printStackTrace();
1174ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            }
1184ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            if (serverException != null) {
1194ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                throw serverException;
1204ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            }
1214ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            if (clientException != null) {
1224ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom                throw clientException;
1234ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            }
12417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom            return new SSLSocket[] { server, client };
125bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        } catch (RuntimeException e) {
126bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            throw e;
127bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        } catch (Exception e) {
128bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            throw new RuntimeException(e);
129bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        }
130bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
131bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom}
132bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
133