changeset 3865:ef5bbbe0dd75

7027797: take care of ECDH_anon/DH_anon server key exchange for TLS 1.2 Summary: the signature of server key exanage message could be null Reviewed-by: vinnie
author xuelei
date Mon, 21 Mar 2011 22:02:00 -0700
parents 1d0039aea814
children 870f7c3f0b61
files src/share/classes/sun/security/ssl/HandshakeMessage.java test/sun/security/ec/TestEC.java test/sun/security/pkcs11/fips/CipherTest.java test/sun/security/pkcs11/sslecc/CipherTest.java test/sun/security/ssl/sanity/interop/CipherTest.java test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java
diffstat 6 files changed, 401 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -694,47 +694,6 @@
     // the preferable signature algorithm used by this ServerKeyExchange message
     private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
 
-    /* Return the Diffie-Hellman modulus */
-    BigInteger getModulus() {
-        return new BigInteger(1, dh_p);
-    }
-
-    /* Return the Diffie-Hellman base/generator */
-    BigInteger getBase() {
-        return new BigInteger(1, dh_g);
-    }
-
-    /* Return the server's Diffie-Hellman public key */
-    BigInteger getServerPublicKey() {
-        return new BigInteger(1, dh_Ys);
-    }
-
-    /*
-     * Update sig with nonces and Diffie-Hellman public key.
-     */
-    private void updateSignature(Signature sig, byte clntNonce[],
-            byte svrNonce[]) throws SignatureException {
-        int tmp;
-
-        sig.update(clntNonce);
-        sig.update(svrNonce);
-
-        tmp = dh_p.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_p);
-
-        tmp = dh_g.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_g);
-
-        tmp = dh_Ys.length;
-        sig.update((byte)(tmp >> 8));
-        sig.update((byte)(tmp & 0x0ff));
-        sig.update(dh_Ys);
-    }
-
     /*
      * Construct from initialized DH key object, for DH_anon
      * key exchange.
@@ -779,12 +738,6 @@
         signature = sig.sign();
     }
 
-    private void setValues(DHCrypt obj) {
-        dh_p = toByteArray(obj.getModulus());
-        dh_g = toByteArray(obj.getBase());
-        dh_Ys = toByteArray(obj.getPublicKey());
-    }
-
     /*
      * Construct a DH_ServerKeyExchange message from an input
      * stream, as if sent from server to client for use with
@@ -875,6 +828,53 @@
         }
     }
 
+    /* Return the Diffie-Hellman modulus */
+    BigInteger getModulus() {
+        return new BigInteger(1, dh_p);
+    }
+
+    /* Return the Diffie-Hellman base/generator */
+    BigInteger getBase() {
+        return new BigInteger(1, dh_g);
+    }
+
+    /* Return the server's Diffie-Hellman public key */
+    BigInteger getServerPublicKey() {
+        return new BigInteger(1, dh_Ys);
+    }
+
+    /*
+     * Update sig with nonces and Diffie-Hellman public key.
+     */
+    private void updateSignature(Signature sig, byte clntNonce[],
+            byte svrNonce[]) throws SignatureException {
+        int tmp;
+
+        sig.update(clntNonce);
+        sig.update(svrNonce);
+
+        tmp = dh_p.length;
+        sig.update((byte)(tmp >> 8));
+        sig.update((byte)(tmp & 0x0ff));
+        sig.update(dh_p);
+
+        tmp = dh_g.length;
+        sig.update((byte)(tmp >> 8));
+        sig.update((byte)(tmp & 0x0ff));
+        sig.update(dh_g);
+
+        tmp = dh_Ys.length;
+        sig.update((byte)(tmp >> 8));
+        sig.update((byte)(tmp & 0x0ff));
+        sig.update(dh_Ys);
+    }
+
+    private void setValues(DHCrypt obj) {
+        dh_p = toByteArray(obj.getModulus());
+        dh_g = toByteArray(obj.getBase());
+        dh_Ys = toByteArray(obj.getPublicKey());
+    }
+
     int messageLength() {
         int temp = 6;   // overhead for p, g, y(s) values.
 
@@ -945,8 +945,7 @@
  * We support named curves only, no explicitly encoded curves.
  */
 static final
-class ECDH_ServerKeyExchange extends ServerKeyExchange
-{
+class ECDH_ServerKeyExchange extends ServerKeyExchange {
 
     // constants for ECCurveType
     private final static int CURVE_EXPLICIT_PRIME = 1;
@@ -1120,10 +1119,12 @@
     }
 
     int messageLength() {
-        int sigLen = (signatureBytes == null) ? 0 : 2 + signatureBytes.length;
-
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            sigLen += SignatureAndHashAlgorithm.sizeInRecord();
+        int sigLen = 0;
+        if (signatureBytes != null) {
+            sigLen = 2 + signatureBytes.length;
+            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+                sigLen += SignatureAndHashAlgorithm.sizeInRecord();
+            }
         }
 
         return 4 + pointBytes.length + sigLen;
@@ -1133,12 +1134,13 @@
         s.putInt8(CURVE_NAMED_CURVE);
         s.putInt16(curveId);
         s.putBytes8(pointBytes);
-        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-            s.putInt8(preferableSignatureAlgorithm.getHashValue());
-            s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
-        }
 
         if (signatureBytes != null) {
+            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+                s.putInt8(preferableSignatureAlgorithm.getHashValue());
+                s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
+            }
+
             s.putBytes16(signatureBytes);
         }
     }
