Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.base/share/classes/sun/security/provider/DSA.java
67848 views
1
/*
2
* Copyright (c) 1996, 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.provider;
27
28
import java.io.*;
29
import java.util.*;
30
import java.math.BigInteger;
31
import java.nio.ByteBuffer;
32
33
import java.security.*;
34
import java.security.SecureRandom;
35
import java.security.interfaces.*;
36
import java.security.spec.*;
37
38
import sun.security.util.Debug;
39
import sun.security.util.DerValue;
40
import sun.security.util.DerInputStream;
41
import sun.security.util.DerOutputStream;
42
import sun.security.jca.JCAUtil;
43
44
/**
45
* The Digital Signature Standard (using the Digital Signature
46
* Algorithm), as described in fips186-3 of the National Instute of
47
* Standards and Technology (NIST), using SHA digest algorithms
48
* from FIPS180-3.
49
*
50
* This file contains the signature implementation for the
51
* SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, SHA384withDSA,
52
* SHA512withDSA, SHA3-224withDSA, SHA3-256withDSA, SHA3-384withDSA,
53
* SHA3-512withDSA, as well as RawDSA, used by TLS among others.
54
* RawDSA expects the 20 byte SHA-1 digest as input via update rather
55
* than the original data like other signature implementations.
56
*
57
* In addition, IEEE P1363 signature format is supported. The
58
* corresponding implementation is registered under <sig>inP1363Format,
59
* e.g. SHA256withDSAinP1363Format.
60
*
61
* @author Benjamin Renaud
62
*
63
* @since 1.1
64
*
65
* @see DSAPublicKey
66
* @see DSAPrivateKey
67
*/
68
abstract class DSA extends SignatureSpi {
69
70
/* Are we debugging? */
71
private static final boolean debug = false;
72
73
/* The number of bits used in exponent blinding */
74
private static final int BLINDING_BITS = 7;
75
76
/* The constant component of the exponent blinding value */
77
private static final BigInteger BLINDING_CONSTANT =
78
BigInteger.valueOf(1 << BLINDING_BITS);
79
80
/* The parameter object */
81
private DSAParams params;
82
83
/* algorithm parameters */
84
private BigInteger presetP, presetQ, presetG;
85
86
/* The public key, if any */
87
private BigInteger presetY;
88
89
/* The private key, if any */
90
private BigInteger presetX;
91
92
/* The RNG used to output a seed for generating k */
93
private SecureRandom signingRandom;
94
95
/* The message digest object used */
96
private final MessageDigest md;
97
98
/* The format. true for the IEEE P1363 format. false (default) for ASN.1 */
99
private final boolean p1363Format;
100
101
/**
102
* Construct a blank DSA object. It must be
103
* initialized before being usable for signing or verifying.
104
*/
105
DSA(MessageDigest md) {
106
this(md, false);
107
}
108
109
/**
110
* Construct a blank DSA object that will use the specified
111
* signature format. {@code p1363Format} should be {@code true} to
112
* use the IEEE P1363 format. If {@code p1363Format} is {@code false},
113
* the DER-encoded ASN.1 format will be used. The DSA object must be
114
* initialized before being usable for signing or verifying.
115
*/
116
DSA(MessageDigest md, boolean p1363Format) {
117
super();
118
this.md = md;
119
this.p1363Format = p1363Format;
120
}
121
122
private static void checkKey(DSAParams params, int digestLen, String mdAlgo)
123
throws InvalidKeyException {
124
// FIPS186-3 states in sec4.2 that a hash function which provides
125
// a lower security strength than the (L, N) pair ordinarily should
126
// not be used.
127
int valueN = params.getQ().bitLength();
128
if (valueN > digestLen) {
129
throw new InvalidKeyException("The security strength of " +
130
mdAlgo + " digest algorithm is not sufficient for this key size");
131
}
132
}
133
134
/**
135
* Initialize the DSA object with a DSA private key.
136
*
137
* @param privateKey the DSA private key
138
*
139
* @exception InvalidKeyException if the key is not a valid DSA private
140
* key.
141
*/
142
protected void engineInitSign(PrivateKey privateKey)
143
throws InvalidKeyException {
144
if (!(privateKey instanceof java.security.interfaces.DSAPrivateKey)) {
145
throw new InvalidKeyException("not a DSA private key: " +
146
privateKey);
147
}
148
149
java.security.interfaces.DSAPrivateKey priv =
150
(java.security.interfaces.DSAPrivateKey)privateKey;
151
152
// check for algorithm specific constraints before doing initialization
153
DSAParams params = priv.getParams();
154
if (params == null) {
155
throw new InvalidKeyException("DSA private key lacks parameters");
156
}
157
158
// check key size against hash output size for signing
159
// skip this check for verification to minimize impact on existing apps
160
if (!"NullDigest20".equals(md.getAlgorithm())) {
161
checkKey(params, md.getDigestLength()*8, md.getAlgorithm());
162
}
163
164
this.params = params;
165
this.presetX = priv.getX();
166
this.presetY = null;
167
this.presetP = params.getP();
168
this.presetQ = params.getQ();
169
this.presetG = params.getG();
170
this.md.reset();
171
}
172
/**
173
* Initialize the DSA object with a DSA public key.
174
*
175
* @param publicKey the DSA public key.
176
*
177
* @exception InvalidKeyException if the key is not a valid DSA public
178
* key.
179
*/
180
protected void engineInitVerify(PublicKey publicKey)
181
throws InvalidKeyException {
182
if (!(publicKey instanceof java.security.interfaces.DSAPublicKey)) {
183
throw new InvalidKeyException("not a DSA public key: " +
184
publicKey);
185
}
186
java.security.interfaces.DSAPublicKey pub =
187
(java.security.interfaces.DSAPublicKey)publicKey;
188
189
// check for algorithm specific constraints before doing initialization
190
DSAParams params = pub.getParams();
191
if (params == null) {
192
throw new InvalidKeyException("DSA public key lacks parameters");
193
}
194
this.params = params;
195
this.presetY = pub.getY();
196
this.presetX = null;
197
this.presetP = params.getP();
198
this.presetQ = params.getQ();
199
this.presetG = params.getG();
200
this.md.reset();
201
}
202
203
/**
204
* Update a byte to be signed or verified.
205
*/
206
protected void engineUpdate(byte b) {
207
md.update(b);
208
}
209
210
/**
211
* Update an array of bytes to be signed or verified.
212
*/
213
protected void engineUpdate(byte[] data, int off, int len) {
214
md.update(data, off, len);
215
}
216
217
protected void engineUpdate(ByteBuffer b) {
218
md.update(b);
219
}
220
221
222
/**
223
* Sign all the data thus far updated. The signature format is
224
* determined by {@code p1363Format}. If {@code p1363Format} is
225
* {@code false} (the default), then the signature is formatted
226
* according to the Canonical Encoding Rules, returned as a DER
227
* sequence of Integers, r and s. If {@code p1363Format} is
228
* {@code false}, the signature is returned in the IEEE P1363
229
* format, which is the concatenation or r and s.
230
*
231
* @return a signature block formatted according to the format
232
* indicated by {@code p1363Format}
233
*
234
* @exception SignatureException if the signature object was not
235
* properly initialized, or if another exception occurs.
236
*
237
* @see sun.security.DSA#engineUpdate
238
* @see sun.security.DSA#engineVerify
239
*/
240
protected byte[] engineSign() throws SignatureException {
241
BigInteger k = generateK(presetQ);
242
BigInteger r = generateR(presetP, presetQ, presetG, k);
243
BigInteger s = generateS(presetX, presetQ, r, k);
244
245
if (p1363Format) {
246
// Return the concatenation of r and s
247
byte[] rBytes = r.toByteArray();
248
byte[] sBytes = s.toByteArray();
249
250
int size = presetQ.bitLength() / 8;
251
byte[] outseq = new byte[size * 2];
252
253
int rLength = rBytes.length;
254
int sLength = sBytes.length;
255
int i;
256
for (i = rLength; i > 0 && rBytes[rLength - i] == 0; i--);
257
258
int j;
259
for (j = sLength;
260
j > 0 && sBytes[sLength - j] == 0; j--);
261
262
System.arraycopy(rBytes, rLength - i, outseq, size - i, i);
263
System.arraycopy(sBytes, sLength - j, outseq, size * 2 - j, j);
264
265
return outseq;
266
} else {
267
// Return the DER-encoded ASN.1 form
268
try {
269
DerOutputStream outseq = new DerOutputStream(100);
270
outseq.putInteger(r);
271
outseq.putInteger(s);
272
DerValue result = new DerValue(DerValue.tag_Sequence,
273
outseq.toByteArray());
274
275
return result.toByteArray();
276
277
} catch (IOException e) {
278
throw new SignatureException("error encoding signature");
279
}
280
}
281
}
282
283
/**
284
* Verify all the data thus far updated.
285
*
286
* @param signature the alleged signature, encoded using the
287
* Canonical Encoding Rules, as a sequence of integers, r and s.
288
*
289
* @exception SignatureException if the signature object was not
290
* properly initialized, or if another exception occurs.
291
*
292
* @see sun.security.DSA#engineUpdate
293
* @see sun.security.DSA#engineSign
294
*/
295
protected boolean engineVerify(byte[] signature)
296
throws SignatureException {
297
return engineVerify(signature, 0, signature.length);
298
}
299
300
/**
301
* Verify all the data thus far updated.
302
*
303
* @param signature the alleged signature, encoded using the
304
* format indicated by {@code p1363Format}. If {@code p1363Format}
305
* is {@code false} (the default), then the signature is formatted
306
* according to the Canonical Encoding Rules, as a DER sequence of
307
* Integers, r and s. If {@code p1363Format} is {@code false},
308
* the signature is in the IEEE P1363 format, which is the
309
* concatenation or r and s.
310
*
311
* @param offset the offset to start from in the array of bytes.
312
*
313
* @param length the number of bytes to use, starting at offset.
314
*
315
* @exception SignatureException if the signature object was not
316
* properly initialized, or if another exception occurs.
317
*
318
* @see sun.security.DSA#engineUpdate
319
* @see sun.security.DSA#engineSign
320
*/
321
protected boolean engineVerify(byte[] signature, int offset, int length)
322
throws SignatureException {
323
324
BigInteger r = null;
325
BigInteger s = null;
326
327
if (p1363Format) {
328
if ((length & 1) == 1) {
329
// length of signature byte array should be even
330
throw new SignatureException("invalid signature format");
331
}
332
int mid = length/2;
333
r = new BigInteger(Arrays.copyOfRange(signature, 0, mid));
334
s = new BigInteger(Arrays.copyOfRange(signature, mid, length));
335
} else {
336
// first decode the signature.
337
try {
338
// Enforce strict DER checking for signatures
339
DerInputStream in =
340
new DerInputStream(signature, offset, length, false);
341
DerValue[] values = in.getSequence(2);
342
343
// check number of components in the read sequence
344
// and trailing data
345
if ((values.length != 2) || (in.available() != 0)) {
346
throw new IOException("Invalid encoding for signature");
347
}
348
r = values[0].getBigInteger();
349
s = values[1].getBigInteger();
350
} catch (IOException e) {
351
throw new SignatureException("Invalid encoding for signature", e);
352
}
353
}
354
355
// some implementations do not correctly encode values in the ASN.1
356
// 2's complement format. force r and s to be positive in order to
357
// to validate those signatures
358
if (r.signum() < 0) {
359
r = new BigInteger(1, r.toByteArray());
360
}
361
if (s.signum() < 0) {
362
s = new BigInteger(1, s.toByteArray());
363
}
364
365
if ((r.compareTo(presetQ) == -1) && (s.compareTo(presetQ) == -1)
366
&& r.signum() > 0 && s.signum() > 0) {
367
BigInteger w = generateW(presetP, presetQ, presetG, s);
368
BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r);
369
return v.equals(r);
370
} else {
371
throw new SignatureException("invalid signature: out of range values");
372
}
373
}
374
375
@Deprecated
376
protected void engineSetParameter(String key, Object param) {
377
throw new InvalidParameterException("No parameter accepted");
378
}
379
380
@Override
381
protected void engineSetParameter(AlgorithmParameterSpec params)
382
throws InvalidAlgorithmParameterException {
383
if (params != null) {
384
throw new InvalidAlgorithmParameterException("No parameter accepted");
385
}
386
}
387
388
@Deprecated
389
protected Object engineGetParameter(String key) {
390
return null;
391
}
392
393
@Override
394
protected AlgorithmParameters engineGetParameters() {
395
return null;
396
}
397
398
399
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
400
BigInteger k) {
401
402
// exponent blinding to hide information from timing channel
403
SecureRandom random = getSigningRandom();
404
// start with a random blinding component
405
BigInteger blindingValue = new BigInteger(BLINDING_BITS, random);
406
// add the fixed blinding component
407
blindingValue = blindingValue.add(BLINDING_CONSTANT);
408
// replace k with a blinded value that is congruent (mod q)
409
k = k.add(q.multiply(blindingValue));
410
411
BigInteger temp = g.modPow(k, p);
412
return temp.mod(q);
413
}
414
415
private BigInteger generateS(BigInteger x, BigInteger q,
416
BigInteger r, BigInteger k) throws SignatureException {
417
418
byte[] s2;
419
try {
420
s2 = md.digest();
421
} catch (RuntimeException re) {
422
// Only for RawDSA due to its 20-byte length restriction
423
throw new SignatureException(re.getMessage());
424
}
425
// get the leftmost min(N, outLen) bits of the digest value
426
int nBytes = q.bitLength()/8;
427
if (nBytes < s2.length) {
428
s2 = Arrays.copyOfRange(s2, 0, nBytes);
429
}
430
BigInteger z = new BigInteger(1, s2);
431
BigInteger k1 = k.modInverse(q);
432
433
return x.multiply(r).add(z).multiply(k1).mod(q);
434
}
435
436
private BigInteger generateW(BigInteger p, BigInteger q,
437
BigInteger g, BigInteger s) {
438
return s.modInverse(q);
439
}
440
441
private BigInteger generateV(BigInteger y, BigInteger p,
442
BigInteger q, BigInteger g, BigInteger w, BigInteger r)
443
throws SignatureException {
444
445
byte[] s2;
446
try {
447
s2 = md.digest();
448
} catch (RuntimeException re) {
449
// Only for RawDSA due to its 20-byte length restriction
450
throw new SignatureException(re.getMessage());
451
}
452
// get the leftmost min(N, outLen) bits of the digest value
453
int nBytes = q.bitLength()/8;
454
if (nBytes < s2.length) {
455
s2 = Arrays.copyOfRange(s2, 0, nBytes);
456
}
457
BigInteger z = new BigInteger(1, s2);
458
459
BigInteger u1 = z.multiply(w).mod(q);
460
BigInteger u2 = (r.multiply(w)).mod(q);
461
462
BigInteger t1 = g.modPow(u1,p);
463
BigInteger t2 = y.modPow(u2,p);
464
BigInteger t3 = t1.multiply(t2);
465
BigInteger t5 = t3.mod(p);
466
return t5.mod(q);
467
}
468
469
protected BigInteger generateK(BigInteger q) {
470
// Implementation defined in FIPS 186-4 AppendixB.2.1.
471
SecureRandom random = getSigningRandom();
472
byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8];
473
474
random.nextBytes(kValue);
475
return new BigInteger(1, kValue).mod(
476
q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
477
}
478
479
// Use the application-specified SecureRandom Object if provided.
480
// Otherwise, use our default SecureRandom Object.
481
protected SecureRandom getSigningRandom() {
482
if (signingRandom == null) {
483
if (appRandom != null) {
484
signingRandom = appRandom;
485
} else {
486
signingRandom = JCAUtil.getSecureRandom();
487
}
488
}
489
return signingRandom;
490
}
491
492
/**
493
* Return a human readable rendition of the engine.
494
*/
495
public String toString() {
496
String printable = "DSA Signature";
497
if (presetP != null && presetQ != null && presetG != null) {
498
printable += "\n\tp: " + Debug.toHexString(presetP);
499
printable += "\n\tq: " + Debug.toHexString(presetQ);
500
printable += "\n\tg: " + Debug.toHexString(presetG);
501
} else {
502
printable += "\n\t P, Q or G not initialized.";
503
}
504
if (presetY != null) {
505
printable += "\n\ty: " + Debug.toHexString(presetY);
506
}
507
if (presetY == null && presetX == null) {
508
printable += "\n\tUNINIIALIZED";
509
}
510
return printable;
511
}
512
513
/**
514
* SHA3-224withDSA implementation.
515
*/
516
public static final class SHA3_224withDSA extends DSA {
517
public SHA3_224withDSA() throws NoSuchAlgorithmException {
518
super(MessageDigest.getInstance("SHA3-224"));
519
}
520
}
521
522
/**
523
* SHA3-224withDSA implementation that uses the IEEE P1363 format.
524
*/
525
public static final class SHA3_224withDSAinP1363Format extends DSA {
526
public SHA3_224withDSAinP1363Format() throws NoSuchAlgorithmException {
527
super(MessageDigest.getInstance("SHA3-224"), true);
528
}
529
}
530
531
/**
532
* Standard SHA3-256withDSA implementation.
533
*/
534
public static final class SHA3_256withDSA extends DSA {
535
public SHA3_256withDSA() throws NoSuchAlgorithmException {
536
super(MessageDigest.getInstance("SHA3-256"));
537
}
538
}
539
540
/**
541
* Standard SHA3-256withDSA implementation that uses the IEEE P1363 format.
542
*/
543
public static final class SHA3_256withDSAinP1363Format extends DSA {
544
public SHA3_256withDSAinP1363Format() throws NoSuchAlgorithmException {
545
super(MessageDigest.getInstance("SHA3-256"), true);
546
}
547
}
548
549
/**
550
* Standard SHA3-384withDSA implementation.
551
*/
552
public static final class SHA3_384withDSA extends DSA {
553
public SHA3_384withDSA() throws NoSuchAlgorithmException {
554
super(MessageDigest.getInstance("SHA3-384"));
555
}
556
}
557
558
/**
559
* Standard SHA3-384withDSA implementation that uses the IEEE P1363 format.
560
*/
561
public static final class SHA3_384withDSAinP1363Format extends DSA {
562
public SHA3_384withDSAinP1363Format() throws NoSuchAlgorithmException {
563
super(MessageDigest.getInstance("SHA3-384"), true);
564
}
565
}
566
567
/**
568
* Standard SHA3-512withDSA implementation.
569
*/
570
public static final class SHA3_512withDSA extends DSA {
571
public SHA3_512withDSA() throws NoSuchAlgorithmException {
572
super(MessageDigest.getInstance("SHA3-512"));
573
}
574
}
575
576
/**
577
* Standard SHA3-512withDSA implementation that uses the IEEE P1363 format.
578
*/
579
public static final class SHA3_512withDSAinP1363Format extends DSA {
580
public SHA3_512withDSAinP1363Format() throws NoSuchAlgorithmException {
581
super(MessageDigest.getInstance("SHA3-512"), true);
582
}
583
}
584
585
/**
586
* Standard SHA224withDSA implementation as defined in FIPS186-3.
587
*/
588
public static final class SHA224withDSA extends DSA {
589
public SHA224withDSA() throws NoSuchAlgorithmException {
590
super(MessageDigest.getInstance("SHA-224"));
591
}
592
}
593
594
/**
595
* SHA224withDSA implementation that uses the IEEE P1363 format.
596
*/
597
public static final class SHA224withDSAinP1363Format extends DSA {
598
public SHA224withDSAinP1363Format() throws NoSuchAlgorithmException {
599
super(MessageDigest.getInstance("SHA-224"), true);
600
}
601
}
602
603
/**
604
* Standard SHA256withDSA implementation as defined in FIPS186-3.
605
*/
606
public static final class SHA256withDSA extends DSA {
607
public SHA256withDSA() throws NoSuchAlgorithmException {
608
super(MessageDigest.getInstance("SHA-256"));
609
}
610
}
611
612
/**
613
* SHA256withDSA implementation that uses the IEEE P1363 format.
614
*/
615
public static final class SHA256withDSAinP1363Format extends DSA {
616
public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException {
617
super(MessageDigest.getInstance("SHA-256"), true);
618
}
619
}
620
621
/**
622
* Standard SHA384withDSA implementation as defined in FIPS186-3.
623
*/
624
public static final class SHA384withDSA extends DSA {
625
public SHA384withDSA() throws NoSuchAlgorithmException {
626
super(MessageDigest.getInstance("SHA-384"));
627
}
628
}
629
630
/**
631
* SHA384withDSA implementation that uses the IEEE P1363 format.
632
*/
633
public static final class SHA384withDSAinP1363Format extends DSA {
634
public SHA384withDSAinP1363Format() throws NoSuchAlgorithmException {
635
super(MessageDigest.getInstance("SHA-384"), true);
636
}
637
}
638
639
/**
640
* Standard SHA512withDSA implementation as defined in FIPS186-3.
641
*/
642
public static final class SHA512withDSA extends DSA {
643
public SHA512withDSA() throws NoSuchAlgorithmException {
644
super(MessageDigest.getInstance("SHA-512"));
645
}
646
}
647
648
/**
649
* SHA512withDSA implementation that uses the IEEE P1363 format.
650
*/
651
public static final class SHA512withDSAinP1363Format extends DSA {
652
public SHA512withDSAinP1363Format() throws NoSuchAlgorithmException {
653
super(MessageDigest.getInstance("SHA-512"), true);
654
}
655
}
656
657
/**
658
* Standard SHA1withDSA implementation.
659
*/
660
public static final class SHA1withDSA extends DSA {
661
public SHA1withDSA() throws NoSuchAlgorithmException {
662
super(MessageDigest.getInstance("SHA-1"));
663
}
664
}
665
666
/**
667
* SHA1withDSA implementation that uses the IEEE P1363 format.
668
*/
669
public static final class SHA1withDSAinP1363Format extends DSA {
670
public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException {
671
super(MessageDigest.getInstance("SHA-1"), true);
672
}
673
}
674
675
/**
676
* Raw DSA.
677
*
678
* Raw DSA requires the data to be exactly 20 bytes long. If it is
679
* not, a SignatureException is thrown when sign()/verify() is called
680
* per JCA spec.
681
*/
682
static class Raw extends DSA {
683
// Internal special-purpose MessageDigest impl for RawDSA
684
// Only override whatever methods used
685
// NOTE: no clone support
686
public static final class NullDigest20 extends MessageDigest {
687
// 20 byte digest buffer
688
private final byte[] digestBuffer = new byte[20];
689
690
// offset into the buffer; use Integer.MAX_VALUE to indicate
691
// out-of-bound condition
692
private int ofs = 0;
693
694
protected NullDigest20() {
695
super("NullDigest20");
696
}
697
protected void engineUpdate(byte input) {
698
if (ofs == digestBuffer.length) {
699
ofs = Integer.MAX_VALUE;
700
} else {
701
digestBuffer[ofs++] = input;
702
}
703
}
704
protected void engineUpdate(byte[] input, int offset, int len) {
705
if (len > (digestBuffer.length - ofs)) {
706
ofs = Integer.MAX_VALUE;
707
} else {
708
System.arraycopy(input, offset, digestBuffer, ofs, len);
709
ofs += len;
710
}
711
}
712
protected final void engineUpdate(ByteBuffer input) {
713
int inputLen = input.remaining();
714
if (inputLen > (digestBuffer.length - ofs)) {
715
ofs = Integer.MAX_VALUE;
716
} else {
717
input.get(digestBuffer, ofs, inputLen);
718
ofs += inputLen;
719
}
720
}
721
protected byte[] engineDigest() throws RuntimeException {
722
if (ofs != digestBuffer.length) {
723
throw new RuntimeException
724
("Data for RawDSA must be exactly 20 bytes long");
725
}
726
reset();
727
return digestBuffer;
728
}
729
protected int engineDigest(byte[] buf, int offset, int len)
730
throws DigestException {
731
if (ofs != digestBuffer.length) {
732
throw new DigestException
733
("Data for RawDSA must be exactly 20 bytes long");
734
}
735
if (len < digestBuffer.length) {
736
throw new DigestException
737
("Output buffer too small; must be at least 20 bytes");
738
}
739
System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length);
740
reset();
741
return digestBuffer.length;
742
}
743
744
protected void engineReset() {
745
ofs = 0;
746
}
747
protected final int engineGetDigestLength() {
748
return digestBuffer.length;
749
}
750
}
751
752
private Raw(boolean p1363Format) throws NoSuchAlgorithmException {
753
super(new NullDigest20(), p1363Format);
754
}
755
756
}
757
758
/**
759
* Standard Raw DSA implementation.
760
*/
761
public static final class RawDSA extends Raw {
762
public RawDSA() throws NoSuchAlgorithmException {
763
super(false);
764
}
765
}
766
767
/**
768
* Raw DSA implementation that uses the IEEE P1363 format.
769
*/
770
public static final class RawDSAinP1363Format extends Raw {
771
public RawDSAinP1363Format() throws NoSuchAlgorithmException {
772
super(true);
773
}
774
}
775
}
776
777