1ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom/*
2ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project
3ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom *
4ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * you may not use this file except in compliance with the License.
6ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * You may obtain a copy of the License at
7ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom *
8ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom *
10ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
11ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * See the License for the specific language governing permissions and
14ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * limitations under the License.
15ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom */
16ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.javax.net.ssl;
18ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
19783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.io.IOException;
205f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.io.InputStream;
215f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.io.OutputStream;
22283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstromimport java.lang.Thread.UncaughtExceptionHandler;
23615225a35dbd838210270b282d1196deff643b51Brian Carlstromimport java.lang.reflect.Method;
2451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstromimport java.net.InetSocketAddress;
25a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstromimport java.net.ServerSocket;
26ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.net.Socket;
275f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.net.SocketException;
28ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.net.SocketTimeoutException;
29ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.security.Principal;
30aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport java.security.PrivateKey;
31ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.security.cert.Certificate;
322915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstromimport java.security.cert.CertificateException;
33aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport java.security.cert.X509Certificate;
34ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.util.Arrays;
354ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstromimport java.util.HashSet;
364ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstromimport java.util.Set;
37783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Callable;
38783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.ExecutorService;
39783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Executors;
40783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Future;
414557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.HandshakeCompletedEvent;
424557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.HandshakeCompletedListener;
43aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.KeyManager;
444557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLContext;
454557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLException;
462915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstromimport javax.net.ssl.SSLHandshakeException;
474557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLParameters;
484557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLPeerUnverifiedException;
494557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLProtocolException;
504557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSession;
514557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSocket;
524557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSocketFactory;
53aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.TrustManager;
54aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.X509KeyManager;
558c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstromimport javax.net.ssl.X509TrustManager;
56ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport junit.framework.TestCase;
575f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport libcore.java.security.StandardNames;
585f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport libcore.java.security.TestKeyStore;
59ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
60ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrompublic class SSLSocketTest extends TestCase {
61ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
62204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    public void test_SSLSocket_getSupportedCipherSuites_names() throws Exception {
638ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
648ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String[] cipherSuites = ssl.getSupportedCipherSuites();
660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(cipherSuites, ssl.getSupportedCipherSuites());
68ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
69ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
70204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
71a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom        // note the rare usage of non-RSA keys
72101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson        TestKeyStore testKeyStore = new TestKeyStore.Builder()
73101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
74101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .aliasPrefix("rsa-dsa-ec")
75101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .ca(true)
76101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .build();
771f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root        StringBuilder error = new StringBuilder();
786882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        if (StandardNames.IS_RI) {
796882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
806882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                            StandardNames.JSSE_PROVIDER_NAME,
816c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                            StandardNames.JSSE_PROVIDER_NAME,
82ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                            true,
831f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            true,
841f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            error);
856882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        } else  {
866882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
876882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                            "HarmonyJSSE",
886c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                            "HarmonyJSSE",
89ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                            false,
901f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            false,
911f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            error);
926882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
936882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                            "AndroidOpenSSL",
946c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                            "AndroidOpenSSL",
95ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                            true,
961f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            true,
971f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            error);
986882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
996882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                            "HarmonyJSSE",
1006c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                            "AndroidOpenSSL",
101ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                            false,
1021f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            true,
1031f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            error);
1046882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
1056882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                            "AndroidOpenSSL",
1066c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                            "HarmonyJSSE",
107ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                            true,
1081f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            false,
1091f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                            error);
1101f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root        }
1111f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root        if (error.length() > 0) {
1121f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root            throw new Exception("One or more problems in "
1131f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                    + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
1146882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        }
1156882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom    }
1166882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom    private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
1176882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                                 String clientProvider,
1186c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                                 String serverProvider,
119ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                                 boolean clientSecureRenegotiation,
1201f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                                 boolean serverSecureRenegotiation,
1211f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root                                                                 StringBuilder error)
1226882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom            throws Exception {
1236882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom
1246882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        String clientToServerString = "this is sent from the client to the server...";
1256882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        String serverToClientString = "... and this from the server to the client";
1266882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        byte[] clientToServer = clientToServerString.getBytes();
1276882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        byte[] serverToClient = serverToClientString.getBytes();
1286882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom
1296882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        TestSSLContext c = TestSSLContext.create(testKeyStore, testKeyStore,
1306882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                 clientProvider, serverProvider);
1314ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom        String[] cipherSuites;
1324ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom        if (clientProvider.equals(serverProvider)) {
1334ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
1344ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom        } else {
135ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom            String[] clientSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
136ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom            String[] serverSuites = c.serverContext.getSocketFactory().getSupportedCipherSuites();
137ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom            Set<String> ccs = new HashSet<String>(Arrays.asList(clientSuites));
138ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom            Set<String> scs = new HashSet<String>(Arrays.asList(serverSuites));
1394ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            Set<String> cs = new HashSet<String>(ccs);
1404ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            cs.retainAll(scs);
1414ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom            cipherSuites = cs.toArray(new String[cs.size()]);
1424ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom        }
1434ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom
144204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        for (String cipherSuite : cipherSuites) {
145aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
146a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom            try {
147a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                /*
1486c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
1496c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 * its own, but instead in conjunction with other
1506c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 * cipher suites.
1516c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 */
1526c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
1536c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                    continue;
1546c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                }
1556c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                /*
156a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                 * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
1576c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
1586c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                 * #KRBRequire
159a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                 */
160a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                if (cipherSuite.startsWith("TLS_KRB5_")) {
161a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                    continue;
162a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                }
1636c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom
164ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                String[] clientCipherSuiteArray
165ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                        = (clientSecureRenegotiation
166ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                           ? new String[] { cipherSuite,
167ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                            StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
168ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                           : new String[] { cipherSuite });
169ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                String[] serverCipherSuiteArray
170ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                        = (serverSecureRenegotiation
1716c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                           ? new String[] { cipherSuite,
1726c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                            StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
1736c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                           : new String[] { cipherSuite });
174ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                SSLSocket[] pair = TestSSLSocketPair.connect(c,
175ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                             clientCipherSuiteArray,
176ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom                                                             serverCipherSuiteArray);
177a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom
178a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                SSLSocket server = pair[0];
179a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                SSLSocket client = pair[1];
180a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                server.getOutputStream().write(serverToClient);
181a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                client.getOutputStream().write(clientToServer);
182a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                // arrays are too big to make sure we get back only what we expect
183a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                byte[] clientFromServer = new byte[serverToClient.length+1];
184a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                byte[] serverFromClient = new byte[clientToServer.length+1];
185a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                int readFromServer = client.getInputStream().read(clientFromServer);
186a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                int readFromClient = server.getInputStream().read(serverFromClient);
187a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                assertEquals(serverToClient.length, readFromServer);
188a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                assertEquals(clientToServer.length, readFromClient);
189a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                assertEquals(clientToServerString, new String(serverFromClient, 0, readFromClient));
190a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                assertEquals(serverToClientString, new String(clientFromServer, 0, readFromServer));
191a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom                client.close();
192b4bb9aba620d8a363fb3617b25839093caf39cf4Brian Carlstrom                server.close();
193aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                assertFalse(errorExpected);
194aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            } catch (Exception maybeExpected) {
195aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                if (!errorExpected) {
19639d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                    String message = ("Problem trying to connect cipher suite " + cipherSuite
19739d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                                      + " client=" + clientProvider
19839d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                                      + " server=" + serverProvider);
19939d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                    System.out.println(message);
20039d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                    maybeExpected.printStackTrace();
20139d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                    error.append(message);
20239d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom                    error.append('\n');
203aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                }
204204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom            }
205204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom        }
206f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
207204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom    }
208204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom
209ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
2108ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2118ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
212bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String[] cipherSuites = ssl.getEnabledCipherSuites();
2130c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
2140c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
215ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
216ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
217ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
2188ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2198ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
220ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
221ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
222ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledCipherSuites(null);
223ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
224e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
225ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
226ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
227ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledCipherSuites(new String[1]);
228ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
229e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
230ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
231ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
232ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
233ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
234e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
235ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
236ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
237ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledCipherSuites(new String[0]);
238ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
239ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
240ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
241ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
242ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_getSupportedProtocols() throws Exception {
2438ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2448ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
245bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String[] protocols = ssl.getSupportedProtocols();
2460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
2470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(protocols, ssl.getSupportedProtocols());
248ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
249ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
250ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_getEnabledProtocols() throws Exception {
2518ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2528ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
253bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        String[] protocols = ssl.getEnabledProtocols();
2540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
2550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(protocols, ssl.getEnabledProtocols());
256ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
257ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
258ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_setEnabledProtocols() throws Exception {
2598ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2608ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
261ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
262ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
263ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledProtocols(null);
264ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
265e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
266ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
267ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
268ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledProtocols(new String[1]);
269ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
270e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
271ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
272ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
273ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            ssl.setEnabledProtocols(new String[] { "Bogus" } );
274ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
275e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (IllegalArgumentException expected) {
276ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
277ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledProtocols(new String[0]);
278ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledProtocols(ssl.getEnabledProtocols());
279ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        ssl.setEnabledProtocols(ssl.getSupportedProtocols());
280ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
281ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
282ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_getSession() throws Exception {
2838ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
2848ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
2858ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom        SSLSession session = ssl.getSession();
286ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(session);
287ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertFalse(session.isValid());
288ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
289ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
290ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    public void test_SSLSocket_startHandshake() throws Exception {
291bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        final TestSSLContext c = TestSSLContext.create();
292059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
293059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
294ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
295783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
296783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
297783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
298783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.startHandshake();
299783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertNotNull(server.getSession());
300ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                try {
301783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    server.getSession().getPeerCertificates();
302783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    fail();
303783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                } catch (SSLPeerUnverifiedException expected) {
304ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                }
305783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                Certificate[] localCertificates = server.getSession().getLocalCertificates();
306783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertNotNull(localCertificates);
307783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                TestKeyStore.assertChainLength(localCertificates);
308783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertNotNull(localCertificates[0]);
309783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                TestSSLContext.assertServerCertificateChain(c.serverTrustManager,
310783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                                                            localCertificates);
311783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
312783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                                                           c.serverKeyStore);
313783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
314ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
315ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
316783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
317ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.startHandshake();
318ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(client.getSession());
319ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNull(client.getSession().getLocalCertificates());
320ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
321ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(peerCertificates);
322059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestKeyStore.assertChainLength(peerCertificates);
323ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(peerCertificates[0]);
324059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
325059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                    peerCertificates);
326059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
327783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
328f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
329f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
330f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
331ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
332ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
333b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom    private static final class SSLServerSessionIdCallable implements Callable<byte[]> {
334b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        private final SSLSocket server;
335b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        private SSLServerSessionIdCallable(SSLSocket server) {
336b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom            this.server = server;
337b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        }
338b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        @Override public byte[] call() throws Exception {
339b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom            server.startHandshake();
340b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom            assertNotNull(server.getSession());
341b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom            assertNotNull(server.getSession().getId());
342b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom            return server.getSession().getId();
343b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        }
344b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom    }
345b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
346b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom    public void test_SSLSocket_confirmSessionReuse() throws Exception {
347b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final TestSSLContext c = TestSSLContext.create();
348b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final ExecutorService executor = Executors.newSingleThreadExecutor();
349b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
350b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
351b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom                                                                                       c.port);
352b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final SSLSocket server1 = (SSLSocket) c.serverSocket.accept();
353b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final Future<byte[]> future1 = executor.submit(new SSLServerSessionIdCallable(server1));
354b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        client1.startHandshake();
355b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertNotNull(client1.getSession());
356b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertNotNull(client1.getSession().getId());
357b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final byte[] clientSessionId1 = client1.getSession().getId();
358b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final byte[] serverSessionId1 = future1.get();
359b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertTrue(Arrays.equals(clientSessionId1, serverSessionId1));
360b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        client1.close();
361b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        server1.close();
362b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
363b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
364b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom                                                                                       c.port);
365b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final SSLSocket server2 = (SSLSocket) c.serverSocket.accept();
366b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final Future<byte[]> future2 = executor.submit(new SSLServerSessionIdCallable(server2));
367b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        client2.startHandshake();
368b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertNotNull(client2.getSession());
369b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertNotNull(client2.getSession().getId());
370b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final byte[] clientSessionId2 = client2.getSession().getId();
371b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        final byte[] serverSessionId2 = future2.get();
372b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertTrue(Arrays.equals(clientSessionId2, serverSessionId2));
373b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        client2.close();
374b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        server2.close();
375b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
376b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        assertTrue(Arrays.equals(clientSessionId1, clientSessionId2));
377b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
378b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        executor.shutdown();
379b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom        c.close();
380b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom    }
381b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom
38217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
3836882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
3846882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                 SSLContext.getDefault(), SSLContext.getDefault());
385059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
386059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
387aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        // RI used to throw SSLException on accept, now throws on startHandshake
388aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        if (StandardNames.IS_RI) {
389aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
390783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            ExecutorService executor = Executors.newSingleThreadExecutor();
391783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            Future<Void> future = executor.submit(new Callable<Void>() {
392783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                @Override public Void call() throws Exception {
393aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    try {
394aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                        server.startHandshake();
395783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                        fail();
396aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    } catch (SSLHandshakeException expected) {
397aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    }
398783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    return null;
399aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                }
400aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            });
401783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            executor.shutdown();
402aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            try {
403aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                client.startHandshake();
404aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                fail();
405aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            } catch (SSLHandshakeException expected) {
406aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
407783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            future.get();
408aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            server.close();
409aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        } else {
410aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            try {
411aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                c.serverSocket.accept();
412aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                fail();
413aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            } catch (SSLException expected) {
414aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
41517c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        }
416f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
417f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
418ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
419ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
420e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
421059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
422059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLContext serverContext = c.serverContext;
423059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLContext clientContext = c.clientContext;
424e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        SSLSocket client = (SSLSocket)
425059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            clientContext.getSocketFactory().createSocket(c.host, c.port);
426059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
427783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
428783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
429783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
430783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.startHandshake();
431783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
432e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            }
433e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        });
434783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
435e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        client.startHandshake();
436783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
437f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
438f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
439f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
440e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    }
441e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
44217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
443bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        final TestSSLContext c = TestSSLContext.create();
444059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        final SSLSocket client = (SSLSocket)
445059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
44617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
447783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
448783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
449783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
450783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.startHandshake();
451783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
452ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
453ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
454783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
455ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom        final boolean[] handshakeCompletedListenerCalled = new boolean[1];
456ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
4578ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom            public void handshakeCompleted(HandshakeCompletedEvent event) {
458ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                try {
459ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    SSLSession session = event.getSession();
460ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    String cipherSuite = event.getCipherSuite();
461ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    Certificate[] localCertificates = event.getLocalCertificates();
462ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    Certificate[] peerCertificates = event.getPeerCertificates();
463e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                    javax.security.cert.X509Certificate[] peerCertificateChain
464e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                            = event.getPeerCertificateChain();
465ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    Principal peerPrincipal = event.getPeerPrincipal();
466ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    Principal localPrincipal = event.getLocalPrincipal();
467ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    Socket socket = event.getSocket();
468ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
469ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    if (false) {
470ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        System.out.println("Session=" + session);
471ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        System.out.println("CipherSuite=" + cipherSuite);
472101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                        System.out.println("LocalCertificates="
473101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                                + Arrays.toString(localCertificates));
474101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                        System.out.println("PeerCertificates="
475101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                                + Arrays.toString(peerCertificates));
476101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                        System.out.println("PeerCertificateChain="
477101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                                + Arrays.toString(peerCertificateChain));
478ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        System.out.println("PeerPrincipal=" + peerPrincipal);
479ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        System.out.println("LocalPrincipal=" + localPrincipal);
480ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        System.out.println("Socket=" + socket);
481ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    }
482ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
483ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(session);
484ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    byte[] id = session.getId();
485ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(id);
486ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertEquals(32, id.length);
487059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
488ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
489ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(cipherSuite);
490e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                    assertTrue(Arrays.asList(
491e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                            client.getEnabledCipherSuites()).contains(cipherSuite));
492e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                    assertTrue(Arrays.asList(
493e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom                            c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
494ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
495ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNull(localCertificates);
496ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
497ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(peerCertificates);
498059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    TestKeyStore.assertChainLength(peerCertificates);
499ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(peerCertificates[0]);
500059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
501059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                peerCertificates);
502059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    TestSSLContext.assertCertificateInKeyStore(peerCertificates[0],
503059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                               c.serverKeyStore);
504ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
505ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(peerCertificateChain);
506059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    TestKeyStore.assertChainLength(peerCertificateChain);
507ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(peerCertificateChain[0]);
508204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom                    TestSSLContext.assertCertificateInKeyStore(
509059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                        peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
510ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
511ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(peerPrincipal);
512059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
513ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
514ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNull(localPrincipal);
515ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
516ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertNotNull(socket);
517ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    assertSame(client, socket);
518ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
519cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom                    synchronized (handshakeCompletedListenerCalled) {
520cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom                        handshakeCompletedListenerCalled[0] = true;
521cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom                        handshakeCompletedListenerCalled.notify();
522cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom                    }
523ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom                    handshakeCompletedListenerCalled[0] = true;
524ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                } catch (RuntimeException e) {
525ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    throw e;
526ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                } catch (Exception e) {
527ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    throw new RuntimeException(e);
528ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                }
529ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
530ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
531ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.startHandshake();
532783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
5330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
534059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            assertNotNull(c.serverContext.getServerSessionContext().getSession(
5350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                    client.getSession().getId()));
5360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
537cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom        synchronized (handshakeCompletedListenerCalled) {
538cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom            while (!handshakeCompletedListenerCalled[0]) {
539cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom                handshakeCompletedListenerCalled.wait();
540cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom            }
541cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom        }
542f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
543f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
544f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
545ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
546ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
547283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom    private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler {
548283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        Throwable actualException;
549283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        @Override public void uncaughtException(Thread thread, Throwable ex) {
550283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom            assertNull(actualException);
551283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom            actualException = ex;
552283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        }
553283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom    }
554283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom
555e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
556283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        final Thread self = Thread.currentThread();
557283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler();
558283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom
559283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        final RuntimeException expectedException = new RuntimeException("expected");
560283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler();
561283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        self.setUncaughtExceptionHandler(test);
562283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom
563e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        final TestSSLContext c = TestSSLContext.create();
564059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        final SSLSocket client = (SSLSocket)
565059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
566e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
567783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
568783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
569783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
570783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.startHandshake();
571783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
572e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            }
573e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        });
574783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
575e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
576e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            public void handshakeCompleted(HandshakeCompletedEvent event) {
577283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom                throw expectedException;
578e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom            }
579e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        });
580e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom        client.startHandshake();
581783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
582f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
583f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
584f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
585283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom
586283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        assertSame(expectedException, test.actualException);
587283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom        self.setUncaughtExceptionHandler(original);
588e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom    }
589e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom
59017c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_getUseClientMode() throws Exception {
59117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
592059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
593059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
59417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        SSLSocket server = (SSLSocket) c.serverSocket.accept();
595ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertTrue(client.getUseClientMode());
59617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        assertFalse(server.getUseClientMode());
597f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
598f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
599f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
600ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
601ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
60217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_setUseClientMode() throws Exception {
603ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        // client is client, server is server
60417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        test_SSLSocket_setUseClientMode(true, false);
605ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        // client is server, server is client
60617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        test_SSLSocket_setUseClientMode(true, false);
607ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        // both are client
608ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
60917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom            test_SSLSocket_setUseClientMode(true, true);
610ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
611e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (SSLProtocolException expected) {
612aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertTrue(StandardNames.IS_RI);
613aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        } catch (SSLHandshakeException expected) {
614aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertFalse(StandardNames.IS_RI);
615ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
616ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
617ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        // both are server
618ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
61917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom            test_SSLSocket_setUseClientMode(false, false);
620ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
621e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (SocketTimeoutException expected) {
622ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
623ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
624ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
62517c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    private void test_SSLSocket_setUseClientMode(final boolean clientClientMode,
62617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom                                                 final boolean serverClientMode)
627ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            throws Exception {
62817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
629059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
630059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
63117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
63217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom
633783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
634783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<IOException> future = executor.submit(new Callable<IOException>() {
635783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public IOException call() throws Exception {
636ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                try {
637ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    if (!serverClientMode) {
638ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                        server.setSoTimeout(1 * 1000);
639ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    }
640ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    server.setUseClientMode(serverClientMode);
641ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                    server.startHandshake();
642783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    return null;
643aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                } catch (SSLHandshakeException e) {
644783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    return e;
645ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                } catch (SocketTimeoutException e) {
646783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    return e;
647ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                }
648ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
649ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
650783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
651ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        if (!clientClientMode) {
652ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            client.setSoTimeout(1 * 1000);
653ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
654ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.setUseClientMode(clientClientMode);
655ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.startHandshake();
656783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        IOException ioe = future.get();
657783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        if (ioe != null) {
658783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            throw ioe;
659ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
660f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
661f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
662f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
663ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
664ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
665783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom    public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
666783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
667783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        // can't set after handshake
668783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        TestSSLEnginePair pair = TestSSLEnginePair.create(null);
669783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        try {
670783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            pair.server.setUseClientMode(false);
671783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            fail();
672783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        } catch (IllegalArgumentException expected) {
673783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        }
674783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        try {
675783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            pair.client.setUseClientMode(false);
676783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            fail();
677783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        } catch (IllegalArgumentException expected) {
678783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        }
679783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom    }
680783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
6812915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom    public void test_SSLSocket_untrustedServer() throws Exception {
6822915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(),
6832915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom                                                 TestKeyStore.getServer());
6842915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
6852915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom                                                                                       c.port);
6862915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
687783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
688783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
689783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
6902915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom                try {
6912915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom                    server.startHandshake();
692783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    assertFalse(StandardNames.IS_RI);
693aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                } catch (SSLHandshakeException expected) {
694783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    assertTrue(StandardNames.IS_RI);
6952915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom                }
696783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
6972915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom            }
6982915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        });
699783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
7002915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        try {
7012915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom            client.startHandshake();
7022915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom            fail();
7032915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        } catch (SSLHandshakeException expected) {
7042915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom            assertTrue(expected.getCause() instanceof CertificateException);
7052915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom        }
706a3d357bd346336f7ff304a9a26c81e93f67f98e6Brian Carlstrom        client.close();
707a3d357bd346336f7ff304a9a26c81e93f67f98e6Brian Carlstrom        server.close();
708783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
709ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
710ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
71117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_clientAuth() throws Exception {
712059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(),
713059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                 TestKeyStore.getServer());
714059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
715059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
71617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
717783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
718783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
719783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
720783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertFalse(server.getWantClientAuth());
721783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertFalse(server.getNeedClientAuth());
722783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
723783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                // confirm turning one on by itself
724783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.setWantClientAuth(true);
725783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertTrue(server.getWantClientAuth());
726783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertFalse(server.getNeedClientAuth());
727783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
728783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                // confirm turning setting on toggles the other
729783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.setNeedClientAuth(true);
730783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertFalse(server.getWantClientAuth());
731783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertTrue(server.getNeedClientAuth());
732783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
733783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                // confirm toggling back
734783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.setWantClientAuth(true);
735783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertTrue(server.getWantClientAuth());
736783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                assertFalse(server.getNeedClientAuth());
737783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
738783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.startHandshake();
739783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
740ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
741ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
742783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
743ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.startHandshake();
744ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(client.getSession().getLocalCertificates());
745059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
746059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
747059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                    client.getSession().getLocalCertificates());
748783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
749f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
750f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
751f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
752ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
753ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
754aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom    public void test_SSLSocket_clientAuth_bogusAlias() throws Exception {
755aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
756aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        SSLContext clientContext = SSLContext.getInstance("TLS");
757aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        X509KeyManager keyManager = new X509KeyManager() {
758aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public String chooseClientAlias(String[] keyType,
759aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                                                      Principal[] issuers,
760aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                                                      Socket socket) {
761aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                return "bogus";
762aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
763aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public String chooseServerAlias(String keyType,
764aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                                                      Principal[] issuers,
765aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                                                      Socket socket) {
766aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                throw new AssertionError();
767aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
768aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public X509Certificate[] getCertificateChain(String alias) {
769aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                // return null for "bogus" alias
770aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                return null;
771aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
772aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public String[] getClientAliases(String keyType, Principal[] issuers) {
773aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                throw new AssertionError();
774aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
775aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public String[] getServerAliases(String keyType, Principal[] issuers) {
776aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                throw new AssertionError();
777aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
778aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            @Override public PrivateKey getPrivateKey(String alias) {
779aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                // return null for "bogus" alias
780aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                return null;
781aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
782aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        };
783aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        clientContext.init(new KeyManager[] { keyManager },
784aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                           new TrustManager[] { c.clientTrustManager },
785aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                           null);
786aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
787aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                                                                                     c.port);
788aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
789783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
790783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
791783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
792aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                try {
793aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    server.setNeedClientAuth(true);
794aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    server.startHandshake();
795aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                    fail();
796aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                } catch (SSLHandshakeException expected) {
797aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                }
798783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
799aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            }
800aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        });
801aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom
802783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
803aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        try {
804aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            client.startHandshake();
805aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            fail();
806aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        } catch (SSLHandshakeException expected) {
807aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            // before we would get a NullPointerException from passing
808aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            // due to the null PrivateKey return by the X509KeyManager.
809aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        }
810783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
811aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        client.close();
812aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        server.close();
813aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        c.close();
814aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom    }
815aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom
8168c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom    public void test_SSLSocket_TrustManagerRuntimeException() throws Exception {
8178c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
8188c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        SSLContext clientContext = SSLContext.getInstance("TLS");
8198c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        X509TrustManager trustManager = new X509TrustManager() {
8208c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
8218c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                    throws CertificateException {
8228c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                throw new AssertionError();
8238c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            }
8248c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
8258c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                    throws CertificateException {
8268c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                throw new RuntimeException();  // throw a RuntimeException from custom TrustManager
8278c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            }
8288c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            @Override public X509Certificate[] getAcceptedIssuers() {
8298c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                throw new AssertionError();
8308c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            }
8318c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        };
8328c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        clientContext.init(null, new TrustManager[] { trustManager }, null);
8338c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
8348c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                                                                                     c.port);
8358c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
8368c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
8378c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
8388c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            @Override public Void call() throws Exception {
8398c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                server.startHandshake();
8408c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom                return null;
8418c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            }
8428c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        });
8438c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom
8448c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        executor.shutdown();
8458c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        try {
8468c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            client.startHandshake();
8478c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            fail();
8488c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        } catch (SSLHandshakeException expected) {
8498c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom            // before we would get a RuntimeException from checkServerTrusted.
8508c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        }
8518c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        future.get();
8528c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        client.close();
8538c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        server.close();
8548c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom        c.close();
8558c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom    }
8568c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom
85717c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_getEnableSessionCreation() throws Exception {
85817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
859059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
860059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
86117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        SSLSocket server = (SSLSocket) c.serverSocket.accept();
862ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertTrue(client.getEnableSessionCreation());
86317c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        assertTrue(server.getEnableSessionCreation());
864f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
865f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
866f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
867ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
868ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
86917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
87017c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
871059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
872059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
87317c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
874783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
875783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
876783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
877783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                server.setEnableSessionCreation(false);
878ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                try {
879783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    server.startHandshake();
880783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    fail();
881783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                } catch (SSLException expected) {
882ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                }
883783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
884ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
885ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
886783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
887ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
888ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            client.startHandshake();
889ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
890e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (SSLException expected) {
891ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
892783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
893f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
894f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
895f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
896ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
897ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
89817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom    public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
89917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
900059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
901059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                                                       c.port);
90217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
903783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
904783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
905783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
906ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                try {
907783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    server.startHandshake();
908783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    fail();
909783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                } catch (SSLException expected) {
910ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom                }
911783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
912ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            }
913ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        });
914783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
915ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        client.setEnableSessionCreation(false);
916ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        try {
917ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            client.startHandshake();
918ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom            fail();
919e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom        } catch (SSLException expected) {
920ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        }
921783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
922f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        client.close();
923f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        server.close();
924f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
925ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
926ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom
9270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLSocket_getSSLParameters() throws Exception {
9280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
9290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
9300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9310c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLParameters p = ssl.getSSLParameters();
9320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(p);
9330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] cipherSuites = p.getCipherSuites();
9350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
9360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
9370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
9380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] protocols = p.getProtocols();
9400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
9410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(protocols, ssl.getEnabledProtocols());
9420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
9430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
9450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
9460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
9470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLSocket_setSSLParameters() throws Exception {
9490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
9500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLSocket ssl = (SSLSocket) sf.createSocket();
9510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
9520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] defaultProtocols = ssl.getEnabledProtocols();
9530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
9540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] supportedProtocols = ssl.getSupportedProtocols();
9550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
9570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters();
9580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            ssl.setSSLParameters(p);
9590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(defaultCipherSuites),
9600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(ssl.getEnabledCipherSuites()));
9610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(defaultProtocols),
9620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(ssl.getEnabledProtocols()));
9630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
9640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
9660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters(supportedCipherSuites,
9670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                                                supportedProtocols);
9680c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            ssl.setSSLParameters(p);
9690c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(supportedCipherSuites),
9700c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(ssl.getEnabledCipherSuites()));
9710c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(supportedProtocols),
9720c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(ssl.getEnabledProtocols()));
9730c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
9740c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
9750c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters();
9760c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setNeedClientAuth(true);
9780c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getNeedClientAuth());
9790c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getWantClientAuth());
9800c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            ssl.setSSLParameters(p);
9810c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(ssl.getNeedClientAuth());
9820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getWantClientAuth());
9830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setWantClientAuth(true);
9850c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(ssl.getNeedClientAuth());
9860c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getWantClientAuth());
9870c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            ssl.setSSLParameters(p);
9880c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getNeedClientAuth());
9890c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(ssl.getWantClientAuth());
9900c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
9910c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setWantClientAuth(false);
9920c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getNeedClientAuth());
9930c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(ssl.getWantClientAuth());
9940c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            ssl.setSSLParameters(p);
9950c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getNeedClientAuth());
9960c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(ssl.getWantClientAuth());
9970c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
9980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
9990c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
10005f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom    public void test_SSLSocket_close() throws Exception {
10015f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        TestSSLSocketPair pair = TestSSLSocketPair.create();
10025f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        SSLSocket server = pair.server;
10035f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        SSLSocket client = pair.client;
10045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertFalse(server.isClosed());
10055f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertFalse(client.isClosed());
10065f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        InputStream input = client.getInputStream();
10075f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        OutputStream output = client.getOutputStream();
10085f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        server.close();
10095f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.close();
10105f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertTrue(server.isClosed());
10115f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertTrue(client.isClosed());
10125f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
10135f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        // close after close is okay...
10145f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        server.close();
10155f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.close();
10165f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
10175f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        // ...so are a lot of other operations...
10185f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        HandshakeCompletedListener l = new HandshakeCompletedListener () {
10195f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            public void handshakeCompleted(HandshakeCompletedEvent e) {}
10205f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        };
10215f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.addHandshakeCompletedListener(l);
10225f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertNotNull(client.getEnabledCipherSuites());
10235f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertNotNull(client.getEnabledProtocols());
10245f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.getEnableSessionCreation();
10255f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.getNeedClientAuth();
10265f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertNotNull(client.getSession());
10275f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertNotNull(client.getSSLParameters());
10285f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertNotNull(client.getSupportedProtocols());
10295f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.getUseClientMode();
10305f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.getWantClientAuth();
10315f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.removeHandshakeCompletedListener(l);
10325f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setEnabledCipherSuites(new String[0]);
10335f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setEnabledProtocols(new String[0]);
10345f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setEnableSessionCreation(false);
10355f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setNeedClientAuth(false);
10365f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setSSLParameters(client.getSSLParameters());
10375f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        client.setWantClientAuth(false);
10385f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
10395f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        // ...but some operations are expected to give SocketException...
10405f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10415f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            client.startHandshake();
10425f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10435f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
10445f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10455f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10465f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            client.getInputStream();
10475f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10485f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
10495f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10505f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10515f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            client.getOutputStream();
10525f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10535f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
10545f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10555f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10565f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            input.read();
10575f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10585f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
10595f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10605f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10615f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            input.read(null, -1, -1);
10625f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
1063aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        } catch (NullPointerException expected) {
1064aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertTrue(StandardNames.IS_RI);
10655f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
1066aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertFalse(StandardNames.IS_RI);
10675f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10685f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10695f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            output.write(-1);
10705f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10715f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
10725f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10735f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10745f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            output.write(null, -1, -1);
10755f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
1076aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom        } catch (NullPointerException expected) {
1077aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertTrue(StandardNames.IS_RI);
10785f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (SocketException expected) {
1079aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom            assertFalse(StandardNames.IS_RI);
10805f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
10815f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
10825f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        // ... and one gives IllegalArgumentException
10835f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
10845f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            client.setUseClientMode(false);
10855f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
10865f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (IllegalArgumentException expected) {
10875f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
1088f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
1089f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        pair.close();
10905f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom    }
10915f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
10921c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom    /**
10931c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom     * b/3350645 Test to confirm that an SSLSocket.close() performing
10941c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom     * an SSL_shutdown does not throw an IOException if the peer
10951c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom     * socket has been closed.
10961c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom     */
10971c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom    public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
10981c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
10991c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        final Socket underlying = new Socket(c.host, c.port);
11001c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        final SSLSocket wrapping = (SSLSocket)
11011c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom                c.clientContext.getSocketFactory().createSocket(underlying,
11021c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom                                                                c.host.getHostName(),
11031c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom                                                                c.port,
11041c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom                                                                false);
1105783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
1106783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1107783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
1108783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                wrapping.startHandshake();
1109783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                wrapping.getOutputStream().write(42);
1110783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                // close the underlying socket,
1111783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                // so that no SSL shutdown is sent
1112783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                underlying.close();
1113783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                wrapping.close();
1114783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
11151c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom            }
11161c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        });
1117783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
11181c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom
11191c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        SSLSocket server = (SSLSocket) c.serverSocket.accept();
11201c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        server.startHandshake();
11211c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        server.getInputStream().read();
11221c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        // wait for thread to finish so we know client is closed.
1123783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        clientFuture.get();
11241c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        // close should cause an SSL_shutdown which will fail
11251c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        // because the peer has closed, but it shouldn't throw.
11261c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom        server.close();
11271c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom    }
11281c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom
1129a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom    public void test_SSLSocket_setSoTimeout_basic() throws Exception {
1130a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        ServerSocket listening = new ServerSocket(0);
1131a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1132a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1133a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        assertEquals(0, underlying.getSoTimeout());
1134a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1135a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1136a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        Socket wrapping = sf.createSocket(underlying, null, -1, false);
1137a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        assertEquals(0, wrapping.getSoTimeout());
1138a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1139a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        // setting wrapper sets underlying and ...
1140615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        int expectedTimeoutMillis = 1000;  // 10 was too small because it was affected by rounding
1141fc1332710b0af3bbe658535a257048cf8c7577f2Brian Carlstrom        wrapping.setSoTimeout(expectedTimeoutMillis);
1142fc1332710b0af3bbe658535a257048cf8c7577f2Brian Carlstrom        assertEquals(expectedTimeoutMillis, wrapping.getSoTimeout());
1143fc1332710b0af3bbe658535a257048cf8c7577f2Brian Carlstrom        assertEquals(expectedTimeoutMillis, underlying.getSoTimeout());
1144a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1145a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        // ... getting wrapper inspects underlying
1146a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        underlying.setSoTimeout(0);
1147a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        assertEquals(0, wrapping.getSoTimeout());
1148a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        assertEquals(0, underlying.getSoTimeout());
1149a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom    }
1150a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1151a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom    public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
1152a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom        if (StandardNames.IS_RI) {
1153a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom            // RI cannot handle this case
1154a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom            return;
1155a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom        }
1156a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        ServerSocket listening = new ServerSocket(0);
1157a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1158a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        // setSoTimeout applies to read, not connect, so connect first
1159a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1160a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        Socket server = listening.accept();
1161a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1162a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1163a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
1164a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1165a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        underlying.setSoTimeout(1);
1166a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        try {
1167a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom            clientWrapping.getInputStream().read();
1168a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom            fail();
1169a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        } catch (SocketTimeoutException expected) {
1170a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        }
1171a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1172a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        clientWrapping.close();
1173a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        server.close();
1174a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        underlying.close();
1175a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom        listening.close();
1176a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom    }
1177a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom
1178615225a35dbd838210270b282d1196deff643b51Brian Carlstrom    public void test_SSLSocket_setSoWriteTimeout() throws Exception {
1179615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        if (StandardNames.IS_RI) {
1180615225a35dbd838210270b282d1196deff643b51Brian Carlstrom            // RI does not support write timeout on sockets
1181615225a35dbd838210270b282d1196deff643b51Brian Carlstrom            return;
1182615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        }
1183615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
1184615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        final TestSSLContext c = TestSSLContext.create();
118551cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
118651cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom
118751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // Try to make the client SO_SNDBUF size as small as possible
118851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // (it can default to 512k or even megabytes).  Note that
118951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // socket(7) says that the kernel will double the request to
119051cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // leave room for its own book keeping and that the minimal
119151cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // value will be 2048. Also note that tcp(7) says the value
119251cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // needs to be set before connect(2).
119351cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        int sendBufferSize = 1024;
119451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        client.setSendBufferSize(sendBufferSize);
119551cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        sendBufferSize = client.getSendBufferSize();
119651cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom
119751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // In jb-mr2 it was found that we need to also set SO_RCVBUF
119851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // to a minimal size or the write would not block. While
119951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // tcp(2) says the value has to be set before listen(2), it
120051cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        // seems fine to set it before accept(2).
120151cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        final int recvBufferSize = 128;
120251cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        c.serverSocket.setReceiveBufferSize(recvBufferSize);
120351cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom
120451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom        client.connect(new InetSocketAddress(c.host, c.port));
120551cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom
1206615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1207615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
1208615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
1209615225a35dbd838210270b282d1196deff643b51Brian Carlstrom            @Override public Void call() throws Exception {
1210615225a35dbd838210270b282d1196deff643b51Brian Carlstrom                server.startHandshake();
1211615225a35dbd838210270b282d1196deff643b51Brian Carlstrom                return null;
1212615225a35dbd838210270b282d1196deff643b51Brian Carlstrom            }
1213615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        });
1214615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        executor.shutdown();
1215615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        client.startHandshake();
1216615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
1217615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        // Reflection is used so this can compile on the RI
1218ee41931d976501d0fb4516bd43919b9564558619Kenny Root        String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl";
1219615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        Class actualClass = client.getClass();
1220615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        assertEquals(expectedClassName, actualClass.getName());
1221615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
1222615225a35dbd838210270b282d1196deff643b51Brian Carlstrom                                                         new Class[] { Integer.TYPE });
1223615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        setSoWriteTimeout.invoke(client, 1);
1224615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
1225615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
1226615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        try {
122751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom            // Add extra space to the write to exceed the send buffer
122851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom            // size and cause the write to block.
122951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom            final int extra = 1;
123051cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom            client.getOutputStream().write(new byte[sendBufferSize + extra]);
1231615225a35dbd838210270b282d1196deff643b51Brian Carlstrom            fail();
1232615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        } catch (SocketTimeoutException expected) {
1233615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        }
1234615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
1235615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        future.get();
1236615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        client.close();
1237615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        server.close();
1238615225a35dbd838210270b282d1196deff643b51Brian Carlstrom        c.close();
1239615225a35dbd838210270b282d1196deff643b51Brian Carlstrom    }
1240615225a35dbd838210270b282d1196deff643b51Brian Carlstrom
124184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    public void test_SSLSocket_interrupt() throws Exception {
12423f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        test_SSLSocket_interrupt_case(true, true);
12433f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        test_SSLSocket_interrupt_case(true, false);
12443f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        test_SSLSocket_interrupt_case(false, true);
12453f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        // Currently failing due to reader blocking closing thread http://b/10681815
12463f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        if (StandardNames.IS_RI) {
12473f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom            test_SSLSocket_interrupt_case(false, false);
124884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        }
124984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    }
125084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
12513f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom    private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
125284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            throws Exception {
12533f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
12543f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        ServerSocket listening = new ServerSocket(0);
12553f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
12563f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
12573f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        Socket server = listening.accept();
12583f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
12593f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
12603f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        Socket clientWrapping = sf.createSocket(underlying, null, -1, true);
12613f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
12623f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        final Socket toRead = (readUnderlying) ? underlying : clientWrapping;
12633f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        final Socket toClose = (closeUnderlying) ? underlying : clientWrapping;
12643f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
1265783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
1266783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> future = executor.submit(new Callable<Void>() {
1267783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
1268783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                Thread.sleep(1 * 1000);
1269783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                toClose.close();
1270783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
127184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            }
1272783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        });
1273783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
127484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        try {
12753f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom            toRead.setSoTimeout(5 * 1000);
127684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            toRead.getInputStream().read();
127784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            fail();
127884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        } catch (SocketTimeoutException e) {
127984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            throw e;
128084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        } catch (SocketException expected) {
128184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        }
1282783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        future.get();
12833f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom
12843f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        server.close();
12853f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        underlying.close();
12863f17b9a79c4331504f32d34ce46adf7a78870f87Brian Carlstrom        listening.close();
1287783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom    }
1288783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
1289783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom    /**
1290783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom     * b/7014266 Test to confirm that an SSLSocket.close() on one
1291783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom     * thread will interupt another thread blocked reading on the same
1292783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom     * socket.
1293783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom     */
1294783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom    public void test_SSLSocket_interrupt_read() throws Exception {
1295783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        TestSSLContext c = TestSSLContext.create();
1296783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        final Socket underlying = new Socket(c.host, c.port);
1297783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        final SSLSocket wrapping = (SSLSocket)
1298783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                c.clientContext.getSocketFactory().createSocket(underlying,
1299783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                                                                c.host.getHostName(),
1300783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                                                                c.port,
1301783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                                                                false);
1302783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        ExecutorService executor = Executors.newSingleThreadExecutor();
1303783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1304783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            @Override public Void call() throws Exception {
1305783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                try {
1306783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    wrapping.startHandshake();
1307783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    assertFalse(StandardNames.IS_RI);
1308783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    wrapping.setSoTimeout(5 * 1000);
1309783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    assertEquals(-1, wrapping.getInputStream().read());
1310783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                } catch (Exception e) {
1311783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                    assertTrue(StandardNames.IS_RI);
1312783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                }
1313783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom                return null;
1314783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom            }
1315783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        });
1316783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        executor.shutdown();
1317783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom
1318783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1319783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        server.startHandshake();
1320783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        wrapping.close();
1321783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        clientFuture.get();
1322783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom        server.close();
132384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    }
132484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
13250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_TestSSLSocketPair_create() {
132617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom        TestSSLSocketPair test = TestSSLSocketPair.create();
1327ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(test.c);
1328ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(test.server);
1329ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(test.client);
1330bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        assertTrue(test.server.isConnected());
1331bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        assertTrue(test.client.isConnected());
13325f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertFalse(test.server.isClosed());
13335f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        assertFalse(test.client.isClosed());
1334ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(test.server.getSession());
1335ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom        assertNotNull(test.client.getSession());
13360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(test.server.getSession().isValid());
13370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(test.client.getSession().isValid());
1338f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        test.close();
1339ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom    }
1340bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
1341bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    /**
1342bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     * Not run by default by JUnit, but can be run by Vogar by
1343101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson     * specifying it explicitly (or with main method below)
1344bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom     */
13450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void stress_test_TestSSLSocketPair_create() {
1346bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        final boolean verbose = true;
1347bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        while (true) {
134817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom            TestSSLSocketPair test = TestSSLSocketPair.create();
1349bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            if (verbose) {
1350bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                System.out.println("client=" + test.client.getLocalPort()
1351bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                                   + " server=" + test.server.getLocalPort());
1352bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            } else {
1353bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom                System.out.print("X");
1354bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom            }
1355f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
1356f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            /*
1357f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom              We don't close on purpose in this stress test to add
1358f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom              races in file descriptors reuse when the garbage
1359f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom              collector runs concurrently and finalizes sockets
1360f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            */
1361f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom            // test.close();
1362f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
1363bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom        }
1364bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
1365bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom
1366101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson    public static void main (String[] args) {
13670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        new SSLSocketTest().stress_test_TestSSLSocketPair_create();
1368bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom    }
1369ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom}
1370