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