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; 18 19 import java.io.ByteArrayInputStream; 20 import java.io.ByteArrayOutputStream; 21 import java.io.FileDescriptor; 22 import java.io.IOException; 23 import java.io.UnsupportedEncodingException; 24 import java.math.BigInteger; 25 import java.net.ServerSocket; 26 import java.net.Socket; 27 import java.net.SocketException; 28 import java.net.SocketTimeoutException; 29 import java.security.KeyPair; 30 import java.security.KeyPairGenerator; 31 import java.security.KeyStore; 32 import java.security.KeyStore.PrivateKeyEntry; 33 import java.security.cert.Certificate; 34 import java.security.cert.CertificateEncodingException; 35 import java.security.cert.CertificateException; 36 import java.security.cert.X509Certificate; 37 import java.security.interfaces.ECPublicKey; 38 import java.security.interfaces.RSAPrivateCrtKey; 39 import java.security.interfaces.RSAPublicKey; 40 import java.security.spec.ECPrivateKeySpec; 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.concurrent.Callable; 46 import java.util.concurrent.ExecutionException; 47 import java.util.concurrent.ExecutorService; 48 import java.util.concurrent.Executors; 49 import java.util.concurrent.Future; 50 import java.util.concurrent.TimeUnit; 51 52 import javax.net.ssl.SSLException; 53 import javax.net.ssl.SSLHandshakeException; 54 import javax.net.ssl.SSLProtocolException; 55 import javax.security.auth.x500.X500Principal; 56 57 import junit.framework.TestCase; 58 import libcore.io.IoUtils; 59 import libcore.java.security.StandardNames; 60 import libcore.java.security.TestKeyStore; 61 62 import org.conscrypt.NativeCrypto.SSLHandshakeCallbacks; 63 import static org.conscrypt.NativeConstants.SSL_MODE_CBC_RECORD_SPLITTING; 64 import static org.conscrypt.NativeConstants.SSL_MODE_HANDSHAKE_CUTTHROUGH; 65 66 import static org.conscrypt.TestUtils.openTestFile; 67 import static org.conscrypt.TestUtils.readTestFile; 68 69 public class NativeCryptoTest extends TestCase { 70 /** Corresponds to the native test library "libjavacoretests.so" */ 71 public static final String TEST_ENGINE_ID = "javacoretests"; 72 73 private static final long NULL = 0; 74 private static final FileDescriptor INVALID_FD = new FileDescriptor(); 75 private static final SSLHandshakeCallbacks DUMMY_CB 76 = new TestSSLHandshakeCallbacks(null, 0, null); 77 78 private static final long TIMEOUT_SECONDS = 5; 79 80 private static OpenSSLKey SERVER_PRIVATE_KEY; 81 private static OpenSSLX509Certificate[] SERVER_CERTIFICATES_HOLDER; 82 private static long[] SERVER_CERTIFICATES; 83 private static OpenSSLKey CLIENT_PRIVATE_KEY; 84 private static OpenSSLX509Certificate[] CLIENT_CERTIFICATES_HOLDER; 85 private static long[] CLIENT_CERTIFICATES; 86 private static byte[][] CA_PRINCIPALS; 87 private static OpenSSLKey CHANNEL_ID_PRIVATE_KEY; 88 private static byte[] CHANNEL_ID; 89 90 @Override 91 protected void tearDown() throws Exception { 92 assertEquals(0, NativeCrypto.ERR_peek_last_error()); 93 } 94 95 private static OpenSSLKey getServerPrivateKey() { 96 initCerts(); 97 return SERVER_PRIVATE_KEY; 98 } 99 100 private static long[] getServerCertificates() { 101 initCerts(); 102 return SERVER_CERTIFICATES; 103 } 104 105 private static OpenSSLKey getClientPrivateKey() { 106 initCerts(); 107 return CLIENT_PRIVATE_KEY; 108 } 109 110 private static long[] getClientCertificates() { 111 initCerts(); 112 return CLIENT_CERTIFICATES; 113 } 114 115 private static byte[][] getCaPrincipals() { 116 initCerts(); 117 return CA_PRINCIPALS; 118 } 119 120 /** 121 * Lazily create shared test certificates. 122 */ 123 private static synchronized void initCerts() { 124 if (SERVER_PRIVATE_KEY != null) { 125 return; 126 } 127 128 try { 129 PrivateKeyEntry serverPrivateKeyEntry 130 = TestKeyStore.getServer().getPrivateKey("RSA", "RSA"); 131 SERVER_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(serverPrivateKeyEntry.getPrivateKey()); 132 SERVER_CERTIFICATES_HOLDER = encodeCertificateList( 133 serverPrivateKeyEntry.getCertificateChain()); 134 SERVER_CERTIFICATES = getCertificateReferences(SERVER_CERTIFICATES_HOLDER); 135 136 PrivateKeyEntry clientPrivateKeyEntry 137 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA"); 138 CLIENT_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(clientPrivateKeyEntry.getPrivateKey()); 139 CLIENT_CERTIFICATES_HOLDER = encodeCertificateList( 140 clientPrivateKeyEntry.getCertificateChain()); 141 CLIENT_CERTIFICATES = getCertificateReferences(CLIENT_CERTIFICATES_HOLDER); 142 143 KeyStore ks = TestKeyStore.getClient().keyStore; 144 String caCertAlias = ks.aliases().nextElement(); 145 X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias); 146 X500Principal principal = certificate.getIssuerX500Principal(); 147 CA_PRINCIPALS = new byte[][] { principal.getEncoded() }; 148 initChannelIdKey(); 149 } catch (Exception e) { 150 throw new RuntimeException(e); 151 } 152 } 153 154 private static long[] getCertificateReferences(OpenSSLX509Certificate[] certs) { 155 final long[] certRefs = new long[certs.length]; 156 for (int i = 0; i < certs.length; i++) { 157 certRefs[i] = certs[i].getContext(); 158 } 159 return certRefs; 160 } 161 162 private static OpenSSLX509Certificate[] encodeCertificateList(Certificate[] chain) 163 throws CertificateEncodingException { 164 final OpenSSLX509Certificate[] openSslCerts = new OpenSSLX509Certificate[chain.length]; 165 for (int i = 0; i < chain.length; i++) { 166 openSslCerts[i] = OpenSSLX509Certificate.fromCertificate(chain[i]); 167 } 168 return openSslCerts; 169 } 170 171 private static synchronized void initChannelIdKey() throws Exception { 172 if (CHANNEL_ID_PRIVATE_KEY != null) { 173 return; 174 } 175 176 // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1 177 OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1"); 178 BigInteger s = new BigInteger( 179 "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16); 180 CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey( 181 new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())).getOpenSSLKey(); 182 183 // Channel ID is the concatenation of the X and Y coordinates of the public key. 184 CHANNEL_ID = new BigInteger( 185 "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" + 186 "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77", 187 16).toByteArray(); 188 } 189 190 public static void assertEqualSessions(long expected, long actual) { 191 assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected), 192 NativeCrypto.SSL_SESSION_session_id(actual)); 193 } 194 public static void assertEqualByteArrays(byte[] expected, byte[] actual) { 195 assertEquals(Arrays.toString(expected), Arrays.toString(actual)); 196 } 197 198 public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) { 199 assertEqualByteArrays(expected, actual); 200 } 201 202 public static void assertEqualCertificateChains(long[] expected, long[] actual) { 203 assertEquals(expected.length, actual.length); 204 for (int i = 0; i < expected.length; i++) { 205 NativeCrypto.X509_cmp(expected[i], actual[i]); 206 } 207 } 208 209 public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) { 210 assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual)); 211 } 212 213 public void test_EVP_PKEY_cmp() throws Exception { 214 try { 215 NativeCrypto.EVP_PKEY_cmp(null, null); 216 fail("Should throw NullPointerException when arguments are NULL"); 217 } catch (NullPointerException expected) { 218 } 219 220 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 221 kpg.initialize(512); 222 223 KeyPair kp1 = kpg.generateKeyPair(); 224 RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate(); 225 226 KeyPair kp2 = kpg.generateKeyPair(); 227 RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate(); 228 229 NativeRef.EVP_PKEY pkey1, pkey1_copy, pkey2; 230 pkey1 = new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA( 231 privKey1.getModulus().toByteArray(), 232 privKey1.getPublicExponent().toByteArray(), 233 privKey1.getPrivateExponent().toByteArray(), 234 privKey1.getPrimeP().toByteArray(), 235 privKey1.getPrimeQ().toByteArray(), 236 privKey1.getPrimeExponentP().toByteArray(), 237 privKey1.getPrimeExponentQ().toByteArray(), 238 privKey1.getCrtCoefficient().toByteArray())); 239 assertNotSame(NULL, pkey1); 240 241 pkey1_copy = new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA( 242 privKey1.getModulus().toByteArray(), 243 privKey1.getPublicExponent().toByteArray(), 244 privKey1.getPrivateExponent().toByteArray(), 245 privKey1.getPrimeP().toByteArray(), 246 privKey1.getPrimeQ().toByteArray(), 247 privKey1.getPrimeExponentP().toByteArray(), 248 privKey1.getPrimeExponentQ().toByteArray(), 249 privKey1.getCrtCoefficient().toByteArray())); 250 assertNotSame(NULL, pkey1_copy); 251 252 pkey2 = new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA( 253 privKey2.getModulus().toByteArray(), 254 privKey2.getPublicExponent().toByteArray(), 255 privKey2.getPrivateExponent().toByteArray(), 256 privKey2.getPrimeP().toByteArray(), 257 privKey2.getPrimeQ().toByteArray(), 258 privKey2.getPrimeExponentP().toByteArray(), 259 privKey2.getPrimeExponentQ().toByteArray(), 260 privKey2.getCrtCoefficient().toByteArray())); 261 assertNotSame(NULL, pkey2); 262 263 try { 264 NativeCrypto.EVP_PKEY_cmp(pkey1, null); 265 fail("Should throw NullPointerException when arguments are NULL"); 266 } catch (NullPointerException expected) { 267 } 268 269 try { 270 NativeCrypto.EVP_PKEY_cmp(null, null); 271 fail("Should throw NullPointerException when arguments are NULL"); 272 } catch (NullPointerException expected) { 273 } 274 275 assertEquals("Same keys should be the equal", 1, 276 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1)); 277 278 assertEquals("Same keys should be the equal", 1, 279 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy)); 280 281 assertEquals("Different keys should not be equal", 0, 282 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2)); 283 } 284 285 public void test_SSL_CTX_new() throws Exception { 286 long c = NativeCrypto.SSL_CTX_new(); 287 assertTrue(c != NULL); 288 long c2 = NativeCrypto.SSL_CTX_new(); 289 assertTrue(c != c2); 290 NativeCrypto.SSL_CTX_free(c); 291 NativeCrypto.SSL_CTX_free(c2); 292 } 293 294 public void test_SSL_CTX_free() throws Exception { 295 try { 296 NativeCrypto.SSL_CTX_free(NULL); 297 fail(); 298 } catch (NullPointerException expected) { 299 } 300 301 NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new()); 302 } 303 304 public void test_SSL_CTX_set_session_id_context() throws Exception { 305 byte[] empty = new byte[0]; 306 try { 307 NativeCrypto.SSL_CTX_set_session_id_context(NULL, empty); 308 fail(); 309 } catch (NullPointerException expected) { 310 } 311 long c = NativeCrypto.SSL_CTX_new(); 312 try { 313 NativeCrypto.SSL_CTX_set_session_id_context(c, null); 314 fail(); 315 } catch (NullPointerException expected) { 316 } 317 NativeCrypto.SSL_CTX_set_session_id_context(c, empty); 318 NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[32]); 319 try { 320 NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[33]); 321 } catch (IllegalArgumentException expected) { 322 } 323 NativeCrypto.SSL_CTX_free(c); 324 } 325 326 public void test_SSL_new() throws Exception { 327 long c = NativeCrypto.SSL_CTX_new(); 328 long s = NativeCrypto.SSL_new(c); 329 330 assertTrue(s != NULL); 331 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) == 0); 332 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_TLSv1) == 0); 333 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_TLSv1_1) == 0); 334 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_TLSv1_2) == 0); 335 336 long s2 = NativeCrypto.SSL_new(c); 337 assertTrue(s != s2); 338 NativeCrypto.SSL_free(s2); 339 340 NativeCrypto.SSL_free(s); 341 NativeCrypto.SSL_CTX_free(c); 342 } 343 344 public void test_SSL_use_certificate() throws Exception { 345 try { 346 NativeCrypto.SSL_use_certificate(NULL, null); 347 fail(); 348 } catch (NullPointerException expected) { 349 } 350 351 long c = NativeCrypto.SSL_CTX_new(); 352 long s = NativeCrypto.SSL_new(c); 353 354 try { 355 NativeCrypto.SSL_use_certificate(s, null); 356 fail(); 357 } catch (NullPointerException expected) { 358 } 359 360 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 361 362 NativeCrypto.SSL_free(s); 363 NativeCrypto.SSL_CTX_free(c); 364 } 365 366 public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception { 367 initChannelIdKey(); 368 369 try { 370 NativeCrypto.SSL_set1_tls_channel_id(NULL, null); 371 fail(); 372 } catch (NullPointerException expected) { 373 } 374 375 long c = NativeCrypto.SSL_CTX_new(); 376 long s = NativeCrypto.SSL_new(c); 377 378 try { 379 NativeCrypto.SSL_set1_tls_channel_id(s, null); 380 fail(); 381 } catch (NullPointerException expected) { 382 } 383 384 // Use the key natively. This works because the initChannelIdKey method ensures that the 385 // key is backed by OpenSSL. 386 NativeCrypto.SSL_set1_tls_channel_id(s, CHANNEL_ID_PRIVATE_KEY.getNativeRef()); 387 388 NativeCrypto.SSL_free(s); 389 NativeCrypto.SSL_CTX_free(c); 390 } 391 392 public void test_SSL_use_PrivateKey() throws Exception { 393 try { 394 NativeCrypto.SSL_use_PrivateKey(NULL, null); 395 fail(); 396 } catch (NullPointerException expected) { 397 } 398 399 long c = NativeCrypto.SSL_CTX_new(); 400 long s = NativeCrypto.SSL_new(c); 401 402 try { 403 NativeCrypto.SSL_use_PrivateKey(s, null); 404 fail(); 405 } catch (NullPointerException expected) { 406 } 407 408 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getNativeRef()); 409 410 NativeCrypto.SSL_free(s); 411 NativeCrypto.SSL_CTX_free(c); 412 } 413 414 public void test_SSL_check_private_key_null() throws Exception { 415 try { 416 NativeCrypto.SSL_check_private_key(NULL); 417 fail(); 418 } catch (NullPointerException expected) { 419 } 420 } 421 422 public void test_SSL_check_private_key_no_key_no_cert() throws Exception { 423 long c = NativeCrypto.SSL_CTX_new(); 424 long s = NativeCrypto.SSL_new(c); 425 426 // neither private or certificate set 427 try { 428 NativeCrypto.SSL_check_private_key(s); 429 fail(); 430 } catch (SSLException expected) { 431 } 432 433 NativeCrypto.SSL_free(s); 434 NativeCrypto.SSL_CTX_free(c); 435 } 436 437 public void test_SSL_check_private_key_cert_then_key() throws Exception { 438 long c = NativeCrypto.SSL_CTX_new(); 439 long s = NativeCrypto.SSL_new(c); 440 441 // first certificate, then private 442 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 443 444 try { 445 NativeCrypto.SSL_check_private_key(s); 446 fail(); 447 } catch (SSLException expected) { 448 } 449 450 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getNativeRef()); 451 NativeCrypto.SSL_check_private_key(s); 452 453 NativeCrypto.SSL_free(s); 454 NativeCrypto.SSL_CTX_free(c); 455 } 456 public void test_SSL_check_private_key_key_then_cert() throws Exception { 457 long c = NativeCrypto.SSL_CTX_new(); 458 long s = NativeCrypto.SSL_new(c); 459 460 // first private, then certificate 461 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getNativeRef()); 462 463 try { 464 NativeCrypto.SSL_check_private_key(s); 465 fail(); 466 } catch (SSLException expected) { 467 } 468 469 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 470 NativeCrypto.SSL_check_private_key(s); 471 472 NativeCrypto.SSL_free(s); 473 NativeCrypto.SSL_CTX_free(c); 474 } 475 476 public void test_SSL_get_mode() throws Exception { 477 try { 478 NativeCrypto.SSL_get_mode(NULL); 479 fail(); 480 } catch (NullPointerException expected) { 481 } 482 483 long c = NativeCrypto.SSL_CTX_new(); 484 long s = NativeCrypto.SSL_new(c); 485 assertTrue(NativeCrypto.SSL_get_mode(s) != 0); 486 NativeCrypto.SSL_free(s); 487 NativeCrypto.SSL_CTX_free(c); 488 } 489 490 public void test_SSL_set_mode_and_clear_mode() throws Exception { 491 try { 492 NativeCrypto.SSL_set_mode(NULL, 0); 493 fail(); 494 } catch (NullPointerException expected) { 495 } 496 497 long c = NativeCrypto.SSL_CTX_new(); 498 long s = NativeCrypto.SSL_new(c); 499 if (NativeCrypto.isBoringSSL) { 500 // check SSL_MODE_HANDSHAKE_CUTTHROUGH on by default for BoringSSL 501 assertEquals(SSL_MODE_HANDSHAKE_CUTTHROUGH, 502 NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 503 } else { 504 // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default for OpenSSL 505 assertEquals(0, NativeCrypto.SSL_get_mode(s) 506 & SSL_MODE_HANDSHAKE_CUTTHROUGH); 507 } 508 // check SSL_MODE_CBC_RECORD_SPLITTING off by default 509 assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_CBC_RECORD_SPLITTING); 510 511 // set SSL_MODE_HANDSHAKE_CUTTHROUGH on 512 NativeCrypto.SSL_set_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 513 assertTrue((NativeCrypto.SSL_get_mode(s) 514 & SSL_MODE_HANDSHAKE_CUTTHROUGH) != 0); 515 // clear SSL_MODE_HANDSHAKE_CUTTHROUGH off 516 NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 517 assertTrue((NativeCrypto.SSL_get_mode(s) 518 & SSL_MODE_HANDSHAKE_CUTTHROUGH) == 0); 519 520 NativeCrypto.SSL_free(s); 521 NativeCrypto.SSL_CTX_free(c); 522 } 523 524 public void test_SSL_get_options() throws Exception { 525 try { 526 NativeCrypto.SSL_get_options(NULL); 527 fail(); 528 } catch (NullPointerException expected) { 529 } 530 531 long c = NativeCrypto.SSL_CTX_new(); 532 long s = NativeCrypto.SSL_new(c); 533 assertTrue(NativeCrypto.SSL_get_options(s) != 0); 534 NativeCrypto.SSL_free(s); 535 NativeCrypto.SSL_CTX_free(c); 536 } 537 538 public void test_SSL_set_options() throws Exception { 539 try { 540 NativeCrypto.SSL_set_options(NULL, 0); 541 fail(); 542 } catch (NullPointerException expected) { 543 } 544 545 long c = NativeCrypto.SSL_CTX_new(); 546 long s = NativeCrypto.SSL_new(c); 547 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) == 0); 548 NativeCrypto.SSL_set_options(s, NativeConstants.SSL_OP_NO_SSLv3); 549 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) != 0); 550 NativeCrypto.SSL_free(s); 551 NativeCrypto.SSL_CTX_free(c); 552 } 553 554 public void test_SSL_clear_options() throws Exception { 555 try { 556 NativeCrypto.SSL_clear_options(NULL, 0); 557 fail(); 558 } catch (NullPointerException expected) { 559 } 560 561 long c = NativeCrypto.SSL_CTX_new(); 562 long s = NativeCrypto.SSL_new(c); 563 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) == 0); 564 NativeCrypto.SSL_set_options(s, NativeConstants.SSL_OP_NO_SSLv3); 565 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) != 0); 566 NativeCrypto.SSL_clear_options(s, NativeConstants.SSL_OP_NO_SSLv3); 567 assertTrue((NativeCrypto.SSL_get_options(s) & NativeConstants.SSL_OP_NO_SSLv3) == 0); 568 NativeCrypto.SSL_free(s); 569 NativeCrypto.SSL_CTX_free(c); 570 } 571 572 public void test_SSL_set_cipher_lists() throws Exception { 573 try { 574 NativeCrypto.SSL_set_cipher_lists(NULL, null); 575 fail("Exception not thrown for null ssl and null list"); 576 } catch (NullPointerException expected) { 577 } 578 579 long c = NativeCrypto.SSL_CTX_new(); 580 long s = NativeCrypto.SSL_new(c); 581 582 try { 583 NativeCrypto.SSL_set_cipher_lists(s, null); 584 fail("Exception not thrown for null list"); 585 } catch (NullPointerException expected) { 586 } 587 588 // Explicitly checking that the empty list is allowed. 589 // b/21816861 590 NativeCrypto.SSL_set_cipher_lists(s, new String[]{}); 591 592 try { 593 NativeCrypto.SSL_set_cipher_lists(s, new String[] { null }); 594 fail("Exception not thrown for list with null element"); 595 } catch (NullPointerException expected) { 596 } 597 598 // see OpenSSL ciphers man page 599 String[] illegals = new String[] { 600 // empty 601 "", 602 // never standardized 603 "EXP1024-DES-CBC-SHA", "EXP1024-RC4-SHA", "DHE-DSS-RC4-SHA", 604 // IDEA 605 "IDEA-CBC-SHA", "IDEA-CBC-MD5" 606 }; 607 608 for (String illegal : illegals) { 609 try { 610 NativeCrypto.SSL_set_cipher_lists(s, new String[] { illegal }); 611 fail("Exception now thrown for illegal cipher: " + illegal); 612 } catch (IllegalArgumentException expected) { 613 } 614 } 615 616 List<String> ciphers 617 = new ArrayList<String>(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.keySet()); 618 NativeCrypto.SSL_set_cipher_lists(s, ciphers.toArray(new String[ciphers.size()])); 619 620 NativeCrypto.SSL_free(s); 621 NativeCrypto.SSL_CTX_free(c); 622 } 623 624 public void test_SSL_set_verify() throws Exception { 625 try { 626 NativeCrypto.SSL_set_verify(NULL, 0); 627 fail(); 628 } catch (NullPointerException expected) { 629 } 630 631 long c = NativeCrypto.SSL_CTX_new(); 632 long s = NativeCrypto.SSL_new(c); 633 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE); 634 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 635 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 636 NativeCrypto.SSL_set_verify(s, (NativeCrypto.SSL_VERIFY_PEER 637 | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT)); 638 NativeCrypto.SSL_free(s); 639 NativeCrypto.SSL_CTX_free(c); 640 } 641 642 private static final boolean DEBUG = false; 643 644 public static class Hooks { 645 protected String negotiatedCipherSuite; 646 private OpenSSLKey channelIdPrivateKey; 647 protected boolean pskEnabled; 648 protected byte[] pskKey; 649 protected List<String> enabledCipherSuites; 650 651 /** 652 * @throws SSLException 653 */ 654 public long getContext() throws SSLException { 655 return NativeCrypto.SSL_CTX_new(); 656 } 657 public long beforeHandshake(long context) throws SSLException { 658 long s = NativeCrypto.SSL_new(context); 659 // without this SSL_set_cipher_lists call the tests were 660 // negotiating DHE-RSA-AES256-SHA by default which had 661 // very slow ephemeral RSA key generation 662 List<String> cipherSuites = new ArrayList<String>(); 663 if (enabledCipherSuites == null) { 664 cipherSuites.add("RC4-MD5"); 665 if (pskEnabled) { 666 // In TLS-PSK the client indicates that PSK key exchange is desired by offering 667 // at least one PSK cipher suite. 668 cipherSuites.add(0, "PSK-AES128-CBC-SHA"); 669 } 670 } else { 671 cipherSuites.addAll(enabledCipherSuites); 672 } 673 NativeCrypto.SSL_set_cipher_lists( 674 s, cipherSuites.toArray(new String[cipherSuites.size()])); 675 676 if (channelIdPrivateKey != null) { 677 NativeCrypto.SSL_set1_tls_channel_id(s, channelIdPrivateKey.getNativeRef()); 678 } 679 return s; 680 } 681 public void configureCallbacks( 682 @SuppressWarnings("unused") TestSSLHandshakeCallbacks callbacks) {} 683 public void clientCertificateRequested(@SuppressWarnings("unused") long s) {} 684 public void afterHandshake(long session, long ssl, long context, 685 Socket socket, FileDescriptor fd, 686 SSLHandshakeCallbacks callback) 687 throws Exception { 688 if (session != NULL) { 689 negotiatedCipherSuite = NativeCrypto.SSL_SESSION_cipher(session); 690 NativeCrypto.SSL_SESSION_free(session); 691 } 692 if (ssl != NULL) { 693 try { 694 NativeCrypto.SSL_shutdown(ssl, fd, callback); 695 } catch (IOException e) { 696 } 697 NativeCrypto.SSL_free(ssl); 698 } 699 if (context != NULL) { 700 NativeCrypto.SSL_CTX_free(context); 701 } 702 if (socket != null) { 703 socket.close(); 704 } 705 } 706 } 707 708 public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks { 709 private final Socket socket; 710 private final long sslNativePointer; 711 private final Hooks hooks; 712 713 public TestSSLHandshakeCallbacks(Socket socket, 714 long sslNativePointer, 715 Hooks hooks) { 716 this.socket = socket; 717 this.sslNativePointer = sslNativePointer; 718 this.hooks = hooks; 719 } 720 721 public long[] certificateChainRefs; 722 public String authMethod; 723 public boolean verifyCertificateChainCalled; 724 725 @Override 726 public void verifyCertificateChain(long sslSessionNativePtr, long[] certChainRefs, 727 String authMethod) throws CertificateException { 728 if (DEBUG) { 729 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 730 + " verifyCertificateChain" 731 + " sessionPtr=0x" + Long.toString(sslSessionNativePtr, 16) 732 + " asn1DerEncodedCertificateChain=" 733 + Arrays.toString(certChainRefs) 734 + " authMethod=" + authMethod); 735 } 736 this.certificateChainRefs = certChainRefs; 737 this.authMethod = authMethod; 738 this.verifyCertificateChainCalled = true; 739 } 740 741 public byte[] keyTypes; 742 public byte[][] asn1DerEncodedX500Principals; 743 public boolean clientCertificateRequestedCalled; 744 745 @Override 746 public void clientCertificateRequested(byte[] keyTypes, 747 byte[][] asn1DerEncodedX500Principals) { 748 if (DEBUG) { 749 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 750 + " clientCertificateRequested" 751 + " keyTypes=" + keyTypes 752 + " asn1DerEncodedX500Principals=" 753 + asn1DerEncodedX500Principals); 754 } 755 this.keyTypes = keyTypes; 756 this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals; 757 this.clientCertificateRequestedCalled = true; 758 if (hooks != null ) { 759 hooks.clientCertificateRequested(sslNativePointer); 760 } 761 } 762 763 public boolean handshakeCompletedCalled; 764 765 @Override 766 public void onSSLStateChange(long sslSessionNativePtr, int type, int val) { 767 if (DEBUG) { 768 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 769 + " onSSLStateChange"); 770 } 771 this.handshakeCompletedCalled = true; 772 } 773 774 public Socket getSocket() { 775 return socket; 776 } 777 778 private boolean clientPSKKeyRequestedInvoked; 779 private String clientPSKKeyRequestedIdentityHint; 780 private int clientPSKKeyRequestedResult; 781 private byte[] clientPSKKeyRequestedResultKey; 782 private byte[] clientPSKKeyRequestedResultIdentity; 783 784 @Override 785 public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) { 786 if (DEBUG) { 787 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 788 + " clientPSKKeyRequested" 789 + " identityHint=" + identityHint 790 + " identity capacity=" + identity.length 791 + " key capacity=" + key.length); 792 } 793 clientPSKKeyRequestedInvoked = true; 794 clientPSKKeyRequestedIdentityHint = identityHint; 795 if (clientPSKKeyRequestedResultKey != null) { 796 System.arraycopy( 797 clientPSKKeyRequestedResultKey, 0, 798 key, 0, 799 clientPSKKeyRequestedResultKey.length); 800 } 801 if (clientPSKKeyRequestedResultIdentity != null) { 802 System.arraycopy( 803 clientPSKKeyRequestedResultIdentity, 0, 804 identity, 0, 805 Math.min(clientPSKKeyRequestedResultIdentity.length, identity.length)); 806 } 807 return clientPSKKeyRequestedResult; 808 } 809 810 private boolean serverPSKKeyRequestedInvoked; 811 private int serverPSKKeyRequestedResult; 812 private byte[] serverPSKKeyRequestedResultKey; 813 private String serverPSKKeyRequestedIdentityHint; 814 private String serverPSKKeyRequestedIdentity; 815 @Override 816 public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) { 817 if (DEBUG) { 818 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 819 + " serverPSKKeyRequested" 820 + " identityHint=" + identityHint 821 + " identity=" + identity 822 + " key capacity=" + key.length); 823 } 824 serverPSKKeyRequestedInvoked = true; 825 serverPSKKeyRequestedIdentityHint = identityHint; 826 serverPSKKeyRequestedIdentity = identity; 827 if (serverPSKKeyRequestedResultKey != null) { 828 System.arraycopy( 829 serverPSKKeyRequestedResultKey, 0, 830 key, 0, 831 serverPSKKeyRequestedResultKey.length); 832 } 833 return serverPSKKeyRequestedResult; 834 } 835 } 836 837 public static class ClientHooks extends Hooks { 838 protected String pskIdentity; 839 840 @Override 841 public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) { 842 super.configureCallbacks(callbacks); 843 if (pskEnabled) { 844 if (pskIdentity != null) { 845 // Create a NULL-terminated modified UTF-8 representation of pskIdentity. 846 byte[] b; 847 try { 848 b = pskIdentity.getBytes("UTF-8"); 849 } catch (UnsupportedEncodingException e) { 850 throw new RuntimeException("UTF-8 encoding not supported", e); 851 } 852 callbacks.clientPSKKeyRequestedResultIdentity = 853 Arrays.copyOf(b, b.length + 1); 854 } 855 callbacks.clientPSKKeyRequestedResultKey = pskKey; 856 callbacks.clientPSKKeyRequestedResult = (pskKey != null) ? pskKey.length : 0; 857 } 858 } 859 860 @Override 861 public long beforeHandshake(long c) throws SSLException { 862 long s = super.beforeHandshake(c); 863 if (pskEnabled) { 864 NativeCrypto.set_SSL_psk_client_callback_enabled(s, true); 865 } 866 return s; 867 } 868 } 869 870 public static class ServerHooks extends Hooks { 871 private final OpenSSLKey privateKey; 872 private final long[] certificates; 873 private boolean channelIdEnabled; 874 private byte[] channelIdAfterHandshake; 875 private Throwable channelIdAfterHandshakeException; 876 877 protected String pskIdentityHint; 878 879 public ServerHooks() { 880 this(null, null); 881 } 882 883 public ServerHooks(OpenSSLKey privateKey, long[] certificates) { 884 this.privateKey = privateKey; 885 this.certificates = certificates; 886 } 887 888 @Override 889 public long beforeHandshake(long c) throws SSLException { 890 long s = super.beforeHandshake(c); 891 if (privateKey != null) { 892 NativeCrypto.SSL_use_PrivateKey(s, privateKey.getNativeRef()); 893 } 894 if (certificates != null) { 895 NativeCrypto.SSL_use_certificate(s, certificates); 896 } 897 if (channelIdEnabled) { 898 NativeCrypto.SSL_enable_tls_channel_id(s); 899 } 900 if (pskEnabled) { 901 NativeCrypto.set_SSL_psk_server_callback_enabled(s, true); 902 NativeCrypto.SSL_use_psk_identity_hint(s, pskIdentityHint); 903 } 904 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE); 905 return s; 906 } 907 908 @Override 909 public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) { 910 super.configureCallbacks(callbacks); 911 if (pskEnabled) { 912 callbacks.serverPSKKeyRequestedResultKey = pskKey; 913 callbacks.serverPSKKeyRequestedResult = (pskKey != null) ? pskKey.length : 0; 914 } 915 } 916 917 @Override 918 public void afterHandshake(long session, long ssl, long context, 919 Socket socket, FileDescriptor fd, 920 SSLHandshakeCallbacks callback) 921 throws Exception { 922 if (channelIdEnabled) { 923 try { 924 channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl); 925 } catch (Exception e) { 926 channelIdAfterHandshakeException = e; 927 } 928 } 929 super.afterHandshake(session, ssl, context, socket, fd, callback); 930 } 931 932 @Override 933 public void clientCertificateRequested(long s) { 934 fail("Server asked for client certificates"); 935 } 936 } 937 938 public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener, 939 final int timeout, final boolean client, final Hooks hooks, final byte[] npnProtocols, 940 final byte[] alpnProtocols) { 941 ExecutorService executor = Executors.newSingleThreadExecutor(); 942 Future<TestSSLHandshakeCallbacks> future = executor.submit( 943 new Callable<TestSSLHandshakeCallbacks>() { 944 @Override public TestSSLHandshakeCallbacks call() throws Exception { 945 @SuppressWarnings("resource") // Socket needs to remain open after the handshake 946 Socket socket = (client 947 ? new Socket(listener.getInetAddress(), 948 listener.getLocalPort()) 949 : listener.accept()); 950 if (timeout == -1) { 951 return new TestSSLHandshakeCallbacks(socket, 0, null); 952 } 953 FileDescriptor fd = socket.getFileDescriptor$(); 954 long c = hooks.getContext(); 955 long s = hooks.beforeHandshake(c); 956 TestSSLHandshakeCallbacks callback 957 = new TestSSLHandshakeCallbacks(socket, s, hooks); 958 hooks.configureCallbacks(callback); 959 if (DEBUG) { 960 System.out.println("ssl=0x" + Long.toString(s, 16) 961 + " handshake" 962 + " context=0x" + Long.toString(c, 16) 963 + " socket=" + socket 964 + " fd=" + fd 965 + " timeout=" + timeout 966 + " client=" + client); 967 } 968 long session = NULL; 969 try { 970 session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client, 971 npnProtocols, alpnProtocols); 972 if (DEBUG) { 973 System.out.println("ssl=0x" + Long.toString(s, 16) 974 + " handshake" 975 + " session=0x" + Long.toString(session, 16)); 976 } 977 } finally { 978 // Ensure afterHandshake is called to free resources 979 hooks.afterHandshake(session, s, c, socket, fd, callback); 980 } 981 return callback; 982 } 983 }); 984 executor.shutdown(); 985 return future; 986 } 987 988 public void test_SSL_do_handshake_NULL_SSL() throws Exception { 989 try { 990 NativeCrypto.SSL_do_handshake(NULL, null, null, 0, false, null, null); 991 fail(); 992 } catch (NullPointerException expected) { 993 } 994 } 995 996 public void test_SSL_do_handshake_null_args() throws Exception { 997 long c = NativeCrypto.SSL_CTX_new(); 998 long s = NativeCrypto.SSL_new(c); 999 1000 try { 1001 NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null, null); 1002 fail(); 1003 } catch (NullPointerException expected) { 1004 } 1005 1006 try { 1007 NativeCrypto.SSL_do_handshake(s, INVALID_FD, null, 0, true, null, null); 1008 fail(); 1009 } catch (NullPointerException expected) { 1010 } 1011 1012 NativeCrypto.SSL_free(s); 1013 NativeCrypto.SSL_CTX_free(c); 1014 } 1015 1016 public void test_SSL_do_handshake_normal() throws Exception { 1017 // normal client and server case 1018 final ServerSocket listener = new ServerSocket(0); 1019 Hooks cHooks = new Hooks(); 1020 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1021 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1022 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1023 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1024 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1025 assertTrue(clientCallback.verifyCertificateChainCalled); 1026 assertEqualCertificateChains(getServerCertificates(), 1027 clientCallback.certificateChainRefs); 1028 assertEquals("RSA", clientCallback.authMethod); 1029 assertFalse(serverCallback.verifyCertificateChainCalled); 1030 assertFalse(clientCallback.clientCertificateRequestedCalled); 1031 assertFalse(serverCallback.clientCertificateRequestedCalled); 1032 assertFalse(clientCallback.clientPSKKeyRequestedInvoked); 1033 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1034 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1035 assertFalse(serverCallback.serverPSKKeyRequestedInvoked); 1036 assertTrue(clientCallback.handshakeCompletedCalled); 1037 assertTrue(serverCallback.handshakeCompletedCalled); 1038 } 1039 1040 public void test_SSL_do_handshake_optional_client_certificate() throws Exception { 1041 // optional client certificate case 1042 final ServerSocket listener = new ServerSocket(0); 1043 1044 Hooks cHooks = new Hooks() { 1045 @Override 1046 public void clientCertificateRequested(long s) { 1047 super.clientCertificateRequested(s); 1048 NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey().getNativeRef()); 1049 NativeCrypto.SSL_use_certificate(s, getClientCertificates()); 1050 } 1051 }; 1052 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1053 @Override 1054 public long beforeHandshake(long c) throws SSLException { 1055 long s = super.beforeHandshake(c); 1056 NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals()); 1057 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 1058 return s; 1059 } 1060 }; 1061 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1062 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1063 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1064 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1065 assertTrue(clientCallback.verifyCertificateChainCalled); 1066 assertEqualCertificateChains(getServerCertificates(), 1067 clientCallback.certificateChainRefs); 1068 assertEquals("RSA", clientCallback.authMethod); 1069 assertTrue(serverCallback.verifyCertificateChainCalled); 1070 assertEqualCertificateChains(getClientCertificates(), 1071 serverCallback.certificateChainRefs); 1072 assertEquals("RSA", serverCallback.authMethod); 1073 1074 assertTrue(clientCallback.clientCertificateRequestedCalled); 1075 assertNotNull(clientCallback.keyTypes); 1076 assertEquals(new HashSet<String>(Arrays.asList("EC", "RSA")), 1077 SSLParametersImpl.getSupportedClientKeyTypes(clientCallback.keyTypes)); 1078 assertEqualPrincipals(getCaPrincipals(), 1079 clientCallback.asn1DerEncodedX500Principals); 1080 assertFalse(serverCallback.clientCertificateRequestedCalled); 1081 1082 assertFalse(clientCallback.clientPSKKeyRequestedInvoked); 1083 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1084 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1085 assertFalse(serverCallback.serverPSKKeyRequestedInvoked); 1086 1087 assertTrue(clientCallback.handshakeCompletedCalled); 1088 assertTrue(serverCallback.handshakeCompletedCalled); 1089 } 1090 1091 public void test_SSL_do_handshake_missing_required_certificate() throws Exception { 1092 // required client certificate negative case 1093 final ServerSocket listener = new ServerSocket(0); 1094 try { 1095 Hooks cHooks = new Hooks(); 1096 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1097 @Override 1098 public long beforeHandshake(long c) throws SSLException { 1099 long s = super.beforeHandshake(c); 1100 NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals()); 1101 NativeCrypto.SSL_set_verify(s, 1102 NativeCrypto.SSL_VERIFY_PEER 1103 | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 1104 return s; 1105 } 1106 }; 1107 @SuppressWarnings("unused") 1108 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 1109 null); 1110 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 1111 null); 1112 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1113 fail(); 1114 } catch (ExecutionException expected) { 1115 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1116 } 1117 } 1118 1119 /** 1120 * Usually if a RuntimeException is thrown by the 1121 * clientCertificateRequestedCalled callback, the caller sees it 1122 * during the call to NativeCrypto_SSL_do_handshake. However, IIS 1123 * does not request client certs until after the initial 1124 * handshake. It does an SSL renegotiation, which means we need to 1125 * be able to deliver the callback's exception in cases like 1126 * SSL_read, SSL_write, and SSL_shutdown. 1127 */ 1128 public void test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate() 1129 throws Exception { 1130 final ServerSocket listener = new ServerSocket(0); 1131 1132 Hooks cHooks = new Hooks() { 1133 @Override 1134 public long beforeHandshake(long context) throws SSLException { 1135 long s = super.beforeHandshake(context); 1136 NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 1137 return s; 1138 } 1139 @Override 1140 public void afterHandshake(long session, long s, long c, 1141 Socket sock, FileDescriptor fd, 1142 SSLHandshakeCallbacks callback) 1143 throws Exception { 1144 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 1145 fail(); 1146 super.afterHandshake(session, s, c, sock, fd, callback); 1147 } 1148 @Override 1149 public void clientCertificateRequested(long s) { 1150 super.clientCertificateRequested(s); 1151 throw new RuntimeException("expected"); 1152 } 1153 }; 1154 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1155 @Override 1156 public void afterHandshake(long session, long s, long c, 1157 Socket sock, FileDescriptor fd, 1158 SSLHandshakeCallbacks callback) 1159 throws Exception { 1160 try { 1161 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 1162 NativeCrypto.SSL_set_options( 1163 s, NativeConstants.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 1164 NativeCrypto.SSL_renegotiate(s); 1165 NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 1166 (int) ((TIMEOUT_SECONDS * 1000) / 2)); 1167 } catch (IOException expected) { 1168 } finally { 1169 super.afterHandshake(session, s, c, sock, fd, callback); 1170 } 1171 } 1172 }; 1173 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1174 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1175 try { 1176 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1177 } catch (ExecutionException e) { 1178 if (!"expected".equals(e.getCause().getMessage())) { 1179 throw e; 1180 } 1181 } 1182 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1183 } 1184 1185 public void test_SSL_do_handshake_client_timeout() throws Exception { 1186 // client timeout 1187 final ServerSocket listener = new ServerSocket(0); 1188 Socket serverSocket = null; 1189 try { 1190 Hooks cHooks = new Hooks(); 1191 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1192 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null, 1193 null); 1194 Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null, 1195 null); 1196 serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket(); 1197 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1198 fail(); 1199 } catch (ExecutionException expected) { 1200 if (SocketTimeoutException.class != expected.getCause().getClass()) { 1201 expected.printStackTrace(); 1202 } 1203 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 1204 } finally { 1205 // Manually close peer socket when testing timeout 1206 IoUtils.closeQuietly(serverSocket); 1207 } 1208 } 1209 1210 public void test_SSL_do_handshake_server_timeout() throws Exception { 1211 // server timeout 1212 final ServerSocket listener = new ServerSocket(0); 1213 Socket clientSocket = null; 1214 try { 1215 Hooks cHooks = new Hooks(); 1216 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1217 Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null, null); 1218 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null, null); 1219 clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket(); 1220 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1221 fail(); 1222 } catch (ExecutionException expected) { 1223 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 1224 } finally { 1225 // Manually close peer socket when testing timeout 1226 IoUtils.closeQuietly(clientSocket); 1227 } 1228 } 1229 1230 public void test_SSL_do_handshake_with_channel_id_normal() throws Exception { 1231 initChannelIdKey(); 1232 1233 // Normal handshake with TLS Channel ID. 1234 final ServerSocket listener = new ServerSocket(0); 1235 Hooks cHooks = new Hooks(); 1236 cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY; 1237 // TLS Channel ID currently requires ECDHE-based key exchanges. 1238 cHooks.enabledCipherSuites = Arrays.asList(new String[] {"ECDHE-RSA-AES128-SHA"}); 1239 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1240 sHooks.channelIdEnabled = true; 1241 sHooks.enabledCipherSuites = cHooks.enabledCipherSuites; 1242 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1243 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1244 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1245 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1246 assertTrue(clientCallback.verifyCertificateChainCalled); 1247 assertEqualCertificateChains(getServerCertificates(), 1248 clientCallback.certificateChainRefs); 1249 assertEquals("ECDHE_RSA", clientCallback.authMethod); 1250 assertFalse(serverCallback.verifyCertificateChainCalled); 1251 assertFalse(clientCallback.clientCertificateRequestedCalled); 1252 assertFalse(serverCallback.clientCertificateRequestedCalled); 1253 assertFalse(clientCallback.clientPSKKeyRequestedInvoked); 1254 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1255 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1256 assertFalse(serverCallback.serverPSKKeyRequestedInvoked); 1257 assertTrue(clientCallback.handshakeCompletedCalled); 1258 assertTrue(serverCallback.handshakeCompletedCalled); 1259 assertNull(sHooks.channelIdAfterHandshakeException); 1260 assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake); 1261 } 1262 1263 public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception { 1264 initChannelIdKey(); 1265 1266 // Client tries to use TLS Channel ID but the server does not enable/offer the extension. 1267 final ServerSocket listener = new ServerSocket(0); 1268 Hooks cHooks = new Hooks(); 1269 cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY; 1270 // TLS Channel ID currently requires ECDHE-based key exchanges. 1271 cHooks.enabledCipherSuites = Arrays.asList(new String[] {"ECDHE-RSA-AES128-SHA"}); 1272 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1273 sHooks.channelIdEnabled = false; 1274 sHooks.enabledCipherSuites = cHooks.enabledCipherSuites; 1275 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1276 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1277 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1278 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1279 assertTrue(clientCallback.verifyCertificateChainCalled); 1280 assertEqualCertificateChains(getServerCertificates(), 1281 clientCallback.certificateChainRefs); 1282 assertEquals("ECDHE_RSA", clientCallback.authMethod); 1283 assertFalse(serverCallback.verifyCertificateChainCalled); 1284 assertFalse(clientCallback.clientCertificateRequestedCalled); 1285 assertFalse(serverCallback.clientCertificateRequestedCalled); 1286 assertFalse(clientCallback.clientPSKKeyRequestedInvoked); 1287 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1288 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1289 assertFalse(serverCallback.serverPSKKeyRequestedInvoked); 1290 assertTrue(clientCallback.handshakeCompletedCalled); 1291 assertTrue(serverCallback.handshakeCompletedCalled); 1292 assertNull(sHooks.channelIdAfterHandshakeException); 1293 assertNull(sHooks.channelIdAfterHandshake); 1294 } 1295 1296 public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception { 1297 initChannelIdKey(); 1298 1299 // Client does not use TLS Channel ID when the server has the extension enabled/offered. 1300 final ServerSocket listener = new ServerSocket(0); 1301 Hooks cHooks = new Hooks(); 1302 cHooks.channelIdPrivateKey = null; 1303 // TLS Channel ID currently requires ECDHE-based key exchanges. 1304 cHooks.enabledCipherSuites = Arrays.asList(new String[] {"ECDHE-RSA-AES128-SHA"}); 1305 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1306 sHooks.channelIdEnabled = true; 1307 sHooks.enabledCipherSuites = cHooks.enabledCipherSuites; 1308 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1309 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1310 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1311 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1312 assertTrue(clientCallback.verifyCertificateChainCalled); 1313 assertEqualCertificateChains(getServerCertificates(), 1314 clientCallback.certificateChainRefs); 1315 assertEquals("ECDHE_RSA", clientCallback.authMethod); 1316 assertFalse(serverCallback.verifyCertificateChainCalled); 1317 assertFalse(clientCallback.clientCertificateRequestedCalled); 1318 assertFalse(serverCallback.clientCertificateRequestedCalled); 1319 assertFalse(clientCallback.clientPSKKeyRequestedInvoked); 1320 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1321 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1322 assertFalse(serverCallback.serverPSKKeyRequestedInvoked); 1323 assertTrue(clientCallback.handshakeCompletedCalled); 1324 assertTrue(serverCallback.handshakeCompletedCalled); 1325 assertNull(sHooks.channelIdAfterHandshakeException); 1326 assertNull(sHooks.channelIdAfterHandshake); 1327 } 1328 1329 public void test_SSL_do_handshake_with_psk_normal() throws Exception { 1330 // normal TLS-PSK client and server case 1331 final ServerSocket listener = new ServerSocket(0); 1332 Hooks cHooks = new ClientHooks(); 1333 ServerHooks sHooks = new ServerHooks(); 1334 cHooks.pskEnabled = true; 1335 sHooks.pskEnabled = true; 1336 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1337 sHooks.pskKey = cHooks.pskKey; 1338 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1339 Future<TestSSLHandshakeCallbacks> server = 1340 handshake(listener, 0, false, sHooks, null, null); 1341 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1342 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1343 assertFalse(clientCallback.verifyCertificateChainCalled); 1344 assertFalse(serverCallback.verifyCertificateChainCalled); 1345 assertFalse(clientCallback.clientCertificateRequestedCalled); 1346 assertFalse(serverCallback.clientCertificateRequestedCalled); 1347 assertTrue(clientCallback.handshakeCompletedCalled); 1348 assertTrue(serverCallback.handshakeCompletedCalled); 1349 assertTrue(clientCallback.clientPSKKeyRequestedInvoked); 1350 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1351 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1352 assertTrue(serverCallback.serverPSKKeyRequestedInvoked); 1353 assertContains(cHooks.negotiatedCipherSuite, "PSK"); 1354 assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite); 1355 assertNull(clientCallback.clientPSKKeyRequestedIdentityHint); 1356 assertNull(serverCallback.serverPSKKeyRequestedIdentityHint); 1357 assertEquals("", serverCallback.serverPSKKeyRequestedIdentity); 1358 } 1359 1360 public void test_SSL_do_handshake_with_psk_with_identity_and_hint() throws Exception { 1361 // normal TLS-PSK client and server case where the server provides the client with a PSK 1362 // identity hint, and the client provides the server with a PSK identity. 1363 final ServerSocket listener = new ServerSocket(0); 1364 ClientHooks cHooks = new ClientHooks(); 1365 ServerHooks sHooks = new ServerHooks(); 1366 cHooks.pskEnabled = true; 1367 sHooks.pskEnabled = true; 1368 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1369 sHooks.pskKey = cHooks.pskKey; 1370 sHooks.pskIdentityHint = "Some non-ASCII characters: \u00c4\u0332"; 1371 cHooks.pskIdentity = "More non-ASCII characters: \u00f5\u044b"; 1372 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1373 Future<TestSSLHandshakeCallbacks> server = 1374 handshake(listener, 0, false, sHooks, null, null); 1375 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1376 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1377 assertFalse(clientCallback.verifyCertificateChainCalled); 1378 assertFalse(serverCallback.verifyCertificateChainCalled); 1379 assertFalse(clientCallback.clientCertificateRequestedCalled); 1380 assertFalse(serverCallback.clientCertificateRequestedCalled); 1381 assertTrue(clientCallback.handshakeCompletedCalled); 1382 assertTrue(serverCallback.handshakeCompletedCalled); 1383 assertTrue(clientCallback.clientPSKKeyRequestedInvoked); 1384 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1385 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1386 assertTrue(serverCallback.serverPSKKeyRequestedInvoked); 1387 assertContains(cHooks.negotiatedCipherSuite, "PSK"); 1388 assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite); 1389 assertEquals(sHooks.pskIdentityHint, clientCallback.clientPSKKeyRequestedIdentityHint); 1390 assertEquals(sHooks.pskIdentityHint, serverCallback.serverPSKKeyRequestedIdentityHint); 1391 assertEquals(cHooks.pskIdentity, serverCallback.serverPSKKeyRequestedIdentity); 1392 } 1393 1394 public void test_SSL_do_handshake_with_psk_with_identity_and_hint_of_max_length() 1395 throws Exception { 1396 // normal TLS-PSK client and server case where the server provides the client with a PSK 1397 // identity hint, and the client provides the server with a PSK identity. 1398 final ServerSocket listener = new ServerSocket(0); 1399 ClientHooks cHooks = new ClientHooks(); 1400 ServerHooks sHooks = new ServerHooks(); 1401 cHooks.pskEnabled = true; 1402 sHooks.pskEnabled = true; 1403 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1404 sHooks.pskKey = cHooks.pskKey; 1405 sHooks.pskIdentityHint = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" 1406 + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx"; 1407 cHooks.pskIdentity = "123456789012345678901234567890123456789012345678901234567890" 1408 + "12345678901234567890123456789012345678901234567890123456789012345678"; 1409 assertEquals(PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES, sHooks.pskIdentityHint.length()); 1410 assertEquals(PSKKeyManager.MAX_IDENTITY_LENGTH_BYTES, cHooks.pskIdentity.length()); 1411 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1412 Future<TestSSLHandshakeCallbacks> server = 1413 handshake(listener, 0, false, sHooks, null, null); 1414 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1415 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1416 assertFalse(clientCallback.verifyCertificateChainCalled); 1417 assertFalse(serverCallback.verifyCertificateChainCalled); 1418 assertFalse(clientCallback.clientCertificateRequestedCalled); 1419 assertFalse(serverCallback.clientCertificateRequestedCalled); 1420 assertTrue(clientCallback.handshakeCompletedCalled); 1421 assertTrue(serverCallback.handshakeCompletedCalled); 1422 assertTrue(clientCallback.clientPSKKeyRequestedInvoked); 1423 assertFalse(clientCallback.serverPSKKeyRequestedInvoked); 1424 assertFalse(serverCallback.clientPSKKeyRequestedInvoked); 1425 assertTrue(serverCallback.serverPSKKeyRequestedInvoked); 1426 assertContains(cHooks.negotiatedCipherSuite, "PSK"); 1427 assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite); 1428 assertEquals(sHooks.pskIdentityHint, clientCallback.clientPSKKeyRequestedIdentityHint); 1429 assertEquals(sHooks.pskIdentityHint, serverCallback.serverPSKKeyRequestedIdentityHint); 1430 assertEquals(cHooks.pskIdentity, serverCallback.serverPSKKeyRequestedIdentity); 1431 } 1432 1433 public void test_SSL_do_handshake_with_psk_key_mismatch() throws Exception { 1434 final ServerSocket listener = new ServerSocket(0); 1435 ClientHooks cHooks = new ClientHooks(); 1436 ServerHooks sHooks = new ServerHooks(); 1437 cHooks.pskEnabled = true; 1438 sHooks.pskEnabled = true; 1439 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1440 sHooks.pskKey = "1, 2, 3, 3, Testing...".getBytes("UTF-8"); 1441 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1442 Future<TestSSLHandshakeCallbacks> server = 1443 handshake(listener, 0, false, sHooks, null, null); 1444 try { 1445 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1446 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1447 fail(); 1448 } catch (ExecutionException expected) { 1449 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1450 } 1451 } 1452 1453 public void test_SSL_do_handshake_with_psk_with_no_client_key() throws Exception { 1454 final ServerSocket listener = new ServerSocket(0); 1455 ClientHooks cHooks = new ClientHooks(); 1456 ServerHooks sHooks = new ServerHooks(); 1457 cHooks.pskEnabled = true; 1458 sHooks.pskEnabled = true; 1459 cHooks.pskKey = null; 1460 sHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1461 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1462 Future<TestSSLHandshakeCallbacks> server = 1463 handshake(listener, 0, false, sHooks, null, null); 1464 try { 1465 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1466 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1467 fail(); 1468 } catch (ExecutionException expected) { 1469 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1470 } 1471 } 1472 1473 public void test_SSL_do_handshake_with_psk_with_no_server_key() throws Exception { 1474 final ServerSocket listener = new ServerSocket(0); 1475 ClientHooks cHooks = new ClientHooks(); 1476 ServerHooks sHooks = new ServerHooks(); 1477 cHooks.pskEnabled = true; 1478 sHooks.pskEnabled = true; 1479 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1480 sHooks.pskKey = null; 1481 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1482 Future<TestSSLHandshakeCallbacks> server = 1483 handshake(listener, 0, false, sHooks, null, null); 1484 try { 1485 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1486 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1487 fail(); 1488 } catch (ExecutionException expected) { 1489 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1490 } 1491 } 1492 1493 public void test_SSL_do_handshake_with_psk_key_too_long() throws Exception { 1494 final ServerSocket listener = new ServerSocket(0); 1495 ClientHooks cHooks = new ClientHooks() { 1496 @Override 1497 public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) { 1498 super.configureCallbacks(callbacks); 1499 callbacks.clientPSKKeyRequestedResult = PSKKeyManager.MAX_KEY_LENGTH_BYTES + 1; 1500 } 1501 }; 1502 ServerHooks sHooks = new ServerHooks(); 1503 cHooks.pskEnabled = true; 1504 sHooks.pskEnabled = true; 1505 cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8"); 1506 sHooks.pskKey = cHooks.pskKey; 1507 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1508 Future<TestSSLHandshakeCallbacks> server = 1509 handshake(listener, 0, false, sHooks, null, null); 1510 try { 1511 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1512 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1513 fail(); 1514 } catch (ExecutionException expected) { 1515 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1516 } 1517 } 1518 1519 public void test_SSL_do_handshake_with_ocsp_response() throws Exception { 1520 // This is only implemented for BoringSSL 1521 if (!NativeCrypto.isBoringSSL) { 1522 return; 1523 } 1524 1525 final byte[] OCSP_TEST_DATA = new byte[] { 1, 2, 3, 4}; 1526 1527 final ServerSocket listener = new ServerSocket(0); 1528 Hooks cHooks = new Hooks() { 1529 @Override 1530 public long beforeHandshake(long c) throws SSLException { 1531 long s = super.beforeHandshake(c); 1532 NativeCrypto.SSL_enable_ocsp_stapling(s); 1533 return s; 1534 } 1535 1536 @Override 1537 public void afterHandshake(long session, long ssl, long context, Socket socket, 1538 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1539 assertEqualByteArrays(OCSP_TEST_DATA, NativeCrypto.SSL_get_ocsp_response(ssl)); 1540 super.afterHandshake(session, ssl, context, socket, fd, callback); 1541 } 1542 }; 1543 1544 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1545 @Override 1546 public long beforeHandshake(long c) throws SSLException { 1547 NativeCrypto.SSL_CTX_set_ocsp_response(c, OCSP_TEST_DATA); 1548 return super.beforeHandshake(c); 1549 } 1550 }; 1551 1552 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1553 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1554 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1555 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1556 1557 assertTrue(clientCallback.handshakeCompletedCalled); 1558 assertTrue(serverCallback.handshakeCompletedCalled); 1559 } 1560 1561 public void test_SSL_do_handshake_with_sct_extension() throws Exception { 1562 // This is only implemented for BoringSSL 1563 if (!NativeCrypto.isBoringSSL) { 1564 return; 1565 } 1566 1567 final byte[] SCT_TEST_DATA = new byte[] { 1, 2, 3, 4}; 1568 1569 final ServerSocket listener = new ServerSocket(0); 1570 Hooks cHooks = new Hooks() { 1571 @Override 1572 public long beforeHandshake(long c) throws SSLException { 1573 long s = super.beforeHandshake(c); 1574 NativeCrypto.SSL_enable_signed_cert_timestamps(s); 1575 return s; 1576 } 1577 1578 @Override 1579 public void afterHandshake(long session, long ssl, long context, Socket socket, 1580 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1581 assertEqualByteArrays(SCT_TEST_DATA, 1582 NativeCrypto.SSL_get_signed_cert_timestamp_list(ssl)); 1583 super.afterHandshake(session, ssl, context, socket, fd, callback); 1584 } 1585 }; 1586 1587 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1588 @Override 1589 public long beforeHandshake(long c) throws SSLException { 1590 NativeCrypto.SSL_CTX_set_signed_cert_timestamp_list(c, SCT_TEST_DATA); 1591 return super.beforeHandshake(c); 1592 } 1593 }; 1594 1595 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1596 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1597 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1598 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1599 1600 assertTrue(clientCallback.handshakeCompletedCalled); 1601 assertTrue(serverCallback.handshakeCompletedCalled); 1602 } 1603 1604 public void test_SSL_use_psk_identity_hint() throws Exception { 1605 long c = NativeCrypto.SSL_CTX_new(); 1606 long s = NativeCrypto.SSL_new(c); 1607 try { 1608 NativeCrypto.SSL_use_psk_identity_hint(s, null); 1609 NativeCrypto.SSL_use_psk_identity_hint(s, "test"); 1610 1611 try { 1612 // 800 characters is much longer than the permitted maximum. 1613 StringBuilder pskIdentityHint = new StringBuilder(); 1614 for (int i = 0; i < 160; i++) { 1615 pskIdentityHint.append(" long"); 1616 } 1617 assertTrue(pskIdentityHint.length() > PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES); 1618 NativeCrypto.SSL_use_psk_identity_hint(s, pskIdentityHint.toString()); 1619 fail(); 1620 } catch (SSLException expected) { 1621 } 1622 } finally { 1623 NativeCrypto.SSL_free(s); 1624 NativeCrypto.SSL_CTX_free(c); 1625 } 1626 } 1627 1628 public void test_SSL_set_session() throws Exception { 1629 try { 1630 NativeCrypto.SSL_set_session(NULL, NULL); 1631 fail(); 1632 } catch (NullPointerException expected) { 1633 } 1634 1635 { 1636 long c = NativeCrypto.SSL_CTX_new(); 1637 long s = NativeCrypto.SSL_new(c); 1638 NativeCrypto.SSL_set_session(s, NULL); 1639 NativeCrypto.SSL_free(s); 1640 NativeCrypto.SSL_CTX_free(c); 1641 } 1642 1643 { 1644 final long clientContext = NativeCrypto.SSL_CTX_new(); 1645 final long serverContext = NativeCrypto.SSL_CTX_new(); 1646 final ServerSocket listener = new ServerSocket(0); 1647 final long[] clientSession = new long[] { NULL }; 1648 final long[] serverSession = new long[] { NULL }; 1649 { 1650 Hooks cHooks = new Hooks() { 1651 @Override 1652 public long getContext() throws SSLException { 1653 return clientContext; 1654 } 1655 @Override 1656 public void afterHandshake(long session, long s, long c, 1657 Socket sock, FileDescriptor fd, 1658 SSLHandshakeCallbacks callback) 1659 throws Exception { 1660 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1661 clientSession[0] = session; 1662 } 1663 }; 1664 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1665 @Override 1666 public long getContext() throws SSLException { 1667 return serverContext; 1668 } 1669 @Override 1670 public void afterHandshake(long session, long s, long c, 1671 Socket sock, FileDescriptor fd, 1672 SSLHandshakeCallbacks callback) 1673 throws Exception { 1674 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1675 serverSession[0] = session; 1676 } 1677 }; 1678 Future<TestSSLHandshakeCallbacks> client 1679 = handshake(listener, 0, true, cHooks, null, null); 1680 Future<TestSSLHandshakeCallbacks> server 1681 = handshake(listener, 0, false, sHooks, null, null); 1682 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1683 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1684 } 1685 assertEqualSessions(clientSession[0], serverSession[0]); 1686 { 1687 Hooks cHooks = new Hooks() { 1688 @Override 1689 public long getContext() throws SSLException { 1690 return clientContext; 1691 } 1692 @Override 1693 public long beforeHandshake(long c) throws SSLException { 1694 long s = NativeCrypto.SSL_new(clientContext); 1695 NativeCrypto.SSL_set_session(s, clientSession[0]); 1696 return s; 1697 } 1698 @Override 1699 public void afterHandshake(long session, long s, long c, 1700 Socket sock, FileDescriptor fd, 1701 SSLHandshakeCallbacks callback) 1702 throws Exception { 1703 assertEqualSessions(clientSession[0], session); 1704 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1705 } 1706 }; 1707 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1708 @Override 1709 public long getContext() throws SSLException { 1710 return serverContext; 1711 } 1712 @Override 1713 public void afterHandshake(long session, long s, long c, 1714 Socket sock, FileDescriptor fd, 1715 SSLHandshakeCallbacks callback) 1716 throws Exception { 1717 assertEqualSessions(serverSession[0], session); 1718 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1719 } 1720 }; 1721 Future<TestSSLHandshakeCallbacks> client 1722 = handshake(listener, 0, true, cHooks, null, null); 1723 Future<TestSSLHandshakeCallbacks> server 1724 = handshake(listener, 0, false, sHooks, null, null); 1725 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1726 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1727 } 1728 NativeCrypto.SSL_SESSION_free(clientSession[0]); 1729 NativeCrypto.SSL_SESSION_free(serverSession[0]); 1730 NativeCrypto.SSL_CTX_free(serverContext); 1731 NativeCrypto.SSL_CTX_free(clientContext); 1732 } 1733 } 1734 1735 public void test_SSL_set_session_creation_enabled() throws Exception { 1736 try { 1737 NativeCrypto.SSL_set_session_creation_enabled(NULL, false); 1738 fail(); 1739 } catch (NullPointerException expected) { 1740 } 1741 1742 { 1743 long c = NativeCrypto.SSL_CTX_new(); 1744 long s = NativeCrypto.SSL_new(c); 1745 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1746 NativeCrypto.SSL_set_session_creation_enabled(s, true); 1747 NativeCrypto.SSL_free(s); 1748 NativeCrypto.SSL_CTX_free(c); 1749 } 1750 1751 final ServerSocket listener = new ServerSocket(0); 1752 1753 // negative test case for SSL_set_session_creation_enabled(false) on client 1754 { 1755 Hooks cHooks = new Hooks() { 1756 @Override 1757 public long beforeHandshake(long c) throws SSLException { 1758 long s = super.beforeHandshake(c); 1759 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1760 return s; 1761 } 1762 }; 1763 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1764 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 1765 null); 1766 @SuppressWarnings("unused") 1767 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 1768 null); 1769 try { 1770 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1771 fail(); 1772 } catch (ExecutionException expected) { 1773 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1774 } 1775 try { 1776 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1777 fail(); 1778 } catch (ExecutionException expected) { 1779 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1780 } 1781 } 1782 1783 // negative test case for SSL_set_session_creation_enabled(false) on server 1784 { 1785 Hooks cHooks = new Hooks(); 1786 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1787 @Override 1788 public long beforeHandshake(long c) throws SSLException { 1789 long s = super.beforeHandshake(c); 1790 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1791 return s; 1792 } 1793 }; 1794 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 1795 null); 1796 @SuppressWarnings("unused") 1797 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 1798 null); 1799 try { 1800 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1801 fail(); 1802 } catch (ExecutionException expected) { 1803 assertEquals(SSLHandshakeException.class, expected.getCause().getClass()); 1804 } 1805 try { 1806 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1807 fail(); 1808 } catch (ExecutionException expected) { 1809 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1810 } 1811 } 1812 } 1813 1814 public void test_SSL_set_tlsext_host_name() throws Exception { 1815 // NULL SSL 1816 try { 1817 NativeCrypto.SSL_set_tlsext_host_name(NULL, null); 1818 fail(); 1819 } catch (NullPointerException expected) { 1820 } 1821 1822 final String hostname = "www.android.com"; 1823 1824 { 1825 long c = NativeCrypto.SSL_CTX_new(); 1826 long s = NativeCrypto.SSL_new(c); 1827 1828 // null hostname 1829 try { 1830 NativeCrypto.SSL_set_tlsext_host_name(s, null); 1831 fail(); 1832 } catch (NullPointerException expected) { 1833 } 1834 1835 // too long hostname 1836 try { 1837 char[] longHostname = new char[256]; 1838 Arrays.fill(longHostname, 'w'); 1839 NativeCrypto.SSL_set_tlsext_host_name(s, new String(longHostname)); 1840 fail(); 1841 } catch (SSLException expected) { 1842 } 1843 1844 assertNull(NativeCrypto.SSL_get_servername(s)); 1845 NativeCrypto.SSL_set_tlsext_host_name(s, new String(hostname)); 1846 assertEquals(hostname, NativeCrypto.SSL_get_servername(s)); 1847 1848 NativeCrypto.SSL_free(s); 1849 NativeCrypto.SSL_CTX_free(c); 1850 } 1851 1852 final ServerSocket listener = new ServerSocket(0); 1853 1854 // normal 1855 Hooks cHooks = new Hooks() { 1856 @Override 1857 public long beforeHandshake(long c) throws SSLException { 1858 long s = super.beforeHandshake(c); 1859 NativeCrypto.SSL_set_tlsext_host_name(s, hostname); 1860 return s; 1861 } 1862 }; 1863 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1864 @Override 1865 public void afterHandshake(long session, long s, long c, 1866 Socket sock, FileDescriptor fd, 1867 SSLHandshakeCallbacks callback) 1868 throws Exception { 1869 assertEquals(hostname, NativeCrypto.SSL_get_servername(s)); 1870 super.afterHandshake(session, s, c, sock, fd, callback); 1871 } 1872 }; 1873 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 1874 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 1875 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1876 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1877 } 1878 1879 public void test_SSL_NpnNegotiateSuccess() throws Exception { 1880 final byte[] clientNpnProtocols = new byte[] { 1881 8, 'h', 't', 't', 'p', '/', '1', '.', '1', 1882 3, 'f', 'o', 'o', 1883 6, 's', 'p', 'd', 'y', '/', '2', 1884 }; 1885 final byte[] serverNpnProtocols = new byte[] { 1886 6, 's', 'p', 'd', 'y', '/', '2', 1887 3, 'f', 'o', 'o', 1888 3, 'b', 'a', 'r', 1889 }; 1890 1891 Hooks cHooks = new Hooks() { 1892 @Override public long beforeHandshake(long context) throws SSLException { 1893 NativeCrypto.SSL_CTX_enable_npn(context); 1894 return super.beforeHandshake(context); 1895 } 1896 @Override public void afterHandshake(long session, long ssl, long context, Socket socket, 1897 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1898 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl); 1899 assertEquals("spdy/2", new String(negotiated)); 1900 /* 1901 * False Start (a.k.a. handshake cut-through): 1902 * In BoringSSL, this is enabled unconditionally since it 1903 * implements the check internally. 1904 */ 1905 assertTrue("NPN should enable cutthrough on the client", 1906 0 != (NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH)); 1907 NativeCrypto.SSL_write(ssl, fd, callback, new byte[] { 42 }, 0, 1, 1908 (int) ((TIMEOUT_SECONDS * 1000) / 2)); 1909 super.afterHandshake(session, ssl, context, socket, fd, callback); 1910 } 1911 }; 1912 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1913 @Override public long beforeHandshake(long context) throws SSLException { 1914 NativeCrypto.SSL_CTX_enable_npn(context); 1915 return super.beforeHandshake(context); 1916 } 1917 @Override public void afterHandshake(long session, long ssl, long c, Socket sock, 1918 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1919 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl); 1920 assertEquals("spdy/2", new String(negotiated)); 1921 if (!NativeCrypto.isBoringSSL) { 1922 /* 1923 * False Start (a.k.a. handshake cut-through): 1924 * In BoringSSL, this is enabled unconditionally since it 1925 * implements the check internally. 1926 */ 1927 assertEquals("NPN should not enable cutthrough on the server", 1928 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 1929 } 1930 byte[] buffer = new byte[1]; 1931 NativeCrypto.SSL_read(ssl, fd, callback, buffer, 0, 1, 0); 1932 assertEquals(42, buffer[0]); 1933 super.afterHandshake(session, ssl, c, sock, fd, callback); 1934 } 1935 }; 1936 1937 ServerSocket listener = new ServerSocket(0); 1938 Future<TestSSLHandshakeCallbacks> client 1939 = handshake(listener, 0, true, cHooks, clientNpnProtocols, null); 1940 Future<TestSSLHandshakeCallbacks> server 1941 = handshake(listener, 0, false, sHooks, serverNpnProtocols, null); 1942 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1943 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1944 } 1945 1946 public void test_SSL_AlpnNegotiateSuccess() throws Exception { 1947 final byte[] clientAlpnProtocols = new byte[] { 1948 8, 'h', 't', 't', 'p', '/', '1', '.', '1', 1949 3, 'f', 'o', 'o', 1950 6, 's', 'p', 'd', 'y', '/', '2', 1951 }; 1952 final byte[] serverAlpnProtocols = new byte[] { 1953 6, 's', 'p', 'd', 'y', '/', '2', 1954 3, 'f', 'o', 'o', 1955 3, 'b', 'a', 'r', 1956 }; 1957 1958 Hooks cHooks = new Hooks() { 1959 @Override public long beforeHandshake(long context) throws SSLException { 1960 long sslContext = super.beforeHandshake(context); 1961 NativeCrypto.SSL_set_alpn_protos(sslContext, clientAlpnProtocols); 1962 return sslContext; 1963 } 1964 @Override public void afterHandshake(long session, long ssl, long context, Socket socket, 1965 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1966 byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl); 1967 assertEquals("spdy/2", new String(negotiated)); 1968 if (!NativeCrypto.isBoringSSL) { 1969 /* 1970 * False Start (a.k.a. handshake cut-through): 1971 * There is no callback on the client, so we can't enable 1972 * cut-through on OpenSSL. In BoringSSL, this is enabled 1973 * unconditionally since it implements the check internally. 1974 */ 1975 assertEquals("ALPN should not enable cutthrough on the client", 0, 1976 NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 1977 } 1978 super.afterHandshake(session, ssl, context, socket, fd, callback); 1979 } 1980 }; 1981 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1982 @Override public void afterHandshake(long session, long ssl, long c, Socket sock, 1983 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1984 byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl); 1985 assertEquals("spdy/2", new String(negotiated)); 1986 if (!NativeCrypto.isBoringSSL) { 1987 /* 1988 * False Start (a.k.a. handshake cut-through): 1989 * In BoringSSL, this is enabled unconditionally since it 1990 * implements the check internally. 1991 */ 1992 assertEquals("ALPN should not enable cutthrough on the server", 1993 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 1994 } 1995 super.afterHandshake(session, ssl, c, sock, fd, callback); 1996 } 1997 }; 1998 1999 ServerSocket listener = new ServerSocket(0); 2000 Future<TestSSLHandshakeCallbacks> client 2001 = handshake(listener, 0, true, cHooks, null, null); 2002 Future<TestSSLHandshakeCallbacks> server 2003 = handshake(listener, 0, false, sHooks, null, serverAlpnProtocols); 2004 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2005 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2006 } 2007 2008 public void test_SSL_get_servername_null() throws Exception { 2009 // NULL SSL 2010 try { 2011 NativeCrypto.SSL_get_servername(NULL); 2012 fail(); 2013 } catch (NullPointerException expected) { 2014 } 2015 2016 long c = NativeCrypto.SSL_CTX_new(); 2017 long s = NativeCrypto.SSL_new(c); 2018 assertNull(NativeCrypto.SSL_get_servername(s)); 2019 NativeCrypto.SSL_free(s); 2020 NativeCrypto.SSL_CTX_free(c); 2021 2022 // additional positive testing by test_SSL_set_tlsext_host_name 2023 } 2024 2025 public void test_SSL_renegotiate() throws Exception { 2026 try { 2027 NativeCrypto.SSL_renegotiate(NULL); 2028 fail(); 2029 } catch (NullPointerException expected) { 2030 } 2031 2032 final ServerSocket listener = new ServerSocket(0); 2033 Hooks cHooks = new Hooks() { 2034 @Override 2035 public void afterHandshake(long session, long s, long c, 2036 Socket sock, FileDescriptor fd, 2037 SSLHandshakeCallbacks callback) 2038 throws Exception { 2039 byte[] buffer = new byte[1]; 2040 NativeCrypto.SSL_read(s, fd, callback, buffer, 0, 1, 0); 2041 assertEquals(42, buffer[0]); 2042 super.afterHandshake(session, s, c, sock, fd, callback); 2043 } 2044 }; 2045 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 2046 @Override 2047 public void afterHandshake(long session, long s, long c, 2048 Socket sock, FileDescriptor fd, 2049 SSLHandshakeCallbacks callback) 2050 throws Exception { 2051 NativeCrypto.SSL_renegotiate(s); 2052 NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0); 2053 super.afterHandshake(session, s, c, sock, fd, callback); 2054 } 2055 }; 2056 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2057 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2058 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2059 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2060 } 2061 2062 public void test_SSL_get_certificate() throws Exception { 2063 try { 2064 NativeCrypto.SSL_get_certificate(NULL); 2065 fail(); 2066 } catch (NullPointerException expected) { 2067 } 2068 2069 final ServerSocket listener = new ServerSocket(0); 2070 Hooks cHooks = new Hooks() { 2071 @Override 2072 public void afterHandshake(long session, long s, long c, 2073 Socket sock, FileDescriptor fd, 2074 SSLHandshakeCallbacks callback) 2075 throws Exception { 2076 assertNull(NativeCrypto.SSL_get_certificate(s)); 2077 super.afterHandshake(session, s, c, sock, fd, callback); 2078 } 2079 }; 2080 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 2081 @Override 2082 public void afterHandshake(long session, long s, long c, 2083 Socket sock, FileDescriptor fd, 2084 SSLHandshakeCallbacks callback) 2085 throws Exception { 2086 assertEqualCertificateChains( 2087 getServerCertificates(), 2088 NativeCrypto.SSL_get_certificate(s)); 2089 super.afterHandshake(session, s, c, sock, fd, callback); 2090 } 2091 }; 2092 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2093 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2094 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2095 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2096 } 2097 2098 public void test_SSL_get_peer_cert_chain() throws Exception { 2099 try { 2100 NativeCrypto.SSL_get_peer_cert_chain(NULL); 2101 fail(); 2102 } catch (NullPointerException expected) { 2103 } 2104 2105 final ServerSocket listener = new ServerSocket(0); 2106 2107 Hooks cHooks = new Hooks() { 2108 @Override 2109 public void afterHandshake(long session, long s, long c, 2110 Socket sock, FileDescriptor fd, 2111 SSLHandshakeCallbacks callback) 2112 throws Exception { 2113 long[] cc = NativeCrypto.SSL_get_peer_cert_chain(s); 2114 assertEqualCertificateChains(getServerCertificates(), cc); 2115 for (long ref : cc) { 2116 NativeCrypto.X509_free(ref); 2117 } 2118 super.afterHandshake(session, s, c, sock, fd, callback); 2119 } 2120 }; 2121 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2122 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2123 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2124 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2125 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2126 } 2127 2128 final byte[] BYTES = new byte[] { 2, -3, 5, 127, 0, -128 }; 2129 2130 public void test_SSL_read() throws Exception { 2131 2132 // NULL ssl 2133 try { 2134 NativeCrypto.SSL_read(NULL, null, null, null, 0, 0, 0); 2135 fail(); 2136 } catch (NullPointerException expected) { 2137 } 2138 2139 // null FileDescriptor 2140 { 2141 long c = NativeCrypto.SSL_CTX_new(); 2142 long s = NativeCrypto.SSL_new(c); 2143 try { 2144 NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0); 2145 fail(); 2146 } catch (NullPointerException expected) { 2147 } 2148 NativeCrypto.SSL_free(s); 2149 NativeCrypto.SSL_CTX_free(c); 2150 } 2151 2152 // null SSLHandshakeCallbacks 2153 { 2154 long c = NativeCrypto.SSL_CTX_new(); 2155 long s = NativeCrypto.SSL_new(c); 2156 try { 2157 NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0); 2158 fail(); 2159 } catch (NullPointerException expected) { 2160 } 2161 NativeCrypto.SSL_free(s); 2162 NativeCrypto.SSL_CTX_free(c); 2163 } 2164 2165 // null byte array 2166 { 2167 long c = NativeCrypto.SSL_CTX_new(); 2168 long s = NativeCrypto.SSL_new(c); 2169 try { 2170 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0); 2171 fail(); 2172 } catch (NullPointerException expected) { 2173 } 2174 NativeCrypto.SSL_free(s); 2175 NativeCrypto.SSL_CTX_free(c); 2176 } 2177 2178 // handshaking not yet performed 2179 { 2180 long c = NativeCrypto.SSL_CTX_new(); 2181 long s = NativeCrypto.SSL_new(c); 2182 try { 2183 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0); 2184 fail(); 2185 } catch (SSLException expected) { 2186 } 2187 NativeCrypto.SSL_free(s); 2188 NativeCrypto.SSL_CTX_free(c); 2189 } 2190 2191 final ServerSocket listener = new ServerSocket(0); 2192 2193 // normal case 2194 { 2195 Hooks cHooks = new Hooks() { 2196 @Override 2197 public void afterHandshake(long session, long s, long c, 2198 Socket sock, FileDescriptor fd, 2199 SSLHandshakeCallbacks callback) 2200 throws Exception { 2201 byte[] in = new byte[256]; 2202 assertEquals(BYTES.length, 2203 NativeCrypto.SSL_read(s, 2204 fd, 2205 callback, 2206 in, 2207 0, 2208 BYTES.length, 2209 0)); 2210 for (int i = 0; i < BYTES.length; i++) { 2211 assertEquals(BYTES[i], in[i]); 2212 } 2213 super.afterHandshake(session, s, c, sock, fd, callback); 2214 } 2215 }; 2216 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 2217 @Override 2218 public void afterHandshake(long session, long s, long c, 2219 Socket sock, FileDescriptor fd, 2220 SSLHandshakeCallbacks callback) 2221 throws Exception { 2222 NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0); 2223 super.afterHandshake(session, s, c, sock, fd, callback); 2224 } 2225 }; 2226 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 2227 null); 2228 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 2229 null); 2230 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2231 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2232 } 2233 2234 // timeout case 2235 try { 2236 Hooks cHooks = new Hooks() { 2237 @Override 2238 public void afterHandshake(long session, long s, long c, 2239 Socket sock, FileDescriptor fd, 2240 SSLHandshakeCallbacks callback) 2241 throws Exception { 2242 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 1); 2243 fail(); 2244 } 2245 }; 2246 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 2247 @Override 2248 public void afterHandshake(long session, long s, long c, 2249 Socket sock, FileDescriptor fd, 2250 SSLHandshakeCallbacks callback) 2251 throws Exception { 2252 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 2253 super.afterHandshake(session, s, c, sock, fd, callback); 2254 } 2255 }; 2256 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 2257 null); 2258 @SuppressWarnings("unused") 2259 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 2260 null); 2261 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2262 fail(); 2263 } catch (ExecutionException expected) { 2264 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 2265 } 2266 } 2267 2268 public void test_SSL_write() throws Exception { 2269 try { 2270 NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0); 2271 fail(); 2272 } catch (NullPointerException expected) { 2273 } 2274 2275 // null FileDescriptor 2276 { 2277 long c = NativeCrypto.SSL_CTX_new(); 2278 long s = NativeCrypto.SSL_new(c); 2279 try { 2280 NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0); 2281 fail(); 2282 } catch (NullPointerException expected) { 2283 } 2284 NativeCrypto.SSL_free(s); 2285 NativeCrypto.SSL_CTX_free(c); 2286 } 2287 2288 // null SSLHandshakeCallbacks 2289 { 2290 long c = NativeCrypto.SSL_CTX_new(); 2291 long s = NativeCrypto.SSL_new(c); 2292 try { 2293 NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0); 2294 fail(); 2295 } catch (NullPointerException expected) { 2296 } 2297 NativeCrypto.SSL_free(s); 2298 NativeCrypto.SSL_CTX_free(c); 2299 } 2300 2301 // null byte array 2302 { 2303 long c = NativeCrypto.SSL_CTX_new(); 2304 long s = NativeCrypto.SSL_new(c); 2305 try { 2306 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0); 2307 fail(); 2308 } catch (NullPointerException expected) { 2309 } 2310 NativeCrypto.SSL_free(s); 2311 NativeCrypto.SSL_CTX_free(c); 2312 } 2313 2314 // handshaking not yet performed 2315 { 2316 long c = NativeCrypto.SSL_CTX_new(); 2317 long s = NativeCrypto.SSL_new(c); 2318 try { 2319 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0); 2320 fail(); 2321 } catch (SSLException expected) { 2322 } 2323 NativeCrypto.SSL_free(s); 2324 NativeCrypto.SSL_CTX_free(c); 2325 } 2326 2327 // positively tested by test_SSL_read 2328 } 2329 2330 public void test_SSL_interrupt() throws Exception { 2331 // SSL_interrupt is a rare case that tolerates a null SSL argument 2332 NativeCrypto.SSL_interrupt(NULL); 2333 2334 // also works without handshaking 2335 { 2336 long c = NativeCrypto.SSL_CTX_new(); 2337 long s = NativeCrypto.SSL_new(c); 2338 NativeCrypto.SSL_interrupt(s); 2339 NativeCrypto.SSL_free(s); 2340 NativeCrypto.SSL_CTX_free(c); 2341 } 2342 2343 final ServerSocket listener = new ServerSocket(0); 2344 2345 Hooks cHooks = new Hooks() { 2346 @Override 2347 public void afterHandshake(long session, long s, long c, 2348 Socket sock, FileDescriptor fd, 2349 SSLHandshakeCallbacks callback) 2350 throws Exception { 2351 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 2352 super.afterHandshake(session, s, c, sock, fd, callback); 2353 } 2354 }; 2355 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 2356 @Override 2357 public void afterHandshake(long session, final long s, long c, 2358 Socket sock, FileDescriptor fd, 2359 SSLHandshakeCallbacks callback) 2360 throws Exception { 2361 new Thread() { 2362 @Override 2363 public void run() { 2364 try { 2365 Thread.sleep(1*1000); 2366 NativeCrypto.SSL_interrupt(s); 2367 } catch (Exception e) { 2368 } 2369 } 2370 }.start(); 2371 assertEquals(-1, NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0)); 2372 super.afterHandshake(session, s, c, sock, fd, callback); 2373 } 2374 }; 2375 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2376 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2377 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2378 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2379 } 2380 2381 private static abstract class SSLSessionWrappedTask { 2382 public abstract void run(long sslSession) throws Exception; 2383 } 2384 2385 private void wrapWithSSLSession(SSLSessionWrappedTask task) throws Exception { 2386 long c = NativeCrypto.SSL_CTX_new(); 2387 long s = NativeCrypto.SSL_new(c); 2388 try { 2389 task.run(s); 2390 } finally { 2391 NativeCrypto.SSL_free(s); 2392 NativeCrypto.SSL_CTX_free(c); 2393 } 2394 } 2395 2396 public void test_SSL_shutdown() throws Exception { 2397 2398 // null FileDescriptor 2399 wrapWithSSLSession(new SSLSessionWrappedTask() { 2400 @Override 2401 public void run(long sslSession) throws Exception { 2402 try { 2403 NativeCrypto.SSL_shutdown(sslSession, null, DUMMY_CB); 2404 fail(); 2405 } catch (NullPointerException expected) { 2406 } 2407 } 2408 }); 2409 2410 // null SSLHandshakeCallbacks 2411 wrapWithSSLSession(new SSLSessionWrappedTask() { 2412 @Override 2413 public void run(long sslSession) throws Exception { 2414 try { 2415 NativeCrypto.SSL_shutdown(sslSession, INVALID_FD, null); 2416 fail(); 2417 } catch (NullPointerException expected) { 2418 } 2419 } 2420 }); 2421 2422 // SSL_shutdown is a rare case that tolerates a null SSL argument 2423 NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB); 2424 2425 // handshaking not yet performed 2426 wrapWithSSLSession(new SSLSessionWrappedTask() { 2427 @Override 2428 public void run(long sslSession) throws Exception { 2429 try { 2430 NativeCrypto.SSL_shutdown(sslSession, INVALID_FD, DUMMY_CB); 2431 fail(); 2432 } catch (SocketException expected) { 2433 } 2434 } 2435 }); 2436 2437 // positively tested elsewhere because handshake uses use 2438 // SSL_shutdown to ensure SSL_SESSIONs are reused. 2439 } 2440 2441 public void test_SSL_free() throws Exception { 2442 try { 2443 NativeCrypto.SSL_free(NULL); 2444 fail(); 2445 } catch (NullPointerException expected) { 2446 } 2447 2448 long c = NativeCrypto.SSL_CTX_new(); 2449 NativeCrypto.SSL_free(NativeCrypto.SSL_new(c)); 2450 NativeCrypto.SSL_CTX_free(c); 2451 2452 // additional positive testing elsewhere because handshake 2453 // uses use SSL_free to cleanup in afterHandshake. 2454 } 2455 2456 public void test_SSL_SESSION_session_id() throws Exception { 2457 try { 2458 NativeCrypto.SSL_SESSION_session_id(NULL); 2459 fail(); 2460 } catch (NullPointerException expected) { 2461 } 2462 2463 final ServerSocket listener = new ServerSocket(0); 2464 2465 Hooks cHooks = new Hooks() { 2466 @Override 2467 public void afterHandshake(long session, long s, long c, 2468 Socket sock, FileDescriptor fd, 2469 SSLHandshakeCallbacks callback) 2470 throws Exception { 2471 byte[] id = NativeCrypto.SSL_SESSION_session_id(session); 2472 assertNotNull(id); 2473 assertEquals(32, id.length); 2474 super.afterHandshake(session, s, c, sock, fd, callback); 2475 } 2476 }; 2477 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2478 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2479 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2480 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2481 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2482 } 2483 2484 public void test_SSL_SESSION_get_time() throws Exception { 2485 try { 2486 NativeCrypto.SSL_SESSION_get_time(NULL); 2487 fail(); 2488 } catch (NullPointerException expected) { 2489 } 2490 2491 final ServerSocket listener = new ServerSocket(0); 2492 2493 { 2494 Hooks cHooks = new Hooks() { 2495 @Override 2496 public void afterHandshake(long session, long s, long c, 2497 Socket sock, FileDescriptor fd, 2498 SSLHandshakeCallbacks callback) 2499 throws Exception { 2500 long time = NativeCrypto.SSL_SESSION_get_time(session); 2501 assertTrue(time != 0); 2502 assertTrue(time < System.currentTimeMillis()); 2503 super.afterHandshake(session, s, c, sock, fd, callback); 2504 } 2505 }; 2506 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2507 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, 2508 null); 2509 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, 2510 null); 2511 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2512 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2513 } 2514 } 2515 2516 public void test_SSL_SESSION_get_version() throws Exception { 2517 try { 2518 NativeCrypto.SSL_SESSION_get_version(NULL); 2519 fail(); 2520 } catch (NullPointerException expected) { 2521 } 2522 2523 final ServerSocket listener = new ServerSocket(0); 2524 2525 Hooks cHooks = new Hooks() { 2526 @Override 2527 public void afterHandshake(long session, long s, long c, 2528 Socket sock, FileDescriptor fd, 2529 SSLHandshakeCallbacks callback) 2530 throws Exception { 2531 String v = NativeCrypto.SSL_SESSION_get_version(session); 2532 assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v)); 2533 super.afterHandshake(session, s, c, sock, fd, callback); 2534 } 2535 }; 2536 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2537 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2538 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2539 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2540 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2541 } 2542 2543 public void test_SSL_SESSION_cipher() throws Exception { 2544 try { 2545 NativeCrypto.SSL_SESSION_cipher(NULL); 2546 fail(); 2547 } catch (NullPointerException expected) { 2548 } 2549 2550 final ServerSocket listener = new ServerSocket(0); 2551 2552 Hooks cHooks = new Hooks() { 2553 @Override 2554 public void afterHandshake(long session, long s, long c, 2555 Socket sock, FileDescriptor fd, 2556 SSLHandshakeCallbacks callback) 2557 throws Exception { 2558 String a = NativeCrypto.SSL_SESSION_cipher(session); 2559 assertTrue(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(a)); 2560 super.afterHandshake(session, s, c, sock, fd, callback); 2561 } 2562 }; 2563 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2564 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2565 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2566 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2567 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2568 } 2569 2570 public void test_SSL_SESSION_free() throws Exception { 2571 try { 2572 NativeCrypto.SSL_SESSION_free(NULL); 2573 fail(); 2574 } catch (NullPointerException expected) { 2575 } 2576 2577 // additional positive testing elsewhere because handshake 2578 // uses use SSL_SESSION_free to cleanup in afterHandshake. 2579 } 2580 2581 public void test_i2d_SSL_SESSION() throws Exception { 2582 try { 2583 NativeCrypto.i2d_SSL_SESSION(NULL); 2584 fail(); 2585 } catch (NullPointerException expected) { 2586 } 2587 2588 final ServerSocket listener = new ServerSocket(0); 2589 2590 Hooks cHooks = new Hooks() { 2591 @Override 2592 public void afterHandshake(long session, long s, long c, 2593 Socket sock, FileDescriptor fd, 2594 SSLHandshakeCallbacks callback) 2595 throws Exception { 2596 byte[] b = NativeCrypto.i2d_SSL_SESSION(session); 2597 assertNotNull(b); 2598 long session2 = NativeCrypto.d2i_SSL_SESSION(b); 2599 assertTrue(session2 != NULL); 2600 2601 // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840 2602 assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null); 2603 assertEquals(NativeCrypto.SSL_SESSION_cipher(session), 2604 NativeCrypto.SSL_SESSION_cipher(session2)); 2605 2606 NativeCrypto.SSL_SESSION_free(session2); 2607 super.afterHandshake(session, s, c, sock, fd, callback); 2608 } 2609 }; 2610 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 2611 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null); 2612 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null); 2613 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2614 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 2615 } 2616 2617 public void test_d2i_SSL_SESSION() throws Exception { 2618 try { 2619 NativeCrypto.d2i_SSL_SESSION(null); 2620 fail(); 2621 } catch (NullPointerException expected) { 2622 } 2623 2624 try { 2625 NativeCrypto.d2i_SSL_SESSION(new byte[0]); 2626 fail("Should throw IOException with invalid SSL_SESSION data"); 2627 } catch (IOException expected) { 2628 } 2629 2630 try { 2631 NativeCrypto.d2i_SSL_SESSION(new byte[1]); 2632 fail("Should throw IOException with invalid SSL_SESSION data"); 2633 } catch (IOException expected) { 2634 } 2635 2636 // positive testing by test_i2d_SSL_SESSION 2637 } 2638 2639 public void test_X509_NAME_hashes() { 2640 // ensure these hash functions are stable over time since the 2641 // /system/etc/security/cacerts CA filenames have to be 2642 // consistent with the output. 2643 X500Principal name = new X500Principal("CN=localhost"); 2644 assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1 2645 assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5 2646 } 2647 2648 public void test_RAND_bytes_Success() throws Exception { 2649 byte[] output = new byte[128]; 2650 NativeCrypto.RAND_bytes(output); 2651 2652 boolean isZero = true; 2653 for (int i = 0; i < output.length; i++) { 2654 isZero &= (output[i] == 0); 2655 } 2656 2657 assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) " 2658 + "and probably indicates an error.", isZero); 2659 } 2660 2661 public void test_RAND_bytes_Null_Failure() throws Exception { 2662 byte[] output = null; 2663 try { 2664 NativeCrypto.RAND_bytes(output); 2665 fail("Should be an error on null buffer input"); 2666 } catch (RuntimeException expected) { 2667 } 2668 } 2669 2670 public void test_EVP_get_digestbyname() throws Exception { 2671 assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL); 2672 2673 try { 2674 NativeCrypto.EVP_get_digestbyname(null); 2675 fail(); 2676 } catch (NullPointerException expected) { 2677 } 2678 2679 try { 2680 NativeCrypto.EVP_get_digestbyname(""); 2681 NativeCrypto.EVP_get_digestbyname("foobar"); 2682 fail(); 2683 } catch (RuntimeException expected) { 2684 } 2685 } 2686 2687 public void test_EVP_DigestSignInit() throws Exception { 2688 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 2689 kpg.initialize(512); 2690 2691 KeyPair kp = kpg.generateKeyPair(); 2692 RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) kp.getPrivate(); 2693 2694 NativeRef.EVP_PKEY pkey; 2695 pkey = new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA( 2696 privKey.getModulus().toByteArray(), 2697 privKey.getPublicExponent().toByteArray(), 2698 privKey.getPrivateExponent().toByteArray(), 2699 privKey.getPrimeP().toByteArray(), 2700 privKey.getPrimeQ().toByteArray(), 2701 privKey.getPrimeExponentP().toByteArray(), 2702 privKey.getPrimeExponentQ().toByteArray(), 2703 privKey.getCrtCoefficient().toByteArray())); 2704 assertNotNull(pkey); 2705 2706 final NativeRef.EVP_MD_CTX ctx = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create()); 2707 long evpMd = NativeCrypto.EVP_get_digestbyname("sha256"); 2708 NativeCrypto.EVP_DigestSignInit(ctx, evpMd, pkey); 2709 2710 try { 2711 NativeCrypto.EVP_DigestSignInit(ctx, 0, pkey); 2712 fail(); 2713 } catch (RuntimeException expected) { 2714 } 2715 2716 try { 2717 NativeCrypto.EVP_DigestSignInit(ctx, evpMd, null); 2718 fail(); 2719 } catch (RuntimeException expected) { 2720 } 2721 } 2722 2723 public void test_get_RSA_private_params() throws Exception { 2724 try { 2725 NativeCrypto.get_RSA_private_params(null); 2726 } catch (NullPointerException expected) { 2727 } 2728 2729 try { 2730 NativeCrypto.get_RSA_private_params(null); 2731 } catch (NullPointerException expected) { 2732 } 2733 2734 // Test getting params for the wrong kind of key. 2735 final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1"); 2736 assertFalse(groupCtx == NULL); 2737 NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupCtx); 2738 NativeRef.EVP_PKEY ctx = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group)); 2739 try { 2740 NativeCrypto.get_RSA_private_params(ctx); 2741 fail(); 2742 } catch (RuntimeException expected) { 2743 } 2744 } 2745 2746 public void test_get_RSA_public_params() throws Exception { 2747 try { 2748 NativeCrypto.get_RSA_public_params(null); 2749 } catch (NullPointerException expected) { 2750 } 2751 2752 try { 2753 NativeCrypto.get_RSA_public_params(null); 2754 } catch (NullPointerException expected) { 2755 } 2756 2757 // Test getting params for the wrong kind of key. 2758 final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1"); 2759 assertFalse(groupCtx == NULL); 2760 NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupCtx); 2761 NativeRef.EVP_PKEY ctx = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group)); 2762 try { 2763 NativeCrypto.get_RSA_public_params(ctx); 2764 fail(); 2765 } catch (RuntimeException expected) { 2766 } 2767 } 2768 2769 public void test_RSA_size_null_key_Failure() throws Exception { 2770 try { 2771 NativeCrypto.RSA_size(null); 2772 fail("Expecting null pointer exception for RSA_size with null key"); 2773 } catch (NullPointerException expected) {} 2774 } 2775 2776 public void test_RSA_private_encrypt_null_key_Failure() throws Exception { 2777 try { 2778 NativeCrypto.RSA_private_encrypt(0, new byte[0], new byte[0], 2779 null, 0); 2780 fail("Expecting null pointer exception for RSA_private encrypt with null key"); 2781 } catch (NullPointerException expected) {} 2782 } 2783 2784 public void test_RSA_private_decrypt_null_key_Failure() throws Exception { 2785 try { 2786 NativeCrypto.RSA_private_decrypt(0, new byte[0], new byte[0], 2787 null, 0); 2788 fail("Expecting null pointer exception for RSA_private_decrypt with null key"); 2789 } catch (NullPointerException expected) {} 2790 } 2791 2792 public void test_RSA_public_encrypt_null_key_Failure() throws Exception { 2793 try { 2794 NativeCrypto.RSA_public_encrypt(0, new byte[0], new byte[0], null, 2795 0); 2796 fail("Expecting null pointer exception for RSA_public encrypt with null key"); 2797 } catch (NullPointerException expected) {} 2798 } 2799 2800 public void test_RSA_public_decrypt_null_key_Failure() throws Exception { 2801 try { 2802 NativeCrypto.RSA_public_decrypt(0, new byte[0], new byte[0], null, 2803 0); 2804 fail("Expecting null pointer exception for RSA_public decrypt with null key"); 2805 } catch (NullPointerException expected) {} 2806 } 2807 2808 /* 2809 * Test vector generation: 2810 * openssl rand -hex 16 2811 */ 2812 private static final byte[] AES_128_KEY = new byte[] { 2813 (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2, 2814 (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29, 2815 (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f, 2816 }; 2817 2818 public void testEC_GROUP() throws Exception { 2819 /* Test using NIST's P-256 curve */ 2820 check_EC_GROUP(NativeCrypto.EC_CURVE_GFP, "prime256v1", 2821 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 2822 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 2823 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 2824 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 2825 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 2826 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 2827 1L); 2828 } 2829 2830 private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr, 2831 String xStr, String yStr, String nStr, long hLong) throws Exception { 2832 long groupRef = NativeCrypto.EC_GROUP_new_by_curve_name(name); 2833 assertFalse(groupRef == NULL); 2834 NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupRef); 2835 assertEquals(NativeCrypto.OBJ_txt2nid_longName(name), 2836 NativeCrypto.EC_GROUP_get_curve_name(group)); 2837 assertEquals(type, NativeCrypto.get_EC_GROUP_type(group)); 2838 2839 // prime 2840 BigInteger p = new BigInteger(pStr, 16); 2841 // first coefficient 2842 BigInteger a = new BigInteger(aStr, 16); 2843 // second coefficient 2844 BigInteger b = new BigInteger(bStr, 16); 2845 // x affine coordinate of generator 2846 BigInteger x = new BigInteger(xStr, 16); 2847 // y affine coordinate of generator 2848 BigInteger y = new BigInteger(yStr, 16); 2849 // order of the generator 2850 BigInteger n = new BigInteger(nStr, 16); 2851 // cofactor of generator 2852 BigInteger h = BigInteger.valueOf(hLong); 2853 2854 byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group); 2855 assertEquals(3, pab.length); 2856 2857 BigInteger p2 = new BigInteger(pab[0]); 2858 assertEquals(p, p2); 2859 2860 BigInteger a2 = new BigInteger(pab[1]); 2861 assertEquals(a, a2); 2862 2863 BigInteger b2 = new BigInteger(pab[2]); 2864 assertEquals(b, b2); 2865 2866 NativeRef.EC_POINT point = new NativeRef.EC_POINT( 2867 NativeCrypto.EC_GROUP_get_generator(group)); 2868 2869 byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group, point); 2870 assertEquals(2, xy.length); 2871 2872 BigInteger x2 = new BigInteger(xy[0]); 2873 assertEquals(x, x2); 2874 2875 BigInteger y2 = new BigInteger(xy[1]); 2876 assertEquals(y, y2); 2877 2878 BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group)); 2879 assertEquals(n, n2); 2880 2881 BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group)); 2882 assertEquals(h, h2); 2883 2884 NativeRef.EVP_PKEY key1 = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group)); 2885 NativeRef.EC_GROUP groupTmp = new NativeRef.EC_GROUP(NativeCrypto.EC_KEY_get1_group(key1)); 2886 assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group), 2887 NativeCrypto.EC_GROUP_get_curve_name(groupTmp)); 2888 } 2889 2890 public void test_EC_KEY_get_private_key_null_key_Failure() throws Exception { 2891 try { 2892 NativeCrypto.EC_KEY_get_private_key(null); 2893 fail(); 2894 } catch (NullPointerException expected) {} 2895 } 2896 2897 public void test_EC_KEY_get_public_key_null_key_Failure() throws Exception { 2898 try { 2899 NativeCrypto.EC_KEY_get_public_key(null); 2900 fail(); 2901 } catch (NullPointerException expected) {} 2902 } 2903 2904 public void test_ECKeyPairGenerator_CurvesAreValid() throws Exception { 2905 OpenSSLECKeyPairGenerator.assertCurvesAreValid(); 2906 } 2907 2908 public void test_ECDH_compute_key_null_key_Failure() throws Exception { 2909 final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1"); 2910 assertFalse(groupCtx == NULL); 2911 NativeRef.EC_GROUP groupRef = new NativeRef.EC_GROUP(groupCtx); 2912 NativeRef.EVP_PKEY pkey1Ref = new NativeRef.EVP_PKEY( 2913 NativeCrypto.EC_KEY_generate_key(groupRef)); 2914 NativeRef.EVP_PKEY pkey2Ref = new NativeRef.EVP_PKEY( 2915 NativeCrypto.EC_KEY_generate_key(groupRef)); 2916 2917 byte[] out = new byte[128]; 2918 int outOffset = 0; 2919 // Assert that the method under test works fine with the two 2920 // non-null keys 2921 NativeCrypto.ECDH_compute_key(out, outOffset, pkey1Ref, pkey2Ref); 2922 2923 // Assert that it fails when only the first key is null 2924 try { 2925 NativeCrypto.ECDH_compute_key(out, outOffset, null, pkey2Ref); 2926 fail(); 2927 } catch (NullPointerException expected) { 2928 } 2929 2930 // Assert that it fails when only the second key is null 2931 try { 2932 NativeCrypto.ECDH_compute_key(out, outOffset, pkey1Ref, null); 2933 fail(); 2934 } catch (NullPointerException expected) { 2935 } 2936 } 2937 2938 public void test_EVP_CipherInit_ex_Null_Failure() throws Exception { 2939 final NativeRef.EVP_CIPHER_CTX ctx = new NativeRef.EVP_CIPHER_CTX( 2940 NativeCrypto.EVP_CIPHER_CTX_new()); 2941 final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2942 2943 try { 2944 NativeCrypto.EVP_CipherInit_ex(null, evpCipher, null, null, true); 2945 fail("Null context should throw NullPointerException"); 2946 } catch (NullPointerException expected) { 2947 } 2948 2949 /* Initialize encrypting. */ 2950 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true); 2951 NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true); 2952 2953 /* Initialize decrypting. */ 2954 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false); 2955 NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false); 2956 } 2957 2958 public void test_EVP_CipherInit_ex_Success() throws Exception { 2959 final NativeRef.EVP_CIPHER_CTX ctx = new NativeRef.EVP_CIPHER_CTX( 2960 NativeCrypto.EVP_CIPHER_CTX_new()); 2961 final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2962 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true); 2963 } 2964 2965 public void test_EVP_CIPHER_iv_length() throws Exception { 2966 long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2967 assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb)); 2968 2969 long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc"); 2970 assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc)); 2971 } 2972 2973 public void test_OpenSSLKey_toJava() throws Exception { 2974 OpenSSLKey key1; 2975 2976 BigInteger e = BigInteger.valueOf(65537); 2977 key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray())); 2978 assertTrue(key1.getPublicKey() instanceof RSAPublicKey); 2979 2980 final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1"); 2981 assertFalse(groupCtx == NULL); 2982 NativeRef.EC_GROUP group1 = new NativeRef.EC_GROUP(groupCtx); 2983 key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1)); 2984 assertTrue(key1.getPublicKey() instanceof ECPublicKey); 2985 } 2986 2987 public void test_create_BIO_InputStream() throws Exception { 2988 byte[] actual = "Test".getBytes(); 2989 ByteArrayInputStream is = new ByteArrayInputStream(actual); 2990 2991 @SuppressWarnings("resource") 2992 OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true); 2993 try { 2994 byte[] buffer = new byte[1024]; 2995 int numRead = NativeCrypto.BIO_read(bis.getBioContext(), buffer); 2996 assertEquals(actual.length, numRead); 2997 assertEquals(Arrays.toString(actual), 2998 Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead))); 2999 } finally { 3000 bis.release(); 3001 } 3002 } 3003 3004 public void test_create_BIO_OutputStream() throws Exception { 3005 byte[] actual = "Test".getBytes(); 3006 ByteArrayOutputStream os = new ByteArrayOutputStream(); 3007 3008 long ctx = NativeCrypto.create_BIO_OutputStream(os); 3009 try { 3010 NativeCrypto.BIO_write(ctx, actual, 0, actual.length); 3011 assertEquals(actual.length, os.size()); 3012 assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray())); 3013 } finally { 3014 NativeCrypto.BIO_free_all(ctx); 3015 } 3016 } 3017 3018 public void test_get_ocsp_single_extension() throws Exception { 3019 // This is only implemented for BoringSSL 3020 if (!NativeCrypto.isBoringSSL) { 3021 return; 3022 } 3023 3024 final String OCSP_SCT_LIST_OID = "1.3.6.1.4.1.11129.2.4.5"; 3025 3026 byte[] ocspResponse = readTestFile("ocsp-response.der"); 3027 byte[] expected = readTestFile("ocsp-response-sct-extension.der"); 3028 OpenSSLX509Certificate certificate = OpenSSLX509Certificate.fromX509PemInputStream( 3029 openTestFile("cert-ct-poisoned.pem")); 3030 OpenSSLX509Certificate issuer = OpenSSLX509Certificate.fromX509PemInputStream( 3031 openTestFile("ca-cert.pem")); 3032 3033 byte[] extension = NativeCrypto.get_ocsp_single_extension(ocspResponse, OCSP_SCT_LIST_OID, 3034 certificate.getContext(), 3035 issuer.getContext()); 3036 3037 assertEqualByteArrays(expected, extension); 3038 } 3039 3040 private static void assertContains(String actualValue, String expectedSubstring) { 3041 if (actualValue == null) { 3042 return; 3043 } 3044 if (actualValue.contains(expectedSubstring)) { 3045 return; 3046 } 3047 fail("\"" + actualValue + "\" does not contain \"" + expectedSubstring + "\""); 3048 } 3049 } 3050