8136355: CKM_SSL3_KEY_AND_MAC_DERIVE no longer available by default on Solaris 12
authorvaleriep
Fri, 23 Sep 2016 01:08:24 +0000
changeset 41123 66eaead2a150
parent 41122 c33012bac916
child 41124 15b45f23f2f7
8136355: CKM_SSL3_KEY_AND_MAC_DERIVE no longer available by default on Solaris 12 Summary: Enhanced to detect and throw InvalidAlgorithmParameterException if SSLv3 is requested but unsupported Reviewed-by: xuelei
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java
jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java
jdk/test/sun/security/pkcs11/tls/TestPremaster.java
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Fri Sep 23 01:08:24 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -68,8 +68,8 @@
     // master secret as a P11Key
     private P11Key p11Key;
 
-    // version, e.g. 0x0301
-    private int version;
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
 
     P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism)
             throws PKCS11Exception {
@@ -77,6 +77,11 @@
         this.token = token;
         this.algorithm = algorithm;
         this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java,
+        // if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE);
     }
 
     protected void engineInit(SecureRandom random) {
@@ -89,20 +94,26 @@
         if (params instanceof TlsKeyMaterialParameterSpec == false) {
             throw new InvalidAlgorithmParameterException(MSG);
         }
-        this.spec = (TlsKeyMaterialParameterSpec)params;
+
+        TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params;
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
         try {
             p11Key = P11SecretKeyFactory.convertKey
                             (token, spec.getMasterSecret(), "TlsMasterSecret");
         } catch (InvalidKeyException e) {
             throw new InvalidAlgorithmParameterException("init() failed", e);
         }
-        version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((version < 0x0300) && (version > 0x0302)) {
-            throw new InvalidAlgorithmParameterException
-                    ("Only SSL 3.0, TLS 1.0, and TLS 1.1 are supported");
-        }
-        // we assume the token supports both the CKM_SSL3_* and the CKM_TLS_*
-        // mechanisms
+        this.spec = spec;
+        this.mechanism = (version == 0x0300)?
+            CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE;
     }
 
     protected void engineInit(int keysize, SecureRandom random) {
@@ -115,8 +126,6 @@
             throw new IllegalStateException
                 ("TlsKeyMaterialGenerator must be initialized");
         }
-        mechanism = (version == 0x0300) ? CKM_SSL3_KEY_AND_MAC_DERIVE
-                                         : CKM_TLS_KEY_AND_MAC_DERIVE;
         int macBits = spec.getMacKeyLength() << 3;
         int ivBits = spec.getIvLength() << 3;
 
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Fri Sep 23 01:08:24 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -61,7 +61,10 @@
     private TlsMasterSecretParameterSpec spec;
     private P11Key p11Key;
 
-    int version;
+    CK_VERSION ckVersion;
+
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
 
     P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism)
             throws PKCS11Exception {
@@ -69,6 +72,11 @@
         this.token = token;
         this.algorithm = algorithm;
         this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java, if
+        // CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE);
     }
 
     protected void engineInit(SecureRandom random) {
@@ -81,7 +89,17 @@
         if (params instanceof TlsMasterSecretParameterSpec == false) {
             throw new InvalidAlgorithmParameterException(MSG);
         }
-        this.spec = (TlsMasterSecretParameterSpec)params;
+
+        TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
+
         SecretKey key = spec.getPremasterSecret();
         // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,
         // but we omit the check
@@ -90,25 +108,7 @@
         } catch (InvalidKeyException e) {
             throw new InvalidAlgorithmParameterException("init() failed", e);
         }
