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