src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java
changeset 51800 bccd9966f1ed
parent 47216 71c04702a3d5
child 53257 5170dc2bcf64
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Wed Sep 19 10:50:25 2018 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Wed Sep 12 13:09:51 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -29,12 +29,11 @@
 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 static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
 /**
@@ -57,6 +56,8 @@
     // mechanism id
     private long mechanism;
 
+    private int tlsVersion;
+
     @SuppressWarnings("deprecation")
     private TlsMasterSecretParameterSpec spec;
     private P11Key p11Key;
@@ -91,13 +92,13 @@
         }
 
         TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
-        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
-            (version > 0x0302)) {
+        tlsVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+        if ((tlsVersion == 0x0300 && !supportSSLv3) ||
+                (tlsVersion < 0x0300) || (tlsVersion > 0x0303)) {
              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();
@@ -109,9 +110,19 @@
             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 == 0x0300) {
+            mechanism = isTlsRsaPremasterSecret ?
+                    CKM_SSL3_MASTER_KEY_DERIVE : CKM_SSL3_MASTER_KEY_DERIVE_DH;
+        } else if (tlsVersion == 0x0301 || tlsVersion == 0x0302) {
+            mechanism = isTlsRsaPremasterSecret ?
+                    CKM_TLS_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE_DH;
+        } else if (tlsVersion == 0x0303) {
+            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
@@ -120,8 +131,6 @@
             // 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;
         }
     }
@@ -139,23 +148,31 @@
         byte[] serverRandom = spec.getServerRandom();
         CK_SSL3_RANDOM_DATA random =
                 new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);
-        CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =
-                new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);
-
+        CK_MECHANISM ckMechanism = null;
+        if (tlsVersion < 0x0303) {
+            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 == 0x0303) {
+            CK_TLS12_MASTER_KEY_DERIVE_PARAMS params =
+                    new CK_TLS12_MASTER_KEY_DERIVE_PARAMS(random, ckVersion,
+                            Functions.getHashMechId(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);