-        version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((version < 0x0300) || (version > 0x0302)) {
-            throw new InvalidAlgorithmParameterException
-                ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
-        }
-        // We assume the token supports the required mechanism. If it does not,
-        // generateKey() will fail and the failover should take care of us.
-    }
-
-    protected void engineInit(int keysize, SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    protected SecretKey engineGenerateKey() {
-        if (spec == null) {
-            throw new IllegalStateException
-                ("TlsMasterSecretGenerator must be initialized");
-        }
-        CK_VERSION ckVersion;
+        this.spec = spec;
         if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) {
             mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE
                                              : CKM_TLS_MASTER_KEY_DERIVE;
@@ -124,6 +124,17 @@
                                              : CKM_TLS_MASTER_KEY_DERIVE_DH;
             ckVersion = null;
         }
+    }
+
+    protected void engineInit(int keysize, SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    protected SecretKey engineGenerateKey() {
+        if (spec == null) {
+            throw new IllegalStateException
+                ("TlsMasterSecretGenerator must be initialized");
+        }
         byte[] clientRandom = spec.getClientRandom();
         byte[] serverRandom = spec.getServerRandom();
         CK_SSL3_RANDOM_DATA random =
@@ -139,13 +150,12 @@
             long keyID = token.p11.C_DeriveKey(session.id(),
                 new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
             int major, minor;
-            ckVersion = params.pVersion;
-            if (ckVersion == null) {
+            if (params.pVersion == null) {
                 major = -1;
                 minor = -1;
             } else {
-                major = ckVersion.major;
-                minor = ckVersion.minor;
+                major = params.pVersion.major;
+                minor = params.pVersion.minor;
             }
             SecretKey key = P11Key.masterSecretKey(session, keyID,
                 "TlsMasterSecret", 48 << 3, attributes, major, minor);
@@ -156,5 +166,4 @@
             token.releaseSession(session);
         }
     }
-
 }
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java	Fri Sep 23 01:08:24 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -60,12 +60,20 @@
     @SuppressWarnings("deprecation")
     private TlsRsaPremasterSecretParameterSpec spec;
 
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
+
     P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism)
             throws PKCS11Exception {
         super();
         this.token = token;
         this.algorithm = algorithm;
         this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java,
+        // if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN);
     }
 
     protected void engineInit(SecureRandom random) {
@@ -78,7 +86,20 @@
         if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
             throw new InvalidAlgorithmParameterException(MSG);
         }
-        this.spec = (TlsRsaPremasterSecretParameterSpec)params;
+
+        TlsRsaPremasterSecretParameterSpec spec =
+            (TlsRsaPremasterSecretParameterSpec) params;
+
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
+        this.spec = spec;
     }
 
     protected void engineInit(int keysize, SecureRandom random) {
--- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Fri Sep 23 01:08:24 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6316539
+ * @bug 6316539 8136355
  * @summary Known-answer-test for TlsKeyMaterial generator
  * @author Andreas Sterbenz
  * @library ..
@@ -37,6 +37,7 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.security.Provider;
+import java.security.InvalidAlgorithmParameterException;
 import java.util.Arrays;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -139,21 +140,28 @@
                         keyLength, expandedKeyLength, ivLength, macLength,
                         null, -1, -1);
 
