History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/pkcs11/P11SecretKeyFactory.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/pkcs11/P11SecretKeyFactory.java+358−0
@@ -0,0 +1,358 @@
1+/*
2+ * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.security.pkcs11;
27+
28+import java.util.*;
29+
30+import java.security.*;
31+import java.security.spec.*;
32+
33+import javax.crypto.*;
34+import javax.crypto.spec.*;
35+
36+import static sun.security.pkcs11.TemplateManager.*;
37+import sun.security.pkcs11.wrapper.*;
38+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
39+
40+/**
41+ * SecretKeyFactory implementation class. This class currently supports
42+ * DES, DESede, AES, ARCFOUR, and Blowfish.
43+ *
44+ * @author Andreas Sterbenz
45+ * @since 1.5
46+ */
47+final class P11SecretKeyFactory extends SecretKeyFactorySpi {
48+
49+ // token instance
50+ private final Token token;
51+
52+ // algorithm name
53+ private final String algorithm;
54+
55+ P11SecretKeyFactory(Token token, String algorithm) {
56+ super();
57+ this.token = token;
58+ this.algorithm = algorithm;
59+ }
60+
61+ private static final Map<String,Long> keyTypes;
62+
63+ static {
64+ keyTypes = new HashMap<String,Long>();
65+ addKeyType("RC4", CKK_RC4);
66+ addKeyType("ARCFOUR", CKK_RC4);
67+ addKeyType("DES", CKK_DES);
68+ addKeyType("DESede", CKK_DES3);
69+ addKeyType("AES", CKK_AES);
70+ addKeyType("Blowfish", CKK_BLOWFISH);
71+
72+ // we don't implement RC2 or IDEA, but we want to be able to generate
73+ // keys for those SSL/TLS ciphersuites.
74+ addKeyType("RC2", CKK_RC2);
75+ addKeyType("IDEA", CKK_IDEA);
76+
77+ addKeyType("TlsPremasterSecret", PCKK_TLSPREMASTER);
78+ addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER);
79+ addKeyType("TlsMasterSecret", PCKK_TLSMASTER);
80+ addKeyType("Generic", CKK_GENERIC_SECRET);
81+ }
82+
83+ private static void addKeyType(String name, long id) {
84+ Long l = Long.valueOf(id);
85+ keyTypes.put(name, l);
86+ keyTypes.put(name.toUpperCase(Locale.ENGLISH), l);
87+ }
88+
89+ static long getKeyType(String algorithm) {
90+ Long l = keyTypes.get(algorithm);
91+ if (l == null) {
92+ algorithm = algorithm.toUpperCase(Locale.ENGLISH);
93+ l = keyTypes.get(algorithm);
94+ if (l == null) {
95+ if (algorithm.startsWith("HMAC")) {
96+ return PCKK_HMAC;
97+ } else if (algorithm.startsWith("SSLMAC")) {
98+ return PCKK_SSLMAC;
99+ }
100+ }
101+ }
102+ return (l != null) ? l.longValue() : -1;
103+ }
104+
105+ /**
106+ * Convert an arbitrary key of algorithm into a P11Key of provider.
107+ * Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
108+ */
109+ static P11Key convertKey(Token token, Key key, String algo)
110+ throws InvalidKeyException {
111+ return convertKey(token, key, algo, null);
112+ }
113+
114+ /**
115+ * Convert an arbitrary key of algorithm w/ custom attributes into a
116+ * P11Key of provider.
117+ * Used in P11KeyStore.storeSkey.
118+ */
119+ static P11Key convertKey(Token token, Key key, String algo,
120+ CK_ATTRIBUTE[] extraAttrs)
121+ throws InvalidKeyException {
122+ token.ensureValid();
123+ if (key == null) {
124+ throw new InvalidKeyException("Key must not be null");
125+ }
126+ if (key instanceof SecretKey == false) {
127+ throw new InvalidKeyException("Key must be a SecretKey");
128+ }
129+ long algoType;
130+ if (algo == null) {
131+ algo = key.getAlgorithm();
132+ algoType = getKeyType(algo);
133+ } else {
134+ algoType = getKeyType(algo);
135+ long keyAlgorithmType = getKeyType(key.getAlgorithm());
136+ if (algoType != keyAlgorithmType) {
137+ if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
138+ // ignore key algorithm for MACs
139+ } else {
140+ throw new InvalidKeyException
141+ ("Key algorithm must be " + algo);
142+ }
143+ }
144+ }
145+ if (key instanceof P11Key) {
146+ P11Key p11Key = (P11Key)key;
147+ if (p11Key.token == token) {
148+ if (extraAttrs != null) {
149+ Session session = null;
150+ try {
151+ session = token.getObjSession();
152+ long newKeyID = token.p11.C_CopyObject(session.id(),
153+ p11Key.keyID, extraAttrs);
154+ p11Key = (P11Key) (P11Key.secretKey(session,
155+ newKeyID, p11Key.algorithm, p11Key.keyLength,
156+ extraAttrs));
157+ } catch (PKCS11Exception p11e) {
158+ throw new InvalidKeyException
159+ ("Cannot duplicate the PKCS11 key", p11e);
160+ } finally {
161+ token.releaseSession(session);
162+ }
163+ }
164+ return p11Key;
165+ }
166+ }
167+ P11Key p11Key = token.secretCache.get(key);
168+ if (p11Key != null) {
169+ return p11Key;
170+ }
171+ if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
172+ throw new InvalidKeyException("Encoded format must be RAW");
173+ }
174+ byte[] encoded = key.getEncoded();
175+ p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
176+ token.secretCache.put(key, p11Key);
177+ return p11Key;
178+ }
179+
180+ static void fixDESParity(byte[] key, int offset) {
181+ for (int i = 0; i < 8; i++) {
182+ int b = key[offset] & 0xfe;
183+ b |= (Integer.bitCount(b) & 1) ^ 1;
184+ key[offset++] = (byte)b;
185+ }
186+ }
187+
188+ private static P11Key createKey(Token token, byte[] encoded,
189+ String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
190+ throws InvalidKeyException {
191+ int n = encoded.length << 3;
192+ int keyLength = n;
193+ try {
194+ switch ((int)keyType) {
195+ case (int)CKK_DES:
196+ keyLength =
197+ P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
198+ fixDESParity(encoded, 0);
199+ break;
200+ case (int)CKK_DES3:
201+ keyLength =
202+ P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
203+ fixDESParity(encoded, 0);
204+ fixDESParity(encoded, 8);
205+ if (keyLength == 112) {
206+ keyType = CKK_DES2;
207+ } else {
208+ keyType = CKK_DES3;
209+ fixDESParity(encoded, 16);
210+ }
211+ break;
212+ case (int)CKK_AES:
213+ keyLength =
214+ P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
215+ break;
216+ case (int)CKK_RC4:
217+ keyLength =
218+ P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
219+ break;
220+ case (int)CKK_BLOWFISH:
221+ keyLength =
222+ P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
223+ token);
224+ break;
225+ case (int)CKK_GENERIC_SECRET:
226+ case (int)PCKK_TLSPREMASTER:
227+ case (int)PCKK_TLSRSAPREMASTER:
228+ case (int)PCKK_TLSMASTER:
229+ keyType = CKK_GENERIC_SECRET;
230+ break;
231+ case (int)PCKK_SSLMAC:
232+ case (int)PCKK_HMAC:
233+ if (n == 0) {
234+ throw new InvalidKeyException
235+ ("MAC keys must not be empty");
236+ }
237+ keyType = CKK_GENERIC_SECRET;
238+ break;
239+ default:
240+ throw new InvalidKeyException("Unknown algorithm " +
241+ algorithm);
242+ }
243+ } catch (InvalidAlgorithmParameterException iape) {
244+ throw new InvalidKeyException("Invalid key for " + algorithm,
245+ iape);
246+ } catch (ProviderException pe) {
247+ throw new InvalidKeyException("Could not create key", pe);
248+ }
249+ Session session = null;
250+ try {
251+ CK_ATTRIBUTE[] attributes;
252+ if (extraAttrs != null) {
253+ attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
254+ System.arraycopy(extraAttrs, 0, attributes, 3,
255+ extraAttrs.length);
256+ } else {
257+ attributes = new CK_ATTRIBUTE[3];
258+ }
259+ attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
260+ attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
261+ attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
262+ attributes = token.getAttributes
263+ (O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
264+ session = token.getObjSession();
265+ long keyID = token.p11.C_CreateObject(session.id(), attributes);
266+ P11Key p11Key = (P11Key)P11Key.secretKey
267+ (session, keyID, algorithm, keyLength, attributes);
268+ return p11Key;
269+ } catch (PKCS11Exception e) {
270+ throw new InvalidKeyException("Could not create key", e);
271+ } finally {
272+ token.releaseSession(session);
273+ }
274+ }
275+
276+ // see JCE spec
277+ protected SecretKey engineGenerateSecret(KeySpec keySpec)
278+ throws InvalidKeySpecException {
279+ token.ensureValid();
280+ if (keySpec == null) {
281+ throw new InvalidKeySpecException("KeySpec must not be null");
282+ }
283+ if (keySpec instanceof SecretKeySpec) {
284+ try {
285+ Key key = convertKey(token, (SecretKey)keySpec, algorithm);
286+ return (SecretKey)key;
287+ } catch (InvalidKeyException e) {
288+ throw new InvalidKeySpecException(e);
289+ }
290+ } else if (algorithm.equalsIgnoreCase("DES")) {
291+ if (keySpec instanceof DESKeySpec) {
292+ byte[] keyBytes = ((DESKeySpec)keySpec).getKey();
293+ keySpec = new SecretKeySpec(keyBytes, "DES");
294+ return engineGenerateSecret(keySpec);
295+ }
296+ } else if (algorithm.equalsIgnoreCase("DESede")) {
297+ if (keySpec instanceof DESedeKeySpec) {
298+ byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey();
299+ keySpec = new SecretKeySpec(keyBytes, "DESede");
300+ return engineGenerateSecret(keySpec);
301+ }
302+ }
303+ throw new InvalidKeySpecException
304+ ("Unsupported spec: " + keySpec.getClass().getName());
305+ }
306+
307+ private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
308+ try {
309+ key = engineTranslateKey(key);
310+ if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
311+ throw new InvalidKeySpecException
312+ ("Could not obtain key bytes");
313+ }
314+ byte[] k = key.getEncoded();
315+ return k;
316+ } catch (InvalidKeyException e) {
317+ throw new InvalidKeySpecException(e);
318+ }
319+ }
320+
321+ // see JCE spec
322+ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
323+ throws InvalidKeySpecException {
324+ token.ensureValid();
325+ if ((key == null) || (keySpec == null)) {
326+ throw new InvalidKeySpecException
327+ ("key and keySpec must not be null");
328+ }
329+ if (SecretKeySpec.class.isAssignableFrom(keySpec)) {
330+ return new SecretKeySpec(getKeyBytes(key), algorithm);
331+ } else if (algorithm.equalsIgnoreCase("DES")) {
332+ try {
333+ if (DESKeySpec.class.isAssignableFrom(keySpec)) {
334+ return new DESKeySpec(getKeyBytes(key));
335+ }
336+ } catch (InvalidKeyException e) {
337+ throw new InvalidKeySpecException(e);
338+ }
339+ } else if (algorithm.equalsIgnoreCase("DESede")) {
340+ try {
341+ if (DESedeKeySpec.class.isAssignableFrom(keySpec)) {
342+ return new DESedeKeySpec(getKeyBytes(key));
343+ }
344+ } catch (InvalidKeyException e) {
345+ throw new InvalidKeySpecException(e);
346+ }
347+ }
348+ throw new InvalidKeySpecException
349+ ("Unsupported spec: " + keySpec.getName());
350+ }
351+
352+ // see JCE spec
353+ protected SecretKey engineTranslateKey(SecretKey key)
354+ throws InvalidKeyException {
355+ return (SecretKey)convertKey(token, key, algorithm);
356+ }
357+
358+}