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 static java.nio.charset.StandardCharsets.UTF_8;
20
21import java.io.ByteArrayInputStream;
22import java.io.Closeable;
23import java.io.DataInputStream;
24import java.io.EOFException;
25import java.io.IOException;
26import java.io.InputStream;
27import java.io.OutputStream;
28import java.lang.Thread.UncaughtExceptionHandler;
29import java.lang.reflect.Method;
30import java.math.BigInteger;
31import java.net.InetAddress;
32import java.net.InetSocketAddress;
33import java.net.ServerSocket;
34import java.net.Socket;
35import java.net.SocketException;
36import java.net.SocketTimeoutException;
37import java.security.AlgorithmParameters;
38import java.security.InvalidAlgorithmParameterException;
39import java.security.InvalidKeyException;
40import java.security.InvalidParameterException;
41import java.security.Key;
42import java.security.KeyManagementException;
43import java.security.NoSuchAlgorithmException;
44import java.security.Principal;
45import java.security.PrivateKey;
46import java.security.Provider;
47import java.security.PublicKey;
48import java.security.SecureRandom;
49import java.security.Security;
50import java.security.Signature;
51import java.security.SignatureException;
52import java.security.SignatureSpi;
53import java.security.cert.Certificate;
54import java.security.cert.CertificateException;
55import java.security.cert.X509Certificate;
56import java.security.interfaces.ECKey;
57import java.security.interfaces.ECPrivateKey;
58import java.security.interfaces.RSAKey;
59import java.security.interfaces.RSAPrivateKey;
60import java.security.spec.AlgorithmParameterSpec;
61import java.security.spec.ECParameterSpec;
62import java.util.ArrayList;
63import java.util.Arrays;
64import java.util.Collections;
65import java.util.List;
66import java.util.concurrent.Callable;
67import java.util.concurrent.ExecutorService;
68import java.util.concurrent.Executors;
69import java.util.concurrent.Future;
70import java.util.concurrent.ThreadFactory;
71import java.util.concurrent.TimeUnit;
72import javax.crypto.BadPaddingException;
73import javax.crypto.Cipher;
74import javax.crypto.CipherSpi;
75import javax.crypto.IllegalBlockSizeException;
76import javax.crypto.NoSuchPaddingException;
77import javax.crypto.SecretKey;
78import javax.crypto.ShortBufferException;
79import javax.crypto.spec.SecretKeySpec;
80import javax.net.ServerSocketFactory;
81import javax.net.SocketFactory;
82import javax.net.ssl.ExtendedSSLSession;
83import javax.net.ssl.HandshakeCompletedEvent;
84import javax.net.ssl.HandshakeCompletedListener;
85import javax.net.ssl.KeyManager;
86import javax.net.ssl.SNIHostName;
87import javax.net.ssl.SNIMatcher;
88import javax.net.ssl.SNIServerName;
89import javax.net.ssl.SSLContext;
90import javax.net.ssl.SSLException;
91import javax.net.ssl.SSLHandshakeException;
92import javax.net.ssl.SSLParameters;
93import javax.net.ssl.SSLPeerUnverifiedException;
94import javax.net.ssl.SSLProtocolException;
95import javax.net.ssl.SSLServerSocket;
96import javax.net.ssl.SSLSession;
97import javax.net.ssl.SSLSocket;
98import javax.net.ssl.SSLSocketFactory;
99import javax.net.ssl.StandardConstants;
100import javax.net.ssl.TrustManager;
101import javax.net.ssl.X509KeyManager;
102import javax.net.ssl.X509TrustManager;
103import junit.framework.TestCase;
104import libcore.java.security.StandardNames;
105import libcore.java.security.TestKeyStore;
106import libcore.tlswire.handshake.CipherSuite;
107import libcore.tlswire.handshake.ClientHello;
108import libcore.tlswire.handshake.CompressionMethod;
109import libcore.tlswire.handshake.EllipticCurve;
110import libcore.tlswire.handshake.EllipticCurvesHelloExtension;
111import libcore.tlswire.handshake.HandshakeMessage;
112import libcore.tlswire.handshake.HelloExtension;
113import libcore.tlswire.handshake.ServerNameHelloExtension;
114import libcore.tlswire.record.TlsProtocols;
115import libcore.tlswire.record.TlsRecord;
116import libcore.tlswire.util.TlsProtocolVersion;
117import tests.net.DelegatingSSLSocketFactory;
118import tests.util.ForEachRunner;
119import tests.util.Pair;
120
121public class SSLSocketTest extends TestCase {
122
123    public void test_SSLSocket_defaultConfiguration() throws Exception {
124        SSLConfigurationAsserts.assertSSLSocketDefaultConfiguration(
125                (SSLSocket) SSLSocketFactory.getDefault().createSocket());
126    }
127
128    public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception {
129        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
130        SSLSocket ssl = (SSLSocket) sf.createSocket();
131        assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites());
132    }
133
134    public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
135        // note the rare usage of non-RSA keys
136        TestKeyStore testKeyStore = new TestKeyStore.Builder()
137                .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
138                .aliasPrefix("rsa-dsa-ec")
139                .ca(true)
140                .build();
141        StringBuilder error = new StringBuilder();
142        test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore, error);
143        if (error.length() > 0) {
144            throw new Exception("One or more problems in "
145                    + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
146        }
147    }
148    private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
149                                                                 StringBuilder error)
150            throws Exception {
151
152        String clientToServerString = "this is sent from the client to the server...";
153        String serverToClientString = "... and this from the server to the client";
154        byte[] clientToServer = clientToServerString.getBytes(UTF_8);
155        byte[] serverToClient = serverToClientString.getBytes(UTF_8);
156
157        KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
158                new PSKKeyManagerProxy() {
159            @Override
160            protected SecretKey getKey(String identityHint, String identity, Socket socket) {
161                return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
162            }
163        });
164        TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
165                testKeyStore, testKeyStore,
166                new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
167
168        String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
169
170        for (String cipherSuite : cipherSuites) {
171            boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
172            try {
173                /*
174                 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
175                 * its own, but instead in conjunction with other
176                 * cipher suites.
177                 */
178                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
179                    continue;
180                }
181                /*
182                 * Similarly with the TLS_FALLBACK_SCSV suite, it is not
183                 * a selectable suite, but is used in conjunction with
184                 * other cipher suites.
185                 */
186                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
187                    continue;
188                }
189                /*
190                 * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
191                 * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
192                 * #KRBRequire
193                 */
194                if (cipherSuite.startsWith("TLS_KRB5_")) {
195                    continue;
196                }
197
198                String[] clientCipherSuiteArray = new String[] {
199                        cipherSuite,
200                        StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION };
201                String[] serverCipherSuiteArray = clientCipherSuiteArray;
202                SSLSocket[] pair = TestSSLSocketPair.connect(c,
203                                                             clientCipherSuiteArray,
204                                                             serverCipherSuiteArray);
205
206                SSLSocket server = pair[0];
207                SSLSocket client = pair[1];
208
209                // Check that the client can read the message sent by the server
210                server.getOutputStream().write(serverToClient);
211                byte[] clientFromServer = new byte[serverToClient.length];
212                readFully(client.getInputStream(), clientFromServer);
213                assertEquals(serverToClientString, new String(clientFromServer));
214
215                // Check that the server can read the message sent by the client
216                client.getOutputStream().write(clientToServer);
217                byte[] serverFromClient = new byte[clientToServer.length];
218                readFully(server.getInputStream(), serverFromClient);
219                assertEquals(clientToServerString, new String(serverFromClient));
220
221                // Check that the server and the client cannot read anything else
222                // (reads should time out)
223                server.setSoTimeout(10);
224                try {
225                  server.getInputStream().read();
226                  fail();
227                } catch (IOException expected) {}
228                client.setSoTimeout(10);
229                try {
230                  client.getInputStream().read();
231                  fail();
232                } catch (IOException expected) {}
233
234                client.close();
235                server.close();
236                assertFalse(errorExpected);
237            } catch (Exception maybeExpected) {
238                if (!errorExpected) {
239                    String message = ("Problem trying to connect cipher suite " + cipherSuite);
240                    System.out.println(message);
241                    maybeExpected.printStackTrace();
242                    error.append(message);
243                    error.append('\n');
244                }
245            }
246        }
247        c.close();
248    }
249
250    public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception {
251        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
252        SSLSocket ssl = (SSLSocket) sf.createSocket();
253        assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites());
254    }
255
256    public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception {
257        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
258        SSLSocket ssl = (SSLSocket) sf.createSocket();
259        String[] array = new String[] {ssl.getEnabledCipherSuites()[0]};
260        String originalFirstElement = array[0];
261        ssl.setEnabledCipherSuites(array);
262        array[0] = "Modified after having been set";
263        assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]);
264    }
265
266    public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
267        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
268        SSLSocket ssl = (SSLSocket) sf.createSocket();
269
270        try {
271            ssl.setEnabledCipherSuites(null);
272            fail();
273        } catch (IllegalArgumentException expected) {
274        }
275        try {
276            ssl.setEnabledCipherSuites(new String[1]);
277            fail();
278        } catch (IllegalArgumentException expected) {
279        }
280        try {
281            ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
282            fail();
283        } catch (IllegalArgumentException expected) {
284        }
285
286        ssl.setEnabledCipherSuites(new String[0]);
287        ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
288        ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
289
290        // Check that setEnabledCipherSuites affects getEnabledCipherSuites
291        String[] cipherSuites = new String[] { ssl.getSupportedCipherSuites()[0] };
292        ssl.setEnabledCipherSuites(cipherSuites);
293        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
294    }
295
296    public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception {
297        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
298        SSLSocket ssl = (SSLSocket) sf.createSocket();
299        assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols());
300    }
301
302    public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception {
303        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
304        SSLSocket ssl = (SSLSocket) sf.createSocket();
305        assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols());
306    }
307
308    public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception {
309        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
310        SSLSocket ssl = (SSLSocket) sf.createSocket();
311        String[] array = new String[] {ssl.getEnabledProtocols()[0]};
312        String originalFirstElement = array[0];
313        ssl.setEnabledProtocols(array);
314        array[0] = "Modified after having been set";
315        assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]);
316    }
317
318    public void test_SSLSocket_setEnabledProtocols() throws Exception {
319        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
320        SSLSocket ssl = (SSLSocket) sf.createSocket();
321
322        try {
323            ssl.setEnabledProtocols(null);
324            fail();
325        } catch (IllegalArgumentException expected) {
326        }
327        try {
328            ssl.setEnabledProtocols(new String[1]);
329            fail();
330        } catch (IllegalArgumentException expected) {
331        }
332        try {
333            ssl.setEnabledProtocols(new String[] { "Bogus" } );
334            fail();
335        } catch (IllegalArgumentException expected) {
336        }
337        ssl.setEnabledProtocols(new String[0]);
338        ssl.setEnabledProtocols(ssl.getEnabledProtocols());
339        ssl.setEnabledProtocols(ssl.getSupportedProtocols());
340
341        // Check that setEnabledProtocols affects getEnabledProtocols
342        for (String protocol : ssl.getSupportedProtocols()) {
343            if ("SSLv2Hello".equals(protocol)) {
344                try {
345                    ssl.setEnabledProtocols(new String[] { protocol });
346                    fail("Should fail when SSLv2Hello is set by itself");
347                } catch (IllegalArgumentException expected) {}
348            } else {
349                String[] protocols = new String[] { protocol };
350                ssl.setEnabledProtocols(protocols);
351                assertEquals(Arrays.deepToString(protocols),
352                        Arrays.deepToString(ssl.getEnabledProtocols()));
353            }
354        }
355    }
356
357    public void test_SSLSocket_getSession() throws Exception {
358        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
359        SSLSocket ssl = (SSLSocket) sf.createSocket();
360        SSLSession session = ssl.getSession();
361        assertNotNull(session);
362        assertFalse(session.isValid());
363    }
364
365    public void test_SSLSocket_getHandshakeSession() throws Exception {
366        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
367        SSLSocket ssl = (SSLSocket) sf.createSocket();
368        SSLSession session = ssl.getHandshakeSession();
369        assertNull(session);
370    }
371
372    public void test_SSLSocket_startHandshake() throws Exception {
373        final TestSSLContext c = TestSSLContext.create();
374        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
375                                                                                       c.port);
376        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
377        ExecutorService executor = Executors.newSingleThreadExecutor();
378        Future<Void> future = executor.submit(new Callable<Void>() {
379            @Override public Void call() throws Exception {
380                server.startHandshake();
381                assertNotNull(server.getSession());
382                assertNull(server.getHandshakeSession());
383                try {
384                    server.getSession().getPeerCertificates();
385                    fail();
386                } catch (SSLPeerUnverifiedException expected) {
387                }
388                Certificate[] localCertificates = server.getSession().getLocalCertificates();
389                assertNotNull(localCertificates);
390                TestKeyStore.assertChainLength(localCertificates);
391                assertNotNull(localCertificates[0]);
392                TestSSLContext.assertServerCertificateChain(c.serverTrustManager,
393                                                            localCertificates);
394                TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
395                                                           c.serverKeyStore);
396                return null;
397            }
398        });
399        executor.shutdown();
400        client.startHandshake();
401        assertNotNull(client.getSession());
402        assertNull(client.getSession().getLocalCertificates());
403        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
404        assertNotNull(peerCertificates);
405        TestKeyStore.assertChainLength(peerCertificates);
406        assertNotNull(peerCertificates[0]);
407        TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
408                                                    peerCertificates);
409        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
410        future.get();
411        client.close();
412        server.close();
413        c.close();
414    }
415
416    private static final class SSLServerSessionIdCallable implements Callable<byte[]> {
417        private final SSLSocket server;
418        private SSLServerSessionIdCallable(SSLSocket server) {
419            this.server = server;
420        }
421        @Override public byte[] call() throws Exception {
422            server.startHandshake();
423            assertNotNull(server.getSession());
424            assertNotNull(server.getSession().getId());
425            return server.getSession().getId();
426        }
427    }
428
429    public void test_SSLSocket_confirmSessionReuse() throws Exception {
430        final TestSSLContext c = TestSSLContext.create();
431        final ExecutorService executor = Executors.newSingleThreadExecutor();
432
433        final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory()
434                .createSocket(c.host.getHostName(), c.port);
435        final SSLSocket server1 = (SSLSocket) c.serverSocket.accept();
436        final Future<byte[]> future1 = executor.submit(new SSLServerSessionIdCallable(server1));
437        client1.startHandshake();
438        assertNotNull(client1.getSession());
439        assertNotNull(client1.getSession().getId());
440        final byte[] clientSessionId1 = client1.getSession().getId();
441        final byte[] serverSessionId1 = future1.get();
442        assertTrue(Arrays.equals(clientSessionId1, serverSessionId1));
443        client1.close();
444        server1.close();
445
446        final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory()
447                .createSocket(c.host.getHostName(), c.port);
448        final SSLSocket server2 = (SSLSocket) c.serverSocket.accept();
449        final Future<byte[]> future2 = executor.submit(new SSLServerSessionIdCallable(server2));
450        client2.startHandshake();
451        assertNotNull(client2.getSession());
452        assertNotNull(client2.getSession().getId());
453        final byte[] clientSessionId2 = client2.getSession().getId();
454        final byte[] serverSessionId2 = future2.get();
455        assertTrue(Arrays.equals(clientSessionId2, serverSessionId2));
456        client2.close();
457        server2.close();
458
459        assertTrue(Arrays.equals(clientSessionId1, clientSessionId2));
460
461        executor.shutdown();
462        c.close();
463    }
464
465    public void test_SSLSocket_NoEnabledCipherSuites_Failure() throws Exception {
466        TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
467                SSLContext.getDefault(), SSLContext.getDefault());
468        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
469                c.port);
470        client.setEnabledCipherSuites(new String[0]);
471        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
472        ExecutorService executor = Executors.newSingleThreadExecutor();
473        Future<Void> future = executor.submit(new Callable<Void>() {
474            @Override
475            public Void call() throws Exception {
476                try {
477                    server.startHandshake();
478                    fail();
479                } catch (SSLHandshakeException expected) {
480                }
481                return null;
482            }
483        });
484        executor.shutdown();
485        try {
486            client.startHandshake();
487            fail();
488        } catch (SSLHandshakeException expected) {
489        }
490        future.get();
491        server.close();
492        client.close();
493        c.close();
494    }
495
496    public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
497        TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
498                                                 SSLContext.getDefault(), SSLContext.getDefault());
499        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
500                                                                                       c.port);
501        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
502        ExecutorService executor = Executors.newSingleThreadExecutor();
503        Future<Void> future = executor.submit(new Callable<Void>() {
504            @Override public Void call() throws Exception {
505                try {
506                    server.startHandshake();
507                    fail();
508                } catch (SSLHandshakeException expected) {
509                }
510                return null;
511            }
512        });
513        executor.shutdown();
514        try {
515            client.startHandshake();
516            fail();
517        } catch (SSLHandshakeException expected) {
518        }
519        future.get();
520        server.close();
521        client.close();
522        c.close();
523    }
524
525    public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
526        TestSSLContext c = TestSSLContext.create();
527        SSLContext serverContext = c.serverContext;
528        SSLContext clientContext = c.clientContext;
529        SSLSocket client = (SSLSocket)
530            clientContext.getSocketFactory().createSocket(c.host, c.port);
531        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
532        ExecutorService executor = Executors.newSingleThreadExecutor();
533        Future<Void> future = executor.submit(new Callable<Void>() {
534            @Override public Void call() throws Exception {
535                server.startHandshake();
536                return null;
537            }
538        });
539        executor.shutdown();
540        client.startHandshake();
541        future.get();
542        client.close();
543        server.close();
544        c.close();
545    }
546
547    public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
548        final TestSSLContext c = TestSSLContext.create();
549        final SSLSocket client = (SSLSocket)
550                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
551        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
552        ExecutorService executor = Executors.newSingleThreadExecutor();
553        Future<Void> future = executor.submit(new Callable<Void>() {
554            @Override public Void call() throws Exception {
555                server.startHandshake();
556                return null;
557            }
558        });
559        executor.shutdown();
560        final boolean[] handshakeCompletedListenerCalled = new boolean[1];
561        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
562            @Override
563            public void handshakeCompleted(HandshakeCompletedEvent event) {
564                try {
565                    SSLSession session = event.getSession();
566                    String cipherSuite = event.getCipherSuite();
567                    Certificate[] localCertificates = event.getLocalCertificates();
568                    Certificate[] peerCertificates = event.getPeerCertificates();
569                    javax.security.cert.X509Certificate[] peerCertificateChain
570                            = event.getPeerCertificateChain();
571                    Principal peerPrincipal = event.getPeerPrincipal();
572                    Principal localPrincipal = event.getLocalPrincipal();
573                    Socket socket = event.getSocket();
574
575                    if (false) {
576                        System.out.println("Session=" + session);
577                        System.out.println("CipherSuite=" + cipherSuite);
578                        System.out.println("LocalCertificates="
579                                + Arrays.toString(localCertificates));
580                        System.out.println("PeerCertificates="
581                                + Arrays.toString(peerCertificates));
582                        System.out.println("PeerCertificateChain="
583                                + Arrays.toString(peerCertificateChain));
584                        System.out.println("PeerPrincipal=" + peerPrincipal);
585                        System.out.println("LocalPrincipal=" + localPrincipal);
586                        System.out.println("Socket=" + socket);
587                    }
588
589                    assertNotNull(session);
590                    byte[] id = session.getId();
591                    assertNotNull(id);
592                    assertEquals(32, id.length);
593                    assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
594
595                    assertNotNull(cipherSuite);
596                    assertTrue(Arrays.asList(
597                            client.getEnabledCipherSuites()).contains(cipherSuite));
598                    assertTrue(Arrays.asList(
599                            c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
600
601                    assertNull(localCertificates);
602
603                    assertNotNull(peerCertificates);
604                    TestKeyStore.assertChainLength(peerCertificates);
605                    assertNotNull(peerCertificates[0]);
606                    TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
607                                                                peerCertificates);
608                    TestSSLContext.assertCertificateInKeyStore(peerCertificates[0],
609                                                               c.serverKeyStore);
610
611                    assertNotNull(peerCertificateChain);
612                    TestKeyStore.assertChainLength(peerCertificateChain);
613                    assertNotNull(peerCertificateChain[0]);
614                    TestSSLContext.assertCertificateInKeyStore(
615                        peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
616
617                    assertNotNull(peerPrincipal);
618                    TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
619
620                    assertNull(localPrincipal);
621
622                    assertNotNull(socket);
623                    assertSame(client, socket);
624
625                    assertTrue(socket instanceof SSLSocket);
626                    assertNull(((SSLSocket) socket).getHandshakeSession());
627
628                    synchronized (handshakeCompletedListenerCalled) {
629                        handshakeCompletedListenerCalled[0] = true;
630                        handshakeCompletedListenerCalled.notify();
631                    }
632                    handshakeCompletedListenerCalled[0] = true;
633                } catch (RuntimeException e) {
634                    throw e;
635                } catch (Exception e) {
636                    throw new RuntimeException(e);
637                }
638            }
639        });
640        client.startHandshake();
641        future.get();
642        if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
643            assertNotNull(c.serverContext.getServerSessionContext().getSession(
644                    client.getSession().getId()));
645        }
646        synchronized (handshakeCompletedListenerCalled) {
647            while (!handshakeCompletedListenerCalled[0]) {
648                handshakeCompletedListenerCalled.wait();
649            }
650        }
651        client.close();
652        server.close();
653        c.close();
654    }
655
656    private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler {
657        Throwable actualException;
658        @Override public void uncaughtException(Thread thread, Throwable ex) {
659            assertNull(actualException);
660            actualException = ex;
661        }
662    }
663
664    public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
665        final Thread self = Thread.currentThread();
666        final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler();
667
668        final RuntimeException expectedException = new RuntimeException("expected");
669        final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler();
670        self.setUncaughtExceptionHandler(test);
671
672        final TestSSLContext c = TestSSLContext.create();
673        final SSLSocket client = (SSLSocket)
674                c.clientContext.getSocketFactory().createSocket(c.host, c.port);
675        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
676        ExecutorService executor = Executors.newSingleThreadExecutor();
677        Future<Void> future = executor.submit(new Callable<Void>() {
678            @Override public Void call() throws Exception {
679                server.startHandshake();
680                return null;
681            }
682        });
683        executor.shutdown();
684        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
685            @Override
686            public void handshakeCompleted(HandshakeCompletedEvent event) {
687                throw expectedException;
688            }
689        });
690        client.startHandshake();
691        future.get();
692        client.close();
693        server.close();
694        c.close();
695
696        assertSame(expectedException, test.actualException);
697        self.setUncaughtExceptionHandler(original);
698    }
699
700    public void test_SSLSocket_getUseClientMode() throws Exception {
701        TestSSLContext c = TestSSLContext.create();
702        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
703                                                                                       c.port);
704        SSLSocket server = (SSLSocket) c.serverSocket.accept();
705        assertTrue(client.getUseClientMode());
706        assertFalse(server.getUseClientMode());
707        client.close();
708        server.close();
709        c.close();
710    }
711
712    public void test_SSLSocket_setUseClientMode() throws Exception {
713        // client is client, server is server
714        test_SSLSocket_setUseClientMode(true, false);
715        // client is server, server is client
716        test_SSLSocket_setUseClientMode(true, false);
717        // both are client
718        try {
719            test_SSLSocket_setUseClientMode(true, true);
720            fail();
721        } catch (SSLProtocolException expected) {
722            assertTrue(StandardNames.IS_RI);
723        } catch (SSLHandshakeException expected) {
724            assertFalse(StandardNames.IS_RI);
725        }
726
727        // both are server
728        try {
729            test_SSLSocket_setUseClientMode(false, false);
730            fail();
731        } catch (SocketTimeoutException expected) {
732        }
733    }
734
735    private void test_SSLSocket_setUseClientMode(final boolean clientClientMode,
736                                                 final boolean serverClientMode)
737            throws Exception {
738        TestSSLContext c = TestSSLContext.create();
739        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
740                                                                                       c.port);
741        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
742
743        ExecutorService executor = Executors.newSingleThreadExecutor();
744        Future<IOException> future = executor.submit(new Callable<IOException>() {
745            @Override public IOException call() throws Exception {
746                try {
747                    if (!serverClientMode) {
748                        server.setSoTimeout(1 * 1000);
749                    }
750                    server.setUseClientMode(serverClientMode);
751                    server.startHandshake();
752                    return null;
753                } catch (SSLHandshakeException e) {
754                    return e;
755                } catch (SocketTimeoutException e) {
756                    return e;
757                }
758            }
759        });
760        executor.shutdown();
761        if (!clientClientMode) {
762            client.setSoTimeout(1 * 1000);
763        }
764        client.setUseClientMode(clientClientMode);
765        client.startHandshake();
766        IOException ioe = future.get();
767        if (ioe != null) {
768            throw ioe;
769        }
770        client.close();
771        server.close();
772        c.close();
773    }
774
775    public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
776
777        // can't set after handshake
778        TestSSLSocketPair pair = TestSSLSocketPair.create();
779        try {
780            pair.server.setUseClientMode(false);
781            fail();
782        } catch (IllegalArgumentException expected) {
783        }
784        try {
785            pair.client.setUseClientMode(false);
786            fail();
787        } catch (IllegalArgumentException expected) {
788        }
789    }
790
791    public void test_SSLSocket_untrustedServer() throws Exception {
792        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(),
793                                                 TestKeyStore.getServer());
794        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
795                                                                                       c.port);
796        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
797        ExecutorService executor = Executors.newSingleThreadExecutor();
798        Future<Void> future = executor.submit(new Callable<Void>() {
799            @Override public Void call() throws Exception {
800                try {
801                    server.startHandshake();
802                    fail();
803                } catch (SSLHandshakeException expected) {
804                }
805                return null;
806            }
807        });
808        executor.shutdown();
809        try {
810            client.startHandshake();
811            fail();
812        } catch (SSLHandshakeException expected) {
813            assertTrue(expected.getCause() instanceof CertificateException);
814        }
815        future.get();
816        client.close();
817        server.close();
818        c.close();
819    }
820
821    public void test_SSLSocket_clientAuth() throws Exception {
822        TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(),
823                                                 TestKeyStore.getServer());
824        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
825                                                                                       c.port);
826        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
827        ExecutorService executor = Executors.newSingleThreadExecutor();
828        Future<Void> future = executor.submit(new Callable<Void>() {
829            @Override public Void call() throws Exception {
830                assertFalse(server.getWantClientAuth());
831                assertFalse(server.getNeedClientAuth());
832
833                // confirm turning one on by itself
834                server.setWantClientAuth(true);
835                assertTrue(server.getWantClientAuth());
836                assertFalse(server.getNeedClientAuth());
837
838                // confirm turning setting on toggles the other
839                server.setNeedClientAuth(true);
840                assertFalse(server.getWantClientAuth());
841                assertTrue(server.getNeedClientAuth());
842
843                // confirm toggling back
844                server.setWantClientAuth(true);
845                assertTrue(server.getWantClientAuth());
846                assertFalse(server.getNeedClientAuth());
847
848                server.startHandshake();
849                return null;
850            }
851        });
852        executor.shutdown();
853        client.startHandshake();
854        assertNotNull(client.getSession().getLocalCertificates());
855        TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
856        TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
857                                                    client.getSession().getLocalCertificates());
858        future.get();
859        client.close();
860        server.close();
861        c.close();
862    }
863
864    public void test_SSLSocket_clientAuth_bogusAlias() throws Exception {
865        TestSSLContext c = TestSSLContext.create();
866        SSLContext clientContext = SSLContext.getInstance("TLS");
867        X509KeyManager keyManager = new X509KeyManager() {
868            @Override public String chooseClientAlias(String[] keyType,
869                                                      Principal[] issuers,
870                                                      Socket socket) {
871                return "bogus";
872            }
873            @Override public String chooseServerAlias(String keyType,
874                                                      Principal[] issuers,
875                                                      Socket socket) {
876                throw new AssertionError();
877            }
878            @Override public X509Certificate[] getCertificateChain(String alias) {
879                // return null for "bogus" alias
880                return null;
881            }
882            @Override public String[] getClientAliases(String keyType, Principal[] issuers) {
883                throw new AssertionError();
884            }
885            @Override public String[] getServerAliases(String keyType, Principal[] issuers) {
886                throw new AssertionError();
887            }
888            @Override public PrivateKey getPrivateKey(String alias) {
889                // return null for "bogus" alias
890                return null;
891            }
892        };
893        clientContext.init(new KeyManager[] { keyManager },
894                           new TrustManager[] { c.clientTrustManager },
895                           null);
896        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
897                                                                                     c.port);
898        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
899        ExecutorService executor = Executors.newSingleThreadExecutor();
900        Future<Void> future = executor.submit(new Callable<Void>() {
901            @Override public Void call() throws Exception {
902                try {
903                    server.setNeedClientAuth(true);
904                    server.startHandshake();
905                    fail();
906                } catch (SSLHandshakeException expected) {
907                }
908                return null;
909            }
910        });
911
912        executor.shutdown();
913        try {
914            client.startHandshake();
915            fail();
916        } catch (SSLHandshakeException expected) {
917            // before we would get a NullPointerException from passing
918            // due to the null PrivateKey return by the X509KeyManager.
919        }
920        future.get();
921        client.close();
922        server.close();
923        c.close();
924    }
925
926    public void test_SSLSocket_clientAuth_OpaqueKey_RSA() throws Exception {
927        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientCertificate());
928    }
929
930    public void test_SSLSocket_clientAuth_OpaqueKey_EC_RSA() throws Exception {
931        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcRsaCertificate());
932    }
933
934    public void test_SSLSocket_clientAuth_OpaqueKey_EC_EC() throws Exception {
935        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcEcCertificate());
936    }
937
938    private void run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore keyStore) throws Exception {
939        try {
940            Security.insertProviderAt(new OpaqueProvider(), 1);
941
942            final TestSSLContext c = TestSSLContext.create(keyStore, TestKeyStore.getServer());
943            SSLContext clientContext = SSLContext.getInstance("TLS");
944            final X509KeyManager delegateKeyManager = (X509KeyManager) c.clientKeyManagers[0];
945            X509KeyManager keyManager = new X509KeyManager() {
946                @Override
947                public String chooseClientAlias(String[] keyType, Principal[] issuers,
948                        Socket socket) {
949                    return delegateKeyManager.chooseClientAlias(keyType, issuers, socket);
950                }
951
952                @Override
953                public String chooseServerAlias(String keyType, Principal[] issuers,
954                        Socket socket) {
955                    return delegateKeyManager.chooseServerAlias(keyType, issuers, socket);
956                }
957
958                @Override
959                public X509Certificate[] getCertificateChain(String alias) {
960                    return delegateKeyManager.getCertificateChain(alias);
961                }
962
963                @Override
964                public String[] getClientAliases(String keyType, Principal[] issuers) {
965                    return delegateKeyManager.getClientAliases(keyType, issuers);
966                }
967
968                @Override
969                public String[] getServerAliases(String keyType, Principal[] issuers) {
970                    return delegateKeyManager.getServerAliases(keyType, issuers);
971                }
972
973                @Override
974                public PrivateKey getPrivateKey(String alias) {
975                    PrivateKey privKey = delegateKeyManager.getPrivateKey(alias);
976                    if (privKey instanceof RSAPrivateKey) {
977                        return new OpaqueDelegatingRSAPrivateKey((RSAPrivateKey) privKey);
978                    } else if (privKey instanceof ECPrivateKey) {
979                        return new OpaqueDelegatingECPrivateKey((ECPrivateKey) privKey);
980                    } else {
981                        return null;
982                    }
983                }
984            };
985            clientContext.init(new KeyManager[] {
986                    keyManager
987            }, new TrustManager[] {
988                    c.clientTrustManager
989            }, null);
990            SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
991                    c.port);
992            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
993            ExecutorService executor = Executors.newSingleThreadExecutor();
994            Future<Void> future = executor.submit(new Callable<Void>() {
995                @Override
996                public Void call() throws Exception {
997                    server.setNeedClientAuth(true);
998                    server.startHandshake();
999                    return null;
1000                }
1001            });
1002            executor.shutdown();
1003            client.startHandshake();
1004            assertNotNull(client.getSession().getLocalCertificates());
1005            TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
1006            TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
1007                    client.getSession().getLocalCertificates());
1008            future.get();
1009            client.close();
1010            server.close();
1011            c.close();
1012        } finally {
1013            Security.removeProvider(OpaqueProvider.NAME);
1014        }
1015    }
1016
1017    @SuppressWarnings("serial")
1018    public static class OpaqueProvider extends Provider {
1019        public static final String NAME = "OpaqueProvider";
1020
1021        public OpaqueProvider() {
1022            super(NAME, 1.0, "test provider");
1023
1024            put("Signature.NONEwithRSA", OpaqueSignatureSpi.RSA.class.getName());
1025            put("Signature.NONEwithECDSA", OpaqueSignatureSpi.ECDSA.class.getName());
1026            put("Cipher.RSA/ECB/NoPadding", OpaqueCipherSpi.class.getName());
1027        }
1028    }
1029
1030    protected static class OpaqueSignatureSpi extends SignatureSpi {
1031        private final String algorithm;
1032
1033        private Signature delegate;
1034
1035        protected OpaqueSignatureSpi(String algorithm) {
1036            this.algorithm = algorithm;
1037        }
1038
1039        public final static class RSA extends OpaqueSignatureSpi {
1040            public RSA() {
1041                super("NONEwithRSA");
1042            }
1043        }
1044
1045        public final static class ECDSA extends OpaqueSignatureSpi {
1046            public ECDSA() {
1047                super("NONEwithECDSA");
1048            }
1049        }
1050
1051        @Override
1052        protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
1053            fail("Cannot verify");
1054        }
1055
1056        @Override
1057        protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
1058            DelegatingPrivateKey opaqueKey = (DelegatingPrivateKey) privateKey;
1059            try {
1060                delegate = Signature.getInstance(algorithm);
1061            } catch (NoSuchAlgorithmException e) {
1062                throw new InvalidKeyException(e);
1063            }
1064            delegate.initSign(opaqueKey.getDelegate());
1065        }
1066
1067        @Override
1068        protected void engineUpdate(byte b) throws SignatureException {
1069            delegate.update(b);
1070        }
1071
1072        @Override
1073        protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
1074            delegate.update(b, off, len);
1075        }
1076
1077        @Override
1078        protected byte[] engineSign() throws SignatureException {
1079            return delegate.sign();
1080        }
1081
1082        @Override
1083        protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
1084            return delegate.verify(sigBytes);
1085        }
1086
1087        @SuppressWarnings("deprecation")
1088        @Override
1089        protected void engineSetParameter(String param, Object value)
1090                throws InvalidParameterException {
1091            delegate.setParameter(param, value);
1092        }
1093
1094        @SuppressWarnings("deprecation")
1095        @Override
1096        protected Object engineGetParameter(String param) throws InvalidParameterException {
1097            return delegate.getParameter(param);
1098        }
1099    }
1100
1101    public static class OpaqueCipherSpi extends CipherSpi {
1102        private Cipher delegate;
1103
1104        public OpaqueCipherSpi() {
1105        }
1106
1107        @Override
1108        protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
1109            fail();
1110        }
1111
1112        @Override
1113        protected void engineSetPadding(String padding) throws NoSuchPaddingException {
1114            fail();
1115        }
1116
1117        @Override
1118        protected int engineGetBlockSize() {
1119            return delegate.getBlockSize();
1120        }
1121
1122        @Override
1123        protected int engineGetOutputSize(int inputLen) {
1124            return delegate.getOutputSize(inputLen);
1125        }
1126
1127        @Override
1128        protected byte[] engineGetIV() {
1129            return delegate.getIV();
1130        }
1131
1132        @Override
1133        protected AlgorithmParameters engineGetParameters() {
1134            return delegate.getParameters();
1135        }
1136
1137        @Override
1138        protected void engineInit(int opmode, Key key, SecureRandom random)
1139                throws InvalidKeyException {
1140            getCipher();
1141            delegate.init(opmode, key, random);
1142        }
1143
1144        protected void getCipher() throws InvalidKeyException {
1145            try {
1146                delegate = Cipher.getInstance("RSA/ECB/NoPadding");
1147            } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
1148                throw new InvalidKeyException(e);
1149            }
1150        }
1151
1152        @Override
1153        protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
1154                SecureRandom random)
1155                throws InvalidKeyException, InvalidAlgorithmParameterException {
1156            getCipher();
1157            delegate.init(opmode, key, params, random);
1158        }
1159
1160        @Override
1161        protected void engineInit(int opmode, Key key, AlgorithmParameters params,
1162                SecureRandom random)
1163                throws InvalidKeyException, InvalidAlgorithmParameterException {
1164            getCipher();
1165            delegate.init(opmode, key, params, random);
1166        }
1167
1168        @Override
1169        protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
1170            return delegate.update(input, inputOffset, inputLen);
1171        }
1172
1173        @Override
1174        protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
1175                int outputOffset) throws ShortBufferException {
1176            return delegate.update(input, inputOffset, inputLen, output, outputOffset);
1177        }
1178
1179        @Override
1180        protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
1181                throws IllegalBlockSizeException, BadPaddingException {
1182            return delegate.update(input, inputOffset, inputLen);
1183        }
1184
1185        @Override
1186        protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
1187                int outputOffset)
1188                throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
1189            return delegate.doFinal(input, inputOffset, inputLen, output, outputOffset);
1190        }
1191    }
1192
1193    private interface DelegatingPrivateKey {
1194        PrivateKey getDelegate();
1195    }
1196
1197    @SuppressWarnings("serial")
1198    private static class OpaqueDelegatingECPrivateKey
1199            implements ECKey, PrivateKey, DelegatingPrivateKey {
1200        private final ECPrivateKey delegate;
1201
1202        public OpaqueDelegatingECPrivateKey(ECPrivateKey delegate) {
1203            this.delegate = delegate;
1204        }
1205
1206        @Override
1207        public PrivateKey getDelegate() {
1208            return delegate;
1209        }
1210
1211        @Override
1212        public String getAlgorithm() {
1213            return delegate.getAlgorithm();
1214        }
1215
1216        @Override
1217        public String getFormat() {
1218            return null;
1219        }
1220
1221        @Override
1222        public byte[] getEncoded() {
1223            return null;
1224        }
1225
1226        @Override
1227        public ECParameterSpec getParams() {
1228            return delegate.getParams();
1229        }
1230    }
1231
1232    @SuppressWarnings("serial")
1233    private static class OpaqueDelegatingRSAPrivateKey
1234            implements RSAKey, PrivateKey, DelegatingPrivateKey {
1235        private final RSAPrivateKey delegate;
1236
1237        public OpaqueDelegatingRSAPrivateKey(RSAPrivateKey delegate) {
1238            this.delegate = delegate;
1239        }
1240
1241        @Override
1242        public String getAlgorithm() {
1243            return delegate.getAlgorithm();
1244        }
1245
1246        @Override
1247        public String getFormat() {
1248            return null;
1249        }
1250
1251        @Override
1252        public byte[] getEncoded() {
1253            return null;
1254        }
1255
1256        @Override
1257        public BigInteger getModulus() {
1258            return delegate.getModulus();
1259        }
1260
1261        @Override
1262        public PrivateKey getDelegate() {
1263            return delegate;
1264        }
1265    }
1266
1267    public void test_SSLSocket_TrustManagerRuntimeException() throws Exception {
1268        TestSSLContext c = TestSSLContext.create();
1269        SSLContext clientContext = SSLContext.getInstance("TLS");
1270        X509TrustManager trustManager = new X509TrustManager() {
1271            @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
1272                    throws CertificateException {
1273                throw new AssertionError();
1274            }
1275            @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
1276                    throws CertificateException {
1277                throw new RuntimeException();  // throw a RuntimeException from custom TrustManager
1278            }
1279            @Override public X509Certificate[] getAcceptedIssuers() {
1280                throw new AssertionError();
1281            }
1282        };
1283        clientContext.init(null, new TrustManager[] { trustManager }, null);
1284        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host,
1285                                                                                     c.port);
1286        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1287        ExecutorService executor = Executors.newSingleThreadExecutor();
1288        Future<Void> future = executor.submit(new Callable<Void>() {
1289            @Override public Void call() throws Exception {
1290                try {
1291                    server.startHandshake();
1292                    fail();
1293                } catch (SSLHandshakeException expected) {
1294                }
1295                return null;
1296            }
1297        });
1298
1299        executor.shutdown();
1300        try {
1301            client.startHandshake();
1302            fail();
1303        } catch (SSLHandshakeException expected) {
1304            // before we would get a RuntimeException from checkServerTrusted.
1305        }
1306        future.get();
1307        client.close();
1308        server.close();
1309        c.close();
1310    }
1311
1312    public void test_SSLSocket_getEnableSessionCreation() throws Exception {
1313        TestSSLContext c = TestSSLContext.create();
1314        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
1315                                                                                       c.port);
1316        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1317        assertTrue(client.getEnableSessionCreation());
1318        assertTrue(server.getEnableSessionCreation());
1319        client.close();
1320        server.close();
1321        c.close();
1322    }
1323
1324    public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
1325        TestSSLContext c = TestSSLContext.create();
1326        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
1327                                                                                       c.port);
1328        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1329        ExecutorService executor = Executors.newSingleThreadExecutor();
1330        Future<Void> future = executor.submit(new Callable<Void>() {
1331            @Override public Void call() throws Exception {
1332                server.setEnableSessionCreation(false);
1333                try {
1334                    server.startHandshake();
1335                    fail();
1336                } catch (SSLException expected) {
1337                }
1338                return null;
1339            }
1340        });
1341        executor.shutdown();
1342        try {
1343            client.startHandshake();
1344            fail();
1345        } catch (SSLException expected) {
1346        }
1347        future.get();
1348        client.close();
1349        server.close();
1350        c.close();
1351    }
1352
1353    public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
1354        TestSSLContext c = TestSSLContext.create();
1355        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
1356                                                                                       c.port);
1357        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1358        ExecutorService executor = Executors.newSingleThreadExecutor();
1359        Future<Void> future = executor.submit(new Callable<Void>() {
1360            @Override public Void call() throws Exception {
1361                try {
1362                    server.startHandshake();
1363                    fail();
1364                } catch (SSLException expected) {
1365                }
1366                return null;
1367            }
1368        });
1369        executor.shutdown();
1370        client.setEnableSessionCreation(false);
1371        try {
1372            client.startHandshake();
1373            fail();
1374        } catch (SSLException expected) {
1375        }
1376        future.get();
1377        client.close();
1378        server.close();
1379        c.close();
1380    }
1381
1382    public void test_SSLSocket_getSSLParameters() throws Exception {
1383        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1384        SSLSocket ssl = (SSLSocket) sf.createSocket();
1385
1386        SSLParameters p = ssl.getSSLParameters();
1387        assertNotNull(p);
1388
1389        String[] cipherSuites = p.getCipherSuites();
1390        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
1391        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
1392
1393        String[] protocols = p.getProtocols();
1394        assertNotSame(protocols, ssl.getEnabledProtocols());
1395        assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
1396
1397        assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
1398        assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
1399
1400        assertNull(p.getEndpointIdentificationAlgorithm());
1401        p.setEndpointIdentificationAlgorithm(null);
1402        assertNull(p.getEndpointIdentificationAlgorithm());
1403        p.setEndpointIdentificationAlgorithm("HTTPS");
1404        assertEquals("HTTPS", p.getEndpointIdentificationAlgorithm());
1405        p.setEndpointIdentificationAlgorithm("FOO");
1406        assertEquals("FOO", p.getEndpointIdentificationAlgorithm());
1407    }
1408
1409    public void test_SSLSocket_setSSLParameters() throws Exception {
1410        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1411        SSLSocket ssl = (SSLSocket) sf.createSocket();
1412        String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
1413        String[] defaultProtocols = ssl.getEnabledProtocols();
1414        String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
1415        String[] supportedProtocols = ssl.getSupportedProtocols();
1416
1417        {
1418            SSLParameters p = new SSLParameters();
1419            ssl.setSSLParameters(p);
1420            assertEquals(Arrays.asList(defaultCipherSuites),
1421                         Arrays.asList(ssl.getEnabledCipherSuites()));
1422            assertEquals(Arrays.asList(defaultProtocols),
1423                         Arrays.asList(ssl.getEnabledProtocols()));
1424        }
1425
1426        {
1427            SSLParameters p = new SSLParameters(supportedCipherSuites,
1428                                                supportedProtocols);
1429            ssl.setSSLParameters(p);
1430            assertEquals(Arrays.asList(supportedCipherSuites),
1431                         Arrays.asList(ssl.getEnabledCipherSuites()));
1432            assertEquals(Arrays.asList(supportedProtocols),
1433                         Arrays.asList(ssl.getEnabledProtocols()));
1434        }
1435        {
1436            SSLParameters p = new SSLParameters();
1437
1438            p.setNeedClientAuth(true);
1439            assertFalse(ssl.getNeedClientAuth());
1440            assertFalse(ssl.getWantClientAuth());
1441            ssl.setSSLParameters(p);
1442            assertTrue(ssl.getNeedClientAuth());
1443            assertFalse(ssl.getWantClientAuth());
1444
1445            p.setWantClientAuth(true);
1446            assertTrue(ssl.getNeedClientAuth());
1447            assertFalse(ssl.getWantClientAuth());
1448            ssl.setSSLParameters(p);
1449            assertFalse(ssl.getNeedClientAuth());
1450            assertTrue(ssl.getWantClientAuth());
1451
1452            p.setWantClientAuth(false);
1453            assertFalse(ssl.getNeedClientAuth());
1454            assertTrue(ssl.getWantClientAuth());
1455            ssl.setSSLParameters(p);
1456            assertFalse(ssl.getNeedClientAuth());
1457            assertFalse(ssl.getWantClientAuth());
1458        }
1459    }
1460
1461    public void test_SSLSocket_close() throws Exception {
1462        TestSSLSocketPair pair = TestSSLSocketPair.create();
1463        SSLSocket server = pair.server;
1464        SSLSocket client = pair.client;
1465        assertFalse(server.isClosed());
1466        assertFalse(client.isClosed());
1467        InputStream input = client.getInputStream();
1468        OutputStream output = client.getOutputStream();
1469        server.close();
1470        client.close();
1471        assertTrue(server.isClosed());
1472        assertTrue(client.isClosed());
1473
1474        // close after close is okay...
1475        server.close();
1476        client.close();
1477
1478        // ...so are a lot of other operations...
1479        HandshakeCompletedListener l = new HandshakeCompletedListener () {
1480            @Override
1481            public void handshakeCompleted(HandshakeCompletedEvent e) {}
1482        };
1483        client.addHandshakeCompletedListener(l);
1484        assertNotNull(client.getEnabledCipherSuites());
1485        assertNotNull(client.getEnabledProtocols());
1486        client.getEnableSessionCreation();
1487        client.getNeedClientAuth();
1488        assertNotNull(client.getSession());
1489        assertNotNull(client.getSSLParameters());
1490        assertNotNull(client.getSupportedProtocols());
1491        client.getUseClientMode();
1492        client.getWantClientAuth();
1493        client.removeHandshakeCompletedListener(l);
1494        client.setEnabledCipherSuites(new String[0]);
1495        client.setEnabledProtocols(new String[0]);
1496        client.setEnableSessionCreation(false);
1497        client.setNeedClientAuth(false);
1498        client.setSSLParameters(client.getSSLParameters());
1499        client.setWantClientAuth(false);
1500
1501        // ...but some operations are expected to give SocketException...
1502        try {
1503            client.startHandshake();
1504            fail();
1505        } catch (SocketException expected) {
1506        }
1507        try {
1508            client.getInputStream();
1509            fail();
1510        } catch (SocketException expected) {
1511        }
1512        try {
1513            client.getOutputStream();
1514            fail();
1515        } catch (SocketException expected) {
1516        }
1517        try {
1518            input.read();
1519            fail();
1520        } catch (SocketException expected) {
1521        }
1522        try {
1523            input.read(null, -1, -1);
1524            fail();
1525        } catch (NullPointerException expected) {
1526            assertTrue(StandardNames.IS_RI);
1527        } catch (SocketException expected) {
1528            assertFalse(StandardNames.IS_RI);
1529        }
1530        try {
1531            output.write(-1);
1532            fail();
1533        } catch (SocketException expected) {
1534        }
1535        try {
1536            output.write(null, -1, -1);
1537            fail();
1538        } catch (NullPointerException expected) {
1539            assertTrue(StandardNames.IS_RI);
1540        } catch (SocketException expected) {
1541            assertFalse(StandardNames.IS_RI);
1542        }
1543
1544        // ... and one gives IllegalArgumentException
1545        try {
1546            client.setUseClientMode(false);
1547            fail();
1548        } catch (IllegalArgumentException expected) {
1549        }
1550
1551        pair.close();
1552    }
1553
1554    /**
1555     * b/3350645 Test to confirm that an SSLSocket.close() performing
1556     * an SSL_shutdown does not throw an IOException if the peer
1557     * socket has been closed.
1558     */
1559    public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
1560        TestSSLContext c = TestSSLContext.create();
1561        final Socket underlying = new Socket(c.host, c.port);
1562        final SSLSocket wrapping = (SSLSocket)
1563                c.clientContext.getSocketFactory().createSocket(underlying,
1564                                                                c.host.getHostName(),
1565                                                                c.port,
1566                                                                false);
1567        ExecutorService executor = Executors.newSingleThreadExecutor();
1568        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1569            @Override public Void call() throws Exception {
1570                wrapping.startHandshake();
1571                wrapping.getOutputStream().write(42);
1572                // close the underlying socket,
1573                // so that no SSL shutdown is sent
1574                underlying.close();
1575                wrapping.close();
1576                return null;
1577            }
1578        });
1579        executor.shutdown();
1580
1581        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1582        server.startHandshake();
1583        server.getInputStream().read();
1584        // wait for thread to finish so we know client is closed.
1585        clientFuture.get();
1586        // close should cause an SSL_shutdown which will fail
1587        // because the peer has closed, but it shouldn't throw.
1588        server.close();
1589    }
1590
1591    public void test_SSLSocket_endpointIdentification_Success() throws Exception {
1592        final TestSSLContext c = TestSSLContext.create();
1593        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1594        SSLParameters p = client.getSSLParameters();
1595        p.setEndpointIdentificationAlgorithm("HTTPS");
1596        client.connect(new InetSocketAddress(c.host, c.port));
1597        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1598        ExecutorService executor = Executors.newSingleThreadExecutor();
1599        Future<Void> future = executor.submit(new Callable<Void>() {
1600            @Override public Void call() throws Exception {
1601                server.startHandshake();
1602                assertNotNull(server.getSession());
1603                try {
1604                    server.getSession().getPeerCertificates();
1605                    fail();
1606                } catch (SSLPeerUnverifiedException expected) {
1607                }
1608                Certificate[] localCertificates = server.getSession().getLocalCertificates();
1609                assertNotNull(localCertificates);
1610                TestKeyStore.assertChainLength(localCertificates);
1611                assertNotNull(localCertificates[0]);
1612                TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
1613                                                           c.serverKeyStore);
1614                return null;
1615            }
1616        });
1617        executor.shutdown();
1618        client.startHandshake();
1619        assertNotNull(client.getSession());
1620        assertNull(client.getSession().getLocalCertificates());
1621        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
1622        assertNotNull(peerCertificates);
1623        TestKeyStore.assertChainLength(peerCertificates);
1624        assertNotNull(peerCertificates[0]);
1625        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
1626        future.get();
1627        client.close();
1628        server.close();
1629        c.close();
1630    }
1631
1632    public void test_SSLSocket_endpointIdentification_Failure() throws Exception {
1633        final TestSSLContext c = TestSSLContext.create();
1634        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1635        SSLParameters p = client.getSSLParameters();
1636        p.setEndpointIdentificationAlgorithm("HTTPS");
1637        client.setSSLParameters(p);
1638        client.connect(c.getLoopbackAsHostname("unmatched.example.com", c.port));
1639        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1640        ExecutorService executor = Executors.newSingleThreadExecutor();
1641        Future<Void> future = executor.submit(new Callable<Void>() {
1642            @Override public Void call() throws Exception {
1643                try {
1644                    server.startHandshake();
1645                    fail("Should receive SSLHandshakeException as server");
1646                } catch (SSLHandshakeException expected) {
1647                }
1648                return null;
1649            }
1650        });
1651        executor.shutdown();
1652        try {
1653            client.startHandshake();
1654            fail("Should throw when hostname does not match expected");
1655        } catch (SSLHandshakeException expected) {
1656        } finally {
1657            try {
1658                future.get();
1659            } finally {
1660                client.close();
1661                server.close();
1662                c.close();
1663            }
1664        }
1665    }
1666
1667    public void test_SSLSocket_setSoTimeout_basic() throws Exception {
1668        ServerSocket listening = new ServerSocket(0);
1669
1670        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1671        assertEquals(0, underlying.getSoTimeout());
1672
1673        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1674        Socket wrapping = sf.createSocket(underlying, null, -1, false);
1675        assertEquals(0, wrapping.getSoTimeout());
1676
1677        // setting wrapper sets underlying and ...
1678        int expectedTimeoutMillis = 1000;  // 10 was too small because it was affected by rounding
1679        wrapping.setSoTimeout(expectedTimeoutMillis);
1680        // The kernel can round the requested value based on the HZ setting. We allow up to 10ms.
1681        assertTrue(Math.abs(expectedTimeoutMillis - wrapping.getSoTimeout()) <= 10);
1682        assertTrue(Math.abs(expectedTimeoutMillis - underlying.getSoTimeout()) <= 10);
1683
1684        // ... getting wrapper inspects underlying
1685        underlying.setSoTimeout(0);
1686        assertEquals(0, wrapping.getSoTimeout());
1687        assertEquals(0, underlying.getSoTimeout());
1688    }
1689
1690    public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
1691        if (StandardNames.IS_RI) {
1692            // RI cannot handle this case
1693            return;
1694        }
1695        ServerSocket listening = new ServerSocket(0);
1696
1697        // setSoTimeout applies to read, not connect, so connect first
1698        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1699        Socket server = listening.accept();
1700
1701        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1702        Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
1703
1704        underlying.setSoTimeout(1);
1705        try {
1706            clientWrapping.getInputStream().read();
1707            fail();
1708        } catch (SocketTimeoutException expected) {
1709        }
1710
1711        clientWrapping.close();
1712        server.close();
1713        underlying.close();
1714        listening.close();
1715    }
1716
1717    public void test_SSLSocket_setSoWriteTimeout() throws Exception {
1718        if (StandardNames.IS_RI) {
1719            // RI does not support write timeout on sockets
1720            return;
1721        }
1722
1723        final TestSSLContext c = TestSSLContext.create();
1724        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1725
1726        // Try to make the client SO_SNDBUF size as small as possible
1727        // (it can default to 512k or even megabytes).  Note that
1728        // socket(7) says that the kernel will double the request to
1729        // leave room for its own book keeping and that the minimal
1730        // value will be 2048. Also note that tcp(7) says the value
1731        // needs to be set before connect(2).
1732        int sendBufferSize = 1024;
1733        client.setSendBufferSize(sendBufferSize);
1734        sendBufferSize = client.getSendBufferSize();
1735
1736        // In jb-mr2 it was found that we need to also set SO_RCVBUF
1737        // to a minimal size or the write would not block. While
1738        // tcp(2) says the value has to be set before listen(2), it
1739        // seems fine to set it before accept(2).
1740        final int recvBufferSize = 128;
1741        c.serverSocket.setReceiveBufferSize(recvBufferSize);
1742
1743        client.connect(new InetSocketAddress(c.host, c.port));
1744
1745        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1746        ExecutorService executor = Executors.newSingleThreadExecutor();
1747        Future<Void> future = executor.submit(new Callable<Void>() {
1748            @Override public Void call() throws Exception {
1749                server.startHandshake();
1750                return null;
1751            }
1752        });
1753        executor.shutdown();
1754        client.startHandshake();
1755
1756        // Reflection is used so this can compile on the RI
1757        String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl";
1758        Class<?> actualClass = client.getClass();
1759        assertEquals(expectedClassName, actualClass.getName());
1760        Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
1761                                                         new Class<?>[] { Integer.TYPE });
1762        setSoWriteTimeout.invoke(client, 1);
1763
1764
1765        try {
1766            // Add extra space to the write to exceed the send buffer
1767            // size and cause the write to block.
1768            final int extra = 1;
1769            client.getOutputStream().write(new byte[sendBufferSize + extra]);
1770            fail();
1771        } catch (SocketTimeoutException expected) {
1772        }
1773
1774        future.get();
1775        client.close();
1776        server.close();
1777        c.close();
1778    }
1779
1780    public void test_SSLSocket_reusedNpnSocket() throws Exception {
1781        if (StandardNames.IS_RI) {
1782            // RI does not support NPN/ALPN
1783            return;
1784        }
1785
1786        byte[] npnProtocols = new byte[] {
1787                8, 'h', 't', 't', 'p', '/', '1', '.', '1'
1788        };
1789
1790        final TestSSLContext c = TestSSLContext.create();
1791        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1792
1793        // Reflection is used so this can compile on the RI
1794        String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl";
1795        Class<?> actualClass = client.getClass();
1796        assertEquals(expectedClassName, actualClass.getName());
1797        Method setNpnProtocols = actualClass.getMethod("setNpnProtocols", byte[].class);
1798
1799        ExecutorService executor = Executors.newSingleThreadExecutor();
1800
1801        // First connection with NPN set on client and server
1802        {
1803            setNpnProtocols.invoke(client, npnProtocols);
1804            client.connect(new InetSocketAddress(c.host, c.port));
1805
1806            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
1807            assertEquals(expectedClassName, server.getClass().getName());
1808            setNpnProtocols.invoke(server, npnProtocols);
1809
1810            Future<Void> future = executor.submit(new Callable<Void>() {
1811                @Override
1812                public Void call() throws Exception {
1813                    server.startHandshake();
1814                    return null;
1815                }
1816            });
1817            client.startHandshake();
1818
1819            future.get();
1820            client.close();
1821            server.close();
1822        }
1823
1824        // Second connection with client NPN already set on the SSL context, but
1825        // without server NPN set.
1826        {
1827            SSLServerSocket serverSocket = (SSLServerSocket) c.serverContext
1828                    .getServerSocketFactory().createServerSocket(0);
1829            InetAddress host = InetAddress.getLocalHost();
1830            int port = serverSocket.getLocalPort();
1831
1832            client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
1833            client.connect(new InetSocketAddress(host, port));
1834
1835            final SSLSocket server = (SSLSocket) serverSocket.accept();
1836
1837            Future<Void> future = executor.submit(new Callable<Void>() {
1838                @Override
1839                public Void call() throws Exception {
1840                    server.startHandshake();
1841                    return null;
1842                }
1843            });
1844            client.startHandshake();
1845
1846            future.get();
1847            client.close();
1848            server.close();
1849            serverSocket.close();
1850        }
1851
1852        c.close();
1853    }
1854
1855    public void test_SSLSocket_interrupt() throws Exception {
1856        test_SSLSocket_interrupt_case(true, true);
1857        test_SSLSocket_interrupt_case(true, false);
1858        test_SSLSocket_interrupt_case(false, true);
1859        test_SSLSocket_interrupt_case(false, false);
1860    }
1861
1862    private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
1863            throws Exception {
1864
1865        ServerSocket listening = new ServerSocket(0);
1866
1867        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
1868        Socket server = listening.accept();
1869
1870        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
1871        Socket clientWrapping = sf.createSocket(underlying, null, -1, true);
1872
1873        final Socket toRead = (readUnderlying) ? underlying : clientWrapping;
1874        final Socket toClose = (closeUnderlying) ? underlying : clientWrapping;
1875
1876        ExecutorService executor = Executors.newSingleThreadExecutor();
1877        Future<Void> future = executor.submit(new Callable<Void>() {
1878            @Override public Void call() throws Exception {
1879                Thread.sleep(1 * 1000);
1880                toClose.close();
1881                return null;
1882            }
1883        });
1884        executor.shutdown();
1885        try {
1886            toRead.setSoTimeout(5 * 1000);
1887            toRead.getInputStream().read();
1888            fail();
1889        } catch (SocketTimeoutException e) {
1890            throw e;
1891        } catch (SocketException expected) {
1892        }
1893        future.get();
1894
1895        server.close();
1896        underlying.close();
1897        listening.close();
1898    }
1899
1900    /**
1901     * b/7014266 Test to confirm that an SSLSocket.close() on one
1902     * thread will interrupt another thread blocked reading on the same
1903     * socket.
1904     */
1905    public void test_SSLSocket_interrupt_read() throws Exception {
1906        final int readingTimeoutMillis = 5000;
1907        TestSSLContext c = TestSSLContext.create();
1908        final Socket underlying = new Socket(c.host, c.port);
1909        final SSLSocket wrapping = (SSLSocket)
1910                c.clientContext.getSocketFactory().createSocket(underlying,
1911                                                                c.host.getHostName(),
1912                                                                c.port,
1913                                                                false);
1914
1915        // Create our own thread group so we can inspect the stack state later.
1916        final ThreadGroup clientGroup = new ThreadGroup("client");
1917        ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
1918            @Override
1919            public Thread newThread(Runnable r) {
1920                return new Thread(clientGroup, r);
1921            }
1922        });
1923
1924        Future<Void> clientFuture = executor.submit(new Callable<Void>() {
1925            @Override public Void call() throws Exception {
1926                try {
1927                    wrapping.startHandshake();
1928                    assertFalse(StandardNames.IS_RI);
1929                    wrapping.setSoTimeout(readingTimeoutMillis);
1930                    assertEquals(-1, wrapping.getInputStream().read());
1931                } catch (Exception e) {
1932                    if (!StandardNames.IS_RI) {
1933                        throw e;
1934                    }
1935                }
1936                return null;
1937            }
1938        });
1939        executor.shutdown();
1940
1941        SSLSocket server = (SSLSocket) c.serverSocket.accept();
1942        server.startHandshake();
1943
1944        /*
1945         * Wait for the client to at least be in the "read" method before
1946         * calling close()
1947         */
1948        Thread[] threads = new Thread[1];
1949        clientGroup.enumerate(threads);
1950        if (threads[0] != null) {
1951            boolean clientInRead = false;
1952            while (!clientInRead) {
1953                StackTraceElement[] elements = threads[0].getStackTrace();
1954                for (StackTraceElement element : elements) {
1955                    if ("read".equals(element.getMethodName())) {
1956                        // The client might be executing "read" but still not have reached the
1957                        // point in which it's blocked reading. This is causing flakiness
1958                        // (b/24367646). Delaying for a fraction of the timeout.
1959                        Thread.sleep(1000);
1960                        clientInRead = true;
1961                        break;
1962                    }
1963                }
1964            }
1965        }
1966
1967        wrapping.close();
1968        clientFuture.get();
1969        server.close();
1970    }
1971
1972    public void test_TestSSLSocketPair_create() {
1973        TestSSLSocketPair test = TestSSLSocketPair.create();
1974        assertNotNull(test.c);
1975        assertNotNull(test.server);
1976        assertNotNull(test.client);
1977        assertTrue(test.server.isConnected());
1978        assertTrue(test.client.isConnected());
1979        assertFalse(test.server.isClosed());
1980        assertFalse(test.client.isClosed());
1981        assertNotNull(test.server.getSession());
1982        assertNotNull(test.client.getSession());
1983        assertTrue(test.server.getSession().isValid());
1984        assertTrue(test.client.getSession().isValid());
1985        test.close();
1986    }
1987
1988    public void test_SSLSocket_ClientHello_record_size() throws Exception {
1989        // This test checks the size of ClientHello of the default SSLSocket. TLS/SSL handshakes
1990        // with older/unpatched F5/BIG-IP appliances are known to stall and time out when
1991        // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long.
1992        SSLContext sslContext = SSLContext.getInstance("TLS");
1993        sslContext.init(null, null, null);
1994        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
1995        sslSocketFactory = new DelegatingSSLSocketFactory(sslSocketFactory) {
1996            @Override
1997            protected SSLSocket configureSocket(SSLSocket socket) {
1998                // Enable SNI extension on the socket (this is typically enabled by default)
1999                // to increase the size of ClientHello.
2000                try {
2001                    Method setHostname =
2002                            socket.getClass().getMethod("setHostname", String.class);
2003                    setHostname.invoke(socket, "sslsockettest.androidcts.google.com");
2004                } catch (NoSuchMethodException ignored) {
2005                } catch (Exception e) {
2006                    throw new RuntimeException("Failed to enable SNI", e);
2007                }
2008
2009                // Enable Session Tickets extension on the socket (this is typically enabled
2010                // by default) to increase the size of ClientHello.
2011                try {
2012                    Method setUseSessionTickets =
2013                            socket.getClass().getMethod(
2014                                    "setUseSessionTickets", boolean.class);
2015                    setUseSessionTickets.invoke(socket, true);
2016                } catch (NoSuchMethodException ignored) {
2017                } catch (Exception e) {
2018                    throw new RuntimeException("Failed to enable Session Tickets", e);
2019                }
2020                return socket;
2021            }
2022        };
2023
2024        TlsRecord firstReceivedTlsRecord = captureTlsHandshakeFirstTlsRecord(sslSocketFactory);
2025        assertEquals("TLS record type", TlsProtocols.HANDSHAKE, firstReceivedTlsRecord.type);
2026        HandshakeMessage handshakeMessage = HandshakeMessage.read(
2027                new DataInputStream(new ByteArrayInputStream(firstReceivedTlsRecord.fragment)));
2028        assertEquals("HandshakeMessage type",
2029                HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
2030        int fragmentLength = firstReceivedTlsRecord.fragment.length;
2031        if ((fragmentLength >= 256) && (fragmentLength <= 511)) {
2032            fail("Fragment containing ClientHello is of dangerous length: "
2033                    + fragmentLength + " bytes");
2034        }
2035    }
2036
2037    public void test_SSLSocket_ClientHello_cipherSuites() throws Exception {
2038        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
2039            @Override
2040            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
2041                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
2042                final String[] cipherSuites;
2043
2044                // RFC 5746 allows you to send an empty "renegotiation_info" extension *or*
2045                // a special signaling cipher suite. The TLS API has no way to check or
2046                // indicate that a certain TLS extension should be used.
2047                HelloExtension renegotiationInfoExtension = clientHello.findExtensionByType(
2048                        HelloExtension.TYPE_RENEGOTIATION_INFO);
2049                if (renegotiationInfoExtension != null &&
2050                        renegotiationInfoExtension.data.length == 1 &&
2051                        renegotiationInfoExtension.data[0] == 0) {
2052                    cipherSuites = new String[clientHello.cipherSuites.size() + 1];
2053                    cipherSuites[clientHello.cipherSuites.size()] =
2054                            StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION;
2055                } else {
2056                    cipherSuites = new String[clientHello.cipherSuites.size()];
2057                }
2058
2059                for (int i = 0; i < clientHello.cipherSuites.size(); i++) {
2060                    CipherSuite cipherSuite = clientHello.cipherSuites.get(i);
2061                    cipherSuites[i] = cipherSuite.getAndroidName();
2062                }
2063                StandardNames.assertDefaultCipherSuites(cipherSuites);
2064            }
2065        }, getSSLSocketFactoriesToTest());
2066    }
2067
2068    public void test_SSLSocket_ClientHello_supportedCurves() throws Exception {
2069        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
2070            @Override
2071            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
2072                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
2073
2074                EllipticCurvesHelloExtension ecExtension = (EllipticCurvesHelloExtension)
2075                        clientHello.findExtensionByType(HelloExtension.TYPE_ELLIPTIC_CURVES);
2076                final String[] supportedCurves;
2077                if (ecExtension == null) {
2078                    supportedCurves = new String[0];
2079                } else {
2080                    assertTrue(ecExtension.wellFormed);
2081                    supportedCurves = new String[ecExtension.supported.size()];
2082                    for (int i = 0; i < ecExtension.supported.size(); i++) {
2083                        EllipticCurve curve = ecExtension.supported.get(i);
2084                        supportedCurves[i] = curve.toString();
2085                    }
2086                }
2087
2088                StandardNames.assertDefaultEllipticCurves(supportedCurves);
2089            }
2090        }, getSSLSocketFactoriesToTest());
2091    }
2092
2093    public void test_SSLSocket_ClientHello_clientProtocolVersion() throws Exception {
2094        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
2095            @Override
2096            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
2097                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
2098                assertEquals(TlsProtocolVersion.TLSv1_2, clientHello.clientVersion);
2099            }
2100        }, getSSLSocketFactoriesToTest());
2101    }
2102
2103    public void test_SSLSocket_ClientHello_compressionMethods() throws Exception {
2104        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
2105            @Override
2106            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
2107                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
2108                assertEquals(Arrays.asList(CompressionMethod.NULL), clientHello.compressionMethods);
2109            }
2110        }, getSSLSocketFactoriesToTest());
2111    }
2112
2113    public void test_SSLSocket_ClientHello_SNI() throws Exception {
2114        ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() {
2115            @Override
2116            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
2117                ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory);
2118                ServerNameHelloExtension sniExtension = (ServerNameHelloExtension)
2119                        clientHello.findExtensionByType(HelloExtension.TYPE_SERVER_NAME);
2120                assertNotNull(sniExtension);
2121                assertEquals(Arrays.asList("localhost.localdomain"), sniExtension.hostnames);
2122            }
2123        }, getSSLSocketFactoriesToTest());
2124    }
2125
2126    private List<Pair<String, SSLSocketFactory>> getSSLSocketFactoriesToTest()
2127            throws NoSuchAlgorithmException, KeyManagementException {
2128        List<Pair<String, SSLSocketFactory>> result =
2129                new ArrayList<Pair<String, SSLSocketFactory>>();
2130        result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault()));
2131        for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
2132            SSLContext sslContext = SSLContext.getInstance(sslContextProtocol);
2133            if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) {
2134                continue;
2135            }
2136            sslContext.init(null, null, null);
2137            result.add(Pair.of(
2138                    "SSLContext(\"" + sslContext.getProtocol() + "\")",
2139                    sslContext.getSocketFactory()));
2140        }
2141        return result;
2142    }
2143
2144    private ClientHello captureTlsHandshakeClientHello(SSLSocketFactory sslSocketFactory)
2145            throws Exception {
2146        TlsRecord record = captureTlsHandshakeFirstTlsRecord(sslSocketFactory);
2147        assertEquals("TLS record type", TlsProtocols.HANDSHAKE, record.type);
2148        ByteArrayInputStream fragmentIn = new ByteArrayInputStream(record.fragment);
2149        HandshakeMessage handshakeMessage = HandshakeMessage.read(new DataInputStream(fragmentIn));
2150        assertEquals("HandshakeMessage type",
2151                HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
2152        // Assert that the fragment does not contain any more messages
2153        assertEquals(0, fragmentIn.available());
2154
2155        return (ClientHello) handshakeMessage;
2156    }
2157
2158    private TlsRecord captureTlsHandshakeFirstTlsRecord(SSLSocketFactory sslSocketFactory)
2159            throws Exception {
2160        byte[] firstReceivedChunk = captureTlsHandshakeFirstTransmittedChunkBytes(sslSocketFactory);
2161        ByteArrayInputStream firstReceivedChunkIn = new ByteArrayInputStream(firstReceivedChunk);
2162        TlsRecord record = TlsRecord.read(new DataInputStream(firstReceivedChunkIn));
2163        // Assert that the chunk does not contain any more data
2164        assertEquals(0, firstReceivedChunkIn.available());
2165
2166        return record;
2167    }
2168
2169    private byte[] captureTlsHandshakeFirstTransmittedChunkBytes(
2170            final SSLSocketFactory sslSocketFactory) throws Exception {
2171        // Since there's no straightforward way to obtain a ClientHello from SSLSocket, this test
2172        // does the following:
2173        // 1. Creates a listening server socket (a plain one rather than a TLS/SSL one).
2174        // 2. Creates a client SSLSocket, which connects to the server socket and initiates the
2175        //    TLS/SSL handshake.
2176        // 3. Makes the server socket accept an incoming connection on the server socket, and reads
2177        //    the first chunk of data received. This chunk is assumed to be the ClientHello.
2178        // NOTE: Steps 2 and 3 run concurrently.
2179        ServerSocket listeningSocket = null;
2180        ExecutorService executorService = Executors.newFixedThreadPool(2);
2181
2182        // Some Socket operations are not interruptible via Thread.interrupt for some reason. To
2183        // work around, we unblock these sockets using Socket.close.
2184        final Socket[] sockets = new Socket[2];
2185        try {
2186            // 1. Create the listening server socket.
2187            listeningSocket = ServerSocketFactory.getDefault().createServerSocket(0);
2188            final ServerSocket finalListeningSocket = listeningSocket;
2189            // 2. (in background) Wait for an incoming connection and read its first chunk.
2190            final Future<byte[]> readFirstReceivedChunkFuture =
2191                    executorService.submit(new Callable<byte[]>() {
2192                        @Override
2193                        public byte[] call() throws Exception {
2194                            Socket socket = finalListeningSocket.accept();
2195                            sockets[1] = socket;
2196                            try {
2197                                byte[] buffer = new byte[64 * 1024];
2198                                int bytesRead = socket.getInputStream().read(buffer);
2199                                if (bytesRead == -1) {
2200                                    throw new EOFException("Failed to read anything");
2201                                }
2202                                return Arrays.copyOf(buffer, bytesRead);
2203                            } finally {
2204                                closeQuietly(socket);
2205                            }
2206                        }
2207                    });
2208
2209            // 3. Create a client socket, connect it to the server socket, and start the TLS/SSL
2210            //    handshake.
2211            executorService.submit(new Callable<Void>() {
2212                @Override
2213                public Void call() throws Exception {
2214                    Socket client = new Socket();
2215                    sockets[0] = client;
2216                    try {
2217                        client.connect(finalListeningSocket.getLocalSocketAddress());
2218                        // Initiate the TLS/SSL handshake which is expected to fail as soon as the
2219                        // server socket receives a ClientHello.
2220                        try {
2221                            SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
2222                                    client,
2223                                    "localhost.localdomain",
2224                                    finalListeningSocket.getLocalPort(),
2225                                    true);
2226                            sslSocket.startHandshake();
2227                            fail();
2228                            return null;
2229                        } catch (IOException expected) {}
2230                        return null;
2231                    } finally {
2232                        closeQuietly(client);
2233                    }
2234                }
2235            });
2236
2237            // Wait for the ClientHello to arrive
2238            return readFirstReceivedChunkFuture.get(10, TimeUnit.SECONDS);
2239        } finally {
2240            executorService.shutdownNow();
2241            closeQuietly(listeningSocket);
2242            closeQuietly(sockets[0]);
2243            closeQuietly(sockets[1]);
2244            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
2245                fail("Timed out while waiting for the test to shut down");
2246            }
2247        }
2248    }
2249
2250    // http://b/18428603
2251    public void test_SSLSocket_getPortWithSNI() throws Exception {
2252        TestSSLContext context = TestSSLContext.create();
2253
2254        SSLSocket client = null;
2255        try {
2256            client = (SSLSocket) context.clientContext.getSocketFactory().createSocket();
2257            client.connect(new InetSocketAddress(context.host, context.port));
2258            try {
2259                // This is crucial to reproducing issue 18428603.
2260                Method setHostname = client.getClass().getMethod("setHostname", String.class);
2261                setHostname.invoke(client, "sslsockettest.androidcts.google.com");
2262            } catch (NoSuchMethodException ignored) {
2263            }
2264
2265            assertTrue(client.getPort() > 0);
2266        } finally {
2267            client.close();
2268            context.close();
2269        }
2270    }
2271
2272    public void test_SSLSocket_SNIHostName() throws Exception {
2273        TestSSLContext c = TestSSLContext.create();
2274
2275        final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
2276        SSLParameters clientParams = client.getSSLParameters();
2277        clientParams.setServerNames(Collections.singletonList(
2278                (SNIServerName) new SNIHostName("www.example.com")));
2279        client.setSSLParameters(clientParams);
2280
2281        SSLParameters serverParams = c.serverSocket.getSSLParameters();
2282        serverParams.setSNIMatchers(Collections.singletonList(
2283                SNIHostName.createSNIMatcher("www\\.example\\.com")));
2284        c.serverSocket.setSSLParameters(serverParams);
2285
2286        client.connect(new InetSocketAddress(c.host, c.port));
2287        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
2288
2289        ExecutorService executor = Executors.newSingleThreadExecutor();
2290        Future<Void> future = executor.submit(new Callable<Void>() {
2291            @Override public Void call() throws Exception {
2292                client.startHandshake();
2293                return null;
2294            }
2295        });
2296        executor.shutdown();
2297        server.startHandshake();
2298
2299        SSLSession serverSession = server.getSession();
2300        assertTrue(serverSession instanceof ExtendedSSLSession);
2301        ExtendedSSLSession extendedServerSession = (ExtendedSSLSession) serverSession;
2302        List<SNIServerName> requestedNames = extendedServerSession.getRequestedServerNames();
2303        assertNotNull(requestedNames);
2304        assertEquals(1, requestedNames.size());
2305        SNIServerName serverName = requestedNames.get(0);
2306        assertEquals(StandardConstants.SNI_HOST_NAME, serverName.getType());
2307        assertTrue(serverName instanceof SNIHostName);
2308        SNIHostName serverHostName = (SNIHostName) serverName;
2309        assertEquals("www.example.com", serverHostName.getAsciiName());
2310    }
2311
2312    public void test_SSLSocket_sendsTlsFallbackScsv_Fallback_Success() throws Exception {
2313        TestSSLContext context = TestSSLContext.create();
2314
2315        final SSLSocket client = (SSLSocket)
2316            context.clientContext.getSocketFactory().createSocket(context.host, context.port);
2317        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
2318
2319        final String[] serverCipherSuites = server.getEnabledCipherSuites();
2320        final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
2321        System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
2322        clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
2323
2324        ExecutorService executor = Executors.newFixedThreadPool(2);
2325        Future<Void> s = executor.submit(new Callable<Void>() {
2326                @Override
2327                public Void call() throws Exception {
2328                    server.setEnabledProtocols(new String[] { "TLSv1.2" });
2329                    server.setEnabledCipherSuites(serverCipherSuites);
2330                    server.startHandshake();
2331                    return null;
2332                }
2333            });
2334        Future<Void> c = executor.submit(new Callable<Void>() {
2335                @Override
2336                public Void call() throws Exception {
2337                    client.setEnabledProtocols(new String[] { "TLSv1.2" });
2338                    client.setEnabledCipherSuites(clientCipherSuites);
2339                    client.startHandshake();
2340                    return null;
2341                }
2342            });
2343        executor.shutdown();
2344
2345        s.get();
2346        c.get();
2347        client.close();
2348        server.close();
2349        context.close();
2350    }
2351
2352    // Confirms that communication without the TLS_FALLBACK_SCSV cipher works as it always did.
2353    public void test_SSLSocket_sendsNoTlsFallbackScsv_Fallback_Success() throws Exception {
2354        TestSSLContext context = TestSSLContext.create();
2355
2356        final SSLSocket client = (SSLSocket)
2357            context.clientContext.getSocketFactory().createSocket(context.host, context.port);
2358        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
2359
2360        // Confirm absence of TLS_FALLBACK_SCSV.
2361        assertFalse(Arrays.asList(client.getEnabledCipherSuites())
2362                .contains(StandardNames.CIPHER_SUITE_FALLBACK));
2363
2364        ExecutorService executor = Executors.newFixedThreadPool(2);
2365        Future<Void> s = executor.submit(new Callable<Void>() {
2366                @Override
2367                public Void call() throws Exception {
2368                    server.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.1" });
2369                    server.startHandshake();
2370                    return null;
2371                }
2372            });
2373        Future<Void> c = executor.submit(new Callable<Void>() {
2374                @Override
2375                public Void call() throws Exception {
2376                    client.setEnabledProtocols(new String[] { "TLSv1.1" });
2377                    client.startHandshake();
2378                    return null;
2379                }
2380            });
2381        executor.shutdown();
2382
2383        s.get();
2384        c.get();
2385        client.close();
2386        server.close();
2387        context.close();
2388    }
2389
2390    private static void assertInappropriateFallbackIsCause(Throwable cause) {
2391        assertTrue(cause.getMessage(), cause.getMessage().contains("inappropriate fallback")
2392                || cause.getMessage().contains("INAPPROPRIATE_FALLBACK"));
2393    }
2394
2395    public void test_SSLSocket_sendsTlsFallbackScsv_InappropriateFallback_Failure() throws Exception {
2396        TestSSLContext context = TestSSLContext.create();
2397
2398        final SSLSocket client = (SSLSocket)
2399            context.clientContext.getSocketFactory().createSocket(context.host, context.port);
2400        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
2401
2402        final String[] serverCipherSuites = server.getEnabledCipherSuites();
2403
2404        // Add TLS_FALLBACK_SCSV
2405        final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
2406        System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
2407        clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
2408
2409        ExecutorService executor = Executors.newFixedThreadPool(2);
2410        Future<Void> s = executor.submit(new Callable<Void>() {
2411                @Override
2412                public Void call() throws Exception {
2413                    server.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1" });
2414                    server.setEnabledCipherSuites(serverCipherSuites);
2415                    try {
2416                        server.startHandshake();
2417                        fail("Should result in inappropriate fallback");
2418                    } catch (SSLHandshakeException expected) {
2419                        Throwable cause = expected.getCause();
2420                        assertEquals(SSLProtocolException.class, cause.getClass());
2421                        assertInappropriateFallbackIsCause(cause);
2422                    }
2423                    return null;
2424                }
2425            });
2426        Future<Void> c = executor.submit(new Callable<Void>() {
2427                @Override
2428                public Void call() throws Exception {
2429                    client.setEnabledProtocols(new String[] { "TLSv1" });
2430                    client.setEnabledCipherSuites(clientCipherSuites);
2431                    try {
2432                        client.startHandshake();
2433                        fail("Should receive TLS alert inappropriate fallback");
2434                    } catch (SSLHandshakeException expected) {
2435                        Throwable cause = expected.getCause();
2436                        assertEquals(SSLProtocolException.class, cause.getClass());
2437                        assertInappropriateFallbackIsCause(cause);
2438                    }
2439                    return null;
2440                }
2441            });
2442        executor.shutdown();
2443
2444        s.get();
2445        c.get();
2446        client.close();
2447        server.close();
2448        context.close();
2449    }
2450
2451    public void test_SSLSocket_ClientGetsAlertDuringHandshake_HasGoodExceptionMessage()
2452            throws Exception {
2453        TestSSLContext context = TestSSLContext.create();
2454
2455        final ServerSocket listener = ServerSocketFactory.getDefault().createServerSocket(0);
2456        final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
2457                context.host, listener.getLocalPort());
2458        final Socket server = listener.accept();
2459
2460        ExecutorService executor = Executors.newFixedThreadPool(2);
2461        Future<Void> c = executor.submit(new Callable<Void>() {
2462            @Override
2463            public Void call() throws Exception {
2464                try {
2465                    client.startHandshake();
2466                    fail("Should receive handshake exception");
2467                } catch (SSLHandshakeException expected) {
2468                    assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
2469                    assertFalse(expected.getMessage().contains("You should never see this."));
2470                }
2471                return null;
2472            }
2473        });
2474        Future<Void> s = executor.submit(new Callable<Void>() {
2475            @Override
2476            public Void call() throws Exception {
2477                // Wait until the client sends something.
2478                byte[] scratch = new byte[8192];
2479                server.getInputStream().read(scratch);
2480
2481                // Write a bogus TLS alert:
2482                // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Protocol Version)
2483                server.getOutputStream().write(new byte[] {
2484                        0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46
2485                });
2486
2487                // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Close Notify)
2488                server.getOutputStream().write(new byte[] {
2489                        0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00
2490                });
2491
2492                return null;
2493            }
2494        });
2495
2496
2497        executor.shutdown();
2498        c.get(5, TimeUnit.SECONDS);
2499        s.get(5, TimeUnit.SECONDS);
2500        client.close();
2501        server.close();
2502        listener.close();
2503        context.close();
2504    }
2505
2506    public void test_SSLSocket_ServerGetsAlertDuringHandshake_HasGoodExceptionMessage()
2507            throws Exception {
2508        TestSSLContext context = TestSSLContext.create();
2509
2510        final Socket client = SocketFactory.getDefault().createSocket(context.host, context.port);
2511        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
2512
2513        ExecutorService executor = Executors.newFixedThreadPool(2);
2514        Future<Void> s = executor.submit(new Callable<Void>() {
2515            @Override
2516            public Void call() throws Exception {
2517                try {
2518                    server.startHandshake();
2519                    fail("Should receive handshake exception");
2520                } catch (SSLHandshakeException expected) {
2521                    assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
2522                    assertFalse(expected.getMessage().contains("You should never see this."));
2523                }
2524                return null;
2525            }
2526        });
2527        Future<Void> c = executor.submit(new Callable<Void>() {
2528            @Override
2529            public Void call() throws Exception {
2530                // Send bogus ClientHello:
2531                // TLSv1.2 Record Layer: Handshake Protocol: Client Hello
2532                client.getOutputStream().write(new byte[] {
2533                        (byte) 0x16, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0xb9,
2534                        (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xb5, (byte) 0x03,
2535                        (byte) 0x03, (byte) 0x5a, (byte) 0x31, (byte) 0xba, (byte) 0x44,
2536                        (byte) 0x24, (byte) 0xfd, (byte) 0xf0, (byte) 0x56, (byte) 0x46,
2537                        (byte) 0xea, (byte) 0xee, (byte) 0x1c, (byte) 0x62, (byte) 0x8f,
2538                        (byte) 0x18, (byte) 0x04, (byte) 0xbd, (byte) 0x1c, (byte) 0xbc,
2539                        (byte) 0xbf, (byte) 0x6d, (byte) 0x84, (byte) 0x12, (byte) 0xe9,
2540                        (byte) 0x94, (byte) 0xf5, (byte) 0x1c, (byte) 0x15, (byte) 0x3e,
2541                        (byte) 0x79, (byte) 0x01, (byte) 0xe2, (byte) 0x00, (byte) 0x00,
2542                        (byte) 0x28, (byte) 0xc0, (byte) 0x2b, (byte) 0xc0, (byte) 0x2c,
2543                        (byte) 0xc0, (byte) 0x2f, (byte) 0xc0, (byte) 0x30, (byte) 0x00,
2544                        (byte) 0x9e, (byte) 0x00, (byte) 0x9f, (byte) 0xc0, (byte) 0x09,
2545                        (byte) 0xc0, (byte) 0x0a, (byte) 0xc0, (byte) 0x13, (byte) 0xc0,
2546                        (byte) 0x14, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x39,
2547                        (byte) 0xc0, (byte) 0x07, (byte) 0xc0, (byte) 0x11, (byte) 0x00,
2548                        (byte) 0x9c, (byte) 0x00, (byte) 0x9d, (byte) 0x00, (byte) 0x2f,
2549                        (byte) 0x00, (byte) 0x35, (byte) 0x00, (byte) 0x05, (byte) 0x00,
2550                        (byte) 0xff, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x64,
2551                        (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x04, (byte) 0x03,
2552                        (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x0a,
2553                        (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x32, (byte) 0x00,
2554                        (byte) 0x0e, (byte) 0x00, (byte) 0x0d, (byte) 0x00, (byte) 0x19,
2555                        (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x0c, (byte) 0x00,
2556                        (byte) 0x18, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x0a,
2557                        (byte) 0x00, (byte) 0x16, (byte) 0x00, (byte) 0x17, (byte) 0x00,
2558                        (byte) 0x08, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x07,
2559                        (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x15, (byte) 0x00,
2560                        (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x12,
2561                        (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x00,
2562                        (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0f,
2563                        (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x11, (byte) 0x00,
2564                        (byte) 0x0d, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x1e,
2565                        (byte) 0x06, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x06,
2566                        (byte) 0x03, (byte) 0x05, (byte) 0x01, (byte) 0x05, (byte) 0x02,
2567                        (byte) 0x05, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x04,
2568                        (byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x03, (byte) 0x01,
2569                        (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x02,
2570                        (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x03,
2571                });
2572
2573                // Wait until the server sends something.
2574                byte[] scratch = new byte[8192];
2575                client.getInputStream().read(scratch);
2576
2577                // Write a bogus TLS alert:
2578                // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
2579                // Protocol Version)
2580                client.getOutputStream().write(new byte[] {
2581                        0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46
2582                });
2583
2584                // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
2585                // Close Notify)
2586                client.getOutputStream().write(new byte[] {
2587                        0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00
2588                });
2589
2590                return null;
2591            }
2592        });
2593
2594        executor.shutdown();
2595        c.get(5, TimeUnit.SECONDS);
2596        s.get(5, TimeUnit.SECONDS);
2597        client.close();
2598        server.close();
2599        context.close();
2600    }
2601
2602    public void test_SSLSocket_SSLv3Unsupported() throws Exception {
2603        TestSSLContext context = TestSSLContext.create();
2604
2605        final SSLSocket client = (SSLSocket)
2606            context.clientContext.getSocketFactory().createSocket();
2607
2608        // For app compatibility, SSLv3 is stripped out when setting only.
2609        client.setEnabledProtocols(new String[] {"SSLv3"});
2610        assertEquals(0, client.getEnabledProtocols().length);
2611
2612        try {
2613            client.setEnabledProtocols(new String[] {"SSL"});
2614            fail("SSLSocket should not support SSL protocol");
2615        } catch (IllegalArgumentException expected) {
2616        }
2617    }
2618
2619    // We modified the toString() of SSLSocket, and it's based on the output
2620    // of Socket.toString(), so we want to make sure that a change in
2621    // Socket.toString() doesn't cause us to output nonsense.
2622    public void test_SSLSocket_toString() throws Exception {
2623        // The actual implementation from a security provider might do something
2624        // special for its toString(), so we create our own implementation
2625        SSLSocket socket = new SSLSocket() {
2626            @Override public String[] getSupportedCipherSuites() { return new String[0]; }
2627            @Override public String[] getEnabledCipherSuites() { return new String[0]; }
2628            @Override public void setEnabledCipherSuites(String[] strings) { }
2629            @Override public String[] getSupportedProtocols() { return new String[0]; }
2630            @Override public String[] getEnabledProtocols() { return new String[0]; }
2631            @Override public void setEnabledProtocols(String[] strings) { }
2632            @Override public SSLSession getSession() { return null; }
2633            @Override public void addHandshakeCompletedListener(
2634                    HandshakeCompletedListener handshakeCompletedListener) { }
2635            @Override public void removeHandshakeCompletedListener(
2636                    HandshakeCompletedListener handshakeCompletedListener) { }
2637            @Override public void startHandshake() throws IOException { }
2638            @Override public void setUseClientMode(boolean b) { }
2639            @Override public boolean getUseClientMode() { return false; }
2640            @Override public void setNeedClientAuth(boolean b) { }
2641            @Override public boolean getNeedClientAuth() { return false; }
2642            @Override public void setWantClientAuth(boolean b) { }
2643            @Override public boolean getWantClientAuth() { return false; }
2644            @Override public void setEnableSessionCreation(boolean b) { }
2645            @Override public boolean getEnableSessionCreation() { return false; }
2646        };
2647        assertTrue(socket.toString().startsWith("SSLSocket["));
2648    }
2649
2650    /**
2651     * Not run by default by JUnit, but can be run by Vogar by
2652     * specifying it explicitly (or with main method below)
2653     */
2654    public void stress_test_TestSSLSocketPair_create() {
2655        final boolean verbose = true;
2656        while (true) {
2657            TestSSLSocketPair test = TestSSLSocketPair.create();
2658            if (verbose) {
2659                System.out.println("client=" + test.client.getLocalPort()
2660                                   + " server=" + test.server.getLocalPort());
2661            } else {
2662                System.out.print("X");
2663            }
2664
2665            /*
2666              We don't close on purpose in this stress test to add
2667              races in file descriptors reuse when the garbage
2668              collector runs concurrently and finalizes sockets
2669            */
2670            // test.close();
2671
2672        }
2673    }
2674
2675    private static final void readFully(InputStream in, byte[] dst) throws IOException {
2676        int offset = 0;
2677        int byteCount = dst.length;
2678        while (byteCount > 0) {
2679            int bytesRead = in.read(dst, offset, byteCount);
2680            if (bytesRead < 0) {
2681                throw new EOFException();
2682            }
2683            offset += bytesRead;
2684            byteCount -= bytesRead;
2685        }
2686    }
2687
2688    private static final void closeQuietly(Closeable socket) {
2689        if (socket != null) {
2690            try {
2691                socket.close();
2692            } catch (Exception ignored) {
2693            }
2694        }
2695    }
2696
2697    public static void main (String[] args) {
2698        new SSLSocketTest().stress_test_TestSSLSocketPair_create();
2699    }
2700}
2701