-                    kg.init(spec);
-                    TlsKeyMaterialSpec result =
-                        (TlsKeyMaterialSpec)kg.generateKey();
-                    match(lineNumber, clientCipherBytes,
-                        result.getClientCipherKey(), cipherAlgorithm);
-                    match(lineNumber, serverCipherBytes,
-                        result.getServerCipherKey(), cipherAlgorithm);
-                    match(lineNumber, clientIv, result.getClientIv(), "");
-                    match(lineNumber, serverIv, result.getServerIv(), "");
-                    match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
-                    match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
-
-                } else {
+                    try {
+                        kg.init(spec);
+                        TlsKeyMaterialSpec result =
+                            (TlsKeyMaterialSpec)kg.generateKey();
+                        match(lineNumber, clientCipherBytes,
+                            result.getClientCipherKey(), cipherAlgorithm);
+                        match(lineNumber, serverCipherBytes,
+                            result.getServerCipherKey(), cipherAlgorithm);
+                        match(lineNumber, clientIv, result.getClientIv(), "");
+                        match(lineNumber, serverIv, result.getServerIv(), "");
+                        match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
+                        match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
+                    } catch (InvalidAlgorithmParameterException iape) {
+                        // SSLv3 support is removed in S12
+                        if (major == 3 && minor == 0) {
+                            System.out.println("Skip testing SSLv3");
+                            continue;
+                        }
+                    }
+               } else {
                     throw new Exception("Unknown line: " + line);
-                }
+               }
             }
             if (n == 0) {
                 throw new Exception("no tests");
--- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Fri Sep 23 01:08:24 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6316539
+ * @bug 6316539 8136355
  * @summary Known-answer-test for TlsMasterSecret generator
  * @author Andreas Sterbenz
  * @library ..
@@ -38,6 +38,7 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.security.Provider;
+import java.security.InvalidAlgorithmParameterException;
 import java.util.Arrays;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -116,15 +117,24 @@
                         new TlsMasterSecretParameterSpec(premasterKey,
                             protoMajor, protoMinor, clientRandom, serverRandom,
                             null, -1, -1);
-                    kg.init(spec);
-                    TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
-                    byte[] enc = key.getEncoded();
-                    if (Arrays.equals(master, enc) == false) {
-                        throw new Exception("mismatch line: " + lineNumber);
-                    }
-                    if ((preMajor != key.getMajorVersion()) ||
-                            (preMinor != key.getMinorVersion())) {
-                        throw new Exception("version mismatch line: " + lineNumber);
+
+                    try {
+                        kg.init(spec);
+                        TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
+                        byte[] enc = key.getEncoded();
+                        if (Arrays.equals(master, enc) == false) {
+                            throw new Exception("mismatch line: " + lineNumber);
+                        }
+                        if ((preMajor != key.getMajorVersion()) ||
+                                (preMinor != key.getMinorVersion())) {
+                           throw new Exception("version mismatch line: " + lineNumber);
+                        }
+                    } catch (InvalidAlgorithmParameterException iape) {
+                        // SSLv3 support is removed in S12
+                        if (preMajor == 3 && preMinor == 0) {
+                            System.out.println("Skip testing SSLv3");
+                            continue;
+                        }
                     }
                 } else {
                     throw new Exception("Unknown line: " + line);
--- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Thu Sep 22 18:31:42 2016 +0000
+++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Fri Sep 23 01:08:24 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6316539
+ * @bug 6316539 8136355
  * @summary Basic tests for TlsRsaPremasterSecret generator
  * @author Andreas Sterbenz
  * @library ..
@@ -34,6 +34,7 @@
  */
 
 import java.security.Provider;
+import java.security.InvalidAlgorithmParameterException;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
@@ -61,7 +62,7 @@
             System.out.println("OK: " + e);
         }
 
-        int[] protocolVersions = {0x0300, 0x0301, 0x0302, 0x0400};
+        int[] protocolVersions = {0x0300, 0x0301, 0x0302};
         for (int clientVersion : protocolVersions) {
             for (int serverVersion : protocolVersions) {
                 test(kg, clientVersion, serverVersion);
@@ -81,8 +82,18 @@
                 "Testing RSA pre-master secret key generation between " +
                 "client (0x%04X) and server(0x%04X)%n",
                 clientVersion, serverVersion);
-        kg.init(new TlsRsaPremasterSecretParameterSpec(
+        try {
+            kg.init(new TlsRsaPremasterSecretParameterSpec(
                                     clientVersion, serverVersion));
+        } catch (InvalidAlgorithmParameterException iape) {
+            // S12 removed support for SSL v3.0
+            if (clientVersion == 0x300 || serverVersion == 0x300) {
+                System.out.println("Skip testing SSLv3 due to no support");
+                return;
+            }
+            // unexpected, pass it up
+            throw iape;
+        }
         SecretKey key = kg.generateKey();
         byte[] encoded = key.getEncoded();
         if (encoded != null) {  // raw key material may be not extractable