Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/security/mscapi/CSignature.java
32288 views
1
/*
2
* Copyright (c) 2005, 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.mscapi;
27
28
import java.nio.ByteBuffer;
29
import java.security.*;
30
import java.security.interfaces.ECPublicKey;
31
import java.security.interfaces.RSAPublicKey;
32
import java.security.spec.AlgorithmParameterSpec;
33
import java.math.BigInteger;
34
import java.security.spec.MGF1ParameterSpec;
35
import java.security.spec.PSSParameterSpec;
36
import java.util.Locale;
37
38
import sun.security.rsa.RSAKeyFactory;
39
import sun.security.util.ECUtil;
40
import sun.security.util.KeyUtil;
41
42
/**
43
* Signature implementation.
44
*
45
* Objects should be instantiated by calling Signature.getInstance() using the
46
* following algorithm names:
47
*
48
* . "NONEwithRSA"
49
* . "SHA1withRSA"
50
* . "SHA256withRSA"
51
* . "SHA384withRSA"
52
* . "SHA512withRSA"
53
* . "MD5withRSA"
54
* . "MD2withRSA"
55
* . "RSASSA-PSS"
56
* . "SHA1withECDSA"
57
* . "SHA224withECDSA"
58
* . "SHA256withECDSA"
59
* . "SHA384withECDSA"
60
* . "SHA512withECDSA"
61
*
62
* NOTE: RSA keys must be at least 512 bits long.
63
*
64
* NOTE: NONEwithRSA must be supplied with a pre-computed message digest.
65
* Only the following digest algorithms are supported: MD5, SHA-1,
66
* SHA-256, SHA-384, SHA-512 and a special-purpose digest
67
* algorithm which is a concatenation of SHA-1 and MD5 digests.
68
*
69
* @since 1.6
70
* @author Stanley Man-Kit Ho
71
*/
72
abstract class CSignature extends SignatureSpi {
73
// private key algorithm name
74
protected String keyAlgorithm;
75
76
// message digest implementation we use
77
protected MessageDigest messageDigest;
78
79
// message digest name
80
protected String messageDigestAlgorithm;
81
82
// flag indicating whether the digest has been reset
83
protected boolean needsReset;
84
85
// the signing key
86
protected CPrivateKey privateKey = null;
87
88
// the verification key
89
protected CPublicKey publicKey = null;
90
91
/**
92
* Constructs a new CSignature. Used by subclasses.
93
*/
94
CSignature(String keyName, String digestName) {
95
96
this.keyAlgorithm = keyName;
97
if (digestName != null) {
98
try {
99
messageDigest = MessageDigest.getInstance(digestName);
100
// Get the digest's canonical name
101
messageDigestAlgorithm = messageDigest.getAlgorithm();
102
} catch (NoSuchAlgorithmException e) {
103
throw new ProviderException(e);
104
}
105
} else {
106
messageDigest = null;
107
messageDigestAlgorithm = null;
108
}
109
needsReset = false;
110
}
111
112
static class RSA extends CSignature {
113
114
public RSA(String digestAlgorithm) {
115
super("RSA", digestAlgorithm);
116
}
117
118
// initialize for signing. See JCA doc
119
@Override
120
protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
121
if (key == null) {
122
throw new InvalidKeyException("Key cannot be null");
123
}
124
if ((key instanceof CPrivateKey) == false
125
|| !key.getAlgorithm().equalsIgnoreCase("RSA")) {
126
throw new InvalidKeyException("Key type not supported: "
127
+ key.getClass() + " " + key.getAlgorithm());
128
}
129
privateKey = (CPrivateKey) key;
130
131
// Check against the local and global values to make sure
132
// the sizes are ok. Round up to nearest byte.
133
RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
134
null, CKeyPairGenerator.RSA.KEY_SIZE_MIN,
135
CKeyPairGenerator.RSA.KEY_SIZE_MAX);
136
137
this.publicKey = null;
138
resetDigest();
139
}
140
141
// initialize for signing. See JCA doc
142
@Override
143
protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
144
if (key == null) {
145
throw new InvalidKeyException("Key cannot be null");
146
}
147
// This signature accepts only RSAPublicKey
148
if ((key instanceof RSAPublicKey) == false) {
149
throw new InvalidKeyException("Key type not supported: "
150
+ key.getClass());
151
}
152
153
154
if ((key instanceof CPublicKey) == false) {
155
156
// convert key to MSCAPI format
157
java.security.interfaces.RSAPublicKey rsaKey =
158
(java.security.interfaces.RSAPublicKey) key;
159
160
BigInteger modulus = rsaKey.getModulus();
161
BigInteger exponent = rsaKey.getPublicExponent();
162
163
// Check against the local and global values to make sure
164
// the sizes are ok. Round up to the nearest byte.
165
RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
166
exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);
167
168
byte[] modulusBytes = modulus.toByteArray();
169
byte[] exponentBytes = exponent.toByteArray();
170
171
// Adjust key length due to sign bit
172
int keyBitLength = (modulusBytes[0] == 0)
173
? (modulusBytes.length - 1) * 8
174
: modulusBytes.length * 8;
175
176
byte[] keyBlob = generatePublicKeyBlob(
177
keyBitLength, modulusBytes, exponentBytes);
178
179
try {
180
publicKey = importPublicKey("RSA", keyBlob, keyBitLength);
181
182
} catch (KeyStoreException e) {
183
throw new InvalidKeyException(e);
184
}
185
186
} else {
187
publicKey = (CPublicKey) key;
188
}
189
190
this.privateKey = null;
191
resetDigest();
192
}
193
194
/**
195
* Returns the signature bytes of all the data
196
* updated so far.
197
* The format of the signature depends on the underlying
198
* signature scheme.
199
*
200
* @return the signature bytes of the signing operation's result.
201
*
202
* @exception SignatureException if the engine is not
203
* initialized properly or if this signature algorithm is unable to
204
* process the input data provided.
205
*/
206
@Override
207
protected byte[] engineSign() throws SignatureException {
208
209
byte[] hash = getDigestValue();
210
211
if (privateKey.getHCryptKey() == 0) {
212
return signCngHash(1, hash, hash.length,
213
0,
214
this instanceof NONEwithRSA ? null : messageDigestAlgorithm,
215
privateKey.getHCryptProvider(), 0);
216
} else {
217
// Omit the hash OID when generating a NONEwithRSA signature
218
boolean noHashOID = this instanceof NONEwithRSA;
219
// Sign hash using MS Crypto APIs
220
byte[] result = signHash(noHashOID, hash, hash.length,
221
messageDigestAlgorithm, privateKey.getHCryptProvider(),
222
privateKey.getHCryptKey());
223
224
// Convert signature array from little endian to big endian
225
return convertEndianArray(result);
226
}
227
}
228
229
/**
230
* Verifies the passed-in signature.
231
*
232
* @param sigBytes the signature bytes to be verified.
233
*
234
* @return true if the signature was verified, false if not.
235
*
236
* @exception SignatureException if the engine is not
237
* initialized properly, the passed-in signature is improperly
238
* encoded or of the wrong type, if this signature algorithm is unable to
239
* process the input data provided, etc.
240
*/
241
@Override
242
protected boolean engineVerify(byte[] sigBytes)
243
throws SignatureException {
244
byte[] hash = getDigestValue();
245
246
if (publicKey.getHCryptKey() == 0) {
247
return verifyCngSignedHash(
248
1, hash, hash.length,
249
sigBytes, sigBytes.length,
250
0,
251
messageDigestAlgorithm,
252
publicKey.getHCryptProvider(),
253
0);
254
} else {
255
return verifySignedHash(hash, hash.length,
256
messageDigestAlgorithm, convertEndianArray(sigBytes),
257
sigBytes.length, publicKey.getHCryptProvider(),
258
publicKey.getHCryptKey());
259
}
260
}
261
262
/**
263
* Generates a public-key BLOB from a key's components.
264
*/
265
// used by CRSACipher
266
static native byte[] generatePublicKeyBlob(
267
int keyBitLength, byte[] modulus, byte[] publicExponent)
268
throws InvalidKeyException;
269
270
}
271
272
// Nested class for NONEwithRSA signatures
273
public static final class NONEwithRSA extends RSA {
274
275
// the longest supported digest is 512 bits (SHA-512)
276
private static final int RAW_RSA_MAX = 64;
277
278
private final byte[] precomputedDigest;
279
private int offset = 0;
280
281
public NONEwithRSA() {
282
super(null);
283
precomputedDigest = new byte[RAW_RSA_MAX];
284
}
285
286
// Stores the precomputed message digest value.
287
@Override
288
protected void engineUpdate(byte b) throws SignatureException {
289
if (offset >= precomputedDigest.length) {
290
offset = RAW_RSA_MAX + 1;
291
return;
292
}
293
precomputedDigest[offset++] = b;
294
}
295
296
// Stores the precomputed message digest value.
297
@Override
298
protected void engineUpdate(byte[] b, int off, int len)
299
throws SignatureException {
300
if (len > (precomputedDigest.length - offset)) {
301
offset = RAW_RSA_MAX + 1;
302
return;
303
}
304
System.arraycopy(b, off, precomputedDigest, offset, len);
305
offset += len;
306
}
307
308
// Stores the precomputed message digest value.
309
@Override
310
protected void engineUpdate(ByteBuffer byteBuffer) {
311
int len = byteBuffer.remaining();
312
if (len <= 0) {
313
return;
314
}
315
if (len > (precomputedDigest.length - offset)) {
316
offset = RAW_RSA_MAX + 1;
317
return;
318
}
319
byteBuffer.get(precomputedDigest, offset, len);
320
offset += len;
321
}
322
323
@Override
324
protected void resetDigest(){
325
offset = 0;
326
}
327
328
// Returns the precomputed message digest value.
329
@Override
330
protected byte[] getDigestValue() throws SignatureException {
331
if (offset > RAW_RSA_MAX) {
332
throw new SignatureException("Message digest is too long");
333
}
334
335
// Determine the digest algorithm from the digest length
336
if (offset == 20) {
337
setDigestName("SHA1");
338
} else if (offset == 36) {
339
setDigestName("SHA1+MD5");
340
} else if (offset == 32) {
341
setDigestName("SHA-256");
342
} else if (offset == 48) {
343
setDigestName("SHA-384");
344
} else if (offset == 64) {
345
setDigestName("SHA-512");
346
} else if (offset == 16) {
347
setDigestName("MD5");
348
} else {
349
throw new SignatureException(
350
"Message digest length is not supported");
351
}
352
353
byte[] result = new byte[offset];
354
System.arraycopy(precomputedDigest, 0, result, 0, offset);
355
offset = 0;
356
357
return result;
358
}
359
}
360
361
public static final class SHA1withRSA extends RSA {
362
public SHA1withRSA() {
363
super("SHA1");
364
}
365
}
366
367
public static final class SHA256withRSA extends RSA {
368
public SHA256withRSA() {
369
super("SHA-256");
370
}
371
}
372
373
public static final class SHA384withRSA extends RSA {
374
public SHA384withRSA() {
375
super("SHA-384");
376
}
377
}
378
379
public static final class SHA512withRSA extends RSA {
380
public SHA512withRSA() {
381
super("SHA-512");
382
}
383
}
384
385
public static final class MD5withRSA extends RSA {
386
public MD5withRSA() {
387
super("MD5");
388
}
389
}
390
391
public static final class MD2withRSA extends RSA {
392
public MD2withRSA() {
393
super("MD2");
394
}
395
}
396
397
public static final class SHA1withECDSA extends ECDSA {
398
public SHA1withECDSA() {
399
super("SHA-1");
400
}
401
}
402
403
public static final class SHA224withECDSA extends ECDSA {
404
public SHA224withECDSA() {
405
super("SHA-224");
406
}
407
}
408
409
public static final class SHA256withECDSA extends ECDSA {
410
public SHA256withECDSA() {
411
super("SHA-256");
412
}
413
}
414
415
public static final class SHA384withECDSA extends ECDSA {
416
public SHA384withECDSA() {
417
super("SHA-384");
418
}
419
}
420
421
public static final class SHA512withECDSA extends ECDSA {
422
public SHA512withECDSA() {
423
super("SHA-512");
424
}
425
}
426
427
static class ECDSA extends CSignature {
428
429
public ECDSA(String messageDigestAlgorithm) {
430
super("EC", messageDigestAlgorithm);
431
}
432
433
// initialize for signing. See JCA doc
434
@Override
435
protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
436
if (key == null) {
437
throw new InvalidKeyException("Key cannot be null");
438
}
439
if ((key instanceof CPrivateKey) == false
440
|| !key.getAlgorithm().equalsIgnoreCase("EC")) {
441
throw new InvalidKeyException("Key type not supported: "
442
+ key.getClass() + " " + key.getAlgorithm());
443
}
444
privateKey = (CPrivateKey) key;
445
446
this.publicKey = null;
447
resetDigest();
448
}
449
450
// initialize for signing. See JCA doc
451
@Override
452
protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
453
if (key == null) {
454
throw new InvalidKeyException("Key cannot be null");
455
}
456
// This signature accepts only ECPublicKey
457
if ((key instanceof ECPublicKey) == false) {
458
throw new InvalidKeyException("Key type not supported: "
459
+ key.getClass());
460
}
461
462
if ((key instanceof CPublicKey) == false) {
463
try {
464
publicKey = importECPublicKey("EC",
465
CKey.generateECBlob(key),
466
KeyUtil.getKeySize(key));
467
} catch (KeyStoreException e) {
468
throw new InvalidKeyException(e);
469
}
470
} else {
471
publicKey = (CPublicKey) key;
472
}
473
474
this.privateKey = null;
475
resetDigest();
476
}
477
478
@Override
479
protected byte[] engineSign() throws SignatureException {
480
byte[] hash = getDigestValue();
481
byte[] raw = signCngHash(0, hash, hash.length,
482
0,
483
null,
484
privateKey.getHCryptProvider(), 0);
485
return ECUtil.encodeSignature(raw);
486
}
487
488
@Override
489
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
490
byte[] hash = getDigestValue();
491
sigBytes = ECUtil.decodeSignature(sigBytes);
492
return verifyCngSignedHash(
493
0,
494
hash, hash.length,
495
sigBytes, sigBytes.length,
496
0,
497
null,
498
publicKey.getHCryptProvider(),
499
0
500
);
501
}
502
}
503
504
public static final class PSS extends RSA {
505
506
private PSSParameterSpec pssParams = null;
507
508
// Workaround: Cannot import raw public key to CNG. This signature
509
// will be used for verification if key is not from MSCAPI.
510
private Signature fallbackSignature;
511
512
public PSS() {
513
super(null);
514
}
515
516
@Override
517
protected void engineInitSign(PrivateKey key) throws InvalidKeyException {
518
super.engineInitSign(key);
519
fallbackSignature = null;
520
}
521
522
@Override
523
protected void engineInitVerify(PublicKey key) throws InvalidKeyException {
524
if (key == null) {
525
throw new InvalidKeyException("Key cannot be null");
526
}
527
// This signature accepts only RSAPublicKey
528
if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {
529
throw new InvalidKeyException("Key type not supported: "
530
+ key.getClass());
531
}
532
533
this.privateKey = null;
534
535
if (key instanceof CPublicKey) {
536
fallbackSignature = null;
537
publicKey = (CPublicKey) key;
538
} else {
539
if (fallbackSignature == null) {
540
try {
541
fallbackSignature = Signature.getInstance(
542
"RSASSA-PSS", "SunRsaSign");
543
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
544
throw new InvalidKeyException("Invalid key", e);
545
}
546
}
547
fallbackSignature.initVerify(key);
548
if (pssParams != null) {
549
try {
550
fallbackSignature.setParameter(pssParams);
551
} catch (InvalidAlgorithmParameterException e) {
552
throw new InvalidKeyException("Invalid params", e);
553
}
554
}
555
publicKey = null;
556
}
557
resetDigest();
558
}
559
560
@Override
561
protected void engineUpdate(byte b) throws SignatureException {
562
ensureInit();
563
if (fallbackSignature != null) {
564
fallbackSignature.update(b);
565
} else {
566
messageDigest.update(b);
567
}
568
needsReset = true;
569
}
570
571
@Override
572
protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
573
ensureInit();
574
if (fallbackSignature != null) {
575
fallbackSignature.update(b, off, len);
576
} else {
577
messageDigest.update(b, off, len);
578
}
579
needsReset = true;
580
}
581
582
@Override
583
protected void engineUpdate(ByteBuffer input) {
584
try {
585
ensureInit();
586
} catch (SignatureException se) {
587
// hack for working around API bug
588
throw new RuntimeException(se.getMessage());
589
}
590
if (fallbackSignature != null) {
591
try {
592
fallbackSignature.update(input);
593
} catch (SignatureException se) {
594
// hack for working around API bug
595
throw new RuntimeException(se.getMessage());
596
}
597
} else {
598
messageDigest.update(input);
599
}
600
needsReset = true;
601
}
602
603
@Override
604
protected byte[] engineSign() throws SignatureException {
605
ensureInit();
606
byte[] hash = getDigestValue();
607
return signCngHash(2, hash, hash.length,
608
pssParams.getSaltLength(),
609
((MGF1ParameterSpec)
610
pssParams.getMGFParameters()).getDigestAlgorithm(),
611
privateKey.getHCryptProvider(), privateKey.getHCryptKey());
612
}
613
614
@Override
615
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
616
ensureInit();
617
if (fallbackSignature != null) {
618
needsReset = false;
619
return fallbackSignature.verify(sigBytes);
620
} else {
621
byte[] hash = getDigestValue();
622
return verifyCngSignedHash(
623
2, hash, hash.length,
624
sigBytes, sigBytes.length,
625
pssParams.getSaltLength(),
626
((MGF1ParameterSpec)
627
pssParams.getMGFParameters()).getDigestAlgorithm(),
628
publicKey.getHCryptProvider(),
629
publicKey.getHCryptKey()
630
);
631
}
632
}
633
634
@Override
635
protected void engineSetParameter(AlgorithmParameterSpec params)
636
throws InvalidAlgorithmParameterException {
637
if (needsReset) {
638
throw new ProviderException
639
("Cannot set parameters during operations");
640
}
641
this.pssParams = validateSigParams(params);
642
if (fallbackSignature != null) {
643
fallbackSignature.setParameter(params);
644
}
645
}
646
647
@Override
648
protected AlgorithmParameters engineGetParameters() {
649
AlgorithmParameters ap = null;
650
if (this.pssParams != null) {
651
try {
652
ap = AlgorithmParameters.getInstance("RSASSA-PSS");
653
ap.init(this.pssParams);
654
} catch (GeneralSecurityException gse) {
655
throw new ProviderException(gse.getMessage());
656
}
657
}
658
return ap;
659
}
660
661
private void ensureInit() throws SignatureException {
662
if (this.privateKey == null && this.publicKey == null
663
&& fallbackSignature == null) {
664
throw new SignatureException("Missing key");
665
}
666
if (this.pssParams == null) {
667
// Parameters are required for signature verification
668
throw new SignatureException
669
("Parameters required for RSASSA-PSS signatures");
670
}
671
if (fallbackSignature == null && messageDigest == null) {
672
// This could happen if initVerify(softKey), setParameter(),
673
// and initSign() were called. No messageDigest. Create it.
674
try {
675
messageDigest = MessageDigest
676
.getInstance(pssParams.getDigestAlgorithm());
677
} catch (NoSuchAlgorithmException e) {
678
throw new SignatureException(e);
679
}
680
}
681
}
682
683
/**
684
* Validate the specified Signature PSS parameters.
685
*/
686
private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
687
throws InvalidAlgorithmParameterException {
688
689
if (p == null) {
690
throw new InvalidAlgorithmParameterException
691
("Parameters cannot be null");
692
}
693
694
if (!(p instanceof PSSParameterSpec)) {
695
throw new InvalidAlgorithmParameterException
696
("parameters must be type PSSParameterSpec");
697
}
698
699
// no need to validate again if same as current signature parameters
700
PSSParameterSpec params = (PSSParameterSpec) p;
701
if (params == this.pssParams) return params;
702
703
// now sanity check the parameter values
704
if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
705
throw new InvalidAlgorithmParameterException("Only supports MGF1");
706
707
}
708
709
if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
710
throw new InvalidAlgorithmParameterException
711
("Only supports TrailerFieldBC(1)");
712
}
713
714
AlgorithmParameterSpec algSpec = params.getMGFParameters();
715
if (!(algSpec instanceof MGF1ParameterSpec)) {
716
throw new InvalidAlgorithmParameterException
717
("Only support MGF1ParameterSpec");
718
}
719
720
MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)algSpec;
721
722
String msgHashAlg = params.getDigestAlgorithm()
723
.toLowerCase(Locale.ROOT).replaceAll("-", "");
724
if (msgHashAlg.equals("sha")) {
725
msgHashAlg = "sha1";
726
}
727
String mgf1HashAlg = mgfSpec.getDigestAlgorithm()
728
.toLowerCase(Locale.ROOT).replaceAll("-", "");
729
if (mgf1HashAlg.equals("sha")) {
730
mgf1HashAlg = "sha1";
731
}
732
733
if (!mgf1HashAlg.equals(msgHashAlg)) {
734
throw new InvalidAlgorithmParameterException
735
("MGF1 hash must be the same as message hash");
736
}
737
738
return params;
739
}
740
}
741
742
/**
743
* Sign hash using CNG API with HCRYPTKEY.
744
* @param type 0 no padding, 1, pkcs1, 2, pss
745
*/
746
native static byte[] signCngHash(
747
int type, byte[] hash,
748
int hashSize, int saltLength, String hashAlgorithm,
749
long hCryptProv, long nCryptKey)
750
throws SignatureException;
751
752
/**
753
* Verify a signed hash using CNG API with HCRYPTKEY.
754
* @param type 0 no padding, 1, pkcs1, 2, pss
755
*/
756
private native static boolean verifyCngSignedHash(
757
int type, byte[] hash, int hashSize,
758
byte[] signature, int signatureSize,
759
int saltLength, String hashAlgorithm,
760
long hCryptProv, long hKey) throws SignatureException;
761
762
/**
763
* Resets the message digest if needed.
764
*/
765
protected void resetDigest() {
766
if (needsReset) {
767
if (messageDigest != null) {
768
messageDigest.reset();
769
}
770
needsReset = false;
771
}
772
}
773
774
protected byte[] getDigestValue() throws SignatureException {
775
needsReset = false;
776
return messageDigest.digest();
777
}
778
779
protected void setDigestName(String name) {
780
messageDigestAlgorithm = name;
781
}
782
783
/**
784
* Updates the data to be signed or verified
785
* using the specified byte.
786
*
787
* @param b the byte to use for the update.
788
*
789
* @exception SignatureException if the engine is not initialized
790
* properly.
791
*/
792
@Override
793
protected void engineUpdate(byte b) throws SignatureException {
794
messageDigest.update(b);
795
needsReset = true;
796
}
797
798
/**
799
* Updates the data to be signed or verified, using the
800
* specified array of bytes, starting at the specified offset.
801
*
802
* @param b the array of bytes
803
* @param off the offset to start from in the array of bytes
804
* @param len the number of bytes to use, starting at offset
805
*
806
* @exception SignatureException if the engine is not initialized
807
* properly
808
*/
809
@Override
810
protected void engineUpdate(byte[] b, int off, int len)
811
throws SignatureException {
812
messageDigest.update(b, off, len);
813
needsReset = true;
814
}
815
816
/**
817
* Updates the data to be signed or verified, using the
818
* specified ByteBuffer.
819
*
820
* @param input the ByteBuffer
821
*/
822
@Override
823
protected void engineUpdate(ByteBuffer input) {
824
messageDigest.update(input);
825
needsReset = true;
826
}
827
828
/**
829
* Convert array from big endian to little endian, or vice versa.
830
*/
831
private static byte[] convertEndianArray(byte[] byteArray) {
832
if (byteArray == null || byteArray.length == 0)
833
return byteArray;
834
835
byte [] retval = new byte[byteArray.length];
836
837
// make it big endian
838
for (int i=0;i < byteArray.length;i++)
839
retval[i] = byteArray[byteArray.length - i - 1];
840
841
return retval;
842
}
843
844
/**
845
* Sign hash using Microsoft Crypto API with HCRYPTKEY.
846
* The returned data is in little-endian.
847
*/
848
private native static byte[] signHash(boolean noHashOID, byte[] hash,
849
int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)
850
throws SignatureException;
851
852
/**
853
* Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.
854
*/
855
private native static boolean verifySignedHash(byte[] hash, int hashSize,
856
String hashAlgorithm, byte[] signature, int signatureSize,
857
long hCryptProv, long hCryptKey) throws SignatureException;
858
859
/**
860
* Sets the specified algorithm parameter to the specified
861
* value. This method supplies a general-purpose mechanism through
862
* which it is possible to set the various parameters of this object.
863
* A parameter may be any settable parameter for the algorithm, such as
864
* a parameter size, or a source of random bits for signature generation
865
* (if appropriate), or an indication of whether or not to perform
866
* a specific but optional computation. A uniform algorithm-specific
867
* naming scheme for each parameter is desirable but left unspecified
868
* at this time.
869
*
870
* @param param the string identifier of the parameter.
871
*
872
* @param value the parameter value.
873
*
874
* @exception InvalidParameterException if <code>param</code> is an
875
* invalid parameter for this signature algorithm engine,
876
* the parameter is already set
877
* and cannot be set again, a security exception occurs, and so on.
878
*
879
* @deprecated Replaced by {@link
880
* #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
881
* engineSetParameter}.
882
*/
883
@Override
884
@Deprecated
885
protected void engineSetParameter(String param, Object value)
886
throws InvalidParameterException {
887
throw new InvalidParameterException("Parameter not supported");
888
}
889
890
/**
891
* Sets this signature engine with the specified algorithm parameter.
892
*
893
* @param params the parameters
894
*
895
* @exception InvalidAlgorithmParameterException if the given
896
* parameter is invalid
897
*/
898
@Override
899
protected void engineSetParameter(AlgorithmParameterSpec params)
900
throws InvalidAlgorithmParameterException {
901
if (params != null) {
902
throw new InvalidAlgorithmParameterException("No parameter accepted");
903
}
904
}
905
906
/**
907
* Gets the value of the specified algorithm parameter.
908
* This method supplies a general-purpose mechanism through which it
909
* is possible to get the various parameters of this object. A parameter
910
* may be any settable parameter for the algorithm, such as a parameter
911
* size, or a source of random bits for signature generation (if
912
* appropriate), or an indication of whether or not to perform a
913
* specific but optional computation. A uniform algorithm-specific
914
* naming scheme for each parameter is desirable but left unspecified
915
* at this time.
916
*
917
* @param param the string name of the parameter.
918
*
919
* @return the object that represents the parameter value, or null if
920
* there is none.
921
*
922
* @exception InvalidParameterException if <code>param</code> is an
923
* invalid parameter for this engine, or another exception occurs while
924
* trying to get this parameter.
925
*
926
* @deprecated
927
*/
928
@Override
929
@Deprecated
930
protected Object engineGetParameter(String param)
931
throws InvalidParameterException {
932
throw new InvalidParameterException("Parameter not supported");
933
}
934
935
/**
936
* Gets the algorithm parameter from this signature engine.
937
*
938
* @return the parameter, or null if no parameter is used.
939
*/
940
@Override
941
protected AlgorithmParameters engineGetParameters() {
942
return null;
943
}
944
945
/**
946
* Imports a public-key BLOB.
947
*/
948
// used by CRSACipher
949
static native CPublicKey importPublicKey(
950
String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
951
952
static native CPublicKey importECPublicKey(
953
String alg, byte[] keyBlob, int keySize) throws KeyStoreException;
954
}
955
956