diff options
11 files changed, 455 insertions, 358 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java index 02b015b..6dd08b9 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java @@ -118,90 +118,91 @@ public class NativeCrypto { static { // Note these are added in priority order + // Android doesn't currently support Elliptic Curve or Diffie-Hellman add("SSL_RSA_WITH_RC4_128_MD5", "RC4-MD5"); add("SSL_RSA_WITH_RC4_128_SHA", "RC4-SHA"); add("TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA"); add("TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA"); - add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA"); - add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA"); - add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA"); - add("TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA"); - add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA"); - add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA"); - add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA"); - add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA"); - add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA"); - add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA"); - add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA"); - add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA"); - add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA"); - add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA"); - add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA"); - add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA"); + // add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA"); + // add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA"); + // add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA"); + // add("TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA"); + // add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA"); + // add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA"); + // add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA"); + // add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA"); + // add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA"); + // add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA"); + // add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA"); + // add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA"); + // add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA"); + // add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA"); + // add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA"); + // add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA"); add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA"); - add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA"); - add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA"); - add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA"); - add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA"); - add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA"); - add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA"); + // add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA"); + // add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA"); + // add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA"); + // add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA"); + // add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA"); + // add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA"); add("SSL_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA"); - add("SSL_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA"); - add("SSL_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA"); + // add("SSL_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA"); + // add("SSL_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA"); add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", "EXP-RC4-MD5"); add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DES-CBC-SHA"); - add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA"); - add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA"); + // add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA"); + // add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA"); add("SSL_RSA_WITH_NULL_MD5", "NULL-MD5"); add("SSL_RSA_WITH_NULL_SHA", "NULL-SHA"); - add("TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA"); - add("TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA"); - add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA"); - add("TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA"); - add("SSL_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5"); - add("TLS_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA"); - add("TLS_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA"); - add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA"); - add("SSL_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA"); - add("TLS_ECDH_anon_WITH_RC4_128_SHA", "AECDH-RC4-SHA"); - add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA"); - add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA"); - add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "AECDH-DES-CBC3-SHA"); - add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5"); - add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA"); - add("TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA"); - + // add("TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA"); + // add("TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA"); + // add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA"); + // add("TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA"); + // add("SSL_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5"); + // add("TLS_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA"); + // add("TLS_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA"); + // add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA"); + // add("SSL_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA"); + // add("TLS_ECDH_anon_WITH_RC4_128_SHA", "AECDH-RC4-SHA"); + // add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA"); + // add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA"); + // add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "AECDH-DES-CBC3-SHA"); + // add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5"); + // add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA"); + // add("TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA"); + // No Kerberos in Android - //add("TLS_KRB5_WITH_RC4_128_SHA", "KRB5-RC4-SHA"); - //add("TLS_KRB5_WITH_RC4_128_MD5", "KRB5-RC4-MD5"); - //add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "KRB5-DES-CBC3-SHA"); - //add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "KRB5-DES-CBC3-MD5"); - //add("TLS_KRB5_WITH_DES_CBC_SHA", "KRB5-DES-CBC-SHA"); - //add("TLS_KRB5_WITH_DES_CBC_MD5", "KRB5-DES-CBC-MD5"); - //add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "EXP-KRB5-RC4-SHA"); - //add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "EXP-KRB5-RC4-MD5"); - //add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "EXP-KRB5-DES-CBC-SHA"); - //add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "EXP-KRB5-DES-CBC-MD5"); + // add("TLS_KRB5_WITH_RC4_128_SHA", "KRB5-RC4-SHA"); + // add("TLS_KRB5_WITH_RC4_128_MD5", "KRB5-RC4-MD5"); + // add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "KRB5-DES-CBC3-SHA"); + // add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "KRB5-DES-CBC3-MD5"); + // add("TLS_KRB5_WITH_DES_CBC_SHA", "KRB5-DES-CBC-SHA"); + // add("TLS_KRB5_WITH_DES_CBC_MD5", "KRB5-DES-CBC-MD5"); + // add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "EXP-KRB5-RC4-SHA"); + // add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "EXP-KRB5-RC4-MD5"); + // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "EXP-KRB5-DES-CBC-SHA"); + // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "EXP-KRB5-DES-CBC-MD5"); // not implemented by either RI or OpenSSL - //add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", null); - //add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", null); + // add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", null); + // add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", null); // EXPORT1024 suites were never standardized but were widely implemented. // OpenSSL 0.9.8c and later have disabled TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES - //add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DES-CBC-SHA"); - //add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-RC4-SHA"); + // add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DES-CBC-SHA"); + // add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-RC4-SHA"); // No RC2 - //add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-RC2-CBC-MD5"); - //add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", "EXP-KRB5-RC2-CBC-SHA"); - //add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-KRB5-RC2-CBC-MD5"); + // add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-RC2-CBC-MD5"); + // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", "EXP-KRB5-RC2-CBC-SHA"); + // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-KRB5-RC2-CBC-MD5"); // PSK is Private Shared Key - didn't exist in Froyo's openssl - no JSSE equivalent - //add(null, "PSK-3DES-EDE-CBC-SHA"); - //add(null, "PSK-AES128-CBC-SHA"); - //add(null, "PSK-AES256-CBC-SHA"); - //add(null, "PSK-RC4-SHA"); + // add(null, "PSK-3DES-EDE-CBC-SHA"); + // add(null, "PSK-AES128-CBC-SHA"); + // add(null, "PSK-AES256-CBC-SHA"); + // add(null, "PSK-RC4-SHA"); } @@ -219,21 +220,22 @@ public class NativeCrypto { public static String[] getDefaultCipherSuites() { return new String[] { + // Android doesn't currently support Elliptic Curve or Diffie-Hellman "SSL_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + // "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + // "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", - "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", - "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + // "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + // "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA", - "SSL_DHE_RSA_WITH_DES_CBC_SHA", - "SSL_DHE_DSS_WITH_DES_CBC_SHA", + // "SSL_DHE_RSA_WITH_DES_CBC_SHA", + // "SSL_DHE_DSS_WITH_DES_CBC_SHA", "SSL_RSA_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_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + // "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" }; } diff --git a/luni/src/main/java/org/bouncycastle/x509/X509Util.java b/luni/src/main/java/org/bouncycastle/x509/X509Util.java index 854ec3a..2130d0e 100644 --- a/luni/src/main/java/org/bouncycastle/x509/X509Util.java +++ b/luni/src/main/java/org/bouncycastle/x509/X509Util.java @@ -16,10 +16,8 @@ import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -// BEGIN android-removed -// import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; -// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -// END android-removed +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; @@ -46,18 +44,16 @@ class X509Util algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2")); algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2")); - // BEGIN android-removed - // algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); - // algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); - // algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); - // algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); - // algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); - // algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); - // algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); - // algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); - // algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); - // algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); - // END android-removed + algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); + algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); + algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); + algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); + algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); + algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); + algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); + algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); + algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); + algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); @@ -65,16 +61,14 @@ class X509Util // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // - // BEGIN android-removed - // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); - // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); - // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); - // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); - // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); - // noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); - // noParams.add(NISTObjectIdentifiers.dsa_with_sha224); - // noParams.add(NISTObjectIdentifiers.dsa_with_sha256); - // END android-removed + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); + noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); + noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); + noParams.add(NISTObjectIdentifiers.dsa_with_sha224); + noParams.add(NISTObjectIdentifiers.dsa_with_sha256); } static DERObjectIdentifier getAlgorithmOID( diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp index 87cedca..a0492ce 100644 --- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp +++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp @@ -115,7 +115,7 @@ static void throwSSLExceptionStr(JNIEnv* env, const char* message) { * @param sslErrorCode error code returned from SSL_get_error() * @param message null-ok; general error message */ -static void throwSSLExceptionWithSslErrors(JNIEnv* env, int sslErrorCode, const char* message) { +static void throwSSLExceptionWithSslErrors(JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) { const char* messageStr = NULL; char* str; int ret; @@ -154,8 +154,8 @@ static void throwSSLExceptionWithSslErrors(JNIEnv* env, int sslErrorCode, const } // Prepend either our explicit message or a default one. - if (asprintf(&str, "%s: %s", - (message != NULL) ? message : "SSL error", messageStr) <= 0) { + if (asprintf(&str, "%s: ssl=%p: %s", + (message != NULL) ? message : "SSL error", ssl, messageStr) <= 0) { // problem with asprintf throwSSLExceptionStr(env, messageStr); LOGV("%s", messageStr); @@ -1421,7 +1421,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, SSL* ssl = SSL_new(ssl_ctx); if (ssl == NULL) { - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Unable to create SSL structure"); JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx); return NULL; @@ -1445,7 +1445,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, if (privatekeyevp == NULL) { LOGE(ERR_error_string(ERR_get_error(), NULL)); - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error parsing the private key"); SSL_free(ssl); JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx); @@ -1459,7 +1459,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, if (certificatesx509 == NULL) { LOGE(ERR_error_string(ERR_get_error(), NULL)); - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error parsing the certificates"); EVP_PKEY_free(privatekeyevp); SSL_free(ssl); @@ -1470,7 +1470,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, int ret = SSL_use_certificate(ssl, certificatesx509); if (ret != 1) { LOGE(ERR_error_string(ERR_get_error(), NULL)); - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error setting the certificates"); X509_free(certificatesx509); EVP_PKEY_free(privatekeyevp); @@ -1482,7 +1482,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, ret = SSL_use_PrivateKey(ssl, privatekeyevp); if (ret != 1) { LOGE(ERR_error_string(ERR_get_error(), NULL)); - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error setting the private key"); X509_free(certificatesx509); EVP_PKEY_free(privatekeyevp); @@ -1493,7 +1493,7 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, ret = SSL_check_private_key(ssl); if (ret != 1) { - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error checking the private key"); X509_free(certificatesx509); EVP_PKEY_free(privatekeyevp); @@ -1685,7 +1685,7 @@ static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass, */ int sslErrorCode = SSL_get_error(ssl, ret); if (sslErrorCode != SSL_ERROR_ZERO_RETURN) { - throwSSLExceptionWithSslErrors(env, sslErrorCode, + throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set"); SSL_clear(ssl); } @@ -1765,7 +1765,7 @@ static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd); if (ret != 1) { - throwSSLExceptionWithSslErrors(env, 0, + throwSSLExceptionWithSslErrors(env, ssl, 0, "Error setting the file descriptor"); SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl); @@ -1835,7 +1835,7 @@ static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, int selectResult = sslSelect(error, fd, appData, timeout); if (selectResult == -1) { - throwSSLExceptionWithSslErrors(env, error, "handshake error"); + throwSSLExceptionWithSslErrors(env, ssl, error, "handshake error"); SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl); return 0; @@ -1864,8 +1864,8 @@ static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, (sslErrorCode == SSL_ERROR_SYSCALL && errno == 0)) { throwSSLExceptionStr(env, "Connection closed by peer"); } else { - throwSSLExceptionWithSslErrors(env, sslErrorCode, - "Trouble accepting connection"); + throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, + "Trouble with SSL handshake"); } SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl); @@ -1877,8 +1877,8 @@ static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, * at this point. */ int sslErrorCode = SSL_get_error(ssl, ret); - throwSSLExceptionWithSslErrors(env, sslErrorCode, - "Trouble accepting connection"); + throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, + "Trouble with SSL handshake"); SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl); return 0; @@ -2064,7 +2064,7 @@ static jint NativeCrypto_SSL_read_byte(JNIEnv* env, jclass, jint ssl_address, ji switch (ret) { case THROW_EXCEPTION: // See sslRead() regarding improper failure to handle normal cases. - throwSSLExceptionWithSslErrors(env, errorCode, "Read error"); + throwSSLExceptionWithSslErrors(env, ssl, errorCode, "Read error"); result = -1; break; case THROW_SOCKETTIMEOUTEXCEPTION: @@ -2107,7 +2107,7 @@ static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jbyteAr int result; if (ret == THROW_EXCEPTION) { // See sslRead() regarding improper failure to handle normal cases. - throwSSLExceptionWithSslErrors(env, errorCode, + throwSSLExceptionWithSslErrors(env, ssl, errorCode, "Read error"); result = -1; } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) { @@ -2263,7 +2263,7 @@ static void NativeCrypto_SSL_write_byte(JNIEnv* env, jclass, jint ssl_address, j if (ret == THROW_EXCEPTION) { // See sslWrite() regarding improper failure to handle normal cases. - throwSSLExceptionWithSslErrors(env, errorCode, + throwSSLExceptionWithSslErrors(env, ssl, errorCode, "Write error"); } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) { throwSocketTimeoutException(env, "Write timed out"); @@ -2289,7 +2289,7 @@ static void NativeCrypto_SSL_write(JNIEnv* env, jclass, if (ret == THROW_EXCEPTION) { // See sslWrite() regarding improper failure to handle normal cases. - throwSSLExceptionWithSslErrors(env, errorCode, + throwSSLExceptionWithSslErrors(env, ssl, errorCode, "Write error"); } else if(ret == THROW_SOCKETTIMEOUTEXCEPTION) { throwSocketTimeoutException(env, "Write timed out"); @@ -2372,7 +2372,7 @@ static void NativeCrypto_SSL_shutdown( * exception. */ int sslErrorCode = SSL_get_error(ssl, ret); - throwSSLExceptionWithSslErrors(env, sslErrorCode, "SSL shutdown failed"); + throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL shutdown failed"); break; } diff --git a/luni/src/test/java/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/javax/net/ssl/SSLContextTest.java index 9200910..ae63e3e 100644 --- a/luni/src/test/java/javax/net/ssl/SSLContextTest.java +++ b/luni/src/test/java/javax/net/ssl/SSLContextTest.java @@ -159,8 +159,6 @@ public class SSLContextTest extends TestCase { assertNotNull(testContext); assertNotNull(testContext.keyStore); assertNull(testContext.keyStorePassword); - assertNotNull(testContext.publicAlias); - assertNotNull(testContext.privateAlias); assertNotNull(testContext.sslContext); assertNotNull(testContext.serverSocket); assertNotNull(testContext.host); diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java index f8aed75..2f6b85a 100644 --- a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java +++ b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java @@ -27,13 +27,13 @@ import junit.framework.TestCase; public class SSLSessionContextTest extends TestCase { public static final void assertSSLSessionContextSize(int expected, SSLContext sslContext) { - assertSSLSessionContextSize(expected, + assertSSLSessionContextSize(expected, sslContext.getClientSessionContext(), sslContext.getServerSessionContext()); } - public static final void assertSSLSessionContextSize(int expected, - SSLSessionContext client, + public static final void assertSSLSessionContextSize(int expected, + SSLSessionContext client, SSLSessionContext server) { assertSSLSessionContextSize(expected, client, false); assertSSLSessionContextSize(expected, server, true); @@ -150,7 +150,7 @@ public class SSLSessionContextTest extends TestCase { String[] supportedCipherSuites = c.serverSocket.getSupportedCipherSuites(); c.serverSocket.setEnabledCipherSuites(supportedCipherSuites); - LinkedList<String> uniqueCipherSuites + LinkedList<String> uniqueCipherSuites = new LinkedList(Arrays.asList(supportedCipherSuites)); // only use RSA cipher suites which will work with our TrustProvider Iterator<String> i = uniqueCipherSuites.iterator(); @@ -192,12 +192,12 @@ public class SSLSessionContextTest extends TestCase { String cipherSuite1 = uniqueCipherSuites.get(0); String cipherSuite2 = uniqueCipherSuites.get(1); String cipherSuite3 = uniqueCipherSuites.get(2); - - TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }); + + TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null); assertSSLSessionContextSize(1, c.sslContext); - TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }); + TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null); assertSSLSessionContextSize(2, c.sslContext); - TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }); + TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null); assertSSLSessionContextSize(3, c.sslContext); client.setSessionCacheSize(1); @@ -205,14 +205,14 @@ public class SSLSessionContextTest extends TestCase { assertEquals(1, client.getSessionCacheSize()); assertEquals(1, server.getSessionCacheSize()); assertSSLSessionContextSize(1, c.sslContext); - TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }); + TestSSLSocketPair.connect(c, new String[] { cipherSuite1 }, null); assertSSLSessionContextSize(1, c.sslContext); client.setSessionCacheSize(2); server.setSessionCacheSize(2); - TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }); + TestSSLSocketPair.connect(c, new String[] { cipherSuite2 }, null); assertSSLSessionContextSize(2, c.sslContext); - TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }); + TestSSLSocketPair.connect(c, new String[] { cipherSuite3 }, null); assertSSLSessionContextSize(2, c.sslContext); } diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java index eb15e57..0306661 100644 --- a/luni/src/test/java/javax/net/ssl/SSLSessionTest.java +++ b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java @@ -95,8 +95,8 @@ public class SSLSessionTest extends TestCase { 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]); + TestSSLContext.assertCertificateInKeyStore(s.server.getLocalCertificates()[0], + s.s.c.keyStore); } @KnownFailure("client local principal should be null as it should not have been requested by server") @@ -108,10 +108,8 @@ public class SSLSessionTest extends TestCase { assertNull(s.client.getLocalPrincipal()); assertNotNull(s.server.getLocalPrincipal()); assertNotNull(s.server.getLocalPrincipal().getName()); - X509Certificate x509certificate = (X509Certificate) - s.s.c.keyStore.getCertificate(s.s.c.publicAlias); - assertEquals(x509certificate.getSubjectDN().getName(), - s.server.getLocalPrincipal().getName()); + TestSSLContext.assertCertificateInKeyStore(s.server.getLocalPrincipal(), + s.s.c.keyStore); } public void test_SSLSession_getPacketBufferSize() { @@ -130,8 +128,9 @@ public class SSLSessionTest extends TestCase { } assertNotNull(s.client.getPeerCertificates()); assertEquals(1, s.client.getPeerCertificates().length); - assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias), - s.client.getPeerCertificates()[0]); + TestSSLContext.assertCertificateInKeyStore(s.client.getPeerCertificates()[0], + s.s.c.keyStore); + try { assertNull(s.server.getPeerCertificates()); fail(); @@ -148,8 +147,8 @@ public class SSLSessionTest extends TestCase { } assertNotNull(s.client.getPeerCertificates()); assertEquals(1, s.client.getPeerCertificates().length); - assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias), - s.client.getPeerCertificates()[0]); + TestSSLContext.assertCertificateInKeyStore(s.client.getPeerCertificates()[0], + s.s.c.keyStore); try { s.server.getPeerCertificates(); fail(); @@ -185,11 +184,8 @@ public class SSLSessionTest extends TestCase { } assertNotNull(s.client.getPeerPrincipal()); assertNotNull(s.client.getPeerPrincipal().getName()); - X509Certificate x509certificate = (X509Certificate) - s.s.c.keyStore.getCertificate(s.s.c.publicAlias); - assertEquals(x509certificate.getSubjectDN().getName(), - s.client.getPeerPrincipal().getName()); - + TestSSLContext.assertCertificateInKeyStore(s.client.getPeerPrincipal(), + s.s.c.keyStore); } public void test_SSLSession_getProtocol() { diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java index 3a44510..067f649 100644 --- a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java +++ b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java @@ -21,6 +21,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.security.Key; +import java.security.KeyStore; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.X509Certificate; @@ -33,7 +34,7 @@ import junit.framework.TestCase; public class SSLSocketTest extends TestCase { - public void test_SSLSocket_getSupportedCipherSuites() throws Exception { + public void test_SSLSocket_getSupportedCipherSuites_names() throws Exception { SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket) sf.createSocket(); String[] cipherSuites = ssl.getSupportedCipherSuites(); @@ -47,6 +48,26 @@ public class SSLSocketTest extends TestCase { assertEquals(StandardNames.CIPHER_SUITES.size(), cipherSuites.length); } + @KnownFailure("Need to support SSL_RSA_EXPORT_WITH_RC4_40_MD5") + public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception { + TestSSLContext c = TestSSLContext.create(); + String[] cipherSuites = c.sslContext.getSocketFactory().getSupportedCipherSuites(); + for (String cipherSuite : cipherSuites) { + if (cipherSuite.startsWith("TLS_KRB5_")) { + /* + * Kerberos cipher suites require external setup. See "3.1 Kerberos Requirements" in + * http://midatl.radford.edu/docs/java-se-5/docs/guide/security/jsse/jsse-tiger-beta1.html#KRB + */ + continue; + } + // System.out.println("Trying to connect cipher suite " + cipherSuite); + String[] cipherSuiteArray = new String[] { cipherSuite }; + // TODO Fix Known Failure + // Need to support SSL_RSA_EXPORT_WITH_RC4_40_MD5 + TestSSLSocketPair.connect(c, cipherSuiteArray, cipherSuiteArray); + } + } + public void test_SSLSocket_getEnabledCipherSuites() throws Exception { SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket) sf.createSocket(); @@ -183,7 +204,7 @@ public class SSLSocketTest extends TestCase { assertNotNull(localCertificates); assertEquals(1, localCertificates.length); assertNotNull(localCertificates[0]); - assertNotNull(localCertificates[0].equals(c.keyStore.getCertificate(c.privateAlias))); + TestSSLContext.assertCertificateInKeyStore(localCertificates[0], c.keyStore); } catch (RuntimeException e) { throw e; } catch (Exception e) { @@ -199,13 +220,13 @@ public class SSLSocketTest extends TestCase { assertNotNull(peerCertificates); assertEquals(1, peerCertificates.length); assertNotNull(peerCertificates[0]); - assertNotNull(peerCertificates[0].equals(c.keyStore.getCertificate(c.publicAlias))); + TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.keyStore); thread.join(); } @KnownFailure("Should throw SSLException from SSLServerSocket.accept with no private key configured") public void test_SSLSocket_startHandshake_noKeyStore() throws Exception { - TestSSLContext c = TestSSLContext.create(null, null, null, null); + TestSSLContext c = TestSSLContext.create(null, null); SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port); try { SSLSocket server = (SSLSocket) c.serverSocket.accept(); @@ -293,27 +314,6 @@ public class SSLSocketTest extends TestCase { assertTrue(Arrays.asList(client.getEnabledCipherSuites()).contains(cipherSuite)); assertTrue(Arrays.asList(c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite)); - 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())); - X509Certificate x509certificate = (X509Certificate) certificate; - // TODO Fix Known Failure // Need to fix NativeCrypto.SSL_new to not use SSL_use_certificate assertNull(localCertificates); @@ -321,17 +321,16 @@ public class SSLSocketTest extends TestCase { assertNotNull(peerCertificates); assertEquals(1, peerCertificates.length); assertNotNull(peerCertificates[0]); - assertEquals(peerCertificates[0], x509certificate); + TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.keyStore); assertNotNull(peerCertificateChain); assertEquals(1, peerCertificateChain.length); assertNotNull(peerCertificateChain[0]); - assertEquals(x509certificate.getSubjectDN().getName(), - peerCertificateChain[0].getSubjectDN().getName()); + TestSSLContext.assertCertificateInKeyStore( + peerCertificateChain[0].getSubjectDN(), c.keyStore); assertNotNull(peerPrincipal); - assertEquals(x509certificate.getSubjectDN().getName(), - peerPrincipal.getName()); + TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.keyStore); assertNull(localPrincipal); diff --git a/support/src/test/java/javax/net/ssl/StandardNames.java b/support/src/test/java/javax/net/ssl/StandardNames.java index bc0e4e3..bc3d97a 100644 --- a/support/src/test/java/javax/net/ssl/StandardNames.java +++ b/support/src/test/java/javax/net/ssl/StandardNames.java @@ -93,60 +93,65 @@ public final class StandardNames { addOpenSsl(cipherSuite); } + private static final void addNeither(String cipherSuite) { + CIPHER_SUITES_NEITHER.add(cipherSuite); + } + static { // Note these are added in priority order as defined by RI 6 documentation. + // Android currently does not support Elliptic Curve or Diffie-Hellman addBoth( "SSL_RSA_WITH_RC4_128_MD5"); addBoth( "SSL_RSA_WITH_RC4_128_SHA"); addBoth( "TLS_RSA_WITH_AES_128_CBC_SHA"); addOpenSsl("TLS_RSA_WITH_AES_256_CBC_SHA"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_RC4_128_SHA"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); - addOpenSsl("TLS_ECDH_RSA_WITH_RC4_128_SHA"); - addOpenSsl("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"); - addOpenSsl("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"); - addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"); - addOpenSsl("TLS_ECDHE_RSA_WITH_RC4_128_SHA"); - addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); - addBoth( "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_DHE_DSS_WITH_AES_256_CBC_SHA"); + addNeither("TLS_ECDH_ECDSA_WITH_RC4_128_SHA"); + addNeither("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"); + addNeither("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); + addNeither("TLS_ECDH_RSA_WITH_RC4_128_SHA"); + addNeither("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"); + addNeither("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"); + addNeither("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"); + addNeither("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"); + addNeither("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"); + addNeither("TLS_ECDHE_RSA_WITH_RC4_128_SHA"); + addNeither("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"); + addNeither("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"); + addRi( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); + addNeither("TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); + addRi( "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"); + addNeither("TLS_DHE_DSS_WITH_AES_256_CBC_SHA"); addBoth( "SSL_RSA_WITH_3DES_EDE_CBC_SHA"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"); - addOpenSsl("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"); - addOpenSsl("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"); - addOpenSsl("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"); + addNeither("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"); + addNeither("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"); + addNeither("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"); + addNeither("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"); addBoth( "SSL_RSA_WITH_DES_CBC_SHA"); - addBoth( "SSL_DHE_RSA_WITH_DES_CBC_SHA"); - addBoth( "SSL_DHE_DSS_WITH_DES_CBC_SHA"); + addRi( "SSL_DHE_RSA_WITH_DES_CBC_SHA"); + addRi( "SSL_DHE_DSS_WITH_DES_CBC_SHA"); addBoth( "SSL_RSA_EXPORT_WITH_RC4_40_MD5"); addBoth( "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"); - addBoth( "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"); - addBoth( "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"); + addRi( "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"); addBoth( "SSL_RSA_WITH_NULL_MD5"); addBoth( "SSL_RSA_WITH_NULL_SHA"); - addOpenSsl("TLS_ECDH_ECDSA_WITH_NULL_SHA"); - addOpenSsl("TLS_ECDH_RSA_WITH_NULL_SHA"); - addOpenSsl("TLS_ECDHE_ECDSA_WITH_NULL_SHA"); - addOpenSsl("TLS_ECDHE_RSA_WITH_NULL_SHA"); - addBoth( "SSL_DH_anon_WITH_RC4_128_MD5"); - addBoth( "TLS_DH_anon_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_DH_anon_WITH_AES_256_CBC_SHA"); - addBoth( "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DH_anon_WITH_DES_CBC_SHA"); - addOpenSsl("TLS_ECDH_anon_WITH_RC4_128_SHA"); - addOpenSsl("TLS_ECDH_anon_WITH_AES_128_CBC_SHA"); - addOpenSsl("TLS_ECDH_anon_WITH_AES_256_CBC_SHA"); - addOpenSsl("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"); - addBoth( "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"); - addBoth( "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); - addOpenSsl("TLS_ECDH_anon_WITH_NULL_SHA"); + addNeither("TLS_ECDH_ECDSA_WITH_NULL_SHA"); + addNeither("TLS_ECDH_RSA_WITH_NULL_SHA"); + addNeither("TLS_ECDHE_ECDSA_WITH_NULL_SHA"); + addNeither("TLS_ECDHE_RSA_WITH_NULL_SHA"); + addRi( "SSL_DH_anon_WITH_RC4_128_MD5"); + addRi( "TLS_DH_anon_WITH_AES_128_CBC_SHA"); + addNeither("TLS_DH_anon_WITH_AES_256_CBC_SHA"); + addRi( "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DH_anon_WITH_DES_CBC_SHA"); + addNeither("TLS_ECDH_anon_WITH_RC4_128_SHA"); + addNeither("TLS_ECDH_anon_WITH_AES_128_CBC_SHA"); + addNeither("TLS_ECDH_anon_WITH_AES_256_CBC_SHA"); + addNeither("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"); + addRi( "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"); + addRi( "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); + addNeither("TLS_ECDH_anon_WITH_NULL_SHA"); // Android does not have Keberos support addRi ("TLS_KRB5_WITH_RC4_128_SHA"); @@ -161,17 +166,17 @@ public final class StandardNames { addRi ("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"); // Dropped - CIPHER_SUITES_NEITHER.add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"); - CIPHER_SUITES_NEITHER.add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"); + addNeither("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"); + addNeither("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"); // Old non standard exportable encryption - CIPHER_SUITES_NEITHER.add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA"); - CIPHER_SUITES_NEITHER.add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA"); + addNeither("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA"); + addNeither("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA"); // No RC2 - CIPHER_SUITES_NEITHER.add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"); - CIPHER_SUITES_NEITHER.add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"); - CIPHER_SUITES_NEITHER.add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"); + addNeither("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"); + addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"); + addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"); CIPHER_SUITES = (TestSSLContext.IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL; } diff --git a/support/src/test/java/javax/net/ssl/TestKeyStore.java b/support/src/test/java/javax/net/ssl/TestKeyStore.java new file mode 100644 index 0000000..97b5c23 --- /dev/null +++ b/support/src/test/java/javax/net/ssl/TestKeyStore.java @@ -0,0 +1,173 @@ +/* + * 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 java.math.BigInteger; +import java.net.InetAddress; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Hashtable; +import org.bouncycastle.jce.X509Principal; +import org.bouncycastle.x509.X509V3CertificateGenerator; + +/** + * TestSSLContext is a convenience class for other tests that + * want a canned KeyStore with a variety of key pairs. + * + * Creating a key store is relatively slow, so a singleton instance is + * accessible via TestKeyStore.get(). + */ +public final class TestKeyStore { + + public final KeyStore keyStore; + public final char[] keyStorePassword; + + private TestKeyStore(KeyStore keyStore, + char[] keyStorePassword) { + this.keyStore = keyStore; + this.keyStorePassword = keyStorePassword; + } + + private static final TestKeyStore SINGLETON = create(); + + public static TestKeyStore get() { + return SINGLETON; + } + + public static TestKeyStore create() { + try { + char[] keyStorePassword = null; + KeyStore keyStore = createKeyStore(); + String[] keyAlgorithms = new String[] { "RSA", "DSA" }; + for (String keyAlgorithm : keyAlgorithms) { + String publicAlias = "public-" + keyAlgorithm; + String privateAlias = "private-" + keyAlgorithm; + createKeys(keyStore, keyStorePassword, keyAlgorithm, publicAlias, privateAlias); + } + return new TestKeyStore(keyStore, keyStorePassword); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Create an empty BKS KeyStore + * + * The KeyStore is optionally password protected by the + * keyStorePassword argument, which can be null if a password is + * not desired. + */ + public static KeyStore createKeyStore() throws Exception { + KeyStore keyStore = KeyStore.getInstance("BKS"); + keyStore.load(null, null); + return keyStore; + } + + /** + * Add newly generated keys of a given key type to an existing + * KeyStore. The PrivateKey will be stored under the specified + * private alias name and a X509Certificate based on the matching + * PublicKey stored under the given public alias name. + * + * 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. + * + * Based on: + * org.bouncycastle.jce.provider.test.SigTest + * org.bouncycastle.jce.provider.test.CertTest + */ + public static KeyStore createKeys(KeyStore keyStore, + char[] keyStorePassword, + String keyAlgorithm, + String publicAlias, + String privateAlias) + throws Exception { + + PrivateKey privateKey; + X509Certificate x509c; + if (publicAlias == null && privateAlias == null) { + // don't want anything apparently + privateKey = null; + x509c = null; + } else { + // 1.) we make the keys + int keysize = 1024; + KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgorithm); + kpg.initialize(keysize, new SecureRandom()); + KeyPair kp = kpg.generateKeyPair(); + privateKey = (PrivateKey)kp.getPrivate(); + PublicKey publicKey = (PublicKey)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. + + Hashtable attributes = new Hashtable(); + attributes.put(X509Principal.CN, InetAddress.getLocalHost().getCanonicalHostName()); + X509Principal dn = new X509Principal(attributes); + + long millisPerDay = 24 * 60 * 60 * 1000; + long now = System.currentTimeMillis(); + Date start = new Date(now - millisPerDay); + Date end = new Date(now + millisPerDay); + BigInteger serial = BigInteger.valueOf(1); + + X509V3CertificateGenerator x509cg = new X509V3CertificateGenerator(); + x509cg.setSubjectDN(dn); + x509cg.setIssuerDN(dn); + x509cg.setNotBefore(start); + x509cg.setNotAfter(end); + x509cg.setPublicKey(publicKey); + x509cg.setSignatureAlgorithm("sha1With" + keyAlgorithm); + x509cg.setSerialNumber(serial); + x509c = x509cg.generateX509Certificate(privateKey); + } + + X509Certificate[] x509cc; + if (privateAlias == null) { + // don't need certificate chain + x509cc = null; + } else { + x509cc = new X509Certificate[] { x509c }; + } + + // 3.) put certificate and private key into the key store + if (privateAlias != null) { + keyStore.setKeyEntry(privateAlias, privateKey, keyStorePassword, x509cc); + } + if (publicAlias != null) { + keyStore.setCertificateEntry(publicAlias, x509c); + } + return keyStore; + } +} diff --git a/support/src/test/java/javax/net/ssl/TestSSLContext.java b/support/src/test/java/javax/net/ssl/TestSSLContext.java index 43e085a..5ec040c 100644 --- a/support/src/test/java/javax/net/ssl/TestSSLContext.java +++ b/support/src/test/java/javax/net/ssl/TestSSLContext.java @@ -16,23 +16,17 @@ package javax.net.ssl; -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.Principal; import java.security.SecureRandom; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.Date; -import java.util.Hashtable; -import org.bouncycastle.jce.X509Principal; +import java.util.Collections; +import junit.framework.AssertionFailedError; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.x509.X509V3CertificateGenerator; /** * TestSSLContext is a convenience class for other tests that @@ -79,8 +73,6 @@ public final class TestSSLContext { 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; @@ -88,16 +80,12 @@ public final class TestSSLContext { private TestSSLContext(KeyStore keyStore, char[] keyStorePassword, - String publicAlias, - String privateAlias, SSLContext sslContext, SSLServerSocket serverSocket, InetAddress host, int port) { this.keyStore = keyStore; this.keyStorePassword = keyStorePassword; - this.publicAlias = publicAlias; - this.privateAlias = privateAlias; this.sslContext = sslContext; this.serverSocket = serverSocket; this.host = host; @@ -110,28 +98,14 @@ public final class TestSSLContext { * listening provided host and port. */ public static TestSSLContext create() { - try { - char[] keyStorePassword = null; - String publicAlias = "public"; - String privateAlias = "private"; - return create(createKeyStore(keyStorePassword, publicAlias, privateAlias), - keyStorePassword, - publicAlias, - privateAlias); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } + TestKeyStore testKeyStore = TestKeyStore.get(); + return create(testKeyStore.keyStore, testKeyStore.keyStorePassword); } /** * TestSSLContext creation method that allows separate creation of key store */ - public static TestSSLContext create(KeyStore keyStore, - char[] keyStorePassword, - String publicAlias, - String privateAlias) { + public static TestSSLContext create(KeyStore keyStore, char[] keyStorePassword) { try { SSLContext sslContext = createSSLContext(keyStore, keyStorePassword); @@ -141,7 +115,7 @@ public final class TestSSLContext { InetAddress host = sa.getAddress(); int port = sa.getPort(); - return new TestSSLContext(keyStore, keyStorePassword, publicAlias, privateAlias, + return new TestSSLContext(keyStore, keyStorePassword, sslContext, serverSocket, host, port); } catch (RuntimeException e) { throw e; @@ -157,15 +131,17 @@ public final class TestSSLContext { */ public static TestSSLContext createClient(TestSSLContext server) { try { - String publicAlias = server.publicAlias; - Certificate cert = server.keyStore.getCertificate(publicAlias); - KeyStore keyStore = KeyStore.getInstance("BKS"); keyStore.load(null, null); - keyStore.setCertificateEntry(publicAlias, cert); + for (String alias: Collections.list(server.keyStore.aliases())) { + if (!server.keyStore.isCertificateEntry(alias)) { + continue; + } + Certificate cert = server.keyStore.getCertificate(alias); + keyStore.setCertificateEntry(alias, cert); + } char[] keyStorePassword = server.keyStorePassword; - String privateAlias = null; String tmfa = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa); @@ -174,7 +150,7 @@ public final class TestSSLContext { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); - return new TestSSLContext(keyStore, keyStorePassword, publicAlias, publicAlias, + return new TestSSLContext(keyStore, keyStorePassword, sslContext, null, null, -1); } catch (RuntimeException e) { throw e; @@ -184,95 +160,6 @@ public final class TestSSLContext { } /** - * 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(char[] keyStorePassword, - String publicAlias, - String privateAlias) - throws Exception { - - RSAPrivateKey privateKey; - X509Certificate x509c; - if (publicAlias == null && privateAlias == null) { - // don't want anything apparently - privateKey = null; - x509c = null; - } else { - // 1.) we make the keys - int keysize = 1024; - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(keysize, new SecureRandom()); - KeyPair kp = kpg.generateKeyPair(); - privateKey = (RSAPrivateKey)kp.getPrivate(); - 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. - - Hashtable attributes = new Hashtable(); - attributes.put(X509Principal.CN, InetAddress.getLocalHost().getCanonicalHostName()); - X509Principal dn = new X509Principal(attributes); - - long millisPerDay = 24 * 60 * 60 * 1000; - long now = System.currentTimeMillis(); - Date start = new Date(now - millisPerDay); - Date end = new Date(now + millisPerDay); - BigInteger serial = BigInteger.valueOf(1); - - 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); - x509c = x509cg.generateX509Certificate(privateKey); - } - - X509Certificate[] x509cc; - if (privateAlias == null) { - // don't need certificate chain - x509cc = null; - } else { - x509cc = new X509Certificate[] { x509c }; - } - - // 3.) put certificate and private key to make a key store - KeyStore ks = KeyStore.getInstance("BKS"); - ks.load(null, null); - if (privateAlias != null) { - ks.setKeyEntry(privateAlias, privateKey, keyStorePassword, x509cc); - } - if (publicAlias != null) { - 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. @@ -291,4 +178,41 @@ public final class TestSSLContext { context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); return context; } + + public static void assertCertificateInKeyStore(Principal principal, + KeyStore keyStore) throws Exception { + String subjectName = principal.getName(); + boolean found = false; + for (String alias: Collections.list(keyStore.aliases())) { + if (!keyStore.isCertificateEntry(alias)) { + continue; + } + X509Certificate keyStoreCertificate = (X509Certificate) keyStore.getCertificate(alias); + if (subjectName.equals(keyStoreCertificate.getSubjectDN().getName())) { + found = true; + break; + } + } + if (!found) { + throw new AssertionFailedError("Could not find princial " + principal + " in key store"); + } + } + + public static void assertCertificateInKeyStore(Certificate certificate, + KeyStore keyStore) throws Exception { + boolean found = false; + for (String alias: Collections.list(keyStore.aliases())) { + if (!keyStore.isCertificateEntry(alias)) { + continue; + } + Certificate keyStoreCertificate = keyStore.getCertificate(alias); + if (certificate.equals(keyStoreCertificate)) { + found = true; + break; + } + } + if (!found) { + throw new AssertionFailedError("Could not find certificate " + certificate + " in key store"); + } + } } diff --git a/support/src/test/java/javax/net/ssl/TestSSLSocketPair.java b/support/src/test/java/javax/net/ssl/TestSSLSocketPair.java index 4409183..cda664c 100644 --- a/support/src/test/java/javax/net/ssl/TestSSLSocketPair.java +++ b/support/src/test/java/javax/net/ssl/TestSSLSocketPair.java @@ -39,17 +39,20 @@ public final class TestSSLSocketPair { */ public static TestSSLSocketPair create () { TestSSLContext c = TestSSLContext.create(); - SSLSocket[] sockets = connect(c, null); + SSLSocket[] sockets = connect(c, null, null); return new TestSSLSocketPair(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 + * existing SSLContext. Optionally specify clientCipherSuites to + * allow forcing new SSLSession to test SSLSessionContext + * caching. Optionally specify serverCipherSuites for testing + * cipher suite negotiation. */ public static SSLSocket[] connect (final TestSSLContext c, - String[] clientCipherSuites) { + final String[] clientCipherSuites, + final String[] serverCipherSuites) { try { SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port); @@ -57,6 +60,9 @@ public final class TestSSLSocketPair { Thread thread = new Thread(new Runnable () { public void run() { try { + if (serverCipherSuites != null) { + server.setEnabledCipherSuites(serverCipherSuites); + } server.startHandshake(); } catch (RuntimeException e) { throw e; |