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