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.apache.harmony.xnet.provider.jsse; 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.math.BigInteger; 25 import java.net.ServerSocket; 26 import java.net.Socket; 27 import java.net.SocketTimeoutException; 28 import java.security.KeyPair; 29 import java.security.KeyPairGenerator; 30 import java.security.KeyStore; 31 import java.security.KeyStore.PrivateKeyEntry; 32 import java.security.PrivateKey; 33 import java.security.cert.CertificateException; 34 import java.security.cert.X509Certificate; 35 import java.security.interfaces.DSAPublicKey; 36 import java.security.interfaces.ECPublicKey; 37 import java.security.interfaces.RSAPrivateCrtKey; 38 import java.security.interfaces.RSAPublicKey; 39 import java.security.spec.ECPrivateKeySpec; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.List; 43 import java.util.concurrent.Callable; 44 import java.util.concurrent.ExecutionException; 45 import java.util.concurrent.ExecutorService; 46 import java.util.concurrent.Executors; 47 import java.util.concurrent.Future; 48 import java.util.concurrent.TimeUnit; 49 import javax.net.ssl.SSLException; 50 import javax.net.ssl.SSLProtocolException; 51 import javax.security.auth.x500.X500Principal; 52 import junit.framework.TestCase; 53 import libcore.io.IoUtils; 54 import libcore.java.security.StandardNames; 55 import libcore.java.security.TestKeyStore; 56 import org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSLHandshakeCallbacks; 57 import static org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH; 58 59 public class NativeCryptoTest extends TestCase { 60 /** Corresponds to the native test library "libjavacoretests.so" */ 61 public static final String TEST_ENGINE_ID = "javacoretests"; 62 63 private static final long NULL = 0; 64 private static final FileDescriptor INVALID_FD = new FileDescriptor(); 65 private static final SSLHandshakeCallbacks DUMMY_CB 66 = new TestSSLHandshakeCallbacks(null, 0, null); 67 68 private static final long TIMEOUT_SECONDS = 5; 69 70 private static byte[] SERVER_PRIVATE_KEY; 71 private static byte[][] SERVER_CERTIFICATES; 72 private static byte[] CLIENT_PRIVATE_KEY; 73 private static byte[][] CLIENT_CERTIFICATES; 74 private static byte[][] CA_PRINCIPALS; 75 private static PrivateKey CHANNEL_ID_PRIVATE_KEY; 76 private static byte[] CHANNEL_ID; 77 78 @Override 79 protected void tearDown() throws Exception { 80 assertEquals(0, NativeCrypto.ERR_peek_last_error()); 81 } 82 83 private static byte[] getServerPrivateKey() { 84 initCerts(); 85 return SERVER_PRIVATE_KEY; 86 } 87 88 private static byte[][] getServerCertificates() { 89 initCerts(); 90 return SERVER_CERTIFICATES; 91 } 92 93 private static byte[] getClientPrivateKey() { 94 initCerts(); 95 return CLIENT_PRIVATE_KEY; 96 } 97 98 private static byte[][] getClientCertificates() { 99 initCerts(); 100 return CLIENT_CERTIFICATES; 101 } 102 103 private static byte[][] getCaPrincipals() { 104 initCerts(); 105 return CA_PRINCIPALS; 106 } 107 108 /** 109 * Lazily create shared test certificates. 110 */ 111 private static synchronized void initCerts() { 112 if (SERVER_PRIVATE_KEY != null) { 113 return; 114 } 115 116 try { 117 PrivateKeyEntry serverPrivateKeyEntry 118 = TestKeyStore.getServer().getPrivateKey("RSA", "RSA"); 119 SERVER_PRIVATE_KEY = serverPrivateKeyEntry.getPrivateKey().getEncoded(); 120 SERVER_CERTIFICATES = NativeCrypto.encodeCertificates( 121 serverPrivateKeyEntry.getCertificateChain()); 122 123 PrivateKeyEntry clientPrivateKeyEntry 124 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA"); 125 CLIENT_PRIVATE_KEY = clientPrivateKeyEntry.getPrivateKey().getEncoded(); 126 CLIENT_CERTIFICATES = NativeCrypto.encodeCertificates( 127 clientPrivateKeyEntry.getCertificateChain()); 128 129 KeyStore ks = TestKeyStore.getClient().keyStore; 130 String caCertAlias = ks.aliases().nextElement(); 131 X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias); 132 X500Principal principal = certificate.getIssuerX500Principal(); 133 CA_PRINCIPALS = new byte[][] { principal.getEncoded() }; 134 initChannelIdKey(); 135 } catch (Exception e) { 136 throw new RuntimeException(e); 137 } 138 } 139 140 private static synchronized void initChannelIdKey() throws Exception { 141 if (CHANNEL_ID_PRIVATE_KEY != null) { 142 return; 143 } 144 145 // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1 146 OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1"); 147 BigInteger s = new BigInteger( 148 "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16); 149 CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey( 150 new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())); 151 152 // Channel ID is the concatenation of the X and Y coordinates of the public key. 153 CHANNEL_ID = new BigInteger( 154 "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" + 155 "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77", 156 16).toByteArray(); 157 } 158 159 public static void assertEqualSessions(long expected, long actual) { 160 assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected), 161 NativeCrypto.SSL_SESSION_session_id(actual)); 162 } 163 public static void assertEqualByteArrays(byte[] expected, byte[] actual) { 164 assertEquals(Arrays.toString(expected), Arrays.toString(actual)); 165 } 166 167 public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) { 168 assertEqualByteArrays(expected, actual); 169 } 170 public static void assertEqualCertificateChains(byte[][] expected, byte[][] actual) { 171 assertEqualByteArrays(expected, actual); 172 } 173 public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) { 174 assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual)); 175 } 176 177 public void test_EVP_PKEY_cmp() throws Exception { 178 try { 179 NativeCrypto.EVP_PKEY_cmp(NULL, NULL); 180 fail("Should throw NullPointerException when arguments are NULL"); 181 } catch (NullPointerException expected) { 182 } 183 184 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 185 kpg.initialize(512); 186 187 KeyPair kp1 = kpg.generateKeyPair(); 188 RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate(); 189 190 KeyPair kp2 = kpg.generateKeyPair(); 191 RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate(); 192 193 long pkey1 = 0, pkey1_copy = 0, pkey2 = 0; 194 try { 195 pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(), 196 privKey1.getPublicExponent().toByteArray(), 197 privKey1.getPrivateExponent().toByteArray(), 198 privKey1.getPrimeP().toByteArray(), 199 privKey1.getPrimeQ().toByteArray(), 200 privKey1.getPrimeExponentP().toByteArray(), 201 privKey1.getPrimeExponentQ().toByteArray(), 202 privKey1.getCrtCoefficient().toByteArray()); 203 assertNotSame(NULL, pkey1); 204 205 pkey1_copy = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(), 206 privKey1.getPublicExponent().toByteArray(), 207 privKey1.getPrivateExponent().toByteArray(), 208 privKey1.getPrimeP().toByteArray(), 209 privKey1.getPrimeQ().toByteArray(), 210 privKey1.getPrimeExponentP().toByteArray(), 211 privKey1.getPrimeExponentQ().toByteArray(), 212 privKey1.getCrtCoefficient().toByteArray()); 213 assertNotSame(NULL, pkey1_copy); 214 215 pkey2 = NativeCrypto.EVP_PKEY_new_RSA(privKey2.getModulus().toByteArray(), 216 privKey2.getPublicExponent().toByteArray(), 217 privKey2.getPrivateExponent().toByteArray(), 218 privKey2.getPrimeP().toByteArray(), 219 privKey2.getPrimeQ().toByteArray(), 220 privKey2.getPrimeExponentP().toByteArray(), 221 privKey2.getPrimeExponentQ().toByteArray(), 222 privKey2.getCrtCoefficient().toByteArray()); 223 assertNotSame(NULL, pkey2); 224 225 try { 226 NativeCrypto.EVP_PKEY_cmp(pkey1, NULL); 227 fail("Should throw NullPointerException when arguments are NULL"); 228 } catch (NullPointerException expected) { 229 } 230 231 try { 232 NativeCrypto.EVP_PKEY_cmp(NULL, pkey1); 233 fail("Should throw NullPointerException when arguments are NULL"); 234 } catch (NullPointerException expected) { 235 } 236 237 assertEquals("Same keys should be the equal", 1, 238 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1)); 239 240 assertEquals("Same keys should be the equal", 1, 241 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy)); 242 243 assertEquals("Different keys should not be equal", 0, 244 NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2)); 245 } finally { 246 if (pkey1 != 0) { 247 NativeCrypto.EVP_PKEY_free(pkey1); 248 } 249 if (pkey1_copy != 0) { 250 NativeCrypto.EVP_PKEY_free(pkey1_copy); 251 } 252 if (pkey2 != 0) { 253 NativeCrypto.EVP_PKEY_free(pkey2); 254 } 255 } 256 } 257 258 public void test_SSL_CTX_new() throws Exception { 259 long c = NativeCrypto.SSL_CTX_new(); 260 assertTrue(c != NULL); 261 long c2 = NativeCrypto.SSL_CTX_new(); 262 assertTrue(c != c2); 263 NativeCrypto.SSL_CTX_free(c); 264 NativeCrypto.SSL_CTX_free(c2); 265 } 266 267 public void test_SSL_CTX_free() throws Exception { 268 try { 269 NativeCrypto.SSL_CTX_free(NULL); 270 fail(); 271 } catch (NullPointerException expected) { 272 } 273 274 NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new()); 275 } 276 277 public void test_SSL_CTX_set_session_id_context() throws Exception { 278 byte[] empty = new byte[0]; 279 try { 280 NativeCrypto.SSL_CTX_set_session_id_context(NULL, empty); 281 fail(); 282 } catch (NullPointerException expected) { 283 } 284 long c = NativeCrypto.SSL_CTX_new(); 285 try { 286 NativeCrypto.SSL_CTX_set_session_id_context(c, null); 287 fail(); 288 } catch (NullPointerException expected) { 289 } 290 NativeCrypto.SSL_CTX_set_session_id_context(c, empty); 291 NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[32]); 292 try { 293 NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[33]); 294 } catch (IllegalArgumentException expected) { 295 } 296 NativeCrypto.SSL_CTX_free(c); 297 } 298 299 public void test_SSL_new() throws Exception { 300 long c = NativeCrypto.SSL_CTX_new(); 301 long s = NativeCrypto.SSL_new(c); 302 303 assertTrue(s != NULL); 304 assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2 305 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0); 306 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1) == 0); 307 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0); 308 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0); 309 310 long s2 = NativeCrypto.SSL_new(c); 311 assertTrue(s != s2); 312 NativeCrypto.SSL_free(s2); 313 314 NativeCrypto.SSL_free(s); 315 NativeCrypto.SSL_CTX_free(c); 316 } 317 318 public void test_SSL_use_certificate() throws Exception { 319 try { 320 NativeCrypto.SSL_use_certificate(NULL, null); 321 fail(); 322 } catch (NullPointerException expected) { 323 } 324 325 long c = NativeCrypto.SSL_CTX_new(); 326 long s = NativeCrypto.SSL_new(c); 327 328 try { 329 NativeCrypto.SSL_use_certificate(s, null); 330 fail(); 331 } catch (NullPointerException expected) { 332 } 333 334 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 335 336 NativeCrypto.SSL_free(s); 337 NativeCrypto.SSL_CTX_free(c); 338 } 339 340 public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception { 341 try { 342 NativeCrypto.SSL_set1_tls_channel_id(NULL, null); 343 fail(); 344 } catch (NullPointerException expected) { 345 } 346 347 long c = NativeCrypto.SSL_CTX_new(); 348 long s = NativeCrypto.SSL_new(c); 349 350 try { 351 NativeCrypto.SSL_set1_tls_channel_id(s, null); 352 fail(); 353 } catch (NullPointerException expected) { 354 } 355 356 // Use the key via the wrapper that decides whether to use PKCS#8 or native OpenSSL. 357 NativeCrypto.SSL_set1_tls_channel_id(s, CHANNEL_ID_PRIVATE_KEY); 358 359 // Use the key via its PKCS#8 representation. 360 assertEquals("PKCS#8", CHANNEL_ID_PRIVATE_KEY.getFormat()); 361 byte[] pkcs8EncodedKeyBytes = CHANNEL_ID_PRIVATE_KEY.getEncoded(); 362 assertNotNull(pkcs8EncodedKeyBytes); 363 NativeCrypto.SSL_use_PKCS8_PrivateKey_for_tls_channel_id(s, pkcs8EncodedKeyBytes); 364 365 // Use the key natively. This works because the initChannelIdKey method ensures that the 366 // key is backed by OpenSSL. 367 NativeCrypto.SSL_use_OpenSSL_PrivateKey_for_tls_channel_id( 368 s, 369 ((OpenSSLECPrivateKey) CHANNEL_ID_PRIVATE_KEY).getOpenSSLKey().getPkeyContext()); 370 371 NativeCrypto.SSL_free(s); 372 NativeCrypto.SSL_CTX_free(c); 373 } 374 375 public void test_SSL_use_PrivateKey() throws Exception { 376 try { 377 NativeCrypto.SSL_use_PrivateKey(NULL, null); 378 fail(); 379 } catch (NullPointerException expected) { 380 } 381 382 long c = NativeCrypto.SSL_CTX_new(); 383 long s = NativeCrypto.SSL_new(c); 384 385 try { 386 NativeCrypto.SSL_use_PrivateKey(s, null); 387 fail(); 388 } catch (NullPointerException expected) { 389 } 390 391 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey()); 392 393 NativeCrypto.SSL_free(s); 394 NativeCrypto.SSL_CTX_free(c); 395 } 396 397 public void test_SSL_check_private_key_null() throws Exception { 398 try { 399 NativeCrypto.SSL_check_private_key(NULL); 400 fail(); 401 } catch (NullPointerException expected) { 402 } 403 } 404 405 public void test_SSL_check_private_key_no_key_no_cert() throws Exception { 406 long c = NativeCrypto.SSL_CTX_new(); 407 long s = NativeCrypto.SSL_new(c); 408 409 // neither private or certificate set 410 try { 411 NativeCrypto.SSL_check_private_key(s); 412 fail(); 413 } catch (SSLException expected) { 414 } 415 416 NativeCrypto.SSL_free(s); 417 NativeCrypto.SSL_CTX_free(c); 418 } 419 420 public void test_SSL_check_private_key_cert_then_key() throws Exception { 421 long c = NativeCrypto.SSL_CTX_new(); 422 long s = NativeCrypto.SSL_new(c); 423 424 // first certificate, then private 425 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 426 427 try { 428 NativeCrypto.SSL_check_private_key(s); 429 fail(); 430 } catch (SSLException expected) { 431 } 432 433 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey()); 434 NativeCrypto.SSL_check_private_key(s); 435 436 NativeCrypto.SSL_free(s); 437 NativeCrypto.SSL_CTX_free(c); 438 } 439 public void test_SSL_check_private_key_key_then_cert() throws Exception { 440 long c = NativeCrypto.SSL_CTX_new(); 441 long s = NativeCrypto.SSL_new(c); 442 443 // first private, then certificate 444 NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey()); 445 446 try { 447 NativeCrypto.SSL_check_private_key(s); 448 fail(); 449 } catch (SSLException expected) { 450 } 451 452 NativeCrypto.SSL_use_certificate(s, getServerCertificates()); 453 NativeCrypto.SSL_check_private_key(s); 454 455 NativeCrypto.SSL_free(s); 456 NativeCrypto.SSL_CTX_free(c); 457 } 458 459 public void test_SSL_get_mode() throws Exception { 460 try { 461 NativeCrypto.SSL_get_mode(NULL); 462 fail(); 463 } catch (NullPointerException expected) { 464 } 465 466 long c = NativeCrypto.SSL_CTX_new(); 467 long s = NativeCrypto.SSL_new(c); 468 assertTrue(NativeCrypto.SSL_get_mode(s) != 0); 469 NativeCrypto.SSL_free(s); 470 NativeCrypto.SSL_CTX_free(c); 471 } 472 473 public void test_SSL_set_mode_and_clear_mode() throws Exception { 474 try { 475 NativeCrypto.SSL_set_mode(NULL, 0); 476 fail(); 477 } catch (NullPointerException expected) { 478 } 479 480 long c = NativeCrypto.SSL_CTX_new(); 481 long s = NativeCrypto.SSL_new(c); 482 // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default 483 assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 484 // set SSL_MODE_HANDSHAKE_CUTTHROUGH on 485 NativeCrypto.SSL_set_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 486 assertTrue((NativeCrypto.SSL_get_mode(s) 487 & SSL_MODE_HANDSHAKE_CUTTHROUGH) != 0); 488 // clear SSL_MODE_HANDSHAKE_CUTTHROUGH off 489 NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 490 assertTrue((NativeCrypto.SSL_get_mode(s) 491 & SSL_MODE_HANDSHAKE_CUTTHROUGH) == 0); 492 493 NativeCrypto.SSL_free(s); 494 NativeCrypto.SSL_CTX_free(c); 495 } 496 497 public void test_SSL_get_options() throws Exception { 498 try { 499 NativeCrypto.SSL_get_options(NULL); 500 fail(); 501 } catch (NullPointerException expected) { 502 } 503 504 long c = NativeCrypto.SSL_CTX_new(); 505 long s = NativeCrypto.SSL_new(c); 506 assertTrue(NativeCrypto.SSL_get_options(s) != 0); 507 NativeCrypto.SSL_free(s); 508 NativeCrypto.SSL_CTX_free(c); 509 } 510 511 public void test_SSL_set_options() throws Exception { 512 try { 513 NativeCrypto.SSL_set_options(NULL, 0); 514 fail(); 515 } catch (NullPointerException expected) { 516 } 517 518 long c = NativeCrypto.SSL_CTX_new(); 519 long s = NativeCrypto.SSL_new(c); 520 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0); 521 NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3); 522 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0); 523 NativeCrypto.SSL_free(s); 524 NativeCrypto.SSL_CTX_free(c); 525 } 526 527 public void test_SSL_clear_options() throws Exception { 528 try { 529 NativeCrypto.SSL_clear_options(NULL, 0); 530 fail(); 531 } catch (NullPointerException expected) { 532 } 533 534 long c = NativeCrypto.SSL_CTX_new(); 535 long s = NativeCrypto.SSL_new(c); 536 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0); 537 NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3); 538 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0); 539 NativeCrypto.SSL_clear_options(s, NativeCrypto.SSL_OP_NO_SSLv3); 540 assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0); 541 NativeCrypto.SSL_free(s); 542 NativeCrypto.SSL_CTX_free(c); 543 } 544 545 public void test_SSL_set_cipher_lists() throws Exception { 546 try { 547 NativeCrypto.SSL_set_cipher_lists(NULL, null); 548 fail(); 549 } catch (NullPointerException expected) { 550 } 551 552 long c = NativeCrypto.SSL_CTX_new(); 553 long s = NativeCrypto.SSL_new(c); 554 555 try { 556 NativeCrypto.SSL_set_cipher_lists(s, null); 557 fail(); 558 } catch (NullPointerException expected) { 559 } 560 561 NativeCrypto.SSL_set_cipher_lists(s, new String[] {}); 562 563 try { 564 NativeCrypto.SSL_set_cipher_lists(s, new String[] { null }); 565 fail(); 566 } catch (NullPointerException expected) { 567 } 568 569 // see OpenSSL ciphers man page 570 String[] illegals = new String[] { 571 // empty 572 "", 573 // never standardized 574 "EXP1024-DES-CBC-SHA", "EXP1024-RC4-SHA", "DHE-DSS-RC4-SHA", 575 // IDEA 576 "IDEA-CBC-SHA", "IDEA-CBC-MD5" 577 }; 578 579 for (String illegal : illegals) { 580 try { 581 NativeCrypto.SSL_set_cipher_lists(s, new String[] { illegal }); 582 fail(illegal); 583 } catch (IllegalArgumentException expected) { 584 } 585 } 586 587 List<String> ciphers 588 = new ArrayList<String>(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.keySet()); 589 NativeCrypto.SSL_set_cipher_lists(s, ciphers.toArray(new String[ciphers.size()])); 590 591 NativeCrypto.SSL_free(s); 592 NativeCrypto.SSL_CTX_free(c); 593 } 594 595 public void test_SSL_set_verify() throws Exception { 596 try { 597 NativeCrypto.SSL_set_verify(NULL, 0); 598 fail(); 599 } catch (NullPointerException expected) { 600 } 601 602 long c = NativeCrypto.SSL_CTX_new(); 603 long s = NativeCrypto.SSL_new(c); 604 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE); 605 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 606 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 607 NativeCrypto.SSL_set_verify(s, (NativeCrypto.SSL_VERIFY_PEER 608 | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT)); 609 NativeCrypto.SSL_free(s); 610 NativeCrypto.SSL_CTX_free(c); 611 } 612 613 private static final boolean DEBUG = false; 614 615 public static class Hooks { 616 private PrivateKey channelIdPrivateKey; 617 618 public long getContext() throws SSLException { 619 return NativeCrypto.SSL_CTX_new(); 620 } 621 public long beforeHandshake(long context) throws SSLException { 622 long s = NativeCrypto.SSL_new(context); 623 // without this SSL_set_cipher_lists call the tests were 624 // negotiating DHE-RSA-AES256-SHA by default which had 625 // very slow ephemeral RSA key generation 626 NativeCrypto.SSL_set_cipher_lists(s, new String[] { "RC4-MD5" }); 627 628 if (channelIdPrivateKey != null) { 629 NativeCrypto.SSL_set1_tls_channel_id(s, channelIdPrivateKey); 630 } 631 return s; 632 } 633 public void clientCertificateRequested(long s) {} 634 public void afterHandshake(long session, long ssl, long context, 635 Socket socket, FileDescriptor fd, 636 SSLHandshakeCallbacks callback) 637 throws Exception { 638 if (session != NULL) { 639 NativeCrypto.SSL_SESSION_free(session); 640 } 641 if (ssl != NULL) { 642 try { 643 NativeCrypto.SSL_shutdown(ssl, fd, callback); 644 } catch (IOException e) { 645 } 646 NativeCrypto.SSL_free(ssl); 647 } 648 if (context != NULL) { 649 NativeCrypto.SSL_CTX_free(context); 650 } 651 if (socket != null) { 652 socket.close(); 653 } 654 } 655 } 656 657 public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks { 658 private final Socket socket; 659 private final long sslNativePointer; 660 private final Hooks hooks; 661 662 public TestSSLHandshakeCallbacks(Socket socket, 663 long sslNativePointer, 664 Hooks hooks) { 665 this.socket = socket; 666 this.sslNativePointer = sslNativePointer; 667 this.hooks = hooks; 668 } 669 670 public byte[][] asn1DerEncodedCertificateChain; 671 public String authMethod; 672 public boolean verifyCertificateChainCalled; 673 674 public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain, 675 String authMethod) 676 throws CertificateException { 677 if (DEBUG) { 678 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 679 + " verifyCertificateChain" 680 + " asn1DerEncodedCertificateChain=" 681 + asn1DerEncodedCertificateChain 682 + " authMethod=" + authMethod); 683 } 684 this.asn1DerEncodedCertificateChain = asn1DerEncodedCertificateChain; 685 this.authMethod = authMethod; 686 this.verifyCertificateChainCalled = true; 687 } 688 689 public byte[] keyTypes; 690 public byte[][] asn1DerEncodedX500Principals; 691 public boolean clientCertificateRequestedCalled; 692 public void clientCertificateRequested(byte[] keyTypes, 693 byte[][] asn1DerEncodedX500Principals) { 694 if (DEBUG) { 695 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 696 + " clientCertificateRequested" 697 + " keyTypes=" + keyTypes 698 + " asn1DerEncodedX500Principals=" 699 + asn1DerEncodedX500Principals); 700 } 701 this.keyTypes = keyTypes; 702 this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals; 703 this.clientCertificateRequestedCalled = true; 704 if (hooks != null ) { 705 hooks.clientCertificateRequested(sslNativePointer); 706 } 707 } 708 709 public boolean handshakeCompletedCalled; 710 public void handshakeCompleted() { 711 if (DEBUG) { 712 System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) 713 + " handshakeCompleted"); 714 } 715 this.handshakeCompletedCalled = true; 716 } 717 718 public Socket getSocket() { 719 return socket; 720 } 721 } 722 723 public static class ServerHooks extends Hooks { 724 private final byte[] privateKey; 725 private final byte[][] certificates; 726 private boolean channelIdEnabled; 727 private byte[] channelIdAfterHandshake; 728 private Throwable channelIdAfterHandshakeException; 729 730 public ServerHooks(byte[] privateKey, byte[][] certificates) { 731 this.privateKey = privateKey; 732 this.certificates = certificates; 733 } 734 735 @Override 736 public long beforeHandshake(long c) throws SSLException { 737 long s = super.beforeHandshake(c); 738 if (privateKey != null) { 739 NativeCrypto.SSL_use_PrivateKey(s, privateKey); 740 } 741 if (certificates != null) { 742 NativeCrypto.SSL_use_certificate(s, certificates); 743 } 744 if (channelIdEnabled) { 745 NativeCrypto.SSL_enable_tls_channel_id(s); 746 } 747 return s; 748 } 749 750 @Override 751 public void afterHandshake(long session, long ssl, long context, 752 Socket socket, FileDescriptor fd, 753 SSLHandshakeCallbacks callback) 754 throws Exception { 755 if (channelIdEnabled) { 756 try { 757 channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl); 758 } catch (Exception e) { 759 channelIdAfterHandshakeException = e; 760 } 761 } 762 super.afterHandshake(session, ssl, context, socket, fd, callback); 763 } 764 765 public void clientCertificateRequested(long s) { 766 fail("Server asked for client certificates"); 767 } 768 } 769 770 public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener, 771 final int timeout, final boolean client, final Hooks hooks, final byte[] npnProtocols) { 772 ExecutorService executor = Executors.newSingleThreadExecutor(); 773 Future<TestSSLHandshakeCallbacks> future = executor.submit( 774 new Callable<TestSSLHandshakeCallbacks>() { 775 @Override public TestSSLHandshakeCallbacks call() throws Exception { 776 Socket socket = (client 777 ? new Socket(listener.getInetAddress(), 778 listener.getLocalPort()) 779 : listener.accept()); 780 if (timeout == -1) { 781 return new TestSSLHandshakeCallbacks(socket, 0, null); 782 } 783 FileDescriptor fd = socket.getFileDescriptor$(); 784 long c = hooks.getContext(); 785 long s = hooks.beforeHandshake(c); 786 TestSSLHandshakeCallbacks callback 787 = new TestSSLHandshakeCallbacks(socket, s, hooks); 788 if (DEBUG) { 789 System.out.println("ssl=0x" + Long.toString(s, 16) 790 + " handshake" 791 + " context=0x" + Long.toString(c, 16) 792 + " socket=" + socket 793 + " fd=" + fd 794 + " timeout=" + timeout 795 + " client=" + client); 796 } 797 long session = NULL; 798 try { 799 session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client, 800 npnProtocols); 801 if (DEBUG) { 802 System.out.println("ssl=0x" + Long.toString(s, 16) 803 + " handshake" 804 + " session=0x" + Long.toString(session, 16)); 805 } 806 } finally { 807 // Ensure afterHandshake is called to free resources 808 hooks.afterHandshake(session, s, c, socket, fd, callback); 809 } 810 return callback; 811 } 812 }); 813 executor.shutdown(); 814 return future; 815 } 816 817 public void test_SSL_do_handshake_NULL_SSL() throws Exception { 818 try { 819 NativeCrypto.SSL_do_handshake(NULL, null, null, 0, false, null); 820 fail(); 821 } catch (NullPointerException expected) { 822 } 823 } 824 825 public void test_SSL_do_handshake_null_args() throws Exception { 826 long c = NativeCrypto.SSL_CTX_new(); 827 long s = NativeCrypto.SSL_new(c); 828 829 try { 830 NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null); 831 fail(); 832 } catch (NullPointerException expected) { 833 } 834 835 try { 836 NativeCrypto.SSL_do_handshake(s, INVALID_FD, null, 0, true, null); 837 fail(); 838 } catch (NullPointerException expected) { 839 } 840 841 NativeCrypto.SSL_free(s); 842 NativeCrypto.SSL_CTX_free(c); 843 } 844 845 public void test_SSL_do_handshake_normal() throws Exception { 846 // normal client and server case 847 final ServerSocket listener = new ServerSocket(0); 848 Hooks cHooks = new Hooks(); 849 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 850 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 851 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 852 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 853 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 854 assertTrue(clientCallback.verifyCertificateChainCalled); 855 assertEqualCertificateChains(getServerCertificates(), 856 clientCallback.asn1DerEncodedCertificateChain); 857 assertEquals("RSA", clientCallback.authMethod); 858 assertFalse(serverCallback.verifyCertificateChainCalled); 859 assertFalse(clientCallback.clientCertificateRequestedCalled); 860 assertFalse(serverCallback.clientCertificateRequestedCalled); 861 assertTrue(clientCallback.handshakeCompletedCalled); 862 assertTrue(serverCallback.handshakeCompletedCalled); 863 } 864 865 public void test_SSL_do_handshake_optional_client_certificate() throws Exception { 866 // optional client certificate case 867 final ServerSocket listener = new ServerSocket(0); 868 869 Hooks cHooks = new Hooks() { 870 @Override 871 public void clientCertificateRequested(long s) { 872 super.clientCertificateRequested(s); 873 NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey()); 874 NativeCrypto.SSL_use_certificate(s, getClientCertificates()); 875 } 876 }; 877 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 878 @Override 879 public long beforeHandshake(long c) throws SSLException { 880 long s = super.beforeHandshake(c); 881 NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals()); 882 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 883 return s; 884 } 885 }; 886 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 887 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 888 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 889 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 890 assertTrue(clientCallback.verifyCertificateChainCalled); 891 assertEqualCertificateChains(getServerCertificates(), 892 clientCallback.asn1DerEncodedCertificateChain); 893 assertEquals("RSA", clientCallback.authMethod); 894 assertTrue(serverCallback.verifyCertificateChainCalled); 895 assertEqualCertificateChains(getClientCertificates(), 896 serverCallback.asn1DerEncodedCertificateChain); 897 assertEquals("RSA", serverCallback.authMethod); 898 899 assertTrue(clientCallback.clientCertificateRequestedCalled); 900 assertNotNull(clientCallback.keyTypes); 901 // this depends on the SSL_set_cipher_lists call in beforeHandshake 902 // the three returned are the non-ephemeral cases. 903 assertEquals(3, clientCallback.keyTypes.length); 904 assertEquals("RSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[0])); 905 assertEquals("DSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[1])); 906 assertEquals("EC", CipherSuite.getClientKeyType(clientCallback.keyTypes[2])); 907 assertEqualPrincipals(getCaPrincipals(), 908 clientCallback.asn1DerEncodedX500Principals); 909 assertFalse(serverCallback.clientCertificateRequestedCalled); 910 911 assertTrue(clientCallback.handshakeCompletedCalled); 912 assertTrue(serverCallback.handshakeCompletedCalled); 913 } 914 915 public void test_SSL_do_handshake_missing_required_certificate() throws Exception { 916 // required client certificate negative case 917 final ServerSocket listener = new ServerSocket(0); 918 try { 919 Hooks cHooks = new Hooks(); 920 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 921 @Override 922 public long beforeHandshake(long c) throws SSLException { 923 long s = super.beforeHandshake(c); 924 NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals()); 925 NativeCrypto.SSL_set_verify(s, 926 NativeCrypto.SSL_VERIFY_PEER 927 | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 928 return s; 929 } 930 }; 931 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 932 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 933 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 934 fail(); 935 } catch (ExecutionException expected) { 936 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 937 } 938 } 939 940 /** 941 * Usually if a RuntimeException is thrown by the 942 * clientCertificateRequestedCalled callback, the caller sees it 943 * during the call to NativeCrypto_SSL_do_handshake. However, IIS 944 * does not request client certs until after the initial 945 * handshake. It does an SSL renegotiation, which means we need to 946 * be able to deliver the callback's exception in cases like 947 * SSL_read, SSL_write, and SSL_shutdown. 948 */ 949 public void test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate() 950 throws Exception { 951 final ServerSocket listener = new ServerSocket(0); 952 953 Hooks cHooks = new Hooks() { 954 @Override 955 public long beforeHandshake(long context) throws SSLException { 956 long s = super.beforeHandshake(context); 957 NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH); 958 return s; 959 } 960 @Override 961 public void afterHandshake(long session, long s, long c, 962 Socket sock, FileDescriptor fd, 963 SSLHandshakeCallbacks callback) 964 throws Exception { 965 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 966 fail(); 967 super.afterHandshake(session, s, c, sock, fd, callback); 968 } 969 @Override 970 public void clientCertificateRequested(long s) { 971 super.clientCertificateRequested(s); 972 throw new RuntimeException("expected"); 973 } 974 }; 975 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 976 @Override 977 public void afterHandshake(long session, long s, long c, 978 Socket sock, FileDescriptor fd, 979 SSLHandshakeCallbacks callback) 980 throws Exception { 981 try { 982 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER); 983 NativeCrypto.SSL_set_options( 984 s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 985 NativeCrypto.SSL_renegotiate(s); 986 NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 987 (int) ((TIMEOUT_SECONDS * 1000) / 2)); 988 } catch (IOException expected) { 989 } finally { 990 super.afterHandshake(session, s, c, sock, fd, callback); 991 } 992 } 993 }; 994 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 995 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 996 try { 997 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 998 } catch (ExecutionException e) { 999 if (!"expected".equals(e.getCause().getMessage())) { 1000 throw e; 1001 } 1002 } 1003 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1004 } 1005 1006 public void test_SSL_do_handshake_client_timeout() throws Exception { 1007 // client timeout 1008 final ServerSocket listener = new ServerSocket(0); 1009 Socket serverSocket = null; 1010 try { 1011 Hooks cHooks = new Hooks(); 1012 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1013 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null); 1014 Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null); 1015 serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket(); 1016 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1017 fail(); 1018 } catch (ExecutionException expected) { 1019 if (SocketTimeoutException.class != expected.getCause().getClass()) { 1020 expected.printStackTrace(); 1021 } 1022 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 1023 } finally { 1024 // Manually close peer socket when testing timeout 1025 IoUtils.closeQuietly(serverSocket); 1026 } 1027 } 1028 1029 public void test_SSL_do_handshake_server_timeout() throws Exception { 1030 // server timeout 1031 final ServerSocket listener = new ServerSocket(0); 1032 Socket clientSocket = null; 1033 try { 1034 Hooks cHooks = new Hooks(); 1035 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1036 Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null); 1037 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null); 1038 clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket(); 1039 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1040 fail(); 1041 } catch (ExecutionException expected) { 1042 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 1043 } finally { 1044 // Manually close peer socket when testing timeout 1045 IoUtils.closeQuietly(clientSocket); 1046 } 1047 } 1048 1049 public void test_SSL_do_handshake_with_channel_id_normal() throws Exception { 1050 initChannelIdKey(); 1051 1052 // Normal handshake with TLS Channel ID. 1053 final ServerSocket listener = new ServerSocket(0); 1054 Hooks cHooks = new Hooks(); 1055 cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY; 1056 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1057 sHooks.channelIdEnabled = true; 1058 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1059 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, 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.asn1DerEncodedCertificateChain); 1065 assertEquals("RSA", clientCallback.authMethod); 1066 assertFalse(serverCallback.verifyCertificateChainCalled); 1067 assertFalse(clientCallback.clientCertificateRequestedCalled); 1068 assertFalse(serverCallback.clientCertificateRequestedCalled); 1069 assertTrue(clientCallback.handshakeCompletedCalled); 1070 assertTrue(serverCallback.handshakeCompletedCalled); 1071 assertNull(sHooks.channelIdAfterHandshakeException); 1072 assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake); 1073 } 1074 1075 public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception { 1076 initChannelIdKey(); 1077 1078 // Client tries to use TLS Channel ID but the server does not enable/offer the extension. 1079 final ServerSocket listener = new ServerSocket(0); 1080 Hooks cHooks = new Hooks(); 1081 cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY; 1082 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1083 sHooks.channelIdEnabled = false; 1084 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1085 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1086 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1087 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1088 assertTrue(clientCallback.verifyCertificateChainCalled); 1089 assertEqualCertificateChains(getServerCertificates(), 1090 clientCallback.asn1DerEncodedCertificateChain); 1091 assertEquals("RSA", clientCallback.authMethod); 1092 assertFalse(serverCallback.verifyCertificateChainCalled); 1093 assertFalse(clientCallback.clientCertificateRequestedCalled); 1094 assertFalse(serverCallback.clientCertificateRequestedCalled); 1095 assertTrue(clientCallback.handshakeCompletedCalled); 1096 assertTrue(serverCallback.handshakeCompletedCalled); 1097 assertNull(sHooks.channelIdAfterHandshakeException); 1098 assertNull(sHooks.channelIdAfterHandshake); 1099 } 1100 1101 public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception { 1102 initChannelIdKey(); 1103 1104 // Client does not use TLS Channel ID when the server has the extension enabled/offered. 1105 final ServerSocket listener = new ServerSocket(0); 1106 Hooks cHooks = new Hooks(); 1107 cHooks.channelIdPrivateKey = null; 1108 ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1109 sHooks.channelIdEnabled = true; 1110 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1111 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1112 TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1113 TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1114 assertTrue(clientCallback.verifyCertificateChainCalled); 1115 assertEqualCertificateChains(getServerCertificates(), 1116 clientCallback.asn1DerEncodedCertificateChain); 1117 assertEquals("RSA", clientCallback.authMethod); 1118 assertFalse(serverCallback.verifyCertificateChainCalled); 1119 assertFalse(clientCallback.clientCertificateRequestedCalled); 1120 assertFalse(serverCallback.clientCertificateRequestedCalled); 1121 assertTrue(clientCallback.handshakeCompletedCalled); 1122 assertTrue(serverCallback.handshakeCompletedCalled); 1123 assertNull(sHooks.channelIdAfterHandshakeException); 1124 assertNull(sHooks.channelIdAfterHandshake); 1125 } 1126 1127 public void test_SSL_set_session() throws Exception { 1128 try { 1129 NativeCrypto.SSL_set_session(NULL, NULL); 1130 fail(); 1131 } catch (NullPointerException expected) { 1132 } 1133 1134 { 1135 long c = NativeCrypto.SSL_CTX_new(); 1136 long s = NativeCrypto.SSL_new(c); 1137 NativeCrypto.SSL_set_session(s, NULL); 1138 NativeCrypto.SSL_free(s); 1139 NativeCrypto.SSL_CTX_free(c); 1140 } 1141 1142 { 1143 final long clientContext = NativeCrypto.SSL_CTX_new(); 1144 final long serverContext = NativeCrypto.SSL_CTX_new(); 1145 final ServerSocket listener = new ServerSocket(0); 1146 final long[] clientSession = new long[] { NULL }; 1147 final long[] serverSession = new long[] { NULL }; 1148 { 1149 Hooks cHooks = new Hooks() { 1150 @Override 1151 public long getContext() throws SSLException { 1152 return clientContext; 1153 } 1154 @Override 1155 public void afterHandshake(long session, long s, long c, 1156 Socket sock, FileDescriptor fd, 1157 SSLHandshakeCallbacks callback) 1158 throws Exception { 1159 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1160 clientSession[0] = session; 1161 } 1162 }; 1163 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1164 @Override 1165 public long getContext() throws SSLException { 1166 return serverContext; 1167 } 1168 @Override 1169 public void afterHandshake(long session, long s, long c, 1170 Socket sock, FileDescriptor fd, 1171 SSLHandshakeCallbacks callback) 1172 throws Exception { 1173 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1174 serverSession[0] = session; 1175 } 1176 }; 1177 Future<TestSSLHandshakeCallbacks> client 1178 = handshake(listener, 0, true, cHooks, null); 1179 Future<TestSSLHandshakeCallbacks> server 1180 = handshake(listener, 0, false, sHooks, null); 1181 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1182 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1183 } 1184 assertEqualSessions(clientSession[0], serverSession[0]); 1185 { 1186 Hooks cHooks = new Hooks() { 1187 @Override 1188 public long getContext() throws SSLException { 1189 return clientContext; 1190 } 1191 @Override 1192 public long beforeHandshake(long c) throws SSLException { 1193 long s = NativeCrypto.SSL_new(clientContext); 1194 NativeCrypto.SSL_set_session(s, clientSession[0]); 1195 return s; 1196 } 1197 @Override 1198 public void afterHandshake(long session, long s, long c, 1199 Socket sock, FileDescriptor fd, 1200 SSLHandshakeCallbacks callback) 1201 throws Exception { 1202 assertEqualSessions(clientSession[0], session); 1203 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1204 } 1205 }; 1206 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1207 @Override 1208 public long getContext() throws SSLException { 1209 return serverContext; 1210 } 1211 @Override 1212 public void afterHandshake(long session, long s, long c, 1213 Socket sock, FileDescriptor fd, 1214 SSLHandshakeCallbacks callback) 1215 throws Exception { 1216 assertEqualSessions(serverSession[0], session); 1217 super.afterHandshake(NULL, s, NULL, sock, fd, callback); 1218 } 1219 }; 1220 Future<TestSSLHandshakeCallbacks> client 1221 = handshake(listener, 0, true, cHooks, null); 1222 Future<TestSSLHandshakeCallbacks> server 1223 = handshake(listener, 0, false, sHooks, null); 1224 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1225 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1226 } 1227 NativeCrypto.SSL_SESSION_free(clientSession[0]); 1228 NativeCrypto.SSL_SESSION_free(serverSession[0]); 1229 NativeCrypto.SSL_CTX_free(serverContext); 1230 NativeCrypto.SSL_CTX_free(clientContext); 1231 } 1232 } 1233 1234 public void test_SSL_set_session_creation_enabled() throws Exception { 1235 try { 1236 NativeCrypto.SSL_set_session_creation_enabled(NULL, false); 1237 fail(); 1238 } catch (NullPointerException expected) { 1239 } 1240 1241 { 1242 long c = NativeCrypto.SSL_CTX_new(); 1243 long s = NativeCrypto.SSL_new(c); 1244 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1245 NativeCrypto.SSL_set_session_creation_enabled(s, true); 1246 NativeCrypto.SSL_free(s); 1247 NativeCrypto.SSL_CTX_free(c); 1248 } 1249 1250 final ServerSocket listener = new ServerSocket(0); 1251 1252 // negative test case for SSL_set_session_creation_enabled(false) on client 1253 try { 1254 Hooks cHooks = new Hooks() { 1255 @Override 1256 public long beforeHandshake(long c) throws SSLException { 1257 long s = super.beforeHandshake(c); 1258 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1259 return s; 1260 } 1261 }; 1262 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1263 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1264 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1265 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1266 fail(); 1267 } catch (ExecutionException expected) { 1268 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1269 } 1270 1271 // negative test case for SSL_set_session_creation_enabled(false) on server 1272 try { 1273 Hooks cHooks = new Hooks(); 1274 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1275 @Override 1276 public long beforeHandshake(long c) throws SSLException { 1277 long s = super.beforeHandshake(c); 1278 NativeCrypto.SSL_set_session_creation_enabled(s, false); 1279 return s; 1280 } 1281 }; 1282 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1283 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1284 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1285 fail(); 1286 } catch (ExecutionException expected) { 1287 assertEquals(SSLProtocolException.class, expected.getCause().getClass()); 1288 } 1289 } 1290 1291 public void test_SSL_set_tlsext_host_name() throws Exception { 1292 // NULL SSL 1293 try { 1294 NativeCrypto.SSL_set_tlsext_host_name(NULL, null); 1295 fail(); 1296 } catch (NullPointerException expected) { 1297 } 1298 1299 final String hostname = "www.android.com"; 1300 1301 { 1302 long c = NativeCrypto.SSL_CTX_new(); 1303 long s = NativeCrypto.SSL_new(c); 1304 1305 // null hostname 1306 try { 1307 NativeCrypto.SSL_set_tlsext_host_name(s, null); 1308 fail(); 1309 } catch (NullPointerException expected) { 1310 } 1311 1312 // too long hostname 1313 try { 1314 char[] longHostname = new char[256]; 1315 Arrays.fill(longHostname, 'w'); 1316 NativeCrypto.SSL_set_tlsext_host_name(s, new String(longHostname)); 1317 fail(); 1318 } catch (SSLException expected) { 1319 } 1320 1321 assertNull(NativeCrypto.SSL_get_servername(s)); 1322 NativeCrypto.SSL_set_tlsext_host_name(s, new String(hostname)); 1323 assertEquals(hostname, NativeCrypto.SSL_get_servername(s)); 1324 1325 NativeCrypto.SSL_free(s); 1326 NativeCrypto.SSL_CTX_free(c); 1327 } 1328 1329 final ServerSocket listener = new ServerSocket(0); 1330 1331 // normal 1332 Hooks cHooks = new Hooks() { 1333 @Override 1334 public long beforeHandshake(long c) throws SSLException { 1335 long s = super.beforeHandshake(c); 1336 NativeCrypto.SSL_set_tlsext_host_name(s, hostname); 1337 return s; 1338 } 1339 }; 1340 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1341 @Override 1342 public void afterHandshake(long session, long s, long c, 1343 Socket sock, FileDescriptor fd, 1344 SSLHandshakeCallbacks callback) 1345 throws Exception { 1346 assertEquals(hostname, NativeCrypto.SSL_get_servername(s)); 1347 super.afterHandshake(session, s, c, sock, fd, callback); 1348 } 1349 }; 1350 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1351 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1352 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1353 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1354 } 1355 1356 public void test_SSL_NpnNegotiateSuccess() throws Exception { 1357 final byte[] clientNpnProtocols = new byte[] { 1358 8, 'h', 't', 't', 'p', '/', '1', '.', '1', 1359 3, 'f', 'o', 'o', 1360 6, 's', 'p', 'd', 'y', '/', '2', 1361 }; 1362 final byte[] serverNpnProtocols = new byte[] { 1363 6, 's', 'p', 'd', 'y', '/', '2', 1364 3, 'f', 'o', 'o', 1365 3, 'b', 'a', 'r', 1366 }; 1367 1368 Hooks cHooks = new Hooks() { 1369 @Override public long beforeHandshake(long context) throws SSLException { 1370 NativeCrypto.SSL_CTX_enable_npn(context); 1371 return super.beforeHandshake(context); 1372 } 1373 @Override public void afterHandshake(long session, long ssl, long context, Socket socket, 1374 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1375 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl); 1376 assertEquals("spdy/2", new String(negotiated)); 1377 assertTrue("NPN should enable cutthrough on the client", 1378 0 != (NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH)); 1379 super.afterHandshake(session, ssl, context, socket, fd, callback); 1380 } 1381 }; 1382 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1383 @Override public long beforeHandshake(long context) throws SSLException { 1384 NativeCrypto.SSL_CTX_enable_npn(context); 1385 return super.beforeHandshake(context); 1386 } 1387 @Override public void afterHandshake(long session, long ssl, long c, Socket sock, 1388 FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { 1389 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl); 1390 assertEquals("spdy/2", new String(negotiated)); 1391 assertEquals("NPN should not enable cutthrough on the server", 1392 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH); 1393 super.afterHandshake(session, ssl, c, sock, fd, callback); 1394 } 1395 }; 1396 1397 ServerSocket listener = new ServerSocket(0); 1398 Future<TestSSLHandshakeCallbacks> client 1399 = handshake(listener, 0, true, cHooks, clientNpnProtocols); 1400 Future<TestSSLHandshakeCallbacks> server 1401 = handshake(listener, 0, false, sHooks, serverNpnProtocols); 1402 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1403 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1404 } 1405 1406 public void test_SSL_get_servername_null() throws Exception { 1407 // NULL SSL 1408 try { 1409 NativeCrypto.SSL_get_servername(NULL); 1410 fail(); 1411 } catch (NullPointerException expected) { 1412 } 1413 1414 long c = NativeCrypto.SSL_CTX_new(); 1415 long s = NativeCrypto.SSL_new(c); 1416 assertNull(NativeCrypto.SSL_get_servername(s)); 1417 NativeCrypto.SSL_free(s); 1418 NativeCrypto.SSL_CTX_free(c); 1419 1420 // additional positive testing by test_SSL_set_tlsext_host_name 1421 } 1422 1423 public void test_SSL_renegotiate() throws Exception { 1424 try { 1425 NativeCrypto.SSL_renegotiate(NULL); 1426 fail(); 1427 } catch (NullPointerException expected) { 1428 } 1429 1430 final ServerSocket listener = new ServerSocket(0); 1431 Hooks cHooks = new Hooks() { 1432 @Override 1433 public void afterHandshake(long session, long s, long c, 1434 Socket sock, FileDescriptor fd, 1435 SSLHandshakeCallbacks callback) 1436 throws Exception { 1437 byte[] buffer = new byte[1]; 1438 NativeCrypto.SSL_read(s, fd, callback, buffer, 0, 1, 0); 1439 assertEquals(42, buffer[0]); 1440 super.afterHandshake(session, s, c, sock, fd, callback); 1441 } 1442 }; 1443 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1444 @Override 1445 public void afterHandshake(long session, long s, long c, 1446 Socket sock, FileDescriptor fd, 1447 SSLHandshakeCallbacks callback) 1448 throws Exception { 1449 NativeCrypto.SSL_renegotiate(s); 1450 NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0); 1451 super.afterHandshake(session, s, c, sock, fd, callback); 1452 } 1453 }; 1454 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1455 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1456 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1457 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1458 } 1459 1460 public void test_SSL_get_certificate() throws Exception { 1461 try { 1462 NativeCrypto.SSL_get_certificate(NULL); 1463 fail(); 1464 } catch (NullPointerException expected) { 1465 } 1466 1467 final ServerSocket listener = new ServerSocket(0); 1468 Hooks cHooks = new Hooks() { 1469 @Override 1470 public void afterHandshake(long session, long s, long c, 1471 Socket sock, FileDescriptor fd, 1472 SSLHandshakeCallbacks callback) 1473 throws Exception { 1474 assertNull(NativeCrypto.SSL_get_certificate(s)); 1475 super.afterHandshake(session, s, c, sock, fd, callback); 1476 } 1477 }; 1478 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1479 @Override 1480 public void afterHandshake(long session, long s, long c, 1481 Socket sock, FileDescriptor fd, 1482 SSLHandshakeCallbacks callback) 1483 throws Exception { 1484 assertEqualCertificateChains( 1485 getServerCertificates(), 1486 NativeCrypto.SSL_get_certificate(s)); 1487 super.afterHandshake(session, s, c, sock, fd, callback); 1488 } 1489 }; 1490 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1491 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1492 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1493 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1494 } 1495 1496 public void test_SSL_get_peer_cert_chain() throws Exception { 1497 try { 1498 NativeCrypto.SSL_get_peer_cert_chain(NULL); 1499 fail(); 1500 } catch (NullPointerException expected) { 1501 } 1502 1503 final ServerSocket listener = new ServerSocket(0); 1504 1505 Hooks cHooks = new Hooks() { 1506 @Override 1507 public void afterHandshake(long session, long s, long c, 1508 Socket sock, FileDescriptor fd, 1509 SSLHandshakeCallbacks callback) 1510 throws Exception { 1511 byte[][] cc = NativeCrypto.SSL_get_peer_cert_chain(s); 1512 assertEqualCertificateChains(getServerCertificates(), cc); 1513 super.afterHandshake(session, s, c, sock, fd, callback); 1514 } 1515 }; 1516 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1517 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1518 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1519 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1520 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1521 } 1522 1523 final byte[] BYTES = new byte[] { 2, -3, 5, 127, 0, -128 }; 1524 1525 public void test_SSL_read() throws Exception { 1526 1527 // NULL ssl 1528 try { 1529 NativeCrypto.SSL_read(NULL, null, null, null, 0, 0, 0); 1530 fail(); 1531 } catch (NullPointerException expected) { 1532 } 1533 1534 // null FileDescriptor 1535 { 1536 long c = NativeCrypto.SSL_CTX_new(); 1537 long s = NativeCrypto.SSL_new(c); 1538 try { 1539 NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0); 1540 fail(); 1541 } catch (NullPointerException expected) { 1542 } 1543 NativeCrypto.SSL_free(s); 1544 NativeCrypto.SSL_CTX_free(c); 1545 } 1546 1547 // null SSLHandshakeCallbacks 1548 { 1549 long c = NativeCrypto.SSL_CTX_new(); 1550 long s = NativeCrypto.SSL_new(c); 1551 try { 1552 NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0); 1553 fail(); 1554 } catch (NullPointerException expected) { 1555 } 1556 NativeCrypto.SSL_free(s); 1557 NativeCrypto.SSL_CTX_free(c); 1558 } 1559 1560 // null byte array 1561 { 1562 long c = NativeCrypto.SSL_CTX_new(); 1563 long s = NativeCrypto.SSL_new(c); 1564 try { 1565 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0); 1566 fail(); 1567 } catch (NullPointerException expected) { 1568 } 1569 NativeCrypto.SSL_free(s); 1570 NativeCrypto.SSL_CTX_free(c); 1571 } 1572 1573 // handshaking not yet performed 1574 { 1575 long c = NativeCrypto.SSL_CTX_new(); 1576 long s = NativeCrypto.SSL_new(c); 1577 try { 1578 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0); 1579 fail(); 1580 } catch (SSLException expected) { 1581 } 1582 NativeCrypto.SSL_free(s); 1583 NativeCrypto.SSL_CTX_free(c); 1584 } 1585 1586 final ServerSocket listener = new ServerSocket(0); 1587 1588 // normal case 1589 { 1590 Hooks cHooks = new Hooks() { 1591 @Override 1592 public void afterHandshake(long session, long s, long c, 1593 Socket sock, FileDescriptor fd, 1594 SSLHandshakeCallbacks callback) 1595 throws Exception { 1596 byte[] in = new byte[256]; 1597 assertEquals(BYTES.length, 1598 NativeCrypto.SSL_read(s, 1599 fd, 1600 callback, 1601 in, 1602 0, 1603 BYTES.length, 1604 0)); 1605 for (int i = 0; i < BYTES.length; i++) { 1606 assertEquals(BYTES[i], in[i]); 1607 } 1608 super.afterHandshake(session, s, c, sock, fd, callback); 1609 } 1610 }; 1611 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1612 @Override 1613 public void afterHandshake(long session, long s, long c, 1614 Socket sock, FileDescriptor fd, 1615 SSLHandshakeCallbacks callback) 1616 throws Exception { 1617 NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0); 1618 super.afterHandshake(session, s, c, sock, fd, callback); 1619 } 1620 }; 1621 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1622 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1623 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1624 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1625 } 1626 1627 // timeout case 1628 try { 1629 Hooks cHooks = new Hooks() { 1630 @Override 1631 public void afterHandshake(long session, long s, long c, 1632 Socket sock, FileDescriptor fd, 1633 SSLHandshakeCallbacks callback) 1634 throws Exception { 1635 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 1); 1636 fail(); 1637 } 1638 }; 1639 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1640 @Override 1641 public void afterHandshake(long session, long s, long c, 1642 Socket sock, FileDescriptor fd, 1643 SSLHandshakeCallbacks callback) 1644 throws Exception { 1645 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 1646 super.afterHandshake(session, s, c, sock, fd, callback); 1647 } 1648 }; 1649 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1650 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1651 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1652 fail(); 1653 } catch (ExecutionException expected) { 1654 assertEquals(SocketTimeoutException.class, expected.getCause().getClass()); 1655 } 1656 } 1657 1658 public void test_SSL_write() throws Exception { 1659 try { 1660 NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0); 1661 fail(); 1662 } catch (NullPointerException expected) { 1663 } 1664 1665 // null FileDescriptor 1666 { 1667 long c = NativeCrypto.SSL_CTX_new(); 1668 long s = NativeCrypto.SSL_new(c); 1669 try { 1670 NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0); 1671 fail(); 1672 } catch (NullPointerException expected) { 1673 } 1674 NativeCrypto.SSL_free(s); 1675 NativeCrypto.SSL_CTX_free(c); 1676 } 1677 1678 // null SSLHandshakeCallbacks 1679 { 1680 long c = NativeCrypto.SSL_CTX_new(); 1681 long s = NativeCrypto.SSL_new(c); 1682 try { 1683 NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0); 1684 fail(); 1685 } catch (NullPointerException expected) { 1686 } 1687 NativeCrypto.SSL_free(s); 1688 NativeCrypto.SSL_CTX_free(c); 1689 } 1690 1691 // null byte array 1692 { 1693 long c = NativeCrypto.SSL_CTX_new(); 1694 long s = NativeCrypto.SSL_new(c); 1695 try { 1696 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0); 1697 fail(); 1698 } catch (NullPointerException expected) { 1699 } 1700 NativeCrypto.SSL_free(s); 1701 NativeCrypto.SSL_CTX_free(c); 1702 } 1703 1704 // handshaking not yet performed 1705 { 1706 long c = NativeCrypto.SSL_CTX_new(); 1707 long s = NativeCrypto.SSL_new(c); 1708 try { 1709 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0); 1710 fail(); 1711 } catch (SSLException expected) { 1712 } 1713 NativeCrypto.SSL_free(s); 1714 NativeCrypto.SSL_CTX_free(c); 1715 } 1716 1717 // positively tested by test_SSL_read 1718 } 1719 1720 public void test_SSL_interrupt() throws Exception { 1721 // SSL_interrupt is a rare case that tolerates a null SSL argument 1722 NativeCrypto.SSL_interrupt(NULL); 1723 1724 // also works without handshaking 1725 { 1726 long c = NativeCrypto.SSL_CTX_new(); 1727 long s = NativeCrypto.SSL_new(c); 1728 NativeCrypto.SSL_interrupt(s); 1729 NativeCrypto.SSL_free(s); 1730 NativeCrypto.SSL_CTX_free(c); 1731 } 1732 1733 final ServerSocket listener = new ServerSocket(0); 1734 1735 Hooks cHooks = new Hooks() { 1736 @Override 1737 public void afterHandshake(long session, long s, long c, 1738 Socket sock, FileDescriptor fd, 1739 SSLHandshakeCallbacks callback) 1740 throws Exception { 1741 NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0); 1742 super.afterHandshake(session, s, c, sock, fd, callback); 1743 } 1744 }; 1745 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) { 1746 @Override 1747 public void afterHandshake(long session, final long s, long c, 1748 Socket sock, FileDescriptor fd, 1749 SSLHandshakeCallbacks callback) 1750 throws Exception { 1751 new Thread() { 1752 public void run() { 1753 try { 1754 Thread.sleep(1*1000); 1755 NativeCrypto.SSL_interrupt(s); 1756 } catch (Exception e) { 1757 } 1758 } 1759 }.start(); 1760 assertEquals(-1, NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0)); 1761 super.afterHandshake(session, s, c, sock, fd, callback); 1762 } 1763 }; 1764 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1765 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1766 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1767 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1768 } 1769 1770 public void test_SSL_shutdown() throws Exception { 1771 1772 // null FileDescriptor 1773 try { 1774 NativeCrypto.SSL_shutdown(NULL, null, DUMMY_CB); 1775 } catch (NullPointerException expected) { 1776 } 1777 1778 // null SSLHandshakeCallbacks 1779 try { 1780 NativeCrypto.SSL_shutdown(NULL, INVALID_FD, null); 1781 } catch (NullPointerException expected) { 1782 } 1783 1784 // SSL_shutdown is a rare case that tolerates a null SSL argument 1785 NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB); 1786 1787 // handshaking not yet performed 1788 long c = NativeCrypto.SSL_CTX_new(); 1789 long s = NativeCrypto.SSL_new(c); 1790 try { 1791 NativeCrypto.SSL_shutdown(s, INVALID_FD, DUMMY_CB); 1792 } catch (SSLProtocolException expected) { 1793 } 1794 NativeCrypto.SSL_free(s); 1795 NativeCrypto.SSL_CTX_free(c); 1796 1797 // positively tested elsewhere because handshake uses use 1798 // SSL_shutdown to ensure SSL_SESSIONs are reused. 1799 } 1800 1801 public void test_SSL_free() throws Exception { 1802 try { 1803 NativeCrypto.SSL_free(NULL); 1804 fail(); 1805 } catch (NullPointerException expected) { 1806 } 1807 1808 long c = NativeCrypto.SSL_CTX_new(); 1809 NativeCrypto.SSL_free(NativeCrypto.SSL_new(c)); 1810 NativeCrypto.SSL_CTX_free(c); 1811 1812 // additional positive testing elsewhere because handshake 1813 // uses use SSL_free to cleanup in afterHandshake. 1814 } 1815 1816 public void test_SSL_SESSION_session_id() throws Exception { 1817 try { 1818 NativeCrypto.SSL_SESSION_session_id(NULL); 1819 fail(); 1820 } catch (NullPointerException expected) { 1821 } 1822 1823 final ServerSocket listener = new ServerSocket(0); 1824 1825 Hooks cHooks = new Hooks() { 1826 @Override 1827 public void afterHandshake(long session, long s, long c, 1828 Socket sock, FileDescriptor fd, 1829 SSLHandshakeCallbacks callback) 1830 throws Exception { 1831 byte[] id = NativeCrypto.SSL_SESSION_session_id(session); 1832 assertNotNull(id); 1833 assertEquals(32, id.length); 1834 super.afterHandshake(session, s, c, sock, fd, callback); 1835 } 1836 }; 1837 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1838 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1839 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1840 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1841 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1842 } 1843 1844 public void test_SSL_SESSION_get_time() throws Exception { 1845 try { 1846 NativeCrypto.SSL_SESSION_get_time(NULL); 1847 fail(); 1848 } catch (NullPointerException expected) { 1849 } 1850 1851 final ServerSocket listener = new ServerSocket(0); 1852 1853 { 1854 Hooks cHooks = new Hooks() { 1855 @Override 1856 public void afterHandshake(long session, long s, long c, 1857 Socket sock, FileDescriptor fd, 1858 SSLHandshakeCallbacks callback) 1859 throws Exception { 1860 long time = NativeCrypto.SSL_SESSION_get_time(session); 1861 assertTrue(time != 0); 1862 assertTrue(time < System.currentTimeMillis()); 1863 super.afterHandshake(session, s, c, sock, fd, callback); 1864 } 1865 }; 1866 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1867 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1868 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1869 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1870 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1871 } 1872 } 1873 1874 public void test_SSL_SESSION_get_version() throws Exception { 1875 try { 1876 NativeCrypto.SSL_SESSION_get_version(NULL); 1877 fail(); 1878 } catch (NullPointerException expected) { 1879 } 1880 1881 final ServerSocket listener = new ServerSocket(0); 1882 1883 Hooks cHooks = new Hooks() { 1884 @Override 1885 public void afterHandshake(long session, long s, long c, 1886 Socket sock, FileDescriptor fd, 1887 SSLHandshakeCallbacks callback) 1888 throws Exception { 1889 String v = NativeCrypto.SSL_SESSION_get_version(session); 1890 assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v)); 1891 super.afterHandshake(session, s, c, sock, fd, callback); 1892 } 1893 }; 1894 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1895 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1896 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1897 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1898 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1899 } 1900 1901 public void test_SSL_SESSION_cipher() throws Exception { 1902 try { 1903 NativeCrypto.SSL_SESSION_cipher(NULL); 1904 fail(); 1905 } catch (NullPointerException expected) { 1906 } 1907 1908 final ServerSocket listener = new ServerSocket(0); 1909 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 String a = NativeCrypto.SSL_SESSION_cipher(session); 1917 assertTrue(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(a)); 1918 super.afterHandshake(session, s, c, sock, fd, callback); 1919 } 1920 }; 1921 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1922 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1923 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1924 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1925 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1926 } 1927 1928 public void test_SSL_SESSION_free() throws Exception { 1929 try { 1930 NativeCrypto.SSL_SESSION_free(NULL); 1931 fail(); 1932 } catch (NullPointerException expected) { 1933 } 1934 1935 // additional positive testing elsewhere because handshake 1936 // uses use SSL_SESSION_free to cleanup in afterHandshake. 1937 } 1938 1939 public void test_i2d_SSL_SESSION() throws Exception { 1940 try { 1941 NativeCrypto.i2d_SSL_SESSION(NULL); 1942 fail(); 1943 } catch (NullPointerException expected) { 1944 } 1945 1946 final ServerSocket listener = new ServerSocket(0); 1947 1948 Hooks cHooks = new Hooks() { 1949 @Override 1950 public void afterHandshake(long session, long s, long c, 1951 Socket sock, FileDescriptor fd, 1952 SSLHandshakeCallbacks callback) 1953 throws Exception { 1954 byte[] b = NativeCrypto.i2d_SSL_SESSION(session); 1955 assertNotNull(b); 1956 long session2 = NativeCrypto.d2i_SSL_SESSION(b); 1957 assertTrue(session2 != NULL); 1958 1959 // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840 1960 assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null); 1961 assertEquals(NativeCrypto.SSL_SESSION_cipher(session), 1962 NativeCrypto.SSL_SESSION_cipher(session2)); 1963 1964 NativeCrypto.SSL_SESSION_free(session2); 1965 super.afterHandshake(session, s, c, sock, fd, callback); 1966 } 1967 }; 1968 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()); 1969 Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null); 1970 Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null); 1971 client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1972 server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); 1973 } 1974 1975 public void test_d2i_SSL_SESSION() throws Exception { 1976 try { 1977 NativeCrypto.d2i_SSL_SESSION(null); 1978 fail(); 1979 } catch (NullPointerException expected) { 1980 } 1981 1982 assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[0])); 1983 assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[1])); 1984 1985 // positive testing by test_i2d_SSL_SESSION 1986 } 1987 1988 public void test_X509_NAME_hashes() { 1989 // ensure these hash functions are stable over time since the 1990 // /system/etc/security/cacerts CA filenames have to be 1991 // consistent with the output. 1992 X500Principal name = new X500Principal("CN=localhost"); 1993 assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1 1994 assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5 1995 } 1996 1997 public void test_ENGINE_by_id_Failure() throws Exception { 1998 NativeCrypto.ENGINE_load_dynamic(); 1999 2000 long engine = NativeCrypto.ENGINE_by_id("non-existent"); 2001 if (engine != 0) { 2002 NativeCrypto.ENGINE_finish(engine); 2003 fail("should not acquire reference to non-existent engine"); 2004 } 2005 } 2006 2007 /** 2008 * Loads the test OpenSSL ENGINE. If it's already loaded, returns 2009 * immediately. 2010 */ 2011 public static void loadTestEngine() throws Exception { 2012 long testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID); 2013 if (testEngine != 0) { 2014 NativeCrypto.ENGINE_finish(testEngine); 2015 return; 2016 } 2017 2018 NativeCrypto.ENGINE_load_dynamic(); 2019 long dynEngine = NativeCrypto.ENGINE_by_id("dynamic"); 2020 try { 2021 ClassLoader loader = NativeCryptoTest.class.getClassLoader(); 2022 2023 final String libraryPaths; 2024 if (loader instanceof BaseDexClassLoader) { 2025 libraryPaths = ((BaseDexClassLoader) loader).getLdLibraryPath(); 2026 } else { 2027 libraryPaths = System.getProperty("java.library.path"); 2028 } 2029 assertNotNull(libraryPaths); 2030 2031 String[] libraryPathArray = libraryPaths.split(":"); 2032 for (String path : libraryPathArray) { 2033 assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "DIR_ADD", path, 0)); 2034 } 2035 2036 // We must add this to the list of ENGINEs 2037 assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LIST_ADD", "2", 0)); 2038 2039 // Do a direct load of the ENGINE. 2040 assertEquals(1, 2041 NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "ID", TEST_ENGINE_ID, 0)); 2042 assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LOAD", null, 0)); 2043 } finally { 2044 NativeCrypto.ENGINE_finish(dynEngine); 2045 } 2046 2047 testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID); 2048 if (testEngine == 0) { 2049 fail("could not load test engine"); 2050 } 2051 NativeCrypto.ENGINE_finish(testEngine); 2052 } 2053 2054 public void test_ENGINE_by_id_TestEngine() throws Exception { 2055 loadTestEngine(); 2056 2057 long engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID); 2058 assertTrue(engine != 0); 2059 NativeCrypto.ENGINE_add(engine); 2060 2061 long pkey = NULL; 2062 try { 2063 final String rsaPem = 2064 "-----BEGIN RSA PRIVATE KEY-----\n" 2065 + "MIICXAIBAAKBgQCvvsYz1VKhU9PT0NHlotX22tcCjeaiVFNg0JrkjoK2XuMb+7a6\n" 2066 + "R5bzgIr24+OnBB0LqgaKnHwxZTA73lo/Wy/Ms5Kvg4yX9UMkNE+PvH5vzcQBbFdI\n" 2067 + "lwETFPvFokHO5OyOcEY+iVWG2fDloteH2JsrKYLh9Sx3Br5pHFCCm5qT5wIDAQAB\n" 2068 + "AoGAWDxoNs371pPH3qkROUIwOuhU2ytziDzeP9V8bxQ9/GJXlE0kyRH4b/kxzBNO\n" 2069 + "0SP3kUukTSOUFxi+xtA0b2rQ7Be2txtjzW1TGOHSCWbFrJAdTqeBcmQJSaZay8n1\n" 2070 + "LOpk4/zvBl7VScBth1IgXP44v6lOzthsrDhMlUYs07ymwYECQQDonaLOhkmVThPa\n" 2071 + "CIThdE5CN/wF5UDzGOz+ZBz3dt8D8QQMu0aZaPzibq9BC462j/fWeWS5OFzbq2+T\n" 2072 + "+cor3nwPAkEAwWmTQdra6GMPEc40zNsM5ehF2FjOpX8aU8267eG56y0Y+GbHx2BN\n" 2073 + "zAHfPxGBBH8cZ0cLhk4RSo/po7Vv+cRyqQJAAQz1N0mT+4Cmxk1TjFEiKVpnYP9w\n" 2074 + "E6kBKQT6vINk7negNQ6Dex3mRn+Jexm6Q0jTLbzOn6eJg9R6ZIi0SQ5wMQJAKX2n\n" 2075 + "fGohqdaORgiRZRzcsHlaemXatsAEetPYdO2Gf7/l6mvKEahEKC6CoLn1jmxiQHmK\n" 2076 + "LF6U8QTcXyUuB0uwOQJBAIwWWjQGGc2sAQ1HW0C2wwCQbWneeBkiRBedonDBHtiB\n" 2077 + "Wz0zS2CMCtBPNeHQmmsXH2Ca+ADdh53sKTuperLiuiw=\n" 2078 + "-----END RSA PRIVATE KEY-----"; 2079 pkey = NativeCrypto.ENGINE_load_private_key(engine, rsaPem); 2080 assertTrue(pkey != 0); 2081 } finally { 2082 if (pkey != NULL) { 2083 NativeCrypto.EVP_PKEY_free(pkey); 2084 } 2085 2086 NativeCrypto.ENGINE_free(engine); 2087 NativeCrypto.ENGINE_finish(engine); 2088 } 2089 } 2090 2091 public void test_RAND_bytes_Success() throws Exception { 2092 byte[] output = new byte[128]; 2093 NativeCrypto.RAND_bytes(output); 2094 2095 boolean isZero = true; 2096 for (int i = 0; i < output.length; i++) { 2097 isZero &= (output[i] == 0); 2098 } 2099 2100 assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) " 2101 + "and probably indicates an error.", isZero); 2102 } 2103 2104 public void test_RAND_bytes_Null_Failure() throws Exception { 2105 byte[] output = null; 2106 try { 2107 NativeCrypto.RAND_bytes(output); 2108 fail("Should be an error on null buffer input"); 2109 } catch (RuntimeException expected) { 2110 } 2111 } 2112 2113 public void test_EVP_get_digestbyname() throws Exception { 2114 assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL); 2115 2116 try { 2117 NativeCrypto.EVP_get_digestbyname(null); 2118 fail(); 2119 } catch (NullPointerException expected) { 2120 } 2121 2122 try { 2123 NativeCrypto.EVP_get_digestbyname(""); 2124 NativeCrypto.EVP_get_digestbyname("foobar"); 2125 fail(); 2126 } catch (RuntimeException expected) { 2127 } 2128 } 2129 2130 public void test_EVP_SignInit() throws Exception { 2131 final long ctx = NativeCrypto.EVP_SignInit("RSA-SHA256"); 2132 assertTrue(ctx != NULL); 2133 NativeCrypto.EVP_MD_CTX_destroy(ctx); 2134 2135 try { 2136 NativeCrypto.EVP_SignInit("foobar"); 2137 fail(); 2138 } catch (RuntimeException expected) { 2139 } 2140 } 2141 2142 public void test_get_RSA_private_params() throws Exception { 2143 try { 2144 NativeCrypto.get_RSA_private_params(NULL); 2145 } catch (NullPointerException expected) { 2146 } 2147 2148 try { 2149 NativeCrypto.get_RSA_private_params(NULL); 2150 } catch (NullPointerException expected) { 2151 } 2152 2153 // Test getting params for the wrong kind of key. 2154 final byte[] seed = new byte[20]; 2155 long ctx = 0; 2156 try { 2157 ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q); 2158 assertTrue(ctx != NULL); 2159 try { 2160 NativeCrypto.get_RSA_private_params(ctx); 2161 fail(); 2162 } catch (RuntimeException expected) { 2163 } 2164 } finally { 2165 if (ctx != 0) { 2166 NativeCrypto.EVP_PKEY_free(ctx); 2167 } 2168 } 2169 } 2170 2171 public void test_get_RSA_public_params() throws Exception { 2172 try { 2173 NativeCrypto.get_RSA_public_params(NULL); 2174 } catch (NullPointerException expected) { 2175 } 2176 2177 try { 2178 NativeCrypto.get_RSA_public_params(NULL); 2179 } catch (NullPointerException expected) { 2180 } 2181 2182 // Test getting params for the wrong kind of key. 2183 final byte[] seed = new byte[20]; 2184 long ctx = 0; 2185 try { 2186 ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q); 2187 assertTrue(ctx != NULL); 2188 try { 2189 NativeCrypto.get_RSA_public_params(ctx); 2190 fail(); 2191 } catch (RuntimeException expected) { 2192 } 2193 } finally { 2194 if (ctx != 0) { 2195 NativeCrypto.EVP_PKEY_free(ctx); 2196 } 2197 } 2198 } 2199 2200 final byte[] dsa2048_p = { 2201 (byte) 0xC3, (byte) 0x16, (byte) 0xD4, (byte) 0xBA, (byte) 0xDC, (byte) 0x0E, 2202 (byte) 0xB8, (byte) 0xFC, (byte) 0x40, (byte) 0xDB, (byte) 0xB0, (byte) 0x76, 2203 (byte) 0x47, (byte) 0xB8, (byte) 0x8D, (byte) 0xC1, (byte) 0xF1, (byte) 0xAB, 2204 (byte) 0x9B, (byte) 0x80, (byte) 0x9D, (byte) 0xDC, (byte) 0x55, (byte) 0x33, 2205 (byte) 0xEC, (byte) 0xB6, (byte) 0x09, (byte) 0x8F, (byte) 0xB7, (byte) 0xD9, 2206 (byte) 0xA5, (byte) 0x7F, (byte) 0xC1, (byte) 0xE3, (byte) 0xAD, (byte) 0xE1, 2207 (byte) 0x7A, (byte) 0x58, (byte) 0xF4, (byte) 0x2D, (byte) 0xB9, (byte) 0x61, 2208 (byte) 0xCF, (byte) 0x5B, (byte) 0xCA, (byte) 0x41, (byte) 0x9F, (byte) 0x73, 2209 (byte) 0x8D, (byte) 0x81, (byte) 0x62, (byte) 0xD2, (byte) 0x19, (byte) 0x7D, 2210 (byte) 0x18, (byte) 0xDB, (byte) 0xB3, (byte) 0x04, (byte) 0xE7, (byte) 0xB2, 2211 (byte) 0x28, (byte) 0x59, (byte) 0x14, (byte) 0x73, (byte) 0x43, (byte) 0xF1, 2212 (byte) 0x45, (byte) 0xC7, (byte) 0x47, (byte) 0xCC, (byte) 0xD1, (byte) 0x12, 2213 (byte) 0x8E, (byte) 0x19, (byte) 0x00, (byte) 0x2C, (byte) 0xD0, (byte) 0x86, 2214 (byte) 0x54, (byte) 0x64, (byte) 0x2D, (byte) 0x42, (byte) 0x6C, (byte) 0x6B, 2215 (byte) 0x5C, (byte) 0x2D, (byte) 0x4D, (byte) 0x97, (byte) 0x6A, (byte) 0x1D, 2216 (byte) 0x89, (byte) 0xB1, (byte) 0x2C, (byte) 0xA0, (byte) 0x05, (byte) 0x2B, 2217 (byte) 0x3C, (byte) 0xDB, (byte) 0x1F, (byte) 0x89, (byte) 0x03, (byte) 0x03, 2218 (byte) 0x92, (byte) 0x63, (byte) 0xB6, (byte) 0x08, (byte) 0x32, (byte) 0x50, 2219 (byte) 0xB2, (byte) 0x54, (byte) 0xA3, (byte) 0xFE, (byte) 0x6C, (byte) 0x35, 2220 (byte) 0x17, (byte) 0x2F, (byte) 0x7F, (byte) 0x54, (byte) 0xA4, (byte) 0xAE, 2221 (byte) 0x96, (byte) 0x1E, (byte) 0x31, (byte) 0x83, (byte) 0xF1, (byte) 0x3F, 2222 (byte) 0x9E, (byte) 0xB9, (byte) 0x5D, (byte) 0xD3, (byte) 0xA9, (byte) 0xCB, 2223 (byte) 0xE5, (byte) 0x2F, (byte) 0xBC, (byte) 0xA4, (byte) 0x1A, (byte) 0x31, 2224 (byte) 0x41, (byte) 0x91, (byte) 0x2C, (byte) 0xA0, (byte) 0xF4, (byte) 0x83, 2225 (byte) 0xAC, (byte) 0xD5, (byte) 0xBA, (byte) 0x3D, (byte) 0x19, (byte) 0xED, 2226 (byte) 0xF1, (byte) 0x6C, (byte) 0xD9, (byte) 0x3F, (byte) 0x30, (byte) 0xDA, 2227 (byte) 0x80, (byte) 0x06, (byte) 0x56, (byte) 0x3A, (byte) 0x8C, (byte) 0x74, 2228 (byte) 0x63, (byte) 0xF2, (byte) 0xED, (byte) 0x1E, (byte) 0xE3, (byte) 0x86, 2229 (byte) 0x95, (byte) 0x64, (byte) 0x2A, (byte) 0xC4, (byte) 0x5F, (byte) 0xB2, 2230 (byte) 0x64, (byte) 0x40, (byte) 0x9D, (byte) 0xA6, (byte) 0xB8, (byte) 0xF5, 2231 (byte) 0x84, (byte) 0x03, (byte) 0x2E, (byte) 0x4A, (byte) 0x7A, (byte) 0x1A, 2232 (byte) 0xB0, (byte) 0x0E, (byte) 0xBA, (byte) 0xB1, (byte) 0xF5, (byte) 0xD2, 2233 (byte) 0xE7, (byte) 0x65, (byte) 0xCE, (byte) 0xEE, (byte) 0x2C, (byte) 0x7C, 2234 (byte) 0x68, (byte) 0x20, (byte) 0x50, (byte) 0x53, (byte) 0x0F, (byte) 0x60, 2235 (byte) 0x92, (byte) 0x81, (byte) 0xC0, (byte) 0x2C, (byte) 0x2A, (byte) 0xEA, 2236 (byte) 0xE9, (byte) 0xB3, (byte) 0x2A, (byte) 0x81, (byte) 0xDA, (byte) 0x0F, 2237 (byte) 0xBB, (byte) 0xFA, (byte) 0x5B, (byte) 0x47, (byte) 0xDA, (byte) 0x57, 2238 (byte) 0x4E, (byte) 0xFC, (byte) 0x05, (byte) 0x2C, (byte) 0x6A, (byte) 0x90, 2239 (byte) 0xA0, (byte) 0x99, (byte) 0x88, (byte) 0x71, (byte) 0x8A, (byte) 0xCC, 2240 (byte) 0xD2, (byte) 0x97, (byte) 0x11, (byte) 0xB1, (byte) 0xCE, (byte) 0xF7, 2241 (byte) 0x47, (byte) 0x53, (byte) 0x53, (byte) 0x68, (byte) 0xE1, (byte) 0x2A, 2242 (byte) 0x56, (byte) 0xD5, (byte) 0x3D, (byte) 0xDF, (byte) 0x08, (byte) 0x16, 2243 (byte) 0x1F, (byte) 0xAA, (byte) 0x54, (byte) 0x15, 2244 }; 2245 2246 final byte[] dsa2048_q = { 2247 (byte) 0xAA, (byte) 0xDD, (byte) 0xE2, (byte) 0xCE, (byte) 0x08, (byte) 0xC0, 2248 (byte) 0x0E, (byte) 0x91, (byte) 0x8C, (byte) 0xD9, (byte) 0xBC, (byte) 0x1E, 2249 (byte) 0x05, (byte) 0x70, (byte) 0x07, (byte) 0x3B, (byte) 0xB5, (byte) 0xA9, 2250 (byte) 0xB5, (byte) 0x8B, (byte) 0x21, (byte) 0x68, (byte) 0xA2, (byte) 0x76, 2251 (byte) 0x53, (byte) 0x1E, (byte) 0x68, (byte) 0x1B, (byte) 0x4F, (byte) 0x88, 2252 (byte) 0x6D, (byte) 0xCF, 2253 }; 2254 2255 final byte[] dsa2048_g = { 2256 (byte) 0x6B, (byte) 0x4D, (byte) 0x21, (byte) 0x92, (byte) 0x24, (byte) 0x76, 2257 (byte) 0xE5, (byte) 0xA2, (byte) 0xCE, (byte) 0x02, (byte) 0x85, (byte) 0x32, 2258 (byte) 0x73, (byte) 0x70, (byte) 0xFF, (byte) 0xB9, (byte) 0xD4, (byte) 0x51, 2259 (byte) 0xBA, (byte) 0x22, (byte) 0x8B, (byte) 0x75, (byte) 0x29, (byte) 0xE3, 2260 (byte) 0xF2, (byte) 0x2E, (byte) 0x20, (byte) 0xF5, (byte) 0x6A, (byte) 0xD9, 2261 (byte) 0x75, (byte) 0xA0, (byte) 0xC0, (byte) 0x3B, (byte) 0x12, (byte) 0x2F, 2262 (byte) 0x4F, (byte) 0x9A, (byte) 0xF8, (byte) 0x5D, (byte) 0x45, (byte) 0xC5, 2263 (byte) 0x80, (byte) 0x6C, (byte) 0x9B, (byte) 0x56, (byte) 0xBE, (byte) 0x8E, 2264 (byte) 0x40, (byte) 0xF9, (byte) 0x0A, (byte) 0xF0, (byte) 0x3D, (byte) 0xD7, 2265 (byte) 0x7C, (byte) 0xDE, (byte) 0x22, (byte) 0x10, (byte) 0x24, (byte) 0xCC, 2266 (byte) 0xAE, (byte) 0x8A, (byte) 0xC0, (byte) 0x05, (byte) 0xCD, (byte) 0xDC, 2267 (byte) 0x10, (byte) 0x29, (byte) 0x4D, (byte) 0xFC, (byte) 0xEC, (byte) 0xEF, 2268 (byte) 0x51, (byte) 0x4B, (byte) 0xF9, (byte) 0xCC, (byte) 0x99, (byte) 0x84, 2269 (byte) 0x1B, (byte) 0x14, (byte) 0x68, (byte) 0xEC, (byte) 0xF0, (byte) 0x5E, 2270 (byte) 0x07, (byte) 0x10, (byte) 0x09, (byte) 0xA9, (byte) 0x2C, (byte) 0x04, 2271 (byte) 0xD0, (byte) 0x14, (byte) 0xBF, (byte) 0x88, (byte) 0x9E, (byte) 0xBB, 2272 (byte) 0xE3, (byte) 0x3F, (byte) 0xDE, (byte) 0x92, (byte) 0xE1, (byte) 0x64, 2273 (byte) 0x07, (byte) 0x28, (byte) 0xC1, (byte) 0xCA, (byte) 0x48, (byte) 0xC1, 2274 (byte) 0x1D, (byte) 0x33, (byte) 0xE4, (byte) 0x35, (byte) 0xBE, (byte) 0xDF, 2275 (byte) 0x5E, (byte) 0x50, (byte) 0xF9, (byte) 0xC2, (byte) 0x0E, (byte) 0x25, 2276 (byte) 0x0D, (byte) 0x20, (byte) 0x8C, (byte) 0x01, (byte) 0x0A, (byte) 0x23, 2277 (byte) 0xD4, (byte) 0x6E, (byte) 0x42, (byte) 0x47, (byte) 0xE1, (byte) 0x9E, 2278 (byte) 0x36, (byte) 0x91, (byte) 0xC8, (byte) 0x65, (byte) 0x44, (byte) 0xE0, 2279 (byte) 0x04, (byte) 0x86, (byte) 0x2F, (byte) 0xD4, (byte) 0x90, (byte) 0x16, 2280 (byte) 0x09, (byte) 0x14, (byte) 0xB1, (byte) 0xC5, (byte) 0x7D, (byte) 0xB2, 2281 (byte) 0x7C, (byte) 0x36, (byte) 0x0D, (byte) 0x9C, (byte) 0x1F, (byte) 0x83, 2282 (byte) 0x57, (byte) 0x94, (byte) 0x26, (byte) 0x32, (byte) 0x9C, (byte) 0x86, 2283 (byte) 0x8E, (byte) 0xE5, (byte) 0x80, (byte) 0x3A, (byte) 0xA9, (byte) 0xAF, 2284 (byte) 0x4A, (byte) 0x95, (byte) 0x78, (byte) 0x8D, (byte) 0xE6, (byte) 0xC3, 2285 (byte) 0x0C, (byte) 0x78, (byte) 0x83, (byte) 0x4B, (byte) 0xF5, (byte) 0x40, 2286 (byte) 0x04, (byte) 0x20, (byte) 0x90, (byte) 0x5C, (byte) 0xA1, (byte) 0x19, 2287 (byte) 0xEB, (byte) 0x95, (byte) 0x70, (byte) 0x2B, (byte) 0x94, (byte) 0xA3, 2288 (byte) 0x43, (byte) 0xDD, (byte) 0xEB, (byte) 0xD4, (byte) 0x0C, (byte) 0xBC, 2289 (byte) 0xBD, (byte) 0x58, (byte) 0x2D, (byte) 0x75, (byte) 0xB0, (byte) 0x8D, 2290 (byte) 0x8B, (byte) 0x70, (byte) 0xB9, (byte) 0xE7, (byte) 0xA3, (byte) 0xCC, 2291 (byte) 0x8C, (byte) 0xB4, (byte) 0xCD, (byte) 0xBB, (byte) 0x4B, (byte) 0xB1, 2292 (byte) 0x15, (byte) 0x18, (byte) 0x79, (byte) 0xDF, (byte) 0x22, (byte) 0xA6, 2293 (byte) 0x5C, (byte) 0x90, (byte) 0x7C, (byte) 0x1F, (byte) 0xEA, (byte) 0x1B, 2294 (byte) 0xF2, (byte) 0x89, (byte) 0x87, (byte) 0xB2, (byte) 0xEC, (byte) 0x57, 2295 (byte) 0xFF, (byte) 0xB2, (byte) 0xDA, (byte) 0xF5, (byte) 0xAD, (byte) 0x73, 2296 (byte) 0xC0, (byte) 0xA0, (byte) 0x20, (byte) 0x8B, (byte) 0x78, (byte) 0xA1, 2297 (byte) 0x5D, (byte) 0x04, (byte) 0x0A, (byte) 0x29, (byte) 0xE3, (byte) 0xD7, 2298 (byte) 0x37, (byte) 0xF6, (byte) 0xA2, (byte) 0xCA, 2299 }; 2300 2301 public void test_DSA_generate_key() throws Exception { 2302 final byte[] seed = new byte[20]; 2303 2304 // Real key 2305 { 2306 long ctx = 0; 2307 try { 2308 ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q); 2309 assertTrue(ctx != NULL); 2310 } finally { 2311 if (ctx != 0) { 2312 NativeCrypto.EVP_PKEY_free(ctx); 2313 } 2314 } 2315 } 2316 2317 // Real key with minimum bit size (should be 512 bits) 2318 { 2319 long ctx = 0; 2320 try { 2321 ctx = NativeCrypto.DSA_generate_key(0, null, null, null, null); 2322 assertTrue(ctx != NULL); 2323 } finally { 2324 if (ctx != 0) { 2325 NativeCrypto.EVP_PKEY_free(ctx); 2326 } 2327 } 2328 } 2329 2330 // Bad DSA params. 2331 { 2332 long ctx = 0; 2333 try { 2334 ctx = NativeCrypto.DSA_generate_key(0, null, new byte[] {}, new byte[] {}, 2335 new byte[] {}); 2336 fail(); 2337 } catch (RuntimeException expected) { 2338 } finally { 2339 if (ctx != 0) { 2340 NativeCrypto.EVP_PKEY_free(ctx); 2341 } 2342 } 2343 } 2344 } 2345 2346 /* 2347 * Test vector generation: 2348 * openssl rand -hex 16 2349 */ 2350 private static final byte[] AES_128_KEY = new byte[] { 2351 (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2, 2352 (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29, 2353 (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f, 2354 }; 2355 2356 private static final byte[] AES_IV_ZEROES = new byte[] { 2357 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 2358 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 2359 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 2360 }; 2361 2362 public void testEC_GROUP() throws Exception { 2363 /* Test using NIST's P-256 curve */ 2364 check_EC_GROUP(NativeCrypto.EC_CURVE_GFP, "prime256v1", 2365 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 2366 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 2367 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 2368 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 2369 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 2370 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 2371 1L); 2372 2373 check_EC_GROUP(NativeCrypto.EC_CURVE_GF2M, "sect283r1", 2374 "0800000000000000000000000000000000000000000000000000000000000000000010A1", 2375 "000000000000000000000000000000000000000000000000000000000000000000000001", 2376 "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 2377 "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", 2378 "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", 2379 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 2380 2L); 2381 } 2382 2383 private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr, 2384 String xStr, String yStr, String nStr, long hLong) throws Exception { 2385 long group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL; 2386 try { 2387 group1 = NativeCrypto.EC_GROUP_new_by_curve_name(name); 2388 assertTrue(group1 != NULL); 2389 assertEquals(NativeCrypto.OBJ_txt2nid_longName(name), 2390 NativeCrypto.EC_GROUP_get_curve_name(group1)); 2391 assertEquals(type, NativeCrypto.get_EC_GROUP_type(group1)); 2392 2393 // prime 2394 BigInteger p = new BigInteger(pStr, 16); 2395 // first coefficient 2396 BigInteger a = new BigInteger(aStr, 16); 2397 // second coefficient 2398 BigInteger b = new BigInteger(bStr, 16); 2399 // x affine coordinate of generator 2400 BigInteger x = new BigInteger(xStr, 16); 2401 // y affine coordinate of generator 2402 BigInteger y = new BigInteger(yStr, 16); 2403 // order of the generator 2404 BigInteger n = new BigInteger(nStr, 16); 2405 // cofactor of generator 2406 BigInteger h = BigInteger.valueOf(hLong); 2407 2408 group2 = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(), 2409 a.toByteArray(), b.toByteArray()); 2410 assertEquals(type, NativeCrypto.get_EC_GROUP_type(group2)); 2411 2412 point2 = NativeCrypto.EC_POINT_new(group2); 2413 2414 NativeCrypto.EC_POINT_set_affine_coordinates(group2, point2, x.toByteArray(), 2415 y.toByteArray()); 2416 2417 NativeCrypto.EC_GROUP_set_generator(group2, point2, n.toByteArray(), h.toByteArray()); 2418 2419 point1 = NativeCrypto.EC_GROUP_get_generator(group2); 2420 assertTrue(NativeCrypto.EC_POINT_cmp(group1, point1, point2)); 2421 2422 byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group2); 2423 assertEquals(3, pab.length); 2424 2425 BigInteger p2 = new BigInteger(pab[0]); 2426 assertEquals(p, p2); 2427 2428 BigInteger a2 = new BigInteger(pab[1]); 2429 assertEquals(a, a2); 2430 2431 BigInteger b2 = new BigInteger(pab[2]); 2432 assertEquals(b, b2); 2433 2434 byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group2, point2); 2435 assertEquals(2, xy.length); 2436 2437 BigInteger x2 = new BigInteger(xy[0]); 2438 assertEquals(x, x2); 2439 2440 BigInteger y2 = new BigInteger(xy[1]); 2441 assertEquals(y, y2); 2442 2443 BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group1)); 2444 assertEquals(n, n2); 2445 2446 BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group2)); 2447 assertEquals(h, h2); 2448 2449 assertTrue(NativeCrypto.EC_GROUP_cmp(group1, group2)); 2450 2451 key1 = NativeCrypto.EC_KEY_generate_key(group1); 2452 long groupTmp = NativeCrypto.EC_KEY_get0_group(key1); 2453 assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group1), 2454 NativeCrypto.EC_GROUP_get_curve_name(groupTmp)); 2455 2456 } finally { 2457 if (group1 != NULL) { 2458 NativeCrypto.EC_GROUP_clear_free(group1); 2459 } 2460 2461 if (group2 != NULL) { 2462 NativeCrypto.EC_GROUP_clear_free(group2); 2463 } 2464 2465 if (point1 != NULL) { 2466 NativeCrypto.EC_POINT_clear_free(point1); 2467 } 2468 2469 if (point2 != NULL) { 2470 NativeCrypto.EC_POINT_clear_free(point2); 2471 } 2472 2473 if (key1 != NULL) { 2474 NativeCrypto.EVP_PKEY_free(key1); 2475 } 2476 } 2477 } 2478 2479 public void test_EVP_CipherInit_ex_Null_Failure() throws Exception { 2480 final long ctx = NativeCrypto.EVP_CIPHER_CTX_new(); 2481 try { 2482 final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2483 2484 try { 2485 NativeCrypto.EVP_CipherInit_ex(NULL, evpCipher, null, null, true); 2486 fail("Null context should throw NullPointerException"); 2487 } catch (NullPointerException expected) { 2488 } 2489 2490 /* Initialize encrypting. */ 2491 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true); 2492 NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true); 2493 2494 /* Initialize decrypting. */ 2495 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false); 2496 NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false); 2497 } finally { 2498 NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx); 2499 } 2500 } 2501 2502 public void test_EVP_CipherInit_ex_Success() throws Exception { 2503 final long ctx = NativeCrypto.EVP_CIPHER_CTX_new(); 2504 try { 2505 final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2506 NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true); 2507 } finally { 2508 NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx); 2509 } 2510 } 2511 2512 public void test_EVP_CIPHER_iv_length() throws Exception { 2513 long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb"); 2514 assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb)); 2515 2516 long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc"); 2517 assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc)); 2518 } 2519 2520 public void test_OpenSSLKey_toJava() throws Exception { 2521 OpenSSLKey key1; 2522 2523 BigInteger e = BigInteger.valueOf(65537); 2524 key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray())); 2525 assertTrue(key1.getPublicKey() instanceof RSAPublicKey); 2526 2527 key1 = new OpenSSLKey(NativeCrypto.DSA_generate_key(1024, null, null, null, null)); 2528 assertTrue(key1.getPublicKey() instanceof DSAPublicKey); 2529 2530 long group1 = NULL; 2531 try { 2532 group1 = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1"); 2533 assertTrue(group1 != NULL); 2534 key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1)); 2535 } finally { 2536 if (group1 != NULL) { 2537 NativeCrypto.EC_GROUP_clear_free(group1); 2538 } 2539 } 2540 assertTrue(key1.getPublicKey() instanceof ECPublicKey); 2541 } 2542 2543 public void test_create_BIO_InputStream() throws Exception { 2544 byte[] actual = "Test".getBytes(); 2545 ByteArrayInputStream is = new ByteArrayInputStream(actual); 2546 2547 long ctx = NativeCrypto.create_BIO_InputStream(new OpenSSLBIOInputStream(is)); 2548 try { 2549 byte[] buffer = new byte[1024]; 2550 int numRead = NativeCrypto.BIO_read(ctx, buffer); 2551 assertEquals(actual.length, numRead); 2552 assertEquals(Arrays.toString(actual), 2553 Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead))); 2554 } finally { 2555 NativeCrypto.BIO_free(ctx); 2556 } 2557 2558 } 2559 2560 public void test_create_BIO_OutputStream() throws Exception { 2561 byte[] actual = "Test".getBytes(); 2562 ByteArrayOutputStream os = new ByteArrayOutputStream(); 2563 2564 long ctx = NativeCrypto.create_BIO_OutputStream(os); 2565 try { 2566 NativeCrypto.BIO_write(ctx, actual, 0, actual.length); 2567 assertEquals(actual.length, os.size()); 2568 assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray())); 2569 } finally { 2570 NativeCrypto.BIO_free(ctx); 2571 } 2572 } 2573 } 2574