Importing more Android integration tests. (#185)

diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/AbstractSSLTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/AbstractSSLTest.java
new file mode 100644
index 0000000..3bfc8e7
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/AbstractSSLTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.javax.net.ssl;
+
+import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
+
+import org.junit.BeforeClass;
+
+/**
+ * Abstract base class for all SSL integration tests. This sets up the default TLS provider.
+ */
+public abstract class AbstractSSLTest {
+
+    @BeforeClass
+    public static void setupStatic() {
+        installConscryptAsDefaultProvider();
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java
new file mode 100644
index 0000000..fec135d
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/HttpsURLConnectionTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class HttpsURLConnectionTest extends AbstractSSLTest {
+    /**
+     * HTTPS URL which cannot be resolved and is thus safe to use in tests where network traffic
+     * should be avoided.
+     */
+    private static final String UNRESOLVABLE_HTTPS_URL = "https:///";
+
+    @Test
+    public void testDefaultHostnameVerifierNotNull() {
+        assertNotNull(HttpsURLConnection.getDefaultHostnameVerifier());
+    }
+
+    @Test
+    public void testDefaultHostnameVerifierUsedForNewConnectionsByDefault() throws IOException {
+        HostnameVerifier originalHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+        HttpsURLConnection connection =
+                (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+        try {
+            assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
+        } finally {
+            connection.disconnect();
+        }
+
+        HostnameVerifier anotherVerifier = new FakeHostnameVerifier();
+        try {
+            HttpsURLConnection.setDefaultHostnameVerifier(anotherVerifier);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(anotherVerifier, connection.getHostnameVerifier());
+            } finally {
+                connection.disconnect();
+            }
+
+            HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
+            } finally {
+                connection.disconnect();
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
+        }
+    }
+
+    @Test
+    public void testDefaultSSLSocketFactoryNotNull() {
+        assertNotNull(HttpsURLConnection.getDefaultSSLSocketFactory());
+    }
+
+    @Test
+    public void testDefaultSSLSocketFactoryUsedForNewConnectionsByDefault() throws IOException {
+        SSLSocketFactory originalFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
+        HttpsURLConnection connection =
+                (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+        try {
+            assertSame(originalFactory, connection.getSSLSocketFactory());
+        } finally {
+            connection.disconnect();
+        }
+
+        SSLSocketFactory anotherFactory = new FakeSSLSocketFactory();
+        try {
+            HttpsURLConnection.setDefaultSSLSocketFactory(anotherFactory);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(anotherFactory, connection.getSSLSocketFactory());
+            } finally {
+                connection.disconnect();
+            }
+
+            HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(originalFactory, connection.getSSLSocketFactory());
+            } finally {
+                connection.disconnect();
+            }
+        } finally {
+            HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
+        }
+    }
+
+    private static final class FakeHostnameVerifier implements HostnameVerifier {
+        @Override
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+
+    private static final class FakeSSLSocketFactory extends SSLSocketFactory {
+        FakeSSLSocketFactory() {}
+
+        @Override
+        public String[] getDefaultCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(
+                InetAddress address, int port, InetAddress localAddress, int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(InetAddress host, int port) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
new file mode 100644
index 0000000..e02394c
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore.Builder;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Set;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.KeyStoreBuilderParameters;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+import libcore.java.security.StandardNames;
+import libcore.java.security.TestKeyStore;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class KeyManagerFactoryTest extends AbstractSSLTest {
+    private TestKeyStore testKeyStore;
+
+    @Before
+    public void setUp() throws Exception {
+        // note the rare usage of DSA keys here in addition to RSA
+        testKeyStore = new TestKeyStore.Builder()
+                               .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
+                               .aliasPrefix("rsa-dsa-ec-dh")
+                               .build();
+    }
+
+    private TestKeyStore getTestKeyStore() throws Exception {
+        return testKeyStore;
+    }
+
+    @Test
+    public void test_KeyManagerFactory_getDefaultAlgorithm() throws Exception {
+        String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+        assertEquals(StandardNames.KEY_MANAGER_FACTORY_DEFAULT, algorithm);
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
+        test_KeyManagerFactory(kmf);
+    }
+
+    private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
+
+    private static boolean supportsManagerFactoryParameters(String algorithm) {
+        // Only the "New" one supports ManagerFactoryParameters
+        return algorithm.equals("NewSunX509");
+    }
+
+    private static String[] keyTypes(String algorithm) {
+        // Although the "New" one supports ManagerFactoryParameters,
+        // it can't handle nulls in the key types array.
+        return (algorithm.equals("NewSunX509") ? KEY_TYPES_WITH_EMPTY
+                                               : KEY_TYPES_WITH_EMPTY_AND_NULL);
+    }
+
+    private void test_KeyManagerFactory(KeyManagerFactory kmf) throws Exception {
+        assertNotNull(kmf);
+        assertNotNull(kmf.getAlgorithm());
+        assertNotNull(kmf.getProvider());
+
+        // before init
+        try {
+            kmf.getKeyManagers();
+            fail();
+        } catch (IllegalStateException expected) {
+            // Ignore
+        }
+
+        // init with null ManagerFactoryParameters
+        try {
+            kmf.init(null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignore
+        }
+
+        // init with useless ManagerFactoryParameters
+        try {
+            kmf.init(new UselessManagerFactoryParameters());
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignore
+        }
+
+        // init with KeyStoreBuilderParameters ManagerFactoryParameters
+        PasswordProtection pp = new PasswordProtection(getTestKeyStore().storePassword);
+        Builder builder = Builder.newInstance(getTestKeyStore().keyStore, pp);
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
+        if (supportsManagerFactoryParameters(kmf.getAlgorithm())) {
+            kmf.init(ksbp);
+            test_KeyManagerFactory_getKeyManagers(kmf, false);
+        } else {
+            try {
+                kmf.init(ksbp);
+                fail();
+            } catch (InvalidAlgorithmParameterException expected) {
+                // Ignore
+            }
+        }
+
+        // init with null for default behavior
+        kmf.init(null, null);
+        test_KeyManagerFactory_getKeyManagers(kmf, true);
+
+        // init with specific key store and password
+        kmf.init(getTestKeyStore().keyStore, getTestKeyStore().storePassword);
+        test_KeyManagerFactory_getKeyManagers(kmf, false);
+    }
+
+    private void test_KeyManagerFactory_getKeyManagers(KeyManagerFactory kmf, boolean empty)
+            throws Exception {
+        KeyManager[] keyManagers = kmf.getKeyManagers();
+        assertNotNull(keyManagers);
+        assertTrue(keyManagers.length > 0);
+        for (KeyManager keyManager : keyManagers) {
+            assertNotNull(keyManager);
+            if (keyManager instanceof X509KeyManager) {
+                test_X509KeyManager((X509KeyManager) keyManager, empty, kmf.getAlgorithm());
+            }
+        }
+    }
+
+    private static final String[] KEY_TYPES_ONLY =
+            StandardNames.KEY_TYPES.toArray(new String[StandardNames.KEY_TYPES.size()]);
+    private static final String[] KEY_TYPES_WITH_EMPTY = new String[KEY_TYPES_ONLY.length + 1];
+    private static final String[] KEY_TYPES_WITH_EMPTY_AND_NULL =
+            new String[KEY_TYPES_ONLY.length + 2];
+    static {
+        System.arraycopy(KEY_TYPES_ONLY, 0, KEY_TYPES_WITH_EMPTY, 0, KEY_TYPES_ONLY.length);
+        KEY_TYPES_WITH_EMPTY[KEY_TYPES_WITH_EMPTY.length - 1] = "";
+
+        System.arraycopy(KEY_TYPES_WITH_EMPTY, 0, KEY_TYPES_WITH_EMPTY_AND_NULL, 0,
+                KEY_TYPES_WITH_EMPTY.length);
+        // extra null at end requires no initialization
+    }
+
+    private void test_X509KeyManager(X509KeyManager km, boolean empty, String algorithm)
+            throws Exception {
+        String[] keyTypes = keyTypes(algorithm);
+        for (String keyType : keyTypes) {
+            String[] aliases = km.getClientAliases(keyType, null);
+            if (empty || keyType == null || keyType.isEmpty()) {
+                assertNull(keyType, aliases);
+                continue;
+            }
+            assertNotNull(keyType, aliases);
+            for (String alias : aliases) {
+                test_X509KeyManager_alias(km, alias, keyType, false, empty);
+            }
+        }
+        for (String keyType : keyTypes) {
+            String[] aliases = km.getServerAliases(keyType, null);
+            if (empty || keyType == null || keyType.isEmpty()) {
+                assertNull(keyType, aliases);
+                continue;
+            }
+            assertNotNull(keyType, aliases);
+            for (String alias : aliases) {
+                test_X509KeyManager_alias(km, alias, keyType, false, empty);
+            }
+        }
+
+        String a = km.chooseClientAlias(keyTypes, null, null);
+        test_X509KeyManager_alias(km, a, null, true, empty);
+
+        for (String keyType : keyTypes) {
+            String[] array = new String[] {keyType};
+            String alias = km.chooseClientAlias(array, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        for (String keyType : keyTypes) {
+            String alias = km.chooseServerAlias(keyType, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        if (km instanceof X509ExtendedKeyManager) {
+            test_X509ExtendedKeyManager((X509ExtendedKeyManager) km, empty, algorithm);
+        }
+    }
+
+    private void test_X509ExtendedKeyManager(
+            X509ExtendedKeyManager km, boolean empty, String algorithm) throws Exception {
+        String[] keyTypes = keyTypes(algorithm);
+        String a = km.chooseEngineClientAlias(keyTypes, null, null);
+        test_X509KeyManager_alias(km, a, null, true, empty);
+        for (String keyType : keyTypes) {
+            String[] array = new String[] {keyType};
+            String alias = km.chooseEngineClientAlias(array, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        for (String keyType : keyTypes) {
+            String alias = km.chooseEngineServerAlias(keyType, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+    }
+
+    private void test_X509KeyManager_alias(X509KeyManager km, String alias, String keyType,
+            boolean many, boolean empty) throws Exception {
+        if (empty || (!many && (keyType == null || keyType.isEmpty()))) {
+            assertNull(keyType, alias);
+            assertNull(keyType, km.getCertificateChain(alias));
+            assertNull(keyType, km.getPrivateKey(alias));
+            return;
+        }
+        assertNotNull(keyType, alias);
+
+        X509Certificate[] certificateChain = km.getCertificateChain(alias);
+        PrivateKey privateKey = km.getPrivateKey(alias);
+
+        String keyAlgName = privateKey.getAlgorithm();
+
+        X509Certificate certificate = certificateChain[0];
+        assertEquals(keyType, keyAlgName, certificate.getPublicKey().getAlgorithm());
+
+        String sigAlgName = certificate.getSigAlgName();
+
+        PrivateKeyEntry privateKeyEntry = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
+
+        assertEquals(keyType, Arrays.asList(privateKeyEntry.getCertificateChain()),
+                Arrays.<Certificate>asList(certificateChain));
+        assertEquals(keyType, privateKeyEntry.getPrivateKey(), privateKey);
+
+        if (keyType != null) {
+            assertEquals(TestKeyStore.keyAlgorithm(keyType), keyAlgName);
+
+            // Skip this when we're given only "DH" or "EC" instead of "DH_DSA",
+            // "EC_RSA", etc. since we don't know what the expected
+            // algorithm was.
+            if (!keyType.equals("DH") && !keyType.equals("EC")) {
+                assertTrue(sigAlgName.contains(TestKeyStore.signatureAlgorithm(keyType)));
+            }
+        }
+    }
+
+    @Test
+    public void test_KeyManagerFactory_getInstance() throws Exception {
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("KeyManagerFactory")) {
+                    continue;
+                }
+                String algorithm = service.getAlgorithm();
+                try {
+                    {
+                        KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
+                        assertEquals(algorithm, kmf.getAlgorithm());
+                        test_KeyManagerFactory(kmf);
+                    }
+
+                    {
+                        KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm, provider);
+                        assertEquals(algorithm, kmf.getAlgorithm());
+                        assertEquals(provider, kmf.getProvider());
+                        test_KeyManagerFactory(kmf);
+                    }
+
+                    {
+                        KeyManagerFactory kmf =
+                                KeyManagerFactory.getInstance(algorithm, provider.getName());
+                        assertEquals(algorithm, kmf.getAlgorithm());
+                        assertEquals(provider, kmf.getProvider());
+                        test_KeyManagerFactory(kmf);
+                    }
+                } catch (Exception e) {
+                    throw new Exception("Problem with algorithm " + algorithm, e);
+                }
+            }
+        }
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java
new file mode 100644
index 0000000..8303cd2
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/KeyStoreBuilderParametersTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.security.KeyStore.Builder;
+import java.security.KeyStore.PasswordProtection;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.KeyStoreBuilderParameters;
+import libcore.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class KeyStoreBuilderParametersTest extends AbstractSSLTest {
+    @Test
+    public void test_init_Builder_null() {
+        try {
+            new KeyStoreBuilderParameters((Builder) null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_init_Builder() {
+        TestKeyStore testKeyStore = TestKeyStore.getClient();
+        Builder builder = Builder.newInstance(
+                testKeyStore.keyStore, new PasswordProtection(testKeyStore.storePassword));
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
+        assertNotNull(ksbp);
+        assertNotNull(ksbp.getParameters());
+        assertEquals(1, ksbp.getParameters().size());
+        assertSame(builder, ksbp.getParameters().get(0));
+    }
+
+    @Test
+    public void test_init_List_null() {
+        try {
+            new KeyStoreBuilderParameters((List<Builder>) null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_init_List() {
+        TestKeyStore testKeyStore1 = TestKeyStore.getClient();
+        TestKeyStore testKeyStore2 = TestKeyStore.getServer();
+        Builder builder1 = Builder.newInstance(
+                testKeyStore1.keyStore, new PasswordProtection(testKeyStore1.storePassword));
+        Builder builder2 = Builder.newInstance(
+                testKeyStore2.keyStore, new PasswordProtection(testKeyStore2.storePassword));
+
+        List<Builder> list = Arrays.asList(builder1, builder2);
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(list);
+        assertNotNull(ksbp);
+        assertNotNull(ksbp.getParameters());
+        assertNotSame(list, ksbp.getParameters());
+        assertEquals(2, ksbp.getParameters().size());
+        assertSame(builder1, ksbp.getParameters().get(0));
+        assertSame(builder2, ksbp.getParameters().get(1));
+
+        // confirm result is not modifiable
+        try {
+            ksbp.getParameters().set(0, builder2);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+            // Ignored.
+        }
+
+        // confirm result is a copy of original
+        list.set(0, builder2);
+        assertSame(builder1, ksbp.getParameters().get(0));
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java
new file mode 100644
index 0000000..da1598d
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SNIHostNameTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.StandardConstants;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SNIHostNameTest extends AbstractSSLTest {
+    @Test
+    public void test_byteArray_Constructor() throws Exception {
+        // From draft-josefsson-idn-test-vectors-00 section 5.2
+        byte[] idnEncoded = new byte[] {
+                (byte) 0xE4, (byte) 0xBB, (byte) 0x96, (byte) 0xE4, (byte) 0xBB, (byte) 0xAC,
+                (byte) 0xE4, (byte) 0xB8, (byte) 0xBA, (byte) 0xE4, (byte) 0xBB, (byte) 0x80,
+                (byte) 0xE4, (byte) 0xB9, (byte) 0x88, (byte) 0xE4, (byte) 0xB8, (byte) 0x8D,
+                (byte) 0xE8, (byte) 0xAF, (byte) 0xB4, (byte) 0xE4, (byte) 0xB8, (byte) 0xAD,
+                (byte) 0xE6, (byte) 0x96, (byte) 0x87,
+        };
+
+        SNIHostName hostName = new SNIHostName(idnEncoded);
+        assertEquals("xn--ihqwcrb4cv8a8dqg056pqjye", hostName.getAsciiName());
+        assertEquals(StandardConstants.SNI_HOST_NAME, hostName.getType());
+        assertEquals(Arrays.toString(idnEncoded), Arrays.toString(hostName.getEncoded()));
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLContextTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
index 5e8e73e..fecdd1b 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLContextTest.java
@@ -16,7 +16,6 @@
 
 package libcore.javax.net.ssl;
 
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
@@ -59,17 +58,12 @@
 import junit.framework.AssertionFailedError;
 import libcore.java.security.StandardNames;
 import org.conscrypt.Conscrypt;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLContextTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLContextTest extends AbstractSSLTest {
 
     @Test
     public void test_SSLContext_getDefault() throws Exception {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index 97ca890..01c94e4 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -17,7 +17,6 @@
 package libcore.javax.net.ssl;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -46,17 +45,12 @@
 import javax.net.ssl.X509ExtendedKeyManager;
 import libcore.java.security.StandardNames;
 import libcore.java.security.TestKeyStore;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLEngineTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLEngineTest extends AbstractSSLTest {
 
     @Test
     public void test_SSLEngine_defaultConfiguration() throws Exception {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
index 7f20660..1831533 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
@@ -16,7 +16,6 @@
 
 package libcore.javax.net.ssl;
 
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -33,17 +32,12 @@
 import javax.net.ssl.SNIMatcher;
 import javax.net.ssl.SNIServerName;
 import javax.net.ssl.SSLParameters;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLParametersTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLParametersTest extends AbstractSSLTest {
 
     @Test
     public void test_SSLParameters_emptyConstructor() {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
index 9dafd24..48a0cc3 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketFactoryTest.java
@@ -16,20 +16,13 @@
 
 package libcore.javax.net.ssl;
 
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
-
 import javax.net.ssl.SSLServerSocketFactory;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLServerSocketFactoryTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLServerSocketFactoryTest extends AbstractSSLTest {
 
     @Test
     public void testDefaultConfiguration() throws Exception {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
index 1bb9c79..0898622 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLServerSocketTest.java
@@ -16,23 +16,17 @@
 
 package libcore.javax.net.ssl;
 
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertEquals;
 
 import java.util.Arrays;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLServerSocketTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLServerSocketTest extends AbstractSSLTest {
 
     @Test
     public void testDefaultConfiguration() throws Exception {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java
new file mode 100644
index 0000000..72de22f
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionContextTest.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.Provider;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SSLSessionContextTest extends AbstractSSLTest {
+
+    @Test
+    public void test_SSLSessionContext_getIds() {
+        TestSSLContext c = TestSSLContext.create();
+        assertSSLSessionContextSize(0, c);
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        assertSSLSessionContextSize(1, s.c);
+        Enumeration<byte[]> clientIds = s.c.clientContext.getClientSessionContext().getIds();
+        Enumeration<byte[]> serverIds = s.c.serverContext.getServerSessionContext().getIds();
+        byte[] clientId = clientIds.nextElement();
+        assertEquals(32, clientId.length);
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertFalse(serverIds.hasMoreElements());
+        } else {
+            byte[] serverId = serverIds.nextElement();
+            assertEquals(32, serverId.length);
+            assertTrue(Arrays.equals(clientId, serverId));
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSession() {
+        TestSSLContext c = TestSSLContext.create();
+        try {
+            c.clientContext.getClientSessionContext().getSession(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+        assertNull(c.clientContext.getClientSessionContext().getSession(new byte[0]));
+        assertNull(c.clientContext.getClientSessionContext().getSession(new byte[1]));
+        try {
+            c.serverContext.getServerSessionContext().getSession(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+        assertNull(c.serverContext.getServerSessionContext().getSession(new byte[0]));
+        assertNull(c.serverContext.getServerSessionContext().getSession(new byte[1]));
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        SSLSessionContext client = s.c.clientContext.getClientSessionContext();
+        SSLSessionContext server = s.c.serverContext.getServerSessionContext();
+        byte[] clientId = client.getIds().nextElement();
+        assertNotNull(client.getSession(clientId));
+        assertTrue(Arrays.equals(clientId, client.getSession(clientId).getId()));
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertFalse(server.getIds().hasMoreElements());
+        } else {
+            byte[] serverId = server.getIds().nextElement();
+            assertNotNull(server.getSession(serverId));
+            assertTrue(Arrays.equals(serverId, server.getSession(serverId).getId()));
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSessionCacheSize() {
+        TestSSLContext c = TestSSLContext.create();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(c);
+        assertEquals(expectedClientSessionCacheSize,
+                c.clientContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize,
+                c.serverContext.getServerSessionContext().getSessionCacheSize());
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        assertEquals(expectedClientSessionCacheSize,
+                s.c.clientContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize,
+                s.c.serverContext.getServerSessionContext().getSessionCacheSize());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_noConnect() {
+        TestSSLContext c = TestSSLContext.create();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(c);
+        assertNoConnectSetSessionCacheSizeBehavior(
+                expectedClientSessionCacheSize,
+                c.clientContext.getClientSessionContext());
+        assertNoConnectSetSessionCacheSizeBehavior(
+                expectedServerSessionCacheSize,
+                c.serverContext.getServerSessionContext());
+        c.close();
+    }
+
+    private static void assertNoConnectSetSessionCacheSizeBehavior(
+            int expectedDefault, SSLSessionContext s) {
+        try {
+            s.setSessionCacheSize(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        assertEquals(expectedDefault, s.getSessionCacheSize());
+        s.setSessionCacheSize(1);
+        assertEquals(1, s.getSessionCacheSize());
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_oneConnect() {
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(s.c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(s.c);
+        SSLSessionContext client = s.c.clientContext.getClientSessionContext();
+        SSLSessionContext server = s.c.serverContext.getServerSessionContext();
+        assertEquals(expectedClientSessionCacheSize,
+                client.getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize,
+                server.getSessionCacheSize());
+        assertSSLSessionContextSize(1, s.c);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_dynamic() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLSessionContext client = c.clientContext.getClientSessionContext();
+        SSLSessionContext server = c.serverContext.getServerSessionContext();
+
+        String[] supportedCipherSuites = c.serverSocket.getSupportedCipherSuites();
+        c.serverSocket.setEnabledCipherSuites(supportedCipherSuites);
+        LinkedList<String> uniqueCipherSuites =
+                new LinkedList<>(Arrays.asList(supportedCipherSuites));
+        // only use RSA cipher suites which will work with our TrustProvider
+        Iterator<String> i = uniqueCipherSuites.iterator();
+        while (i.hasNext()) {
+            String cipherSuite = i.next();
+
+            // Certificate key length too long for export ciphers
+            if (cipherSuite.startsWith("SSL_RSA_EXPORT_")) {
+                i.remove();
+                continue;
+            }
+
+            if (cipherSuite.startsWith("SSL_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_DHE_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("SSL_DHE_RSA_")) {
+                continue;
+            }
+            i.remove();
+        }
+
+        /*
+         * having more than 3 uniqueCipherSuites is a test
+         * requirement, not a requirement of the interface or
+         * implementation. It simply allows us to make sure that we
+         * will not get a cached session ID since we'll have to
+         * renegotiate a new session due to the new cipher suite
+         * requirement. even this test only really needs three if it
+         * reused the unique cipher suites every time it resets the
+         * session cache.
+         */
+        assertTrue(uniqueCipherSuites.size() >= 3);
+        String cipherSuite1 = uniqueCipherSuites.get(0);
+        String cipherSuite2 = uniqueCipherSuites.get(1);
+        String cipherSuite3 = uniqueCipherSuites.get(2);
+
+        List<SSLSocket[]> toClose = new ArrayList<>();
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite1}, null));
+        assertSSLSessionContextSize(1, c);
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite2}, null));
+        assertSSLSessionContextSize(2, c);
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite3}, null));
+        assertSSLSessionContextSize(3, c);
+
+        client.setSessionCacheSize(1);
+        server.setSessionCacheSize(1);
+        assertEquals(1, client.getSessionCacheSize());
+        assertEquals(1, server.getSessionCacheSize());
+        assertSSLSessionContextSize(1, c);
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite1}, null));
+        assertSSLSessionContextSize(1, c);
+
+        client.setSessionCacheSize(2);
+        server.setSessionCacheSize(2);
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite2}, null));
+        assertSSLSessionContextSize(2, c);
+        toClose.add(TestSSLSocketPair.connect(c, new String[] {cipherSuite3}, null));
+        assertSSLSessionContextSize(2, c);
+
+        for (SSLSocket[] pair : toClose) {
+            for (SSLSocket s : pair) {
+                s.close();
+            }
+        }
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSessionTimeout() {
+        TestSSLContext c = TestSSLContext.create();
+        int expectedCacheTimeout = expectedSslSessionCacheTimeout(c);
+        assertEquals(expectedCacheTimeout,
+                c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                c.serverContext.getServerSessionContext().getSessionTimeout());
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        assertEquals(expectedCacheTimeout,
+                s.c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                s.c.serverContext.getServerSessionContext().getSessionTimeout());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionTimeout() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        int expectedCacheTimeout = expectedSslSessionCacheTimeout(c);
+        assertEquals(expectedCacheTimeout,
+                c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                c.serverContext.getServerSessionContext().getSessionTimeout());
+        c.clientContext.getClientSessionContext().setSessionTimeout(0);
+        c.serverContext.getServerSessionContext().setSessionTimeout(0);
+        assertEquals(0, c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(0, c.serverContext.getServerSessionContext().getSessionTimeout());
+
+        try {
+            c.clientContext.getClientSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            c.serverContext.getServerSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create();
+        assertSSLSessionContextSize(1, s.c);
+        Thread.sleep(1000);
+        s.c.clientContext.getClientSessionContext().setSessionTimeout(1);
+        s.c.serverContext.getServerSessionContext().setSessionTimeout(1);
+        assertSSLSessionContextSize(0, s.c);
+        s.close();
+    }
+
+    private static void assertSSLSessionContextSize(int expected, TestSSLContext c) {
+        assertSSLSessionContextSize(expected, c.clientContext.getClientSessionContext(),
+                c.serverContext.getServerSessionContext());
+        assertSSLSessionContextSize(0, c.serverContext.getClientSessionContext(),
+                c.clientContext.getServerSessionContext());
+    }
+
+    private static void assertSSLSessionContextSize(
+            int expected, SSLSessionContext client, SSLSessionContext server) {
+        assertSSLSessionContextSize(expected, client, false);
+        assertSSLSessionContextSize(expected, server, true);
+    }
+
+    private static void assertSSLSessionContextSize(
+            int expected, SSLSessionContext s, boolean server) {
+        int size = Collections.list(s.getIds()).size();
+        if (server && TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertEquals(0, size);
+        } else {
+            assertEquals(expected, size);
+        }
+    }
+
+    private int expectedClientSslSessionCacheSize(TestSSLContext c) {
+        return isConscrypt(c.clientContext.getProvider()) ? 10 : 0;
+    }
+
+    private int expectedServerSslSessionCacheSize(TestSSLContext c) {
+        return isConscrypt(c.serverContext.getProvider()) ? 100 : 0;
+    }
+
+    private int expectedSslSessionCacheTimeout(TestSSLContext c) {
+        return (isConscrypt(c.serverContext.getProvider())) ? 8 * 3600 : 24 * 3600;
+    }
+
+    private boolean isConscrypt(Provider provider) {
+        return "AndroidOpenSSL".equals(provider.getName());
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
new file mode 100644
index 0000000..cf6b841
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSessionTest.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import libcore.java.security.StandardNames;
+import libcore.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SSLSessionTest extends AbstractSSLTest {
+    @Test
+    public void test_SSLSocket_TestSSLSessions_create() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid);
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getApplicationBufferSize() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getApplicationBufferSize() > 0);
+        assertTrue(s.server.getApplicationBufferSize() > 0);
+        assertTrue(s.client.getApplicationBufferSize() > 0);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getCipherSuite() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getCipherSuite());
+        assertEquals(StandardNames.CIPHER_SUITE_INVALID, s.invalid.getCipherSuite());
+        assertNotNull(s.server.getCipherSuite());
+        assertNotNull(s.client.getCipherSuite());
+        assertEquals(s.server.getCipherSuite(), s.client.getCipherSuite());
+        StandardNames.assertValidCipherSuites(new String[] {s.server.getCipherSuite()});
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getCreationTime() {
+        // We use OpenSSL, which only returns times accurate to the nearest second.
+        // NativeCrypto just multiplies by 1000, which looks like truncation, which
+        // would make it appear as if the OpenSSL side of things was created before
+        // we called it.
+        long t0 = System.currentTimeMillis() / 1000;
+        TestSSLSessions s = TestSSLSessions.create();
+        long t1 = System.currentTimeMillis() / 1000;
+
+        assertTrue(s.invalid.getCreationTime() > 0);
+
+        long sTime = s.server.getCreationTime() / 1000;
+        assertTrue(sTime + " >= " + t0, sTime >= t0);
+        assertTrue(sTime + " <= " + t1, sTime <= t1);
+
+        long cTime = s.client.getCreationTime() / 1000;
+        assertTrue(cTime + " >= " + t0, cTime >= t0);
+        assertTrue(cTime + " <= " + t1, cTime <= t1);
+
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getId() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getId());
+        assertNotNull(s.server.getId());
+        assertNotNull(s.client.getId());
+        assertEquals(0, s.invalid.getId().length);
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertEquals(0, s.server.getId().length);
+        } else {
+            assertEquals(32, s.server.getId().length);
+            assertTrue(Arrays.equals(s.server.getId(), s.client.getId()));
+        }
+        assertEquals(32, s.client.getId().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLastAccessedTime() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getLastAccessedTime() > 0);
+        assertTrue(s.server.getLastAccessedTime() > 0);
+        assertTrue(s.client.getLastAccessedTime() > 0);
+        assertTrue("s.server.getLastAccessedTime()=" + s.server.getLastAccessedTime() + " "
+                        + "s.client.getLastAccessedTime()=" + s.client.getLastAccessedTime(),
+                Math.abs(s.server.getLastAccessedTime() - s.client.getLastAccessedTime())
+                        <= 1000);
+        assertTrue(s.server.getLastAccessedTime() >= s.server.getCreationTime());
+        assertTrue(s.client.getLastAccessedTime() >= s.client.getCreationTime());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLocalCertificates() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getLocalCertificates());
+        assertNull(s.client.getLocalCertificates());
+        assertNotNull(s.server.getLocalCertificates());
+        TestKeyStore.assertChainLength(s.server.getLocalCertificates());
+        TestSSLContext.assertServerCertificateChain(
+                s.s.c.serverTrustManager, s.server.getLocalCertificates());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.server.getLocalCertificates()[0], s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLocalPrincipal() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getLocalPrincipal());
+        assertNull(s.client.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal().getName());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.server.getLocalPrincipal(), s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPacketBufferSize() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getPacketBufferSize() > 0);
+        assertTrue(s.server.getPacketBufferSize() > 0);
+        assertTrue(s.client.getPacketBufferSize() > 0);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerCertificateChain() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerCertificateChain();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        TestKeyStore.assertChainLength(s.client.getPeerCertificateChain());
+        try {
+            assertNull(s.server.getPeerCertificateChain());
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerCertificates() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        TestKeyStore.assertChainLength(s.client.getPeerCertificates());
+        TestSSLContext.assertServerCertificateChain(
+                s.s.c.serverTrustManager, s.client.getPeerCertificates());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.client.getPeerCertificates()[0], s.s.c.serverKeyStore);
+        try {
+            s.server.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerHost() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getPeerHost());
+        assertNotNull(s.server.getPeerHost());
+        assertNotNull(s.client.getPeerHost());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerPort() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertEquals(-1, s.invalid.getPeerPort());
+        assertTrue(s.server.getPeerPort() > 0);
+        assertEquals(s.s.c.port, s.client.getPeerPort());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerPrincipal() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        try {
+            s.server.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerPrincipal());
+        assertNotNull(s.client.getPeerPrincipal().getName());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.client.getPeerPrincipal(), s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getProtocol() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getProtocol());
+        assertEquals("NONE", s.invalid.getProtocol());
+        assertNotNull(s.server.getProtocol());
+        assertNotNull(s.client.getProtocol());
+        assertEquals(s.server.getProtocol(), s.client.getProtocol());
+        assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(s.server.getProtocol()));
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getSessionContext() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getSessionContext());
+        assertNotNull(s.server.getSessionContext());
+        assertNotNull(s.client.getSessionContext());
+        assertEquals(s.s.c.serverContext.getServerSessionContext(), s.server.getSessionContext());
+        assertEquals(s.s.c.clientContext.getClientSessionContext(), s.client.getSessionContext());
+        assertNotSame(s.server.getSessionContext(), s.client.getSessionContext());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getValue(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        assertNull(s.invalid.getValue("BOGUS"));
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getValueNames() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getValueNames());
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_invalidate() {
+        TestSSLSessions s = TestSSLSessions.create();
+
+        assertFalse(s.invalid.isValid());
+        s.invalid.invalidate();
+        assertFalse(s.invalid.isValid());
+        assertNull(s.invalid.getSessionContext());
+
+        assertTrue(s.server.isValid());
+        s.server.invalidate();
+        assertFalse(s.server.isValid());
+        assertNull(s.server.getSessionContext());
+
+        assertTrue(s.client.isValid());
+        s.client.invalidate();
+        assertFalse(s.client.isValid());
+        assertNull(s.client.getSessionContext());
+
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_isValid() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_putValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        String key = "KEY";
+        String value = "VALUE";
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.invalid.putValue(key, value);
+        assertSame(value, s.invalid.getValue(key));
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_removeValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        String key = "KEY";
+        String value = "VALUE";
+        s.invalid.putValue(key, value);
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+        s.invalid.removeValue(key);
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.close();
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
index 707b77b..8147579 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketFactoryTest.java
@@ -16,7 +16,6 @@
 
 package libcore.javax.net.ssl;
 
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
@@ -31,17 +30,12 @@
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
-public class SSLSocketFactoryTest {
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
+public class SSLSocketFactoryTest extends AbstractSSLTest {
 
     @Test
     public void test_SSLSocketFactory_getDefault() {
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 7efd10d..a6f5502 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -17,7 +17,6 @@
 package libcore.javax.net.ssl;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.conscrypt.TestUtils.installConscryptAsDefaultProvider;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -122,7 +121,6 @@
 import org.conscrypt.Conscrypt;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -132,15 +130,10 @@
 import tests.util.Pair;
 
 @RunWith(JUnit4.class)
-public class SSLSocketTest {
+public class SSLSocketTest extends AbstractSSLTest {
     private ExecutorService executor;
     private ThreadGroup threadGroup;
 
-    @BeforeClass
-    public static void setupStatic() {
-        installConscryptAsDefaultProvider();
-    }
-
     @Before
     public void setup() {
         threadGroup = new ThreadGroup("SSLSocketTest");
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java
new file mode 100644
index 0000000..556d89f
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/TrustManagerFactoryTest.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.util.Set;
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import libcore.java.security.StandardNames;
+import libcore.java.security.TestKeyStore;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class TrustManagerFactoryTest extends AbstractSSLTest {
+    private static final String[] KEY_TYPES = new String[] {"RSA", "DSA", "EC", "EC_RSA"};
+
+    private static TestKeyStore TEST_KEY_STORE;
+
+    // note the rare usage of DSA keys here in addition to RSA
+    private static TestKeyStore getTestKeyStore() throws Exception {
+        if (TEST_KEY_STORE == null) {
+            TEST_KEY_STORE = new TestKeyStore.Builder()
+                                     .keyAlgorithms(KEY_TYPES)
+                                     .aliasPrefix("rsa-dsa-ec")
+                                     .build();
+        }
+        return TEST_KEY_STORE;
+    }
+
+    private static boolean supportsManagerFactoryParameters(String algorithm) {
+        return (StandardNames.IS_RI && algorithm.equals("PKIX"));
+    }
+
+    @Test
+    public void test_TrustManagerFactory_getDefaultAlgorithm() throws Exception {
+        String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+        assertEquals(StandardNames.TRUST_MANAGER_FACTORY_DEFAULT, algorithm);
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+        test_TrustManagerFactory(tmf);
+    }
+
+    private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
+
+    private void test_TrustManagerFactory(TrustManagerFactory tmf) throws Exception {
+        assertNotNull(tmf);
+        assertNotNull(tmf.getAlgorithm());
+        assertNotNull(tmf.getProvider());
+
+        // before init
+        try {
+            tmf.getTrustManagers();
+            fail();
+        } catch (IllegalStateException expected) {
+            // Ignored.
+        }
+
+        // init with null ManagerFactoryParameters
+        try {
+            tmf.init((ManagerFactoryParameters) null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with useless ManagerFactoryParameters
+        try {
+            tmf.init(new UselessManagerFactoryParameters());
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with PKIXParameters ManagerFactoryParameters
+        try {
+            PKIXParameters pp = new PKIXParameters(getTestKeyStore().keyStore);
+            CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pp);
+            tmf.init(cptmp);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with PKIXBuilderParameters ManagerFactoryParameters
+        X509CertSelector xcs = new X509CertSelector();
+        PKIXBuilderParameters pbp = new PKIXBuilderParameters(getTestKeyStore().keyStore, xcs);
+        CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pbp);
+        if (supportsManagerFactoryParameters(tmf.getAlgorithm())) {
+            tmf.init(cptmp);
+            test_TrustManagerFactory_getTrustManagers(tmf);
+        } else {
+            try {
+                tmf.init(cptmp);
+                fail();
+            } catch (InvalidAlgorithmParameterException expected) {
+                // Ignored.
+            }
+        }
+
+        // init with null for default KeyStore
+        tmf.init((KeyStore) null);
+        test_TrustManagerFactory_getTrustManagers(tmf);
+
+        // init with specific key store
+        tmf.init(getTestKeyStore().keyStore);
+        test_TrustManagerFactory_getTrustManagers(tmf);
+    }
+
+    private void test_TrustManagerFactory_getTrustManagers(TrustManagerFactory tmf)
+            throws Exception {
+        TrustManager[] trustManagers = tmf.getTrustManagers();
+        assertNotNull(trustManagers);
+        assertTrue(trustManagers.length > 0);
+        for (TrustManager trustManager : trustManagers) {
+            assertNotNull(trustManager);
+            if (trustManager instanceof X509TrustManager) {
+                test_X509TrustManager((X509TrustManager) trustManager);
+            }
+        }
+    }
+
+    private void test_X509TrustManager(X509TrustManager tm) throws Exception {
+        for (String keyType : KEY_TYPES) {
+            X509Certificate[] issuers = tm.getAcceptedIssuers();
+            assertNotNull(issuers);
+            assertTrue(issuers.length > 1);
+            assertNotSame(issuers, tm.getAcceptedIssuers());
+            boolean defaultTrustManager
+                    // RI de-duplicates certs from TrustedCertificateEntry and PrivateKeyEntry
+                    = issuers.length > (StandardNames.IS_RI ? 1 : 2) * KEY_TYPES.length;
+
+            String keyAlgName = TestKeyStore.keyAlgorithm(keyType);
+            String sigAlgName = TestKeyStore.signatureAlgorithm(keyType);
+            PrivateKeyEntry pke = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
+            X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
+            if (defaultTrustManager) {
+                try {
+                    tm.checkClientTrusted(chain, keyType);
+                    fail();
+                } catch (CertificateException expected) {
+                    // Ignored.
+                }
+                try {
+                    tm.checkServerTrusted(chain, keyType);
+                    fail();
+                } catch (CertificateException expected) {
+                    // Ignored.
+                }
+            } else {
+                tm.checkClientTrusted(chain, keyType);
+                tm.checkServerTrusted(chain, keyType);
+            }
+        }
+    }
+
+    @Test
+    public void test_TrustManagerFactory_getInstance() throws Exception {
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("TrustManagerFactory")) {
+                    continue;
+                }
+                String algorithm = service.getAlgorithm();
+                {
+                    TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+                    assertEquals(algorithm, tmf.getAlgorithm());
+                    test_TrustManagerFactory(tmf);
+                }
+
+                {
+                    TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm, provider);
+                    assertEquals(algorithm, tmf.getAlgorithm());
+                    assertEquals(provider, tmf.getProvider());
+                    test_TrustManagerFactory(tmf);
+                }
+
+                {
+                    TrustManagerFactory tmf =
+                            TrustManagerFactory.getInstance(algorithm, provider.getName());
+                    assertEquals(algorithm, tmf.getAlgorithm());
+                    assertEquals(provider, tmf.getProvider());
+                    test_TrustManagerFactory(tmf);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void test_TrustManagerFactory_intermediate() throws Exception {
+        // chain should be server/intermediate/root
+        PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+        X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
+        assertEquals(3, chain.length);
+
+        // keyStore should contain only the intermediate CA so we can
+        // test proper validation even if there are extra certs after
+        // the trusted one (in this case the original root is "extra")
+        KeyStore keyStore = TestKeyStore.createKeyStore();
+        keyStore.setCertificateEntry("alias", chain[1]);
+
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("TrustManagerFactory")) {
+                    continue;
+                }
+                String algorithm = service.getAlgorithm();
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+                tmf.init(keyStore);
+                TrustManager[] trustManagers = tmf.getTrustManagers();
+                for (TrustManager trustManager : trustManagers) {
+                    if (!(trustManager instanceof X509TrustManager)) {
+                        continue;
+                    }
+                    X509TrustManager tm = (X509TrustManager) trustManager;
+                    tm.checkClientTrusted(chain, "RSA");
+                    tm.checkServerTrusted(chain, "RSA");
+                }
+            }
+        }
+    }
+
+    @Test
+    public void test_TrustManagerFactory_keyOnly() throws Exception {
+        // create a KeyStore containing only a private key with chain.
+        // unlike PKIXParameters(KeyStore), the cert chain of the key should be trusted.
+        KeyStore ks = TestKeyStore.createKeyStore();
+        KeyStore.PrivateKeyEntry pke = getTestKeyStore().getPrivateKey("RSA", "RSA");
+        ks.setKeyEntry("key", pke.getPrivateKey(), "pw".toCharArray(), pke.getCertificateChain());
+
+        String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+        tmf.init(ks);
+        X509TrustManager trustManager = (X509TrustManager) tmf.getTrustManagers()[0];
+        trustManager.checkServerTrusted((X509Certificate[]) pke.getCertificateChain(), "RSA");
+    }
+
+    @Test
+    public void test_TrustManagerFactory_extendedKeyUsage() throws Exception {
+        // anyExtendedKeyUsage should work for client or server
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.anyExtendedKeyUsage, false, true, true);
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.anyExtendedKeyUsage, true, true, true);
+
+        // critical clientAuth should work for client
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_clientAuth, false, true, false);
+        test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, true, true, false);
+
+        // critical serverAuth should work for server
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_serverAuth, false, false, true);
+        test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, true, false, true);
+
+        // codeSigning should not work
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_codeSigning, false, false, false);
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_codeSigning, true, false, false);
+    }
+
+    private void test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId keyPurposeId,
+            boolean critical, boolean client, boolean server) throws Exception {
+        String algorithm = "RSA";
+        TestKeyStore intermediateCa = TestKeyStore.getIntermediateCa();
+        TestKeyStore leaf = new TestKeyStore.Builder()
+                                    .keyAlgorithms(algorithm)
+                                    .aliasPrefix("criticalCodeSigning")
+                                    .signer(intermediateCa.getPrivateKey("RSA", "RSA"))
+                                    .rootCa(intermediateCa.getRootCertificate("RSA"))
+                                    .addExtendedKeyUsage(keyPurposeId, critical)
+                                    .build();
+        // leaf.dump("test_TrustManagerFactory_criticalCodeSigning");
+        PrivateKeyEntry privateKeyEntry = leaf.getPrivateKey(algorithm, algorithm);
+        X509Certificate[] chain = (X509Certificate[]) privateKeyEntry.getCertificateChain();
+
+        TestKeyStore rootCa = TestKeyStore.getRootCa();
+        X509TrustManager trustManager = (X509TrustManager) rootCa.trustManagers[0];
+        try {
+            trustManager.checkClientTrusted(chain, algorithm);
+            assertTrue(client);
+        } catch (Exception e) {
+            assertFalse(client);
+        }
+        try {
+            trustManager.checkServerTrusted(chain, algorithm);
+            assertTrue(server);
+        } catch (Exception e) {
+            assertFalse(server);
+        }
+    }
+}
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java
new file mode 100644
index 0000000..63ebd55
--- /dev/null
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/X509KeyManagerTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.X509KeyManager;
+import libcore.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class X509KeyManagerTest extends AbstractSSLTest {
+    /**
+     * Tests whether the key manager will select the right key when the CA is of
+     * one key type and the client is of a possibly different key type.
+     *
+     * <p>There was a bug where EC was being interpreted as EC_EC and only
+     * accepting EC signatures when it should accept any signature type.
+     */
+    @Test
+    public void testChooseClientAlias_Combinations() throws Exception {
+        test_ChooseClientAlias_KeyType("RSA", "RSA", "RSA", true);
+        test_ChooseClientAlias_KeyType("RSA", "EC", "RSA", true);
+        test_ChooseClientAlias_KeyType("RSA", "EC", "EC", false);
+
+        test_ChooseClientAlias_KeyType("EC", "RSA", "EC_RSA", true);
+        test_ChooseClientAlias_KeyType("EC", "EC", "EC_RSA", false);
+
+        test_ChooseClientAlias_KeyType("EC", "EC", "EC_EC", true);
+        test_ChooseClientAlias_KeyType("EC", "RSA", "EC_EC", false);
+
+        test_ChooseClientAlias_KeyType("EC", "RSA", "RSA", false);
+    }
+
+    private void test_ChooseClientAlias_KeyType(String clientKeyType, String caKeyType,
+            String selectedKeyType, boolean succeeds) throws Exception {
+        TestKeyStore ca = new TestKeyStore.Builder().keyAlgorithms(caKeyType).build();
+        TestKeyStore client = new TestKeyStore.Builder()
+                                      .keyAlgorithms(clientKeyType)
+                                      .signer(ca.getPrivateKey(caKeyType, caKeyType))
+                                      .build();
+
+        KeyManagerFactory kmf =
+                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        kmf.init(client.keyStore, client.keyPassword);
+
+        String[] keyTypes = new String[] {selectedKeyType};
+        KeyManager[] managers = kmf.getKeyManagers();
+        for (KeyManager manager : managers) {
+            if (manager instanceof X509KeyManager) {
+                String alias = ((X509KeyManager) manager).chooseClientAlias(keyTypes, null, null);
+                if (succeeds) {
+                    assertNotNull(alias);
+                } else {
+                    assertNull(alias);
+                }
+            }
+        }
+    }
+}
diff --git a/testing/src/main/java/libcore/javax/net/ssl/TestSSLContext.java b/testing/src/main/java/libcore/javax/net/ssl/TestSSLContext.java
index 4bce15e..aa58a80 100644
--- a/testing/src/main/java/libcore/javax/net/ssl/TestSSLContext.java
+++ b/testing/src/main/java/libcore/javax/net/ssl/TestSSLContext.java
@@ -42,7 +42,6 @@
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509ExtendedTrustManager;
 import javax.net.ssl.X509TrustManager;
-import libcore.java.security.StandardNames;
 import libcore.java.security.TestKeyStore;
 
 /**
@@ -51,16 +50,6 @@
  * don't have to duplicate the logic.
  */
 public final class TestSSLContext {
-    /*
-     * The RI and Android have very different default SSLSession cache behaviors.
-     * The RI keeps an unlimited number of SSLSesions around for 1 day.
-     * Android keeps 10 SSLSessions forever.
-     */
-    private static final boolean IS_RI = StandardNames.IS_RI;
-    public static final int EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 10;
-    public static final int EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 100;
-    public static final int EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT =
-            (IS_RI) ? 24 * 3600 : 8 * 3600;
     /**
      * The Android SSLSocket and SSLServerSocket implementations are
      * based on a version of OpenSSL which includes support for RFC