summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--expectations/knownfailures.txt63
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java198
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java16
-rw-r--r--support/src/test/java/libcore/java/security/StandardNames.java69
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java5
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java2
-rw-r--r--support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java53
7 files changed, 213 insertions, 193 deletions
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 66b39fb..276e781 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -939,49 +939,6 @@
name: "libcore.java.sql.OldStatementTest#testGetUpdateCount"
},
{
- description: "Handshake Status is never finished. NPE in ClientSessionContext$HostAndPort.hashCode() when host
- is null",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#testHandshake"
-},
-{
- description: "com.android.org.conscrypt.SSLEngineImpl#getDelegatedTask() throws NPE instead of
- returning null",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_getDelegatedTask"
-},
-{
- description: "Fixed in DonutBurger, boundary checks missing",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_02"
-},
-{
- description: "Fixed on DonutBurger, Wrong Exception thrown",
- bug: 3403706,
- names: [
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_04",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer$ByteBuffer_02",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer$ByteBuffer_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer_ByteBuffer_02",
- "tests.api.javax.net.ssl.SSLEngineTest#test_unwrap_ByteBuffer_ByteBuffer_03"
- ]
-},
-{
- description: "Fixed in DonutBurger, boundary checks missing",
- bug: 3403706,
- name: "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_02"
-},
-{
- description: "Fixed on DonutBurger, Wrong Exception thrown",
- bug: 3403706,
- names: [
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_04",
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_ByteBuffer$ByteBuffer_03",
- "tests.api.javax.net.ssl.SSLEngineTest#test_wrap_ByteBuffer_ByteBuffer_03"
- ]
-},
-{
description: "ManagerFactoryParameters object is not supported and InvalidAlgorithmParameterException was
thrown.",
bug: 3403706,
@@ -993,26 +950,6 @@
name: "tests.api.javax.net.ssl.HostnameVerifierTest#testVerifyIpAddress"
},
{
- description: "NO SERVER CERTIFICATE FOUND - selectSuite should not pick a suite that needs a certificate if it is missing",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_beginHandshake_noKeyStore"
-},
-{
- description: "AlertException instead of SSLException",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_client"
-},
-{
- description: "SSLException instead of failure to handshake",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_server"
-},
-{
- description: "SSLHandshakeException instead of failure to handshake",
- bug: 3045163,
- name: "libcore.javax.net.ssl.SSLEngineTest#test_SSLEngine_setUseClientMode"
-},
-{
description: "method test fails once in a while. Cannot be sure that exception is thrown in every test execution.",
bug: 3403706,
name: "libcore.sqlite.OldDatabaseTest#testBusy_handler"
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index 1bd1347..a7d0df2 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -82,9 +82,7 @@ public class SSLEngineTest extends TestCase {
.ca(true)
.build();
test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, false);
- if (StandardNames.IS_RI) {
- test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
- }
+ test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
}
private void test_SSLEngine_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
boolean secureRenegotiation)
@@ -133,86 +131,96 @@ public class SSLEngineTest extends TestCase {
testKeyStore.keyManagers[replaceIndex] = originalKeyManager;
}
+ // To catch all the errors.
+ StringBuilder error = new StringBuilder();
+
String[] cipherSuites = c.clientContext.createSSLEngine().getSupportedCipherSuites();
for (String cipherSuite : cipherSuites) {
- boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256");
try {
- /*
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
- * its own, but instead in conjunction with other
- * cipher suites.
- */
- if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
- continue;
- }
- /*
- * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
- * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
- * #KRBRequire
- */
- if (cipherSuite.startsWith("TLS_KRB5_")) {
- continue;
- }
+ // Skip cipher suites that are obsoleted.
+ if (StandardNames.IS_RI && "TLSv1.2".equals(c.clientContext.getProtocol())
+ && StandardNames.CIPHER_SUITES_OBSOLETE_TLS12.contains(cipherSuite)) {
+ continue;
+ }
+ /*
+ * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
+ * its own, but instead in conjunction with other
+ * cipher suites.
+ */
+ if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
+ continue;
+ }
+ /*
+ * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
+ * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
+ * #KRBRequire
+ */
+ if (cipherSuite.startsWith("TLS_KRB5_")) {
+ continue;
+ }
- final String[] cipherSuiteArray
- = (secureRenegotiation
- ? new String[] { cipherSuite,
- StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
- : new String[] { cipherSuite });
+ final String[] cipherSuiteArray
+ = (secureRenegotiation
+ ? new String[] { cipherSuite,
+ StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }
+ : new String[] { cipherSuite });
- // Check that handshake succeeds.
- TestSSLEnginePair pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnabledCipherSuites(cipherSuiteArray);
- server.setEnabledCipherSuites(cipherSuiteArray);
- }
- });
- assertConnected(pair);
-
- boolean needsRecordSplit =
- ("TLS".equalsIgnoreCase(c.clientContext.getProtocol())
- || "SSLv3".equalsIgnoreCase(c.clientContext.getProtocol()))
- && cipherSuite.contains("_CBC_");
-
- assertSendsCorrectly("This is the client. Hello!".getBytes(),
- pair.client, pair.server, needsRecordSplit);
- assertSendsCorrectly("This is the server. Hi!".getBytes(),
- pair.server, pair.client, needsRecordSplit);
- assertFalse(errorExpected);
-
- // Check that handshake fails when the server does not possess the private key
- // corresponding to the server's certificate. This is achieved by using SSLContext
- // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
- // the algorithm (and parameters) of the correct keys.
- if (!cipherSuite.contains("_anon_")) {
- // The identity of the server is verified only in non-anonymous key exchanges.
- try {
- TestSSLEnginePair p = TestSSLEnginePair.create(
- cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
- @Override
- void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
- client.setEnabledCipherSuites(cipherSuiteArray);
- server.setEnabledCipherSuites(cipherSuiteArray);
- }
- });
- assertConnected(p);
- fail("Handshake succeeded for " + cipherSuite
- + " despite server not having the correct private key");
- } catch (IOException expected) {}
- }
- } catch (Exception maybeExpected) {
- if (!errorExpected) {
- throw new Exception("Problem trying to connect cipher suite " + cipherSuite,
- maybeExpected);
+ // Check that handshake succeeds.
+ TestSSLEnginePair pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setEnabledCipherSuites(cipherSuiteArray);
+ server.setEnabledCipherSuites(cipherSuiteArray);
}
+ });
+ assertConnected(pair);
+
+ boolean needsRecordSplit =
+ ("TLS".equalsIgnoreCase(c.clientContext.getProtocol())
+ || "SSLv3".equalsIgnoreCase(c.clientContext.getProtocol()))
+ && cipherSuite.contains("_CBC_");
+
+ assertSendsCorrectly("This is the client. Hello!".getBytes(),
+ pair.client, pair.server, needsRecordSplit);
+ assertSendsCorrectly("This is the server. Hi!".getBytes(),
+ pair.server, pair.client, needsRecordSplit);
+
+ // Check that handshake fails when the server does not possess the private key
+ // corresponding to the server's certificate. This is achieved by using SSLContext
+ // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
+ // the algorithm (and parameters) of the correct keys.
+ if (!cipherSuite.contains("_anon_")) {
+ // The identity of the server is verified only in non-anonymous key exchanges.
+ try {
+ TestSSLEnginePair p = TestSSLEnginePair.create(
+ cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setEnabledCipherSuites(cipherSuiteArray);
+ server.setEnabledCipherSuites(cipherSuiteArray);
+ }
+ });
+ assertNotConnected(p);
+ } catch (IOException expected) {}
+ }
+ } catch (Exception e) {
+ String message = ("Problem trying to connect cipher suite " + cipherSuite);
+ System.out.println(message);
+ e.printStackTrace();
+ error.append(message);
+ error.append('\n');
}
}
c.close();
+
+ if (error.length() > 0) {
+ throw new Exception("One or more problems in "
+ + "test_SSLEngine_getSupportedCipherSuites_connect:\n" + error);
+ }
}
- private void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source, SSLEngine dest,
- boolean needsRecordSplit) throws SSLException {
+ private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
+ SSLEngine dest, boolean needsRecordSplit) throws SSLException {
ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
SSLSession sourceSession = source.getSession();
ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
@@ -327,9 +335,19 @@ public class SSLEngineTest extends TestCase {
e.setEnabledProtocols(e.getSupportedProtocols());
// Check that setEnabledProtocols affects getEnabledProtocols
- String[] protocols = new String[] { e.getSupportedProtocols()[0] };
- e.setEnabledProtocols(protocols);
- assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
+ for (String protocol : e.getSupportedProtocols()) {
+ if ("SSLv2Hello".equals(protocol)) {
+ try {
+ e.setEnabledProtocols(new String[] { protocol });
+ fail("Should fail when SSLv2Hello is set by itself");
+ } catch (IllegalArgumentException expected) {}
+ } else {
+ String[] protocols = new String[] { protocol };
+ e.setEnabledProtocols(protocols);
+ assertEquals(Arrays.deepToString(protocols),
+ Arrays.deepToString(e.getEnabledProtocols()));
+ }
+ }
c.close();
}
@@ -385,17 +403,34 @@ public class SSLEngineTest extends TestCase {
}
public void test_SSLEngine_setUseClientMode() throws Exception {
+ boolean[] finished;
+
// client is client, server is server
- assertConnected(test_SSLEngine_setUseClientMode(true, false));
+ finished = new boolean[2];
+ assertConnected(test_SSLEngine_setUseClientMode(true, false, finished));
+ assertTrue(finished[0]);
+ assertTrue(finished[1]);
// client is server, server is client
- assertConnected(test_SSLEngine_setUseClientMode(false, true));
+ finished = new boolean[2];
+ assertConnected(test_SSLEngine_setUseClientMode(false, true, finished));
+ assertTrue(finished[0]);
+ assertTrue(finished[1]);
// both are client
- assertNotConnected(test_SSLEngine_setUseClientMode(true, true));
+ /*
+ * Our implementation throws an SSLHandshakeException, but RI just
+ * stalls forever
+ */
+ try {
+ assertNotConnected(test_SSLEngine_setUseClientMode(true, true, null));
+ assertTrue(StandardNames.IS_RI);
+ } catch (SSLHandshakeException maybeExpected) {
+ assertFalse(StandardNames.IS_RI);
+ }
// both are server
- assertNotConnected(test_SSLEngine_setUseClientMode(false, false));
+ assertNotConnected(test_SSLEngine_setUseClientMode(false, false, null));
}
public void test_SSLEngine_setUseClientMode_afterHandshake() throws Exception {
@@ -415,7 +450,8 @@ public class SSLEngineTest extends TestCase {
}
private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
- final boolean serverClientMode)
+ final boolean serverClientMode,
+ final boolean[] finished)
throws Exception {
TestSSLContext c;
if (!clientClientMode && serverClientMode) {
@@ -430,7 +466,7 @@ public class SSLEngineTest extends TestCase {
client.setUseClientMode(clientClientMode);
server.setUseClientMode(serverClientMode);
}
- });
+ }, finished);
}
public void test_SSLEngine_clientAuth() throws Exception {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 5c46406..2911b48 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -246,9 +246,19 @@ public class SSLSocketTest extends TestCase {
ssl.setEnabledProtocols(ssl.getSupportedProtocols());
// Check that setEnabledProtocols affects getEnabledProtocols
- String[] protocols = new String[] { ssl.getSupportedProtocols()[0] };
- ssl.setEnabledProtocols(protocols);
- assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
+ for (String protocol : ssl.getSupportedProtocols()) {
+ if ("SSLv2Hello".equals(protocol)) {
+ try {
+ ssl.setEnabledProtocols(new String[] { protocol });
+ fail("Should fail when SSLv2Hello is set by itself");
+ } catch (IllegalArgumentException expected) {}
+ } else {
+ String[] protocols = new String[] { protocol };
+ ssl.setEnabledProtocols(protocols);
+ assertEquals(Arrays.deepToString(protocols),
+ Arrays.deepToString(ssl.getEnabledProtocols()));
+ }
+ }
}
public void test_SSLSocket_getSession() throws Exception {
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 74263f6..da6fcd6 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -583,12 +583,6 @@ public final class StandardNames extends Assert {
* do to disable general use of SSLv2.
*/
SSL_SOCKET_PROTOCOLS.add("SSLv2Hello");
-
- // RI doesn't support these by default.
- SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT.remove("TLSv1.1");
- SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT.remove("TLSv1.2");
- SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT.remove("TLSv1.1");
- SSL_SOCKET_PROTOCOLS_SERVER_DEFAULT.remove("TLSv1.2");
}
}
@@ -596,12 +590,8 @@ public final class StandardNames extends Assert {
public static final Set<String> SSL_SOCKET_PROTOCOLS_DEFAULT_SSLENGINE =
new HashSet<String>(SSL_SOCKET_PROTOCOLS_CLIENT_DEFAULT);
static {
- // No TLSv1.1 or TLSv1.2 support on SSLEngine based provider
- if (!IS_RI) {
- SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.1");
- SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.2");
- SSL_SOCKET_PROTOCOLS_DEFAULT_SSLENGINE.remove("TLSv1.1");
- SSL_SOCKET_PROTOCOLS_DEFAULT_SSLENGINE.remove("TLSv1.2");
+ if (IS_RI) {
+ SSL_SOCKET_PROTOCOLS_DEFAULT_SSLENGINE.add("SSLv2Hello");
}
}
@@ -790,16 +780,47 @@ public final class StandardNames extends Assert {
CIPHER_SUITES = (IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL;
}
+ /**
+ * Cipher suites that are not negotiated when TLSv1.2 is selected on the RI.
+ */
+ public static final List<String> CIPHER_SUITES_OBSOLETE_TLS12 =
+ Arrays.asList(
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_DH_anon_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
+ );
+
// NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
// javax.net.ssl.SSLEngine.
public static final List<String> CIPHER_SUITES_DEFAULT = (IS_RI)
- ? Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ ? Arrays.asList("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
+ "TLS_RSA_WITH_AES_256_CBC_SHA256",
+ "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
+ "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
+ "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
+ "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
+ "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
@@ -866,28 +887,6 @@ public final class StandardNames extends Assert {
public static final List<String> CIPHER_SUITES_DEFAULT_SSLENGINE =
new ArrayList<String>(CIPHER_SUITES_DEFAULT);
public static final Set<String> CIPHER_SUITES_SSLENGINE = new HashSet<String>(CIPHER_SUITES);
- static {
- // No Elliptic Curve or TLSv1.2 cipher suite support on SSLEngine based provider
- if (!IS_RI) {
- Iterator<String> i = CIPHER_SUITES_SSLENGINE.iterator();
- while (i.hasNext()) {
- String cs = i.next();
- if (cs.startsWith("TLS_EC") || cs.contains("_SHA256") || cs.contains("_SHA384")
- || cs.equals(CIPHER_SUITE_SECURE_RENEGOTIATION)) {
- i.remove();
- }
- }
-
- i = CIPHER_SUITES_DEFAULT_SSLENGINE.iterator();
- while (i.hasNext()) {
- String cs = i.next();
- if (cs.startsWith("TLS_EC") || cs.contains("_SHA256") || cs.contains("_SHA384")
- || cs.equals(CIPHER_SUITE_SECURE_RENEGOTIATION)) {
- i.remove();
- }
- }
- }
- }
public static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;
public static final Map<String, Class<? extends KeySpec>> PUBLIC_KEY_SPEC_CLASSES;
diff --git a/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java b/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
index fd5cc0b..ce40129 100644
--- a/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
+++ b/support/src/test/java/libcore/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
@@ -21,6 +21,7 @@ import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
+import java.security.interfaces.ECPrivateKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.RSAPrivateKeySpec;
@@ -71,6 +72,10 @@ public class RandomPrivateKeyX509ExtendedKeyManager extends ForwardingX509Extend
keyPairGenerator.initialize(new DSAParameterSpec(
originalKeySpec.getP(), originalKeySpec.getQ(), originalKeySpec.getG()));
result = keyPairGenerator.generateKeyPair().getPrivate();
+ } else if ("EC".equals(keyAlgorithm)) {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
+ keyPairGenerator.initialize(((ECPrivateKey) originalPrivateKey).getParams());
+ result = keyPairGenerator.generateKeyPair().getPrivate();
} else {
Assert.fail("Unsupported key algorithm: " + originalPrivateKey.getAlgorithm());
result = null;
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
index 64c8ccb..9793d9a 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLContext.java
@@ -141,7 +141,7 @@ public final class TestSSLContext extends Assert {
* TestSSLContext creation method that allows separate creation of server key store
*/
public static TestSSLContext create(TestKeyStore client, TestKeyStore server) {
- String protocol = "TLS";
+ String protocol = "TLSv1.2";
SSLContext clientContext =
createSSLContext(protocol, client.keyManagers, client.trustManagers);
SSLContext serverContext =
diff --git a/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java b/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
index b6efdeb..79d5d00 100644
--- a/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
+++ b/support/src/test/java/libcore/javax/net/ssl/TestSSLEnginePair.java
@@ -47,10 +47,19 @@ public final class TestSSLEnginePair extends Assert {
}
public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks) throws IOException {
- SSLEngine[] engines = connect(c, hooks);
+ return create(c, hooks, null);
+ }
+
+ public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks, boolean[] finished)
+ throws IOException {
+ SSLEngine[] engines = connect(c, hooks, finished);
return new TestSSLEnginePair(c, engines[0], engines[1]);
}
+ public static SSLEngine[] connect(TestSSLContext c, Hooks hooks) throws IOException {
+ return connect(c, hooks, null);
+ }
+
/**
* Create a new connected server/client engine pair within a
* existing SSLContext. Optionally specify clientCipherSuites to
@@ -59,11 +68,16 @@ public final class TestSSLEnginePair extends Assert {
* cipher suite negotiation.
*/
public static SSLEngine[] connect(final TestSSLContext c,
- Hooks hooks) throws IOException {
+ Hooks hooks,
+ boolean finished[]) throws IOException {
if (hooks == null) {
hooks = new Hooks();
}
+ // FINISHED state should be returned only once.
+ boolean[] clientFinished = new boolean[1];
+ boolean[] serverFinished = new boolean[1];
+
SSLSession session = c.clientContext.createSSLEngine().getSession();
int packetBufferSize = session.getPacketBufferSize();
@@ -73,7 +87,7 @@ public final class TestSSLEnginePair extends Assert {
int applicationBufferSize = session.getApplicationBufferSize();
ByteBuffer scratch = ByteBuffer.allocate(applicationBufferSize);
- SSLEngine client = c.clientContext.createSSLEngine();
+ SSLEngine client = c.clientContext.createSSLEngine(c.host.getHostName(), c.port);
SSLEngine server = c.serverContext.createSSLEngine();
client.setUseClientMode(true);
server.setUseClientMode(false);
@@ -93,20 +107,26 @@ public final class TestSSLEnginePair extends Assert {
progress |= handshakeCompleted(client,
clientToServer,
serverToClient,
- scratch);
+ scratch,
+ clientFinished);
}
if (!serverDone) {
progress |= handshakeCompleted(server,
serverToClient,
clientToServer,
- scratch);
+ scratch,
+ serverFinished);
}
if (!progress) {
- // let caller detect the problem, but don't just hang here
break;
}
}
+ if (finished != null) {
+ assertEquals(2, finished.length);
+ finished[0] = clientFinished[0];
+ finished[1] = clientFinished[0];
+ }
return new SSLEngine[] { server, client };
}
@@ -119,7 +139,8 @@ public final class TestSSLEnginePair extends Assert {
private static boolean handshakeCompleted(SSLEngine engine,
ByteBuffer output,
ByteBuffer input,
- ByteBuffer scratch) throws IOException {
+ ByteBuffer scratch,
+ boolean[] finished) throws IOException {
try {
// make the other side's output into our input
input.flip();
@@ -127,7 +148,7 @@ public final class TestSSLEnginePair extends Assert {
HandshakeStatus status = engine.getHandshakeStatus();
switch (status) {
- case NEED_TASK:
+ case NEED_TASK: {
boolean progress = false;
while (true) {
Runnable runnable = engine.getDelegatedTask();
@@ -137,8 +158,9 @@ public final class TestSSLEnginePair extends Assert {
runnable.run();
progress = true;
}
+ }
- case NEED_UNWRAP:
+ case NEED_UNWRAP: {
// avoid underflow
if (input.remaining() == 0) {
return false;
@@ -146,16 +168,20 @@ public final class TestSSLEnginePair extends Assert {
SSLEngineResult unwrapResult = engine.unwrap(input, scratch);
assertEquals(SSLEngineResult.Status.OK, unwrapResult.getStatus());
assertEquals(0, scratch.position());
+ assertFinishedOnce(finished, unwrapResult);
return true;
+ }
- case NEED_WRAP:
+ case NEED_WRAP: {
// avoid possible overflow
if (output.remaining() != output.capacity()) {
return false;
}
SSLEngineResult wrapResult = engine.wrap(EMPTY_BYTE_BUFFER, output);
assertEquals(SSLEngineResult.Status.OK, wrapResult.getStatus());
+ assertFinishedOnce(finished, wrapResult);
return true;
+ }
case NOT_HANDSHAKING:
// should have been checked by caller before calling
@@ -170,4 +196,11 @@ public final class TestSSLEnginePair extends Assert {
input.compact();
}
}
+
+ private static void assertFinishedOnce(boolean[] finishedOut, SSLEngineResult result) {
+ if (result.getHandshakeStatus() == HandshakeStatus.FINISHED) {
+ assertFalse("should only return FINISHED once", finishedOut[0]);
+ finishedOut[0] = true;
+ }
+ }
}