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