< 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 >