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/RSAPrivateCrtKeyImpl.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.io.IOException;
29
import java.math.BigInteger;
30
31
import java.security.*;
32
import java.security.spec.*;
33
import java.security.interfaces.*;
34
35
import sun.security.util.*;
36
37
import sun.security.x509.AlgorithmId;
38
import sun.security.pkcs.PKCS8Key;
39
40
import static 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
private static final long serialVersionUID = -1326088454257084918L;
59
60
private BigInteger n; // modulus
61
private BigInteger e; // public exponent
62
private BigInteger d; // private exponent
63
private BigInteger p; // prime p
64
private BigInteger q; // prime q
65
private BigInteger pe; // prime exponent p
66
private BigInteger qe; // prime exponent q
67
private BigInteger coeff; // CRT coeffcient
68
69
// Optional parameters associated with this RSA key
70
// specified in the encoding of its AlgorithmId.
71
// Must be null for "RSA" keys.
72
private AlgorithmParameterSpec keyParams;
73
74
/**
75
* Generate a new key from its encoding. Returns a CRT key if possible
76
* and a non-CRT key otherwise. Used by RSAKeyFactory.
77
*/
78
public static RSAPrivateKey newKey(byte[] encoded)
79
throws InvalidKeyException {
80
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
81
// check all CRT-specific components are available, if any one
82
// missing, return a non-CRT key instead
83
if ((key.getPublicExponent().signum() == 0) ||
84
(key.getPrimeExponentP().signum() == 0) ||
85
(key.getPrimeExponentQ().signum() == 0) ||
86
(key.getPrimeP().signum() == 0) ||
87
(key.getPrimeQ().signum() == 0) ||
88
(key.getCrtCoefficient().signum() == 0)) {
89
return new RSAPrivateKeyImpl(
90
key.algid,
91
key.getModulus(),
92
key.getPrivateExponent()
93
);
94
} else {
95
return key;
96
}
97
}
98
99
/**
100
* Generate a new key from the specified type and components.
101
* Returns a CRT key if possible and a non-CRT key otherwise.
102
* Used by SunPKCS11 provider.
103
*/
104
public static RSAPrivateKey newKey(KeyType type,
105
AlgorithmParameterSpec params,
106
BigInteger n, BigInteger e, BigInteger d,
107
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
108
BigInteger coeff) throws InvalidKeyException {
109
RSAPrivateKey key;
110
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
111
if ((e.signum() == 0) || (p.signum() == 0) ||
112
(q.signum() == 0) || (pe.signum() == 0) ||
113
(qe.signum() == 0) || (coeff.signum() == 0)) {
114
// if any component is missing, return a non-CRT key
115
return new RSAPrivateKeyImpl(rsaId, n, d);
116
} else {
117
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
118
p, q, pe, qe, coeff);
119
}
120
}
121
122
/**
123
* Construct a key from its encoding. Called from newKey above.
124
*/
125
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
126
if (encoded == null || encoded.length == 0) {
127
throw new InvalidKeyException("Missing key encoding");
128
}
129
130
decode(encoded);
131
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
132
try {
133
// this will check the validity of params
134
this.keyParams = RSAUtil.getParamSpec(algid);
135
} catch (ProviderException e) {
136
throw new InvalidKeyException(e);
137
}
138
}
139
140
/**
141
* Construct a RSA key from its components. Used by the
142
* RSAKeyFactory and the RSAKeyPairGenerator.
143
*/
144
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
145
BigInteger n, BigInteger e, BigInteger d,
146
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
147
BigInteger coeff) throws InvalidKeyException {
148
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
149
150
this.n = n;
151
this.e = e;
152
this.d = d;
153
this.p = p;
154
this.q = q;
155
this.pe = pe;
156
this.qe = qe;
157
this.coeff = coeff;
158
this.keyParams = RSAUtil.getParamSpec(rsaId);
159
160
// generate the encoding
161
algid = rsaId;
162
try {
163
DerOutputStream out = new DerOutputStream();
164
out.putInteger(0); // version must be 0
165
out.putInteger(n);
166
out.putInteger(e);
167
out.putInteger(d);
168
out.putInteger(p);
169
out.putInteger(q);
170
out.putInteger(pe);
171
out.putInteger(qe);
172
out.putInteger(coeff);
173
DerValue val =
174
new DerValue(DerValue.tag_Sequence, out.toByteArray());
175
key = val.toByteArray();
176
} catch (IOException exc) {
177
// should never occur
178
throw new InvalidKeyException(exc);
179
}
180
}
181
182
// see JCA doc
183
@Override
184
public String getAlgorithm() {
185
return algid.getName();
186
}
187
188
// see JCA doc
189
@Override
190
public BigInteger getModulus() {
191
return n;
192
}
193
194
// see JCA doc
195
@Override
196
public BigInteger getPublicExponent() {
197
return e;
198
}
199
200
// see JCA doc
201
@Override
202
public BigInteger getPrivateExponent() {
203
return d;
204
}
205
206
// see JCA doc
207
@Override
208
public BigInteger getPrimeP() {
209
return p;
210
}
211
212
// see JCA doc
213
@Override
214
public BigInteger getPrimeQ() {
215
return q;
216
}
217
218
// see JCA doc
219
@Override
220
public BigInteger getPrimeExponentP() {
221
return pe;
222
}
223
224
// see JCA doc
225
@Override
226
public BigInteger getPrimeExponentQ() {
227
return qe;
228
}
229
230
// see JCA doc
231
@Override
232
public BigInteger getCrtCoefficient() {
233
return coeff;
234
}
235
236
// see JCA doc
237
@Override
238
public AlgorithmParameterSpec getParams() {
239
return keyParams;
240
}
241
242
// return a string representation of this key for debugging
243
@Override
244
public String toString() {
245
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
246
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
247
+ "\n private exponent: " + d;
248
}
249
250
/**
251
* Parse the key. Called by PKCS8Key.
252
*/
253
protected void parseKeyBits() throws InvalidKeyException {
254
try {
255
DerInputStream in = new DerInputStream(key);
256
DerValue derValue = in.getDerValue();
257
if (derValue.tag != DerValue.tag_Sequence) {
258
throw new IOException("Not a SEQUENCE");
259
}
260
DerInputStream data = derValue.data;
261
int version = data.getInteger();
262
if (version != 0) {
263
throw new IOException("Version must be 0");
264
}
265
266
/*
267
* Some implementations do not correctly encode ASN.1 INTEGER values
268
* in 2's complement format, resulting in a negative integer when
269
* decoded. Correct the error by converting it to a positive integer.
270
*
271
* See CR 6255949
272
*/
273
n = data.getPositiveBigInteger();
274
e = data.getPositiveBigInteger();
275
d = data.getPositiveBigInteger();
276
p = data.getPositiveBigInteger();
277
q = data.getPositiveBigInteger();
278
pe = data.getPositiveBigInteger();
279
qe = data.getPositiveBigInteger();
280
coeff = data.getPositiveBigInteger();
281
if (derValue.data.available() != 0) {
282
throw new IOException("Extra data available");
283
}
284
} catch (IOException e) {
285
throw new InvalidKeyException("Invalid RSA private key", e);
286
}
287
}
288
}
289
290