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/P11SecretKeyFactory.java
38919 views
1
/*
2
* Copyright (c) 2003, 2018, 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
P11Key newP11Key = null;
150
Session session = null;
151
long p11KeyID = p11Key.getKeyID();
152
try {
153
session = token.getObjSession();
154
long newKeyID = token.p11.C_CopyObject(session.id(),
155
p11KeyID, extraAttrs);
156
newP11Key = (P11Key) (P11Key.secretKey(session,
157
newKeyID, p11Key.algorithm, p11Key.keyLength,
158
extraAttrs));
159
} catch (PKCS11Exception p11e) {
160
throw new InvalidKeyException
161
("Cannot duplicate the PKCS11 key", p11e);
162
} finally {
163
p11Key.releaseKeyID();
164
token.releaseSession(session);
165
}
166
p11Key = newP11Key;
167
}
168
return p11Key;
169
}
170
}
171
P11Key p11Key = token.secretCache.get(key);
172
if (p11Key != null) {
173
return p11Key;
174
}
175
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
176
throw new InvalidKeyException("Encoded format must be RAW");
177
}
178
byte[] encoded = key.getEncoded();
179
p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
180
token.secretCache.put(key, p11Key);
181
return p11Key;
182
}
183
184
static void fixDESParity(byte[] key, int offset) {
185
for (int i = 0; i < 8; i++) {
186
int b = key[offset] & 0xfe;
187
b |= (Integer.bitCount(b) & 1) ^ 1;
188
key[offset++] = (byte)b;
189
}
190
}
191
192
private static P11Key createKey(Token token, byte[] encoded,
193
String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
194
throws InvalidKeyException {
195
int n = encoded.length << 3;
196
int keyLength = n;
197
try {
198
switch ((int)keyType) {
199
case (int)CKK_DES:
200
keyLength =
201
P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
202
fixDESParity(encoded, 0);
203
break;
204
case (int)CKK_DES3:
205
keyLength =
206
P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
207
fixDESParity(encoded, 0);
208
fixDESParity(encoded, 8);
209
if (keyLength == 112) {
210
keyType = CKK_DES2;
211
} else {
212
keyType = CKK_DES3;
213
fixDESParity(encoded, 16);
214
}
215
break;
216
case (int)CKK_AES:
217
keyLength =
218
P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
219
break;
220
case (int)CKK_RC4:
221
keyLength =
222
P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
223
break;
224
case (int)CKK_BLOWFISH:
225
keyLength =
226
P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
227
token);
228
break;
229
case (int)CKK_GENERIC_SECRET:
230
case (int)PCKK_TLSPREMASTER:
231
case (int)PCKK_TLSRSAPREMASTER:
232
case (int)PCKK_TLSMASTER:
233
keyType = CKK_GENERIC_SECRET;
234
break;
235
case (int)PCKK_SSLMAC:
236
case (int)PCKK_HMAC:
237
if (n == 0) {
238
throw new InvalidKeyException
239
("MAC keys must not be empty");
240
}
241
keyType = CKK_GENERIC_SECRET;
242
break;
243
default:
244
throw new InvalidKeyException("Unknown algorithm " +
245
algorithm);
246
}
247
} catch (InvalidAlgorithmParameterException iape) {
248
throw new InvalidKeyException("Invalid key for " + algorithm,
249
iape);
250
} catch (ProviderException pe) {
251
throw new InvalidKeyException("Could not create key", pe);
252
}
253
Session session = null;
254
try {
255
CK_ATTRIBUTE[] attributes;
256
if (extraAttrs != null) {
257
attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
258
System.arraycopy(extraAttrs, 0, attributes, 3,
259
extraAttrs.length);
260
} else {
261
attributes = new CK_ATTRIBUTE[3];
262
}
263
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
264
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
265
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
266
attributes = token.getAttributes
267
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
268
session = token.getObjSession();
269
long keyID = token.p11.C_CreateObject(session.id(), attributes);
270
P11Key p11Key = (P11Key)P11Key.secretKey
271
(session, keyID, algorithm, keyLength, attributes);
272
return p11Key;
273
} catch (PKCS11Exception e) {
274
throw new InvalidKeyException("Could not create key", e);
275
} finally {
276
token.releaseSession(session);
277
}
278
}
279
280
// see JCE spec
281
protected SecretKey engineGenerateSecret(KeySpec keySpec)
282
throws InvalidKeySpecException {
283
token.ensureValid();
284
if (keySpec == null) {
285
throw new InvalidKeySpecException("KeySpec must not be null");
286
}
287
if (keySpec instanceof SecretKeySpec) {
288
try {
289
Key key = convertKey(token, (SecretKey)keySpec, algorithm);
290
return (SecretKey)key;
291
} catch (InvalidKeyException e) {
292
throw new InvalidKeySpecException(e);
293
}
294
} else if (algorithm.equalsIgnoreCase("DES")) {
295
if (keySpec instanceof DESKeySpec) {
296
byte[] keyBytes = ((DESKeySpec)keySpec).getKey();
297
keySpec = new SecretKeySpec(keyBytes, "DES");
298
return engineGenerateSecret(keySpec);
299
}
300
} else if (algorithm.equalsIgnoreCase("DESede")) {
301
if (keySpec instanceof DESedeKeySpec) {
302
byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey();
303
keySpec = new SecretKeySpec(keyBytes, "DESede");
304
return engineGenerateSecret(keySpec);
305
}
306
}
307
throw new InvalidKeySpecException
308
("Unsupported spec: " + keySpec.getClass().getName());
309
}
310
311
private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
312
try {
313
key = engineTranslateKey(key);
314
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
315
throw new InvalidKeySpecException
316
("Could not obtain key bytes");
317
}
318
byte[] k = key.getEncoded();
319
return k;
320
} catch (InvalidKeyException e) {
321
throw new InvalidKeySpecException(e);
322
}
323
}
324
325
// see JCE spec
326
protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec)
327
throws InvalidKeySpecException {
328
token.ensureValid();
329
if ((key == null) || (keySpec == null)) {
330
throw new InvalidKeySpecException
331
("key and keySpec must not be null");
332
}
333
if (SecretKeySpec.class.isAssignableFrom(keySpec)) {
334
return new SecretKeySpec(getKeyBytes(key), algorithm);
335
} else if (algorithm.equalsIgnoreCase("DES")) {
336
try {
337
if (DESKeySpec.class.isAssignableFrom(keySpec)) {
338
return new DESKeySpec(getKeyBytes(key));
339
}
340
} catch (InvalidKeyException e) {
341
throw new InvalidKeySpecException(e);
342
}
343
} else if (algorithm.equalsIgnoreCase("DESede")) {
344
try {
345
if (DESedeKeySpec.class.isAssignableFrom(keySpec)) {
346
return new DESedeKeySpec(getKeyBytes(key));
347
}
348
} catch (InvalidKeyException e) {
349
throw new InvalidKeySpecException(e);
350
}
351
}
352
throw new InvalidKeySpecException
353
("Unsupported spec: " + keySpec.getName());
354
}
355
356
// see JCE spec
357
protected SecretKey engineTranslateKey(SecretKey key)
358
throws InvalidKeyException {
359
return (SecretKey)convertKey(token, key, algorithm);
360
}
361
362
}
363
364