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