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