# HG changeset patch # User mbalao # Date 1541016287 10800 # Wed Oct 31 17:04:47 2018 -0300 # Node ID fa06cdb4c6f7b5ca148f26d345090d48014fecff # Parent 478a4add975beb90696a4ead5f8fcd9c17fc1a83 8029661, PR3642, RH1477159: Support TLS v1.2 algorithm in SunPKCS11 provider Summary: TLS v1.2 algorithms for key and MAC derivation added to SunPKCS11 crypto provider. 8210912 fix is included as part of this changeset. Reviewed-by: valeriep diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, 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 @@ -95,9 +95,9 @@ throw new InvalidAlgorithmParameterException("init() failed", e); } version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) && (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 are supported"); + if ((version < 0x0300) && (version > 0x0303)) { + throw new InvalidAlgorithmParameterException("Only SSL 3.0," + + " TLS 1.0, TLS 1.1, and TLS 1.2 are supported"); } // we assume the token supports both the CKM_SSL3_* and the CKM_TLS_* // mechanisms @@ -112,8 +112,11 @@ throw new IllegalStateException ("TlsKeyMaterialGenerator must be initialized"); } - mechanism = (version == 0x0300) ? CKM_SSL3_KEY_AND_MAC_DERIVE - : CKM_TLS_KEY_AND_MAC_DERIVE; + if (version == 0x0300) { + mechanism = CKM_SSL3_KEY_AND_MAC_DERIVE; + } else if (version == 0x0301 || version == 0x0302) { + mechanism = CKM_TLS_KEY_AND_MAC_DERIVE; + } int macBits = spec.getMacKeyLength() << 3; int ivBits = spec.getIvLength() << 3; @@ -129,8 +132,18 @@ CK_SSL3_RANDOM_DATA random = new CK_SSL3_RANDOM_DATA (spec.getClientRandom(), spec.getServerRandom()); - CK_SSL3_KEY_MAT_PARAMS params = new CK_SSL3_KEY_MAT_PARAMS - (macBits, keyBits, ivBits, isExportable, random); + Object params = null; + CK_MECHANISM ckMechanism = null; + if (version < 0x0303) { + params = new CK_SSL3_KEY_MAT_PARAMS + (macBits, keyBits, ivBits, isExportable, random); + ckMechanism = new CK_MECHANISM(mechanism, (CK_SSL3_KEY_MAT_PARAMS)params); + } else if (version == 0x0303) { + params = new CK_TLS12_KEY_MAT_PARAMS + (macBits, keyBits, ivBits, isExportable, random, + Functions.getHashMechId(spec.getPRFHashAlg())); + ckMechanism = new CK_MECHANISM(mechanism, (CK_TLS12_KEY_MAT_PARAMS)params); + } String cipherAlgorithm = spec.getCipherAlgorithm(); long keyType = P11SecretKeyFactory.getKeyType(cipherAlgorithm); @@ -162,9 +175,14 @@ (O_GENERATE, CKO_SECRET_KEY, keyType, attributes); // the returned keyID is a dummy, ignore long keyID = token.p11.C_DeriveKey(session.id(), - new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes); + ckMechanism, p11Key.keyID, attributes); - CK_SSL3_KEY_MAT_OUT out = params.pReturnedKeyMaterial; + CK_SSL3_KEY_MAT_OUT out = null; + if (params instanceof CK_SSL3_KEY_MAT_PARAMS) { + out = ((CK_SSL3_KEY_MAT_PARAMS)params).pReturnedKeyMaterial; + } else if (params instanceof CK_TLS12_KEY_MAT_PARAMS) { + out = ((CK_TLS12_KEY_MAT_PARAMS)params).pReturnedKeyMaterial; + } // Note that the MAC keys do not inherit all attributes from the // template, but they do inherit the sensitive/extractable/token // flags, which is all P11Key cares about. diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2007, 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 @@ -89,9 +89,9 @@ throw new InvalidAlgorithmParameterException("init() failed", e); } version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) || (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported"); + if ((version < 0x0300) && (version > 0x0303)) { + throw new InvalidAlgorithmParameterException("Only SSL 3.0," + + " TLS 1.0, TLS 1.1, and TLS 1.2 are supported"); } // We assume the token supports the required mechanism. If it does not, // generateKey() will fail and the failover should take care of us. @@ -106,10 +106,20 @@ throw new IllegalStateException ("TlsMasterSecretGenerator must be initialized"); } + final boolean isTlsRsaPremasterSecret = + p11Key.getAlgorithm().equals("TlsRsaPremasterSecret"); + if (version == 0x0300) { + mechanism = isTlsRsaPremasterSecret ? + CKM_SSL3_MASTER_KEY_DERIVE : CKM_SSL3_MASTER_KEY_DERIVE_DH; + } else if (version == 0x0301 || version == 0x0302) { + mechanism = isTlsRsaPremasterSecret ? + CKM_TLS_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE_DH; + } else if (version == 0x0303) { + mechanism = isTlsRsaPremasterSecret ? + CKM_TLS12_MASTER_KEY_DERIVE : CKM_TLS12_MASTER_KEY_DERIVE_DH; + } CK_VERSION ckVersion; - if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) { - mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE - : CKM_TLS_MASTER_KEY_DERIVE; + if (isTlsRsaPremasterSecret) { ckVersion = new CK_VERSION(0, 0); } else { // Note: we use DH for all non-RSA premaster secrets. That includes @@ -118,16 +128,23 @@ // 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; } byte[] clientRandom = spec.getClientRandom(); 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 (version < 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 (version == 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 { @@ -135,9 +152,8 @@ 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; - ckVersion = params.pVersion; if (ckVersion == null) { major = -1; minor = -1; diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, 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 @@ -124,8 +124,46 @@ if (spec == null) { throw new IllegalStateException("TlsPrfGenerator must be initialized"); } + byte[] seed = spec.getSeed(); + + // TLS 1.2 + if (mechanism == CKM_TLS_MAC) { + SecretKey k = null; + int ulServerOrClient = 0; + if (spec.getLabel().equals("server finished")) { + ulServerOrClient = 1; + } + if (spec.getLabel().equals("client finished")) { + ulServerOrClient = 2; + } + + if (ulServerOrClient != 0) { + // Finished message + CK_TLS_MAC_PARAMS params = new CK_TLS_MAC_PARAMS( + Functions.getHashMechId(spec.getPRFHashAlg()), + spec.getOutputLength(), ulServerOrClient); + Session session = null; + try { + session = token.getOpSession(); + token.p11.C_SignInit(session.id(), + new CK_MECHANISM(mechanism, params), p11Key.keyID); + token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length); + byte[] out = token.p11.C_SignFinal + (session.id(), spec.getOutputLength()); + k = new SecretKeySpec(out, "TlsPrf"); + } catch (PKCS11Exception e) { + throw new ProviderException("Could not calculate PRF", e); + } finally { + token.releaseSession(session); + } + } else { + throw new ProviderException("Only Finished message authentication code"+ + " generation supported for TLS 1.2."); + } + return k; + } + byte[] label = P11Util.getBytesUTF8(spec.getLabel()); - byte[] seed = spec.getSeed(); if (mechanism == CKM_NSS_TLS_PRF_GENERAL) { Session session = null; diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, 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 @@ -57,6 +57,8 @@ // mechanism id private long mechanism; + private int version; + private TlsRsaPremasterSecretParameterSpec spec; P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism) @@ -77,6 +79,11 @@ throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsRsaPremasterSecretParameterSpec)params; + version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + if ((version < 0x0300) && (version > 0x0303)) { + throw new InvalidAlgorithmParameterException + ("Only SSL 3.0, TLS 1.0, TLS 1.1, and TLS 1.2 are supported"); + } } protected void engineInit(int keysize, SecureRandom random) { diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -720,38 +720,28 @@ s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"), m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - /* - * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the - * PRF calculations. As of 2010, there is no PKCS11-level - * support for TLS 1.2 PRF calculations, and no known OS's have - * an internal variant we could use. Therefore for TLS 1.2, we - * are updating JSSE to request different provider algorithms - * (e.g. "SunTls12Prf"), and currently only SunJCE has these - * TLS 1.2 algorithms. - * - * If we reused the names such as "SunTlsPrf", the PKCS11 - * providers would need be updated to fail correctly when - * presented with the wrong version number (via - * Provider.Service.supportsParameters()), and we would also - * need to add the appropriate supportsParamters() checks into - * KeyGenerators (not currently there). - * - * In the future, if PKCS11 support is added, we will restructure - * this. - */ d(KG, "SunTlsRsaPremasterSecret", "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator", + s("SunTls12RsaPremasterSecret"), m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN)); d(KG, "SunTlsMasterSecret", "sun.security.pkcs11.P11TlsMasterSecretGenerator", m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_MASTER_KEY_DERIVE_DH)); + d(KG, "SunTls12MasterSecret", + "sun.security.pkcs11.P11TlsMasterSecretGenerator", + m(CKM_TLS12_MASTER_KEY_DERIVE, CKM_TLS12_MASTER_KEY_DERIVE_DH)); d(KG, "SunTlsKeyMaterial", "sun.security.pkcs11.P11TlsKeyMaterialGenerator", m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE)); + d(KG, "SunTls12KeyMaterial", + "sun.security.pkcs11.P11TlsKeyMaterialGenerator", + m(CKM_TLS12_KEY_AND_MAC_DERIVE)); d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator", m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL)); + d(KG, "SunTls12Prf", "sun.security.pkcs11.P11TlsPrfGenerator", + m(CKM_TLS_MAC)); } // background thread that periodically checks for token insertion @@ -1016,13 +1006,16 @@ if (algorithm == "SunTlsRsaPremasterSecret") { return new P11TlsRsaPremasterSecretGenerator( token, algorithm, mechanism); - } else if (algorithm == "SunTlsMasterSecret") { + } else if (algorithm == "SunTlsMasterSecret" + || algorithm == "SunTls12MasterSecret") { return new P11TlsMasterSecretGenerator( token, algorithm, mechanism); - } else if (algorithm == "SunTlsKeyMaterial") { + } else if (algorithm == "SunTlsKeyMaterial" + || algorithm == "SunTls12KeyMaterial") { return new P11TlsKeyMaterialGenerator( token, algorithm, mechanism); - } else if (algorithm == "SunTlsPrf") { + } else if (algorithm == "SunTlsPrf" + || algorithm == "SunTls12Prf") { return new P11TlsPrfGenerator(token, algorithm, mechanism); } else { return new P11KeyGenerator(token, algorithm, mechanism); diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -112,14 +112,26 @@ init(mechanism, params); } + public CK_MECHANISM(long mechanism, CK_TLS12_MASTER_KEY_DERIVE_PARAMS params) { + init(mechanism, params); + } + public CK_MECHANISM(long mechanism, CK_SSL3_KEY_MAT_PARAMS params) { init(mechanism, params); } + public CK_MECHANISM(long mechanism, CK_TLS12_KEY_MAT_PARAMS params) { + init(mechanism, params); + } + public CK_MECHANISM(long mechanism, CK_TLS_PRF_PARAMS params) { init(mechanism, params); } + public CK_MECHANISM(long mechanism, CK_TLS_MAC_PARAMS params) { + init(mechanism, params); + } + public CK_MECHANISM(long mechanism, CK_ECDH1_DERIVE_PARAMS params) { init(mechanism, params); } diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_KEY_MAT_PARAMS.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_KEY_MAT_PARAMS.java new file mode 100644 --- /dev/null +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_KEY_MAT_PARAMS.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.pkcs11.wrapper; + +/** + * CK_TLS12_KEY_MAT_PARAMS from PKCS#11 v2.40. + */ +public class CK_TLS12_KEY_MAT_PARAMS { + + /** + * PKCS#11: + *
+     *   CK_ULONG ulMacSizeInBits;
+     * 
+ */ + public long ulMacSizeInBits; + + /** + * PKCS#11: + *
+     *   CK_ULONG ulKeySizeInBits;
+     * 
+ */ + public long ulKeySizeInBits; + + /** + * PKCS#11: + *
+     *   CK_ULONG ulIVSizeInBits;
+     * 
+ */ + public long ulIVSizeInBits; + + /** + * PKCS#11: + *
+     *   CK_BBOOL bIsExport;
+     * 
+ */ + public boolean bIsExport; + + /** + * PKCS#11: + *
+     *   CK_SSL3_RANDOM_DATA RandomInfo;
+     * 
+ */ + public CK_SSL3_RANDOM_DATA RandomInfo; + + /** + * PKCS#11: + *
+     *   CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+     * 
+ */ + public CK_SSL3_KEY_MAT_OUT pReturnedKeyMaterial; + + /** + * PKCS#11: + *
+     *   CK_MECHANISM_TYPE prfHashMechanism;
+     * 
+ */ + public long prfHashMechanism; + + public CK_TLS12_KEY_MAT_PARAMS( + int macSize, int keySize, int ivSize, boolean export, + CK_SSL3_RANDOM_DATA random, long prfHashMechanism) { + ulMacSizeInBits = macSize; + ulKeySizeInBits = keySize; + ulIVSizeInBits = ivSize; + bIsExport = export; + RandomInfo = random; + pReturnedKeyMaterial = new CK_SSL3_KEY_MAT_OUT(); + if (ivSize != 0) { + int n = ivSize >> 3; + pReturnedKeyMaterial.pIVClient = new byte[n]; + pReturnedKeyMaterial.pIVServer = new byte[n]; + } + this.prfHashMechanism = prfHashMechanism; + } + + /** + * Returns the string representation of CK_TLS12_KEY_MAT_PARAMS. + * + * @return the string representation of CK_TLS12_KEY_MAT_PARAMS + */ + public String toString() { + StringBuilder buffer = new StringBuilder(); + + buffer.append(Constants.INDENT); + buffer.append("ulMacSizeInBits: "); + buffer.append(ulMacSizeInBits); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("ulKeySizeInBits: "); + buffer.append(ulKeySizeInBits); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("ulIVSizeInBits: "); + buffer.append(ulIVSizeInBits); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("bIsExport: "); + buffer.append(bIsExport); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("RandomInfo: "); + buffer.append(RandomInfo); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("pReturnedKeyMaterial: "); + buffer.append(pReturnedKeyMaterial); + buffer.append(Constants.NEWLINE); + + buffer.append(Constants.INDENT); + buffer.append("prfHashMechanism: "); + buffer.append(prfHashMechanism); + + return buffer.toString(); + } + +} diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_MASTER_KEY_DERIVE_PARAMS.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_MASTER_KEY_DERIVE_PARAMS.java new file mode 100644 --- /dev/null +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS12_MASTER_KEY_DERIVE_PARAMS.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.pkcs11.wrapper; + +/** + * CK_TLS12_MASTER_KEY_DERIVE_PARAMS from PKCS#11 v2.40. + */ +public class CK_TLS12_MASTER_KEY_DERIVE_PARAMS { + + /** + * PKCS#11: + *
+     *   CK_SSL3_RANDOM_DATA RandomInfo;
+     * 
+ */ + public CK_SSL3_RANDOM_DATA RandomInfo; + + /** + * PKCS#11: + *
+     *   CK_VERSION_PTR pVersion;
+     * 
+ */ + public CK_VERSION pVersion; + + /** + * PKCS#11: + *
+     *   CK_MECHANISM_TYPE prfHashMechanism;
+     * 
+ */ + public long prfHashMechanism; + + public CK_TLS12_MASTER_KEY_DERIVE_PARAMS( + CK_SSL3_RANDOM_DATA random, CK_VERSION version, + long prfHashMechanism) { + RandomInfo = random; + pVersion = version; + this.prfHashMechanism = prfHashMechanism; + } + +} diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS.java new file mode 100644 --- /dev/null +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.pkcs11.wrapper; + +/** + * CK_TLS_MAC_PARAMS from PKCS#11 v2.40. + */ +public class CK_TLS_MAC_PARAMS { + + /** + * PKCS#11: + *
+     *   CK_MECHANISM_TYPE prfMechanism;
+     * 
+ */ + public long prfMechanism; + + /** + * PKCS#11: + *
+     *   CK_ULONG ulMacLength;
+     * 
+ */ + public long ulMacLength; + + /** + * PKCS#11: + *
+     *   CK_ULONG ulServerOrClient;
+     * 
+ */ + public long ulServerOrClient; + + public CK_TLS_MAC_PARAMS(long prfMechanism, + long ulMacLength, long ulServerOrClient) { + this.prfMechanism = prfMechanism; + this.ulMacLength = ulMacLength; + this.ulServerOrClient = ulServerOrClient; + } + +} diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/Functions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -73,6 +73,9 @@ private static final Map mechIds = new HashMap(); + private static final Map hashMechIds = + new HashMap(); + // key types (CKK_*) private static final Map keyNames = new HashMap(); @@ -94,7 +97,6 @@ private static final Map objectClassIds = new HashMap(); - /** * For converting numbers to their hex presentation. */ @@ -444,6 +446,10 @@ return getId(objectClassIds, name); } + public static long getHashMechId(String name) { + return hashMechIds.get(name); + } + /** * Check the given arrays for equalitiy. This method considers both arrays as * equal, if both are null or both have the same length and @@ -589,6 +595,10 @@ addMapping(objectClassNames, objectClassIds, id, name); } + private static void addHashMech(long id, String name) { + hashMechIds.put(name, id); + } + static { addMech(CKM_RSA_PKCS_KEY_PAIR_GEN, "CKM_RSA_PKCS_KEY_PAIR_GEN"); addMech(CKM_RSA_PKCS, "CKM_RSA_PKCS"); @@ -719,6 +729,10 @@ addMech(CKM_TLS_PRF, "CKM_TLS_PRF"); addMech(CKM_SSL3_MD5_MAC, "CKM_SSL3_MD5_MAC"); addMech(CKM_SSL3_SHA1_MAC, "CKM_SSL3_SHA1_MAC"); + addMech(CKM_TLS12_MASTER_KEY_DERIVE, "CKM_TLS12_MASTER_KEY_DERIVE"); + addMech(CKM_TLS12_KEY_AND_MAC_DERIVE, "CKM_TLS12_KEY_AND_MAC_DERIVE"); + addMech(CKM_TLS12_MASTER_KEY_DERIVE_DH, "CKM_TLS12_MASTER_KEY_DERIVE_DH"); + addMech(CKM_TLS_MAC, "CKM_TLS_MAC"); addMech(CKM_MD5_KEY_DERIVATION, "CKM_MD5_KEY_DERIVATION"); addMech(CKM_MD2_KEY_DERIVATION, "CKM_MD2_KEY_DERIVATION"); addMech(CKM_SHA1_KEY_DERIVATION, "CKM_SHA1_KEY_DERIVATION"); @@ -794,6 +808,12 @@ addMech(PCKM_SECURERANDOM, "SecureRandom"); addMech(PCKM_KEYSTORE, "KeyStore"); + addHashMech(CKM_SHA_1, "SHA-1"); + addHashMech(CKM_SHA224, "SHA-224"); + addHashMech(CKM_SHA256, "SHA-256"); + addHashMech(CKM_SHA384, "SHA-384"); + addHashMech(CKM_SHA512, "SHA-512"); + addKeyType(CKK_RSA, "CKK_RSA"); addKeyType(CKK_DSA, "CKK_DSA"); addKeyType(CKK_DH, "CKK_DH"); diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java --- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java +++ openjdk/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -625,6 +625,14 @@ public static final long CKM_PKCS5_PBKD2 = 0x000003B0L; public static final long CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0L; + + /* CKM_TLS12_MASTER_KEY_DERIVE, CKM_TLS12_KEY_AND_MAC_DERIVE, + * CKM_TLS12_MASTER_KEY_DERIVE_DH and CKM_TLS_MAC are new for v2.40 */ + public static final long CKM_TLS12_MASTER_KEY_DERIVE = 0x000003E0L; + public static final long CKM_TLS12_KEY_AND_MAC_DERIVE = 0x000003E1L; + public static final long CKM_TLS12_MASTER_KEY_DERIVE_DH = 0x000003E2L; + public static final long CKM_TLS_MAC = 0x000003E4L; + public static final long CKM_KEY_WRAP_LYNKS = 0x00000400L; public static final long CKM_KEY_WRAP_SET_OAEP = 0x00000401L; diff --git openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c --- openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c +++ openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -457,67 +457,113 @@ return ckAttribute ; } -/* - * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a - * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure - * - * @param env - used to call JNI funktions to get the Java classes and objects - * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert - * @return - the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure - */ -CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam) -{ - // XXX don't return structs - // XXX prefetch class and field ids - jclass jSsl3MasterKeyDeriveParamsClass; - CK_SSL3_MASTER_KEY_DERIVE_PARAMS ckParam; +void masterKeyDeriveParamToCKMasterKeyDeriveParam(JNIEnv *env, jobject jParam, + jclass masterKeyDeriveParamClass, + CK_VERSION_PTR* cKMasterKeyDeriveParamVersion, + CK_SSL3_RANDOM_DATA* cKMasterKeyDeriveParamRandomInfo) { jfieldID fieldID; jclass jSsl3RandomDataClass; jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion; - memset(&ckParam, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS)); /* get RandomInfo */ - jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); - if (jSsl3MasterKeyDeriveParamsClass == NULL) { return ckParam; } - fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "RandomInfo", "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, masterKeyDeriveParamClass, "RandomInfo", + "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;"); + if (fieldID == NULL) { return; } jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID); /* get pClientRandom and ulClientRandomLength out of RandomInfo */ jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA); - if (jSsl3RandomDataClass == NULL) { return ckParam; } + if (jSsl3RandomDataClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID); /* get pServerRandom and ulServerRandomLength out of RandomInfo */ fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID); /* get pVersion */ - fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "pVersion", "Lsun/security/pkcs11/wrapper/CK_VERSION;"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, masterKeyDeriveParamClass, "pVersion", + "Lsun/security/pkcs11/wrapper/CK_VERSION;"); + if (fieldID == NULL) { return; } jVersion = (*env)->GetObjectField(env, jParam, fieldID); /* populate java values */ - ckParam.pVersion = jVersionToCKVersionPtr(env, jVersion); - if ((*env)->ExceptionCheck(env)) { return ckParam; } - jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen)); + *cKMasterKeyDeriveParamVersion = jVersionToCKVersionPtr(env, jVersion); + if ((*env)->ExceptionCheck(env)) { return; } + jByteArrayToCKByteArray(env, jRIClientRandom, + &(cKMasterKeyDeriveParamRandomInfo->pClientRandom), + &(cKMasterKeyDeriveParamRandomInfo->ulClientRandomLen)); if ((*env)->ExceptionCheck(env)) { - free(ckParam.pVersion); - return ckParam; + free(*cKMasterKeyDeriveParamVersion); + return; } - jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen)); + jByteArrayToCKByteArray(env, jRIServerRandom, + &(cKMasterKeyDeriveParamRandomInfo->pServerRandom), + &(cKMasterKeyDeriveParamRandomInfo->ulServerRandomLen)); if ((*env)->ExceptionCheck(env)) { - free(ckParam.pVersion); - free(ckParam.RandomInfo.pClientRandom); - return ckParam; + free(*cKMasterKeyDeriveParamVersion); + free(cKMasterKeyDeriveParamRandomInfo->pClientRandom); + return; } - - return ckParam ; } +/* + * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a + * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure + * + * @param env - used to call JNI functions to get the Java classes and objects + * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert + * @return - the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure + */ +CK_SSL3_MASTER_KEY_DERIVE_PARAMS +jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, + jobject jParam) +{ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS ckParam; + jclass jSsl3MasterKeyDeriveParamsClass; + memset(&ckParam, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS)); + jSsl3MasterKeyDeriveParamsClass = + (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); + if (jSsl3MasterKeyDeriveParamsClass == NULL) { return ckParam; } + masterKeyDeriveParamToCKMasterKeyDeriveParam(env, jParam, + jSsl3MasterKeyDeriveParamsClass, + &ckParam.pVersion, &ckParam.RandomInfo); + return ckParam; +} + +/* + * converts the Java CK_TLS12_MASTER_KEY_DERIVE_PARAMS object to a + * CK_TLS12_MASTER_KEY_DERIVE_PARAMS structure + * + * @param env - used to call JNI functions to get the Java classes and objects + * @param jParam - the Java CK_TLS12_MASTER_KEY_DERIVE_PARAMS object to convert + * @return - the new CK_TLS12_MASTER_KEY_DERIVE_PARAMS structure + */ +CK_TLS12_MASTER_KEY_DERIVE_PARAMS +jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParam(JNIEnv *env, + jobject jParam) +{ + CK_TLS12_MASTER_KEY_DERIVE_PARAMS ckParam; + jclass jTls12MasterKeyDeriveParamsClass; + jfieldID fieldID; + memset(&ckParam, 0, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS)); + jTls12MasterKeyDeriveParamsClass = + (*env)->FindClass(env, CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS); + if (jTls12MasterKeyDeriveParamsClass == NULL) { return ckParam; } + masterKeyDeriveParamToCKMasterKeyDeriveParam(env, jParam, + jTls12MasterKeyDeriveParamsClass, &ckParam.pVersion, + &ckParam.RandomInfo); + fieldID = (*env)->GetFieldID(env, + jTls12MasterKeyDeriveParamsClass, "prfHashMechanism", "J"); + if (fieldID != NULL) { + jlong prfHashMechanism = + (*env)->GetLongField(env, jParam, fieldID); + ckParam.prfHashMechanism = (CK_MECHANISM_TYPE)prfHashMechanism; + } + return ckParam; +} /* * converts the Java CK_TLS_PRF_PARAMS object to a CK_TLS_PRF_PARAMS structure @@ -576,126 +622,220 @@ } /* - * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a CK_SSL3_KEY_MAT_PARAMS structure - * - * @param env - used to call JNI funktions to get the Java classes and objects - * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert - * @return - the new CK_SSL3_KEY_MAT_PARAMS structure + * converts the Java CK_TLS_MAC_PARAMS object to a CK_TLS_MAC_PARAMS structure */ -CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam) +CK_TLS_MAC_PARAMS jTlsMacParamsToCKTlsMacParam(JNIEnv *env, jobject jParam) { - // XXX don't return structs - // XXX prefetch class and field ids - jclass jSsl3KeyMatParamsClass, jSsl3RandomDataClass, jSsl3KeyMatOutClass; - CK_SSL3_KEY_MAT_PARAMS ckParam; + jclass jTlsMacParamsClass; + CK_TLS_MAC_PARAMS ckParam; + jfieldID fieldID; + jlong jPrfMechanism, jUlMacLength, jUlServerOrClient; + memset(&ckParam, 0, sizeof(CK_TLS_MAC_PARAMS)); + + jTlsMacParamsClass = (*env)->FindClass(env, CLASS_TLS_MAC_PARAMS); + if (jTlsMacParamsClass == NULL) { return ckParam; } + + /* get prfMechanism */ + fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "prfMechanism", "J"); + if (fieldID == NULL) { return ckParam; } + jPrfMechanism = (*env)->GetLongField(env, jParam, fieldID); + + /* get ulMacLength */ + fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "ulMacLength", "J"); + if (fieldID == NULL) { return ckParam; } + jUlMacLength = (*env)->GetLongField(env, jParam, fieldID); + + /* get ulServerOrClient */ + fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "ulServerOrClient", "J"); + if (fieldID == NULL) { return ckParam; } + jUlServerOrClient = (*env)->GetLongField(env, jParam, fieldID); + + /* populate java values */ + ckParam.prfMechanism = jLongToCKULong(jPrfMechanism); + ckParam.ulMacLength = jLongToCKULong(jUlMacLength); + ckParam.ulServerOrClient = jLongToCKULong(jUlServerOrClient); + + return ckParam; +} + +void keyMatParamToCKKeyMatParam(JNIEnv *env, jobject jParam, + jclass jKeyMatParamClass, + CK_ULONG* cKKeyMatParamUlMacSizeInBits, + CK_ULONG* cKKeyMatParamUlKeySizeInBits, + CK_ULONG* cKKeyMatParamUlIVSizeInBits, + CK_BBOOL* cKKeyMatParamBIsExport, + CK_SSL3_RANDOM_DATA* cKKeyMatParamRandomInfo, + CK_SSL3_KEY_MAT_OUT_PTR* cKKeyMatParamPReturnedKeyMaterial) +{ + jclass jSsl3RandomDataClass, jSsl3KeyMatOutClass; jfieldID fieldID; jlong jMacSizeInBits, jKeySizeInBits, jIVSizeInBits; jboolean jIsExport; jobject jRandomInfo, jRIClientRandom, jRIServerRandom; jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer; CK_ULONG ckTemp; - memset(&ckParam, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS)); /* get ulMacSizeInBits */ - jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS); - if (jSsl3KeyMatParamsClass == NULL) { return ckParam; } - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulMacSizeInBits", "J"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulMacSizeInBits", "J"); + if (fieldID == NULL) { return; } jMacSizeInBits = (*env)->GetLongField(env, jParam, fieldID); /* get ulKeySizeInBits */ - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulKeySizeInBits", "J"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulKeySizeInBits", "J"); + if (fieldID == NULL) { return; } jKeySizeInBits = (*env)->GetLongField(env, jParam, fieldID); /* get ulIVSizeInBits */ - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulIVSizeInBits", "J"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulIVSizeInBits", "J"); + if (fieldID == NULL) { return; } jIVSizeInBits = (*env)->GetLongField(env, jParam, fieldID); /* get bIsExport */ - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "bIsExport", "Z"); - if (fieldID == NULL) { return ckParam; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "bIsExport", "Z"); + if (fieldID == NULL) { return; } jIsExport = (*env)->GetBooleanField(env, jParam, fieldID); /* get RandomInfo */ jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA); - if (jSsl3RandomDataClass == NULL) { return ckParam; } - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "RandomInfo", "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;"); - if (fieldID == NULL) { return ckParam; } + if (jSsl3RandomDataClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "RandomInfo", + "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;"); + if (fieldID == NULL) { return; } jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID); /* get pClientRandom and ulClientRandomLength out of RandomInfo */ fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID); /* get pServerRandom and ulServerRandomLength out of RandomInfo */ fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID); /* get pReturnedKeyMaterial */ jSsl3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT); - if (jSsl3KeyMatOutClass == NULL) { return ckParam; } - fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "pReturnedKeyMaterial", "Lsun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT;"); - if (fieldID == NULL) { return ckParam; } + if (jSsl3KeyMatOutClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "pReturnedKeyMaterial", + "Lsun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT;"); + if (fieldID == NULL) { return; } jReturnedKeyMaterial = (*env)->GetObjectField(env, jParam, fieldID); /* get pIVClient out of pReturnedKeyMaterial */ fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVClient", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRMIvClient = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID); /* get pIVServer out of pReturnedKeyMaterial */ fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVServer", "[B"); - if (fieldID == NULL) { return ckParam; } + if (fieldID == NULL) { return; } jRMIvServer = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID); /* populate java values */ - ckParam.ulMacSizeInBits = jLongToCKULong(jMacSizeInBits); - ckParam.ulKeySizeInBits = jLongToCKULong(jKeySizeInBits); - ckParam.ulIVSizeInBits = jLongToCKULong(jIVSizeInBits); - ckParam.bIsExport = jBooleanToCKBBool(jIsExport); - jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen)); - if ((*env)->ExceptionCheck(env)) { return ckParam; } - jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen)); + *cKKeyMatParamUlMacSizeInBits = jLongToCKULong(jMacSizeInBits); + *cKKeyMatParamUlKeySizeInBits = jLongToCKULong(jKeySizeInBits); + *cKKeyMatParamUlIVSizeInBits = jLongToCKULong(jIVSizeInBits); + *cKKeyMatParamBIsExport = jBooleanToCKBBool(jIsExport); + jByteArrayToCKByteArray(env, jRIClientRandom, + &(cKKeyMatParamRandomInfo->pClientRandom), + &(cKKeyMatParamRandomInfo->ulClientRandomLen)); + if ((*env)->ExceptionCheck(env)) { return; } + jByteArrayToCKByteArray(env, jRIServerRandom, + &(cKKeyMatParamRandomInfo->pServerRandom), + &(cKKeyMatParamRandomInfo->ulServerRandomLen)); if ((*env)->ExceptionCheck(env)) { - free(ckParam.RandomInfo.pClientRandom); - return ckParam; + free(cKKeyMatParamRandomInfo->pClientRandom); + return; } /* allocate memory for pRetrunedKeyMaterial */ - ckParam.pReturnedKeyMaterial = (CK_SSL3_KEY_MAT_OUT_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_OUT)); - if (ckParam.pReturnedKeyMaterial == NULL) { - free(ckParam.RandomInfo.pClientRandom); - free(ckParam.RandomInfo.pServerRandom); + *cKKeyMatParamPReturnedKeyMaterial = + (CK_SSL3_KEY_MAT_OUT_PTR)malloc(sizeof(CK_SSL3_KEY_MAT_OUT)); + if (*cKKeyMatParamPReturnedKeyMaterial == NULL) { + free(cKKeyMatParamRandomInfo->pClientRandom); + free(cKKeyMatParamRandomInfo->pServerRandom); throwOutOfMemoryError(env, 0); - return ckParam; + return; } // the handles are output params only, no need to fetch them from Java - ckParam.pReturnedKeyMaterial->hClientMacSecret = 0; - ckParam.pReturnedKeyMaterial->hServerMacSecret = 0; - ckParam.pReturnedKeyMaterial->hClientKey = 0; - ckParam.pReturnedKeyMaterial->hServerKey = 0; + (*cKKeyMatParamPReturnedKeyMaterial)->hClientMacSecret = 0; + (*cKKeyMatParamPReturnedKeyMaterial)->hServerMacSecret = 0; + (*cKKeyMatParamPReturnedKeyMaterial)->hClientKey = 0; + (*cKKeyMatParamPReturnedKeyMaterial)->hServerKey = 0; - jByteArrayToCKByteArray(env, jRMIvClient, &(ckParam.pReturnedKeyMaterial->pIVClient), &ckTemp); + jByteArrayToCKByteArray(env, jRMIvClient, + &((*cKKeyMatParamPReturnedKeyMaterial)->pIVClient), &ckTemp); if ((*env)->ExceptionCheck(env)) { - free(ckParam.RandomInfo.pClientRandom); - free(ckParam.RandomInfo.pServerRandom); - free(ckParam.pReturnedKeyMaterial); - return ckParam; + free(cKKeyMatParamRandomInfo->pClientRandom); + free(cKKeyMatParamRandomInfo->pServerRandom); + free((*cKKeyMatParamPReturnedKeyMaterial)); + return; } - jByteArrayToCKByteArray(env, jRMIvServer, &(ckParam.pReturnedKeyMaterial->pIVServer), &ckTemp); + jByteArrayToCKByteArray(env, jRMIvServer, + &((*cKKeyMatParamPReturnedKeyMaterial)->pIVServer), &ckTemp); if ((*env)->ExceptionCheck(env)) { - free(ckParam.RandomInfo.pClientRandom); - free(ckParam.RandomInfo.pServerRandom); - free(ckParam.pReturnedKeyMaterial->pIVClient); - free(ckParam.pReturnedKeyMaterial); - return ckParam; + free(cKKeyMatParamRandomInfo->pClientRandom); + free(cKKeyMatParamRandomInfo->pServerRandom); + free((*cKKeyMatParamPReturnedKeyMaterial)->pIVClient); + free((*cKKeyMatParamPReturnedKeyMaterial)); + return; } - return ckParam ; + return; +} +/* + * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a + * CK_SSL3_KEY_MAT_PARAMS structure + * + * @param env - used to call JNI funktions to get the Java classes and objects + * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert + * @return - the new CK_SSL3_KEY_MAT_PARAMS structure + */ +CK_SSL3_KEY_MAT_PARAMS +jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam) +{ + CK_SSL3_KEY_MAT_PARAMS ckParam; + jclass jSsl3KeyMatParamsClass; + memset(&ckParam, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS)); + jSsl3KeyMatParamsClass = (*env)->FindClass(env, + CLASS_SSL3_KEY_MAT_PARAMS); + if (jSsl3KeyMatParamsClass == NULL) { return ckParam; } + keyMatParamToCKKeyMatParam(env, jParam, jSsl3KeyMatParamsClass, + &ckParam.ulMacSizeInBits, &ckParam.ulKeySizeInBits, + &ckParam.ulIVSizeInBits, &ckParam.bIsExport, + &ckParam.RandomInfo, &ckParam.pReturnedKeyMaterial); + return ckParam; +} + +/* + * converts the Java CK_TLS12_KEY_MAT_PARAMS object to a + * CK_TLS12_KEY_MAT_PARAMS structure + * + * @param env - used to call JNI functions to get the Java classes and objects + * @param jParam - the Java CK_TLS12_KEY_MAT_PARAMS object to convert + * @return - the new CK_TLS12_KEY_MAT_PARAMS structure + */ +CK_TLS12_KEY_MAT_PARAMS jTls12KeyMatParamToCKTls12KeyMatParam(JNIEnv *env, + jobject jParam) +{ + CK_TLS12_KEY_MAT_PARAMS ckParam; + jclass jTls12KeyMatParamsClass; + jfieldID fieldID; + memset(&ckParam, 0, sizeof(CK_TLS12_KEY_MAT_PARAMS)); + jTls12KeyMatParamsClass = (*env)->FindClass(env, + CLASS_TLS12_KEY_MAT_PARAMS); + if (jTls12KeyMatParamsClass == NULL) { return ckParam; } + keyMatParamToCKKeyMatParam(env, jParam, jTls12KeyMatParamsClass, + &ckParam.ulMacSizeInBits, &ckParam.ulKeySizeInBits, + &ckParam.ulIVSizeInBits, &ckParam.bIsExport, + &ckParam.RandomInfo, &ckParam.pReturnedKeyMaterial); + fieldID = (*env)->GetFieldID(env, jTls12KeyMatParamsClass, + "prfHashMechanism", "J"); + if (fieldID != NULL) { + jlong prfHashMechanism = (*env)->GetLongField(env, jParam, fieldID); + ckParam.prfHashMechanism = (CK_MECHANISM_TYPE)prfHashMechanism; + } + return ckParam; } /* @@ -980,8 +1120,11 @@ void jMechanismParameterToCKMechanismParameterSlow(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength) { /* get all Java mechanism parameter classes */ - jclass jVersionClass, jSsl3MasterKeyDeriveParamsClass, jSsl3KeyMatParamsClass; - jclass jTlsPrfParamsClass, jAesCtrParamsClass, jRsaPkcsOaepParamsClass; + jclass jVersionClass, jSsl3MasterKeyDeriveParamsClass; + jclass jTls12MasterKeyDeriveParamsClass, jSsl3KeyMatParamsClass; + jclass jTls12KeyMatParamsClass; + jclass jTlsPrfParamsClass, jTlsMacParamsClass, jAesCtrParamsClass; + jclass jRsaPkcsOaepParamsClass; jclass jPbeParamsClass, jPkcs5Pbkd2ParamsClass, jRsaPkcsPssParamsClass; jclass jEcdh1DeriveParamsClass, jEcdh2DeriveParamsClass; jclass jX942Dh1DeriveParamsClass, jX942Dh2DeriveParamsClass; @@ -1061,6 +1204,62 @@ return; } + jTls12KeyMatParamsClass = (*env)->FindClass(env, CLASS_TLS12_KEY_MAT_PARAMS); + if (jTls12KeyMatParamsClass == NULL) { return; } + if ((*env)->IsInstanceOf(env, jParam, jTls12KeyMatParamsClass)) { + /* + * CK_TLS12_KEY_MAT_PARAMS + */ + CK_TLS12_KEY_MAT_PARAMS_PTR ckpParam; + + ckpParam = (CK_TLS12_KEY_MAT_PARAMS_PTR) malloc(sizeof(CK_TLS12_KEY_MAT_PARAMS)); + if (ckpParam == NULL) { + throwOutOfMemoryError(env, 0); + return; + } + + /* convert jParameter to CKParameter */ + *ckpParam = jTls12KeyMatParamToCKTls12KeyMatParam(env, jParam); + if ((*env)->ExceptionCheck(env)) { + free(ckpParam); + return; + } + + /* get length and pointer of parameter */ + *ckpLength = sizeof(CK_TLS12_KEY_MAT_PARAMS); + *ckpParamPtr = ckpParam; + return; + } + + jTls12MasterKeyDeriveParamsClass = + (*env)->FindClass(env, CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS); + if (jTls12MasterKeyDeriveParamsClass == NULL) { return; } + if ((*env)->IsInstanceOf(env, jParam, jTls12MasterKeyDeriveParamsClass)) { + /* + * CK_TLS12_MASTER_KEY_DERIVE_PARAMS + */ + CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR ckpParam; + + ckpParam = (CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR)malloc( + sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS)); + if (ckpParam == NULL) { + throwOutOfMemoryError(env, 0); + return; + } + + /* convert jParameter to CKParameter */ + *ckpParam = jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParam(env, jParam); + if ((*env)->ExceptionCheck(env)) { + free(ckpParam); + return; + } + + /* get length and pointer of parameter */ + *ckpLength = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS); + *ckpParamPtr = ckpParam; + return; + } + jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS); if (jTlsPrfParamsClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jParam, jTlsPrfParamsClass)) { @@ -1088,6 +1287,30 @@ return; } + jTlsMacParamsClass = (*env)->FindClass(env, CLASS_TLS_MAC_PARAMS); + if (jTlsMacParamsClass == NULL) { return; } + if ((*env)->IsInstanceOf(env, jParam, jTlsMacParamsClass)) { + CK_TLS_MAC_PARAMS_PTR ckpParam; + + ckpParam = (CK_TLS_MAC_PARAMS_PTR) malloc(sizeof(CK_TLS_MAC_PARAMS)); + if (ckpParam == NULL) { + throwOutOfMemoryError(env, 0); + return; + } + + /* convert jParameter to CKParameter */ + *ckpParam = jTlsMacParamsToCKTlsMacParam(env, jParam); + if ((*env)->ExceptionCheck(env)) { + free(ckpParam); + return; + } + + /* get length and pointer of parameter */ + *ckpLength = sizeof(CK_TLS_MAC_PARAMS); + *ckpParamPtr = ckpParam; + return; + } + jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS); if (jAesCtrParamsClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jParam, jAesCtrParamsClass)) { diff --git openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c --- openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c +++ openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -355,25 +355,38 @@ #ifdef P11_ENABLE_C_DERIVEKEY -void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) { +static void freeMasterKeyDeriveParams(CK_SSL3_RANDOM_DATA *RandomInfo, CK_VERSION_PTR pVersion) { + if (RandomInfo->pClientRandom != NULL) { + free(RandomInfo->pClientRandom); + } + if (RandomInfo->pServerRandom != NULL) { + free(RandomInfo->pServerRandom); + } + if (pVersion != NULL) { + free(pVersion); + } +} + +void ssl3FreeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) { CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter; if (params == NULL) { return; } + freeMasterKeyDeriveParams(&(params->RandomInfo), params->pVersion); +} - if (params->RandomInfo.pClientRandom != NULL) { - free(params->RandomInfo.pClientRandom); +void tls12FreeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) { + CK_TLS12_MASTER_KEY_DERIVE_PARAMS *params = + (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)ckMechanism->pParameter; + if (params == NULL) { + return; } - if (params->RandomInfo.pServerRandom != NULL) { - free(params->RandomInfo.pServerRandom); - } - if (params->pVersion != NULL) { - free(params->pVersion); - } + freeMasterKeyDeriveParams(&(params->RandomInfo), params->pVersion); } void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) { - CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter; + CK_ECDH1_DERIVE_PARAMS *params = + (CK_ECDH1_DERIVE_PARAMS *)ckMechanism->pParameter; if (params == NULL) { return; } @@ -498,6 +511,7 @@ switch (ckMechanism.mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_TLS_KEY_AND_MAC_DERIVE: + case CKM_TLS12_KEY_AND_MAC_DERIVE: case CKM_TLS_PRF: // these mechanism do not return a key handle via phKey // set to NULL in case pedantic implementations check for it @@ -519,17 +533,28 @@ case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_TLS_MASTER_KEY_DERIVE: /* we must copy back the client version */ - copyBackClientVersion(env, &ckMechanism, jMechanism); - freeMasterKeyDeriveParams(&ckMechanism); + ssl3CopyBackClientVersion(env, &ckMechanism, jMechanism); + ssl3FreeMasterKeyDeriveParams(&ckMechanism); + break; + case CKM_TLS12_MASTER_KEY_DERIVE: + tls12CopyBackClientVersion(env, &ckMechanism, jMechanism); + tls12FreeMasterKeyDeriveParams(&ckMechanism); break; case CKM_SSL3_MASTER_KEY_DERIVE_DH: case CKM_TLS_MASTER_KEY_DERIVE_DH: - freeMasterKeyDeriveParams(&ckMechanism); + ssl3FreeMasterKeyDeriveParams(&ckMechanism); + break; + case CKM_TLS12_MASTER_KEY_DERIVE_DH: + tls12FreeMasterKeyDeriveParams(&ckMechanism); break; case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_TLS_KEY_AND_MAC_DERIVE: /* we must copy back the unwrapped key info to the jMechanism object */ - copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism); + ssl3CopyBackKeyMatParams(env, &ckMechanism, jMechanism); + break; + case CKM_TLS12_KEY_AND_MAC_DERIVE: + /* we must copy back the unwrapped key info to the jMechanism object */ + tls12CopyBackKeyMatParams(env, &ckMechanism, jMechanism); break; case CKM_TLS_PRF: copyBackTLSPrfParams(env, &ckMechanism, jMechanism); @@ -550,53 +575,42 @@ return jKeyHandle ; } -/* - * Copy back the client version information from the native - * structure to the Java object. This is only used for the - * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key. - * - */ -void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) +static void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism, + CK_VERSION *ckVersion, const char *class_master_key_derive_params) { - jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass; - CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams; - CK_VERSION *ckVersion; - jfieldID fieldID; - CK_MECHANISM_TYPE ckMechanismType; - jlong jMechanismType; - jobject jSSL3MasterKeyDeriveParams; - jobject jVersion; + jclass jMasterKeyDeriveParamsClass, jMechanismClass, jVersionClass; + jobject jMasterKeyDeriveParams; + jfieldID fieldID; + CK_MECHANISM_TYPE ckMechanismType; + jlong jMechanismType; + jobject jVersion; - /* get mechanism */ - jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM); - if (jMechanismClass == NULL) { return; } - fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); - if (fieldID == NULL) { return; } - jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); - ckMechanismType = jLongToCKULong(jMechanismType); - if (ckMechanismType != ckMechanism->mechanism) { - /* we do not have maching types, this should not occur */ - return; - } + /* get mechanism */ + jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM); + if (jMechanismClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); + if (fieldID == NULL) { return; } + jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); + ckMechanismType = jLongToCKULong(jMechanismType); + if (ckMechanismType != ckMechanism->mechanism) { + /* we do not have maching types, this should not occur */ + return; + } - /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */ - ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter; - if (ckSSL3MasterKeyDeriveParams != NULL_PTR) { - /* get the native CK_VERSION */ - ckVersion = ckSSL3MasterKeyDeriveParams->pVersion; if (ckVersion != NULL_PTR) { /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */ fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); if (fieldID == NULL) { return; } - jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID); + jMasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID); /* get the Java CK_VERSION */ - jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); - if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; } - fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";"); + jMasterKeyDeriveParamsClass = (*env)->FindClass(env, class_master_key_derive_params); + if (jMasterKeyDeriveParamsClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jMasterKeyDeriveParamsClass, + "pVersion", "L"CLASS_VERSION";"); if (fieldID == NULL) { return; } - jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID); + jVersion = (*env)->GetObjectField(env, jMasterKeyDeriveParams, fieldID); /* now copy back the version from the native structure to the Java structure */ @@ -612,92 +626,126 @@ if (fieldID == NULL) { return; } (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor)); } - } } +/* + * Copy back the client version information from the native + * structure to the Java object. This is only used for + * CKM_SSL3_MASTER_KEY_DERIVE and CKM_TLS_MASTER_KEY_DERIVE + * mechanisms when used for deriving a key. + * + */ +void ssl3CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, + jobject jMechanism) +{ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams; + ckSSL3MasterKeyDeriveParams = + (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)ckMechanism->pParameter; + if (ckSSL3MasterKeyDeriveParams != NULL_PTR) { + copyBackClientVersion(env, ckMechanism, jMechanism, + ckSSL3MasterKeyDeriveParams->pVersion, + CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); + } +} /* - * Copy back the derived keys and initialization vectors from the native - * structure to the Java object. This is only used for the - * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key. + * Copy back the client version information from the native + * structure to the Java object. This is only used for + * CKM_TLS12_MASTER_KEY_DERIVE mechanism when used for deriving a key. * */ -void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) +void tls12CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, + jobject jMechanism) { - jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass; - CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam; - CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut; - jfieldID fieldID; - CK_MECHANISM_TYPE ckMechanismType; - jlong jMechanismType; - CK_BYTE_PTR iv; - jobject jSSL3KeyMatParam; - jobject jSSL3KeyMatOut; - jobject jIV; - jint jLength; - jbyte* jBytes; - int i; + CK_TLS12_MASTER_KEY_DERIVE_PARAMS *ckTLS12MasterKeyDeriveParams; + ckTLS12MasterKeyDeriveParams = + (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)ckMechanism->pParameter; + if (ckTLS12MasterKeyDeriveParams != NULL_PTR) { + copyBackClientVersion(env, ckMechanism, jMechanism, + ckTLS12MasterKeyDeriveParams->pVersion, + CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS); + } +} - /* get mechanism */ - jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM); - if (jMechanismClass == NULL) { return; } - fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); - if (fieldID == NULL) { return; } - jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); - ckMechanismType = jLongToCKULong(jMechanismType); - if (ckMechanismType != ckMechanism->mechanism) { - /* we do not have maching types, this should not occur */ - return; - } +static void copyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, + jobject jMechanism, CK_SSL3_RANDOM_DATA *RandomInfo, + CK_SSL3_KEY_MAT_OUT_PTR ckSSL3KeyMatOut, const char *class_key_mat_params) +{ + jclass jMechanismClass, jKeyMatParamsClass, jSSL3KeyMatOutClass; + jfieldID fieldID; + CK_MECHANISM_TYPE ckMechanismType; + jlong jMechanismType; + CK_BYTE_PTR iv; + jobject jKeyMatParam; + jobject jSSL3KeyMatOut; + jobject jIV; + jint jLength; + jbyte* jBytes; + int i; - /* get the native CK_SSL3_KEY_MAT_PARAMS */ - ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter; - if (ckSSL3KeyMatParam != NULL_PTR) { - // free malloc'd data - if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) { - free(ckSSL3KeyMatParam->RandomInfo.pClientRandom); - } - if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) { - free(ckSSL3KeyMatParam->RandomInfo.pServerRandom); + /* get mechanism */ + jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM); + if (jMechanismClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); + if (fieldID == NULL) { return; } + jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); + ckMechanismType = jLongToCKULong(jMechanismType); + if (ckMechanismType != ckMechanism->mechanism) { + /* we do not have maching types, this should not occur */ + return; } - /* get the native CK_SSL3_KEY_MAT_OUT */ - ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial; + // free malloc'd data + if (RandomInfo->pClientRandom != NULL) { + free(RandomInfo->pClientRandom); + } + if (RandomInfo->pServerRandom != NULL) { + free(RandomInfo->pServerRandom); + } + if (ckSSL3KeyMatOut != NULL_PTR) { - /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */ - fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); + /* get the Java params object (pParameter) */ + fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", + "Ljava/lang/Object;"); if (fieldID == NULL) { return; } - jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID); + jKeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID); /* get the Java CK_SSL3_KEY_MAT_OUT */ - jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS); - if (jSSL3KeyMatParamsClass == NULL) { return; } - fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";"); + jKeyMatParamsClass = (*env)->FindClass(env, class_key_mat_params); + if (jKeyMatParamsClass == NULL) { return; } + fieldID = (*env)->GetFieldID(env, jKeyMatParamsClass, + "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";"); if (fieldID == NULL) { return; } - jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID); + jSSL3KeyMatOut = (*env)->GetObjectField(env, jKeyMatParam, fieldID); /* now copy back all the key handles and the initialization vectors */ /* copy back client MAC secret handle */ jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT); if (jSSL3KeyMatOutClass == NULL) { return; } - fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J"); + fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, + "hClientMacSecret", "J"); if (fieldID == NULL) { return; } - (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret)); + (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, + ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret)); /* copy back server MAC secret handle */ - fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J"); + fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, + "hServerMacSecret", "J"); if (fieldID == NULL) { return; } - (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret)); + (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, + ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret)); /* copy back client secret key handle */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J"); if (fieldID == NULL) { return; } - (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey)); + (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, + ckULongToJLong(ckSSL3KeyMatOut->hClientKey)); /* copy back server secret key handle */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J"); if (fieldID == NULL) { return; } - (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey)); + (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, + ckULongToJLong(ckSSL3KeyMatOut->hServerKey)); /* copy back the client IV */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B"); @@ -740,7 +788,45 @@ free(ckSSL3KeyMatOut->pIVServer); free(ckSSL3KeyMatOut); } - } +} + +/* + * Copy back the derived keys and initialization vectors from the native + * structure to the Java object. This is only used for + * CKM_SSL3_KEY_AND_MAC_DERIVE and CKM_TLS_KEY_AND_MAC_DERIVE mechanisms + * when used for deriving a key. + * + */ +void ssl3CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, + jobject jMechanism) +{ + CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam; + ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *)ckMechanism->pParameter; + if (ckSSL3KeyMatParam != NULL_PTR) { + copyBackKeyMatParams(env, ckMechanism, jMechanism, + &(ckSSL3KeyMatParam->RandomInfo), + ckSSL3KeyMatParam->pReturnedKeyMaterial, + CLASS_SSL3_KEY_MAT_PARAMS); + } +} + +/* + * Copy back the derived keys and initialization vectors from the native + * structure to the Java object. This is only used for + * CKM_TLS12_KEY_AND_MAC_DERIVE mechanism when used for deriving a key. + * + */ +void tls12CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, + jobject jMechanism) +{ + CK_TLS12_KEY_MAT_PARAMS *ckTLS12KeyMatParam; + ckTLS12KeyMatParam = (CK_TLS12_KEY_MAT_PARAMS *) ckMechanism->pParameter; + if (ckTLS12KeyMatParam != NULL_PTR) { + copyBackKeyMatParams(env, ckMechanism, jMechanism, + &(ckTLS12KeyMatParam->RandomInfo), + ckTLS12KeyMatParam->pReturnedKeyMaterial, + CLASS_TLS12_KEY_MAT_PARAMS); + } } #endif diff --git openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h --- openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h +++ openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h @@ -807,6 +807,12 @@ #define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4 #define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5 +/* new for v2.40 */ +#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0 +#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1 +#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2 +#define CKM_TLS_MAC 0x000003E4 + #define CKM_KEY_WRAP_LYNKS 0x00000400 #define CKM_KEY_WRAP_SET_OAEP 0x00000401 @@ -1682,4 +1688,34 @@ typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; +/* new for v2.40 */ + +typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; + CK_MECHANISM_TYPE prfHashMechanism; +} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; + +typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; + +typedef struct CK_TLS12_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + CK_MECHANISM_TYPE prfHashMechanism; +} CK_TLS12_KEY_MAT_PARAMS; + +typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; + +typedef struct CK_TLS_MAC_PARAMS { + CK_MECHANISM_TYPE prfMechanism; + CK_ULONG ulMacLength; + CK_ULONG ulServerOrClient; +} CK_TLS_MAC_PARAMS; + +typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; + #endif diff --git openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h --- openjdk.orig/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h +++ openjdk/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -268,10 +268,13 @@ #define CLASS_SSL3_RANDOM_DATA "sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA" // CLASS_SSL3_RANDOM_DATA is used by CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS #define CLASS_SSL3_KEY_MAT_OUT "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT" -// CLASS_SSL3_KEY_MAT_OUT is used by CLASS_SSL3_KEY_MAT_PARAMS +// CLASS_SSL3_KEY_MAT_OUT is used by CLASS_SSL3_KEY_MAT_PARAMS and CK_TLS12_KEY_MAT_PARAMS #define CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS" +#define CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_TLS12_MASTER_KEY_DERIVE_PARAMS" #define CLASS_SSL3_KEY_MAT_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS" +#define CLASS_TLS12_KEY_MAT_PARAMS "sun/security/pkcs11/wrapper/CK_TLS12_KEY_MAT_PARAMS" #define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS" +#define CLASS_TLS_MAC_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS" #define CLASS_AES_CTR_PARAMS "sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS" /* function to convert a PKCS#11 return value other than CK_OK into a Java Exception @@ -361,9 +364,11 @@ CK_KEY_WRAP_SET_OAEP_PARAMS jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv *env, jobject jParam); void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam); -void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); +void ssl3CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); +void tls12CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam); -void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); +void ssl3CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); +void tls12CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam); CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam); CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam); diff --git openjdk.orig/jdk/test/sun/security/pkcs11/fips/TestTLS12.java openjdk/jdk/test/sun/security/pkcs11/fips/TestTLS12.java new file mode 100644 --- /dev/null +++ openjdk/jdk/test/sun/security/pkcs11/fips/TestTLS12.java @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8029661 + * @summary Test TLS 1.2 + * @library .. + * @run main/othervm/timeout=120 TestTLS12 + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.ByteBuffer; + +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; + +import java.util.Arrays; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; + +import sun.security.internal.spec.TlsMasterSecretParameterSpec; +import sun.security.internal.spec.TlsPrfParameterSpec; +import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; + +public final class TestTLS12 extends SecmodTest { + + private static final boolean enableDebug = true; + + private static Provider sunPKCS11NSSProvider; + private static Provider sunJCEProvider; + private static com.sun.net.ssl.internal.ssl.Provider jsseProvider; + private static KeyStore ks; + private static KeyStore ts; + private static char[] passphrase = "JAHshj131@@".toCharArray(); + private static RSAPrivateKey privateKey; + private static RSAPublicKey publicKey; + + public static void main(String[] args) throws Exception { + try { + initialize(); + } catch (Exception e) { + System.out.println("Test skipped: failure during" + + " initialization"); + return; + } + + if (shouldRun()) { + // Test against JCE + testTlsAuthenticationCodeGeneration(); + + // Self-integrity test (complete TLS 1.2 communication) + new testTLS12SunPKCS11Communication().run(); + + System.out.println("Test PASS - OK"); + } else { + System.out.println("Test skipped: TLS 1.2 mechanisms" + + " not supported by current SunPKCS11 back-end"); + } + } + + private static boolean shouldRun() { + if (sunPKCS11NSSProvider == null) { + return false; + } + try { + KeyGenerator.getInstance("SunTls12MasterSecret", + sunPKCS11NSSProvider); + KeyGenerator.getInstance( + "SunTls12RsaPremasterSecret", sunPKCS11NSSProvider); + KeyGenerator.getInstance("SunTls12Prf", sunPKCS11NSSProvider); + } catch (NoSuchAlgorithmException e) { + return false; + } + return true; + } + + private static void testTlsAuthenticationCodeGeneration() + throws Exception { + // Generate RSA Pre-Master Secret in SunPKCS11 provider + SecretKey rsaPreMasterSecret = null; + @SuppressWarnings("deprecation") + TlsRsaPremasterSecretParameterSpec rsaPreMasterSecretSpec = + new TlsRsaPremasterSecretParameterSpec(0x0303, 0x0303); + { + KeyGenerator rsaPreMasterSecretKG = KeyGenerator.getInstance( + "SunTls12RsaPremasterSecret", sunPKCS11NSSProvider); + rsaPreMasterSecretKG.init(rsaPreMasterSecretSpec, null); + rsaPreMasterSecret = rsaPreMasterSecretKG.generateKey(); + } + + // Get RSA Pre-Master Secret in plain (from SunPKCS11 provider) + byte[] rsaPlainPreMasterSecret = null; + { + Cipher rsaPreMasterSecretWrapperCipher = + Cipher.getInstance("RSA/ECB/PKCS1Padding", + sunPKCS11NSSProvider); + rsaPreMasterSecretWrapperCipher.init(Cipher.WRAP_MODE, publicKey, + new SecureRandom()); + byte[] rsaEncryptedPreMasterSecret = + rsaPreMasterSecretWrapperCipher.wrap(rsaPreMasterSecret); + Cipher rsaPreMasterSecretUnwrapperCipher = + Cipher.getInstance("RSA/ECB/PKCS1Padding", sunJCEProvider); + rsaPreMasterSecretUnwrapperCipher.init(Cipher.UNWRAP_MODE, + privateKey, rsaPreMasterSecretSpec); + rsaPlainPreMasterSecret = rsaPreMasterSecretUnwrapperCipher.unwrap( + rsaEncryptedPreMasterSecret, "TlsRsaPremasterSecret", + Cipher.SECRET_KEY).getEncoded(); + + if (enableDebug) { + System.out.println("rsaPlainPreMasterSecret:"); + for (byte b : rsaPlainPreMasterSecret) { + System.out.printf("%02X, ", b); + } + System.out.println(""); + } + } + + // Generate Master Secret + SecretKey sunPKCS11MasterSecret = null; + SecretKey jceMasterSecret = null; + { + KeyGenerator sunPKCS11MasterSecretGenerator = + KeyGenerator.getInstance("SunTls12MasterSecret", + sunPKCS11NSSProvider); + KeyGenerator jceMasterSecretGenerator = KeyGenerator.getInstance( + "SunTls12MasterSecret", sunJCEProvider); + @SuppressWarnings("deprecation") + TlsMasterSecretParameterSpec sunPKCS11MasterSecretSpec = + new TlsMasterSecretParameterSpec(rsaPreMasterSecret, 3, 3, + new byte[32], new byte[32], "SHA-256", 32, 64); + @SuppressWarnings("deprecation") + TlsMasterSecretParameterSpec jceMasterSecretSpec = + new TlsMasterSecretParameterSpec( + new SecretKeySpec(rsaPlainPreMasterSecret, + "Generic"), 3, 3, new byte[32], + new byte[32], "SHA-256", 32, 64); + sunPKCS11MasterSecretGenerator.init(sunPKCS11MasterSecretSpec, + null); + jceMasterSecretGenerator.init(jceMasterSecretSpec, null); + sunPKCS11MasterSecret = + sunPKCS11MasterSecretGenerator.generateKey(); + jceMasterSecret = jceMasterSecretGenerator.generateKey(); + if (enableDebug) { + System.out.println("Master Secret (SunJCE):"); + if (jceMasterSecret != null) { + for (byte b : jceMasterSecret.getEncoded()) { + System.out.printf("%02X, ", b); + } + System.out.println(""); + } + } + } + + // Generate authentication codes + byte[] sunPKCS11AuthenticationCode = null; + byte[] jceAuthenticationCode = null; + { + // Generate SunPKCS11 authentication code + { + @SuppressWarnings("deprecation") + TlsPrfParameterSpec sunPKCS11AuthenticationCodeSpec = + new TlsPrfParameterSpec(sunPKCS11MasterSecret, + "client finished", "a".getBytes(), 12, + "SHA-256", 32, 64); + KeyGenerator sunPKCS11AuthCodeGenerator = + KeyGenerator.getInstance("SunTls12Prf", + sunPKCS11NSSProvider); + sunPKCS11AuthCodeGenerator.init( + sunPKCS11AuthenticationCodeSpec); + sunPKCS11AuthenticationCode = + sunPKCS11AuthCodeGenerator.generateKey().getEncoded(); + } + + // Generate SunJCE authentication code + { + @SuppressWarnings("deprecation") + TlsPrfParameterSpec jceAuthenticationCodeSpec = + new TlsPrfParameterSpec(jceMasterSecret, + "client finished", "a".getBytes(), 12, + "SHA-256", 32, 64); + KeyGenerator jceAuthCodeGenerator = + KeyGenerator.getInstance("SunTls12Prf", + sunJCEProvider); + jceAuthCodeGenerator.init(jceAuthenticationCodeSpec); + jceAuthenticationCode = + jceAuthCodeGenerator.generateKey().getEncoded(); + } + + if (enableDebug) { + System.out.println("SunPKCS11 Authentication Code: "); + for (byte b : sunPKCS11AuthenticationCode) { + System.out.printf("%02X, ", b); + } + System.out.println(""); + System.out.println("SunJCE Authentication Code: "); + for (byte b : jceAuthenticationCode) { + System.out.printf("%02X, ", b); + } + System.out.println(""); + } + } + + if (sunPKCS11AuthenticationCode == null || + jceAuthenticationCode == null || + sunPKCS11AuthenticationCode.length == 0 || + jceAuthenticationCode.length == 0 || + !Arrays.equals(sunPKCS11AuthenticationCode, + jceAuthenticationCode)) { + throw new Exception("Authentication codes from JCE" + + " and SunPKCS11 differ."); + } + } + + private static class testTLS12SunPKCS11Communication { + public static void run() throws Exception { + SSLEngine[][] enginesToTest = getSSLEnginesToTest(); + + for (SSLEngine[] engineToTest : enginesToTest) { + + SSLEngine clientSSLEngine = engineToTest[0]; + SSLEngine serverSSLEngine = engineToTest[1]; + + // SSLEngine code based on RedhandshakeFinished.java + + boolean dataDone = false; + + ByteBuffer clientOut = null; + ByteBuffer clientIn = null; + ByteBuffer serverOut = null; + ByteBuffer serverIn = null; + ByteBuffer cTOs; + ByteBuffer sTOc; + + SSLSession session = clientSSLEngine.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + clientIn = ByteBuffer.allocate(appBufferMax + 50); + serverIn = ByteBuffer.allocate(appBufferMax + 50); + + cTOs = ByteBuffer.allocateDirect(netBufferMax); + sTOc = ByteBuffer.allocateDirect(netBufferMax); + + clientOut = ByteBuffer.wrap( + "Hi Server, I'm Client".getBytes()); + serverOut = ByteBuffer.wrap( + "Hello Client, I'm Server".getBytes()); + + SSLEngineResult clientResult; + SSLEngineResult serverResult; + + while (!dataDone) { + clientResult = clientSSLEngine.wrap(clientOut, cTOs); + runDelegatedTasks(clientResult, clientSSLEngine); + serverResult = serverSSLEngine.wrap(serverOut, sTOc); + runDelegatedTasks(serverResult, serverSSLEngine); + cTOs.flip(); + sTOc.flip(); + + if (enableDebug) { + System.out.println("Client -> Network"); + printTlsNetworkPacket("", cTOs); + System.out.println(""); + System.out.println("Server -> Network"); + printTlsNetworkPacket("", sTOc); + System.out.println(""); + } + + clientResult = clientSSLEngine.unwrap(sTOc, clientIn); + runDelegatedTasks(clientResult, clientSSLEngine); + serverResult = serverSSLEngine.unwrap(cTOs, serverIn); + runDelegatedTasks(serverResult, serverSSLEngine); + + cTOs.compact(); + sTOc.compact(); + + if (!dataDone && + (clientOut.limit() == serverIn.position()) && + (serverOut.limit() == clientIn.position())) { + checkTransfer(serverOut, clientIn); + checkTransfer(clientOut, serverIn); + dataDone = true; + } + } + } + } + + static void printTlsNetworkPacket(String prefix, ByteBuffer bb) { + ByteBuffer slice = bb.slice(); + byte[] buffer = new byte[slice.remaining()]; + slice.get(buffer); + for (int i = 0; i < buffer.length; i++) { + System.out.printf("%02X, ", (byte)(buffer[i] & (byte)0xFF)); + if (i % 8 == 0 && i % 16 != 0) { + System.out.print(" "); + } + if (i % 16 == 0) { + System.out.println(""); + } + } + System.out.flush(); + } + + private static void checkTransfer(ByteBuffer a, ByteBuffer b) + throws Exception { + a.flip(); + b.flip(); + if (!a.equals(b)) { + throw new Exception("Data didn't transfer cleanly"); + } + a.position(a.limit()); + b.position(b.limit()); + a.limit(a.capacity()); + b.limit(b.capacity()); + } + + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + } + } + + private static SSLEngine[][] getSSLEnginesToTest() throws Exception { + SSLEngine[][] enginesToTest = new SSLEngine[2][2]; + String[][] preferredSuites = new String[][]{ new String[] { + "TLS_RSA_WITH_AES_128_CBC_SHA256" + }, new String[] { + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" + }}; + for (int i = 0; i < enginesToTest.length; i++) { + enginesToTest[i][0] = createSSLEngine(true); + enginesToTest[i][1] = createSSLEngine(false); + enginesToTest[i][0].setEnabledCipherSuites(preferredSuites[i]); + enginesToTest[i][1].setEnabledCipherSuites(preferredSuites[i]); + } + return enginesToTest; + } + + static private SSLEngine createSSLEngine(boolean client) + throws Exception { + SSLEngine ssle; + KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX", + jsseProvider); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", + jsseProvider); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance("TLSv1.2", + jsseProvider); + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ssle = sslCtx.createSSLEngine("localhost", 443); + ssle.setUseClientMode(client); + SSLParameters sslParameters = ssle.getSSLParameters(); + ssle.setSSLParameters(sslParameters); + + return ssle; + } + } + + private static void initialize() throws Exception { + if (initSecmod() == false) { + return; + } + String configName = BASE + SEP + "fips.cfg"; + sunPKCS11NSSProvider = getSunPKCS11(configName); + System.out.println("SunPKCS11 provider: " + sunPKCS11NSSProvider); + Security.addProvider(sunPKCS11NSSProvider); + + sunJCEProvider = new com.sun.crypto.provider.SunJCE(); + Security.addProvider(sunJCEProvider); + + Security.removeProvider("SunJSSE"); + jsseProvider =new com.sun.net.ssl.internal.ssl.Provider( + sunPKCS11NSSProvider); + Security.addProvider(jsseProvider); + System.out.println(jsseProvider.getInfo()); + + ks = KeyStore.getInstance("PKCS11", sunPKCS11NSSProvider); + ks.load(null, "test12".toCharArray()); + ts = ks; + + KeyStore ksPlain = readTestKeyStore(); + privateKey = (RSAPrivateKey)ksPlain.getKey("rh_rsa_sha256", + passphrase); + publicKey = (RSAPublicKey)ksPlain.getCertificate( + "rh_rsa_sha256").getPublicKey(); + } + + private static KeyStore readTestKeyStore() throws Exception { + File file = new File(System.getProperty("test.src", "."), "keystore"); + InputStream in = new FileInputStream(file); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(in, "passphrase".toCharArray()); + in.close(); + return ks; + } +} \ No newline at end of file