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/RSAPrivateCrtKeyImpl.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.io.IOException;
29
import java.math.BigInteger;
30
31
import java.security.*;
32
import java.security.spec.*;
33
import java.security.interfaces.*;
34
import java.util.Arrays;
35
36
import sun.security.util.*;
37
38
import sun.security.pkcs.PKCS8Key;
39
40
import sun.security.rsa.RSAUtil.KeyType;
41
42
/**
43
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
44
* For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes
45
* to ensure correct behavior in instanceof checks, etc.
46
*
47
* Note: RSA keys must be at least 512 bits long
48
*
49
* @see RSAPrivateKeyImpl
50
* @see RSAKeyFactory
51
*
52
* @since 1.5
53
* @author Andreas Sterbenz
54
*/
55
public final class RSAPrivateCrtKeyImpl
56
extends PKCS8Key implements RSAPrivateCrtKey {
57
58
@java.io.Serial
59
private static final long serialVersionUID = -1326088454257084918L;
60
61
private BigInteger n; // modulus
62
private BigInteger e; // public exponent
63
private BigInteger d; // private exponent
64
private BigInteger p; // prime p
65
private BigInteger q; // prime q
66
private BigInteger pe; // prime exponent p
67
private BigInteger qe; // prime exponent q
68
private BigInteger coeff; // CRT coeffcient
69
70
private transient KeyType type;
71
72
// Optional parameters associated with this RSA key
73
// specified in the encoding of its AlgorithmId.
74
// Must be null for "RSA" keys.
75
private transient AlgorithmParameterSpec keyParams;
76
77
/**
78
* Generate a new RSAPrivate(Crt)Key from the specified type,
79
* format and encoding. Returns a CRT key if possible and a non-CRT
80
* key otherwise.
81
* Also used by SunPKCS11 provider.
82
*/
83
public static RSAPrivateKey newKey(KeyType type, String format,
84
byte[] encoded) throws InvalidKeyException {
85
if (encoded == null || encoded.length == 0) {
86
throw new InvalidKeyException("Missing key encoding");
87
}
88
switch (format) {
89
case "PKCS#8":
90
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
91
RSAKeyFactory.checkKeyAlgo(key, type.keyAlgo);
92
// check all CRT-specific components are available, if any one
93
// missing, return a non-CRT key instead
94
if ((key.getPublicExponent().signum() == 0) ||
95
(key.getPrimeExponentP().signum() == 0) ||
96
(key.getPrimeExponentQ().signum() == 0) ||
97
(key.getPrimeP().signum() == 0) ||
98
(key.getPrimeQ().signum() == 0) ||
99
(key.getCrtCoefficient().signum() == 0)) {
100
return new RSAPrivateKeyImpl(key.type, key.keyParams,
101
key.getModulus(), key.getPrivateExponent());
102
} else {
103
return key;
104
}
105
case "PKCS#1":
106
try {
107
BigInteger[] comps = parseASN1(encoded);
108
if ((comps[1].signum() == 0) || (comps[3].signum() == 0) ||
109
(comps[4].signum() == 0) || (comps[5].signum() == 0) ||
110
(comps[6].signum() == 0) || (comps[7].signum() == 0)) {
111
return new RSAPrivateKeyImpl(type, null, comps[0],
112
comps[2]);
113
} else {
114
return new RSAPrivateCrtKeyImpl(type, null, comps[0],
115
comps[1], comps[2], comps[3], comps[4], comps[5],
116
comps[6], comps[7]);
117
}
118
} catch (IOException ioe) {
119
throw new InvalidKeyException("Invalid PKCS#1 encoding", ioe);
120
}
121
default:
122
throw new InvalidKeyException("Unsupported RSA Private(Crt)Key "
123
+ "format: " + format);
124
}
125
}
126
127
/**
128
* Generate a new key from the specified type and components.
129
* Returns a CRT key if possible and a non-CRT key otherwise.
130
* Used by SunPKCS11 provider.
131
*/
132
public static RSAPrivateKey newKey(KeyType type,
133
AlgorithmParameterSpec params,
134
BigInteger n, BigInteger e, BigInteger d,
135
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
136
BigInteger coeff) throws InvalidKeyException {
137
RSAPrivateKey key;
138
if ((e.signum() == 0) || (p.signum() == 0) ||
139
(q.signum() == 0) || (pe.signum() == 0) ||
140
(qe.signum() == 0) || (coeff.signum() == 0)) {
141
// if any component is missing, return a non-CRT key
142
return new RSAPrivateKeyImpl(type, params, n, d);
143
} else {
144
return new RSAPrivateCrtKeyImpl(type, params, n, e, d,
145
p, q, pe, qe, coeff);
146
}
147
}
148
149
/**
150
* Construct a key from its encoding. Called from newKey above.
151
*/
152
private RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
153
super(encoded);
154
parseKeyBits();
155
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
156
try {
157
// check the validity of oid and params
158
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
159
this.type = (KeyType) o[0];
160
this.keyParams = (AlgorithmParameterSpec) o[1];
161
} catch (ProviderException e) {
162
throw new InvalidKeyException(e);
163
}
164
}
165
166
/**
167
* Construct a RSA key from its components. Used by the
168
* RSAKeyFactory and the RSAKeyPairGenerator.
169
*/
170
RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
171
BigInteger n, BigInteger e, BigInteger d,
172
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
173
BigInteger coeff) throws InvalidKeyException {
174
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
175
176
this.n = n;
177
this.e = e;
178
this.d = d;
179
this.p = p;
180
this.q = q;
181
this.pe = pe;
182
this.qe = qe;
183
this.coeff = coeff;
184
185
try {
186
// validate and generate the algid encoding
187
algid = RSAUtil.createAlgorithmId(type, keyParams);
188
} catch (ProviderException exc) {
189
throw new InvalidKeyException(exc);
190
}
191
192
this.type = type;
193
this.keyParams = keyParams;
194
195
try {
196
byte[][] nbytes = new byte[8][];
197
nbytes[0] = n.toByteArray();
198
nbytes[1] = e.toByteArray();
199
nbytes[2] = d.toByteArray();
200
nbytes[3] = p.toByteArray();
201
nbytes[4] = q.toByteArray();
202
nbytes[5] = pe.toByteArray();
203
nbytes[6] = qe.toByteArray();
204
nbytes[7] = coeff.toByteArray();
205
206
// Initiate with a big enough size so there's no need to
207
// reallocate memory later and thus can be cleaned up
208
// reliably.
209
DerOutputStream out = new DerOutputStream(
210
nbytes[0].length + nbytes[1].length +
211
nbytes[2].length + nbytes[3].length +
212
nbytes[4].length + nbytes[5].length +
213
nbytes[6].length + nbytes[7].length +
214
100); // Enough for version(3) and 8 tag+length(3 or 4)
215
out.putInteger(0); // version must be 0
216
out.putInteger(nbytes[0]);
217
out.putInteger(nbytes[1]);
218
out.putInteger(nbytes[2]);
219
out.putInteger(nbytes[3]);
220
out.putInteger(nbytes[4]);
221
out.putInteger(nbytes[5]);
222
out.putInteger(nbytes[6]);
223
out.putInteger(nbytes[7]);
224
// Private values from [2] on.
225
Arrays.fill(nbytes[2], (byte)0);
226
Arrays.fill(nbytes[3], (byte)0);
227
Arrays.fill(nbytes[4], (byte)0);
228
Arrays.fill(nbytes[5], (byte)0);
229
Arrays.fill(nbytes[6], (byte)0);
230
Arrays.fill(nbytes[7], (byte)0);
231
DerValue val = DerValue.wrap(DerValue.tag_Sequence, out);
232
key = val.toByteArray();
233
val.clear();
234
} catch (IOException exc) {
235
// should never occur
236
throw new InvalidKeyException(exc);
237
}
238
}
239
240
// see JCA doc
241
@Override
242
public String getAlgorithm() {
243
return type.keyAlgo;
244
}
245
246
// see JCA doc
247
@Override
248
public BigInteger getModulus() {
249
return n;
250
}
251
252
// see JCA doc
253
@Override
254
public BigInteger getPublicExponent() {
255
return e;
256
}
257
258
// see JCA doc
259
@Override
260
public BigInteger getPrivateExponent() {
261
return d;
262
}
263
264
// see JCA doc
265
@Override
266
public BigInteger getPrimeP() {
267
return p;
268
}
269
270
// see JCA doc
271
@Override
272
public BigInteger getPrimeQ() {
273
return q;
274
}
275
276
// see JCA doc
277
@Override
278
public BigInteger getPrimeExponentP() {
279
return pe;
280
}
281
282
// see JCA doc
283
@Override
284
public BigInteger getPrimeExponentQ() {
285
return qe;
286
}
287
288
// see JCA doc
289
@Override
290
public BigInteger getCrtCoefficient() {
291
return coeff;
292
}
293
294
// see JCA doc
295
@Override
296
public AlgorithmParameterSpec getParams() {
297
return keyParams;
298
}
299
300
// return a string representation of this key for debugging
301
@Override
302
public String toString() {
303
return "SunRsaSign " + type.keyAlgo + " private CRT key, "
304
+ n.bitLength() + " bits" + "\n params: " + keyParams
305
+ "\n modulus: " + n + "\n private exponent: " + d;
306
}
307
308
// utility method for parsing DER encoding of RSA private keys in PKCS#1
309
// format as defined in RFC 8017 Appendix A.1.2, i.e. SEQ of version, n,
310
// e, d, p, q, pe, qe, and coeff, and return the parsed components.
311
private static BigInteger[] parseASN1(byte[] raw) throws IOException {
312
DerValue derValue = new DerValue(raw);
313
try {
314
if (derValue.tag != DerValue.tag_Sequence) {
315
throw new IOException("Not a SEQUENCE");
316
}
317
int version = derValue.data.getInteger();
318
if (version != 0) {
319
throw new IOException("Version must be 0");
320
}
321
322
BigInteger[] result = new BigInteger[8]; // n, e, d, p, q, pe, qe, coeff
323
/*
324
* Some implementations do not correctly encode ASN.1 INTEGER values
325
* in 2's complement format, resulting in a negative integer when
326
* decoded. Correct the error by converting it to a positive integer.
327
*
328
* See CR 6255949
329
*/
330
for (int i = 0; i < result.length; i++) {
331
result[i] = derValue.data.getPositiveBigInteger();
332
}
333
if (derValue.data.available() != 0) {
334
throw new IOException("Extra data available");
335
}
336
return result;
337
} finally {
338
derValue.clear();
339
}
340
}
341
342
private void parseKeyBits() throws InvalidKeyException {
343
try {
344
BigInteger[] comps = parseASN1(key);
345
n = comps[0];
346
e = comps[1];
347
d = comps[2];
348
p = comps[3];
349
q = comps[4];
350
pe = comps[5];
351
qe = comps[6];
352
coeff = comps[7];
353
} catch (IOException e) {
354
throw new InvalidKeyException("Invalid RSA private key", e);
355
}
356
}
357
}
358
359