@@ -1147,9 +1149,13 @@
         s.println("*** ECDH ServerKeyExchange");
 
         if (debug != null && Debug.isOn("verbose")) {
-            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
-                s.println("Signature Algorithm " +
-                        preferableSignatureAlgorithm.getAlgorithmName());
+            if (signatureBytes == null) {
+                s.println("Anonymous");
+            } else {
+                if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+                    s.println("Signature Algorithm " +
+                            preferableSignatureAlgorithm.getAlgorithmName());
+                }
             }
 
             s.println("Server key: " + publicKey);
--- a/test/sun/security/ec/TestEC.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/test/sun/security/ec/TestEC.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,6 @@
  * @test
  * @bug 6840752
  * @summary  Provide out-of-the-box support for ECC algorithms
- * @ignore JSSE supported cipher suites are changed with CR 6916074,
- *     need to update this test case in JDK 7 soon
  * @library ../pkcs11
  * @library ../pkcs11/ec
  * @library ../pkcs11/sslecc
--- a/test/sun/security/pkcs11/fips/CipherTest.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/test/sun/security/pkcs11/fips/CipherTest.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,19 +114,7 @@
         }
 
         boolean isEnabled() {
-            // ignore SCSV
-            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
-                return false;
-            }
-
-            // ignore exportable cipher suite for TLSv1.1
-            if (protocol.equals("TLSv1.1")) {
-                if(cipherSuite.indexOf("_EXPORT_") != -1) {
-                    return false;
-                }
-            }
-
-            return true;
+            return TLSCipherStatus.isEnabled(cipherSuite, protocol);
         }
 
         public String toString() {
@@ -137,6 +125,114 @@
             return s;
         }
 
