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