10c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom/*
20c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project
30c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom *
40c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
50c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * you may not use this file except in compliance with the License.
60c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * You may obtain a copy of the License at
70c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom *
80c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
90c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom *
100c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
110c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
120c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * See the License for the specific language governing permissions and
140c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom * limitations under the License.
150c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom */
160c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.javax.net.ssl;
180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
190669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubinimport java.io.IOException;
20c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Rootimport java.nio.ByteBuffer;
210c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport java.util.Arrays;
22c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubinimport javax.crypto.SecretKey;
23c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubinimport javax.crypto.spec.SecretKeySpec;
240669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubinimport javax.net.ssl.KeyManager;
254557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLContext;
264557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLEngine;
27c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Rootimport javax.net.ssl.SSLEngineResult;
280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport javax.net.ssl.SSLEngineResult.HandshakeStatus;
294557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLException;
304557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLHandshakeException;
314557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLParameters;
324557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSession;
33edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubinimport javax.net.ssl.X509ExtendedKeyManager;
340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport junit.framework.TestCase;
35101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilsonimport libcore.java.security.StandardNames;
36101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilsonimport libcore.java.security.TestKeyStore;
370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrompublic class SSLEngineTest extends TestCase {
390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void assertConnected(TestSSLEnginePair e) {
410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertConnected(e.client, e.server);
420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void assertNotConnected(TestSSLEnginePair e) {
450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotConnected(e.client, e.server);
460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void assertConnected(SSLEngine a, SSLEngine b) {
490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(connected(a, b));
500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void assertNotConnected(SSLEngine a, SSLEngine b) {
530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(connected(a, b));
540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public boolean connected(SSLEngine a, SSLEngine b) {
570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        return (a.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && b.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && a.getSession() != null
600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && b.getSession() != null
610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && !a.isInboundDone()
620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && !b.isInboundDone()
630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && !a.isOutboundDone()
640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                && !b.isOutboundDone());
650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
67f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    public void test_SSLEngine_defaultConfiguration() throws Exception {
68f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin        SSLDefaultConfigurationAsserts.assertSSLEngine(
69f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin                TestSSLContext.create().clientContext.createSSLEngine());
70f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    }
71f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin
72f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    public void test_SSLEngine_getSupportedCipherSuites_returnsCopies() throws Exception {
730c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
74059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
75f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin        assertNotSame(e.getSupportedCipherSuites(), e.getSupportedCipherSuites());
76f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
780c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
790c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_getSupportedCipherSuites_connect() throws Exception {
80a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom        // note the rare usage of non-RSA keys
81101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson        TestKeyStore testKeyStore = new TestKeyStore.Builder()
82101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
83101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .aliasPrefix("rsa-dsa-ec")
84101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .ca(true)
85101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson                .build();
866c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom        test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, false);
87727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
886c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom    }
8903365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath
9003365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    // http://b/18554122
9103365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    public void test_SSLEngine_underflowsOnEmptyBuffersDuringHandshake() throws Exception {
9203365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        final SSLEngine sslEngine = SSLContext.getDefault().createSSLEngine();
9303365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        sslEngine.setUseClientMode(false);
9403365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        ByteBuffer input = ByteBuffer.allocate(1024);
9503365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        input.flip();
9603365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        ByteBuffer output = ByteBuffer.allocate(1024);
9703365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        sslEngine.beginHandshake();
9803365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, sslEngine.getHandshakeStatus());
9903365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        SSLEngineResult result = sslEngine.unwrap(input, output);
10003365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW, result.getStatus());
10103365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
10203365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    }
10303365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath
10403365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    // http://b/18554122
10503365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    public void test_SSLEngine_underflowsOnEmptyBuffersAfterHandshake() throws Exception {
10603365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        // Note that create performs the handshake.
10703365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        final TestSSLEnginePair engines = TestSSLEnginePair.create(null /* hooks */);
10803365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        ByteBuffer input = ByteBuffer.allocate(1024);
10903365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        input.flip();
11003365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        ByteBuffer output = ByteBuffer.allocate(1024);
11103365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath        assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW,
11203365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath                engines.client.unwrap(input, output).getStatus());
11303365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath    }
11403365a863c7316325ff12bf88aa19dc33e34f19fNarayan Kamath
1156c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom    private void test_SSLEngine_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
1166c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom                                                                 boolean secureRenegotiation)
1176c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom            throws Exception {
118c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin        KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
119c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                new PSKKeyManagerProxy() {
120c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            @Override
121c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
122c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                return new SecretKeySpec("Just an arbitrary key".getBytes(), "RAW");
123c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            }
124c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin        });
125c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin        TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
126c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                testKeyStore, testKeyStore,
127c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager});
1280669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin
1290669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        // Create a TestSSLContext where the KeyManager returns wrong (randomly generated) private
1300669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        // keys, matching the algorithm and parameters of the correct keys.
1310669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        // I couldn't find a more elegant way to achieve this other than temporarily replacing the
132edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin        // first X509ExtendedKeyManager element of TestKeyStore.keyManagers while invoking
133edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin        // TestSSLContext.create.
1340669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        TestSSLContext cWithWrongPrivateKeys;
1350669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        {
136edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            // Create a RandomPrivateKeyX509ExtendedKeyManager based on the first
137edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            // X509ExtendedKeyManager in c.serverKeyManagers.
138edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            KeyManager randomPrivateKeyX509ExtendedKeyManager = null;
139edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            for (KeyManager keyManager : c.serverKeyManagers) {
140edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              if (keyManager instanceof X509ExtendedKeyManager) {
141edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin                randomPrivateKeyX509ExtendedKeyManager =
142edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin                    new RandomPrivateKeyX509ExtendedKeyManager((X509ExtendedKeyManager) keyManager);
143edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin                break;
144edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              }
145edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            }
146edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            if (randomPrivateKeyX509ExtendedKeyManager == null) {
147edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              fail("No X509ExtendedKeyManager in c.serverKeyManagers");
148edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            }
149edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin
150edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            // Find the first X509ExtendedKeyManager in testKeyStore.keyManagers
151edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            int replaceIndex = -1;
152edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            for (int i = 0; i < testKeyStore.keyManagers.length; i++) {
153edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              KeyManager keyManager = testKeyStore.keyManagers[i];
154edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              if (keyManager instanceof X509ExtendedKeyManager) {
155edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin                replaceIndex = i;
156edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin                break;
157edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              }
158edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            }
159edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            if (replaceIndex == -1) {
160edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin              fail("No X509ExtendedKeyManager in testKeyStore.keyManagers");
161edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            }
162edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin
163edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            // Temporarily substitute the RandomPrivateKeyX509ExtendedKeyManager in place of the
164edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            // original X509ExtendedKeyManager.
165edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            KeyManager originalKeyManager = testKeyStore.keyManagers[replaceIndex];
166edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            testKeyStore.keyManagers[replaceIndex] = randomPrivateKeyX509ExtendedKeyManager;
1670669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin            cWithWrongPrivateKeys = TestSSLContext.create(testKeyStore, testKeyStore);
168edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin            testKeyStore.keyManagers[replaceIndex] = originalKeyManager;
1690669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin        }
1700669a8cf8b08b2d66a7ff758e5e3dbd456855495Alex Klyubin
171727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        // To catch all the errors.
172727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        StringBuilder error = new StringBuilder();
173727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root
174059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        String[] cipherSuites = c.clientContext.createSSLEngine().getSupportedCipherSuites();
1750c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        for (String cipherSuite : cipherSuites) {
176727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            try {
1773ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // Skip cipher suites that are obsoleted.
1783ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            if (StandardNames.IS_RI && "TLSv1.2".equals(c.clientContext.getProtocol())
1793ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    && StandardNames.CIPHER_SUITES_OBSOLETE_TLS12.contains(cipherSuite)) {
1803ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                continue;
1813ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            }
1823ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            /*
183e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root             * Signaling Cipher Suite Values (SCSV) cannot be used on their own, but instead in
184e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root             * conjunction with other cipher suites.
1853ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root             */
186e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root            if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
187e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root                    || cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
1883ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                continue;
1893ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            }
1903ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            /*
1913ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root             * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
1923ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root             * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
1933ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root             * #KRBRequire
1943ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root             */
1953ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            if (cipherSuite.startsWith("TLS_KRB5_")) {
1963ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                continue;
1973ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            }
1986c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom
1993ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            final String[] cipherSuiteArray
2003ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    = (secureRenegotiation
2013ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                       ? new String[] { cipherSuite,
2023ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                                        StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
2033ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                       : new String[] { cipherSuite });
2043ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root
2053ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // Check that handshake succeeds.
2063ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            TestSSLEnginePair pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
2073ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                @Override
2083ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
2093ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    client.setEnabledCipherSuites(cipherSuiteArray);
2103ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    server.setEnabledCipherSuites(cipherSuiteArray);
211aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom                }
2123ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            });
2133ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            assertConnected(pair);
2143ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root
2153ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            boolean needsRecordSplit =
2163ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    ("TLS".equalsIgnoreCase(c.clientContext.getProtocol())
2173ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                            || "SSLv3".equalsIgnoreCase(c.clientContext.getProtocol()))
2183ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    && cipherSuite.contains("_CBC_");
2193ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root
2203ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            assertSendsCorrectly("This is the client. Hello!".getBytes(),
2213ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    pair.client, pair.server, needsRecordSplit);
2223ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            assertSendsCorrectly("This is the server. Hi!".getBytes(),
2233ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    pair.server, pair.client, needsRecordSplit);
2243ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root
2253ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // Check that handshake fails when the server does not possess the private key
2263ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // corresponding to the server's certificate. This is achieved by using SSLContext
2273ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
2283ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            // the algorithm (and parameters) of the correct keys.
229c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            boolean serverAuthenticatedUsingPublicKey = true;
230c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            if (cipherSuite.contains("_anon_")) {
231c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                serverAuthenticatedUsingPublicKey = false;
232c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            } else if ((cipherSuite.startsWith("TLS_PSK_"))
233c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                    || (cipherSuite.startsWith("TLS_ECDHE_PSK_"))) {
234c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin                serverAuthenticatedUsingPublicKey = false;
235c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            }
236c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin            if (serverAuthenticatedUsingPublicKey) {
2373ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                try {
2383ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    TestSSLEnginePair p = TestSSLEnginePair.create(
2393ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                            cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
2403ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                        @Override
2413ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
2423ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                            client.setEnabledCipherSuites(cipherSuiteArray);
2433ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                            server.setEnabledCipherSuites(cipherSuiteArray);
2443ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                        }
2453ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    });
2463ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    assertNotConnected(p);
2473ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                } catch (IOException expected) {}
248a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom            }
249727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            } catch (Exception e) {
250727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                String message = ("Problem trying to connect cipher suite " + cipherSuite);
251727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                System.out.println(message);
252727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                e.printStackTrace();
253727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                error.append(message);
254727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                error.append('\n');
255727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            }
2560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
257f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
258727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root
259727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        if (error.length() > 0) {
260727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            throw new Exception("One or more problems in "
261727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                    + "test_SSLEngine_getSupportedCipherSuites_connect:\n" + error);
262727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        }
2630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
2640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
2653ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root    private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
2663ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            SSLEngine dest, boolean needsRecordSplit) throws SSLException {
267c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
268c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        SSLSession sourceSession = source.getSession();
269c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
270c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        SSLEngineResult sourceOutRes = source.wrap(sourceOut, sourceToDest);
271c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        sourceToDest.flip();
272c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
273c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        String sourceCipherSuite = source.getSession().getCipherSuite();
274c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
275c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
276c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root                sourceOutRes.getHandshakeStatus());
277c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
278c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        SSLSession destSession = dest.getSession();
279c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
280c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
281c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        int numUnwrapCalls = 0;
282c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        while (destIn.position() != sourceOut.limit()) {
283c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
284c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
285c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root                    destRes.getHandshakeStatus());
286c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            if (needsRecordSplit && numUnwrapCalls == 0) {
287c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root                assertEquals(sourceCipherSuite, 1, destRes.bytesProduced());
288c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            }
289c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            numUnwrapCalls++;
290c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        }
291c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
292c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        destIn.flip();
293c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        byte[] actual = new byte[destIn.remaining()];
294c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        destIn.get(actual);
295c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
296c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
297c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        if (needsRecordSplit) {
298c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            assertEquals(sourceCipherSuite, 2, numUnwrapCalls);
299c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        } else {
300c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root            assertEquals(sourceCipherSuite, 1, numUnwrapCalls);
301c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root        }
302c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root    }
303c118df9e19edaa61ec3f61c4c8b73268642818f7Kenny Root
304f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    public void test_SSLEngine_getEnabledCipherSuites_returnsCopies() throws Exception {
3050c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
306059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
307f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin        assertNotSame(e.getEnabledCipherSuites(), e.getEnabledCipherSuites());
308f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
3090c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
3100c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
311ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin    public void test_SSLEngine_setEnabledCipherSuites_storesCopy() throws Exception {
312ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        TestSSLContext c = TestSSLContext.create();
313ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        SSLEngine e = c.clientContext.createSSLEngine();
314ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        String[] array = new String[] {e.getEnabledCipherSuites()[0]};
315ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        String originalFirstElement = array[0];
316ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        e.setEnabledCipherSuites(array);
317ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        array[0] = "Modified after having been set";
318ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        assertEquals(originalFirstElement, e.getEnabledCipherSuites()[0]);
319ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin    }
320ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin
3210c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setEnabledCipherSuites() throws Exception {
3220c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
323059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
3240c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
3250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3260c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledCipherSuites(null);
3270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3310c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledCipherSuites(new String[1]);
3320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledCipherSuites(new String[] { "Bogus" } );
3370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
3410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledCipherSuites(new String[0]);
3420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledCipherSuites(e.getEnabledCipherSuites());
3430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledCipherSuites(e.getSupportedCipherSuites());
344358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin
345358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin        // Check that setEnabledCipherSuites affects getEnabledCipherSuites
346358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin        String[] cipherSuites = new String[] { e.getSupportedCipherSuites()[0] };
347358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin        e.setEnabledCipherSuites(cipherSuites);
348358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
349358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin
350f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
3510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
3520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
353f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    public void test_SSLEngine_getSupportedProtocols_returnsCopies() throws Exception {
3540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
355059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
356f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin        assertNotSame(e.getSupportedProtocols(), e.getSupportedProtocols());
357f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
3580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
3590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
360f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin    public void test_SSLEngine_getEnabledProtocols_returnsCopies() throws Exception {
3610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
362059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
363f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin        assertNotSame(e.getEnabledProtocols(), e.getEnabledProtocols());
364f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
3650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
3660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
367ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin    public void test_SSLEngine_setEnabledProtocols_storesCopy() throws Exception {
368ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        TestSSLContext c = TestSSLContext.create();
369ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        SSLEngine e = c.clientContext.createSSLEngine();
370ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        String[] array = new String[] {e.getEnabledProtocols()[0]};
371ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        String originalFirstElement = array[0];
372ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        e.setEnabledProtocols(array);
373ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        array[0] = "Modified after having been set";
374ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin        assertEquals(originalFirstElement, e.getEnabledProtocols()[0]);
375ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin    }
376ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin
3770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setEnabledProtocols() throws Exception {
3780c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
379059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
3800c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
3810c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledProtocols(null);
3830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3850c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3860c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3870c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledProtocols(new String[1]);
3880c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3890c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3900c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3910c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
3920c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setEnabledProtocols(new String[] { "Bogus" } );
3930c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
3940c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalArgumentException expected) {
3950c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
3960c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledProtocols(new String[0]);
3970c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledProtocols(e.getEnabledProtocols());
3980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setEnabledProtocols(e.getSupportedProtocols());
399358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin
400358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin        // Check that setEnabledProtocols affects getEnabledProtocols
4013ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root        for (String protocol : e.getSupportedProtocols()) {
4023ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            if ("SSLv2Hello".equals(protocol)) {
4033ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                try {
4043ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    e.setEnabledProtocols(new String[] { protocol });
4053ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                    fail("Should fail when SSLv2Hello is set by itself");
4063ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                } catch (IllegalArgumentException expected) {}
4073ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            } else {
4083ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                String[] protocols = new String[] { protocol };
4093ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                e.setEnabledProtocols(protocols);
4103ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                assertEquals(Arrays.deepToString(protocols),
4113ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root                        Arrays.deepToString(e.getEnabledProtocols()));
4123ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root            }
4133ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root        }
414358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin
415f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4160c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4170c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_getSession() throws Exception {
4190c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
420059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
4210c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLSession session = e.getSession();
4220c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(session);
4230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(session.isValid());
424f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4260c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_beginHandshake() throws Exception {
4280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
4290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
431059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            c.clientContext.createSSLEngine().beginHandshake();
4320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
4330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (IllegalStateException expected) {
4340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
4350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertConnected(TestSSLEnginePair.create(null));
437f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
438f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_beginHandshake_noKeyStore() throws Exception {
4426882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom        TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
4436882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom                                                 SSLContext.getDefault(), SSLContext.getDefault());
4440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
4450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            // TODO Fix KnownFailure AlertException "NO SERVER CERTIFICATE FOUND"
4460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            // ServerHandshakeImpl.selectSuite should not select a suite without a required cert
447059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            TestSSLEnginePair.connect(c, null);
4480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
4490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (SSLHandshakeException expected) {
4500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
451f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_beginHandshake_noClientCertificate() throws Exception {
455059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
456059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine[] engines = TestSSLEnginePair.connect(c, null);
4570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertConnected(engines[0], engines[1]);
458f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_getUseClientMode() throws Exception {
4620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
463059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        assertFalse(c.clientContext.createSSLEngine().getUseClientMode());
464059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        assertFalse(c.clientContext.createSSLEngine(null, -1).getUseClientMode());
465f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
4660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4680c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setUseClientMode() throws Exception {
469727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        boolean[] finished;
470727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root
4710c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // client is client, server is server
472727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        finished = new boolean[2];
473727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertConnected(test_SSLEngine_setUseClientMode(true, false, finished));
474727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertTrue(finished[0]);
475727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertTrue(finished[1]);
4760c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // client is server, server is client
478727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        finished = new boolean[2];
479727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertConnected(test_SSLEngine_setUseClientMode(false, true, finished));
480727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertTrue(finished[0]);
481727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertTrue(finished[1]);
4820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // both are client
484727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        /*
485727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root         * Our implementation throws an SSLHandshakeException, but RI just
486727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root         * stalls forever
487727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root         */
488727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        try {
489727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            assertNotConnected(test_SSLEngine_setUseClientMode(true, true, null));
490727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            assertTrue(StandardNames.IS_RI);
491727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        } catch (SSLHandshakeException maybeExpected) {
492727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root            assertFalse(StandardNames.IS_RI);
493727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        }
4940c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4950c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // both are server
496727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        assertNotConnected(test_SSLEngine_setUseClientMode(false, false, null));
4970c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
4980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
4995f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom    public void test_SSLEngine_setUseClientMode_afterHandshake() throws Exception {
5005f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
5015f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        // can't set after handshake
5025f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        TestSSLEnginePair pair = TestSSLEnginePair.create(null);
5035f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
5045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            pair.server.setUseClientMode(false);
5055f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
5065f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (IllegalArgumentException expected) {
5075f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
5085f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        try {
5095f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            pair.client.setUseClientMode(false);
5105f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom            fail();
5115f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        } catch (IllegalArgumentException expected) {
5125f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom        }
5135f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom    }
5145f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom
5150c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
516727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                                                              final boolean serverClientMode,
517727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root                                                              final boolean[] finished)
5180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throws Exception {
519059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext c;
520059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        if (!clientClientMode && serverClientMode) {
521059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            c = TestSSLContext.create(TestKeyStore.getServer(), TestKeyStore.getClient());
522059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        } else {
523059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom            c = TestSSLContext.create();
524059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        }
525059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom
526059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        return TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
5270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            @Override
5280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
5290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                client.setUseClientMode(clientClientMode);
5300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                server.setUseClientMode(serverClientMode);
5310c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            }
532727df1258e3b8386afea4778626c9ab16ef467d6Kenny Root        }, finished);
5330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
5340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_clientAuth() throws Exception {
5360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
537059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
5380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(e.getWantClientAuth());
5400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(e.getNeedClientAuth());
5410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // confirm turning one on by itself
5430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setWantClientAuth(true);
5440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(e.getWantClientAuth());
5450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(e.getNeedClientAuth());
5460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // confirm turning setting on toggles the other
5480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setNeedClientAuth(true);
5490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(e.getWantClientAuth());
5500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(e.getNeedClientAuth());
5510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // confirm toggling back
5530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        e.setWantClientAuth(true);
5540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(e.getWantClientAuth());
5550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertFalse(e.getNeedClientAuth());
5560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        // TODO Fix KnownFailure "init - invalid private key"
558059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext clientAuthContext
559059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                = TestSSLContext.create(TestKeyStore.getClientCertificate(),
560059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                        TestKeyStore.getServer());
561059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLEnginePair p = TestSSLEnginePair.create(clientAuthContext,
562059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                       new TestSSLEnginePair.Hooks() {
5630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            @Override
564059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
5650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                server.setWantClientAuth(true);
5660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            }
5670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        });
5680c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertConnected(p);
5690c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(p.client.getSession().getLocalCertificates());
570059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestKeyStore.assertChainLength(p.client.getSession().getLocalCertificates());
571059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        TestSSLContext.assertClientCertificateChain(clientAuthContext.clientTrustManager,
572059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom                                                    p.client.getSession().getLocalCertificates());
573f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        clientAuthContext.close();
574f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
5750c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
5760c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
5777c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins   /**
5787c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * http://code.google.com/p/android/issues/detail?id=31903
5797c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * This test case directly tests the fix for the issue.
5807c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    */
5817c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    public void test_SSLEngine_clientAuthWantedNoClientCert() throws Exception {
5827c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        TestSSLContext clientAuthContext
5837c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                = TestSSLContext.create(TestKeyStore.getClient(),
5847c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                                        TestKeyStore.getServer());
5857c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        TestSSLEnginePair p = TestSSLEnginePair.create(clientAuthContext,
5867c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                                                       new TestSSLEnginePair.Hooks() {
5877c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            @Override
5887c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
5897c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                server.setWantClientAuth(true);
5907c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            }
5917c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        });
5927c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        assertConnected(p);
5937c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        clientAuthContext.close();
5947c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    }
5957c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins
5967c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins   /**
5977c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * http://code.google.com/p/android/issues/detail?id=31903
5987c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * This test case verifies that if the server requires a client cert
5997c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * (setNeedClientAuth) but the client does not provide one SSL connection
6007c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    * establishment will fail
6017c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    */
6027c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    public void test_SSLEngine_clientAuthNeededNoClientCert() throws Exception {
6037c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        boolean handshakeExceptionCaught = false;
6047c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        TestSSLContext clientAuthContext
6057c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                = TestSSLContext.create(TestKeyStore.getClient(),
6067c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                                        TestKeyStore.getServer());
6077c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        try {
6087c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            TestSSLEnginePair.create(clientAuthContext,
6097c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                             new TestSSLEnginePair.Hooks() {
6107c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                @Override
6117c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
6127c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                    server.setNeedClientAuth(true);
6137c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins                }
6147c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            });
6157c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            fail();
6167c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        } catch (SSLHandshakeException expected) {
6177c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        } finally {
6187c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins            clientAuthContext.close();
6197c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins        }
6207c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins    }
6217c935d4e4ca990334200cf5eb4fbcfac718c6b45gcollins
6220c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_getEnableSessionCreation() throws Exception {
6230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
624059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
6250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertTrue(e.getEnableSessionCreation());
626f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
6270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
6280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setEnableSessionCreation_server() throws Exception {
630a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root        try {
631a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            TestSSLEnginePair p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
632a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root                @Override
633a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
634a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root                    server.setEnableSessionCreation(false);
635a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root                }
636a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            });
637a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            // For some reason, the RI doesn't throw an SSLException.
638a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            assertTrue(StandardNames.IS_RI);
639a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            assertNotConnected(p);
640a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root        } catch (SSLException maybeExpected) {
641a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root            assertFalse(StandardNames.IS_RI);
642a368cef707903c2adc7868ba48a95ccdac5f7625Kenny Root        }
6430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
6440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setEnableSessionCreation_client() throws Exception {
6460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        try {
6470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
6480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                @Override
6490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
6500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                    client.setEnableSessionCreation(false);
6510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                }
6520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            });
6530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            fail();
6540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        } catch (SSLException expected) {
6550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
6560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
6570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_getSSLParameters() throws Exception {
6590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
660059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
6610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        SSLParameters p = e.getSSLParameters();
6630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(p);
6640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] cipherSuites = p.getCipherSuites();
6660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(cipherSuites, e.getEnabledCipherSuites());
6670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
6680c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6690c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] protocols = p.getProtocols();
6700c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotSame(protocols, e.getEnabledProtocols());
6710c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
6720c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6730c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(p.getWantClientAuth(), e.getWantClientAuth());
6740c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertEquals(p.getNeedClientAuth(), e.getNeedClientAuth());
675f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
676f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
6770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
6780c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6790c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_SSLEngine_setSSLParameters() throws Exception {
6800c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLContext c = TestSSLContext.create();
681059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        SSLEngine e = c.clientContext.createSSLEngine();
6820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] defaultCipherSuites = e.getEnabledCipherSuites();
6830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] defaultProtocols = e.getEnabledProtocols();
6840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] supportedCipherSuites = e.getSupportedCipherSuites();
6850c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        String[] supportedProtocols = e.getSupportedProtocols();
6860c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6870c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
6880c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters();
6890c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setSSLParameters(p);
6900c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(defaultCipherSuites),
6910c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(e.getEnabledCipherSuites()));
6920c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(defaultProtocols),
6930c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(e.getEnabledProtocols()));
6940c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
6950c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
6960c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
6970c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters(supportedCipherSuites,
6980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                                                supportedProtocols);
6990c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setSSLParameters(p);
7000c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(supportedCipherSuites),
7010c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(e.getEnabledCipherSuites()));
7020c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertEquals(Arrays.asList(supportedProtocols),
7030c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                         Arrays.asList(e.getEnabledProtocols()));
7040c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
7050c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        {
7060c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            SSLParameters p = new SSLParameters();
7070c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
7080c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setNeedClientAuth(true);
7090c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getNeedClientAuth());
7100c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getWantClientAuth());
7110c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setSSLParameters(p);
7120c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(e.getNeedClientAuth());
7130c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getWantClientAuth());
7140c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
7150c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setWantClientAuth(true);
7160c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(e.getNeedClientAuth());
7170c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getWantClientAuth());
7180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setSSLParameters(p);
7190c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getNeedClientAuth());
7200c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(e.getWantClientAuth());
7210c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
7220c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            p.setWantClientAuth(false);
7230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getNeedClientAuth());
7240c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertTrue(e.getWantClientAuth());
7250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            e.setSSLParameters(p);
7260c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getNeedClientAuth());
7270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            assertFalse(e.getWantClientAuth());
7280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
729f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom        c.close();
7300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
7310c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
7320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    public void test_TestSSLEnginePair_create() throws Exception {
7330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        TestSSLEnginePair test = TestSSLEnginePair.create(null);
7340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(test.c);
7350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(test.server);
7360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertNotNull(test.client);
7370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        assertConnected(test);
7380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
7390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom}
740