--- old/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java 2017-01-18 23:06:48.023886645 -0800 +++ /dev/null 2017-01-18 09:30:05.425422781 -0800 @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2003, 2011, 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 - * 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; - -import java.util.*; - -import java.security.*; -import java.security.spec.*; - -import javax.crypto.*; -import javax.crypto.spec.*; - -import static sun.security.pkcs11.TemplateManager.*; -import sun.security.pkcs11.wrapper.*; -import static sun.security.pkcs11.wrapper.PKCS11Constants.*; - -/** - * SecretKeyFactory implementation class. This class currently supports - * DES, DESede, AES, ARCFOUR, and Blowfish. - * - * @author Andreas Sterbenz - * @since 1.5 - */ -final class P11SecretKeyFactory extends SecretKeyFactorySpi { - - // token instance - private final Token token; - - // algorithm name - private final String algorithm; - - P11SecretKeyFactory(Token token, String algorithm) { - super(); - this.token = token; - this.algorithm = algorithm; - } - - private static final Map keyTypes; - - static { - keyTypes = new HashMap(); - addKeyType("RC4", CKK_RC4); - addKeyType("ARCFOUR", CKK_RC4); - addKeyType("DES", CKK_DES); - addKeyType("DESede", CKK_DES3); - addKeyType("AES", CKK_AES); - addKeyType("Blowfish", CKK_BLOWFISH); - - // we don't implement RC2 or IDEA, but we want to be able to generate - // keys for those SSL/TLS ciphersuites. - addKeyType("RC2", CKK_RC2); - addKeyType("IDEA", CKK_IDEA); - - addKeyType("TlsPremasterSecret", PCKK_TLSPREMASTER); - addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER); - addKeyType("TlsMasterSecret", PCKK_TLSMASTER); - addKeyType("Generic", CKK_GENERIC_SECRET); - } - - private static void addKeyType(String name, long id) { - Long l = Long.valueOf(id); - keyTypes.put(name, l); - keyTypes.put(name.toUpperCase(Locale.ENGLISH), l); - } - - static long getKeyType(String algorithm) { - Long l = keyTypes.get(algorithm); - if (l == null) { - algorithm = algorithm.toUpperCase(Locale.ENGLISH); - l = keyTypes.get(algorithm); - if (l == null) { - if (algorithm.startsWith("HMAC")) { - return PCKK_HMAC; - } else if (algorithm.startsWith("SSLMAC")) { - return PCKK_SSLMAC; - } - } - } - return (l != null) ? l.longValue() : -1; - } - - /** - * Convert an arbitrary key of algorithm into a P11Key of provider. - * Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init(). - */ - static P11Key convertKey(Token token, Key key, String algo) - throws InvalidKeyException { - return convertKey(token, key, algo, null); - } - - /** - * Convert an arbitrary key of algorithm w/ custom attributes into a - * P11Key of provider. - * Used in P11KeyStore.storeSkey. - */ - static P11Key convertKey(Token token, Key key, String algo, - CK_ATTRIBUTE[] extraAttrs) - throws InvalidKeyException { - token.ensureValid(); - if (key == null) { - throw new InvalidKeyException("Key must not be null"); - } - if (key instanceof SecretKey == false) { - throw new InvalidKeyException("Key must be a SecretKey"); - } - long algoType; - if (algo == null) { - algo = key.getAlgorithm(); - algoType = getKeyType(algo); - } else { - algoType = getKeyType(algo); - long keyAlgorithmType = getKeyType(key.getAlgorithm()); - if (algoType != keyAlgorithmType) { - if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) { - // ignore key algorithm for MACs - } else { - throw new InvalidKeyException - ("Key algorithm must be " + algo); - } - } - } - if (key instanceof P11Key) { - P11Key p11Key = (P11Key)key; - if (p11Key.token == token) { - if (extraAttrs != null) { - Session session = null; - try { - session = token.getObjSession(); - long newKeyID = token.p11.C_CopyObject(session.id(), - p11Key.keyID, extraAttrs); - p11Key = (P11Key) (P11Key.secretKey(session, - newKeyID, p11Key.algorithm, p11Key.keyLength, - extraAttrs)); - } catch (PKCS11Exception p11e) { - throw new InvalidKeyException - ("Cannot duplicate the PKCS11 key", p11e); - } finally { - token.releaseSession(session); - } - } - return p11Key; - } - } - P11Key p11Key = token.secretCache.get(key); - if (p11Key != null) { - return p11Key; - } - if ("RAW".equalsIgnoreCase(key.getFormat()) == false) { - throw new InvalidKeyException("Encoded format must be RAW"); - } - byte[] encoded = key.getEncoded(); - p11Key = createKey(token, encoded, algo, algoType, extraAttrs); - token.secretCache.put(key, p11Key); - return p11Key; - } - - static void fixDESParity(byte[] key, int offset) { - for (int i = 0; i < 8; i++) { - int b = key[offset] & 0xfe; - b |= (Integer.bitCount(b) & 1) ^ 1; - key[offset++] = (byte)b; - } - } - - private static P11Key createKey(Token token, byte[] encoded, - String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs) - throws InvalidKeyException { - int n = encoded.length << 3; - int keyLength = n; - try { - switch ((int)keyType) { - case (int)CKK_DES: - keyLength = - P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token); - fixDESParity(encoded, 0); - break; - case (int)CKK_DES3: - keyLength = - P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token); - fixDESParity(encoded, 0); - fixDESParity(encoded, 8); - if (keyLength == 112) { - keyType = CKK_DES2; - } else { - keyType = CKK_DES3; - fixDESParity(encoded, 16); - } - break; - case (int)CKK_AES: - keyLength = - P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token); - break; - case (int)CKK_RC4: - keyLength = - P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token); - break; - case (int)CKK_BLOWFISH: - keyLength = - P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n, - token); - break; - case (int)CKK_GENERIC_SECRET: - case (int)PCKK_TLSPREMASTER: - case (int)PCKK_TLSRSAPREMASTER: - case (int)PCKK_TLSMASTER: - keyType = CKK_GENERIC_SECRET; - break; - case (int)PCKK_SSLMAC: - case (int)PCKK_HMAC: - if (n == 0) { - throw new InvalidKeyException - ("MAC keys must not be empty"); - } - keyType = CKK_GENERIC_SECRET; - break; - default: - throw new InvalidKeyException("Unknown algorithm " + - algorithm); - } - } catch (InvalidAlgorithmParameterException iape) { - throw new InvalidKeyException("Invalid key for " + algorithm, - iape); - } catch (ProviderException pe) { - throw new InvalidKeyException("Could not create key", pe); - } - Session session = null; - try { - CK_ATTRIBUTE[] attributes; - if (extraAttrs != null) { - attributes = new CK_ATTRIBUTE[3 + extraAttrs.length]; - System.arraycopy(extraAttrs, 0, attributes, 3, - extraAttrs.length); - } else { - attributes = new CK_ATTRIBUTE[3]; - } - attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY); - attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType); - attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded); - attributes = token.getAttributes - (O_IMPORT, CKO_SECRET_KEY, keyType, attributes); - session = token.getObjSession(); - long keyID = token.p11.C_CreateObject(session.id(), attributes); - P11Key p11Key = (P11Key)P11Key.secretKey - (session, keyID, algorithm, keyLength, attributes); - return p11Key; - } catch (PKCS11Exception e) { - throw new InvalidKeyException("Could not create key", e); - } finally { - token.releaseSession(session); - } - } - - // see JCE spec - protected SecretKey engineGenerateSecret(KeySpec keySpec) - throws InvalidKeySpecException { - token.ensureValid(); - if (keySpec == null) { - throw new InvalidKeySpecException("KeySpec must not be null"); - } - if (keySpec instanceof SecretKeySpec) { - try { - Key key = convertKey(token, (SecretKey)keySpec, algorithm); - return (SecretKey)key; - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); - } - } else if (algorithm.equalsIgnoreCase("DES")) { - if (keySpec instanceof DESKeySpec) { - byte[] keyBytes = ((DESKeySpec)keySpec).getKey(); - keySpec = new SecretKeySpec(keyBytes, "DES"); - return engineGenerateSecret(keySpec); - } - } else if (algorithm.equalsIgnoreCase("DESede")) { - if (keySpec instanceof DESedeKeySpec) { - byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey(); - keySpec = new SecretKeySpec(keyBytes, "DESede"); - return engineGenerateSecret(keySpec); - } - } - throw new InvalidKeySpecException - ("Unsupported spec: " + keySpec.getClass().getName()); - } - - private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException { - try { - key = engineTranslateKey(key); - if ("RAW".equalsIgnoreCase(key.getFormat()) == false) { - throw new InvalidKeySpecException - ("Could not obtain key bytes"); - } - byte[] k = key.getEncoded(); - return k; - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); - } - } - - // see JCE spec - protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) - throws InvalidKeySpecException { - token.ensureValid(); - if ((key == null) || (keySpec == null)) { - throw new InvalidKeySpecException - ("key and keySpec must not be null"); - } - if (SecretKeySpec.class.isAssignableFrom(keySpec)) { - return new SecretKeySpec(getKeyBytes(key), algorithm); - } else if (algorithm.equalsIgnoreCase("DES")) { - try { - if (DESKeySpec.class.isAssignableFrom(keySpec)) { - return new DESKeySpec(getKeyBytes(key)); - } - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); - } - } else if (algorithm.equalsIgnoreCase("DESede")) { - try { - if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { - return new DESedeKeySpec(getKeyBytes(key)); - } - } catch (InvalidKeyException e) { - throw new InvalidKeySpecException(e); - } - } - throw new InvalidKeySpecException - ("Unsupported spec: " + keySpec.getName()); - } - - // see JCE spec - protected SecretKey engineTranslateKey(SecretKey key) - throws InvalidKeyException { - return (SecretKey)convertKey(token, key, algorithm); - } - -}