summaryrefslogtreecommitdiffstats
path: root/luni
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2010-04-03 08:13:40 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-04-03 08:13:40 -0700
commitc2e77ad88fc2d6244b2d9ee405052eeaaa4663fa (patch)
tree57f6803957c213eb0991e13e4fd7625b495e5c76 /luni
parent2d5415be0fe89bca6476964e0e79659e0e061188 (diff)
parentebabb91c8c87ac2be2dca70ae343130f9755047f (diff)
downloadlibcore-c2e77ad88fc2d6244b2d9ee405052eeaaa4663fa.zip
libcore-c2e77ad88fc2d6244b2d9ee405052eeaaa4663fa.tar.gz
libcore-c2e77ad88fc2d6244b2d9ee405052eeaaa4663fa.tar.bz2
Merge "New "from scratch" Junit tests for javax.net.ssl" into dalvik-dev
Diffstat (limited to 'luni')
-rw-r--r--luni/src/test/java/javax/net/ssl/AllTests.java32
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLContextTest.java361
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java220
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSessionTest.java317
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java76
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSocketTest.java686
-rw-r--r--luni/src/test/java/tests/AllTests.java1
7 files changed, 1693 insertions, 0 deletions
diff --git a/luni/src/test/java/javax/net/ssl/AllTests.java b/luni/src/test/java/javax/net/ssl/AllTests.java
new file mode 100644
index 0000000..740b788
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/AllTests.java
@@ -0,0 +1,32 @@
+/*
+ * 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 javax.net.ssl;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(SSLSocketFactoryTest.class);
+ suite.addTestSuite(SSLContextTest.class);
+ suite.addTestSuite(SSLSocketTest.class);
+ suite.addTestSuite(SSLSessionTest.class);
+ suite.addTestSuite(SSLSessionContextTest.class);
+ return suite;
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
new file mode 100644
index 0000000..39a59e3
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
@@ -0,0 +1,361 @@
+/*
+ * 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 javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+import java.util.Hashtable;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.x509.X509V3CertificateGenerator;
+
+public class SSLContextTest extends TestCase {
+
+ public static final boolean IS_RI = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
+ public static final String PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "HarmonyJSSE";
+
+ public void test_SSLContext_getInstance() throws Exception {
+ try {
+ SSLContext.getInstance(null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ assertNotNull(SSLContext.getInstance("SSL"));
+ assertNotNull(SSLContext.getInstance("SSLv3"));
+ assertNotNull(SSLContext.getInstance("TLS"));
+ assertNotNull(SSLContext.getInstance("TLSv1"));
+
+ assertNotSame(SSLContext.getInstance("TLS"),
+ SSLContext.getInstance("TLS"));
+
+ try {
+ SSLContext.getInstance(null, (String) null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ SSLContext.getInstance(null, "");
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ SSLContext.getInstance("TLS", (String) null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ SSLContext.getInstance(null, PROVIDER_NAME);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void test_SSLContext_getProtocol() throws Exception {
+ assertProtocolExistsForName("SSL");
+ assertProtocolExistsForName("TLS");
+ }
+
+ private void assertProtocolExistsForName(String protocolName) throws Exception {
+ String protocol = SSLContext.getInstance(protocolName).getProtocol();
+ assertNotNull(protocol);
+ assertEquals(protocolName, protocol);
+ }
+
+ public void test_SSLContext_getProvider() throws Exception {
+ Provider provider = SSLContext.getInstance("TLS").getProvider();
+ assertNotNull(provider);
+ assertEquals(PROVIDER_NAME, provider.getName());
+ }
+
+ public void test_SSLContext_init() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ }
+
+ public void test_SSLContext_getSocketFactory() throws Exception {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.getSocketFactory();
+ fail();
+ } catch (IllegalStateException e) {
+ }
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ SocketFactory sf = sslContext.getSocketFactory();
+ assertNotNull(sf);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+ }
+
+ public void test_SSLContext_getServerSocketFactory() throws Exception {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.getServerSocketFactory();
+ fail();
+ } catch (IllegalStateException e) {
+ }
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ ServerSocketFactory ssf = sslContext.getServerSocketFactory();
+ assertNotNull(ssf);
+ assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
+ }
+
+ public void test_SSLContext_createSSLEngine() throws Exception {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.createSSLEngine();
+ fail();
+ } catch (IllegalStateException e) {
+ }
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.createSSLEngine(null, -1);
+ fail();
+ } catch (IllegalStateException e) {
+ }
+ {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ SSLEngine se = sslContext.createSSLEngine();
+ assertNotNull(se);
+ }
+ {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ SSLEngine se = sslContext.createSSLEngine(null, -1);
+ assertNotNull(se);
+ }
+ }
+
+ @KnownFailure("Should be able to ask SSLContext for SSLSessionContext's before called SSLContext.init")
+ public void test_SSLContext_getServerSessionContext() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLSessionContext sessionContext = sslContext.getServerSessionContext();
+ assertNotNull(sessionContext);
+
+ assertNotSame(SSLContext.getInstance("TLS").getServerSessionContext(),
+ sessionContext);
+ }
+
+ @KnownFailure("Should be able to ask SSLContext for SSLSessionContext's before called SSLContext.init")
+ public void test_SSLContext_getClientSessionContext() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLSessionContext sessionContext = sslContext.getClientSessionContext();
+ assertNotNull(sessionContext);
+
+ assertNotSame(SSLContext.getInstance("TLS").getClientSessionContext(),
+ sessionContext);
+ }
+
+ /**
+ * SSLContextTest.Helper is a convenience class for other tests that
+ * want a canned SSLContext and related state for testing so they
+ * don't have to duplicate the logic.
+ */
+ public static final class Helper {
+
+ static {
+ if (SSLContextTest.IS_RI) {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+ }
+
+ public final KeyStore keyStore;
+ public final char[] keyStorePassword;
+ public final String publicAlias;
+ public final String privateAlias;
+ public final SSLContext sslContext;
+ public final SSLServerSocket serverSocket;
+ public final InetAddress host;
+ public final int port;
+
+ private Helper(final KeyStore keyStore,
+ final char[] keyStorePassword,
+ final String publicAlias,
+ final String privateAlias,
+ final SSLContext sslContext,
+ final SSLServerSocket serverSocket,
+ final InetAddress host,
+ final int port) {
+ this.keyStore = keyStore;
+ this.keyStorePassword = keyStorePassword;
+ this.publicAlias = publicAlias;
+ this.privateAlias = privateAlias;
+ this.sslContext = sslContext;
+ this.serverSocket = serverSocket;
+ this.host = host;
+ this.port = port;
+ }
+
+ public static Helper create() {
+ try {
+ final char[] keyStorePassword = null;
+ final String publicAlias = "public";
+ final String privateAlias = "private";
+ return create(createKeyStore(keyStorePassword, publicAlias, privateAlias),
+ null,
+ publicAlias,
+ privateAlias);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Helper create(final KeyStore keyStore,
+ final char[] keyStorePassword,
+ final String publicAlias,
+ final String privateAlias) {
+ try {
+ final SSLContext sslContext = createSSLContext(keyStore, keyStorePassword);
+
+ final SSLServerSocket serverSocket = (SSLServerSocket)
+ sslContext.getServerSocketFactory().createServerSocket(0);
+ final InetSocketAddress sa = (InetSocketAddress) serverSocket.getLocalSocketAddress();
+ final InetAddress host = sa.getAddress();
+ final int port = sa.getPort();
+
+ return new Helper(keyStore, keyStorePassword, publicAlias, privateAlias,
+ sslContext, serverSocket, host, port);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Create a BKS KeyStore containing an RSAPrivateKey with alias
+ * "private" and a X509Certificate based on the matching
+ * RSAPublicKey stored under the alias name publicAlias.
+ *
+ * The private key will have a certificate chain including the
+ * certificate stored under the alias name privateAlias. The
+ * certificate will be signed by the private key. The certificate
+ * Subject and Issuer Common-Name will be the local host's
+ * canonical hostname. The certificate will be valid for one day
+ * before and one day after the time of creation.
+ *
+ * The KeyStore is optionally password protected by the
+ * keyStorePassword argument, which can be null if a password is
+ * not desired.
+ *
+ * Based on:
+ * org.bouncycastle.jce.provider.test.SigTest
+ * org.bouncycastle.jce.provider.test.CertTest
+ */
+ public static KeyStore createKeyStore(final char[] keyStorePassword,
+ String publicAlias,
+ String privateAlias)
+ throws Exception {
+
+ // 1.) we make the keys
+ final int keysize = 1024;
+ final KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(keysize, new SecureRandom());
+ final KeyPair kp = kpg.generateKeyPair();
+ final RSAPrivateKey privateKey = (RSAPrivateKey)kp.getPrivate();
+ final RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic();
+
+ // 2.) use keys to make certficate
+
+ // note that there doesn't seem to be a standard way to make a
+ // certificate using java.* or javax.*. The CertificateFactory
+ // interface assumes you want to read in a stream of bytes a
+ // factory specific format. So here we use Bouncy Castle's
+ // X509V3CertificateGenerator and related classes.
+
+ final Hashtable attributes = new Hashtable();
+ attributes.put(X509Principal.CN, InetAddress.getLocalHost().getCanonicalHostName());
+ final X509Principal dn = new X509Principal(attributes);
+
+ final long millisPerDay = 24 * 60 * 60 * 1000;
+ final long now = System.currentTimeMillis();
+ final Date start = new Date(now - millisPerDay);
+ final Date end = new Date(now + millisPerDay);
+ final BigInteger serial = BigInteger.valueOf(1);
+
+ final X509V3CertificateGenerator x509cg = new X509V3CertificateGenerator();
+ x509cg.setSubjectDN(dn);
+ x509cg.setIssuerDN(dn);
+ x509cg.setNotBefore(start);
+ x509cg.setNotAfter(end);
+ x509cg.setPublicKey(publicKey);
+ x509cg.setSignatureAlgorithm("sha1WithRSAEncryption");
+ x509cg.setSerialNumber(serial);
+ final X509Certificate x509c = x509cg.generateX509Certificate(privateKey);
+ final X509Certificate[] x509cc = new X509Certificate[] { x509c };
+
+
+ // 3.) put certificate and private key to make a key store
+ final KeyStore ks = KeyStore.getInstance("BKS");
+ ks.load(null, null);
+ ks.setKeyEntry(privateAlias, privateKey, keyStorePassword, x509cc);
+ ks.setCertificateEntry(publicAlias, x509c);
+ return ks;
+ }
+
+ /**
+ * Create a SSLContext with a KeyManager using the private key and
+ * certificate chain from the given KeyStore and a TrustManager
+ * using the certificates authorities from the same KeyStore.
+ */
+ public static final SSLContext createSSLContext(final KeyStore keyStore, final char[] keyStorePassword)
+ throws Exception {
+ final String kmfa = KeyManagerFactory.getDefaultAlgorithm();
+ final KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa);
+ kmf.init(keyStore, keyStorePassword);
+
+ final String tmfa = TrustManagerFactory.getDefaultAlgorithm();
+ final TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa);
+ tmf.init(keyStore);
+
+ final SSLContext context = SSLContext.getInstance("TLS");
+ context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
+ return context;
+ }
+ }
+
+ public void test_SSLContextTest_Helper_create() {
+ Helper helper = Helper.create();
+ assertNotNull(helper);
+ assertNotNull(helper.keyStore);
+ assertNull(helper.keyStorePassword);
+ assertNotNull(helper.publicAlias);
+ assertNotNull(helper.privateAlias);
+ assertNotNull(helper.sslContext);
+ assertNotNull(helper.serverSocket);
+ assertNotNull(helper.host);
+ assertTrue(helper.port != 0);
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
new file mode 100644
index 0000000..38848da
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
@@ -0,0 +1,220 @@
+/*
+ * 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 javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import junit.framework.TestCase;
+
+public class SSLSessionContextTest extends TestCase {
+
+ public static final void assertSSLSessionContextSize(int expected, SSLSessionContext s) {
+ assertEquals(expected, Collections.list(s.getIds()).size());
+ }
+
+ public void test_SSLSessionContext_getIds() {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ assertSSLSessionContextSize(0, c.sslContext.getClientSessionContext());
+ assertSSLSessionContextSize(0, c.sslContext.getServerSessionContext());
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ assertSSLSessionContextSize(1, s.c.sslContext.getClientSessionContext());
+ assertSSLSessionContextSize(1, s.c.sslContext.getServerSessionContext());
+ final Enumeration clientIds = s.c.sslContext.getClientSessionContext().getIds();
+ final Enumeration serverIds = s.c.sslContext.getServerSessionContext().getIds();
+ final byte[] clientId = (byte[]) clientIds.nextElement();
+ final byte[] serverId = (byte[]) serverIds.nextElement();
+ assertEquals(32, clientId.length);
+ assertEquals(32, serverId.length);
+ assertEquals(clientId, serverId);
+ }
+
+ @KnownFailure("Should throw NullPointerException on getSession(null)")
+ public void test_SSLSessionContext_getSession() {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ try {
+ c.sslContext.getClientSessionContext().getSession(null);
+ fail();
+ } catch (NullPointerException e) {
+ }
+ assertNull(c.sslContext.getClientSessionContext().getSession(new byte[0]));
+ assertNull(c.sslContext.getClientSessionContext().getSession(new byte[1]));
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ final SSLSessionContext client = s.c.sslContext.getClientSessionContext();
+ final SSLSessionContext server = s.c.sslContext.getServerSessionContext();
+ final byte[] clientId = (byte[]) client.getIds().nextElement();
+ final byte[] serverId = (byte[]) server.getIds().nextElement();
+ assertNotNull(client.getSession(clientId));
+ assertNotNull(server.getSession(serverId));
+ assertEquals(clientId, client.getSession(clientId).getId());
+ assertEquals(serverId, server.getSession(serverId).getId());
+ }
+
+ @KnownFailure("Should return 0 for unlimited, not 10 entries")
+ public void test_SSLSessionContext_getSessionCacheSize() {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ assertEquals(0, c.sslContext.getClientSessionContext().getSessionCacheSize());
+ assertEquals(0, c.sslContext.getServerSessionContext().getSessionCacheSize());
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ assertEquals(0, s.c.sslContext.getClientSessionContext().getSessionCacheSize());
+ assertEquals(0, s.c.sslContext.getServerSessionContext().getSessionCacheSize());
+ }
+
+ @KnownFailure("Should return 0 for unlimited, not 10 entries")
+ public void test_SSLSessionContext_setSessionCacheSize_basic() {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ assertBasicSetSessionCacheSizeBehavior(c.sslContext.getClientSessionContext());
+ assertBasicSetSessionCacheSizeBehavior(c.sslContext.getServerSessionContext());
+ }
+
+ private static void assertBasicSetSessionCacheSizeBehavior(SSLSessionContext s) {
+ try {
+ s.setSessionCacheSize(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(0, s.getSessionCacheSize());
+ s.setSessionCacheSize(1);
+ assertEquals(1, s.getSessionCacheSize());
+ }
+
+ @KnownFailure("Should return 0 for unlimited, not 10 entries")
+ public void test_SSLSessionContext_setSessionCacheSize_dynamic() {
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ final SSLSessionContext client = s.c.sslContext.getClientSessionContext();
+ final SSLSessionContext server = s.c.sslContext.getServerSessionContext();
+ assertEquals(0, client.getSessionCacheSize());
+ assertEquals(0, server.getSessionCacheSize());
+ assertSSLSessionContextSize(1, client);
+ assertSSLSessionContextSize(1, server);
+
+ final LinkedList<String> uniqueCipherSuites
+ = new LinkedList(Arrays.asList(s.server.getEnabledCipherSuites()));
+ uniqueCipherSuites.remove(s.client.getSession().getCipherSuite());
+
+ // only use RSA cipher suites which will work with our TrustProvider
+ Iterator<String> i = uniqueCipherSuites.iterator();
+ while (i.hasNext()) {
+ String cipherSuite = i.next();
+ 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 5 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() > 5);
+
+ SSLSocketTest.Helper.connect_workaround(s.c,
+ new String[] { uniqueCipherSuites.remove() }); // 1
+ assertSSLSessionContextSize(2, client);
+ assertSSLSessionContextSize(2, server);
+ SSLSocketTest.Helper.connect_workaround(s.c,
+ new String[] { uniqueCipherSuites.remove() }); // 2
+ assertSSLSessionContextSize(3, client);
+ assertSSLSessionContextSize(3, server);
+
+ client.setSessionCacheSize(1);
+ server.setSessionCacheSize(1);
+ assertEquals(1, client.getSessionCacheSize());
+ assertEquals(1, server.getSessionCacheSize());
+ assertSSLSessionContextSize(1, client);
+ assertSSLSessionContextSize(1, server);
+ SSLSocketTest.Helper.connect_workaround(s.c,
+ new String[] { uniqueCipherSuites.remove() }); // 3
+ assertSSLSessionContextSize(1, client);
+ assertSSLSessionContextSize(1, server);
+
+ client.setSessionCacheSize(2);
+ server.setSessionCacheSize(2);
+ SSLSocketTest.Helper.connect_workaround(s.c,
+ new String[] { uniqueCipherSuites.remove() }); // 4
+ assertSSLSessionContextSize(2, client);
+ assertSSLSessionContextSize(2, server);
+ SSLSocketTest.Helper.connect_workaround(s.c,
+ new String[] { uniqueCipherSuites.remove() }); // 5
+ assertSSLSessionContextSize(2, client);
+ assertSSLSessionContextSize(2, server);
+ }
+
+ @KnownFailure("Should return 86400 seconds (1 day), not 0 for unlimited")
+ public void test_SSLSessionContext_getSessionTimeout() {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ assertEquals(86400, c.sslContext.getClientSessionContext().getSessionTimeout());
+ assertEquals(86400, c.sslContext.getServerSessionContext().getSessionTimeout());
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ assertEquals(86400, s.c.sslContext.getClientSessionContext().getSessionTimeout());
+ assertEquals(86400, s.c.sslContext.getServerSessionContext().getSessionTimeout());
+ }
+
+ @KnownFailure("Should return 86400 seconds (1 day), not 0 for unlimited")
+ public void test_SSLSessionContext_setSessionTimeout() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ assertEquals(86400, c.sslContext.getClientSessionContext().getSessionTimeout());
+ assertEquals(86400, c.sslContext.getServerSessionContext().getSessionTimeout());
+ c.sslContext.getClientSessionContext().setSessionTimeout(0);
+ c.sslContext.getServerSessionContext().setSessionTimeout(0);
+ assertEquals(0, c.sslContext.getClientSessionContext().getSessionTimeout());
+ assertEquals(0, c.sslContext.getServerSessionContext().getSessionTimeout());
+
+ try {
+ c.sslContext.getClientSessionContext().setSessionTimeout(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ c.sslContext.getServerSessionContext().setSessionTimeout(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ assertSSLSessionContextSize(1, s.c.sslContext.getClientSessionContext());
+ assertSSLSessionContextSize(1, s.c.sslContext.getServerSessionContext());
+ Thread.sleep(1 * 1000);
+ s.c.sslContext.getClientSessionContext().setSessionTimeout(1);
+ s.c.sslContext.getServerSessionContext().setSessionTimeout(1);
+ assertSSLSessionContextSize(0, s.c.sslContext.getClientSessionContext());
+ assertSSLSessionContextSize(0, s.c.sslContext.getServerSessionContext());
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java
new file mode 100644
index 0000000..bf0e4d6
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java
@@ -0,0 +1,317 @@
+/*
+ * 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 javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public class SSLSessionTest extends TestCase {
+
+ public static final class Helper {
+
+ /**
+ * An invalid session that is not connected
+ */
+ public final SSLSession invalid;
+
+ /**
+ * The server side of a connected session
+ */
+ public final SSLSession server;
+
+ /**
+ * The client side of a connected session
+ */
+ public final SSLSession client;
+
+ /**
+ * The associated SSLSocketTest.Helper that is the source of
+ * the client and server SSLSessions.
+ */
+ public final SSLSocketTest.Helper s;
+
+ private Helper(final SSLSession invalid,
+ final SSLSession server,
+ final SSLSession client,
+ final SSLSocketTest.Helper s) {
+ this.invalid = invalid;
+ this.server = server;
+ this.client = client;
+ this.s = s;
+ }
+
+ public static final Helper create() {
+ try {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final SSLSession invalid = ssl.getSession();
+ final SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+ return new Helper(invalid, s.server.getSession(), s.client.getSession(), s);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+ public void test_SSLSocket_Helper_create() {
+ final Helper s = Helper.create();
+ assertNotNull(s.invalid);
+ assertFalse(s.invalid.isValid());
+ assertTrue(s.server.isValid());
+ assertTrue(s.client.isValid());
+ }
+
+ public void test_SSLSession_getApplicationBufferSize() {
+ final Helper s = Helper.create();
+ assertTrue(s.invalid.getApplicationBufferSize() > 0);
+ assertTrue(s.server.getApplicationBufferSize() > 0);
+ assertTrue(s.client.getApplicationBufferSize() > 0);
+ }
+
+ @KnownFailure("Expected SSL_NULL_WITH_NULL_NULL but received TLS_NULL_WITH_NULL_NULL")
+ public void test_SSLSession_getCipherSuite() {
+ final Helper s = Helper.create();
+ assertNotNull(s.invalid.getCipherSuite());
+ assertEquals("SSL_NULL_WITH_NULL_NULL", s.invalid.getCipherSuite());
+ assertNotNull(s.server.getCipherSuite());
+ assertNotNull(s.client.getCipherSuite());
+ assertEquals(s.server.getCipherSuite(),
+ s.client.getCipherSuite());
+ }
+
+ public void test_SSLSession_getCreationTime() {
+ final Helper s = Helper.create();
+ assertTrue(s.invalid.getCreationTime() > 0);
+ assertTrue(s.server.getCreationTime() > 0);
+ assertTrue(s.client.getCreationTime() > 0);
+ assertTrue(Math.abs(s.server.getCreationTime() - s.client.getCreationTime()) < 1 * 1000);
+ }
+
+ public void test_SSLSession_getId() {
+ final Helper s = Helper.create();
+ assertNotNull(s.invalid.getId());
+ assertNotNull(s.server.getId());
+ assertNotNull(s.client.getId());
+ assertEquals(0, s.invalid.getId().length);
+ assertEquals(32, s.server.getId().length);
+ assertEquals(32, s.client.getId().length);
+ assertEquals(s.server.getId(), s.client.getId());
+ }
+
+ public void test_SSLSession_getLastAccessedTime() {
+ final Helper s = Helper.create();
+ assertTrue(s.invalid.getLastAccessedTime() > 0);
+ assertTrue(s.server.getLastAccessedTime() > 0);
+ assertTrue(s.client.getLastAccessedTime() > 0);
+ assertTrue(Math.abs(s.server.getLastAccessedTime() -
+ s.client.getLastAccessedTime()) < 1 * 1000);
+ assertTrue(s.server.getLastAccessedTime() >=
+ s.server.getCreationTime());
+ assertTrue(s.client.getLastAccessedTime() >=
+ s.client.getCreationTime());
+ }
+
+ public void test_SSLSession_getLocalCertificates() throws Exception {
+ final Helper s = Helper.create();
+ assertNull(s.invalid.getLocalCertificates());
+ assertNull(s.client.getLocalCertificates());
+ assertNotNull(s.server.getLocalCertificates());
+ assertEquals(1, s.server.getLocalCertificates().length);
+ assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+ s.server.getLocalCertificates()[0]);
+ }
+
+ public void test_SSLSession_getLocalPrincipal() throws Exception {
+ final Helper s = Helper.create();
+ assertNull(s.invalid.getLocalPrincipal());
+ assertNull(s.client.getLocalPrincipal());
+ assertNotNull(s.server.getLocalPrincipal());
+ assertNotNull(s.server.getLocalPrincipal().getName());
+ final X509Certificate x509certificate = (X509Certificate)
+ s.s.c.keyStore.getCertificate(s.s.c.publicAlias);
+ assertEquals(x509certificate.getSubjectDN().getName(),
+ s.server.getLocalPrincipal().getName());
+ }
+
+ public void test_SSLSession_getPacketBufferSize() {
+ final Helper s = Helper.create();
+ assertTrue(s.invalid.getPacketBufferSize() > 0);
+ assertTrue(s.server.getPacketBufferSize() > 0);
+ assertTrue(s.client.getPacketBufferSize() > 0);
+ }
+
+ public void test_SSLSession_getPeerCertificateChain() throws Exception {
+ final Helper s = Helper.create();
+ try {
+ s.invalid.getPeerCertificateChain();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ assertNotNull(s.client.getPeerCertificates());
+ assertEquals(1, s.client.getPeerCertificates().length);
+ assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+ s.client.getPeerCertificates()[0]);
+ try {
+ assertNull(s.server.getPeerCertificates());
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ }
+
+ public void test_SSLSession_getPeerCertificates() throws Exception {
+ final Helper s = Helper.create();
+ try {
+ s.invalid.getPeerCertificates();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ assertNotNull(s.client.getPeerCertificates());
+ assertEquals(1, s.client.getPeerCertificates().length);
+ assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+ s.client.getPeerCertificates()[0]);
+ try {
+ s.server.getPeerCertificates();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ }
+
+ public void test_SSLSession_getPeerHost() {
+ final Helper s = Helper.create();
+ assertNull(s.invalid.getPeerHost());
+ assertNotNull(s.server.getPeerHost());
+ assertNotNull(s.client.getPeerHost());
+ }
+
+ public void test_SSLSession_getPeerPort() {
+ final Helper s = Helper.create();
+ assertEquals(-1, s.invalid.getPeerPort());
+ assertTrue(s.server.getPeerPort() > 0);
+ assertEquals(s.s.c.port, s.client.getPeerPort());
+ }
+
+ public void test_SSLSession_getPeerPrincipal() throws Exception {
+ final Helper s = Helper.create();
+ try {
+ s.invalid.getPeerPrincipal();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ try {
+ s.server.getPeerPrincipal();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ assertNotNull(s.client.getPeerPrincipal());
+ assertNotNull(s.client.getPeerPrincipal().getName());
+ final X509Certificate x509certificate = (X509Certificate)
+ s.s.c.keyStore.getCertificate(s.s.c.publicAlias);
+ assertEquals(x509certificate.getSubjectDN().getName(),
+ s.client.getPeerPrincipal().getName());
+
+ }
+
+ public void test_SSLSession_getProtocol() {
+ final Helper s = Helper.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());
+ }
+
+ public void test_SSLSession_getSessionContext() {
+ final Helper s = Helper.create();
+ assertNull(s.invalid.getSessionContext());
+ assertNotNull(s.server.getSessionContext());
+ assertNotNull(s.client.getSessionContext());
+ assertEquals(s.s.c.sslContext.getServerSessionContext(),
+ s.server.getSessionContext());
+ assertEquals(s.s.c.sslContext.getClientSessionContext(),
+ s.client.getSessionContext());
+ assertNotSame(s.server.getSessionContext(),
+ s.client.getSessionContext());
+ }
+
+ public void test_SSLSession_getValue() {
+ final Helper s = Helper.create();
+ try {
+ s.invalid.getValue(null);
+ } catch (IllegalArgumentException e) {
+ }
+ assertNull(s.invalid.getValue("BOGUS"));
+ }
+
+ public void test_SSLSession_getValueNames() {
+ final Helper s = Helper.create();
+ assertNotNull(s.invalid.getValueNames());
+ assertEquals(0, s.invalid.getValueNames().length);
+ }
+
+ public void test_SSLSession_invalidate() {
+ final Helper s = Helper.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());
+ }
+
+ public void test_SSLSession_isValid() {
+ final Helper s = Helper.create();
+ assertFalse(s.invalid.isValid());
+ assertTrue(s.server.isValid());
+ assertTrue(s.client.isValid());
+ }
+
+ public void test_SSLSession_putValue() {
+ final Helper s = Helper.create();
+ final String key = "KEY";
+ final 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]);
+ }
+
+ public void test_SSLSession_removeValue() {
+ final Helper s = Helper.create();
+ final String key = "KEY";
+ final 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);
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
new file mode 100644
index 0000000..5ccae7f
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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 javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.ServerSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+
+public class SSLSocketFactoryTest extends TestCase {
+ public void test_SSLSocketFactory_getDefault() {
+ SocketFactory sf = SSLSocketFactory.getDefault();
+ assertNotNull(sf);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+ }
+
+ public void test_SSLSocketFactory_getDefaultCipherSuites() {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ String[] cs = sf.getDefaultCipherSuites();
+ assertNotNull(cs);
+ assertTrue(cs.length != 0);
+ }
+
+ public void test_SSLSocketFactory_getSupportedCipherSuites() {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ String[] cs = sf.getSupportedCipherSuites();
+ assertNotNull(cs);
+ assertTrue(cs.length != 0);
+ }
+
+ @KnownFailure("Should not parse bogus port number -1 during createSocket")
+ public void test_SSLSocketFactory_createSocket() throws Exception {
+ try {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ Socket s = sf.createSocket(null, null, -1, false);
+ fail();
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ Socket ssl = sf.createSocket(new Socket(), null, -1, false);
+ fail();
+ } catch (SocketException e) {
+ }
+
+ ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
+ InetSocketAddress sa = (InetSocketAddress) ss.getLocalSocketAddress();
+ InetAddress host = sa.getAddress();
+ int port = sa.getPort();
+ Socket s = new Socket(host, port);
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ Socket ssl = sf.createSocket(s, null, -1, false);
+ assertNotNull(ssl);
+ assertTrue(SSLSocket.class.isAssignableFrom(ssl.getClass()));
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
new file mode 100644
index 0000000..e5ad54d
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
@@ -0,0 +1,686 @@
+/*
+ * 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 javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+
+public class SSLSocketTest extends TestCase {
+
+ public void test_SSLSocket_getSupportedCipherSuites() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final String[] cs = ssl.getSupportedCipherSuites();
+ assertNotNull(cs);
+ assertTrue(cs.length != 0);
+ }
+
+ public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final String[] cs = ssl.getEnabledCipherSuites();
+ assertNotNull(cs);
+ assertTrue(cs.length != 0);
+ }
+
+ @KnownFailure("Should support disabling all cipher suites")
+ public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+
+ try {
+ ssl.setEnabledCipherSuites(null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ssl.setEnabledCipherSuites(new String[1]);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+
+ ssl.setEnabledCipherSuites(new String[0]);
+ ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+ ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+ }
+
+ public void test_SSLSocket_getSupportedProtocols() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final String[] p = ssl.getSupportedProtocols();
+ assertNotNull(p);
+ assertTrue(p.length != 0);
+ }
+
+ public void test_SSLSocket_getEnabledProtocols() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final String[] p = ssl.getEnabledProtocols();
+ assertNotNull(p);
+ assertTrue(p.length != 0);
+ }
+
+ @KnownFailure("Should thow IllegalArgumentException not NullPointerException on null enabled protocols argument")
+ public void test_SSLSocket_setEnabledProtocols() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+
+ try {
+ ssl.setEnabledProtocols(null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ssl.setEnabledProtocols(new String[1]);
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ ssl.setEnabledProtocols(new String[] { "Bogus" } );
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ ssl.setEnabledProtocols(new String[0]);
+ ssl.setEnabledProtocols(ssl.getEnabledProtocols());
+ ssl.setEnabledProtocols(ssl.getSupportedProtocols());
+ }
+
+ @KnownFailure("session of unconnected socket should not be valid")
+ public void test_SSLSocket_getSession() throws Exception {
+ final SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLSocket ssl = (SSLSocket) sf.createSocket();
+ final SSLSession session = ssl.getSession();
+ assertNotNull(session);
+ assertFalse(session.isValid());
+ }
+
+ @KnownFailure("Implementation should not start handshake in ServerSocket.accept")
+ public void test_SSLSocket_startHandshake() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ if (!SSLContextTest.IS_RI) {
+ /*
+ * The following hangs in accept in the Dalvik
+ * implementation because accept is also incorrectly
+ * starting the handhake.
+ */
+ c.serverSocket.setSoTimeout(1 * 1000);
+ /*
+ * That workaround doesn't seem to work so...
+ *
+ * See test_SSLSocket_startHandshake_workaround for
+ * redundant version of this test that works around this
+ * issue.
+ */
+ fail();
+ }
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ server.startHandshake();
+ assertNotNull(server.getSession());
+ try {
+ server.getSession().getPeerCertificates();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ Certificate[] localCertificates = server.getSession().getLocalCertificates();
+ assertNotNull(localCertificates);
+ assertEquals(1, localCertificates.length);
+ assertNotNull(localCertificates[0]);
+ assertNotNull(localCertificates[0].equals(c.keyStore.getCertificate(c.privateAlias)));
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ client.startHandshake();
+ assertNotNull(client.getSession());
+ assertNull(client.getSession().getLocalCertificates());
+ Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+ assertNotNull(peerCertificates);
+ assertEquals(1, peerCertificates.length);
+ assertNotNull(peerCertificates[0]);
+ assertNotNull(peerCertificates[0].equals(c.keyStore.getCertificate(c.publicAlias)));
+ thread.join();
+ }
+
+ @KnownFailure("local certificates should be null as it should not have been requested by server")
+ public void test_SSLSocket_startHandshake_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ server.startHandshake();
+ assertNotNull(server.getSession());
+ try {
+ server.getSession().getPeerCertificates();
+ fail();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ Certificate[] localCertificates = server.getSession().getLocalCertificates();
+ assertNotNull(localCertificates);
+ assertEquals(1, localCertificates.length);
+ assertNotNull(localCertificates[0]);
+ assertNotNull(localCertificates[0].equals(c.keyStore.getCertificate(c.privateAlias)));
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ client.startHandshake();
+ assertNotNull(client.getSession());
+ assertNull(client.getSession().getLocalCertificates());
+ Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+ assertNotNull(peerCertificates);
+ assertEquals(1, peerCertificates.length);
+ assertNotNull(peerCertificates[0]);
+ assertNotNull(peerCertificates[0].equals(c.keyStore.getCertificate(c.publicAlias)));
+ thread.join();
+ }
+
+ @KnownFailure("Should throw SSLException on server, not IOException on client")
+ public void test_SSLSocket_startHandshake_noKeyStore_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create(null, null, null, null);
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ c.serverSocket.accept();
+ fail();
+ } catch (SSLException e) {
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ if (!SSLContextTest.IS_RI) {
+ client.startHandshake();
+ }
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+ */
+ @KnownFailure("local certificates should be null as it should not have been requested by server")
+ public void test_SSLSocket_HandshakeCompletedListener_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ server.startHandshake();
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+ public void handshakeCompleted(final HandshakeCompletedEvent event) {
+ try {
+ SSLSession session = event.getSession();
+ String cipherSuite = event.getCipherSuite();
+ Certificate[] localCertificates = event.getLocalCertificates();
+ Certificate[] peerCertificates = event.getPeerCertificates();
+ javax.security.cert.X509Certificate[] peerCertificateChain = event.getPeerCertificateChain();
+ Principal peerPrincipal = event.getPeerPrincipal();
+ Principal localPrincipal = event.getLocalPrincipal();
+ Socket socket = event.getSocket();
+
+ if (false) {
+ System.out.println("Session=" + session);
+ System.out.println("CipherSuite=" + cipherSuite);
+ System.out.println("LocalCertificates=" + localCertificates);
+ System.out.println("PeerCertificates=" + peerCertificates);
+ System.out.println("PeerCertificateChain=" + peerCertificateChain);
+ System.out.println("PeerPrincipal=" + peerPrincipal);
+ System.out.println("LocalPrincipal=" + localPrincipal);
+ System.out.println("Socket=" + socket);
+ }
+
+ assertNotNull(session);
+ byte[] id = session.getId();
+ assertNotNull(id);
+ assertEquals(32, id.length);
+ assertNotNull(c.sslContext.getClientSessionContext().getSession(id));
+ assertNotNull(c.sslContext.getServerSessionContext().getSession(id));
+
+ assertNotNull(cipherSuite);
+ assertTrue(Arrays.asList(client.getEnabledCipherSuites()).contains(cipherSuite));
+ assertTrue(Arrays.asList(c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
+
+ final Enumeration e = c.keyStore.aliases();
+ Certificate certificate = null;
+ Key key = null;
+ while (e.hasMoreElements()) {
+ String alias = (String) e.nextElement();
+ if (c.keyStore.isCertificateEntry(alias)) {
+ assertNull(certificate);
+ certificate = c.keyStore.getCertificate(alias);
+ } else if (c.keyStore.isKeyEntry(alias)) {
+ assertNull(key);
+ key = c.keyStore.getKey(alias, c.keyStorePassword);
+ }
+ else {
+ fail();
+ }
+ }
+ assertNotNull(certificate);
+ assertNotNull(key);
+
+ assertTrue(X509Certificate.class.isAssignableFrom(certificate.getClass()));
+ final X509Certificate x509certificate = (X509Certificate) certificate;
+
+ assertNull(localCertificates);
+
+ assertNotNull(peerCertificates);
+ assertEquals(1, peerCertificates.length);
+ assertNotNull(peerCertificates[0]);
+ assertEquals(peerCertificates[0], x509certificate);
+
+ assertNotNull(peerCertificateChain);
+ assertEquals(1, peerCertificateChain.length);
+ assertNotNull(peerCertificateChain[0]);
+ assertEquals(x509certificate.getSubjectDN().getName(),
+ peerCertificateChain[0].getSubjectDN().getName());
+
+ assertNotNull(peerPrincipal);
+ assertEquals(x509certificate.getSubjectDN().getName(),
+ peerPrincipal.getName());
+
+ assertNull(localPrincipal);
+
+ assertNotNull(socket);
+ assertSame(client, socket);
+
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ client.startHandshake();
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround.
+ * Technically this test shouldn't even need a second thread.
+ */
+ public void test_SSLSocket_getUseClientMode_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ assertFalse(server.getUseClientMode());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ if (!SSLContextTest.IS_RI) {
+ client.startHandshake();
+ }
+ assertTrue(client.getUseClientMode());
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround.
+ * Technically this test shouldn't even need a second thread.
+ */
+ @KnownFailure("This test relies on socket timeouts which are not working. It also fails because ServerSocket.accept is handshaking")
+ public void test_SSLSocket_setUseClientMode_workaround() throws Exception {
+ // client is client, server is server
+ test_SSLSocket_setUseClientMode_workaround(true, false);
+ // client is server, server is client
+ test_SSLSocket_setUseClientMode_workaround(true, false);
+ // both are client
+ try {
+ test_SSLSocket_setUseClientMode_workaround(true, true);
+ fail();
+ } catch (SSLProtocolException e) {
+ }
+
+ // both are server
+ try {
+ test_SSLSocket_setUseClientMode_workaround(false, false);
+ fail();
+ } catch (SocketTimeoutException e) {
+ }
+ }
+
+ private void test_SSLSocket_setUseClientMode_workaround(final boolean clientClientMode,
+ final boolean serverClientMode)
+ throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final SSLProtocolException[] sslProtocolException = new SSLProtocolException[1];
+ final SocketTimeoutException[] socketTimeoutException = new SocketTimeoutException[1];
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ if (!serverClientMode) {
+ server.setSoTimeout(1 * 1000);
+ if (!SSLContextTest.IS_RI) {
+ /* as above setSoTimeout isn't working in dalvikvm */
+ fail();
+ }
+ }
+ server.setUseClientMode(serverClientMode);
+ server.startHandshake();
+ } catch (SSLProtocolException e) {
+ sslProtocolException[0] = e;
+ } catch (SocketTimeoutException e) {
+ socketTimeoutException[0] = e;
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ if (!clientClientMode) {
+ client.setSoTimeout(1 * 1000);
+ if (!SSLContextTest.IS_RI) {
+ /* as above setSoTimeout isn't working in dalvikvm */
+ fail();
+ }
+ }
+ client.setUseClientMode(clientClientMode);
+ client.startHandshake();
+ thread.join();
+ if (sslProtocolException[0] != null) {
+ throw sslProtocolException[0];
+ }
+ if (socketTimeoutException[0] != null) {
+ throw socketTimeoutException[0];
+ }
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+ */
+ public void test_SSLSocket_clientAuth_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ assertFalse(server.getWantClientAuth());
+ assertFalse(server.getNeedClientAuth());
+
+ // confirm turning one on by itself
+ server.setWantClientAuth(true);
+ assertTrue(server.getWantClientAuth());
+ assertFalse(server.getNeedClientAuth());
+
+ // confirm turning setting on toggles the other
+ server.setNeedClientAuth(true);
+ assertFalse(server.getWantClientAuth());
+ assertTrue(server.getNeedClientAuth());
+
+ // confirm toggling back
+ server.setWantClientAuth(true);
+ assertTrue(server.getWantClientAuth());
+ assertFalse(server.getNeedClientAuth());
+
+ server.startHandshake();
+
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ client.startHandshake();
+ assertNotNull(client.getSession().getLocalCertificates());
+ assertEquals(1, client.getSession().getLocalCertificates().length);
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+ * Technically this test shouldn't even need a second thread.
+ */
+ public void test_SSLSocket_getEnableSessionCreation_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ assertTrue(server.getEnableSessionCreation());
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ assertTrue(client.getEnableSessionCreation());
+ if (!SSLContextTest.IS_RI) {
+ client.startHandshake();
+ }
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+ */
+ @KnownFailure("Server side session creation disabling does not work, should throw SSLException, not fail")
+ public void test_SSLSocket_setEnableSessionCreation_server_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ server.setEnableSessionCreation(false);
+ try {
+ server.startHandshake();
+ fail();
+ } catch (SSLException e) {
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ try {
+ client.startHandshake();
+ fail();
+ } catch (SSLException e) {
+ }
+ thread.join();
+ }
+
+ /**
+ * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+ */
+ @KnownFailure("Should throw SSLException on server, not IOException")
+ public void test_SSLSocket_setEnableSessionCreation_client_workaround() throws Exception {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ try {
+ server.startHandshake();
+ fail();
+ } catch (SSLException e) {
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ client.setEnableSessionCreation(false);
+ try {
+ client.startHandshake();
+ fail();
+ } catch (SSLException e) {
+ if (!SSLContextTest.IS_RI) {
+ fail();
+ }
+ }
+ thread.join();
+ }
+
+ /**
+ * SSLSocketTest.Helper is a convenience class for other tests that
+ * want a pair of connected and handshaked client and server
+ * SSLSocketsfor testing so they don't have to duplicate the
+ * logic.
+ */
+ public static final class Helper {
+ public final SSLContextTest.Helper c;
+ public final SSLSocket server;
+ public final SSLSocket client;
+
+ private Helper (final SSLContextTest.Helper c,
+ final SSLSocket server,
+ final SSLSocket client) {
+ this.c = c;
+ this.server = server;
+ this.client = client;
+ }
+
+ /**
+ * based on test_SSLSocket_startHandshake_workaround, should
+ * be written to non-workaround form when possible
+ */
+ public static Helper create_workaround () {
+ final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+ final SSLSocket[] sockets = connect_workaround(c, null);
+ return new Helper(c, sockets[0], sockets[1]);
+ }
+
+ /**
+ * Create a new connected server/client socket pair within a
+ * existing SSLContext. Optional clientCipherSuites allows
+ * forcing new SSLSession to test SSLSessionContext caching
+ */
+ public static SSLSocket[] connect_workaround (final SSLContextTest.Helper c,
+ String[] clientCipherSuites) {
+ try {
+ final SSLSocket[] server = new SSLSocket[1];
+ final Thread thread = new Thread(new Runnable () {
+ public void run() {
+ try {
+ server[0] = (SSLSocket) c.serverSocket.accept();
+ server[0].startHandshake();
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ thread.start();
+ final SSLSocket client = (SSLSocket)
+ c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+ if (clientCipherSuites != null) {
+ client.setEnabledCipherSuites(clientCipherSuites);
+ }
+ client.startHandshake();
+ thread.join();
+ return new SSLSocket[] { server[0], client };
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void test_SSLSocketTest_Test_create() {
+ Helper test = Helper.create_workaround();
+ assertNotNull(test.c);
+ assertNotNull(test.server);
+ assertNotNull(test.client);
+ assertNotNull(test.server.isConnected());
+ assertNotNull(test.client.isConnected());
+ assertNotNull(test.server.getSession());
+ assertNotNull(test.client.getSession());
+ }
+}
diff --git a/luni/src/test/java/tests/AllTests.java b/luni/src/test/java/tests/AllTests.java
index 3110026..4b3a484 100644
--- a/luni/src/test/java/tests/AllTests.java
+++ b/luni/src/test/java/tests/AllTests.java
@@ -65,6 +65,7 @@ public class AllTests
suite.addTest(java.text.AllTests.suite());
suite.addTest(java.util.AllTests.suite());
suite.addTest(javax.xml.parsers.AllTests.suite());
+ suite.addTest(javax.net.ssl.AllTests.suite());
suite.addTest(org.apache.harmony.luni.platform.AllTests.suite());
suite.addTest(org.json.AllTests.suite());
suite.addTest(tests.api.org.apache.harmony.kernel.dalvik.AllTests.suite());