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