NativeCryptoTest.java revision 860d2707ce126ef8f66e3eac7ceeab6d24218cd8
1860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root/*
2860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Copyright (C) 2010 The Android Open Source Project
3860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
4860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * you may not use this file except in compliance with the License.
6860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * You may obtain a copy of the License at
7860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
8860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root *
10860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * Unless required by applicable law or agreed to in writing, software
11860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * See the License for the specific language governing permissions and
14860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root * limitations under the License.
15860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root */
16860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt;
18860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
19860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport dalvik.system.BaseDexClassLoader;
20860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.ByteArrayInputStream;
21860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.ByteArrayOutputStream;
22860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.FileDescriptor;
23860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.io.IOException;
24860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.math.BigInteger;
25860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.net.ServerSocket;
26860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.net.Socket;
27860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.net.SocketTimeoutException;
28860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.KeyPair;
29860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.KeyPairGenerator;
30860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.KeyStore;
31860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.KeyStore.PrivateKeyEntry;
32860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.PrivateKey;
33860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.cert.CertificateException;
34860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.cert.X509Certificate;
35860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.interfaces.DSAPublicKey;
36860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.interfaces.ECPublicKey;
37860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.interfaces.RSAPrivateCrtKey;
38860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.interfaces.RSAPublicKey;
39860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.spec.ECPrivateKeySpec;
40860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.ArrayList;
41860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.Arrays;
42860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.List;
43860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.Callable;
44860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.ExecutionException;
45860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.ExecutorService;
46860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.Executors;
47860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.Future;
48860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.util.concurrent.TimeUnit;
49860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport javax.net.ssl.SSLException;
50860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport javax.net.ssl.SSLProtocolException;
51860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport javax.security.auth.x500.X500Principal;
52860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport junit.framework.TestCase;
53860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport libcore.io.IoUtils;
54860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport libcore.java.security.StandardNames;
55860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport libcore.java.security.TestKeyStore;
56860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport org.conscrypt.NativeCrypto.SSLHandshakeCallbacks;
57860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport static org.conscrypt.NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH;
58860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
59860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpublic class NativeCryptoTest extends TestCase {
60860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /** Corresponds to the native test library "libjavacoretests.so" */
61860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static final String TEST_ENGINE_ID = "javacoretests";
62860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
63860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final long NULL = 0;
64860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final FileDescriptor INVALID_FD = new FileDescriptor();
65860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final SSLHandshakeCallbacks DUMMY_CB
66860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            = new TestSSLHandshakeCallbacks(null, 0, null);
67860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
68860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final long TIMEOUT_SECONDS = 5;
69860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
70860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[] SERVER_PRIVATE_KEY;
71860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] SERVER_CERTIFICATES;
72860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[] CLIENT_PRIVATE_KEY;
73860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] CLIENT_CERTIFICATES;
74860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] CA_PRINCIPALS;
75860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static PrivateKey CHANNEL_ID_PRIVATE_KEY;
76860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[] CHANNEL_ID;
77860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
78860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    @Override
79860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    protected void tearDown() throws Exception {
80860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(0, NativeCrypto.ERR_peek_last_error());
81860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
82860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
83860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[] getServerPrivateKey() {
84860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
85860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return SERVER_PRIVATE_KEY;
86860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
87860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
88860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] getServerCertificates() {
89860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
90860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return SERVER_CERTIFICATES;
91860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
92860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
93860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[] getClientPrivateKey() {
94860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
95860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CLIENT_PRIVATE_KEY;
96860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
97860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
98860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] getClientCertificates() {
99860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
100860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CLIENT_CERTIFICATES;
101860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
102860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
103860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static byte[][] getCaPrincipals() {
104860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initCerts();
105860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return CA_PRINCIPALS;
106860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
107860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
108860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
109860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Lazily create shared test certificates.
110860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
111860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static synchronized void initCerts() {
112860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (SERVER_PRIVATE_KEY != null) {
113860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return;
114860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
115860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
116860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
117860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            PrivateKeyEntry serverPrivateKeyEntry
118860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
119860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            SERVER_PRIVATE_KEY = serverPrivateKeyEntry.getPrivateKey().getEncoded();
120860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            SERVER_CERTIFICATES = NativeCrypto.encodeCertificates(
121860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    serverPrivateKeyEntry.getCertificateChain());
122860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
123860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            PrivateKeyEntry clientPrivateKeyEntry
124860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
125860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CLIENT_PRIVATE_KEY = clientPrivateKeyEntry.getPrivateKey().getEncoded();
126860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CLIENT_CERTIFICATES = NativeCrypto.encodeCertificates(
127860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    clientPrivateKeyEntry.getCertificateChain());
128860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
129860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            KeyStore ks = TestKeyStore.getClient().keyStore;
130860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            String caCertAlias = ks.aliases().nextElement();
131860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias);
132860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            X500Principal principal = certificate.getIssuerX500Principal();
133860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            CA_PRINCIPALS = new byte[][] { principal.getEncoded() };
134860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            initChannelIdKey();
135860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (Exception e) {
136860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throw new RuntimeException(e);
137860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
138860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
139860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
140860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static synchronized void initChannelIdKey() throws Exception {
141860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (CHANNEL_ID_PRIVATE_KEY != null) {
142860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return;
143860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
144860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
145860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1
146860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1");
147860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        BigInteger s = new BigInteger(
148860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16);
149860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey(
150860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec()));
151860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
152860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Channel ID is the concatenation of the X and Y coordinates of the public key.
153860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        CHANNEL_ID = new BigInteger(
154860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" +
155860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77",
156860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                16).toByteArray();
157860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
158860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
159860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void assertEqualSessions(long expected, long actual) {
160860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected),
161860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                              NativeCrypto.SSL_SESSION_session_id(actual));
162860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
163860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void assertEqualByteArrays(byte[] expected, byte[] actual) {
164860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(Arrays.toString(expected), Arrays.toString(actual));
165860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
166860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
167860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) {
168860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualByteArrays(expected, actual);
169860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
170860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void assertEqualCertificateChains(byte[][] expected, byte[][] actual) {
171860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualByteArrays(expected, actual);
172860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
173860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) {
174860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual));
175860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
176860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
177860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_PKEY_cmp() throws Exception {
178860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
179860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_PKEY_cmp(NULL, NULL);
180860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail("Should throw NullPointerException when arguments are NULL");
181860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
182860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
183860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
184860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
185860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        kpg.initialize(512);
186860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
187860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        KeyPair kp1 = kpg.generateKeyPair();
188860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate();
189860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
190860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        KeyPair kp2 = kpg.generateKeyPair();
191860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate();
192860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
193860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
194860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
195860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
196860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPublicExponent().toByteArray(),
197860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPrivateExponent().toByteArray(),
198860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPrimeP().toByteArray(),
199860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPrimeQ().toByteArray(),
200860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPrimeExponentP().toByteArray(),
201860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getPrimeExponentQ().toByteArray(),
202860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        privKey1.getCrtCoefficient().toByteArray());
203860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertNotSame(NULL, pkey1);
204860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
205860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            pkey1_copy = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
206860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPublicExponent().toByteArray(),
207860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPrivateExponent().toByteArray(),
208860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPrimeP().toByteArray(),
209860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPrimeQ().toByteArray(),
210860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPrimeExponentP().toByteArray(),
211860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getPrimeExponentQ().toByteArray(),
212860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey1.getCrtCoefficient().toByteArray());
213860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertNotSame(NULL, pkey1_copy);
214860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
215860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            pkey2 = NativeCrypto.EVP_PKEY_new_RSA(privKey2.getModulus().toByteArray(),
216860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPublicExponent().toByteArray(),
217860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPrivateExponent().toByteArray(),
218860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPrimeP().toByteArray(),
219860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPrimeQ().toByteArray(),
220860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPrimeExponentP().toByteArray(),
221860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getPrimeExponentQ().toByteArray(),
222860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    privKey2.getCrtCoefficient().toByteArray());
223860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertNotSame(NULL, pkey2);
224860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
225860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
226860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_cmp(pkey1, NULL);
227860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail("Should throw NullPointerException when arguments are NULL");
228860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
229860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
230860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
231860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
232860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_cmp(NULL, pkey1);
233860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail("Should throw NullPointerException when arguments are NULL");
234860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
235860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
236860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
237860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals("Same keys should be the equal", 1,
238860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1));
239860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
240860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals("Same keys should be the equal", 1,
241860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy));
242860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
243860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals("Different keys should not be equal", 0,
244860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2));
245860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
246860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (pkey1 != 0) {
247860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(pkey1);
248860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
249860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (pkey1_copy != 0) {
250860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(pkey1_copy);
251860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
252860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (pkey2 != 0) {
253860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(pkey2);
254860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
255860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
256860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
257860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
258860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_CTX_new() throws Exception {
259860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
260860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(c != NULL);
261860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c2 = NativeCrypto.SSL_CTX_new();
262860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(c != c2);
263860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
264860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c2);
265860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
266860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
267860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_CTX_free() throws Exception {
268860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
269860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(NULL);
270860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
271860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
272860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
273860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
274860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new());
275860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
276860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
277860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_CTX_set_session_id_context() throws Exception {
278860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] empty = new byte[0];
279860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
280860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_set_session_id_context(NULL, empty);
281860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
282860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
283860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
284860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
285860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
286860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_set_session_id_context(c, null);
287860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
288860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
289860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
290860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_set_session_id_context(c, empty);
291860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[32]);
292860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
293860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[33]);
294860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (IllegalArgumentException expected) {
295860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
296860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
297860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
298860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
299860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_new() throws Exception {
300860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
301860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
302860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
303860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(s != NULL);
304860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2
305860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
306860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1) == 0);
307860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0);
308860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0);
309860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
310860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s2 = NativeCrypto.SSL_new(c);
311860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(s != s2);
312860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s2);
313860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
314860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
315860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
316860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
317860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
318860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_use_certificate() throws Exception {
319860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
320860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_use_certificate(NULL, null);
321860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
322860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
323860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
324860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
325860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
326860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
327860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
328860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
329860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_use_certificate(s, null);
330860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
331860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
332860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
333860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
334860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_certificate(s, getServerCertificates());
335860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
336860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
337860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
338860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
339860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
340860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception {
341860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
342860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set1_tls_channel_id(NULL, null);
343860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
344860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
345860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
346860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
347860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
348860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
349860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
350860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
351860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set1_tls_channel_id(s, null);
352860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
353860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
354860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
355860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
356860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Use the key via the wrapper that decides whether to use PKCS#8 or native OpenSSL.
357860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set1_tls_channel_id(s, CHANNEL_ID_PRIVATE_KEY);
358860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
359860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Use the key via its PKCS#8 representation.
360860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("PKCS#8", CHANNEL_ID_PRIVATE_KEY.getFormat());
361860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] pkcs8EncodedKeyBytes = CHANNEL_ID_PRIVATE_KEY.getEncoded();
362860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNotNull(pkcs8EncodedKeyBytes);
363860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_PKCS8_PrivateKey_for_tls_channel_id(s, pkcs8EncodedKeyBytes);
364860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
365860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Use the key natively. This works because the initChannelIdKey method ensures that the
366860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // key is backed by OpenSSL.
367860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_OpenSSL_PrivateKey_for_tls_channel_id(
368860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                s,
369860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                ((OpenSSLECPrivateKey) CHANNEL_ID_PRIVATE_KEY).getOpenSSLKey().getPkeyContext());
370860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
371860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
372860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
373860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
374860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
375860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_use_PrivateKey() throws Exception {
376860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
377860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_use_PrivateKey(NULL, null);
378860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
379860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
380860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
381860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
382860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
383860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
384860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
385860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
386860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_use_PrivateKey(s, null);
387860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
388860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
389860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
390860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
391860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey());
392860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
393860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
394860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
395860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
396860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
397860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_check_private_key_null() throws Exception {
398860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
399860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_check_private_key(NULL);
400860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
401860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
402860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
403860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
404860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
405860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_check_private_key_no_key_no_cert() throws Exception {
406860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
407860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
408860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
409860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // neither private or certificate set
410860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
411860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_check_private_key(s);
412860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
413860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (SSLException expected) {
414860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
415860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
416860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
417860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
418860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
419860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
420860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_check_private_key_cert_then_key() throws Exception {
421860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
422860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
423860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
424860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // first certificate, then private
425860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_certificate(s, getServerCertificates());
426860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
427860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
428860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_check_private_key(s);
429860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
430860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (SSLException expected) {
431860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
432860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
433860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey());
434860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_check_private_key(s);
435860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
436860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
437860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
438860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
439860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_check_private_key_key_then_cert() throws Exception {
440860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
441860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
442860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
443860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // first private, then certificate
444860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey());
445860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
446860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
447860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_check_private_key(s);
448860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
449860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (SSLException expected) {
450860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
451860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
452860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_use_certificate(s, getServerCertificates());
453860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_check_private_key(s);
454860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
455860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
456860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
457860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
458860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
459860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_get_mode() throws Exception {
460860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
461860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_get_mode(NULL);
462860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
463860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
464860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
465860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
466860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
467860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
468860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(NativeCrypto.SSL_get_mode(s) != 0);
469860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
470860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
471860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
472860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
473860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_mode_and_clear_mode() throws Exception {
474860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
475860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_mode(NULL, 0);
476860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
477860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
478860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
479860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
480860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
481860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
482860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default
483860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
484860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // set SSL_MODE_HANDSHAKE_CUTTHROUGH on
485860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
486860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_mode(s)
487860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                & SSL_MODE_HANDSHAKE_CUTTHROUGH) != 0);
488860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // clear SSL_MODE_HANDSHAKE_CUTTHROUGH off
489860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
490860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_mode(s)
491860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    & SSL_MODE_HANDSHAKE_CUTTHROUGH) == 0);
492860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
493860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
494860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
495860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
496860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
497860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_get_options() throws Exception {
498860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
499860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_get_options(NULL);
500860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
501860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
502860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
503860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
504860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
505860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
506860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(NativeCrypto.SSL_get_options(s) != 0);
507860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
508860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
509860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
510860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
511860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_options() throws Exception {
512860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
513860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_options(NULL, 0);
514860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
515860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
516860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
517860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
518860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
519860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
520860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
521860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
522860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
523860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
524860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
525860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
526860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
527860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_clear_options() throws Exception {
528860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
529860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_clear_options(NULL, 0);
530860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
531860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
532860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
533860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
534860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
535860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
536860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
537860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
538860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
539860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_clear_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
540860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
541860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
542860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
543860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
544860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
545860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_cipher_lists() throws Exception {
546860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
547860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_cipher_lists(NULL, null);
548860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
549860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
550860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
551860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
552860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
553860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
554860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
555860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
556860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_cipher_lists(s, null);
557860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
558860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
559860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
560860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
561860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_cipher_lists(s, new String[] {});
562860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
563860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
564860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_cipher_lists(s, new String[] { null });
565860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
566860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
567860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
568860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
569860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // see OpenSSL ciphers man page
570860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        String[] illegals = new String[] {
571860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // empty
572860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            "",
573860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // never standardized
574860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            "EXP1024-DES-CBC-SHA", "EXP1024-RC4-SHA", "DHE-DSS-RC4-SHA",
575860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // IDEA
576860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            "IDEA-CBC-SHA", "IDEA-CBC-MD5"
577860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
578860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
579860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        for (String illegal : illegals) {
580860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
581860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_cipher_lists(s, new String[] { illegal });
582860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail(illegal);
583860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (IllegalArgumentException expected) {
584860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
585860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
586860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
587860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        List<String> ciphers
588860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                = new ArrayList<String>(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.keySet());
589860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_cipher_lists(s, ciphers.toArray(new String[ciphers.size()]));
590860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
591860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
592860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
593860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
594860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
595860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_verify() throws Exception {
596860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
597860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_verify(NULL, 0);
598860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
599860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
600860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
601860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
602860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
603860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
604860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE);
605860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
606860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
607860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_set_verify(s, (NativeCrypto.SSL_VERIFY_PEER
608860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                        | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
609860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
610860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
611860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
612860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
613860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final boolean DEBUG = false;
614860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
615860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static class Hooks {
616860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private PrivateKey channelIdPrivateKey;
617860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
618860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public long getContext() throws SSLException {
619860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return NativeCrypto.SSL_CTX_new();
620860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
621860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public long beforeHandshake(long context) throws SSLException {
622860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(context);
623860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // without this SSL_set_cipher_lists call the tests were
624860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // negotiating DHE-RSA-AES256-SHA by default which had
625860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // very slow ephemeral RSA key generation
626860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_cipher_lists(s, new String[] { "RC4-MD5" });
627860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
628860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (channelIdPrivateKey != null) {
629860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set1_tls_channel_id(s, channelIdPrivateKey);
630860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
631860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return s;
632860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
633860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void clientCertificateRequested(long s) {}
634860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void afterHandshake(long session, long ssl, long context,
635860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   Socket socket, FileDescriptor fd,
636860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   SSLHandshakeCallbacks callback)
637860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throws Exception {
638860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (session != NULL) {
639860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_SESSION_free(session);
640860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
641860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (ssl != NULL) {
642860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                try {
643860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_shutdown(ssl, fd, callback);
644860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                } catch (IOException e) {
645860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
646860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_free(ssl);
647860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
648860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (context != NULL) {
649860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_CTX_free(context);
650860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
651860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (socket != null) {
652860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                socket.close();
653860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
654860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
655860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
656860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
657860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
658860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private final Socket socket;
659860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private final long sslNativePointer;
660860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private final Hooks hooks;
661860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
662860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public TestSSLHandshakeCallbacks(Socket socket,
663860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                         long sslNativePointer,
664860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                         Hooks hooks) {
665860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.socket = socket;
666860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.sslNativePointer = sslNativePointer;
667860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.hooks = hooks;
668860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
669860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
670860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public byte[][] asn1DerEncodedCertificateChain;
671860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public String authMethod;
672860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public boolean verifyCertificateChainCalled;
673860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
674860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain,
675860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           String authMethod)
676860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throws CertificateException {
677860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (DEBUG) {
678860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
679860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " verifyCertificateChain"
680860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " asn1DerEncodedCertificateChain="
681860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + asn1DerEncodedCertificateChain
682860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " authMethod=" + authMethod);
683860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
684860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.asn1DerEncodedCertificateChain = asn1DerEncodedCertificateChain;
685860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.authMethod = authMethod;
686860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.verifyCertificateChainCalled = true;
687860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
688860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
689860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public byte[] keyTypes;
690860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public byte[][] asn1DerEncodedX500Principals;
691860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public boolean clientCertificateRequestedCalled;
692860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void clientCertificateRequested(byte[] keyTypes,
693860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               byte[][] asn1DerEncodedX500Principals) {
694860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (DEBUG) {
695860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
696860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " clientCertificateRequested"
697860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " keyTypes=" + keyTypes
698860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " asn1DerEncodedX500Principals="
699860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + asn1DerEncodedX500Principals);
700860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
701860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.keyTypes = keyTypes;
702860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals;
703860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.clientCertificateRequestedCalled = true;
704860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (hooks != null ) {
705860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                hooks.clientCertificateRequested(sslNativePointer);
706860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
707860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
708860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
709860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public boolean handshakeCompletedCalled;
710860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void handshakeCompleted() {
711860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (DEBUG) {
712860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
713860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   + " handshakeCompleted");
714860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
715860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.handshakeCompletedCalled = true;
716860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
717860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
718860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public Socket getSocket() {
719860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return socket;
720860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
721860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
722860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
723860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static class ServerHooks extends Hooks {
724860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private final byte[] privateKey;
725860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private final byte[][] certificates;
726860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private boolean channelIdEnabled;
727860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private byte[] channelIdAfterHandshake;
728860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        private Throwable channelIdAfterHandshakeException;
729860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
730860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public ServerHooks(byte[] privateKey, byte[][] certificates) {
731860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.privateKey = privateKey;
732860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            this.certificates = certificates;
733860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
734860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
735860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        @Override
736860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public long beforeHandshake(long c) throws SSLException {
737860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = super.beforeHandshake(c);
738860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (privateKey != null) {
739860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_use_PrivateKey(s, privateKey);
740860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
741860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (certificates != null) {
742860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_use_certificate(s, certificates);
743860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
744860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (channelIdEnabled) {
745860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_enable_tls_channel_id(s);
746860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
747860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return s;
748860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
749860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
750860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        @Override
751860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void afterHandshake(long session, long ssl, long context,
752860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   Socket socket, FileDescriptor fd,
753860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                   SSLHandshakeCallbacks callback)
754860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throws Exception {
755860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root          if (channelIdEnabled) {
756860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
757860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root              channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl);
758860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (Exception e) {
759860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root              channelIdAfterHandshakeException = e;
760860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
761860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root          }
762860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root          super.afterHandshake(session, ssl, context, socket, fd, callback);
763860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
764860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
765860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        public void clientCertificateRequested(long s) {
766860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail("Server asked for client certificates");
767860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
768860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
769860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
770860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener,
771860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final int timeout, final boolean client, final Hooks hooks, final byte[] npnProtocols) {
772860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ExecutorService executor = Executors.newSingleThreadExecutor();
773860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> future = executor.submit(
774860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                new Callable<TestSSLHandshakeCallbacks>() {
775860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override public TestSSLHandshakeCallbacks call() throws Exception {
776860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Socket socket = (client
777860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                 ? new Socket(listener.getInetAddress(),
778860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                              listener.getLocalPort())
779860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                 : listener.accept());
780860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                if (timeout == -1) {
781860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    return new TestSSLHandshakeCallbacks(socket, 0, null);
782860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
783860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                FileDescriptor fd = socket.getFileDescriptor$();
784860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long c = hooks.getContext();
785860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long s = hooks.beforeHandshake(c);
786860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                TestSSLHandshakeCallbacks callback
787860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        = new TestSSLHandshakeCallbacks(socket, s, hooks);
788860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                if (DEBUG) {
789860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    System.out.println("ssl=0x" + Long.toString(s, 16)
790860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " handshake"
791860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " context=0x" + Long.toString(c, 16)
792860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " socket=" + socket
793860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " fd=" + fd
794860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " timeout=" + timeout
795860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       + " client=" + client);
796860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
797860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long session = NULL;
798860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                try {
799860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
800860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                            npnProtocols);
801860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    if (DEBUG) {
802860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        System.out.println("ssl=0x" + Long.toString(s, 16)
803860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           + " handshake"
804860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           + " session=0x" + Long.toString(session, 16));
805860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
806860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                } finally {
807860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    // Ensure afterHandshake is called to free resources
808860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    hooks.afterHandshake(session, s, c, socket, fd, callback);
809860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
810860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return callback;
811860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
812860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        });
813860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        executor.shutdown();
814860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        return future;
815860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
816860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
817860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_NULL_SSL() throws Exception {
818860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
819860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_do_handshake(NULL, null, null, 0, false, null);
820860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
821860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
822860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
823860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
824860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
825860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_null_args() throws Exception {
826860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
827860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
828860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
829860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
830860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null);
831860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
832860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
833860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
834860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
835860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
836860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_do_handshake(s, INVALID_FD, null, 0, true, null);
837860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
838860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
839860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
840860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
841860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
842860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
843860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
844860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
845860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_normal() throws Exception {
846860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // normal client and server case
847860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
848860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks();
849860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
850860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
851860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
852860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
853860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
854860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.verifyCertificateChainCalled);
855860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getServerCertificates(),
856860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                     clientCallback.asn1DerEncodedCertificateChain);
857860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", clientCallback.authMethod);
858860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.verifyCertificateChainCalled);
859860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(clientCallback.clientCertificateRequestedCalled);
860860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.clientCertificateRequestedCalled);
861860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.handshakeCompletedCalled);
862860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.handshakeCompletedCalled);
863860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
864860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
865860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_optional_client_certificate() throws Exception {
866860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // optional client certificate case
867860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
868860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
869860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
870860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
871860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void clientCertificateRequested(long s) {
872860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.clientCertificateRequested(s);
873860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey());
874860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_use_certificate(s, getClientCertificates());
875860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
876860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
877860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
878860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
879860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public long beforeHandshake(long c) throws SSLException {
880860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long s = super.beforeHandshake(c);
881860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
882860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
883860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return s;
884860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
885860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
886860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
887860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
888860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
889860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
890860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.verifyCertificateChainCalled);
891860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getServerCertificates(),
892860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                     clientCallback.asn1DerEncodedCertificateChain);
893860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", clientCallback.authMethod);
894860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.verifyCertificateChainCalled);
895860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getClientCertificates(),
896860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                serverCallback.asn1DerEncodedCertificateChain);
897860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", serverCallback.authMethod);
898860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
899860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.clientCertificateRequestedCalled);
900860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNotNull(clientCallback.keyTypes);
901860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // this depends on the SSL_set_cipher_lists call in beforeHandshake
902860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // the three returned are the non-ephemeral cases.
903860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(3, clientCallback.keyTypes.length);
904860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[0]));
905860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("DSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[1]));
906860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("EC", CipherSuite.getClientKeyType(clientCallback.keyTypes[2]));
907860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualPrincipals(getCaPrincipals(),
908860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                              clientCallback.asn1DerEncodedX500Principals);
909860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.clientCertificateRequestedCalled);
910860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
911860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.handshakeCompletedCalled);
912860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.handshakeCompletedCalled);
913860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
914860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
915860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_missing_required_certificate() throws Exception {
916860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // required client certificate negative case
917860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
918860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
919860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks();
920860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
921860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
922860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public long beforeHandshake(long c) throws SSLException {
923860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    long s = super.beforeHandshake(c);
924860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
925860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_verify(s,
926860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                NativeCrypto.SSL_VERIFY_PEER
927860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
928860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    return s;
929860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
930860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
931860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
932860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
933860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
934860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
935860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
936860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
937860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
938860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
939860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
940860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
941860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Usually if a RuntimeException is thrown by the
942860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * clientCertificateRequestedCalled callback, the caller sees it
943860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * during the call to NativeCrypto_SSL_do_handshake.  However, IIS
944860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * does not request client certs until after the initial
945860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * handshake. It does an SSL renegotiation, which means we need to
946860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * be able to deliver the callback's exception in cases like
947860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * SSL_read, SSL_write, and SSL_shutdown.
948860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
949860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate()
950860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            throws Exception {
951860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
952860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
953860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
954860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
955860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public long beforeHandshake(long context) throws SSLException {
956860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long s = super.beforeHandshake(context);
957860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
958860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return s;
959860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
960860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
961860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
962860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
963860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
964860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
965860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
966860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
967860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
968860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
969860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
970860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void clientCertificateRequested(long s) {
971860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.clientCertificateRequested(s);
972860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throw new RuntimeException("expected");
973860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
974860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
975860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
976860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
977860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
978860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
979860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
980860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
981860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                try {
982860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
983860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_options(
984860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
985860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_renegotiate(s);
986860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1,
987860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           (int) ((TIMEOUT_SECONDS * 1000) / 2));
988860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                } catch (IOException expected) {
989860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                } finally {
990860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    super.afterHandshake(session, s, c, sock, fd, callback);
991860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
992860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
993860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
994860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
995860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
996860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
997860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
998860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException e) {
999860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (!"expected".equals(e.getCause().getMessage())) {
1000860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throw e;
1001860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1002860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1003860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1004860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1005860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1006860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_client_timeout() throws Exception {
1007860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // client timeout
1008860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1009860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Socket serverSocket = null;
1010860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1011860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks();
1012860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1013860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null);
1014860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null);
1015860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
1016860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1017860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1018860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
1019860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (SocketTimeoutException.class != expected.getCause().getClass()) {
1020860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                expected.printStackTrace();
1021860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1022860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
1023860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
1024860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // Manually close peer socket when testing timeout
1025860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            IoUtils.closeQuietly(serverSocket);
1026860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1027860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1028860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1029860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_server_timeout() throws Exception {
1030860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // server timeout
1031860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1032860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Socket clientSocket = null;
1033860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1034860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks();
1035860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1036860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null);
1037860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null);
1038860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
1039860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1040860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1041860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
1042860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
1043860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
1044860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // Manually close peer socket when testing timeout
1045860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            IoUtils.closeQuietly(clientSocket);
1046860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1047860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1048860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1049860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_with_channel_id_normal() throws Exception {
1050860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initChannelIdKey();
1051860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1052860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Normal handshake with TLS Channel ID.
1053860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1054860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks();
1055860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
1056860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1057860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        sHooks.channelIdEnabled = true;
1058860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1059860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1060860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1061860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1062860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.verifyCertificateChainCalled);
1063860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getServerCertificates(),
1064860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                     clientCallback.asn1DerEncodedCertificateChain);
1065860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", clientCallback.authMethod);
1066860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.verifyCertificateChainCalled);
1067860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(clientCallback.clientCertificateRequestedCalled);
1068860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.clientCertificateRequestedCalled);
1069860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.handshakeCompletedCalled);
1070860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.handshakeCompletedCalled);
1071860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(sHooks.channelIdAfterHandshakeException);
1072860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake);
1073860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1074860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1075860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception {
1076860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initChannelIdKey();
1077860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1078860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Client tries to use TLS Channel ID but the server does not enable/offer the extension.
1079860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1080860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks();
1081860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
1082860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1083860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        sHooks.channelIdEnabled = false;
1084860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1085860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1086860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1087860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1088860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.verifyCertificateChainCalled);
1089860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getServerCertificates(),
1090860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                     clientCallback.asn1DerEncodedCertificateChain);
1091860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", clientCallback.authMethod);
1092860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.verifyCertificateChainCalled);
1093860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(clientCallback.clientCertificateRequestedCalled);
1094860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.clientCertificateRequestedCalled);
1095860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.handshakeCompletedCalled);
1096860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.handshakeCompletedCalled);
1097860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(sHooks.channelIdAfterHandshakeException);
1098860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(sHooks.channelIdAfterHandshake);
1099860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1100860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1101860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception {
1102860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        initChannelIdKey();
1103860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1104860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Client does not use TLS Channel ID when the server has the extension enabled/offered.
1105860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1106860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks();
1107860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        cHooks.channelIdPrivateKey = null;
1108860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1109860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        sHooks.channelIdEnabled = true;
1110860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1111860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1112860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1113860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1114860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.verifyCertificateChainCalled);
1115860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEqualCertificateChains(getServerCertificates(),
1116860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                     clientCallback.asn1DerEncodedCertificateChain);
1117860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals("RSA", clientCallback.authMethod);
1118860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.verifyCertificateChainCalled);
1119860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(clientCallback.clientCertificateRequestedCalled);
1120860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse(serverCallback.clientCertificateRequestedCalled);
1121860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(clientCallback.handshakeCompletedCalled);
1122860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(serverCallback.handshakeCompletedCalled);
1123860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(sHooks.channelIdAfterHandshakeException);
1124860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(sHooks.channelIdAfterHandshake);
1125860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1126860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1127860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_session() throws Exception {
1128860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1129860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_session(NULL, NULL);
1130860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1131860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1132860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1133860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1134860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1135860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1136860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1137860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_session(s, NULL);
1138860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1139860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1140860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1141860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1142860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1143860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long clientContext = NativeCrypto.SSL_CTX_new();
1144860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long serverContext = NativeCrypto.SSL_CTX_new();
1145860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final ServerSocket listener = new ServerSocket(0);
1146860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long[] clientSession = new long[] { NULL };
1147860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long[] serverSession = new long[] { NULL };
1148860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            {
1149860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Hooks cHooks = new Hooks() {
1150860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1151860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public long getContext() throws SSLException {
1152860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        return clientContext;
1153860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1154860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1155860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public void afterHandshake(long session, long s, long c,
1156860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               Socket sock, FileDescriptor fd,
1157860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               SSLHandshakeCallbacks callback)
1158860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            throws Exception {
1159860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
1160860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        clientSession[0] = session;
1161860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1162860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                };
1163860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1164860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1165860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public long getContext() throws SSLException {
1166860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        return serverContext;
1167860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1168860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1169860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public void afterHandshake(long session, long s, long c,
1170860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               Socket sock, FileDescriptor fd,
1171860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               SSLHandshakeCallbacks callback)
1172860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            throws Exception {
1173860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
1174860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        serverSession[0] = session;
1175860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1176860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                };
1177860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Future<TestSSLHandshakeCallbacks> client
1178860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        = handshake(listener, 0, true, cHooks, null);
1179860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Future<TestSSLHandshakeCallbacks> server
1180860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        = handshake(listener, 0, false, sHooks, null);
1181860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1182860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1183860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1184860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEqualSessions(clientSession[0], serverSession[0]);
1185860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            {
1186860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Hooks cHooks = new Hooks() {
1187860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1188860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public long getContext() throws SSLException {
1189860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        return clientContext;
1190860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1191860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1192860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public long beforeHandshake(long c) throws SSLException {
1193860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        long s = NativeCrypto.SSL_new(clientContext);
1194860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        NativeCrypto.SSL_set_session(s, clientSession[0]);
1195860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        return s;
1196860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1197860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1198860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public void afterHandshake(long session, long s, long c,
1199860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               Socket sock, FileDescriptor fd,
1200860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               SSLHandshakeCallbacks callback)
1201860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            throws Exception {
1202860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        assertEqualSessions(clientSession[0], session);
1203860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
1204860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1205860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                };
1206860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1207860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1208860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public long getContext() throws SSLException {
1209860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        return serverContext;
1210860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1211860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    @Override
1212860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public void afterHandshake(long session, long s, long c,
1213860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               Socket sock, FileDescriptor fd,
1214860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                               SSLHandshakeCallbacks callback)
1215860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            throws Exception {
1216860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        assertEqualSessions(serverSession[0], session);
1217860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
1218860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1219860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                };
1220860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Future<TestSSLHandshakeCallbacks> client
1221860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        = handshake(listener, 0, true, cHooks, null);
1222860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Future<TestSSLHandshakeCallbacks> server
1223860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        = handshake(listener, 0, false, sHooks, null);
1224860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1225860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1226860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1227860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_free(clientSession[0]);
1228860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_free(serverSession[0]);
1229860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(serverContext);
1230860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(clientContext);
1231860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1232860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1233860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1234860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_session_creation_enabled() throws Exception {
1235860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1236860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_session_creation_enabled(NULL, false);
1237860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1238860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1239860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1240860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1241860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1242860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1243860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1244860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_session_creation_enabled(s, false);
1245860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_session_creation_enabled(s, true);
1246860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1247860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1248860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1249860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1250860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1251860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1252860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // negative test case for SSL_set_session_creation_enabled(false) on client
1253860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1254860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks() {
1255860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1256860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public long beforeHandshake(long c) throws SSLException {
1257860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    long s = super.beforeHandshake(c);
1258860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_session_creation_enabled(s, false);
1259860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    return s;
1260860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1261860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1262860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1263860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1264860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1265860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1266860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1267860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
1268860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
1269860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1270860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1271860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // negative test case for SSL_set_session_creation_enabled(false) on server
1272860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1273860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks();
1274860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1275860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1276860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public long beforeHandshake(long c) throws SSLException {
1277860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    long s = super.beforeHandshake(c);
1278860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_set_session_creation_enabled(s, false);
1279860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    return s;
1280860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1281860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1282860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1283860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1284860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1285860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1286860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
1287860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
1288860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1289860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1290860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1291860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_set_tlsext_host_name() throws Exception {
1292860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // NULL SSL
1293860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1294860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_tlsext_host_name(NULL, null);
1295860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1296860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1297860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1298860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1299860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final String hostname = "www.android.com";
1300860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1301860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1302860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1303860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1304860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1305860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // null hostname
1306860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1307860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_tlsext_host_name(s, null);
1308860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1309860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1310860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1311860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1312860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // too long hostname
1313860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1314860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                char[] longHostname = new char[256];
1315860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                Arrays.fill(longHostname, 'w');
1316860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_tlsext_host_name(s, new String(longHostname));
1317860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1318860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (SSLException expected) {
1319860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1320860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1321860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertNull(NativeCrypto.SSL_get_servername(s));
1322860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_set_tlsext_host_name(s, new String(hostname));
1323860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
1324860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1325860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1326860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1327860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1328860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1329860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1330860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1331860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // normal
1332860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1333860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1334860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public long beforeHandshake(long c) throws SSLException {
1335860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long s = super.beforeHandshake(c);
1336860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_set_tlsext_host_name(s, hostname);
1337860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return s;
1338860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1339860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1340860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1341860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1342860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1343860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1344860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1345860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1346860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
1347860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1348860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1349860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1350860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1351860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1352860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1353860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1354860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1355860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1356860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_NpnNegotiateSuccess() throws Exception {
1357860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final byte[] clientNpnProtocols = new byte[] {
1358860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                8, 'h', 't', 't', 'p', '/', '1', '.', '1',
1359860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                3, 'f', 'o', 'o',
1360860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                6, 's', 'p', 'd', 'y', '/', '2',
1361860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1362860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final byte[] serverNpnProtocols = new byte[] {
1363860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                6, 's', 'p', 'd', 'y', '/', '2',
1364860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                3, 'f', 'o', 'o',
1365860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                3, 'b', 'a', 'r',
1366860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1367860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1368860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1369860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override public long beforeHandshake(long context) throws SSLException {
1370860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_CTX_enable_npn(context);
1371860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return super.beforeHandshake(context);
1372860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1373860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
1374860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
1375860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
1376860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals("spdy/2", new String(negotiated));
1377860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue("NPN should enable cutthrough on the client",
1378860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        0 != (NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH));
1379860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, ssl, context, socket, fd, callback);
1380860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1381860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1382860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1383860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override public long beforeHandshake(long context) throws SSLException {
1384860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_CTX_enable_npn(context);
1385860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                return super.beforeHandshake(context);
1386860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1387860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
1388860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
1389860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
1390860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals("spdy/2", new String(negotiated));
1391860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals("NPN should not enable cutthrough on the server",
1392860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
1393860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, ssl, c, sock, fd, callback);
1394860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1395860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1396860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1397860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ServerSocket listener = new ServerSocket(0);
1398860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client
1399860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                = handshake(listener, 0, true, cHooks, clientNpnProtocols);
1400860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server
1401860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                = handshake(listener, 0, false, sHooks, serverNpnProtocols);
1402860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1403860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1404860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1405860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1406860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_get_servername_null() throws Exception {
1407860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // NULL SSL
1408860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1409860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_get_servername(NULL);
1410860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1411860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1412860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1413860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1414860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
1415860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
1416860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertNull(NativeCrypto.SSL_get_servername(s));
1417860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
1418860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
1419860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1420860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // additional positive testing by test_SSL_set_tlsext_host_name
1421860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1422860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1423860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_renegotiate() throws Exception {
1424860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1425860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_renegotiate(NULL);
1426860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1427860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1428860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1429860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1430860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1431860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1432860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1433860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1434860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1435860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1436860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1437860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[] buffer = new byte[1];
1438860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, fd, callback, buffer, 0, 1, 0);
1439860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(42, buffer[0]);
1440860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1441860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1442860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1443860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1444860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1445860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1446860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1447860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1448860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throws Exception {
1449860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_renegotiate(s);
1450860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0);
1451860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1452860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1453860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1454860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1455860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1456860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1457860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1458860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1459860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1460860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_get_certificate() throws Exception {
1461860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1462860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_get_certificate(NULL);
1463860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1464860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1465860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1466860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1467860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1468860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1469860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1470860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1471860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1472860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1473860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                throws Exception {
1474860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertNull(NativeCrypto.SSL_get_certificate(s));
1475860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1476860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1477860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1478860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1479860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1480860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1481860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1482860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1483860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1484860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEqualCertificateChains(
1485860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                             getServerCertificates(),
1486860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                             NativeCrypto.SSL_get_certificate(s));
1487860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1488860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1489860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1490860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1491860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1492860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1493860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1494860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1495860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1496860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_get_peer_cert_chain() throws Exception {
1497860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1498860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_get_peer_cert_chain(NULL);
1499860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1500860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1501860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1502860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1503860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1504860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1505860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1506860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1507860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1508860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1509860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1510860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1511860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[][] cc = NativeCrypto.SSL_get_peer_cert_chain(s);
1512860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEqualCertificateChains(getServerCertificates(), cc);
1513860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1514860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1515860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1516860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1517860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1518860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1519860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1520860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1521860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1522860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1523860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    final byte[] BYTES = new byte[] { 2, -3, 5, 127, 0, -128 };
1524860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1525860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_read() throws Exception {
1526860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1527860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // NULL ssl
1528860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1529860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_read(NULL, null, null, null, 0, 0, 0);
1530860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1531860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1532860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1533860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1534860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null FileDescriptor
1535860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1536860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1537860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1538860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1539860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0);
1540860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1541860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1542860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1543860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1544860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1545860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1546860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1547860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null SSLHandshakeCallbacks
1548860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1549860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1550860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1551860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1552860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0);
1553860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1554860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1555860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1556860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1557860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1558860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1559860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1560860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null byte array
1561860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1562860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1563860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1564860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1565860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0);
1566860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1567860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1568860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1569860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1570860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1571860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1572860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1573860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // handshaking not yet performed
1574860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1575860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1576860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1577860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1578860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
1579860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1580860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (SSLException expected) {
1581860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1582860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1583860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1584860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1585860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1586860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1587860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1588860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // normal case
1589860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1590860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks() {
1591860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1592860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public void afterHandshake(long session, long s, long c,
1593860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           Socket sock, FileDescriptor fd,
1594860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           SSLHandshakeCallbacks callback)
1595860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1596860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    byte[] in = new byte[256];
1597860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    assertEquals(BYTES.length,
1598860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                 NativeCrypto.SSL_read(s,
1599860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       fd,
1600860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       callback,
1601860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       in,
1602860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       0,
1603860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       BYTES.length,
1604860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                                       0));
1605860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    for (int i = 0; i < BYTES.length; i++) {
1606860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        assertEquals(BYTES[i], in[i]);
1607860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1608860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    super.afterHandshake(session, s, c, sock, fd, callback);
1609860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1610860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1611860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1612860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1613860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public void afterHandshake(long session, long s, long c,
1614860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           Socket sock, FileDescriptor fd,
1615860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           SSLHandshakeCallbacks callback)
1616860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1617860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0);
1618860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    super.afterHandshake(session, s, c, sock, fd, callback);
1619860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1620860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1621860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1622860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1623860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1624860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1625860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1626860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1627860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // timeout case
1628860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1629860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks() {
1630860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1631860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public void afterHandshake(long session, long s, long c,
1632860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           Socket sock, FileDescriptor fd,
1633860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           SSLHandshakeCallbacks callback)
1634860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1635860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 1);
1636860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    fail();
1637860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1638860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1639860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1640860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1641860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public void afterHandshake(long session, long s, long c,
1642860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           Socket sock, FileDescriptor fd,
1643860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           SSLHandshakeCallbacks callback)
1644860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1645860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
1646860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    super.afterHandshake(session, s, c, sock, fd, callback);
1647860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1648860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1649860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1650860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1651860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1652860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1653860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (ExecutionException expected) {
1654860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
1655860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1656860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1657860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1658860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_write() throws Exception {
1659860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1660860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0);
1661860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1662860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1663860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1664860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1665860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null FileDescriptor
1666860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1667860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1668860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1669860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1670860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0);
1671860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1672860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1673860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1674860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1675860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1676860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1677860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1678860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null SSLHandshakeCallbacks
1679860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1680860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1681860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1682860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1683860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0);
1684860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1685860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1686860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1687860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1688860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1689860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1690860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1691860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null byte array
1692860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1693860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1694860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1695860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1696860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
1697860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1698860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
1699860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1700860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1701860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1702860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1703860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1704860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // handshaking not yet performed
1705860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1706860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1707860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1708860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
1709860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
1710860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
1711860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (SSLException expected) {
1712860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1713860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1714860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1715860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1716860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1717860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // positively tested by test_SSL_read
1718860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1719860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1720860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_interrupt() throws Exception {
1721860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // SSL_interrupt is a rare case that tolerates a null SSL argument
1722860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_interrupt(NULL);
1723860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1724860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // also works without handshaking
1725860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1726860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long c = NativeCrypto.SSL_CTX_new();
1727860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long s = NativeCrypto.SSL_new(c);
1728860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_interrupt(s);
1729860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(s);
1730860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_CTX_free(c);
1731860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1732860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1733860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1734860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1735860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1736860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1737860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1738860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1739860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1740860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1741860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
1742860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1743860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1744860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1745860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
1746860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1747860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, final long s, long c,
1748860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1749860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1750860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1751860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                new Thread() {
1752860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    public void run() {
1753860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        try {
1754860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            Thread.sleep(1*1000);
1755860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                            NativeCrypto.SSL_interrupt(s);
1756860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        } catch (Exception e) {
1757860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        }
1758860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    }
1759860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }.start();
1760860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(-1, NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0));
1761860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1762860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1763860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1764860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1765860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1766860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1767860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1768860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1769860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1770860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_shutdown() throws Exception {
1771860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1772860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null FileDescriptor
1773860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1774860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_shutdown(NULL, null, DUMMY_CB);
1775860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1776860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1777860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1778860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // null SSLHandshakeCallbacks
1779860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1780860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_shutdown(NULL, INVALID_FD, null);
1781860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1782860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1783860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1784860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // SSL_shutdown is a rare case that tolerates a null SSL argument
1785860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB);
1786860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1787860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // handshaking not yet performed
1788860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
1789860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long s = NativeCrypto.SSL_new(c);
1790860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1791860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_shutdown(s, INVALID_FD, DUMMY_CB);
1792860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (SSLProtocolException expected) {
1793860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1794860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(s);
1795860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
1796860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1797860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // positively tested elsewhere because handshake uses use
1798860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // SSL_shutdown to ensure SSL_SESSIONs are reused.
1799860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1800860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1801860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_free() throws Exception {
1802860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1803860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_free(NULL);
1804860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1805860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1806860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1807860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1808860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long c = NativeCrypto.SSL_CTX_new();
1809860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_free(NativeCrypto.SSL_new(c));
1810860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.SSL_CTX_free(c);
1811860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1812860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // additional positive testing elsewhere because handshake
1813860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // uses use SSL_free to cleanup in afterHandshake.
1814860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1815860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1816860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_SESSION_session_id() throws Exception {
1817860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1818860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_session_id(NULL);
1819860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1820860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1821860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1822860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1823860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1824860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1825860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1826860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1827860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1828860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1829860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1830860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1831860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[] id = NativeCrypto.SSL_SESSION_session_id(session);
1832860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertNotNull(id);
1833860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(32, id.length);
1834860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1835860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1836860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1837860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1838860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1839860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1840860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1841860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1842860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1843860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1844860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_SESSION_get_time() throws Exception {
1845860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1846860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_get_time(NULL);
1847860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1848860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1849860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1850860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1851860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1852860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1853860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
1854860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks cHooks = new Hooks() {
1855860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                @Override
1856860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                public void afterHandshake(long session, long s, long c,
1857860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           Socket sock, FileDescriptor fd,
1858860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                           SSLHandshakeCallbacks callback)
1859860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1860860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    long time = NativeCrypto.SSL_SESSION_get_time(session);
1861860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    assertTrue(time != 0);
1862860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    assertTrue(time < System.currentTimeMillis());
1863860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    super.afterHandshake(session, s, c, sock, fd, callback);
1864860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
1865860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            };
1866860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1867860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1868860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1869860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1870860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1871860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1872860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1873860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1874860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_SESSION_get_version() throws Exception {
1875860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1876860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_get_version(NULL);
1877860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1878860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1879860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1880860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1881860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1882860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1883860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1884860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1885860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1886860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1887860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1888860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1889860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                String v = NativeCrypto.SSL_SESSION_get_version(session);
1890860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v));
1891860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1892860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1893860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1894860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1895860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1896860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1897860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1898860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1899860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1900860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1901860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_SESSION_cipher() throws Exception {
1902860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1903860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_cipher(NULL);
1904860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1905860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1906860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1907860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1908860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1909860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1910860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1911860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1912860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1913860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1914860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1915860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        throws Exception {
1916860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                String a = NativeCrypto.SSL_SESSION_cipher(session);
1917860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(a));
1918860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1919860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1920860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1921860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1922860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1923860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1924860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1925860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1926860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1927860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1928860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_SSL_SESSION_free() throws Exception {
1929860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1930860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.SSL_SESSION_free(NULL);
1931860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1932860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1933860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1934860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1935860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // additional positive testing elsewhere because handshake
1936860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // uses use SSL_SESSION_free to cleanup in afterHandshake.
1937860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1938860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1939860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_i2d_SSL_SESSION() throws Exception {
1940860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1941860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.i2d_SSL_SESSION(NULL);
1942860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1943860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1944860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1945860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1946860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final ServerSocket listener = new ServerSocket(0);
1947860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1948860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks cHooks = new Hooks() {
1949860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            @Override
1950860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            public void afterHandshake(long session, long s, long c,
1951860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       Socket sock, FileDescriptor fd,
1952860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                                       SSLHandshakeCallbacks callback)
1953860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    throws Exception {
1954860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                byte[] b = NativeCrypto.i2d_SSL_SESSION(session);
1955860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertNotNull(b);
1956860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                long session2 = NativeCrypto.d2i_SSL_SESSION(b);
1957860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(session2 != NULL);
1958860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1959860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840
1960860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null);
1961860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(NativeCrypto.SSL_SESSION_cipher(session),
1962860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                             NativeCrypto.SSL_SESSION_cipher(session2));
1963860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1964860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.SSL_SESSION_free(session2);
1965860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                super.afterHandshake(session, s, c, sock, fd, callback);
1966860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
1967860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        };
1968860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
1969860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
1970860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
1971860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1972860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
1973860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1974860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1975860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_d2i_SSL_SESSION() throws Exception {
1976860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
1977860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.d2i_SSL_SESSION(null);
1978860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
1979860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
1980860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
1981860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1982860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[0]));
1983860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[1]));
1984860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1985860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // positive testing by test_i2d_SSL_SESSION
1986860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1987860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1988860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_X509_NAME_hashes() {
1989860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // ensure these hash functions are stable over time since the
1990860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // /system/etc/security/cacerts CA filenames have to be
1991860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // consistent with the output.
1992860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        X500Principal name = new X500Principal("CN=localhost");
1993860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1
1994860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5
1995860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
1996860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
1997860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_ENGINE_by_id_Failure() throws Exception {
1998860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.ENGINE_load_dynamic();
1999860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2000860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long engine = NativeCrypto.ENGINE_by_id("non-existent");
2001860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (engine != 0) {
2002860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.ENGINE_finish(engine);
2003860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail("should not acquire reference to non-existent engine");
2004860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2005860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2006860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2007860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /**
2008860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Loads the test OpenSSL ENGINE. If it's already loaded, returns
2009860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * immediately.
2010860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
2011860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public static void loadTestEngine() throws Exception {
2012860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
2013860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (testEngine != 0) {
2014860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.ENGINE_finish(testEngine);
2015860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            return;
2016860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2017860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2018860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.ENGINE_load_dynamic();
2019860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long dynEngine = NativeCrypto.ENGINE_by_id("dynamic");
2020860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2021860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ClassLoader loader = NativeCryptoTest.class.getClassLoader();
2022860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2023860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final String libraryPaths;
2024860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (loader instanceof BaseDexClassLoader) {
2025860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                libraryPaths = ((BaseDexClassLoader) loader).getLdLibraryPath();
2026860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } else {
2027860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                libraryPaths = System.getProperty("java.library.path");
2028860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2029860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertNotNull(libraryPaths);
2030860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2031860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            String[] libraryPathArray = libraryPaths.split(":");
2032860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            for (String path : libraryPathArray) {
2033860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "DIR_ADD", path, 0));
2034860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2035860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2036860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // We must add this to the list of ENGINEs
2037860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LIST_ADD", "2", 0));
2038860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2039860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // Do a direct load of the ENGINE.
2040860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(1,
2041860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "ID", TEST_ENGINE_ID, 0));
2042860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LOAD", null, 0));
2043860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2044860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.ENGINE_finish(dynEngine);
2045860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2046860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2047860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
2048860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        if (testEngine == 0) {
2049860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail("could not load test engine");
2050860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2051860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.ENGINE_finish(testEngine);
2052860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2053860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2054860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_ENGINE_by_id_TestEngine() throws Exception {
2055860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        loadTestEngine();
2056860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2057860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
2058860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(engine != 0);
2059860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.ENGINE_add(engine);
2060860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2061860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long pkey = NULL;
2062860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2063860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final String rsaPem =
2064860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                      "-----BEGIN RSA PRIVATE KEY-----\n"
2065860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "MIICXAIBAAKBgQCvvsYz1VKhU9PT0NHlotX22tcCjeaiVFNg0JrkjoK2XuMb+7a6\n"
2066860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "R5bzgIr24+OnBB0LqgaKnHwxZTA73lo/Wy/Ms5Kvg4yX9UMkNE+PvH5vzcQBbFdI\n"
2067860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "lwETFPvFokHO5OyOcEY+iVWG2fDloteH2JsrKYLh9Sx3Br5pHFCCm5qT5wIDAQAB\n"
2068860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "AoGAWDxoNs371pPH3qkROUIwOuhU2ytziDzeP9V8bxQ9/GJXlE0kyRH4b/kxzBNO\n"
2069860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "0SP3kUukTSOUFxi+xtA0b2rQ7Be2txtjzW1TGOHSCWbFrJAdTqeBcmQJSaZay8n1\n"
2070860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "LOpk4/zvBl7VScBth1IgXP44v6lOzthsrDhMlUYs07ymwYECQQDonaLOhkmVThPa\n"
2071860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "CIThdE5CN/wF5UDzGOz+ZBz3dt8D8QQMu0aZaPzibq9BC462j/fWeWS5OFzbq2+T\n"
2072860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "+cor3nwPAkEAwWmTQdra6GMPEc40zNsM5ehF2FjOpX8aU8267eG56y0Y+GbHx2BN\n"
2073860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "zAHfPxGBBH8cZ0cLhk4RSo/po7Vv+cRyqQJAAQz1N0mT+4Cmxk1TjFEiKVpnYP9w\n"
2074860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "E6kBKQT6vINk7negNQ6Dex3mRn+Jexm6Q0jTLbzOn6eJg9R6ZIi0SQ5wMQJAKX2n\n"
2075860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "fGohqdaORgiRZRzcsHlaemXatsAEetPYdO2Gf7/l6mvKEahEKC6CoLn1jmxiQHmK\n"
2076860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "LF6U8QTcXyUuB0uwOQJBAIwWWjQGGc2sAQ1HW0C2wwCQbWneeBkiRBedonDBHtiB\n"
2077860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "Wz0zS2CMCtBPNeHQmmsXH2Ca+ADdh53sKTuperLiuiw=\n"
2078860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    + "-----END RSA PRIVATE KEY-----";
2079860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            pkey = NativeCrypto.ENGINE_load_private_key(engine, rsaPem);
2080860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(pkey != 0);
2081860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2082860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (pkey != NULL) {
2083860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(pkey);
2084860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2085860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2086860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.ENGINE_free(engine);
2087860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.ENGINE_finish(engine);
2088860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2089860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2090860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2091860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_RAND_bytes_Success() throws Exception {
2092860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] output = new byte[128];
2093860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.RAND_bytes(output);
2094860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2095860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        boolean isZero = true;
2096860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        for (int i = 0; i < output.length; i++) {
2097860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            isZero &= (output[i] == 0);
2098860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2099860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2100860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) "
2101860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                + "and probably indicates an error.", isZero);
2102860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2103860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2104860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_RAND_bytes_Null_Failure() throws Exception {
2105860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] output = null;
2106860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2107860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.RAND_bytes(output);
2108860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail("Should be an error on null buffer input");
2109860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (RuntimeException expected) {
2110860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2111860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2112860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2113860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_get_digestbyname() throws Exception {
2114860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL);
2115860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2116860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2117860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_get_digestbyname(null);
2118860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
2119860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
2120860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2121860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2122860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2123860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_get_digestbyname("");
2124860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_get_digestbyname("foobar");
2125860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
2126860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (RuntimeException expected) {
2127860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2128860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2129860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2130860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_SignInit() throws Exception {
2131860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final long ctx = NativeCrypto.EVP_SignInit("RSA-SHA256");
2132860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(ctx != NULL);
2133860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        NativeCrypto.EVP_MD_CTX_destroy(ctx);
2134860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2135860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2136860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_SignInit("foobar");
2137860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            fail();
2138860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (RuntimeException expected) {
2139860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2140860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2141860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2142860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_get_RSA_private_params() throws Exception {
2143860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2144860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.get_RSA_private_params(NULL);
2145860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
2146860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2147860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2148860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2149860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.get_RSA_private_params(NULL);
2150860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
2151860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2152860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2153860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Test getting params for the wrong kind of key.
2154860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final byte[] seed = new byte[20];
2155860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long ctx = 0;
2156860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2157860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
2158860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(ctx != NULL);
2159860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2160860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.get_RSA_private_params(ctx);
2161860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
2162860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (RuntimeException expected) {
2163860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2164860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2165860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (ctx != 0) {
2166860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(ctx);
2167860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2168860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2169860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2170860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2171860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_get_RSA_public_params() throws Exception {
2172860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2173860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.get_RSA_public_params(NULL);
2174860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
2175860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2176860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2177860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2178860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.get_RSA_public_params(NULL);
2179860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } catch (NullPointerException expected) {
2180860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2181860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2182860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Test getting params for the wrong kind of key.
2183860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final byte[] seed = new byte[20];
2184860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long ctx = 0;
2185860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2186860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
2187860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(ctx != NULL);
2188860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2189860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.get_RSA_public_params(ctx);
2190860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
2191860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (RuntimeException expected) {
2192860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2193860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2194860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (ctx != 0) {
2195860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(ctx);
2196860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2197860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2198860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2199860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2200860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    final byte[] dsa2048_p = {
2201860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xC3, (byte) 0x16, (byte) 0xD4, (byte) 0xBA, (byte) 0xDC, (byte) 0x0E,
2202860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xB8, (byte) 0xFC, (byte) 0x40, (byte) 0xDB, (byte) 0xB0, (byte) 0x76,
2203860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x47, (byte) 0xB8, (byte) 0x8D, (byte) 0xC1, (byte) 0xF1, (byte) 0xAB,
2204860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x9B, (byte) 0x80, (byte) 0x9D, (byte) 0xDC, (byte) 0x55, (byte) 0x33,
2205860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xEC, (byte) 0xB6, (byte) 0x09, (byte) 0x8F, (byte) 0xB7, (byte) 0xD9,
2206860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xA5, (byte) 0x7F, (byte) 0xC1, (byte) 0xE3, (byte) 0xAD, (byte) 0xE1,
2207860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x7A, (byte) 0x58, (byte) 0xF4, (byte) 0x2D, (byte) 0xB9, (byte) 0x61,
2208860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xCF, (byte) 0x5B, (byte) 0xCA, (byte) 0x41, (byte) 0x9F, (byte) 0x73,
2209860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8D, (byte) 0x81, (byte) 0x62, (byte) 0xD2, (byte) 0x19, (byte) 0x7D,
2210860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x18, (byte) 0xDB, (byte) 0xB3, (byte) 0x04, (byte) 0xE7, (byte) 0xB2,
2211860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x28, (byte) 0x59, (byte) 0x14, (byte) 0x73, (byte) 0x43, (byte) 0xF1,
2212860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x45, (byte) 0xC7, (byte) 0x47, (byte) 0xCC, (byte) 0xD1, (byte) 0x12,
2213860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8E, (byte) 0x19, (byte) 0x00, (byte) 0x2C, (byte) 0xD0, (byte) 0x86,
2214860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x54, (byte) 0x64, (byte) 0x2D, (byte) 0x42, (byte) 0x6C, (byte) 0x6B,
2215860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x5C, (byte) 0x2D, (byte) 0x4D, (byte) 0x97, (byte) 0x6A, (byte) 0x1D,
2216860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x89, (byte) 0xB1, (byte) 0x2C, (byte) 0xA0, (byte) 0x05, (byte) 0x2B,
2217860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x3C, (byte) 0xDB, (byte) 0x1F, (byte) 0x89, (byte) 0x03, (byte) 0x03,
2218860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x92, (byte) 0x63, (byte) 0xB6, (byte) 0x08, (byte) 0x32, (byte) 0x50,
2219860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xB2, (byte) 0x54, (byte) 0xA3, (byte) 0xFE, (byte) 0x6C, (byte) 0x35,
2220860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x17, (byte) 0x2F, (byte) 0x7F, (byte) 0x54, (byte) 0xA4, (byte) 0xAE,
2221860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x96, (byte) 0x1E, (byte) 0x31, (byte) 0x83, (byte) 0xF1, (byte) 0x3F,
2222860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x9E, (byte) 0xB9, (byte) 0x5D, (byte) 0xD3, (byte) 0xA9, (byte) 0xCB,
2223860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xE5, (byte) 0x2F, (byte) 0xBC, (byte) 0xA4, (byte) 0x1A, (byte) 0x31,
2224860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x41, (byte) 0x91, (byte) 0x2C, (byte) 0xA0, (byte) 0xF4, (byte) 0x83,
2225860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xAC, (byte) 0xD5, (byte) 0xBA, (byte) 0x3D, (byte) 0x19, (byte) 0xED,
2226860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xF1, (byte) 0x6C, (byte) 0xD9, (byte) 0x3F, (byte) 0x30, (byte) 0xDA,
2227860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x80, (byte) 0x06, (byte) 0x56, (byte) 0x3A, (byte) 0x8C, (byte) 0x74,
2228860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x63, (byte) 0xF2, (byte) 0xED, (byte) 0x1E, (byte) 0xE3, (byte) 0x86,
2229860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x95, (byte) 0x64, (byte) 0x2A, (byte) 0xC4, (byte) 0x5F, (byte) 0xB2,
2230860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x64, (byte) 0x40, (byte) 0x9D, (byte) 0xA6, (byte) 0xB8, (byte) 0xF5,
2231860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x84, (byte) 0x03, (byte) 0x2E, (byte) 0x4A, (byte) 0x7A, (byte) 0x1A,
2232860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xB0, (byte) 0x0E, (byte) 0xBA, (byte) 0xB1, (byte) 0xF5, (byte) 0xD2,
2233860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xE7, (byte) 0x65, (byte) 0xCE, (byte) 0xEE, (byte) 0x2C, (byte) 0x7C,
2234860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x68, (byte) 0x20, (byte) 0x50, (byte) 0x53, (byte) 0x0F, (byte) 0x60,
2235860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x92, (byte) 0x81, (byte) 0xC0, (byte) 0x2C, (byte) 0x2A, (byte) 0xEA,
2236860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xE9, (byte) 0xB3, (byte) 0x2A, (byte) 0x81, (byte) 0xDA, (byte) 0x0F,
2237860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xBB, (byte) 0xFA, (byte) 0x5B, (byte) 0x47, (byte) 0xDA, (byte) 0x57,
2238860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x4E, (byte) 0xFC, (byte) 0x05, (byte) 0x2C, (byte) 0x6A, (byte) 0x90,
2239860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xA0, (byte) 0x99, (byte) 0x88, (byte) 0x71, (byte) 0x8A, (byte) 0xCC,
2240860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xD2, (byte) 0x97, (byte) 0x11, (byte) 0xB1, (byte) 0xCE, (byte) 0xF7,
2241860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x47, (byte) 0x53, (byte) 0x53, (byte) 0x68, (byte) 0xE1, (byte) 0x2A,
2242860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x56, (byte) 0xD5, (byte) 0x3D, (byte) 0xDF, (byte) 0x08, (byte) 0x16,
2243860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x1F, (byte) 0xAA, (byte) 0x54, (byte) 0x15,
2244860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    };
2245860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2246860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    final byte[] dsa2048_q = {
2247860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xAA, (byte) 0xDD, (byte) 0xE2, (byte) 0xCE, (byte) 0x08, (byte) 0xC0,
2248860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x0E, (byte) 0x91, (byte) 0x8C, (byte) 0xD9, (byte) 0xBC, (byte) 0x1E,
2249860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x05, (byte) 0x70, (byte) 0x07, (byte) 0x3B, (byte) 0xB5, (byte) 0xA9,
2250860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xB5, (byte) 0x8B, (byte) 0x21, (byte) 0x68, (byte) 0xA2, (byte) 0x76,
2251860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x53, (byte) 0x1E, (byte) 0x68, (byte) 0x1B, (byte) 0x4F, (byte) 0x88,
2252860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x6D, (byte) 0xCF,
2253860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    };
2254860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2255860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    final byte[] dsa2048_g = {
2256860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x6B, (byte) 0x4D, (byte) 0x21, (byte) 0x92, (byte) 0x24, (byte) 0x76,
2257860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xE5, (byte) 0xA2, (byte) 0xCE, (byte) 0x02, (byte) 0x85, (byte) 0x32,
2258860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x73, (byte) 0x70, (byte) 0xFF, (byte) 0xB9, (byte) 0xD4, (byte) 0x51,
2259860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xBA, (byte) 0x22, (byte) 0x8B, (byte) 0x75, (byte) 0x29, (byte) 0xE3,
2260860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xF2, (byte) 0x2E, (byte) 0x20, (byte) 0xF5, (byte) 0x6A, (byte) 0xD9,
2261860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x75, (byte) 0xA0, (byte) 0xC0, (byte) 0x3B, (byte) 0x12, (byte) 0x2F,
2262860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x4F, (byte) 0x9A, (byte) 0xF8, (byte) 0x5D, (byte) 0x45, (byte) 0xC5,
2263860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x80, (byte) 0x6C, (byte) 0x9B, (byte) 0x56, (byte) 0xBE, (byte) 0x8E,
2264860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x40, (byte) 0xF9, (byte) 0x0A, (byte) 0xF0, (byte) 0x3D, (byte) 0xD7,
2265860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x7C, (byte) 0xDE, (byte) 0x22, (byte) 0x10, (byte) 0x24, (byte) 0xCC,
2266860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xAE, (byte) 0x8A, (byte) 0xC0, (byte) 0x05, (byte) 0xCD, (byte) 0xDC,
2267860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x10, (byte) 0x29, (byte) 0x4D, (byte) 0xFC, (byte) 0xEC, (byte) 0xEF,
2268860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x51, (byte) 0x4B, (byte) 0xF9, (byte) 0xCC, (byte) 0x99, (byte) 0x84,
2269860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x1B, (byte) 0x14, (byte) 0x68, (byte) 0xEC, (byte) 0xF0, (byte) 0x5E,
2270860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x07, (byte) 0x10, (byte) 0x09, (byte) 0xA9, (byte) 0x2C, (byte) 0x04,
2271860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xD0, (byte) 0x14, (byte) 0xBF, (byte) 0x88, (byte) 0x9E, (byte) 0xBB,
2272860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xE3, (byte) 0x3F, (byte) 0xDE, (byte) 0x92, (byte) 0xE1, (byte) 0x64,
2273860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x07, (byte) 0x28, (byte) 0xC1, (byte) 0xCA, (byte) 0x48, (byte) 0xC1,
2274860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x1D, (byte) 0x33, (byte) 0xE4, (byte) 0x35, (byte) 0xBE, (byte) 0xDF,
2275860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x5E, (byte) 0x50, (byte) 0xF9, (byte) 0xC2, (byte) 0x0E, (byte) 0x25,
2276860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x0D, (byte) 0x20, (byte) 0x8C, (byte) 0x01, (byte) 0x0A, (byte) 0x23,
2277860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xD4, (byte) 0x6E, (byte) 0x42, (byte) 0x47, (byte) 0xE1, (byte) 0x9E,
2278860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x36, (byte) 0x91, (byte) 0xC8, (byte) 0x65, (byte) 0x44, (byte) 0xE0,
2279860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x04, (byte) 0x86, (byte) 0x2F, (byte) 0xD4, (byte) 0x90, (byte) 0x16,
2280860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x09, (byte) 0x14, (byte) 0xB1, (byte) 0xC5, (byte) 0x7D, (byte) 0xB2,
2281860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x7C, (byte) 0x36, (byte) 0x0D, (byte) 0x9C, (byte) 0x1F, (byte) 0x83,
2282860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x57, (byte) 0x94, (byte) 0x26, (byte) 0x32, (byte) 0x9C, (byte) 0x86,
2283860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8E, (byte) 0xE5, (byte) 0x80, (byte) 0x3A, (byte) 0xA9, (byte) 0xAF,
2284860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x4A, (byte) 0x95, (byte) 0x78, (byte) 0x8D, (byte) 0xE6, (byte) 0xC3,
2285860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x0C, (byte) 0x78, (byte) 0x83, (byte) 0x4B, (byte) 0xF5, (byte) 0x40,
2286860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x04, (byte) 0x20, (byte) 0x90, (byte) 0x5C, (byte) 0xA1, (byte) 0x19,
2287860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xEB, (byte) 0x95, (byte) 0x70, (byte) 0x2B, (byte) 0x94, (byte) 0xA3,
2288860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x43, (byte) 0xDD, (byte) 0xEB, (byte) 0xD4, (byte) 0x0C, (byte) 0xBC,
2289860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xBD, (byte) 0x58, (byte) 0x2D, (byte) 0x75, (byte) 0xB0, (byte) 0x8D,
2290860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8B, (byte) 0x70, (byte) 0xB9, (byte) 0xE7, (byte) 0xA3, (byte) 0xCC,
2291860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8C, (byte) 0xB4, (byte) 0xCD, (byte) 0xBB, (byte) 0x4B, (byte) 0xB1,
2292860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x15, (byte) 0x18, (byte) 0x79, (byte) 0xDF, (byte) 0x22, (byte) 0xA6,
2293860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x5C, (byte) 0x90, (byte) 0x7C, (byte) 0x1F, (byte) 0xEA, (byte) 0x1B,
2294860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xF2, (byte) 0x89, (byte) 0x87, (byte) 0xB2, (byte) 0xEC, (byte) 0x57,
2295860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xFF, (byte) 0xB2, (byte) 0xDA, (byte) 0xF5, (byte) 0xAD, (byte) 0x73,
2296860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0xC0, (byte) 0xA0, (byte) 0x20, (byte) 0x8B, (byte) 0x78, (byte) 0xA1,
2297860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x5D, (byte) 0x04, (byte) 0x0A, (byte) 0x29, (byte) 0xE3, (byte) 0xD7,
2298860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x37, (byte) 0xF6, (byte) 0xA2, (byte) 0xCA,
2299860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    };
2300860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2301860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_DSA_generate_key() throws Exception {
2302860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final byte[] seed = new byte[20];
2303860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2304860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Real key
2305860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
2306860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long ctx = 0;
2307860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2308860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
2309860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(ctx != NULL);
2310860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } finally {
2311860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                if (ctx != 0) {
2312860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_free(ctx);
2313860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
2314860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2315860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2316860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2317860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Real key with minimum bit size (should be 512 bits)
2318860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
2319860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long ctx = 0;
2320860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2321860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                ctx = NativeCrypto.DSA_generate_key(0, null, null, null, null);
2322860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                assertTrue(ctx != NULL);
2323860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } finally {
2324860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                if (ctx != 0) {
2325860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_free(ctx);
2326860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
2327860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2328860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2329860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2330860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        // Bad DSA params.
2331860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        {
2332860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long ctx = 0;
2333860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2334860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                ctx = NativeCrypto.DSA_generate_key(0, null, new byte[] {}, new byte[] {},
2335860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                        new byte[] {});
2336860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail();
2337860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (RuntimeException expected) {
2338860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } finally {
2339860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                if (ctx != 0) {
2340860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EVP_PKEY_free(ctx);
2341860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                }
2342860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2343860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2344860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2345860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2346860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    /*
2347860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * Test vector generation:
2348860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     * openssl rand -hex 16
2349860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root     */
2350860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final byte[] AES_128_KEY = new byte[] {
2351860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
2352860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
2353860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
2354860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    };
2355860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2356860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private static final byte[] AES_IV_ZEROES = new byte[] {
2357860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
2358860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
2359860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
2360860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    };
2361860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2362860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void testEC_GROUP() throws Exception {
2363860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        /* Test using NIST's P-256 curve */
2364860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        check_EC_GROUP(NativeCrypto.EC_CURVE_GFP, "prime256v1",
2365860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
2366860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
2367860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
2368860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
2369860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
2370860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
2371860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                1L);
2372860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2373860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        check_EC_GROUP(NativeCrypto.EC_CURVE_GF2M, "sect283r1",
2374860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "0800000000000000000000000000000000000000000000000000000000000000000010A1",
2375860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "000000000000000000000000000000000000000000000000000000000000000000000001",
2376860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
2377860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
2378860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
2379860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
2380860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                2L);
2381860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2382860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2383860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr,
2384860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            String xStr, String yStr, String nStr, long hLong) throws Exception {
2385860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL;
2386860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2387860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            group1 = NativeCrypto.EC_GROUP_new_by_curve_name(name);
2388860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(group1 != NULL);
2389860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(NativeCrypto.OBJ_txt2nid_longName(name),
2390860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EC_GROUP_get_curve_name(group1));
2391860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(type, NativeCrypto.get_EC_GROUP_type(group1));
2392860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2393860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // prime
2394860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger p = new BigInteger(pStr, 16);
2395860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // first coefficient
2396860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger a = new BigInteger(aStr, 16);
2397860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // second coefficient
2398860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger b = new BigInteger(bStr, 16);
2399860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // x affine coordinate of generator
2400860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger x = new BigInteger(xStr, 16);
2401860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // y affine coordinate of generator
2402860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger y = new BigInteger(yStr, 16);
2403860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // order of the generator
2404860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger n = new BigInteger(nStr, 16);
2405860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            // cofactor of generator
2406860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger h = BigInteger.valueOf(hLong);
2407860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2408860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            group2 = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(),
2409860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    a.toByteArray(), b.toByteArray());
2410860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(type, NativeCrypto.get_EC_GROUP_type(group2));
2411860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2412860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            point2 = NativeCrypto.EC_POINT_new(group2);
2413860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2414860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EC_POINT_set_affine_coordinates(group2, point2, x.toByteArray(),
2415860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    y.toByteArray());
2416860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2417860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EC_GROUP_set_generator(group2, point2, n.toByteArray(), h.toByteArray());
2418860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2419860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            point1 = NativeCrypto.EC_GROUP_get_generator(group2);
2420860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(NativeCrypto.EC_POINT_cmp(group1, point1, point2));
2421860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2422860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group2);
2423860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(3, pab.length);
2424860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2425860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger p2 = new BigInteger(pab[0]);
2426860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(p, p2);
2427860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2428860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger a2 = new BigInteger(pab[1]);
2429860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(a, a2);
2430860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2431860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger b2 = new BigInteger(pab[2]);
2432860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(b, b2);
2433860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2434860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group2, point2);
2435860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(2, xy.length);
2436860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2437860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger x2 = new BigInteger(xy[0]);
2438860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(x, x2);
2439860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2440860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger y2 = new BigInteger(xy[1]);
2441860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(y, y2);
2442860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2443860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group1));
2444860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(n, n2);
2445860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2446860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group2));
2447860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(h, h2);
2448860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2449860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(NativeCrypto.EC_GROUP_cmp(group1, group2));
2450860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2451860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            key1 = NativeCrypto.EC_KEY_generate_key(group1);
2452860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            long groupTmp = NativeCrypto.EC_KEY_get0_group(key1);
2453860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group1),
2454860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    NativeCrypto.EC_GROUP_get_curve_name(groupTmp));
2455860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2456860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2457860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (group1 != NULL) {
2458860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EC_GROUP_clear_free(group1);
2459860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2460860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2461860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (group2 != NULL) {
2462860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EC_GROUP_clear_free(group2);
2463860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2464860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2465860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (point1 != NULL) {
2466860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EC_POINT_clear_free(point1);
2467860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2468860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2469860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (point2 != NULL) {
2470860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EC_POINT_clear_free(point2);
2471860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2472860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2473860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (key1 != NULL) {
2474860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_PKEY_free(key1);
2475860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2476860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2477860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2478860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2479860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_CipherInit_ex_Null_Failure() throws Exception {
2480860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
2481860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2482860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
2483860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2484860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            try {
2485860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EVP_CipherInit_ex(NULL, evpCipher, null, null, true);
2486860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                fail("Null context should throw NullPointerException");
2487860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            } catch (NullPointerException expected) {
2488860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2489860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2490860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            /* Initialize encrypting. */
2491860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true);
2492860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true);
2493860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2494860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            /* Initialize decrypting. */
2495860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false);
2496860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false);
2497860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2498860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
2499860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2500860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2501860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2502860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_CipherInit_ex_Success() throws Exception {
2503860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
2504860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2505860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
2506860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true);
2507860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2508860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
2509860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2510860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2511860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2512860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_EVP_CIPHER_iv_length() throws Exception {
2513860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
2514860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb));
2515860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2516860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
2517860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc));
2518860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2519860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2520860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_OpenSSLKey_toJava() throws Exception {
2521860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        OpenSSLKey key1;
2522860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2523860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        BigInteger e = BigInteger.valueOf(65537);
2524860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray()));
2525860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(key1.getPublicKey() instanceof RSAPublicKey);
2526860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2527860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        key1 = new OpenSSLKey(NativeCrypto.DSA_generate_key(1024, null, null, null, null));
2528860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(key1.getPublicKey() instanceof DSAPublicKey);
2529860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2530860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long group1 = NULL;
2531860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2532860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            group1 = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
2533860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertTrue(group1 != NULL);
2534860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1));
2535860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2536860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            if (group1 != NULL) {
2537860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                NativeCrypto.EC_GROUP_clear_free(group1);
2538860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            }
2539860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2540860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        assertTrue(key1.getPublicKey() instanceof ECPublicKey);
2541860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2542860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2543860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_create_BIO_InputStream() throws Exception {
2544860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] actual = "Test".getBytes();
2545860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ByteArrayInputStream is = new ByteArrayInputStream(actual);
2546860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2547860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long ctx = NativeCrypto.create_BIO_InputStream(new OpenSSLBIOInputStream(is));
2548860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2549860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            byte[] buffer = new byte[1024];
2550860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            int numRead = NativeCrypto.BIO_read(ctx, buffer);
2551860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(actual.length, numRead);
2552860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(Arrays.toString(actual),
2553860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root                    Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead)));
2554860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2555860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.BIO_free(ctx);
2556860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2557860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2558860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2559860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2560860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    public void test_create_BIO_OutputStream() throws Exception {
2561860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        byte[] actual = "Test".getBytes();
2562860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        ByteArrayOutputStream os = new ByteArrayOutputStream();
2563860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root
2564860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        long ctx = NativeCrypto.create_BIO_OutputStream(os);
2565860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        try {
2566860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.BIO_write(ctx, actual, 0, actual.length);
2567860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(actual.length, os.size());
2568860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray()));
2569860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        } finally {
2570860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root            NativeCrypto.BIO_free(ctx);
2571860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root        }
2572860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root    }
2573860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root}
2574