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/P11KeyGenerator.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/pkcs11/P11KeyGenerator.java+284−0
@@ -0,0 +1,284 @@
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.security.*;
29+import java.security.spec.AlgorithmParameterSpec;
30+
31+import javax.crypto.*;
32+
33+import static sun.security.pkcs11.TemplateManager.*;
34+import sun.security.pkcs11.wrapper.*;
35+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
36+
37+/**
38+ * KeyGenerator implementation class. This class currently supports
39+ * DES, DESede, AES, ARCFOUR, and Blowfish.
40+ *
41+ * @author Andreas Sterbenz
42+ * @since 1.5
43+ */
44+final class P11KeyGenerator extends KeyGeneratorSpi {
45+
46+ // token instance
47+ private final Token token;
48+
49+ // algorithm name
50+ private final String algorithm;
51+
52+ // mechanism id
53+ private long mechanism;
54+
55+ // raw key size in bits, e.g. 64 for DES. Always valid.
56+ private int keySize;
57+
58+ // bits of entropy in the key, e.g. 56 for DES. Always valid.
59+ private int significantKeySize;
60+
61+ // keyType (CKK_*), needed for TemplateManager call only.
62+ private long keyType;
63+
64+ // for determining if both 112 and 168 bits of DESede key lengths
65+ // are supported.
66+ private boolean supportBothKeySizes;
67+
68+ /**
69+ * Utility method for checking if the specified key size is valid
70+ * and within the supported range. Return the significant key size
71+ * upon successful validation.
72+ * @param keyGenMech the PKCS#11 key generation mechanism.
73+ * @param keySize the to-be-checked key size for this mechanism.
74+ * @param token token which provides this mechanism.
75+ * @return the significant key size (in bits) corresponding to the
76+ * specified key size.
77+ * @throws InvalidParameterException if the specified key size is invalid.
78+ * @throws ProviderException if this mechanism isn't supported by SunPKCS11
79+ * or underlying native impl.
80+ */
81+ static int checkKeySize(long keyGenMech, int keySize, Token token)
82+ throws InvalidAlgorithmParameterException, ProviderException {
83+ int sigKeySize;
84+ switch ((int)keyGenMech) {
85+ case (int)CKM_DES_KEY_GEN:
86+ if ((keySize != 64) && (keySize != 56)) {
87+ throw new InvalidAlgorithmParameterException
88+ ("DES key length must be 56 bits");
89+ }
90+ sigKeySize = 56;
91+ break;
92+ case (int)CKM_DES2_KEY_GEN:
93+ case (int)CKM_DES3_KEY_GEN:
94+ if ((keySize == 112) || (keySize == 128)) {
95+ sigKeySize = 112;
96+ } else if ((keySize == 168) || (keySize == 192)) {
97+ sigKeySize = 168;
98+ } else {
99+ throw new InvalidAlgorithmParameterException
100+ ("DESede key length must be 112, or 168 bits");
101+ }
102+ break;
103+ default:
104+ // Handle all variable-key-length algorithms here
105+ CK_MECHANISM_INFO info = null;
106+ try {
107+ info = token.getMechanismInfo(keyGenMech);
108+ } catch (PKCS11Exception p11e) {
109+ // Should never happen
110+ throw new ProviderException
111+ ("Cannot retrieve mechanism info", p11e);
112+ }
113+ if (info == null) {
114+ // XXX Unable to retrieve the supported key length from
115+ // the underlying native impl. Skip the checking for now.
116+ return keySize;
117+ }
118+ // PKCS#11 defines these to be in number of bytes except for
119+ // RC4 which is in bits. However, some PKCS#11 impls still use
120+ // bytes for all mechs, e.g. NSS. We try to detect this
121+ // inconsistency if the minKeySize seems unreasonably small.
122+ int minKeySize = (int)info.ulMinKeySize;
123+ int maxKeySize = (int)info.ulMaxKeySize;
124+ if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
125+ minKeySize = (int)info.ulMinKeySize << 3;
126+ maxKeySize = (int)info.ulMaxKeySize << 3;
127+ }
128+ // Explicitly disallow keys shorter than 40-bits for security
129+ if (minKeySize < 40) minKeySize = 40;
130+ if (keySize < minKeySize || keySize > maxKeySize) {
131+ throw new InvalidAlgorithmParameterException
132+ ("Key length must be between " + minKeySize +
133+ " and " + maxKeySize + " bits");
134+ }
135+ if (keyGenMech == CKM_AES_KEY_GEN) {
136+ if ((keySize != 128) && (keySize != 192) &&
137+ (keySize != 256)) {
138+ throw new InvalidAlgorithmParameterException
139+ ("AES key length must be " + minKeySize +
140+ (maxKeySize >= 192? ", 192":"") +
141+ (maxKeySize >= 256? ", or 256":"") + " bits");
142+ }
143+ }
144+ sigKeySize = keySize;
145+ }
146+ return sigKeySize;
147+ }
148+
149+ P11KeyGenerator(Token token, String algorithm, long mechanism)
150+ throws PKCS11Exception {
151+ super();
152+ this.token = token;
153+ this.algorithm = algorithm;
154+ this.mechanism = mechanism;
155+
156+ if (this.mechanism == CKM_DES3_KEY_GEN) {
157+ /* Given the current lookup order specified in SunPKCS11.java,
158+ if CKM_DES2_KEY_GEN is used to construct this object, it
159+ means that CKM_DES3_KEY_GEN is disabled or unsupported.
160+ */
161+ supportBothKeySizes =
162+ (token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
163+ (token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
164+ }
165+ setDefaultKeySize();
166+ }
167+
168+ // set default keysize and also initialize keyType
169+ private void setDefaultKeySize() {
170+ switch ((int)mechanism) {
171+ case (int)CKM_DES_KEY_GEN:
172+ keySize = 64;
173+ keyType = CKK_DES;
174+ break;
175+ case (int)CKM_DES2_KEY_GEN:
176+ keySize = 128;
177+ keyType = CKK_DES2;
178+ break;
179+ case (int)CKM_DES3_KEY_GEN:
180+ keySize = 192;
181+ keyType = CKK_DES3;
182+ break;
183+ case (int)CKM_AES_KEY_GEN:
184+ keySize = 128;
185+ keyType = CKK_AES;
186+ break;
187+ case (int)CKM_RC4_KEY_GEN:
188+ keySize = 128;
189+ keyType = CKK_RC4;
190+ break;
191+ case (int)CKM_BLOWFISH_KEY_GEN:
192+ keySize = 128;
193+ keyType = CKK_BLOWFISH;
194+ break;
195+ default:
196+ throw new ProviderException("Unknown mechanism " + mechanism);
197+ }
198+ try {
199+ significantKeySize = checkKeySize(mechanism, keySize, token);
200+ } catch (InvalidAlgorithmParameterException iape) {
201+ throw new ProviderException("Unsupported default key size", iape);
202+ }
203+ }
204+
205+ // see JCE spec
206+ protected void engineInit(SecureRandom random) {
207+ token.ensureValid();
208+ setDefaultKeySize();
209+ }
210+
211+ // see JCE spec
212+ protected void engineInit(AlgorithmParameterSpec params,
213+ SecureRandom random) throws InvalidAlgorithmParameterException {
214+ throw new InvalidAlgorithmParameterException
215+ ("AlgorithmParameterSpec not supported");
216+ }
217+
218+ // see JCE spec
219+ protected void engineInit(int keySize, SecureRandom random) {
220+ token.ensureValid();
221+ int newSignificantKeySize;
222+ try {
223+ newSignificantKeySize = checkKeySize(mechanism, keySize, token);
224+ } catch (InvalidAlgorithmParameterException iape) {
225+ throw (InvalidParameterException)
226+ (new InvalidParameterException().initCause(iape));
227+ }
228+ if ((mechanism == CKM_DES2_KEY_GEN) ||
229+ (mechanism == CKM_DES3_KEY_GEN)) {
230+ long newMechanism = (newSignificantKeySize == 112 ?
231+ CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
232+ if (mechanism != newMechanism) {
233+ if (supportBothKeySizes) {
234+ mechanism = newMechanism;
235+ // Adjust keyType to reflect the mechanism change
236+ keyType = (mechanism == CKM_DES2_KEY_GEN ?
237+ CKK_DES2 : CKK_DES3);
238+ } else {
239+ throw new InvalidParameterException
240+ ("Only " + significantKeySize +
241+ "-bit DESede is supported");
242+ }
243+ }
244+ }
245+ this.keySize = keySize;
246+ this.significantKeySize = newSignificantKeySize;
247+ }
248+
249+ // see JCE spec
250+ protected SecretKey engineGenerateKey() {
251+ Session session = null;
252+ try {
253+ session = token.getObjSession();
254+ CK_ATTRIBUTE[] attributes;
255+ switch ((int)keyType) {
256+ case (int)CKK_DES:
257+ case (int)CKK_DES2:
258+ case (int)CKK_DES3:
259+ // fixed length, do not specify CKA_VALUE_LEN
260+ attributes = new CK_ATTRIBUTE[] {
261+ new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
262+ };
263+ break;
264+ default:
265+ attributes = new CK_ATTRIBUTE[] {
266+ new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
267+ new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3),
268+ };
269+ break;
270+ }
271+ attributes = token.getAttributes
272+ (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
273+ long keyID = token.p11.C_GenerateKey
274+ (session.id(), new CK_MECHANISM(mechanism), attributes);
275+ return P11Key.secretKey
276+ (session, keyID, algorithm, significantKeySize, attributes);
277+ } catch (PKCS11Exception e) {
278+ throw new ProviderException("Could not generate key", e);
279+ } finally {
280+ token.releaseSession(session);
281+ }
282+ }
283+
284+}