--- old/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java 2018-05-22 17:08:43.632347096 -0300 +++ new/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java 2018-05-22 17:08:43.432346941 -0300 @@ -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,12 @@ 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.*; /** @@ -57,6 +57,8 @@ // mechanism id private long mechanism; + private ProtocolVersion tlsVersion; + @SuppressWarnings("deprecation") private TlsMasterSecretParameterSpec spec; private P11Key p11Key; @@ -91,13 +93,14 @@ } 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(); @@ -109,9 +112,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.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 @@ -120,8 +133,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 +150,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.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);