1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.javax.net.ssl;
18
19import java.io.IOException;
20import java.io.InputStream;
21import java.io.OutputStream;
22import java.lang.Thread.UncaughtExceptionHandler;
23import java.lang.reflect.Method;
24import java.net.InetSocketAddress;
25import java.net.ServerSocket;
26import java.net.Socket;
27import java.net.SocketException;
28import java.net.SocketTimeoutException;
29import java.security.Principal;
30import java.security.PrivateKey;
31import java.security.cert.Certificate;
32import java.security.cert.CertificateException;
33import java.security.cert.X509Certificate;
34import java.util.Arrays;
35import java.util.HashSet;
36import java.util.Set;
37import java.util.concurrent.Callable;
38import java.util.concurrent.ExecutorService;
39import java.util.concurrent.Executors;
40import java.util.concurrent.Future;
41import javax.net.ssl.HandshakeCompletedEvent;
42import javax.net.ssl.HandshakeCompletedListener;
43import javax.net.ssl.KeyManager;
44import javax.net.ssl.SSLContext;
45import javax.net.ssl.SSLException;
46import javax.net.ssl.SSLHandshakeException;
47import javax.net.ssl.SSLParameters;
48import javax.net.ssl.SSLPeerUnverifiedException;
49import javax.net.ssl.SSLProtocolException;
50import javax.net.ssl.SSLSession;
51import javax.net.ssl.SSLSocket;
52import javax.net.ssl.SSLSocketFactory;
53import javax.net.ssl.TrustManager;
54import javax.net.ssl.X509KeyManager;
55import javax.net.ssl.X509TrustManager;
56import junit.framework.TestCase;
57import libcore.java.security.StandardNames;
58import libcore.java.security.TestKeyStore;
59
60public class SSLSocketTest extends TestCase {
61
62    public void test_SSLSocket_getSupportedCipherSuites_names() throws Exception {
63        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
64        SSLSocket ssl = (SSLSocket) sf.createSocket();
65        String[] cipherSuites = ssl.getSupportedCipherSuites();
66        StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
67        assertNotSame(cipherSuites, ssl.getSupportedCipherSuites());
68    }
69
70    public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
71        // note the rare usage of non-RSA keys
72        TestKeyStore testKeyStore = new TestKeyStore.Builder()
73                .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
74                .aliasPrefix("rsa-dsa-ec")
75                .ca(true)
76                .build();
77        StringBuilder error = new StringBuilder();
78        if (StandardNames.IS_RI) {
79            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
80                                                            StandardNames.JSSE_PROVIDER_NAME,
81                                                            StandardNames.JSSE_PROVIDER_NAME,
82                                                            true,
83                                                            true,
84                                                            error);
85        } else  {
86            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
87                                                            "HarmonyJSSE",
88                                                            "HarmonyJSSE",
89                                                            false,
90                                                            false,
91                                                            error);
92            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
93                                                            "AndroidOpenSSL",
94                                                            "AndroidOpenSSL",
95                                                            true,
96                                                            true,
97                                                            error);
98            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
99                                                            "HarmonyJSSE",
100                                                            "AndroidOpenSSL",
101                                                            false,
102                                                            true,
103                                                            error);
104            test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
105                                                            "AndroidOpenSSL",
106                                                            "HarmonyJSSE",
107                                                            true,
108                                                            false,
109                                                            error);
110        }
111        if (error.length() > 0) {
112            throw new Exception("One or more problems in "
113                    + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
114        }
115    }
116    private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
117                                                                 String clientProvider,
118                                                                 String serverProvider,
119                                                                 boolean clientSecureRenegotiation,
120                                                                 boolean serverSecureRenegotiation,
121                                                                 StringBuilder error)
122            throws Exception {
123
124        String clientToServerString = "this is sent from the client to the server...";
125        String serverToClientString = "... and this from the server to the client";
126        byte[] clientToServer = clientToServerString.getBytes();
127        byte[] serverToClient = serverToClientString.getBytes();
128
129        TestSSLContext c = TestSSLContext.create(testKeyStore, testKeyStore,
130                                                 clientProvider, serverProvider);
131        String[] cipherSuites;
132        if (clientProvider.equals(serverProvider)) {
133            cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
134        } else {
135            String[] clientSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
136            String[] serverSuites = c.serverContext.getSocketFactory().getSupportedCipherSuites();
137            Set<String> ccs = new HashSet<String>(Arrays.asList(clientSuites));
138            Set<String> scs = new HashSet<String>(Arrays.asList(serverSuites));
139            Set<String> cs = new HashSet<String>(ccs);
140            cs.retainAll(scs);
141            cipherSuites = cs.toArray(new String[cs.size()]);
142        }
143
144        for (String cipherSuite : cipherSuites) {
145            boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
146            try {
147                /*
148                 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
149                 * its own, but instead in conjunction with other
150                 * cipher suites.
151                 */
152                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
153                    continue;
154                }
155                /*
156                 * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
157                 * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
158                 * #KRBRequire
159                 */
160                if (cipherSuite.startsWith("TLS_KRB5_")) {
161                    continue;
162                }
163
164                String[] clientCipherSuiteArray
165                        = (clientSecureRenegotiation
166                           ? new String[] { cipherSuite,
167                                            StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
168                           : new String[] { cipherSuite });
169                String[] serverCipherSuiteArray
170                        = (serverSecureRenegotiation
171                           ? new String[] { cipherSuite,
172                                            StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
173                           : new String[] { cipherSuite });
174                SSLSocket[] pair = TestSSLSocketPair.connect(c,
175                                                             clientCipherSuiteArray,
176                                                             serverCipherSuiteArray);
177
178                SSLSocket server = pair[0];
179                SSLSocket client = pair[1];
180                server.getOutputStream().write(serverToClient);
181                client.getOutputStream().write(clientToServer);
182                // arrays are too big to make sure we get back only what we expect
183                byte[] clientFromServer = new byte[serverToClient.length+1];
184                byte[] serverFromClient = new byte[clientToServer.length+1];
185                int readFromServer = client.getInputStream().read(clientFromServer);
186                int readFromClient = server.getInputStream().read(serverFromClient);
187                assertEquals(serverToClient.length, readFromServer);
188                assertEquals(clientToServer.length, readFromClient);
189                assertEquals(clientToServerString, new String(serverFromClient, 0, readFromClient));
190                assertEquals(serverToClientString, new String(clientFromServer, 0, readFromServer));
191                client.close();
192                server.close();
193                assertFalse(errorExpected);
194            } catch (Exception maybeExpected) {
195                if (!errorExpected) {
196                    String message = ("Problem trying to connect cipher suite " + cipherSuite
197                                      + " client=" + clientProvider
198                                      + " server=" + serverProvider);
199                    System.out.println(message);
200                    maybeExpected.printStackTrace();
201                    error.append(message);
202                    error.append('\n');
203                }
204            }
205        }
206        c.close();
207    }
208
209    public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
210        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
211        SSLSocket ssl = (SSLSocket) sf.createSocket();
212        String[] cipherSuites = ssl.getEnabledCipherSuites();
213        StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
214        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
215    }
216
217    public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
218        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
219        SSLSocket ssl = (SSLSocket) sf.createSocket();
220
221        try {
222            ssl.setEnabledCipherSuites(null);
223            fail();
224        } catch (IllegalArgumentException expected) {
225        }
226        try {
227            ssl.setEnabledCipherSuites(new String[1]);
228            fail();
229        } catch (IllegalArgumentException expected) {
230        }
231        try {
232            ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
233            fail();
234        } catch (IllegalArgumentException expected) {
235        }
236
237        ssl.setEnabledCipherSuites(new String[0]);
238        ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
239        ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
240    }
241
242    public void test_SSLSocket_getSupportedProtocols() throws Exception {
243        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
244        SSLSocket ssl = (SSLSocket) sf.createSocket();
245        String[] protocols = ssl.getSupportedProtocols();
246        StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
247        assertNotSame(protocols, ssl.getSupportedProtocols());
248    }
249
250    public void test_SSLSocket_getEnabledProtocols() throws Exception {
251        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
252        SSLSocket ssl = (SSLSocket) sf.createSocket();
253        String[] protocols = ssl.getEnabledProtocols();
254        StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
255        assertNotSame(protocols, ssl.getEnabledProtocols());
256    }
257
258    public void test_SSLSocket_setEnabledProtocols() throws Exception {
259        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
260        SSLSocket ssl = (SSLSocket) sf.createSocket();
261
262        try {
263            ssl.setEnabledProtocols(null);
264            fail();
265        } catch (IllegalArgumentException expected) {
266        }
267        try {
268            ssl.setEnabledProtocols(new String[1]);
269            fail();
270        } catch (IllegalArgumentException expected) {
271        }
272        try {
273            ssl.setEnabledProtocols(new String[] { "Bogus" } );
274            fail();
275        } catch (IllegalArgumentException expected) {
276        }
277        ssl.setEnabledProtocols(new String[0]);
278        ssl.setEnabledProtocols(ssl.getEnabledProtocols());
279        ssl.setEnabledProtocols(ssl.getSupportedProtocols());
280    }
281
282    public void test_SSLSocket_getSession() throws Exception {
283        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
284        SSLSocket ssl = (SSLSocket) sf.createSocket();
285        SSLSession session = ssl.getSession();
286        assertNotNull(session);
287        assertFalse(session.isValid());
288    }
289
290    public void test_SSLSocket_startHandshake() throws Exception {
291        final TestSSLContext c = TestSSLContext.create();
292        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
293                                                                                       c.port);
294        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
295        ExecutorService executor = Executors.newSingleThreadExecutor();
296        Future<Void> future = executor.submit(new Callable<Void>() {
297            @Override public Void call() throws Exception {
298                server.startHandshake();
299                assertNotNull(server.getSession());
300                try {
301                    server.getSession().getPeerCertificates();
302                    fail();
303                } catch (SSLPeerUnverifiedException expected) {
304                }
305                Certificate[] localCertificates = server.getSession().getLocalCertificates();
306                assertNotNull(localCertificates);
307                TestKeyStore.assertChainLength(localCertificates);
308                assertNotNull(localCertificates[0]);
309                TestSSLContext.assertServerCertificateChain(c.serverTrustManager,
310                                                            localCertificates);
311                TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
312                                                           c.serverKeyStore);
313                return null;
314            }
315        });
316        executor.shutdown();
317        client.startHandshake();
318        assertNotNull(client.getSession());
319        assertNull(client.getSession().getLocalCertificates());
320        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
321        assertNotNull(peerCertificates);
322        TestKeyStore.assertChainLength(peerCertificates);
323        assertNotNull(peerCertificates[0]);
324        TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
325                                                    peerCertificates);
326        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
327        future.get();
328        client.close();
329        server.close();
330        c.close();
331    }
332
333    private static final class SSLServerSessionIdCallable implements Callable<byte[]> {
334        private final SSLSocket server;
335        private SSLServerSessionIdCallable(SSLSocket server) {
336            this.server = server;
337        }
338        @Override public byte[] call() throws Exception {
339            server.startHandshake();
340            assertNotNull(server.getSession());
341            assertNotNull(server.getSession().getId());
342            return server.getSession().getId();
343        }
344    }
345
346    public void test_SSLSocket_confirmSessionReuse() throws Exception {
347        final TestSSLContext c = TestSSLContext.create();
348        final ExecutorService executor = Executors.newSingleThreadExecutor();
349
350        final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
351                                                                                       c.port);
352        final SSLSocket server1 = (SSLSocket) c.serverSocket.accept();
353        final Future<byte[]> future1 = executor.submit(new SSLServerSessionIdCallable(server1));
354        client1.startHandshake();
355        assertNotNull(client1.getSession());
356        assertNotNull(client1.getSession().getId());
357        final byte[] clientSessionId1 = client1.getSession().getId();
358        final byte[] serverSessionId1 = future1.get();
359        assertTrue(Arrays.equals(clientSessionId1, serverSessionId1));
360        client1.close();
361        server1.close();
362
363        final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
364                                                                                       c.port);
365        final SSLSocket server2 = (SSLSocket) c.serverSocket.accept();
366        final Future<byte[]> future2 = executor.submit(new SSLServerSessionIdCallable(server2));
367        client2.startHandshake();
368        assertNotNull(client2.getSession());
369        assertNotNull(client2.getSession().getId());
370        final byte[] clientSessionId2 = client2.getSession().getId();
371        final byte[] serverSessionId2 = future2.get();
372        assertTrue(Arrays.equals(clientSessionId2, serverSessionId2));
373        client2.close();
374        server2.close();
375
376        assertTrue(Arrays.equals(clientSessionId1, clientSessionId2));
377
378        executor.shutdown();
379        c.close();
380    }
381
382    public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
383        TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
384                                                 SSLContext.getDefault(), SSLContext.getDefault());
385        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
386                                                                                       c.port);
387        // RI used to throw SSLException on accept, now throws on startHandshake
388        if (StandardNames.IS_RI) {
389            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
390            ExecutorService executor = Executors.newSingleThreadExecutor();
391            Future<Void> future = executor.submit(new Callable<Void>() {
392                @Override public Void call() throws Exception {
393                    try {
394                        server.startHandshake();
395                        fail();
396                    } catch (SSLHandshakeException expected) {
397                    }
398                    return null;
399                }
400            });
401            executor.shutdown();
402            try {
403                client.startHandshake();
404                fail();
405            } catch (SSLHandshakeException expected) {
406            }
407            future.get();
408            server.close();
409        } else {
410            try {
411                c.serverSocket.accept();
412                fail();
413            } catch (SSLException expected) {
414            }
415        }
416        client.close();
417        c.close();
418    }
419
420    public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
421        TestSSLContext c = TestSSLContext.create();
422        SSLContext serverContext = c.serverContext;
423        SSLContext clientContext = c.clientContext;
424        SSLSocket client = (SSLSocket)
425            clientContext.getSocketFactory().createSocket(c.host, c.port);
426        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
427        ExecutorService executor = Executors.newSingleThreadExecutor();
428        Future<Void> future = executor.submit(new Callable<Void>() {
429            @Override public Void call() throws Exception {
430                server.startHandshake();
431                return null;
432            }
433        });
434        executor.shutdown();
435        client.startHandshake();
436        future.get();
437        client.close();
438        server.close();
439        c.close();
440    }
441
442    public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
443        final TestSSLContext c = TestSSLContext.create();
444        final SSLSocket client = (SSLSocket)
445                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
446        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
447        ExecutorService executor = Executors.newSingleThreadExecutor();
448        Future<Void> future = executor.submit(new Callable<Void>() {
449            @Override public Void call() throws Exception {
450                server.startHandshake();
451                return null;
452            }
453        });
454        executor.shutdown();
455        final boolean[] handshakeCompletedListenerCalled = new boolean[1];
456        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
457            public void handshakeCompleted(HandshakeCompletedEvent event) {
458                try {
459                    SSLSession session = event.getSession();
460                    String cipherSuite = event.getCipherSuite();
461                    Certificate[] localCertificates = event.getLocalCertificates();
462                    Certificate[] peerCertificates = event.getPeerCertificates();
463                    javax.security.cert.X509Certificate[] peerCertificateChain
464                            = event.getPeerCertificateChain();
465                    Principal peerPrincipal = event.getPeerPrincipal();
466                    Principal localPrincipal = event.getLocalPrincipal();
467                    Socket socket = event.getSocket();
468
469                    if (false) {
470                        System.out.println("Session=" + session);
471                        System.out.println("CipherSuite=" + cipherSuite);
472                        System.out.println("LocalCertificates="
473                                + Arrays.toString(localCertificates));
474                        System.out.println("PeerCertificates="
475                                + Arrays.toString(peerCertificates));
476                        System.out.println("PeerCertificateChain="
477                                + Arrays.toString(peerCertificateChain));
478                        System.out.println("PeerPrincipal=" + peerPrincipal);
479                        System.out.println("LocalPrincipal=" + localPrincipal);
480                        System.out.println("Socket=" + socket);
481                    }
482
483                    assertNotNull(session);
484                    byte[] id = session.getId();
485                    assertNotNull(id);
486                    assertEquals(32, id.length);
487                    assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
488
489                    assertNotNull(cipherSuite);
490                    assertTrue(Arrays.asList(
491                            client.getEnabledCipherSuites()).contains(cipherSuite));
492                    assertTrue(Arrays.asList(
493                            c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
494
495                    assertNull(localCertificates);
496
497                    assertNotNull(peerCertificates);
498                    TestKeyStore.assertChainLength(peerCertificates);
499                    assertNotNull(peerCertificates[0]);
500                    TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
501                                                                peerCertificates);
502                    TestSSLContext.assertCertificateInKeyStore(peerCertificates[0],
503                                                               c.serverKeyStore);
504
505                    assertNotNull(peerCertificateChain);
506                    TestKeyStore.assertChainLength(peerCertificateChain);
507                    assertNotNull(peerCertificateChain[0]);
508                    TestSSLContext.assertCertificateInKeyStore(
509                        peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
510
511                    assertNotNull(peerPrincipal);
512                    TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
513
514                    assertNull(localPrincipal);
515
516                    assertNotNull(socket);
517                    assertSame(client, socket);
518
519                    synchronized (handshakeCompletedListenerCalled) {
520                        handshakeCompletedListenerCalled[0] = true;
521                        handshakeCompletedListenerCalled.notify();
522                    }
523                    handshakeCompletedListenerCalled[0] = true;
524                } catch (RuntimeException e) {
525                    throw e;
526                } catch (Exception e) {
527                    throw new RuntimeException(e);
528                }
529            }
530        });
531        client.startHandshake();
532        future.get();
533        if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
534            assertNotNull(c.serverContext.getServerSessionContext().getSession(
535                    client.getSession().getId()));
536        }
537        synchronized (handshakeCompletedListenerCalled) {
538            while (!handshakeCompletedListenerCalled[0]) {
539                handshakeCompletedListenerCalled.wait();
540            }
541        }
542        client.close();
543        server.close();
544        c.close();
545    }
546
547    private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler {
548        Throwable actualException;
549        @Override public void uncaughtException(Thread thread, Throwable ex) {
550            assertNull(actualException);
551            actualException = ex;
552        }
553    }
554
555    public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
556        final Thread self = Thread.currentThread();
557        final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler();
558
559        final RuntimeException expectedException = new RuntimeException("expected");
560        final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler();
561        self.setUncaughtExceptionHandler(test);
562
563        final TestSSLContext c = TestSSLContext.create();
564        final SSLSocket client = (SSLSocket)
565                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
566        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
567        ExecutorService executor = Executors.newSingleThreadExecutor();
568        Future<Void> future = executor.submit(new Callable<Void>() {
569            @Override public Void call() throws Exception {
570                server.startHandshake();
571                return null;
572            }
573        });
574        executor.shutdown();
575        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
576            public void handshakeCompleted(HandshakeCompletedEvent event) {
577                throw expectedException;
578            }
579        });
580        client.startHandshake();
581        future.get();
582        client.close();
583        server.close();
584        c.close();
585
586        assertSame(expectedException, test.actualException);
587        self.setUncaughtExceptionHandler(original);
588    }
589
590    public void test_SSLSocket_getUseClientMode() throws Exception {
591        TestSSLContext c = TestSSLContext.create();
592        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
593                                                                                       c.port);
594        SSLSocket server = (SSLSocket) c.serverSocket.accept();
595        assertTrue(client.getUseClientMode());
596        assertFalse(server.getUseClientMode());
597        client.close();
598        server.close();
599        c.close();
600    }
601
602    public void test_SSLSocket_setUseClientMode() throws Exception {
603        // client is client, server is server
604        test_SSLSocket_setUseClientMode(true, false);
605        // client is server, server is client
606        test_SSLSocket_setUseClientMode(true, false);
607        // both are client
608        try {
609            test_SSLSocket_setUseClientMode(true, true);
610            fail();
611        } catch (SSLProtocolException expected) {
612            assertTrue(StandardNames.IS_RI);
613        } catch (SSLHandshakeException expected) {
614            assertFalse(StandardNames.IS_RI);
615        }
616
617        // both are server
618        try {
619            test_SSLSocket_setUseClientMode(false, false);
620            fail();
621        } catch (SocketTimeoutException expected) {
622        }
623    }
624
625    private void test_SSLSocket_setUseClientMode(final boolean clientClientMode,
626                                                 final boolean serverClientMode)
627            throws Exception {
628        TestSSLContext c = TestSSLContext.create();
629        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
630                                                                                       c.port);
631        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
632
633        ExecutorService executor = Executors.newSingleThreadExecutor();
634        Future<IOException> future = executor.submit(new Callable<IOException>() {
635            @Override public IOException call() throws Exception {
636                try {
637                    if (!serverClientMode) {
638                        server.setSoTimeout(1 * 1000);
639                    }
640                    server.setUseClientMode(serverClientMode);
641                    server.startHandshake();
642                    return null;
643                } catch (SSLHandshakeException e) {
644                    return e;
645                } catch (SocketTimeoutException e) {
646                    return e;
647                }
648            }
649        });
650        executor.shutdown();
651        if (!clientClientMode) {
652            client.setSoTimeout(1 * 1000);
653        }
654        client.setUseClientMode(clientClientMode);
655        client.startHandshake();
656        IOException ioe = future.get();
657        if (ioe != null) {
658            throw ioe;
659        }
660        client.close();
661        server.close();
662        c.close();
663    }
664
665    public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
666
667        // can't set after handshake
668        TestSSLEnginePair pair = TestSSLEnginePair.create(null);
669        try {
670            pair.server.setUseClientMode(false);
671            fail();
672        } catch (IllegalArgumentException expected) {
673        }
674        try {
675            pair.client.setUseClientMode(false);
676            fail();
677        } catch (IllegalArgumentException expected) {
678        }
679    }
680
681    public void test_SSLSocket_untrustedServer() throws Exception {
682        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(),
683                                                 TestKeyStore.getServer());
684        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
685                                                                                       c.port);
686        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
687        ExecutorService executor = Executors.newSingleThreadExecutor();
688        Future<Void> future = executor.submit(new Callable<Void>() {
689            @Override public Void call() throws Exception {
690                try {
691                    server.startHandshake();
692                    assertFalse(StandardNames.IS_RI);
693                } catch (SSLHandshakeException expected) {
694                    assertTrue(StandardNames.IS_RI);
695                }
696                return null;
697            }
698        });
699        executor.shutdown();
700        try {
701            client.startHandshake();
702            fail();
703        } catch (SSLHandshakeException expected) {
704            assertTrue(expected.getCause() instanceof CertificateException);
705        }
706        client.close();
707        server.close();
708        future.get();
709    }
710
711    public void test_SSLSocket_clientAuth() throws Exception {
712        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(),
713                                                 TestKeyStore.getServer());
714        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
715                                                                                       c.port);
716        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
717        ExecutorService executor = Executors.newSingleThreadExecutor();
718        Future<Void> future = executor.submit(new Callable<Void>() {
719            @Override public Void call() throws Exception {
720                assertFalse(server.getWantClientAuth());
721                assertFalse(server.getNeedClientAuth());
722
723                // confirm turning one on by itself
724                server.setWantClientAuth(true);
725                assertTrue(server.getWantClientAuth());
726                assertFalse(server.getNeedClientAuth());
727
728                // confirm turning setting on toggles the other
729                server.setNeedClientAuth(true);
730                assertFalse(server.getWantClientAuth());
731                assertTrue(server.getNeedClientAuth());
732
733                // confirm toggling back
734                server.setWantClientAuth(true);
735                assertTrue(server.getWantClientAuth());
736                assertFalse(server.getNeedClientAuth());
737
738                server.startHandshake();
739                return null;
740            }
741        });
742        executor.shutdown();
743        client.startHandshake();
744        assertNotNull(client.getSession().getLocalCertificates());
745        TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
746        TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
747                                                    client.getSession().getLocalCertificates());
748        future.get();
749        client.close();
750        server.close();
751        c.close();
752    }
753
754    public void test_SSLSocket_clientAuth_bogusAlias() throws Exception {
755        TestSSLContext c = TestSSLContext.create();
756        SSLContext clientContext = SSLContext.getInstance("TLS");
757        X509KeyManager keyManager = new X509KeyManager() {
758            @Override public String chooseClientAlias(String[] keyType,
759                                                      Principal[] issuers,
760                                                      Socket socket) {
761                return "bogus";
762            }
763            @Override public String chooseServerAlias(String keyType,
764                                                      Principal[] issuers,
765                                                      Socket socket) {
766                throw new AssertionError();
767            }
768            @Override public X509Certificate[] getCertificateChain(String alias) {
769                // return null for "bogus" alias
770                return null;
771            }
772            @Override public String[] getClientAliases(String keyType, Principal[] issuers) {
773                throw new AssertionError();
774            }
775            @Override public String[] getServerAliases(String keyType, Principal[] issuers) {
776                throw new AssertionError();
777            }
778            @Override public PrivateKey getPrivateKey(String alias) {
779                // return null for "bogus" alias
780                return null;
781            }
782        };
783        clientContext.init(new KeyManager[] { keyManager },
784                           new TrustManager[] { c.clientTrustManager },
785                           null);
786        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
787                                                                                     c.port);
788        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
789        ExecutorService executor = Executors.newSingleThreadExecutor();
790        Future<Void> future = executor.submit(new Callable<Void>() {
791            @Override public Void call() throws Exception {
792                try {
793                    server.setNeedClientAuth(true);
794                    server.startHandshake();
795                    fail();
796                } catch (SSLHandshakeException expected) {
797                }
798                return null;
799            }
800        });
801
802        executor.shutdown();
803        try {
804            client.startHandshake();
805            fail();
806        } catch (SSLHandshakeException expected) {
807            // before we would get a NullPointerException from passing
808            // due to the null PrivateKey return by the X509KeyManager.
809        }
810        future.get();
811        client.close();
812        server.close();
813        c.close();
814    }
815
816    public void test_SSLSocket_TrustManagerRuntimeException() throws Exception {
817        TestSSLContext c = TestSSLContext.create();
818        SSLContext clientContext = SSLContext.getInstance("TLS");
819        X509TrustManager trustManager = new X509TrustManager() {
820            @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
821                    throws CertificateException {
822                throw new AssertionError();
823            }
824            @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
825                    throws CertificateException {
826                throw new RuntimeException();  // throw a RuntimeException from custom TrustManager
827            }
828            @Override public X509Certificate[] getAcceptedIssuers() {
829                throw new AssertionError();
830            }
831        };
832        clientContext.init(null, new TrustManager[] { trustManager }, null);
833        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
834                                                                                     c.port);
835        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
836        ExecutorService executor = Executors.newSingleThreadExecutor();
837        Future<Void> future = executor.submit(new Callable<Void>() {
838            @Override public Void call() throws Exception {
839                server.startHandshake();
840                return null;
841            }
842        });
843
844        executor.shutdown();
845        try {
846            client.startHandshake();
847            fail();
848        } catch (SSLHandshakeException expected) {
849            // before we would get a RuntimeException from checkServerTrusted.
850        }
851        future.get();
852        client.close();
853        server.close();
854        c.close();
855    }
856
857    public void test_SSLSocket_getEnableSessionCreation() throws Exception {
858        TestSSLContext c = TestSSLContext.create();
859        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
860                                                                                       c.port);
861        SSLSocket server = (SSLSocket) c.serverSocket.accept();
862        assertTrue(client.getEnableSessionCreation());
863        assertTrue(server.getEnableSessionCreation());
864        client.close();
865        server.close();
866        c.close();
867    }
868
869    public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
870        TestSSLContext c = TestSSLContext.create();
871        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
872                                                                                       c.port);
873        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
874        ExecutorService executor = Executors.newSingleThreadExecutor();
875        Future<Void> future = executor.submit(new Callable<Void>() {
876            @Override public Void call() throws Exception {
877                server.setEnableSessionCreation(false);
878                try {
879                    server.startHandshake();
880                    fail();
881                } catch (SSLException expected) {
882                }
883                return null;
884            }
885        });
886        executor.shutdown();
887        try {
888            client.startHandshake();
889            fail();
890        } catch (SSLException expected) {
891        }
892        future.get();
893        client.close();
894        server.close();
895        c.close();
896    }
897
898    public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
899        TestSSLContext c = TestSSLContext.create();
900        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
901                                                                                       c.port);
902        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
903        ExecutorService executor = Executors.newSingleThreadExecutor();
904        Future<Void> future = executor.submit(new Callable<Void>() {
905            @Override public Void call() throws Exception {
906                try {
907                    server.startHandshake();
908                    fail();
909                } catch (SSLException expected) {
910                }
911                return null;
912            }
913        });
914        executor.shutdown();
915        client.setEnableSessionCreation(false);
916        try {
917            client.startHandshake();
918            fail();
919        } catch (SSLException expected) {
920        }
921        future.get();
922        client.close();
923        server.close();
924        c.close();
925    }
926
927    public void test_SSLSocket_getSSLParameters() throws Exception {
928        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
929        SSLSocket ssl = (SSLSocket) sf.createSocket();
930
931        SSLParameters p = ssl.getSSLParameters();
932        assertNotNull(p);
933
934        String[] cipherSuites = p.getCipherSuites();
935        StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
936        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
937        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
938
939        String[] protocols = p.getProtocols();
940        StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
941        assertNotSame(protocols, ssl.getEnabledProtocols());
942        assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
943
944        assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
945        assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
946    }
947
948    public void test_SSLSocket_setSSLParameters() throws Exception {
949        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
950        SSLSocket ssl = (SSLSocket) sf.createSocket();
951        String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
952        String[] defaultProtocols = ssl.getEnabledProtocols();
953        String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
954        String[] supportedProtocols = ssl.getSupportedProtocols();
955
956        {
957            SSLParameters p = new SSLParameters();
958            ssl.setSSLParameters(p);
959            assertEquals(Arrays.asList(defaultCipherSuites),
960                         Arrays.asList(ssl.getEnabledCipherSuites()));
961            assertEquals(Arrays.asList(defaultProtocols),
962                         Arrays.asList(ssl.getEnabledProtocols()));
963        }
964
965        {
966            SSLParameters p = new SSLParameters(supportedCipherSuites,
967                                                supportedProtocols);
968            ssl.setSSLParameters(p);
969            assertEquals(Arrays.asList(supportedCipherSuites),
970                         Arrays.asList(ssl.getEnabledCipherSuites()));
971            assertEquals(Arrays.asList(supportedProtocols),
972                         Arrays.asList(ssl.getEnabledProtocols()));
973        }
974        {
975            SSLParameters p = new SSLParameters();
976
977            p.setNeedClientAuth(true);
978            assertFalse(ssl.getNeedClientAuth());
979            assertFalse(ssl.getWantClientAuth());
980            ssl.setSSLParameters(p);
981            assertTrue(ssl.getNeedClientAuth());
982            assertFalse(ssl.getWantClientAuth());
983
984            p.setWantClientAuth(true);
985            assertTrue(ssl.getNeedClientAuth());
986            assertFalse(ssl.getWantClientAuth());
987            ssl.setSSLParameters(p);
988            assertFalse(ssl.getNeedClientAuth());
989            assertTrue(ssl.getWantClientAuth());
990
991            p.setWantClientAuth(false);
992            assertFalse(ssl.getNeedClientAuth());
993            assertTrue(ssl.getWantClientAuth());
994            ssl.setSSLParameters(p);
995            assertFalse(ssl.getNeedClientAuth());
996            assertFalse(ssl.getWantClientAuth());
997        }
998    }
999
1000    public void test_SSLSocket_close() throws Exception {
1001        TestSSLSocketPair pair = TestSSLSocketPair.create();
1002        SSLSocket server = pair.server;
1003        SSLSocket client = pair.client;
1004        assertFalse(server.isClosed());
1005        assertFalse(client.isClosed());
1006        InputStream input = client.getInputStream();
1007        OutputStream output = client.getOutputStream();
1008        server.close();
1009        client.close();
1010        assertTrue(server.isClosed());
1011        assertTrue(client.isClosed());
1012
1013        // close after close is okay...
1014        server.close();
1015        client.close();
1016
1017        // ...so are a lot of other operations...
1018        HandshakeCompletedListener l = new HandshakeCompletedListener () {
1019            public void handshakeCompleted(HandshakeCompletedEvent e) {}
1020        };
1021        client.addHandshakeCompletedListener(l);
1022        assertNotNull(client.getEnabledCipherSuites());
1023        assertNotNull(client.getEnabledProtocols());
1024        client.getEnableSessionCreation();
1025        client.getNeedClientAuth();
1026        assertNotNull(client.getSession());
1027        assertNotNull(client.getSSLParameters());
1028        assertNotNull(client.getSupportedProtocols());
1029        client.getUseClientMode();
1030        client.getWantClientAuth();
1031        client.removeHandshakeCompletedListener(l);
1032        client.setEnabledCipherSuites(new String[0]);
1033        client.setEnabledProtocols(new String[0]);
1034        client.setEnableSessionCreation(false);
1035        client.setNeedClientAuth(false);
1036        client.setSSLParameters(client.getSSLParameters());
1037        client.setWantClientAuth(false);
1038
1039        // ...but some operations are expected to give SocketException...
1040        try {
1041            client.startHandshake();
1042            fail();
1043        } catch (SocketException expected) {
1044        }
1045        try {
1046            client.getInputStream();
1047            fail();
1048        } catch (SocketException expected) {
1049        }
1050        try {
1051            client.getOutputStream();
1052            fail();
1053        } catch (SocketException expected) {
1054        }
1055        try {
1056            input.read();
1057            fail();
1058        } catch (SocketException expected) {
1059        }
1060        try {
1061            input.read(null, -1, -1);
1062            fail();
1063        } catch (NullPointerException expected) {
1064            assertTrue(StandardNames.IS_RI);
1065        } catch (SocketException expected) {
1066            assertFalse(StandardNames.IS_RI);
1067        }
1068        try {
1069            output.write(-1);
1070            fail();
1071        } catch (SocketException expected) {
1072        }
1073        try {
1074            output.write(null, -1, -1);
1075            fail();
1076        } catch (NullPointerException expected) {
1077            assertTrue(StandardNames.IS_RI);
1078        } catch (SocketException expected) {
1079            assertFalse(StandardNames.IS_RI);
1080        }
1081
1082        // ... and one gives IllegalArgumentException
1083        try {
1084            client.setUseClientMode(false);
1085            fail();
1086        } catch (IllegalArgumentException expected) {
1087        }
1088
1089        pair.close();
1090    }
1091
1092    /**
1093     * b/3350645 Test to confirm that an SSLSocket.close() performing
1094     * an SSL_shutdown does not throw an IOException if the peer
1095     * socket has been closed.
1096     */
1097    public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
1098        TestSSLContext c = TestSSLContext.create();
1099        final Socket underlying = new Socket(c.host, c.port);
1100        final SSLSocket wrapping = (SSLSocket)
1101                c.clientContext.getSocketFactory().createSocket(underlying,
1102                                                                c.host.getHostName(),
1103                                                                c.port,
1104                                                                false);
1105        ExecutorService executor = Executors.newSingleThreadExecutor();
1106        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1107            @Override public Void call() throws Exception {
1108                wrapping.startHandshake();
1109                wrapping.getOutputStream().write(42);
1110                // close the underlying socket,
1111                // so that no SSL shutdown is sent
1112                underlying.close();
1113                wrapping.close();
1114                return null;
1115            }
1116        });
1117        executor.shutdown();
1118
1119        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1120        server.startHandshake();
1121        server.getInputStream().read();
1122        // wait for thread to finish so we know client is closed.
1123        clientFuture.get();
1124        // close should cause an SSL_shutdown which will fail
1125        // because the peer has closed, but it shouldn't throw.
1126        server.close();
1127    }
1128
1129    public void test_SSLSocket_setSoTimeout_basic() throws Exception {
1130        ServerSocket listening = new ServerSocket(0);
1131
1132        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1133        assertEquals(0, underlying.getSoTimeout());
1134
1135        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1136        Socket wrapping = sf.createSocket(underlying, null, -1, false);
1137        assertEquals(0, wrapping.getSoTimeout());
1138
1139        // setting wrapper sets underlying and ...
1140        int expectedTimeoutMillis = 1000;  // 10 was too small because it was affected by rounding
1141        wrapping.setSoTimeout(expectedTimeoutMillis);
1142        assertEquals(expectedTimeoutMillis, wrapping.getSoTimeout());
1143        assertEquals(expectedTimeoutMillis, underlying.getSoTimeout());
1144
1145        // ... getting wrapper inspects underlying
1146        underlying.setSoTimeout(0);
1147        assertEquals(0, wrapping.getSoTimeout());
1148        assertEquals(0, underlying.getSoTimeout());
1149    }
1150
1151    public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
1152        if (StandardNames.IS_RI) {
1153            // RI cannot handle this case
1154            return;
1155        }
1156        ServerSocket listening = new ServerSocket(0);
1157
1158        // setSoTimeout applies to read, not connect, so connect first
1159        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1160        Socket server = listening.accept();
1161
1162        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1163        Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
1164
1165        underlying.setSoTimeout(1);
1166        try {
1167            clientWrapping.getInputStream().read();
1168            fail();
1169        } catch (SocketTimeoutException expected) {
1170        }
1171
1172        clientWrapping.close();
1173        server.close();
1174        underlying.close();
1175        listening.close();
1176    }
1177
1178    public void test_SSLSocket_setSoWriteTimeout() throws Exception {
1179        if (StandardNames.IS_RI) {
1180            // RI does not support write timeout on sockets
1181            return;
1182        }
1183
1184        final TestSSLContext c = TestSSLContext.create();
1185        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1186
1187        // Try to make the client SO_SNDBUF size as small as possible
1188        // (it can default to 512k or even megabytes).  Note that
1189        // socket(7) says that the kernel will double the request to
1190        // leave room for its own book keeping and that the minimal
1191        // value will be 2048. Also note that tcp(7) says the value
1192        // needs to be set before connect(2).
1193        int sendBufferSize = 1024;
1194        client.setSendBufferSize(sendBufferSize);
1195        sendBufferSize = client.getSendBufferSize();
1196
1197        // In jb-mr2 it was found that we need to also set SO_RCVBUF
1198        // to a minimal size or the write would not block. While
1199        // tcp(2) says the value has to be set before listen(2), it
1200        // seems fine to set it before accept(2).
1201        final int recvBufferSize = 128;
1202        c.serverSocket.setReceiveBufferSize(recvBufferSize);
1203
1204        client.connect(new InetSocketAddress(c.host, c.port));
1205
1206        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1207        ExecutorService executor = Executors.newSingleThreadExecutor();
1208        Future<Void> future = executor.submit(new Callable<Void>() {
1209            @Override public Void call() throws Exception {
1210                server.startHandshake();
1211                return null;
1212            }
1213        });
1214        executor.shutdown();
1215        client.startHandshake();
1216
1217        // Reflection is used so this can compile on the RI
1218        String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl";
1219        Class actualClass = client.getClass();
1220        assertEquals(expectedClassName, actualClass.getName());
1221        Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
1222                                                         new Class[] { Integer.TYPE });
1223        setSoWriteTimeout.invoke(client, 1);
1224
1225
1226        try {
1227            // Add extra space to the write to exceed the send buffer
1228            // size and cause the write to block.
1229            final int extra = 1;
1230            client.getOutputStream().write(new byte[sendBufferSize + extra]);
1231            fail();
1232        } catch (SocketTimeoutException expected) {
1233        }
1234
1235        future.get();
1236        client.close();
1237        server.close();
1238        c.close();
1239    }
1240
1241    public void test_SSLSocket_interrupt() throws Exception {
1242        test_SSLSocket_interrupt_case(true, true);
1243        test_SSLSocket_interrupt_case(true, false);
1244        test_SSLSocket_interrupt_case(false, true);
1245        // Currently failing due to reader blocking closing thread http://b/10681815
1246        if (StandardNames.IS_RI) {
1247            test_SSLSocket_interrupt_case(false, false);
1248        }
1249    }
1250
1251    private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
1252            throws Exception {
1253
1254        ServerSocket listening = new ServerSocket(0);
1255
1256        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1257        Socket server = listening.accept();
1258
1259        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1260        Socket clientWrapping = sf.createSocket(underlying, null, -1, true);
1261
1262        final Socket toRead = (readUnderlying) ? underlying : clientWrapping;
1263        final Socket toClose = (closeUnderlying) ? underlying : clientWrapping;
1264
1265        ExecutorService executor = Executors.newSingleThreadExecutor();
1266        Future<Void> future = executor.submit(new Callable<Void>() {
1267            @Override public Void call() throws Exception {
1268                Thread.sleep(1 * 1000);
1269                toClose.close();
1270                return null;
1271            }
1272        });
1273        executor.shutdown();
1274        try {
1275            toRead.setSoTimeout(5 * 1000);
1276            toRead.getInputStream().read();
1277            fail();
1278        } catch (SocketTimeoutException e) {
1279            throw e;
1280        } catch (SocketException expected) {
1281        }
1282        future.get();
1283
1284        server.close();
1285        underlying.close();
1286        listening.close();
1287    }
1288
1289    /**
1290     * b/7014266 Test to confirm that an SSLSocket.close() on one
1291     * thread will interupt another thread blocked reading on the same
1292     * socket.
1293     */
1294    public void test_SSLSocket_interrupt_read() throws Exception {
1295        TestSSLContext c = TestSSLContext.create();
1296        final Socket underlying = new Socket(c.host, c.port);
1297        final SSLSocket wrapping = (SSLSocket)
1298                c.clientContext.getSocketFactory().createSocket(underlying,
1299                                                                c.host.getHostName(),
1300                                                                c.port,
1301                                                                false);
1302        ExecutorService executor = Executors.newSingleThreadExecutor();
1303        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1304            @Override public Void call() throws Exception {
1305                try {
1306                    wrapping.startHandshake();
1307                    assertFalse(StandardNames.IS_RI);
1308                    wrapping.setSoTimeout(5 * 1000);
1309                    assertEquals(-1, wrapping.getInputStream().read());
1310                } catch (Exception e) {
1311                    assertTrue(StandardNames.IS_RI);
1312                }
1313                return null;
1314            }
1315        });
1316        executor.shutdown();
1317
1318        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1319        server.startHandshake();
1320        wrapping.close();
1321        clientFuture.get();
1322        server.close();
1323    }
1324
1325    public void test_TestSSLSocketPair_create() {
1326        TestSSLSocketPair test = TestSSLSocketPair.create();
1327        assertNotNull(test.c);
1328        assertNotNull(test.server);
1329        assertNotNull(test.client);
1330        assertTrue(test.server.isConnected());
1331        assertTrue(test.client.isConnected());
1332        assertFalse(test.server.isClosed());
1333        assertFalse(test.client.isClosed());
1334        assertNotNull(test.server.getSession());
1335        assertNotNull(test.client.getSession());
1336        assertTrue(test.server.getSession().isValid());
1337        assertTrue(test.client.getSession().isValid());
1338        test.close();
1339    }
1340
1341    /**
1342     * Not run by default by JUnit, but can be run by Vogar by
1343     * specifying it explicitly (or with main method below)
1344     */
1345    public void stress_test_TestSSLSocketPair_create() {
1346        final boolean verbose = true;
1347        while (true) {
1348            TestSSLSocketPair test = TestSSLSocketPair.create();
1349            if (verbose) {
1350                System.out.println("client=" + test.client.getLocalPort()
1351                                   + " server=" + test.server.getLocalPort());
1352            } else {
1353                System.out.print("X");
1354            }
1355
1356            /*
1357              We don't close on purpose in this stress test to add
1358              races in file descriptors reuse when the garbage
1359              collector runs concurrently and finalizes sockets
1360            */
1361            // test.close();
1362
1363        }
1364    }
1365
1366    public static void main (String[] args) {
1367        new SSLSocketTest().stress_test_TestSSLSocketPair_create();
1368    }
1369}
1370