< prev index next >

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -27,16 +27,16 @@
 
 import java.security.*;
 import java.security.spec.AlgorithmParameterSpec;
 
 import javax.crypto.*;
-import javax.crypto.spec.*;
-
 import sun.security.internal.spec.TlsMasterSecretParameterSpec;
 
 import static sun.security.pkcs11.TemplateManager.*;
 import sun.security.pkcs11.wrapper.*;
+import sun.security.ssl.ProtocolVersion;
+
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
 /**
  * KeyGenerator for the SSL/TLS master secret.
  *

@@ -55,10 +55,12 @@
     private final String algorithm;
 
     // mechanism id
     private long mechanism;
 
+    private ProtocolVersion tlsVersion;
+
     @SuppressWarnings("deprecation")
     private TlsMasterSecretParameterSpec spec;
     private P11Key p11Key;
 
     CK_VERSION ckVersion;

@@ -89,17 +91,18 @@
         if (params instanceof TlsMasterSecretParameterSpec == false) {
             throw new InvalidAlgorithmParameterException(MSG);
         }
 
         TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
-        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
-            (version > 0x0302)) {
+        tlsVersion = ProtocolVersion.valueOf(spec.getMajorVersion(), spec.getMinorVersion());
+        if ((tlsVersion.compareTo(ProtocolVersion.SSL30) == 0 && !supportSSLv3) ||
+                (tlsVersion.compareTo(ProtocolVersion.SSL30) < 0) ||
+                (tlsVersion.compareTo(ProtocolVersion.TLS12) > 0)) {
              throw new InvalidAlgorithmParameterException
                     ("Only" + (supportSSLv3? " SSL 3.0,": "") +
-                     " TLS 1.0, and TLS 1.1 are supported (0x" +
-                     Integer.toHexString(version) + ")");
+                     " TLS 1.0, TLS 1.1 and TLS 1.2 are supported (" +
+                     tlsVersion + ")");
         }
 
         SecretKey key = spec.getPremasterSecret();
         // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,
         // but we omit the check

@@ -107,23 +110,31 @@
             p11Key = P11SecretKeyFactory.convertKey(token, key, null);
         } catch (InvalidKeyException e) {
             throw new InvalidAlgorithmParameterException("init() failed", e);
         }
         this.spec = spec;
-        if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) {
-            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE
-                                             : CKM_TLS_MASTER_KEY_DERIVE;
+        final boolean isTlsRsaPremasterSecret = p11Key.getAlgorithm().equals("TlsRsaPremasterSecret");
+        if (tlsVersion.compareTo(ProtocolVersion.SSL30) == 0) {
+            mechanism = isTlsRsaPremasterSecret ?
+                    CKM_SSL3_MASTER_KEY_DERIVE : CKM_SSL3_MASTER_KEY_DERIVE_DH;
+        } else if (tlsVersion.compareTo(ProtocolVersion.TLS10) == 0 ||
+                    tlsVersion.compareTo(ProtocolVersion.TLS11) == 0) {
+            mechanism = isTlsRsaPremasterSecret ?
+                    CKM_TLS_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE_DH;
+        } else if (tlsVersion.compareTo(ProtocolVersion.TLS12) == 0) {
+            mechanism = isTlsRsaPremasterSecret ?
+                    CKM_TLS12_MASTER_KEY_DERIVE : CKM_TLS12_MASTER_KEY_DERIVE_DH;
+        }
+        if (isTlsRsaPremasterSecret) {
             ckVersion = new CK_VERSION(0, 0);
         } else {
             // Note: we use DH for all non-RSA premaster secrets. That includes
             // Kerberos. That should not be a problem because master secret
             // calculation is always a straightforward application of the
             // TLS PRF (or the SSL equivalent).
             // The only thing special about RSA master secret calculation is
             // that it extracts the version numbers from the premaster secret.
-            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE_DH
-                                             : CKM_TLS_MASTER_KEY_DERIVE_DH;
             ckVersion = null;
         }
     }
 
     protected void engineInit(int keysize, SecureRandom random) {

@@ -137,27 +148,35 @@
         }
         byte[] clientRandom = spec.getClientRandom();
         byte[] serverRandom = spec.getServerRandom();
         CK_SSL3_RANDOM_DATA random =
                 new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);
+        CK_MECHANISM ckMechanism = null;
+        if (tlsVersion.compareTo(ProtocolVersion.TLS12) < 0) {
         CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =
                 new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);
-
+            ckMechanism = new CK_MECHANISM(mechanism, params);
+        } else if (tlsVersion.compareTo(ProtocolVersion.TLS12) == 0) {
+            CK_TLS12_MASTER_KEY_DERIVE_PARAMS params =
+                    new CK_TLS12_MASTER_KEY_DERIVE_PARAMS(random, ckVersion,
+                            SunPKCS11.hashAlgorithmToHashMechanismMap.get(spec.getPRFHashAlg()));
+            ckMechanism = new CK_MECHANISM(mechanism, params);
+        }
         Session session = null;
         try {
             session = token.getObjSession();
             CK_ATTRIBUTE[] attributes = token.getAttributes(O_GENERATE,
                 CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
             long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
+                    ckMechanism, p11Key.keyID, attributes);
             int major, minor;
-            if (params.pVersion == null) {
+            if (ckVersion == null) {
                 major = -1;
                 minor = -1;
             } else {
-                major = params.pVersion.major;
-                minor = params.pVersion.minor;
+                major = ckVersion.major;
+                minor = ckVersion.minor;
             }
             SecretKey key = P11Key.masterSecretKey(session, keyID,
                 "TlsMasterSecret", 48 << 3, attributes, major, minor);
             return key;
         } catch (Exception e) {
< prev index next >