diff options
Diffstat (limited to 'luni/src')
11 files changed, 547 insertions, 362 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java index 6b55e55..a6c2e4c 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java @@ -76,171 +76,171 @@ public class CipherSuite { /** * key exchange values */ - static final int KeyExchange_RSA = 1; - static final int KeyExchange_RSA_EXPORT = 2; - static final int KeyExchange_DHE_DSS = 3; - static final int KeyExchange_DHE_DSS_EXPORT = 4; - static final int KeyExchange_DHE_RSA = 5; - static final int KeyExchange_DHE_RSA_EXPORT = 6; - static final int KeyExchange_DH_DSS = 7; - static final int KeyExchange_DH_RSA = 8; - static final int KeyExchange_DH_anon = 9; - static final int KeyExchange_DH_anon_EXPORT = 10; - static final int KeyExchange_DH_DSS_EXPORT = 11; - static final int KeyExchange_DH_RSA_EXPORT = 12; + static final int KEY_EXCHANGE_RSA = 1; + static final int KEY_EXCHANGE_RSA_EXPORT = 2; + static final int KEY_EXCHANGE_DHE_DSS = 3; + static final int KEY_EXCHANGE_DHE_DSS_EXPORT = 4; + static final int KEY_EXCHANGE_DHE_RSA = 5; + static final int KEY_EXCHANGE_DHE_RSA_EXPORT = 6; + static final int KEY_EXCHANGE_DH_DSS = 7; + static final int KEY_EXCHANGE_DH_RSA = 8; + static final int KEY_EXCHANGE_DH_anon = 9; + static final int KEY_EXCHANGE_DH_anon_EXPORT = 10; + static final int KEY_EXCHANGE_DH_DSS_EXPORT = 11; + static final int KEY_EXCHANGE_DH_RSA_EXPORT = 12; /** * TLS cipher suite codes */ - static final byte[] code_TLS_NULL_WITH_NULL_NULL = { 0x00, 0x00 }; - static final byte[] code_TLS_RSA_WITH_NULL_MD5 = { 0x00, 0x01 }; - static final byte[] code_TLS_RSA_WITH_NULL_SHA = { 0x00, 0x02 }; - static final byte[] code_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 }; - static final byte[] code_TLS_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 }; - static final byte[] code_TLS_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 }; - static final byte[] code_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 }; - static final byte[] code_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 }; - static final byte[] code_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 }; - static final byte[] code_TLS_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 }; - static final byte[] code_TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A }; - static final byte[] code_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B }; - static final byte[] code_TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C }; - static final byte[] code_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D }; - static final byte[] code_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E }; - static final byte[] code_TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F }; - static final byte[] code_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 }; - static final byte[] code_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 }; - static final byte[] code_TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 }; - static final byte[] code_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 }; - static final byte[] code_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 }; - static final byte[] code_TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 }; - static final byte[] code_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 }; - static final byte[] code_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 }; - static final byte[] code_TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 }; - static final byte[] code_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 }; - static final byte[] code_TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A }; - static final byte[] code_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B }; + static final byte[] CODE_TLS_NULL_WITH_NULL_NULL = { 0x00, 0x00 }; + static final byte[] CODE_TLS_RSA_WITH_NULL_MD5 = { 0x00, 0x01 }; + static final byte[] CODE_TLS_RSA_WITH_NULL_SHA = { 0x00, 0x02 }; + static final byte[] CODE_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 }; + static final byte[] CODE_TLS_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 }; + static final byte[] CODE_TLS_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 }; + static final byte[] CODE_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 }; + static final byte[] CODE_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 }; + static final byte[] CODE_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 }; + static final byte[] CODE_TLS_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 }; + static final byte[] CODE_TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A }; + static final byte[] CODE_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B }; + static final byte[] CODE_TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C }; + static final byte[] CODE_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D }; + static final byte[] CODE_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E }; + static final byte[] CODE_TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F }; + static final byte[] CODE_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 }; + static final byte[] CODE_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 }; + static final byte[] CODE_TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 }; + static final byte[] CODE_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 }; + static final byte[] CODE_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 }; + static final byte[] CODE_TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 }; + static final byte[] CODE_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 }; + static final byte[] CODE_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 }; + static final byte[] CODE_TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 }; + static final byte[] CODE_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 }; + static final byte[] CODE_TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A }; + static final byte[] CODE_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B }; static final CipherSuite TLS_NULL_WITH_NULL_NULL = new CipherSuite( "SSL_NULL_WITH_NULL_NULL", true, 0, null, null, - code_TLS_NULL_WITH_NULL_NULL); + CODE_TLS_NULL_WITH_NULL_NULL); static final CipherSuite TLS_RSA_WITH_NULL_MD5 = new CipherSuite( - "SSL_RSA_WITH_NULL_MD5", true, KeyExchange_RSA, null, "MD5", - code_TLS_RSA_WITH_NULL_MD5); + "SSL_RSA_WITH_NULL_MD5", true, KEY_EXCHANGE_RSA, null, "MD5", + CODE_TLS_RSA_WITH_NULL_MD5); static final CipherSuite TLS_RSA_WITH_NULL_SHA = new CipherSuite( - "SSL_RSA_WITH_NULL_SHA", true, KeyExchange_RSA, null, "SHA", - code_TLS_RSA_WITH_NULL_SHA); + "SSL_RSA_WITH_NULL_SHA", true, KEY_EXCHANGE_RSA, null, "SHA", + CODE_TLS_RSA_WITH_NULL_SHA); static final CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite( - "SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KeyExchange_RSA_EXPORT, - "RC4_40", "MD5", code_TLS_RSA_EXPORT_WITH_RC4_40_MD5); + "SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT, + "RC4_40", "MD5", CODE_TLS_RSA_EXPORT_WITH_RC4_40_MD5); static final CipherSuite TLS_RSA_WITH_RC4_128_MD5 = new CipherSuite( - "SSL_RSA_WITH_RC4_128_MD5", false, KeyExchange_RSA, "RC4_128", - "MD5", code_TLS_RSA_WITH_RC4_128_MD5); + "SSL_RSA_WITH_RC4_128_MD5", false, KEY_EXCHANGE_RSA, "RC4_128", + "MD5", CODE_TLS_RSA_WITH_RC4_128_MD5); static final CipherSuite TLS_RSA_WITH_RC4_128_SHA = new CipherSuite( - "SSL_RSA_WITH_RC4_128_SHA", false, KeyExchange_RSA, "RC4_128", - "SHA", code_TLS_RSA_WITH_RC4_128_SHA); + "SSL_RSA_WITH_RC4_128_SHA", false, KEY_EXCHANGE_RSA, "RC4_128", + "SHA", CODE_TLS_RSA_WITH_RC4_128_SHA); static final CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite( - "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KeyExchange_RSA_EXPORT, - "RC2_CBC_40", "MD5", code_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5); + "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT, + "RC2_CBC_40", "MD5", CODE_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5); static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite( - "TLS_RSA_WITH_IDEA_CBC_SHA", false, KeyExchange_RSA, "IDEA_CBC", - "SHA", code_TLS_RSA_WITH_IDEA_CBC_SHA); + "TLS_RSA_WITH_IDEA_CBC_SHA", false, KEY_EXCHANGE_RSA, "IDEA_CBC", + "SHA", CODE_TLS_RSA_WITH_IDEA_CBC_SHA); static final CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( - "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KeyExchange_RSA_EXPORT, - "DES40_CBC", "SHA", code_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA); + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KEY_EXCHANGE_RSA_EXPORT, + "DES40_CBC", "SHA", CODE_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_RSA_WITH_DES_CBC_SHA = new CipherSuite( - "SSL_RSA_WITH_DES_CBC_SHA", false, KeyExchange_RSA, "DES_CBC", - "SHA", code_TLS_RSA_WITH_DES_CBC_SHA); + "SSL_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_RSA, "DES_CBC", + "SHA", CODE_TLS_RSA_WITH_DES_CBC_SHA); static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_RSA, - "3DES_EDE_CBC", "SHA", code_TLS_RSA_WITH_3DES_EDE_CBC_SHA); + "SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_RSA, + "3DES_EDE_CBC", "SHA", CODE_TLS_RSA_WITH_3DES_EDE_CBC_SHA); static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true, - KeyExchange_DH_DSS_EXPORT, "DES40_CBC", "SHA", - code_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA); + KEY_EXCHANGE_DH_DSS_EXPORT, "DES40_CBC", "SHA", + CODE_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite( - "TLS_DH_DSS_WITH_DES_CBC_SHA", false, KeyExchange_DH_DSS, - "DES_CBC", "SHA", code_TLS_DH_DSS_WITH_DES_CBC_SHA); + "TLS_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS, + "DES_CBC", "SHA", CODE_TLS_DH_DSS_WITH_DES_CBC_SHA); static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_DSS, - "3DES_EDE_CBC", "SHA", code_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA); + "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS, + "3DES_EDE_CBC", "SHA", CODE_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA); static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true, - KeyExchange_DH_RSA_EXPORT, "DES40_CBC", "SHA", - code_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA); + KEY_EXCHANGE_DH_RSA_EXPORT, "DES40_CBC", "SHA", + CODE_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite( - "TLS_DH_RSA_WITH_DES_CBC_SHA", false, KeyExchange_DH_RSA, - "DES_CBC", "SHA", code_TLS_DH_RSA_WITH_DES_CBC_SHA); + "TLS_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA, + "DES_CBC", "SHA", CODE_TLS_DH_RSA_WITH_DES_CBC_SHA); static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_RSA, - "3DES_EDE_CBC", "SHA", code_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA); + "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA, + "3DES_EDE_CBC", "SHA", CODE_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA); static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true, - KeyExchange_DHE_DSS_EXPORT, "DES40_CBC", "SHA", - code_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA); + KEY_EXCHANGE_DHE_DSS_EXPORT, "DES40_CBC", "SHA", + CODE_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite( - "SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KeyExchange_DHE_DSS, - "DES_CBC", "SHA", code_TLS_DHE_DSS_WITH_DES_CBC_SHA); + "SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS, + "DES_CBC", "SHA", CODE_TLS_DHE_DSS_WITH_DES_CBC_SHA); static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DHE_DSS, - "3DES_EDE_CBC", "SHA", code_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA); + "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS, + "3DES_EDE_CBC", "SHA", CODE_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA); static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true, - KeyExchange_DHE_RSA_EXPORT, "DES40_CBC", "SHA", - code_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA); + KEY_EXCHANGE_DHE_RSA_EXPORT, "DES40_CBC", "SHA", + CODE_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite( - "SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KeyExchange_DHE_RSA, - "DES_CBC", "SHA", code_TLS_DHE_RSA_WITH_DES_CBC_SHA); + "SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA, + "DES_CBC", "SHA", CODE_TLS_DHE_RSA_WITH_DES_CBC_SHA); static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DHE_RSA, - "3DES_EDE_CBC", "SHA", code_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA); + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA, + "3DES_EDE_CBC", "SHA", CODE_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA); static final CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite( "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", true, - KeyExchange_DH_anon_EXPORT, "RC4_40", "MD5", - code_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5); + KEY_EXCHANGE_DH_anon_EXPORT, "RC4_40", "MD5", + CODE_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5); static final CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = new CipherSuite( - "SSL_DH_anon_WITH_RC4_128_MD5", false, KeyExchange_DH_anon, - "RC4_128", "MD5", code_TLS_DH_anon_WITH_RC4_128_MD5); + "SSL_DH_anon_WITH_RC4_128_MD5", false, KEY_EXCHANGE_DH_anon, + "RC4_128", "MD5", CODE_TLS_DH_anon_WITH_RC4_128_MD5); static final CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite( "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true, - KeyExchange_DH_anon_EXPORT, "DES40_CBC", "SHA", - code_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA); + KEY_EXCHANGE_DH_anon_EXPORT, "DES40_CBC", "SHA", + CODE_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA); static final CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = new CipherSuite( - "SSL_DH_anon_WITH_DES_CBC_SHA", false, KeyExchange_DH_anon, - "DES_CBC", "SHA", code_TLS_DH_anon_WITH_DES_CBC_SHA); + "SSL_DH_anon_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_anon, + "DES_CBC", "SHA", CODE_TLS_DH_anon_WITH_DES_CBC_SHA); static final CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite( - "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_anon, - "3DES_EDE_CBC", "SHA", code_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA); + "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_anon, + "3DES_EDE_CBC", "SHA", CODE_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA); // array for quick access to cipher suite by code - private static final CipherSuite[] suitesByCode = { + private static final CipherSuite[] SUITES_BY_CODE = { TLS_NULL_WITH_NULL_NULL, TLS_RSA_WITH_NULL_MD5, TLS_RSA_WITH_NULL_SHA, @@ -272,7 +272,7 @@ public class CipherSuite { }; // hash for quick access to cipher suite by name - private static final Hashtable<String, CipherSuite> suitesByName; + private static final Hashtable<String, CipherSuite> SUITES_BY_NAME; /** * array of supported cipher suites. @@ -280,64 +280,66 @@ public class CipherSuite { */ // TODO Dynamically supported suites: new providers may be dynamically // added/removed and the set of supported suites may be changed - static final CipherSuite[] supportedCipherSuites; + static final CipherSuite[] SUPPORTED_CIPHER_SUITES; /** * array of supported cipher suites names */ - static final String[] supportedCipherSuiteNames; + static final String[] SUPPORTED_CIPHER_SUITE_NAMES; /** * default cipher suites */ - static final CipherSuite[] defaultCipherSuites; + static final CipherSuite[] DEFAULT_CIPHER_SUITES; static { int count = 0; - suitesByName = new Hashtable<String, CipherSuite>(); - for (int i = 0; i < suitesByCode.length; i++) { - suitesByName.put(suitesByCode[i].getName(), suitesByCode[i]); - if (suitesByCode[i].supported) { + SUITES_BY_NAME = new Hashtable<String, CipherSuite>(); + for (int i = 0; i < SUITES_BY_CODE.length; i++) { + SUITES_BY_NAME.put(SUITES_BY_CODE[i].getName(), SUITES_BY_CODE[i]); + if (SUITES_BY_CODE[i].supported) { count++; } } - supportedCipherSuites = new CipherSuite[count]; - supportedCipherSuiteNames = new String[count]; + SUPPORTED_CIPHER_SUITES = new CipherSuite[count]; + SUPPORTED_CIPHER_SUITE_NAMES = new String[count]; count = 0; - for (int i = 0; i < suitesByCode.length; i++) { - if (suitesByCode[i].supported) { - supportedCipherSuites[count] = suitesByCode[i]; - supportedCipherSuiteNames[count] = supportedCipherSuites[count].getName(); + for (int i = 0; i < SUITES_BY_CODE.length; i++) { + if (SUITES_BY_CODE[i].supported) { + SUPPORTED_CIPHER_SUITES[count] = SUITES_BY_CODE[i]; + SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName(); count++; } } - CipherSuite[] defaultPretendent = { + CipherSuite[] defaultCipherSuites = { TLS_RSA_WITH_RC4_128_MD5, TLS_RSA_WITH_RC4_128_SHA, // TLS_RSA_WITH_AES_128_CBC_SHA, // TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - // LS_DHE_DSS_WITH_AES_128_CBC_SHA, + // TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_DES_CBC_SHA, - TLS_DHE_RSA_WITH_DES_CBC_SHA, TLS_DHE_DSS_WITH_DES_CBC_SHA, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_RSA_WITH_DES_CBC_SHA, + TLS_DHE_RSA_WITH_DES_CBC_SHA, + TLS_DHE_DSS_WITH_DES_CBC_SHA, TLS_RSA_EXPORT_WITH_RC4_40_MD5, TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA }; count = 0; - for (int i = 0; i < defaultPretendent.length; i++) { - if (defaultPretendent[i].supported) { + for (int i = 0; i < defaultCipherSuites.length; i++) { + if (defaultCipherSuites[i].supported) { count++; } } - defaultCipherSuites = new CipherSuite[count]; + DEFAULT_CIPHER_SUITES = new CipherSuite[count]; count = 0; - for (int i = 0; i < defaultPretendent.length; i++) { - if (defaultPretendent[i].supported) { - defaultCipherSuites[count++] = defaultPretendent[i]; + for (int i = 0; i < defaultCipherSuites.length; i++) { + if (defaultCipherSuites[i].supported) { + DEFAULT_CIPHER_SUITES[count++] = defaultCipherSuites[i]; } } } @@ -348,7 +350,7 @@ public class CipherSuite { * @return */ public static CipherSuite getByName(String name) { - return suitesByName.get(name); + return SUITES_BY_NAME.get(name); } /** @@ -359,12 +361,12 @@ public class CipherSuite { * @return */ public static CipherSuite getByCode(byte b1, byte b2) { - if (b1 != 0 || (b2 & 0xFF) > suitesByCode.length) { + if (b1 != 0 || (b2 & 0xFF) > SUITES_BY_CODE.length) { // Unknown return new CipherSuite("UNKNOWN_" + b1 + "_" + b2, false, 0, "", "", new byte[] { b1, b2 }); } - return suitesByCode[b2]; + return SUITES_BY_CODE[b2]; } /** @@ -378,8 +380,8 @@ public class CipherSuite { */ public static CipherSuite getByCode(byte b1, byte b2, byte b3) { if (b1 == 0 && b2 == 0) { - if ((b3 & 0xFF) <= suitesByCode.length) { - return suitesByCode[b3]; + if ((b3 & 0xFF) <= SUITES_BY_CODE.length) { + return SUITES_BY_CODE[b3]; } } // as TLSv1 equivalent of V2CipherSpec should be included in @@ -498,8 +500,8 @@ public class CipherSuite { * @return */ public boolean isAnonymous() { - if (keyExchange == KeyExchange_DH_anon - || keyExchange == KeyExchange_DH_anon_EXPORT) { + if (keyExchange == KEY_EXCHANGE_DH_anon + || keyExchange == KEY_EXCHANGE_DH_anon_EXPORT) { return true; } return false; @@ -510,7 +512,7 @@ public class CipherSuite { * @return */ public static CipherSuite[] getSupported() { - return supportedCipherSuites; + return SUPPORTED_CIPHER_SUITES; } /** @@ -518,7 +520,7 @@ public class CipherSuite { * @return */ public static String[] getSupportedCipherSuiteNames() { - return supportedCipherSuiteNames.clone(); + return SUPPORTED_CIPHER_SUITE_NAMES.clone(); } /** diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java index cec1208..1460cca 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java @@ -375,15 +375,15 @@ public class ClientHandshakeImpl extends HandshakeProtocol { PrivateKey clientKey = null; if (serverCert != null) { - if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) { + if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) { unexpectedMessage(); return; } verifyServerCert(); } else { - if (session.cipherSuite.keyExchange != CipherSuite.KeyExchange_DH_anon - && session.cipherSuite.keyExchange != CipherSuite.KeyExchange_DH_anon_EXPORT) { + if (session.cipherSuite.keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon + && session.cipherSuite.keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) { unexpectedMessage(); return; } @@ -407,8 +407,8 @@ public class ClientHandshakeImpl extends HandshakeProtocol { send(clientCert); } // Client key exchange - if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { // RSA encrypted premaster secret message Cipher c; try { @@ -477,8 +477,8 @@ public class ClientHandshakeImpl extends HandshakeProtocol { Key key = kp.getPublic(); if (clientCert != null && serverCert != null - && (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS)) { + && (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS)) { PublicKey client_pk = clientCert.certs[0].getPublicKey(); PublicKey server_pk = serverCert.certs[0].getPublicKey(); if (client_pk instanceof DHKey @@ -521,18 +521,18 @@ public class ClientHandshakeImpl extends HandshakeProtocol { session.cipherSuite.keyExchange); ds.init(clientKey); - if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) { + if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT) { ds.setMD5(io_stream.getDigestMD5()); ds.setSHA(io_stream.getDigestSHA()); - } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) { + } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT) { ds.setSHA(io_stream.getDigestSHA()); // The Signature should be empty in case of anonimous signature algorithm: - // } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon || - // session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) { + // } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon || + // session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) { } certificateVerify = new CertificateVerify(ds.sign()); send(certificateVerify); diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java index 3c77846..12f1923 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java @@ -72,16 +72,16 @@ public class DigitalSignature { try { sha = MessageDigest.getInstance("SHA-1"); - if (keyExchange == CipherSuite.KeyExchange_RSA_EXPORT || - keyExchange == CipherSuite.KeyExchange_RSA || - keyExchange == CipherSuite.KeyExchange_DHE_RSA || - keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) { + if (keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT || + keyExchange == CipherSuite.KEY_EXCHANGE_RSA || + keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA || + keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT) { // SignatureAlgorithm is rsa md5 = MessageDigest.getInstance("MD5"); cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); signature = null; - } else if (keyExchange == CipherSuite.KeyExchange_DHE_DSS || - keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT ) { + } else if (keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS || + keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT ) { // SignatureAlgorithm is dsa signature = Signature.getInstance("NONEwithDSA"); cipher = null; 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 501a4a4..75ca8ea 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 @@ -128,7 +128,7 @@ public class NativeCrypto { static { // Note these are added in priority order - // Android doesn't currently support Elliptic Curve or Diffie-Hellman + // Android doesn't currently support Elliptic Curve 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"); @@ -145,41 +145,41 @@ public class NativeCrypto { // 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_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("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("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("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 @@ -230,22 +230,21 @@ 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/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java index 08e5bd2..8bb2ee9 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java @@ -161,59 +161,89 @@ public class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket { @Override public Socket accept() throws IOException { + + if (!sslParameters.getUseClientMode()) { + checkEnabledCipherSuites(); + } + + OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters, + enabledProtocols.clone(), + enabledCipherSuites.clone()); + implAccept(socket); + return socket; + } + + /** + * Check if any of the enabled cipher suites has a chance to work. + * Not 100% accurate, just a useful diagnostic that the RI does. + */ + private void checkEnabledCipherSuites() throws SSLException { + /* Loop over all enabled cipher suites. If we find a problem, + * we just continue to the next one. If we find one that could + * work, we return. This basically makes sure the caller has + * configured some appropriate certificate/key unless + * an anonymous cipher is picked. + */ for (String enabledCipherSuite : enabledCipherSuites) { CipherSuite cipherSuite = CipherSuite.getByName(enabledCipherSuite); + + int keyExchange; if (cipherSuite == null) { - continue; + // An NativeCrypto cipher suite unknown to the Java + // implementation, use some safe heuristics + if (enabledCipherSuite.contains("_RSA_")) { + keyExchange = CipherSuite.KEY_EXCHANGE_RSA; + } else if (enabledCipherSuite.contains("_DSS_")) { + keyExchange = CipherSuite.KEY_EXCHANGE_DH_DSS; + } else if (enabledCipherSuite.contains("_anon_")) { + keyExchange = CipherSuite.KEY_EXCHANGE_DH_anon; + } else { + keyExchange = -1; + } + } else { + keyExchange = cipherSuite.keyExchange; } - switch (cipherSuite.keyExchange) { - case CipherSuite.KeyExchange_DHE_RSA: - case CipherSuite.KeyExchange_DHE_RSA_EXPORT: - case CipherSuite.KeyExchange_DH_RSA: - case CipherSuite.KeyExchange_DH_RSA_EXPORT: - case CipherSuite.KeyExchange_RSA: - case CipherSuite.KeyExchange_RSA_EXPORT: - String rsaAlias = sslParameters.getKeyManager().chooseServerAlias("RSA", - null, - null); - if (rsaAlias == null) { - break; - } - PrivateKey rsa = sslParameters.getKeyManager().getPrivateKey(rsaAlias); - if ((rsa == null) || !(rsa instanceof RSAPrivateKey)) { - break; + + switch (keyExchange) { + case CipherSuite.KEY_EXCHANGE_DHE_RSA: + case CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT: + case CipherSuite.KEY_EXCHANGE_DH_RSA: + case CipherSuite.KEY_EXCHANGE_DH_RSA_EXPORT: + case CipherSuite.KEY_EXCHANGE_RSA: + case CipherSuite.KEY_EXCHANGE_RSA_EXPORT: + if (checkForPrivateKey("RSA", RSAPrivateKey.class)) { + return; } continue; - case CipherSuite.KeyExchange_DHE_DSS: - case CipherSuite.KeyExchange_DHE_DSS_EXPORT: - case CipherSuite.KeyExchange_DH_DSS: - case CipherSuite.KeyExchange_DH_DSS_EXPORT: - String dsaAlias = sslParameters.getKeyManager().chooseServerAlias("DSA", - null, - null); - if (dsaAlias == null) { - break; - } - PrivateKey dsa = sslParameters.getKeyManager().getPrivateKey(dsaAlias); - if ((dsa == null) || !(dsa instanceof DSAPrivateKey)) { - break; + case CipherSuite.KEY_EXCHANGE_DHE_DSS: + case CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT: + case CipherSuite.KEY_EXCHANGE_DH_DSS: + case CipherSuite.KEY_EXCHANGE_DH_DSS_EXPORT: + if (checkForPrivateKey("DSA", DSAPrivateKey.class)) { + return; } continue; - case CipherSuite.KeyExchange_DH_anon: - case CipherSuite.KeyExchange_DH_anon_EXPORT: + case CipherSuite.KEY_EXCHANGE_DH_anon: + case CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT: + // anonymous always works + return; default: - continue; + // unknown, just assume it will work + return; } - throw new SSLException("Could not find key store entry to support cipher suite " - + cipherSuite); } + throw new SSLException("Could not find any key store entries " + + "to support the enabled cipher suites."); + } - OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters, - enabledProtocols.clone(), - enabledCipherSuites.clone()); - implAccept(socket); - return socket; + private boolean checkForPrivateKey(String keyType, Class keyClass) { + String alias = sslParameters.getKeyManager().chooseServerAlias(keyType, null, null); + if (alias == null) { + return false; + } + PrivateKey key = sslParameters.getKeyManager().getPrivateKey(alias); + return (key != null && keyClass.isAssignableFrom(key.getClass())); } } diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java index 581ac1a..dd94ea9 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java @@ -95,7 +95,9 @@ public class SSLParameters implements Cloneable { // BEGIN android-changed protected CipherSuite[] getEnabledCipherSuitesMember() { - if (enabledCipherSuites == null) this.enabledCipherSuites = CipherSuite.defaultCipherSuites; + if (enabledCipherSuites == null) { + this.enabledCipherSuites = CipherSuite.DEFAULT_CIPHER_SUITES; + } return enabledCipherSuites; } // END android-changed diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java index a525fbb..08264e6 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java @@ -181,17 +181,17 @@ public class ServerHandshakeImpl extends HandshakeProtocol { byte[] md5_hash = null; byte[] sha_hash = null; - if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) { + if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT) { md5_hash = io_stream.getDigestMD5withoutLast(); sha_hash = io_stream.getDigestSHAwithoutLast(); - } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) { + } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT) { sha_hash = io_stream.getDigestSHAwithoutLast(); - } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) { + } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) { } ds.setMD5(md5_hash); ds.setSHA(sha_hash); @@ -209,8 +209,8 @@ public class ServerHandshakeImpl extends HandshakeProtocol { unexpectedMessage(); return; } - if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA - || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA + || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { clientKeyExchange = new ClientKeyExchange(io_stream, length, serverHello.server_version[1] == 1, true); @@ -451,17 +451,17 @@ public class ServerHandshakeImpl extends HandshakeProtocol { if (!cipher_suite.isAnonymous()) { // need to send server certificate X509Certificate[] certs = null; String certType = null; - if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA - || cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) { + if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT) { certType = "RSA"; - } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) { + } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT) { certType = "DSA"; - } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_DSS) { + } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_DSS) { certType = "DH_DSA"; - } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_RSA) { + } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_RSA) { certType = "DH_RSA"; } // obtain certificates from key manager @@ -514,19 +514,19 @@ public class ServerHandshakeImpl extends HandshakeProtocol { KeyPairGenerator kpg = null; try { - if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { PublicKey pk = serverCert.certs[0].getPublicKey(); if (getRSAKeyLength(pk) > 512) { // key is longer than 512 bits kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(512); } - } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon - || cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) { + } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon + || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) { try { kpg = KeyPairGenerator.getInstance("DH"); } catch (NoSuchAlgorithmException ee) { @@ -547,7 +547,7 @@ public class ServerHandshakeImpl extends HandshakeProtocol { KeyPair kp = null; try { kp = kpg.genKeyPair(); - if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { rsakey = (RSAPublicKey) kp.getPublic(); } else { DHPublicKey dhkey = (DHPublicKey) kp.getPublic(); @@ -574,7 +574,7 @@ public class ServerHandshakeImpl extends HandshakeProtocol { byte[] tmp; byte[] tmpLength = new byte[2]; //FIXME 1_byte==0x00 - if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { tmp = ServerKeyExchange.toUnsignedByteArray(rsakey.getModulus()); tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8); tmpLength[1] = (byte) (tmp.length & 0xFF); @@ -610,7 +610,7 @@ public class ServerHandshakeImpl extends HandshakeProtocol { fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e); } - if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) { + if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { serverKeyExchange = new ServerKeyExchange(rsakey.getModulus(), rsakey.getPublicExponent(), null, hash); } else { diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerKeyExchange.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerKeyExchange.java index b2b0351..d3626b9 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerKeyExchange.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerKeyExchange.java @@ -118,7 +118,7 @@ public class ServerKeyExchange extends Message { bytes2 = in.read(size); par2 = new BigInteger(1, bytes2); this.length += 2 + bytes2.length; - if (keyExchange != CipherSuite.KeyExchange_RSA_EXPORT) { + if (keyExchange != CipherSuite.KEY_EXCHANGE_RSA_EXPORT) { size = in.readUint16(); bytes3 = in.read(size); par3 = new BigInteger(1, bytes3); @@ -127,8 +127,8 @@ public class ServerKeyExchange extends Message { par3 = null; bytes3 = null; } - if (keyExchange != CipherSuite.KeyExchange_DH_anon_EXPORT - && keyExchange != CipherSuite.KeyExchange_DH_anon) { + if (keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT + && keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon) { size = in.readUint16(); hash = in.read(size); this.length += 2 + hash.length; 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 dd12dc1..787f899 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 @@ -53,6 +53,84 @@ #else #define JNI_TRACE(...) ((void)0) #endif + +struct BIO_Delete { + void operator()(BIO* p) const { + BIO_free(p); + } +}; +typedef UniquePtr<BIO, BIO_Delete> Unique_BIO; + +struct BIGNUM_Delete { + void operator()(BIGNUM* p) const { + BN_free(p); + } +}; +typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; + +struct DH_Delete { + void operator()(DH* p) const { + DH_free(p); + } +}; +typedef UniquePtr<DH, DH_Delete> Unique_DH; + +struct DSA_Delete { + void operator()(DSA* p) const { + DSA_free(p); + } +}; +typedef UniquePtr<DSA, DSA_Delete> Unique_DSA; + +struct EVP_PKEY_Delete { + void operator()(EVP_PKEY* p) const { + EVP_PKEY_free(p); + } +}; +typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; + +struct RSA_Delete { + void operator()(RSA* p) const { + RSA_free(p); + } +}; +typedef UniquePtr<RSA, RSA_Delete> Unique_RSA; + +struct SSL_Delete { + void operator()(SSL* p) const { + SSL_free(p); + } +}; +typedef UniquePtr<SSL, SSL_Delete> Unique_SSL; + +struct SSL_CTX_Delete { + void operator()(SSL_CTX* p) const { + SSL_CTX_free(p); + } +}; +typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX; + +struct X509_Delete { + void operator()(X509* p) const { + X509_free(p); + } +}; +typedef UniquePtr<X509, X509_Delete> Unique_X509; + +struct sk_SSL_CIPHER_Delete { + void operator()(STACK_OF(SSL_CIPHER)* p) const { + sk_SSL_CIPHER_free(p); + } +}; +typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER; + +struct sk_X509_Delete { + void operator()(STACK_OF(X509)* p) const { + sk_X509_free(p); + } +}; +typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509; + /** * Frees the SSL error state. * @@ -93,27 +171,21 @@ static int throwExceptionIfNecessary(JNIEnv* env, const char* /*location*/) { * Throws an SocketTimeoutException with the given string as a message. */ static void throwSocketTimeoutException(JNIEnv* env, const char* message) { - if (jniThrowException(env, "java/net/SocketTimeoutException", message)) { - LOGE("Unable to throw"); - } + jniThrowException(env, "java/net/SocketTimeoutException", message); } /** * Throws a javax.net.ssl.SSLException with the given string as a message. */ static void throwSSLExceptionStr(JNIEnv* env, const char* message) { - if (jniThrowException(env, "javax/net/ssl/SSLException", message)) { - LOGE("Unable to throw"); - } + jniThrowException(env, "javax/net/ssl/SSLException", message); } /** * Throws a javax.net.ssl.SSLProcotolException with the given string as a message. */ static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) { - if (jniThrowException(env, "javax/net/ssl/SSLProtocolException", message)) { - LOGE("Unable to throw"); - } + jniThrowException(env, "javax/net/ssl/SSLProtocolException", message); } /** @@ -121,6 +193,7 @@ static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) { * SSL errors. This will also log the errors. * * @param env the JNI environment + * @param ssl the possibly NULL SSL * @param sslErrorCode error code returned from SSL_get_error() or * SSL_ERROR_NONE to probe with ERR_get_error * @param message null-ok; general error message @@ -319,15 +392,13 @@ static unsigned long id_function(void) { } int THREAD_setup(void) { - int i; - mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE)); - if(!mutex_buf) { + if (!mutex_buf) { return 0; } - for (i = 0; i < CRYPTO_num_locks( ); i++) { + for (int i = 0; i < CRYPTO_num_locks( ); i++) { MUTEX_SETUP(mutex_buf[i]); } @@ -338,8 +409,6 @@ int THREAD_setup(void) { } int THREAD_cleanup(void) { - int i; - if (!mutex_buf) { return 0; } @@ -347,7 +416,7 @@ int THREAD_cleanup(void) { CRYPTO_set_id_callback(NULL); CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks( ); i++) { + for (int i = 0; i < CRYPTO_num_locks( ); i++) { MUTEX_CLEANUP(mutex_buf[i]); } @@ -379,8 +448,8 @@ static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass, jbyteArray pub_key, jbyteArray priv_key) { // LOGD("Entering EVP_PKEY_new_DSA()"); - DSA* dsa = DSA_new(); - if (dsa == NULL) { + Unique_DSA dsa(DSA_new()); + if (dsa.get() == NULL) { jniThrowRuntimeException(env, "DSA_new failed"); return NULL; } @@ -395,19 +464,21 @@ static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass, } if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) { - DSA_free(dsa); jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM"); return NULL; } - EVP_PKEY* pkey = EVP_PKEY_new(); - if (pkey == NULL) { + Unique_EVP_PKEY pkey(EVP_PKEY_new()); + if (pkey.get() == NULL) { jniThrowRuntimeException(env, "EVP_PKEY_new failed"); return NULL; } - EVP_PKEY_assign_DSA(pkey, dsa); - - return pkey; + if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) { + jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed"); + return NULL; + } + dsa.release(); + return pkey.release(); } /** @@ -418,8 +489,8 @@ static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass, jbyteArray p, jbyteArray q) { // LOGD("Entering EVP_PKEY_new_RSA()"); - RSA* rsa = RSA_new(); - if (rsa == NULL) { + Unique_RSA rsa(RSA_new()); + if (rsa.get() == NULL) { jniThrowRuntimeException(env, "RSA_new failed"); return NULL; } @@ -443,20 +514,21 @@ static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass, // LOGI("RSA_check_key returns %d", check); if (rsa->n == NULL || rsa->e == NULL) { - RSA_free(rsa); jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM"); return NULL; } - EVP_PKEY* pkey = EVP_PKEY_new(); - if (pkey == NULL) { - RSA_free(rsa); + Unique_EVP_PKEY pkey(EVP_PKEY_new()); + if (pkey.get() == NULL) { jniThrowRuntimeException(env, "EVP_PKEY_new failed"); return NULL; } - EVP_PKEY_assign_RSA(pkey, rsa); - - return pkey; + if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) { + jniThrowRuntimeException(env, "EVP_PKEY_new failed"); + return NULL; + } + rsa.release(); + return pkey.release(); } /** @@ -669,8 +741,8 @@ static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jb static RSA* rsaCreateKey(unsigned char* mod, int modLen, unsigned char* exp, int expLen) { // LOGD("Entering rsaCreateKey()"); - RSA* rsa = RSA_new(); - if (rsa == NULL) { + Unique_RSA rsa(RSA_new()); + if (rsa.get() == NULL) { return NULL; } @@ -678,11 +750,10 @@ static RSA* rsaCreateKey(unsigned char* mod, int modLen, unsigned char* exp, int rsa->e = BN_bin2bn(exp, expLen, NULL); if (rsa->n == NULL || rsa->e == NULL) { - RSA_free(rsa); return NULL; } - return rsa; + return rsa.release(); } /** @@ -703,29 +774,26 @@ static int rsaVerify(unsigned char* msg, unsigned int msgLen, unsigned char* sig // LOGD("Entering rsaVerify(%x, %d, %x, %d, %s, %x)", msg, msgLen, sig, sigLen, algorithm, rsa); - EVP_PKEY* pkey = EVP_PKEY_new(); - if (pkey == NULL) { + Unique_EVP_PKEY pkey(EVP_PKEY_new()); + if (pkey.get() == NULL) { return -1; } - EVP_PKEY_set1_RSA(pkey, rsa); + EVP_PKEY_set1_RSA(pkey.get(), rsa); const EVP_MD *type = EVP_get_digestbyname(algorithm); if (type == NULL) { - EVP_PKEY_free(pkey); return -1; } EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) { - EVP_PKEY_free(pkey); return -1; } EVP_VerifyUpdate(&ctx, msg, msgLen); - int result = EVP_VerifyFinal(&ctx, sig, sigLen, pkey); + int result = EVP_VerifyFinal(&ctx, sig, sigLen, pkey.get()); EVP_MD_CTX_cleanup(&ctx); - EVP_PKEY_free(pkey); return result; } @@ -754,13 +822,12 @@ static int NativeCrypto_verifysignature(JNIEnv* env, jclass, ScopedUtfChars algorithmChars(env, algorithm); JNI_TRACE("NativeCrypto_verifysignature algorithmChars=%s", algorithmChars.c_str()); - RSA* rsa = rsaCreateKey((unsigned char*) modBytes.get(), modBytes.size(), - (unsigned char*) expBytes.get(), expBytes.size()); - if (rsa != NULL) { + Unique_RSA rsa(rsaCreateKey((unsigned char*) modBytes.get(), modBytes.size(), + (unsigned char*) expBytes.get(), expBytes.size())); + if (rsa.get() != NULL) { result = rsaVerify((unsigned char*) msgBytes.get(), msgBytes.size(), (unsigned char*) sigBytes.get(), sigBytes.size(), - (char*) algorithmChars.c_str(), rsa); - RSA_free(rsa); + (char*) algorithmChars.c_str(), rsa.get()); } if (result == -1) { @@ -919,7 +986,7 @@ static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, * Returns an array containing all the X509 certificate's bytes. */ static jobjectArray getCertificateBytes(JNIEnv* env, - const STACK_OF(X509) *chain) + const STACK_OF(X509)* chain) { if (chain == NULL) { // Chain can be NULL if the associated cipher doesn't do certs. @@ -936,8 +1003,8 @@ static jobjectArray getCertificateBytes(JNIEnv* env, return NULL; } - BIO* bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { + Unique_BIO bio(BIO_new(BIO_s_mem())); + if (bio.get() == NULL) { jniThrowRuntimeException(env, "BIO_new failed"); return NULL; } @@ -946,11 +1013,11 @@ static jobjectArray getCertificateBytes(JNIEnv* env, for (int i = 0; i < count; i++) { X509* cert = sk_X509_value(chain, i); - BIO_reset(bio); - PEM_write_bio_X509(bio, cert); + BIO_reset(bio.get()); + PEM_write_bio_X509(bio.get(), cert); BUF_MEM* bptr; - BIO_get_mem_ptr(bio, &bptr); + BIO_get_mem_ptr(bio.get(), &bptr); jbyteArray bytes = env->NewByteArray(bptr->length); if (bytes == NULL) { @@ -967,7 +1034,6 @@ static jobjectArray getCertificateBytes(JNIEnv* env, } // LOGD("Certificate fetching complete"); - BIO_free(bio); return joa; } @@ -1031,6 +1097,11 @@ static jobjectArray getCertificateBytes(JNIEnv* env, * can read and write to the SSL such as SSL_do_handshake, SSL_read, * SSL_write, and SSL_shutdown if handshaking is not complete. * + * Finally, we have one other piece of state setup by OpenSSL callbacks: + * + * (7) a set of emphemeral RSA keys that is lazily generated if a peer + * wants to use an exportable RSA cipher suite. + * */ class AppData { public: @@ -1040,6 +1111,7 @@ class AppData { MUTEX_TYPE mutex; JNIEnv* env; jobject sslHandshakeCallbacks; + Unique_RSA ephemeralRsa; /** * Creates our application data and attaches it to a given SSL connection. @@ -1083,7 +1155,8 @@ class AppData { aliveAndKicking(1), waitingThreads(0), env(NULL), - sslHandshakeCallbacks(NULL) { + sslHandshakeCallbacks(NULL), + ephemeralRsa(NULL) { setEnv(env); fdsEmergency[0] = -1; fdsEmergency[1] = -1; @@ -1413,19 +1486,101 @@ static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) { return result; } +static RSA* rsaGenerateKey(int keylength) { + Unique_BIGNUM bn(BN_new()); + if (bn.get() == NULL) { + return NULL; + } + int setWordResult = BN_set_word(bn.get(), RSA_F4); + if (setWordResult != 1) { + return NULL; + } + Unique_RSA rsa(RSA_new()); + if (rsa.get() == NULL) { + return NULL; + } + int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL); + if (generateResult != 1) { + return NULL; + } + return rsa.release(); +} + +/** + * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5) + */ +static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)), + int is_export __attribute__ ((unused)), + int keylength) { + JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength); + + AppData* appData = (AppData*) SSL_get_app_data(ssl); + if (appData->ephemeralRsa.get() == NULL) { + JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl); + appData->ephemeralRsa.reset(rsaGenerateKey(keylength)); + } + JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get()); + return appData->ephemeralRsa.get(); +} + +static DH* dhGenerateParameters(int keylength) { + + /* + * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two + * different options for generating DH keys. One is generating the + * keys using a single set of DH parameters. However, generating + * DH parameters is slow enough (minutes) that they suggest doing + * it once at install time. The other is to generate DH keys from + * DSA parameters. Generating DSA parameters is faster than DH + * parameters, but to prevent small subgroup attacks, they needed + * to be regenerated for each set of DH keys. Setting the + * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back + * for new DH parameters every type it needs to generate DH keys. + */ +#if 0 + // Slow path that takes minutes but could be cached + Unique_DH dh(DH_new()); + if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) { + return NULL; + } + return dh.release(); +#else + // Faster path but must have SSL_OP_SINGLE_DH_USE set + Unique_DSA dsa(DSA_new()); + if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) { + return NULL; + } + DH* dh = DSA_dup_DH(dsa.get()); + return dh; +#endif +} + +/** + * Call back to ask for Diffie-Hellman parameters + */ +static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)), + int is_export __attribute__ ((unused)), + int keylength) { + JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength); + DH* tmp_dh = dhGenerateParameters(keylength); + JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh); + return tmp_dh; +} + /* * public static native int SSL_CTX_new(); */ static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) { - SSL_CTX* sslCtx = SSL_CTX_new(SSLv23_method()); - if (sslCtx == NULL) { + Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method())); + if (sslCtx.get() == NULL) { jniThrowRuntimeException(env, "SSL_CTX_new"); return NULL; } // Note: We explicitly do not allow SSLv2 to be used. - SSL_CTX_set_options(sslCtx, SSL_OP_ALL | SSL_OP_NO_SSLv2); + SSL_CTX_set_options(sslCtx.get(), + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); - int mode = SSL_CTX_get_mode(sslCtx); + int mode = SSL_CTX_get_mode(sslCtx.get()); /* * Turn on "partial write" mode. This means that SSL_write() will * behave like Posix write() and possibly return after only @@ -1444,17 +1599,19 @@ static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) { mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; /* enable sending of client data as soon as * ClientCCS and ClientFinished are sent */ #endif - SSL_CTX_set_mode(sslCtx, mode); + SSL_CTX_set_mode(sslCtx.get(), mode); - SSL_CTX_set_cert_verify_callback(sslCtx, cert_verify_callback, NULL); - SSL_CTX_set_info_callback(sslCtx, info_callback); - SSL_CTX_set_client_cert_cb(sslCtx, client_cert_cb); + SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL); + SSL_CTX_set_info_callback(sslCtx.get(), info_callback); + SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb); + SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback); + SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback); #ifdef WITH_JNI_TRACE - SSL_CTX_set_msg_callback(sslCtx, ssl_msg_callback_LOG); /* enable for message debug */ + SSL_CTX_set_msg_callback(sslCtx.get(), ssl_msg_callback_LOG); /* enable for message debug */ #endif - JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx); - return (jint) sslCtx; + JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get()); + return (jint) sslCtx.release(); } /** @@ -1482,9 +1639,9 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address) if (ssl_ctx == NULL) { return NULL; } - SSL* ssl = SSL_new(ssl_ctx); - if (ssl == NULL) { - throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, + Unique_SSL ssl(SSL_new(ssl_ctx)); + if (ssl.get() == NULL) { + throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE, "Unable to create SSL structure"); JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx); return NULL; @@ -1498,10 +1655,10 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address) * function. The handshake will be continued regardless of the * verification result. */ - SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); + SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL); - JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl); - return (jint)ssl; + JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get()); + return (jint)ssl.release(); } /** @@ -1509,13 +1666,13 @@ static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address) */ static BIO* jbyteArrayToMemBuf(JNIEnv* env, jbyteArray byteArray) { ScopedByteArray buf(env, byteArray); - BIO* bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { + Unique_BIO bio(BIO_new(BIO_s_mem())); + if (bio.get() == NULL) { jniThrowRuntimeException(env, "BIO_new failed"); return NULL; } - BIO_write(bio, buf.get(), buf.size()); - return bio; + BIO_write(bio.get(), buf.get(), buf.size()); + return bio.release(); } static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, @@ -1533,11 +1690,9 @@ static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, return; } - BIO* privatekeybio = jbyteArrayToMemBuf(env, privatekey); - EVP_PKEY* privatekeyevp = PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL); - BIO_free(privatekeybio); - - if (privatekeyevp == NULL) { + Unique_BIO privatekeybio(jbyteArrayToMemBuf(env, privatekey)); + Unique_EVP_PKEY privatekeyevp(PEM_read_bio_PrivateKey(privatekeybio.get(), NULL, 0, NULL)); + if (privatekeyevp.get() == NULL) { LOGE(ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing the private key"); SSL_clear(ssl); @@ -1545,11 +1700,12 @@ static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, return; } - int ret = SSL_use_PrivateKey(ssl, privatekeyevp); - if (ret != 1) { + int ret = SSL_use_PrivateKey(ssl, privatekeyevp.get()); + if (ret == 1) { + privatekeyevp.release(); + } else { LOGE(ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting the private key"); - EVP_PKEY_free(privatekeyevp); SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error", ssl); return; @@ -1573,11 +1729,10 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, return; } - BIO* certificatesbio = jbyteArrayToMemBuf(env, certificates); - X509* certificatesx509 = PEM_read_bio_X509(certificatesbio, NULL, 0, NULL); - BIO_free(certificatesbio); + Unique_BIO certificatesbio(jbyteArrayToMemBuf(env, certificates)); + Unique_X509 certificatesx509(PEM_read_bio_X509(certificatesbio.get(), NULL, 0, NULL)); - if (certificatesx509 == NULL) { + if (certificatesx509.get() == NULL) { LOGE(ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing the certificates"); SSL_clear(ssl); @@ -1585,11 +1740,12 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, return; } - int ret = SSL_use_certificate(ssl, certificatesx509); - if (ret != 1) { + int ret = SSL_use_certificate(ssl, certificatesx509.get()); + if (ret == 1) { + certificatesx509.release(); + } else { LOGE(ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting the certificates"); - X509_free(certificatesx509); SSL_clear(ssl); JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => error", ssl); return; @@ -1716,8 +1872,8 @@ static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass, return; } - STACK_OF(SSL_CIPHER)* cipherstack = sk_SSL_CIPHER_new_null(); - if (cipherstack == NULL) { + Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null()); + if (cipherstack.get() == NULL) { jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed"); return; } @@ -1737,23 +1893,24 @@ static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass, const SSL_CIPHER* cipher = ssl_method->get_cipher(j); if ((strcmp(c.c_str(), cipher->name) == 0) && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) { - sk_SSL_CIPHER_push(cipherstack, cipher); + sk_SSL_CIPHER_push(cipherstack.get(), cipher); found = true; } } if (!found) { - sk_SSL_CIPHER_free(cipherstack); jniThrowException(env, "java/lang/IllegalArgumentException", "Could not find cipher suite."); return; } } - int rc = SSL_set_cipher_lists(ssl, cipherstack); + int rc = SSL_set_cipher_lists(ssl, cipherstack.get()); if (rc == 0) { freeSslErrorState(); jniThrowException(env, "java/lang/IllegalArgumentException", "Illegal cipher suite strings."); + } else { + cipherstack.release(); } } @@ -2011,15 +2168,14 @@ static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint s // option would be to have the chain remembered where // SSL_use_certificate is used. Another would be to save the // intermediate CAs with SSL_CTX SSL_CTX_add_extra_chain_cert. - STACK_OF(X509)* chain = sk_X509_new_null(); - if (chain == NULL) { + Unique_sk_X509 chain(sk_X509_new_null()); + if (chain.get() == NULL) { jniThrowRuntimeException(env, "Unable to allocate local certificate chain"); JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl); return NULL; } - sk_X509_push(chain, certificate); - jobjectArray objectArray = getCertificateBytes(env, chain); - sk_X509_free(chain); + sk_X509_push(chain.get(), certificate); + jobjectArray objectArray = getCertificateBytes(env, chain.get()); JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray); return objectArray; } @@ -2533,13 +2689,12 @@ static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass, */ // TODO move to jsse.patch static STACK_OF(X509)* SSL_SESSION_get_peer_cert_chain(SSL_CTX* ssl_ctx, SSL_SESSION* ssl_session) { - SSL* ssl = SSL_new(ssl_ctx); - if (ssl == NULL) { + Unique_SSL ssl(SSL_new(ssl_ctx)); + if (ssl.get() == NULL) { return NULL; } - SSL_set_session(ssl, ssl_session); - STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl); - SSL_free(ssl); + SSL_set_session(ssl.get(), ssl_session); + STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl.get()); return chain; } diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java index d41892e..a83035c 100644 --- a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java +++ b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java @@ -16,7 +16,6 @@ package javax.net.ssl; -import dalvik.annotation.KnownFailure; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; @@ -48,7 +47,6 @@ 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(); @@ -62,8 +60,6 @@ public class SSLSocketTest extends TestCase { } // 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); } } diff --git a/luni/src/test/java/tests/AllTests.java b/luni/src/test/java/tests/AllTests.java index afc298f..abfdda3 100644 --- a/luni/src/test/java/tests/AllTests.java +++ b/luni/src/test/java/tests/AllTests.java @@ -50,6 +50,7 @@ public class AllTests suite.addTest(tests.regex.AllTests.suite()); suite.addTest(tests.security.AllTests.suite()); suite.addTest(tests.sql.AllTests.suite()); + suite.addTest(tests.SQLite.AllTests.suite()); suite.addTest(tests.suncompat.AllTests.suite()); suite.addTest(tests.text.AllTests.suite()); suite.addTest(tests.xml.AllTests.suite()); |