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