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/rsa/RSAKeyFactory.java
38830 views
1
/*
2
* Copyright (c) 2003, 2020, 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.rsa;
27
28
import java.math.BigInteger;
29
30
import java.security.*;
31
import java.security.interfaces.*;
32
import java.security.spec.*;
33
34
import sun.security.action.GetPropertyAction;
35
import sun.security.x509.AlgorithmId;
36
import static sun.security.rsa.RSAUtil.KeyType;
37
38
/**
39
* KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
40
* Keys must be instances of PublicKey or PrivateKey
41
* and getAlgorithm() must return a value which matches the type which are
42
* specified during construction time of the KeyFactory object.
43
* For such keys, it supports conversion
44
* between the following:
45
*
46
* For public keys:
47
* . PublicKey with an X.509 encoding
48
* . RSAPublicKey
49
* . RSAPublicKeySpec
50
* . X509EncodedKeySpec
51
*
52
* For private keys:
53
* . PrivateKey with a PKCS#8 encoding
54
* . RSAPrivateKey
55
* . RSAPrivateCrtKey
56
* . RSAPrivateKeySpec
57
* . RSAPrivateCrtKeySpec
58
* . PKCS8EncodedKeySpec
59
* (of course, CRT variants only for CRT keys)
60
*
61
* Note: as always, RSA keys should be at least 512 bits long
62
*
63
* @since 1.5
64
* @author Andreas Sterbenz
65
*/
66
public class RSAKeyFactory extends KeyFactorySpi {
67
68
private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class;
69
private static final Class<?> RSA_PRIV_KEYSPEC_CLS =
70
RSAPrivateKeySpec.class;
71
private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS =
72
RSAPrivateCrtKeySpec.class;
73
private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class;
74
private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class;
75
76
public final static int MIN_MODLEN = 512;
77
public final static int MAX_MODLEN = 16384;
78
79
private final KeyType type;
80
81
/*
82
* If the modulus length is above this value, restrict the size of
83
* the exponent to something that can be reasonably computed. We
84
* could simply hardcode the exp len to something like 64 bits, but
85
* this approach allows flexibility in case impls would like to use
86
* larger module and exponent values.
87
*/
88
public final static int MAX_MODLEN_RESTRICT_EXP = 3072;
89
public final static int MAX_RESTRICTED_EXPLEN = 64;
90
91
private static final boolean restrictExpLen =
92
"true".equalsIgnoreCase(AccessController.doPrivileged(
93
new GetPropertyAction(
94
"sun.security.rsa.restrictRSAExponent", "true")));
95
96
static RSAKeyFactory getInstance(KeyType type) {
97
return new RSAKeyFactory(type);
98
}
99
100
// Internal utility method for checking key algorithm
101
private static void checkKeyAlgo(Key key, String expectedAlg)
102
throws InvalidKeyException {
103
String keyAlg = key.getAlgorithm();
104
if (keyAlg == null || !(keyAlg.equalsIgnoreCase(expectedAlg))) {
105
throw new InvalidKeyException("Expected a " + expectedAlg
106
+ " key, but got " + keyAlg);
107
}
108
}
109
110
/**
111
* Static method to convert Key into an instance of RSAPublicKeyImpl
112
* or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
113
* used, throw an InvalidKeyException.
114
*
115
* Used by RSASignature and RSACipher.
116
*/
117
public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
118
if (key == null) {
119
throw new InvalidKeyException("Key must not be null");
120
}
121
if ((key instanceof RSAPrivateKeyImpl) ||
122
(key instanceof RSAPrivateCrtKeyImpl) ||
123
(key instanceof RSAPublicKeyImpl)) {
124
return (RSAKey)key;
125
} else {
126
try {
127
KeyType type = KeyType.lookup(key.getAlgorithm());
128
RSAKeyFactory kf = RSAKeyFactory.getInstance(type);
129
return (RSAKey) kf.engineTranslateKey(key);
130
} catch (ProviderException e) {
131
throw new InvalidKeyException(e);
132
}
133
}
134
}
135
136
/*
137
* Single test entry point for all of the mechanisms in the SunRsaSign
138
* provider (RSA*KeyImpls). All of the tests are the same.
139
*
140
* For compatibility, we round up to the nearest byte here:
141
* some Key impls might pass in a value within a byte of the
142
* real value.
143
*/
144
static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
145
throws InvalidKeyException {
146
checkKeyLengths(((modulusLen + 7) & ~7), exponent,
147
RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
148
}
149
150
/**
151
* Check the length of an RSA key modulus/exponent to make sure it
152
* is not too short or long. Some impls have their own min and
153
* max key sizes that may or may not match with a system defined value.
154
*
155
* @param modulusLen the bit length of the RSA modulus.
156
* @param exponent the RSA exponent
157
* @param minModulusLen if > 0, check to see if modulusLen is at
158
* least this long, otherwise unused.
159
* @param maxModulusLen caller will allow this max number of bits.
160
* Allow the smaller of the system-defined maximum and this param.
161
*
162
* @throws InvalidKeyException if any of the values are unacceptable.
163
*/
164
public static void checkKeyLengths(int modulusLen, BigInteger exponent,
165
int minModulusLen, int maxModulusLen) throws InvalidKeyException {
166
167
if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
168
throw new InvalidKeyException( "RSA keys must be at least " +
169
minModulusLen + " bits long");
170
}
171
172
// Even though our policy file may allow this, we don't want
173
// either value (mod/exp) to be too big.
174
175
int maxLen = Math.min(maxModulusLen, MAX_MODLEN);
176
177
// If a RSAPrivateKey/RSAPublicKey, make sure the
178
// modulus len isn't too big.
179
if (modulusLen > maxLen) {
180
throw new InvalidKeyException(
181
"RSA keys must be no longer than " + maxLen + " bits");
182
}
183
184
// If a RSAPublicKey, make sure the exponent isn't too big.
185
if (restrictExpLen && (exponent != null) &&
186
(modulusLen > MAX_MODLEN_RESTRICT_EXP) &&
187
(exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) {
188
throw new InvalidKeyException(
189
"RSA exponents can be no longer than " +
190
MAX_RESTRICTED_EXPLEN + " bits " +
191
" if modulus is greater than " +
192
MAX_MODLEN_RESTRICT_EXP + " bits");
193
}
194
}
195
196
// disallowed as KeyType is required
197
private RSAKeyFactory() {
198
this.type = KeyType.RSA;
199
}
200
201
public RSAKeyFactory(KeyType type) {
202
this.type = type;
203
}
204
205
/**
206
* Translate an RSA key into a SunRsaSign RSA key. If conversion is
207
* not possible, throw an InvalidKeyException.
208
* See also JCA doc.
209
*/
210
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
211
if (key == null) {
212
throw new InvalidKeyException("Key must not be null");
213
}
214
// ensure the key algorithm matches the current KeyFactory instance
215
checkKeyAlgo(key, type.keyAlgo());
216
217
// no translation needed if the key is already our own impl
218
if ((key instanceof RSAPrivateKeyImpl) ||
219
(key instanceof RSAPrivateCrtKeyImpl) ||
220
(key instanceof RSAPublicKeyImpl)) {
221
return key;
222
}
223
if (key instanceof PublicKey) {
224
return translatePublicKey((PublicKey)key);
225
} else if (key instanceof PrivateKey) {
226
return translatePrivateKey((PrivateKey)key);
227
} else {
228
throw new InvalidKeyException("Neither a public nor a private key");
229
}
230
}
231
232
// see JCA doc
233
protected PublicKey engineGeneratePublic(KeySpec keySpec)
234
throws InvalidKeySpecException {
235
try {
236
return generatePublic(keySpec);
237
} catch (InvalidKeySpecException e) {
238
throw e;
239
} catch (GeneralSecurityException e) {
240
throw new InvalidKeySpecException(e);
241
}
242
}
243
244
// see JCA doc
245
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
246
throws InvalidKeySpecException {
247
try {
248
return generatePrivate(keySpec);
249
} catch (InvalidKeySpecException e) {
250
throw e;
251
} catch (GeneralSecurityException e) {
252
throw new InvalidKeySpecException(e);
253
}
254
}
255
256
// internal implementation of translateKey() for public keys. See JCA doc
257
private PublicKey translatePublicKey(PublicKey key)
258
throws InvalidKeyException {
259
if (key instanceof RSAPublicKey) {
260
RSAPublicKey rsaKey = (RSAPublicKey)key;
261
try {
262
return new RSAPublicKeyImpl(
263
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
264
rsaKey.getModulus(),
265
rsaKey.getPublicExponent());
266
} catch (ProviderException e) {
267
// catch providers that incorrectly implement RSAPublicKey
268
throw new InvalidKeyException("Invalid key", e);
269
}
270
} else if ("X.509".equals(key.getFormat())) {
271
RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
272
// ensure the key algorithm matches the current KeyFactory instance
273
checkKeyAlgo(translated, type.keyAlgo());
274
return translated;
275
} else {
276
throw new InvalidKeyException("Public keys must be instance "
277
+ "of RSAPublicKey or have X.509 encoding");
278
}
279
}
280
281
// internal implementation of translateKey() for private keys. See JCA doc
282
private PrivateKey translatePrivateKey(PrivateKey key)
283
throws InvalidKeyException {
284
if (key instanceof RSAPrivateCrtKey) {
285
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
286
try {
287
return new RSAPrivateCrtKeyImpl(
288
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
289
rsaKey.getModulus(),
290
rsaKey.getPublicExponent(),
291
rsaKey.getPrivateExponent(),
292
rsaKey.getPrimeP(),
293
rsaKey.getPrimeQ(),
294
rsaKey.getPrimeExponentP(),
295
rsaKey.getPrimeExponentQ(),
296
rsaKey.getCrtCoefficient()
297
);
298
} catch (ProviderException e) {
299
// catch providers that incorrectly implement RSAPrivateCrtKey
300
throw new InvalidKeyException("Invalid key", e);
301
}
302
} else if (key instanceof RSAPrivateKey) {
303
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
304
try {
305
return new RSAPrivateKeyImpl(
306
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
307
rsaKey.getModulus(),
308
rsaKey.getPrivateExponent()
309
);
310
} catch (ProviderException e) {
311
// catch providers that incorrectly implement RSAPrivateKey
312
throw new InvalidKeyException("Invalid key", e);
313
}
314
} else if ("PKCS#8".equals(key.getFormat())) {
315
RSAPrivateKey translated =
316
RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
317
// ensure the key algorithm matches the current KeyFactory instance
318
checkKeyAlgo(translated, type.keyAlgo());
319
return translated;
320
} else {
321
throw new InvalidKeyException("Private keys must be instance "
322
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
323
}
324
}
325
326
// internal implementation of generatePublic. See JCA doc
327
private PublicKey generatePublic(KeySpec keySpec)
328
throws GeneralSecurityException {
329
if (keySpec instanceof X509EncodedKeySpec) {
330
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
331
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
332
// ensure the key algorithm matches the current KeyFactory instance
333
checkKeyAlgo(generated, type.keyAlgo());
334
return generated;
335
} else if (keySpec instanceof RSAPublicKeySpec) {
336
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
337
try {
338
return new RSAPublicKeyImpl(
339
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
340
rsaSpec.getModulus(),
341
rsaSpec.getPublicExponent()
342
);
343
} catch (ProviderException e) {
344
throw new InvalidKeySpecException(e);
345
}
346
} else {
347
throw new InvalidKeySpecException("Only RSAPublicKeySpec "
348
+ "and X509EncodedKeySpec supported for RSA public keys");
349
}
350
}
351
352
// internal implementation of generatePrivate. See JCA doc
353
private PrivateKey generatePrivate(KeySpec keySpec)
354
throws GeneralSecurityException {
355
if (keySpec instanceof PKCS8EncodedKeySpec) {
356
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
357
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
358
// ensure the key algorithm matches the current KeyFactory instance
359
checkKeyAlgo(generated, type.keyAlgo());
360
return generated;
361
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
362
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
363
try {
364
return new RSAPrivateCrtKeyImpl(
365
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
366
rsaSpec.getModulus(),
367
rsaSpec.getPublicExponent(),
368
rsaSpec.getPrivateExponent(),
369
rsaSpec.getPrimeP(),
370
rsaSpec.getPrimeQ(),
371
rsaSpec.getPrimeExponentP(),
372
rsaSpec.getPrimeExponentQ(),
373
rsaSpec.getCrtCoefficient()
374
);
375
} catch (ProviderException e) {
376
throw new InvalidKeySpecException(e);
377
}
378
} else if (keySpec instanceof RSAPrivateKeySpec) {
379
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
380
try {
381
return new RSAPrivateKeyImpl(
382
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
383
rsaSpec.getModulus(),
384
rsaSpec.getPrivateExponent()
385
);
386
} catch (ProviderException e) {
387
throw new InvalidKeySpecException(e);
388
}
389
} else {
390
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
391
+ "and PKCS8EncodedKeySpec supported for RSA private keys");
392
}
393
}
394
395
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
396
throws InvalidKeySpecException {
397
try {
398
// convert key to one of our keys
399
// this also verifies that the key is a valid RSA key and ensures
400
// that the encoding is X.509/PKCS#8 for public/private keys
401
key = engineTranslateKey(key);
402
} catch (InvalidKeyException e) {
403
throw new InvalidKeySpecException(e);
404
}
405
if (key instanceof RSAPublicKey) {
406
RSAPublicKey rsaKey = (RSAPublicKey)key;
407
if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
408
return keySpec.cast(new RSAPublicKeySpec(
409
rsaKey.getModulus(),
410
rsaKey.getPublicExponent(),
411
rsaKey.getParams()
412
));
413
} else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
414
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));
415
} else {
416
throw new InvalidKeySpecException
417
("KeySpec must be RSAPublicKeySpec or "
418
+ "X509EncodedKeySpec for RSA public keys");
419
}
420
} else if (key instanceof RSAPrivateKey) {
421
if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
422
return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));
423
} else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
424
if (key instanceof RSAPrivateCrtKey) {
425
RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key;
426
return keySpec.cast(new RSAPrivateCrtKeySpec(
427
crtKey.getModulus(),
428
crtKey.getPublicExponent(),
429
crtKey.getPrivateExponent(),
430
crtKey.getPrimeP(),
431
crtKey.getPrimeQ(),
432
crtKey.getPrimeExponentP(),
433
crtKey.getPrimeExponentQ(),
434
crtKey.getCrtCoefficient(),
435
crtKey.getParams()
436
));
437
} else {
438
throw new InvalidKeySpecException
439
("RSAPrivateCrtKeySpec can only be used with CRT keys");
440
}
441
} else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) {
442
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
443
return keySpec.cast(new RSAPrivateKeySpec(
444
rsaKey.getModulus(),
445
rsaKey.getPrivateExponent(),
446
rsaKey.getParams()
447
));
448
} else {
449
throw new InvalidKeySpecException
450
("KeySpec must be RSAPrivate(Crt)KeySpec or "
451
+ "PKCS8EncodedKeySpec for RSA private keys");
452
}
453
} else {
454
// should not occur, caught in engineTranslateKey()
455
throw new InvalidKeySpecException("Neither public nor private key");
456
}
457
}
458
459
public static final class Legacy extends RSAKeyFactory {
460
public Legacy() {
461
super(KeyType.RSA);
462
}
463
}
464
465
public static final class PSS extends RSAKeyFactory {
466
public PSS() {
467
super(KeyType.PSS);
468
}
469
}
470
}
471
472