+        static enum TLSCipherStatus {
+            // cipher suites supported since TLS 1.2
+            CS_01("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF),
+            CS_02("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",   0x0303, 0xFFFF),
+            CS_03("TLS_RSA_WITH_AES_256_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_04("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",  0x0303, 0xFFFF),
+            CS_05("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",    0x0303, 0xFFFF),
+            CS_06("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_07("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_08("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF),
+            CS_09("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",   0x0303, 0xFFFF),
+            CS_10("TLS_RSA_WITH_AES_128_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_11("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",  0x0303, 0xFFFF),
+            CS_12("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",    0x0303, 0xFFFF),
+            CS_13("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_14("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_15("TLS_DH_anon_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
+
+            // cipher suites obsoleted since TLS 1.2
+            CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
+            CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_52("SSL_DHE_DSS_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_53("SSL_DH_anon_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_54("TLS_KRB5_WITH_DES_CBC_SHA",               0x0000, 0x0303),
+            CS_55("TLS_KRB5_WITH_DES_CBC_MD5",               0x0000, 0x0303),
+
+            // cipher suites obsoleted since TLS 1.1
+            CS_60("SSL_RSA_EXPORT_WITH_RC4_40_MD5",          0x0000, 0x0302),
+            CS_61("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",      0x0000, 0x0302),
+            CS_62("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",       0x0000, 0x0302),
+            CS_63("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_64("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_65("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_66("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",         0x0000, 0x0302),
+            CS_67("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",         0x0000, 0x0302),
+            CS_68("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",     0x0000, 0x0302),
+            CS_69("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",     0x0000, 0x0302),
+
+            // ignore TLS_EMPTY_RENEGOTIATION_INFO_SCSV always
+            CS_99("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",       0xFFFF, 0x0000);
+
+            // the cipher suite name
+            final String cipherSuite;
+
+            // supported since protocol version
+            final int supportedSince;
+
+            // obsoleted since protocol version
+            final int obsoletedSince;
+
+            TLSCipherStatus(String cipherSuite,
+                    int supportedSince, int obsoletedSince) {
+                this.cipherSuite = cipherSuite;
+                this.supportedSince = supportedSince;
+                this.obsoletedSince = obsoletedSince;
+            }
+
+            static boolean isEnabled(String cipherSuite, String protocol) {
+                int versionNumber = toVersionNumber(protocol);
+
+                if (versionNumber < 0) {
+                    return true;  // unlikely to happen
+                }
+
+                for (TLSCipherStatus status : TLSCipherStatus.values()) {
+                    if (cipherSuite.equals(status.cipherSuite)) {
+                        if ((versionNumber < status.supportedSince) ||
+                            (versionNumber >= status.obsoletedSince)) {
+                            return false;
+                        }
+
+                        return true;
+                    }
+                }
+
+                return true;
+            }
+
+            private static int toVersionNumber(String protocol) {
+                int versionNumber = -1;
+
+                switch (protocol) {
+                    case "SSLv2Hello":
+                        versionNumber = 0x0002;
+                        break;
+                    case "SSLv3":
+                        versionNumber = 0x0300;
+                        break;
+                    case "TLSv1":
+                        versionNumber = 0x0301;
+                        break;
+                    case "TLSv1.1":
+                        versionNumber = 0x0302;
+                        break;
+                    case "TLSv1.2":
+                        versionNumber = 0x0303;
+                        break;
+                    default:
+                        // unlikely to happen
+                }
+
+                return versionNumber;
+            }
+        }
     }
 
     private List<TestParameters> tests;
--- a/test/sun/security/pkcs11/sslecc/CipherTest.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/test/sun/security/pkcs11/sslecc/CipherTest.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,19 +114,7 @@
         }
 
         boolean isEnabled() {
-            // ignore SCSV
-            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
-                return false;
-            }
-
-            // ignore exportable cipher suite for TLSv1.1
-            if (protocol.equals("TLSv1.1")) {
-                if(cipherSuite.indexOf("_EXPORT_") != -1) {
-                    return false;
-                }
-            }
-
-            return true;
+            return TLSCipherStatus.isEnabled(cipherSuite, protocol);
         }
 
         public String toString() {
@@ -137,6 +125,114 @@
             return s;
         }
 
+        static enum TLSCipherStatus {
+            // cipher suites supported since TLS 1.2
+            CS_01("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF),
+            CS_02("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",   0x0303, 0xFFFF),
+            CS_03("TLS_RSA_WITH_AES_256_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_04("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",  0x0303, 0xFFFF),
+            CS_05("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",    0x0303, 0xFFFF),
+            CS_06("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_07("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_08("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF),
+            CS_09("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",   0x0303, 0xFFFF),
+            CS_10("TLS_RSA_WITH_AES_128_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_11("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",  0x0303, 0xFFFF),
+            CS_12("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",    0x0303, 0xFFFF),
+            CS_13("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_14("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_15("TLS_DH_anon_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
+
+            // cipher suites obsoleted since TLS 1.2
+            CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
+            CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_52("SSL_DHE_DSS_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_53("SSL_DH_anon_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_54("TLS_KRB5_WITH_DES_CBC_SHA",               0x0000, 0x0303),
+            CS_55("TLS_KRB5_WITH_DES_CBC_MD5",               0x0000, 0x0303),
+
+            // cipher suites obsoleted since TLS 1.1
+            CS_60("SSL_RSA_EXPORT_WITH_RC4_40_MD5",          0x0000, 0x0302),
+            CS_61("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",      0x0000, 0x0302),
+            CS_62("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",       0x0000, 0x0302),
+            CS_63("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_64("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_65("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_66("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",         0x0000, 0x0302),
+            CS_67("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",         0x0000, 0x0302),
+            CS_68("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",     0x0000, 0x0302),
+            CS_69("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",     0x0000, 0x0302),
+
+            // ignore TLS_EMPTY_RENEGOTIATION_INFO_SCSV always
+            CS_99("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",       0xFFFF, 0x0000);
+
+            // the cipher suite name
+            final String cipherSuite;
+
+            // supported since protocol version
+            final int supportedSince;
+
+            // obsoleted since protocol version
+            final int obsoletedSince;
+
+            TLSCipherStatus(String cipherSuite,
+                    int supportedSince, int obsoletedSince) {
+                this.cipherSuite = cipherSuite;
+                this.supportedSince = supportedSince;
+                this.obsoletedSince = obsoletedSince;
+            }
+
+            static boolean isEnabled(String cipherSuite, String protocol) {
+                int versionNumber = toVersionNumber(protocol);
+
+                if (versionNumber < 0) {
+                    return true;  // unlikely to happen
+                }
+
+                for (TLSCipherStatus status : TLSCipherStatus.values()) {
+                    if (cipherSuite.equals(status.cipherSuite)) {
+                        if ((versionNumber < status.supportedSince) ||
+                            (versionNumber >= status.obsoletedSince)) {
+                            return false;
+                        }
+
+                        return true;
+                    }
+                }
+
+                return true;
+            }
+
+            private static int toVersionNumber(String protocol) {
+                int versionNumber = -1;
+
+                switch (protocol) {
+                    case "SSLv2Hello":
+                        versionNumber = 0x0002;
+                        break;
+                    case "SSLv3":
+                        versionNumber = 0x0300;
+                        break;
+                    case "TLSv1":
+                        versionNumber = 0x0301;
+                        break;
+                    case "TLSv1.1":
+                        versionNumber = 0x0302;
+                        break;
+                    case "TLSv1.2":
+                        versionNumber = 0x0303;
+                        break;
+                    default:
+                        // unlikely to happen
+                }
+
+                return versionNumber;
+            }
+        }
     }
 
     private List<TestParameters> tests;
@@ -170,11 +266,13 @@
                         // no client with anonymous ciphersuites
                         continue;
                     }
+
                     tests.add(new TestParameters(cipherSuite, protocol,
                         clientAuth));
                 }
             }
         }
+
         testIterator = tests.iterator();
     }
 
--- a/test/sun/security/ssl/sanity/interop/CipherTest.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/test/sun/security/ssl/sanity/interop/CipherTest.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -115,19 +115,7 @@
         }
 
         boolean isEnabled() {
-            // ignore SCSV
-            if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) {
-                return false;
-            }
-
-            // ignore exportable cipher suite for TLSv1.1
-            if (protocol.equals("TLSv1.1")) {
-                if(cipherSuite.indexOf("_EXPORT_") != -1) {
-                    return false;
-                }
-            }
-
-            return true;
+            return TLSCipherStatus.isEnabled(cipherSuite, protocol);
         }
 
         public String toString() {
@@ -138,6 +126,114 @@
             return s;
         }
 
+        static enum TLSCipherStatus {
+            // cipher suites supported since TLS 1.2
+            CS_01("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0x0303, 0xFFFF),
+            CS_02("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",   0x0303, 0xFFFF),
+            CS_03("TLS_RSA_WITH_AES_256_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_04("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",  0x0303, 0xFFFF),
+            CS_05("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",    0x0303, 0xFFFF),
+            CS_06("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_07("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_08("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0x0303, 0xFFFF),
+            CS_09("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",   0x0303, 0xFFFF),
+            CS_10("TLS_RSA_WITH_AES_128_CBC_SHA256",         0x0303, 0xFFFF),
+            CS_11("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",  0x0303, 0xFFFF),
+            CS_12("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",    0x0303, 0xFFFF),
+            CS_13("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_14("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+
+            CS_15("TLS_DH_anon_WITH_AES_256_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
+            CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
+
+            // cipher suites obsoleted since TLS 1.2
+            CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
+            CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_52("SSL_DHE_DSS_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_53("SSL_DH_anon_WITH_DES_CBC_SHA",            0x0000, 0x0303),
+            CS_54("TLS_KRB5_WITH_DES_CBC_SHA",               0x0000, 0x0303),
+            CS_55("TLS_KRB5_WITH_DES_CBC_MD5",               0x0000, 0x0303),
+
+            // cipher suites obsoleted since TLS 1.1
+            CS_60("SSL_RSA_EXPORT_WITH_RC4_40_MD5",          0x0000, 0x0302),
+            CS_61("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",      0x0000, 0x0302),
+            CS_62("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",       0x0000, 0x0302),
+            CS_63("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_64("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_65("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",   0x0000, 0x0302),
+            CS_66("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",         0x0000, 0x0302),
+            CS_67("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",         0x0000, 0x0302),
+            CS_68("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",     0x0000, 0x0302),
+            CS_69("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",     0x0000, 0x0302),
+
+            // ignore TLS_EMPTY_RENEGOTIATION_INFO_SCSV always
+            CS_99("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",       0xFFFF, 0x0000);
+
+            // the cipher suite name
+            final String cipherSuite;
+
+            // supported since protocol version
+            final int supportedSince;
+
+            // obsoleted since protocol version
+            final int obsoletedSince;
+
+            TLSCipherStatus(String cipherSuite,
+                    int supportedSince, int obsoletedSince) {
+                this.cipherSuite = cipherSuite;
+                this.supportedSince = supportedSince;
+                this.obsoletedSince = obsoletedSince;
+            }
+
+            static boolean isEnabled(String cipherSuite, String protocol) {
+                int versionNumber = toVersionNumber(protocol);
+
+                if (versionNumber < 0) {
+                    return true;  // unlikely to happen
+                }
+
+                for (TLSCipherStatus status : TLSCipherStatus.values()) {
+                    if (cipherSuite.equals(status.cipherSuite)) {
+                        if ((versionNumber < status.supportedSince) ||
+                            (versionNumber >= status.obsoletedSince)) {
+                            return false;
+                        }
+
+                        return true;
+                    }
+                }
+
+                return true;
+            }
+
+            private static int toVersionNumber(String protocol) {
+                int versionNumber = -1;
+
+                switch (protocol) {
+                    case "SSLv2Hello":
+                        versionNumber = 0x0002;
+                        break;
+                    case "SSLv3":
+                        versionNumber = 0x0300;
+                        break;
+                    case "TLSv1":
+                        versionNumber = 0x0301;
+                        break;
+                    case "TLSv1.1":
+                        versionNumber = 0x0302;
+                        break;
+                    case "TLSv1.2":
+                        versionNumber = 0x0303;
+                        break;
+                    default:
+                        // unlikely to happen
+                }
+
+                return versionNumber;
+            }
+        }
     }
 
     private List<TestParameters> tests;
--- a/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java	Mon Mar 21 11:49:37 2011 -0700
+++ b/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java	Mon Mar 21 22:02:00 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,6 @@
  * @test
  * @bug 4496785
  * @summary Verify that all ciphersuites work in all configurations
- * @ignore JSSE supported cipher suites are changed with CR 6916074,
- *     need to update this test case in JDK 7 soon
  * @author Andreas Sterbenz
  * @run main/othervm/timeout=300 ClientJSSEServerJSSE
  */