Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java
38919 views
/*1* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.pkcs11;2627import java.security.*;28import java.security.spec.AlgorithmParameterSpec;2930import javax.crypto.*;31import javax.crypto.spec.*;3233import sun.security.internal.spec.TlsMasterSecretParameterSpec;3435import static sun.security.pkcs11.TemplateManager.*;36import sun.security.pkcs11.wrapper.*;37import static sun.security.pkcs11.wrapper.PKCS11Constants.*;3839/**40* KeyGenerator for the SSL/TLS master secret.41*42* @author Andreas Sterbenz43* @since 1.644*/45public final class P11TlsMasterSecretGenerator extends KeyGeneratorSpi {4647private final static String MSG = "TlsMasterSecretGenerator must be "48+ "initialized using a TlsMasterSecretParameterSpec";4950// token instance51private final Token token;5253// algorithm name54private final String algorithm;5556// mechanism id57private long mechanism;5859private TlsMasterSecretParameterSpec spec;60private P11Key p11Key;6162int version;6364P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism)65throws PKCS11Exception {66super();67this.token = token;68this.algorithm = algorithm;69this.mechanism = mechanism;70}7172protected void engineInit(SecureRandom random) {73throw new InvalidParameterException(MSG);74}7576protected void engineInit(AlgorithmParameterSpec params,77SecureRandom random) throws InvalidAlgorithmParameterException {78if (params instanceof TlsMasterSecretParameterSpec == false) {79throw new InvalidAlgorithmParameterException(MSG);80}81this.spec = (TlsMasterSecretParameterSpec)params;82SecretKey key = spec.getPremasterSecret();83// algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,84// but we omit the check85try {86p11Key = P11SecretKeyFactory.convertKey(token, key, null);87} catch (InvalidKeyException e) {88throw new InvalidAlgorithmParameterException("init() failed", e);89}90version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();91if ((version < 0x0300) && (version > 0x0303)) {92throw new InvalidAlgorithmParameterException("Only SSL 3.0," +93" TLS 1.0, TLS 1.1, and TLS 1.2 are supported");94}95// We assume the token supports the required mechanism. If it does not,96// generateKey() will fail and the failover should take care of us.97}9899protected void engineInit(int keysize, SecureRandom random) {100throw new InvalidParameterException(MSG);101}102103protected SecretKey engineGenerateKey() {104if (spec == null) {105throw new IllegalStateException106("TlsMasterSecretGenerator must be initialized");107}108final boolean isTlsRsaPremasterSecret =109p11Key.getAlgorithm().equals("TlsRsaPremasterSecret");110if (version == 0x0300) {111mechanism = isTlsRsaPremasterSecret ?112CKM_SSL3_MASTER_KEY_DERIVE : CKM_SSL3_MASTER_KEY_DERIVE_DH;113} else if (version == 0x0301 || version == 0x0302) {114mechanism = isTlsRsaPremasterSecret ?115CKM_TLS_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE_DH;116} else if (version == 0x0303) {117mechanism = isTlsRsaPremasterSecret ?118CKM_TLS12_MASTER_KEY_DERIVE : CKM_TLS12_MASTER_KEY_DERIVE_DH;119}120CK_VERSION ckVersion;121if (isTlsRsaPremasterSecret) {122ckVersion = new CK_VERSION(0, 0);123} else {124// Note: we use DH for all non-RSA premaster secrets. That includes125// Kerberos. That should not be a problem because master secret126// calculation is always a straightforward application of the127// TLS PRF (or the SSL equivalent).128// The only thing special about RSA master secret calculation is129// that it extracts the version numbers from the premaster secret.130ckVersion = null;131}132byte[] clientRandom = spec.getClientRandom();133byte[] serverRandom = spec.getServerRandom();134CK_SSL3_RANDOM_DATA random =135new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);136CK_MECHANISM ckMechanism = null;137if (version < 0x0303) {138CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =139new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);140ckMechanism = new CK_MECHANISM(mechanism, params);141} else if (version == 0x0303) {142CK_TLS12_MASTER_KEY_DERIVE_PARAMS params =143new CK_TLS12_MASTER_KEY_DERIVE_PARAMS(random, ckVersion,144Functions.getHashMechId(spec.getPRFHashAlg()));145ckMechanism = new CK_MECHANISM(mechanism, params);146}147148Session session = null;149long p11KeyID = p11Key.getKeyID();150try {151session = token.getObjSession();152CK_ATTRIBUTE[] attributes = token.getAttributes(O_GENERATE,153CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);154long keyID = token.p11.C_DeriveKey(session.id(),155ckMechanism, p11KeyID, attributes);156int major, minor;157if (ckVersion == null) {158major = -1;159minor = -1;160} else {161major = ckVersion.major;162minor = ckVersion.minor;163}164return P11Key.masterSecretKey(session, keyID,165"TlsMasterSecret", 48 << 3, attributes, major, minor);166} catch (Exception e) {167throw new ProviderException("Could not generate key", e);168} finally {169p11Key.releaseKeyID();170token.releaseSession(session);171}172}173174}175176177