Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11KeyGenerator.java
38919 views
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
}
285
286