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