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/RSASignature.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.nio.ByteBuffer;
30
31
import java.security.*;
32
import java.security.interfaces.*;
33
import java.security.spec.AlgorithmParameterSpec;
34
35
import sun.security.rsa.RSAUtil.KeyType;
36
import sun.security.util.*;
37
import sun.security.x509.AlgorithmId;
38
39
/**
40
* PKCS#1 v1.5 RSA signatures with the various message digest algorithms.
41
* This file contains an abstract base class with all the logic plus
42
* a nested static class for each of the message digest algorithms
43
* (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
44
* SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
45
*
46
* @since 1.5
47
* @author Andreas Sterbenz
48
*/
49
public abstract class RSASignature extends SignatureSpi {
50
51
// we sign an ASN.1 SEQUENCE of AlgorithmId and digest
52
// it has the form 30:xx:30:xx:[digestOID]:05:00:04:xx:[digest]
53
// this means the encoded length is (8 + digestOID.length + digest.length)
54
private static final int baseLength = 8;
55
56
// object identifier for the message digest algorithm used
57
private final ObjectIdentifier digestOID;
58
59
// length of the encoded signature blob
60
private final int encodedLength;
61
62
// message digest implementation we use
63
private final MessageDigest md;
64
// flag indicating whether the digest is reset
65
private boolean digestReset;
66
67
// private key, if initialized for signing
68
private RSAPrivateKey privateKey;
69
// public key, if initialized for verifying
70
private RSAPublicKey publicKey;
71
72
// padding to use, set when the initSign/initVerify is called
73
private RSAPadding padding;
74
75
/**
76
* Construct a new RSASignature. Used by subclasses.
77
*/
78
RSASignature(String algorithm, ObjectIdentifier digestOID, int oidLength) {
79
this.digestOID = digestOID;
80
try {
81
md = MessageDigest.getInstance(algorithm);
82
} catch (NoSuchAlgorithmException e) {
83
throw new ProviderException(e);
84
}
85
digestReset = true;
86
encodedLength = baseLength + oidLength + md.getDigestLength();
87
}
88
89
// initialize for verification. See JCA doc
90
@Override
91
protected void engineInitVerify(PublicKey publicKey)
92
throws InvalidKeyException {
93
RSAPublicKey rsaKey = (RSAPublicKey)RSAKeyFactory.toRSAKey(publicKey);
94
this.privateKey = null;
95
this.publicKey = rsaKey;
96
initCommon(rsaKey, null);
97
}
98
99
// initialize for signing. See JCA doc
100
@Override
101
protected void engineInitSign(PrivateKey privateKey)
102
throws InvalidKeyException {
103
engineInitSign(privateKey, null);
104
}
105
106
// initialize for signing. See JCA doc
107
@Override
108
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
109
throws InvalidKeyException {
110
RSAPrivateKey rsaKey =
111
(RSAPrivateKey)RSAKeyFactory.toRSAKey(privateKey);
112
this.privateKey = rsaKey;
113
this.publicKey = null;
114
initCommon(rsaKey, random);
115
}
116
117
/**
118
* Init code common to sign and verify.
119
*/
120
private void initCommon(RSAKey rsaKey, SecureRandom random)
121
throws InvalidKeyException {
122
try {
123
RSAUtil.checkParamsAgainstType(KeyType.RSA, rsaKey.getParams());
124
} catch (ProviderException e) {
125
throw new InvalidKeyException("Invalid key for RSA signatures", e);
126
}
127
resetDigest();
128
int keySize = RSACore.getByteLength(rsaKey);
129
try {
130
padding = RSAPadding.getInstance
131
(RSAPadding.PAD_BLOCKTYPE_1, keySize, random);
132
} catch (InvalidAlgorithmParameterException iape) {
133
throw new InvalidKeyException(iape.getMessage());
134
}
135
int maxDataSize = padding.getMaxDataSize();
136
if (encodedLength > maxDataSize) {
137
throw new InvalidKeyException
138
("Key is too short for this signature algorithm");
139
}
140
}
141
142
/**
143
* Reset the message digest if it is not already reset.
144
*/
145
private void resetDigest() {
146
if (digestReset == false) {
147
md.reset();
148
digestReset = true;
149
}
150
}
151
152
/**
153
* Return the message digest value.
154
*/
155
private byte[] getDigestValue() {
156
digestReset = true;
157
return md.digest();
158
}
159
160
// update the signature with the plaintext data. See JCA doc
161
@Override
162
protected void engineUpdate(byte b) throws SignatureException {
163
md.update(b);
164
digestReset = false;
165
}
166
167
// update the signature with the plaintext data. See JCA doc
168
@Override
169
protected void engineUpdate(byte[] b, int off, int len)
170
throws SignatureException {
171
md.update(b, off, len);
172
digestReset = false;
173
}
174
175
// update the signature with the plaintext data. See JCA doc
176
@Override
177
protected void engineUpdate(ByteBuffer b) {
178
md.update(b);
179
digestReset = false;
180
}
181
182
// sign the data and return the signature. See JCA doc
183
@Override
184
protected byte[] engineSign() throws SignatureException {
185
if (privateKey == null) {
186
throw new SignatureException("Missing private key");
187
}
188
byte[] digest = getDigestValue();
189
try {
190
byte[] encoded = encodeSignature(digestOID, digest);
191
byte[] padded = padding.pad(encoded);
192
byte[] encrypted = RSACore.rsa(padded, privateKey, true);
193
return encrypted;
194
} catch (GeneralSecurityException e) {
195
throw new SignatureException("Could not sign data", e);
196
} catch (IOException e) {
197
throw new SignatureException("Could not encode data", e);
198
}
199
}
200
201
// verify the data and return the result. See JCA doc
202
@Override
203
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
204
if (publicKey == null) {
205
throw new SignatureException("Missing public key");
206
}
207
208
if (sigBytes.length != RSACore.getByteLength(publicKey)) {
209
throw new SignatureException("Signature length not correct: got " +
210
sigBytes.length + " but was expecting " +
211
RSACore.getByteLength(publicKey));
212
}
213
byte[] digest = getDigestValue();
214
try {
215
byte[] decrypted = RSACore.rsa(sigBytes, publicKey);
216
byte[] unpadded = padding.unpad(decrypted);
217
byte[] decodedDigest = decodeSignature(digestOID, unpadded);
218
return MessageDigest.isEqual(digest, decodedDigest);
219
} catch (javax.crypto.BadPaddingException e) {
220
// occurs if the app has used the wrong RSA public key
221
// or if sigBytes is invalid
222
// return false rather than propagating the exception for
223
// compatibility/ease of use
224
return false;
225
} catch (IOException e) {
226
throw new SignatureException("Signature encoding error", e);
227
}
228
}
229
230
/**
231
* Encode the digest, return the to-be-signed data.
232
* Also used by the PKCS#11 provider.
233
*/
234
public static byte[] encodeSignature(ObjectIdentifier oid, byte[] digest)
235
throws IOException {
236
DerOutputStream out = new DerOutputStream();
237
new AlgorithmId(oid).encode(out);
238
out.putOctetString(digest);
239
DerValue result =
240
new DerValue(DerValue.tag_Sequence, out.toByteArray());
241
return result.toByteArray();
242
}
243
244
/**
245
* Decode the signature data. Verify that the object identifier matches
246
* and return the message digest.
247
*/
248
public static byte[] decodeSignature(ObjectIdentifier oid, byte[] sig)
249
throws IOException {
250
// Enforce strict DER checking for signatures
251
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
252
DerValue[] values = in.getSequence(2);
253
if ((values.length != 2) || (in.available() != 0)) {
254
throw new IOException("SEQUENCE length error");
255
}
256
AlgorithmId algId = AlgorithmId.parse(values[0]);
257
if (algId.getOID().equals((Object)oid) == false) {
258
throw new IOException("ObjectIdentifier mismatch: "
259
+ algId.getOID());
260
}
261
if (algId.getEncodedParams() != null) {
262
throw new IOException("Unexpected AlgorithmId parameters");
263
}
264
byte[] digest = values[1].getOctetString();
265
return digest;
266
}
267
268
// set parameter, not supported. See JCA doc
269
@Deprecated
270
@Override
271
protected void engineSetParameter(String param, Object value)
272
throws InvalidParameterException {
273
throw new UnsupportedOperationException("setParameter() not supported");
274
}
275
276
// See JCA doc
277
@Override
278
protected void engineSetParameter(AlgorithmParameterSpec params)
279
throws InvalidAlgorithmParameterException {
280
if (params != null) {
281
throw new InvalidAlgorithmParameterException("No parameters accepted");
282
}
283
}
284
285
// get parameter, not supported. See JCA doc
286
@Deprecated
287
@Override
288
protected Object engineGetParameter(String param)
289
throws InvalidParameterException {
290
throw new UnsupportedOperationException("getParameter() not supported");
291
}
292
293
// See JCA doc
294
@Override
295
protected AlgorithmParameters engineGetParameters() {
296
return null;
297
}
298
299
// Nested class for MD2withRSA signatures
300
public static final class MD2withRSA extends RSASignature {
301
public MD2withRSA() {
302
super("MD2", AlgorithmId.MD2_oid, 10);
303
}
304
}
305
306
// Nested class for MD5withRSA signatures
307
public static final class MD5withRSA extends RSASignature {
308
public MD5withRSA() {
309
super("MD5", AlgorithmId.MD5_oid, 10);
310
}
311
}
312
313
// Nested class for SHA1withRSA signatures
314
public static final class SHA1withRSA extends RSASignature {
315
public SHA1withRSA() {
316
super("SHA-1", AlgorithmId.SHA_oid, 7);
317
}
318
}
319
320
// Nested class for SHA224withRSA signatures
321
public static final class SHA224withRSA extends RSASignature {
322
public SHA224withRSA() {
323
super("SHA-224", AlgorithmId.SHA224_oid, 11);
324
}
325
}
326
327
// Nested class for SHA256withRSA signatures
328
public static final class SHA256withRSA extends RSASignature {
329
public SHA256withRSA() {
330
super("SHA-256", AlgorithmId.SHA256_oid, 11);
331
}
332
}
333
334
// Nested class for SHA384withRSA signatures
335
public static final class SHA384withRSA extends RSASignature {
336
public SHA384withRSA() {
337
super("SHA-384", AlgorithmId.SHA384_oid, 11);
338
}
339
}
340
341
// Nested class for SHA512withRSA signatures
342
public static final class SHA512withRSA extends RSASignature {
343
public SHA512withRSA() {
344
super("SHA-512", AlgorithmId.SHA512_oid, 11);
345
}
346
}
347
348
// Nested class for SHA512/224withRSA signatures
349
public static final class SHA512_224withRSA extends RSASignature {
350
public SHA512_224withRSA() {
351
super("SHA-512/224", AlgorithmId.SHA512_224_oid, 11);
352
}
353
}
354
355
// Nested class for SHA512/256withRSA signatures
356
public static final class SHA512_256withRSA extends RSASignature {
357
public SHA512_256withRSA() {
358
super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);
359
}
360
}
361
}
362
363