Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/provider/DSA.java
41159 views
1
/*
2
* Copyright (c) 1996, 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.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
BigInteger w = generateW(presetP, presetQ, presetG, s);
367
BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r);
368
return v.equals(r);
369
} else {
370
throw new SignatureException("invalid signature: out of range values");
371
}
372
}
373
374
@Deprecated
375
protected void engineSetParameter(String key, Object param) {
376
throw new InvalidParameterException("No parameter accepted");
377
}
378
379
@Override
380
protected void engineSetParameter(AlgorithmParameterSpec params)
381
throws InvalidAlgorithmParameterException {
382
if (params != null) {
383
throw new InvalidAlgorithmParameterException("No parameter accepted");
384
}
385
}
386
387
@Deprecated
388
protected Object engineGetParameter(String key) {
389
return null;
390
}
391
392
@Override
393
protected AlgorithmParameters engineGetParameters() {
394
return null;
395
}
396
397
398
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
399
BigInteger k) {
400
401
// exponent blinding to hide information from timing channel
402
SecureRandom random = getSigningRandom();
403
// start with a random blinding component
404
BigInteger blindingValue = new BigInteger(BLINDING_BITS, random);
405
// add the fixed blinding component
406
blindingValue = blindingValue.add(BLINDING_CONSTANT);
407
// replace k with a blinded value that is congruent (mod q)
408
k = k.add(q.multiply(blindingValue));
409
410
BigInteger temp = g.modPow(k, p);
411
return temp.mod(q);
412
}
413
414
private BigInteger generateS(BigInteger x, BigInteger q,
415
BigInteger r, BigInteger k) throws SignatureException {
416
417
byte[] s2;
418
try {
419
s2 = md.digest();
420
} catch (RuntimeException re) {
421
// Only for RawDSA due to its 20-byte length restriction
422
throw new SignatureException(re.getMessage());
423
}
424
// get the leftmost min(N, outLen) bits of the digest value
425
int nBytes = q.bitLength()/8;
426
if (nBytes < s2.length) {
427
s2 = Arrays.copyOfRange(s2, 0, nBytes);
428
}
429
BigInteger z = new BigInteger(1, s2);
430
BigInteger k1 = k.modInverse(q);
431
432
return x.multiply(r).add(z).multiply(k1).mod(q);
433
}
434
435
private BigInteger generateW(BigInteger p, BigInteger q,
436
BigInteger g, BigInteger s) {
437
return s.modInverse(q);
438
}
439
440
private BigInteger generateV(BigInteger y, BigInteger p,
441
BigInteger q, BigInteger g, BigInteger w, BigInteger r)
442
throws SignatureException {
443
444
byte[] s2;
445
try {
446
s2 = md.digest();
447
} catch (RuntimeException re) {
448
// Only for RawDSA due to its 20-byte length restriction
449
throw new SignatureException(re.getMessage());
450
}
451
// get the leftmost min(N, outLen) bits of the digest value
452
int nBytes = q.bitLength()/8;
453
if (nBytes < s2.length) {
454
s2 = Arrays.copyOfRange(s2, 0, nBytes);
455
}
456
BigInteger z = new BigInteger(1, s2);
457
458
BigInteger u1 = z.multiply(w).mod(q);
459
BigInteger u2 = (r.multiply(w)).mod(q);
460
461
BigInteger t1 = g.modPow(u1,p);
462
BigInteger t2 = y.modPow(u2,p);
463
BigInteger t3 = t1.multiply(t2);
464
BigInteger t5 = t3.mod(p);
465
return t5.mod(q);
466
}
467
468
protected BigInteger generateK(BigInteger q) {
469
// Implementation defined in FIPS 186-4 AppendixB.2.1.
470
SecureRandom random = getSigningRandom();
471
byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8];
472
473
random.nextBytes(kValue);
474
return new BigInteger(1, kValue).mod(
475
q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
476
}
477
478
// Use the application-specified SecureRandom Object if provided.
479
// Otherwise, use our default SecureRandom Object.
480
protected SecureRandom getSigningRandom() {
481
if (signingRandom == null) {
482
if (appRandom != null) {
483
signingRandom = appRandom;
484
} else {
485
signingRandom = JCAUtil.getSecureRandom();
486
}
487
}
488
return signingRandom;
489
}
490
491
/**
492
* Return a human readable rendition of the engine.
493
*/
494
public String toString() {
495
String printable = "DSA Signature";
496
if (presetP != null && presetQ != null && presetG != null) {
497
printable += "\n\tp: " + Debug.toHexString(presetP);
498
printable += "\n\tq: " + Debug.toHexString(presetQ);
499
printable += "\n\tg: " + Debug.toHexString(presetG);
500
} else {
501
printable += "\n\t P, Q or G not initialized.";
502
}
503
if (presetY != null) {
504
printable += "\n\ty: " + Debug.toHexString(presetY);
505
}
506
if (presetY == null && presetX == null) {
507
printable += "\n\tUNINIIALIZED";
508
}
509
return printable;
510
}
511
512
/**
513
* SHA3-224withDSA implementation.
514
*/
515
public static final class SHA3_224withDSA extends DSA {
516
public SHA3_224withDSA() throws NoSuchAlgorithmException {
517
super(MessageDigest.getInstance("SHA3-224"));
518
}
519
}
520
521
/**
522
* SHA3-224withDSA implementation that uses the IEEE P1363 format.
523
*/
524
public static final class SHA3_224withDSAinP1363Format extends DSA {
525
public SHA3_224withDSAinP1363Format() throws NoSuchAlgorithmException {
526
super(MessageDigest.getInstance("SHA3-224"), true);
527
}
528
}
529
530
/**
531
* Standard SHA3-256withDSA implementation.
532
*/
533
public static final class SHA3_256withDSA extends DSA {
534
public SHA3_256withDSA() throws NoSuchAlgorithmException {
535
super(MessageDigest.getInstance("SHA3-256"));
536
}
537
}
538
539
/**
540
* Standard SHA3-256withDSA implementation that uses the IEEE P1363 format.
541
*/
542
public static final class SHA3_256withDSAinP1363Format extends DSA {
543
public SHA3_256withDSAinP1363Format() throws NoSuchAlgorithmException {
544
super(MessageDigest.getInstance("SHA3-256"), true);
545
}
546
}
547
548
/**
549
* Standard SHA3-384withDSA implementation.
550
*/
551
public static final class SHA3_384withDSA extends DSA {
552
public SHA3_384withDSA() throws NoSuchAlgorithmException {
553
super(MessageDigest.getInstance("SHA3-384"));
554
}
555
}
556
557
/**
558
* Standard SHA3-384withDSA implementation that uses the IEEE P1363 format.
559
*/
560
public static final class SHA3_384withDSAinP1363Format extends DSA {
561
public SHA3_384withDSAinP1363Format() throws NoSuchAlgorithmException {
562
super(MessageDigest.getInstance("SHA3-384"), true);
563
}
564
}
565
566
/**
567
* Standard SHA3-512withDSA implementation.
568
*/
569
public static final class SHA3_512withDSA extends DSA {
570
public SHA3_512withDSA() throws NoSuchAlgorithmException {
571
super(MessageDigest.getInstance("SHA3-512"));
572
}
573
}
574
575
/**
576
* Standard SHA3-512withDSA implementation that uses the IEEE P1363 format.
577
*/
578
public static final class SHA3_512withDSAinP1363Format extends DSA {
579
public SHA3_512withDSAinP1363Format() throws NoSuchAlgorithmException {
580
super(MessageDigest.getInstance("SHA3-512"), true);
581
}
582
}
583
584
/**
585
* Standard SHA224withDSA implementation as defined in FIPS186-3.
586
*/
587
public static final class SHA224withDSA extends DSA {
588
public SHA224withDSA() throws NoSuchAlgorithmException {
589
super(MessageDigest.getInstance("SHA-224"));
590
}
591
}
592
593
/**
594
* SHA224withDSA implementation that uses the IEEE P1363 format.
595
*/
596
public static final class SHA224withDSAinP1363Format extends DSA {
597
public SHA224withDSAinP1363Format() throws NoSuchAlgorithmException {
598
super(MessageDigest.getInstance("SHA-224"), true);
599
}
600
}
601
602
/**
603
* Standard SHA256withDSA implementation as defined in FIPS186-3.
604
*/
605
public static final class SHA256withDSA extends DSA {
606
public SHA256withDSA() throws NoSuchAlgorithmException {
607
super(MessageDigest.getInstance("SHA-256"));
608
}
609
}
610
611
/**
612
* SHA256withDSA implementation that uses the IEEE P1363 format.
613
*/
614
public static final class SHA256withDSAinP1363Format extends DSA {
615
public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException {
616
super(MessageDigest.getInstance("SHA-256"), true);
617
}
618
}
619
620
/**
621
* Standard SHA384withDSA implementation as defined in FIPS186-3.
622
*/
623
public static final class SHA384withDSA extends DSA {
624
public SHA384withDSA() throws NoSuchAlgorithmException {
625
super(MessageDigest.getInstance("SHA-384"));
626
}
627
}
628
629
/**
630
* SHA384withDSA implementation that uses the IEEE P1363 format.
631
*/
632
public static final class SHA384withDSAinP1363Format extends DSA {
633
public SHA384withDSAinP1363Format() throws NoSuchAlgorithmException {
634
super(MessageDigest.getInstance("SHA-384"), true);
635
}
636
}
637
638
/**
639
* Standard SHA512withDSA implementation as defined in FIPS186-3.
640
*/
641
public static final class SHA512withDSA extends DSA {
642
public SHA512withDSA() throws NoSuchAlgorithmException {
643
super(MessageDigest.getInstance("SHA-512"));
644
}
645
}
646
647
/**
648
* SHA512withDSA implementation that uses the IEEE P1363 format.
649
*/
650
public static final class SHA512withDSAinP1363Format extends DSA {
651
public SHA512withDSAinP1363Format() throws NoSuchAlgorithmException {
652
super(MessageDigest.getInstance("SHA-512"), true);
653
}
654
}
655
656
/**
657
* Standard SHA1withDSA implementation.
658
*/
659
public static final class SHA1withDSA extends DSA {
660
public SHA1withDSA() throws NoSuchAlgorithmException {
661
super(MessageDigest.getInstance("SHA-1"));
662
}
663
}
664
665
/**
666
* SHA1withDSA implementation that uses the IEEE P1363 format.
667
*/
668
public static final class SHA1withDSAinP1363Format extends DSA {
669
public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException {
670
super(MessageDigest.getInstance("SHA-1"), true);
671
}
672
}
673
674
/**
675
* Raw DSA.
676
*
677
* Raw DSA requires the data to be exactly 20 bytes long. If it is
678
* not, a SignatureException is thrown when sign()/verify() is called
679
* per JCA spec.
680
*/
681
static class Raw extends DSA {
682
// Internal special-purpose MessageDigest impl for RawDSA
683
// Only override whatever methods used
684
// NOTE: no clone support
685
public static final class NullDigest20 extends MessageDigest {
686
// 20 byte digest buffer
687
private final byte[] digestBuffer = new byte[20];
688
689
// offset into the buffer; use Integer.MAX_VALUE to indicate
690
// out-of-bound condition
691
private int ofs = 0;
692
693
protected NullDigest20() {
694
super("NullDigest20");
695
}
696
protected void engineUpdate(byte input) {
697
if (ofs == digestBuffer.length) {
698
ofs = Integer.MAX_VALUE;
699
} else {
700
digestBuffer[ofs++] = input;
701
}
702
}
703
protected void engineUpdate(byte[] input, int offset, int len) {
704
if (len > (digestBuffer.length - ofs)) {
705
ofs = Integer.MAX_VALUE;
706
} else {
707
System.arraycopy(input, offset, digestBuffer, ofs, len);
708
ofs += len;
709
}
710
}
711
protected final void engineUpdate(ByteBuffer input) {
712
int inputLen = input.remaining();
713
if (inputLen > (digestBuffer.length - ofs)) {
714
ofs = Integer.MAX_VALUE;
715
} else {
716
input.get(digestBuffer, ofs, inputLen);
717
ofs += inputLen;
718
}
719
}
720
protected byte[] engineDigest() throws RuntimeException {
721
if (ofs != digestBuffer.length) {
722
throw new RuntimeException
723
("Data for RawDSA must be exactly 20 bytes long");
724
}
725
reset();
726
return digestBuffer;
727
}
728
protected int engineDigest(byte[] buf, int offset, int len)
729
throws DigestException {
730
if (ofs != digestBuffer.length) {
731
throw new DigestException
732
("Data for RawDSA must be exactly 20 bytes long");
733
}
734
if (len < digestBuffer.length) {
735
throw new DigestException
736
("Output buffer too small; must be at least 20 bytes");
737
}
738
System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length);
739
reset();
740
return digestBuffer.length;
741
}
742
743
protected void engineReset() {
744
ofs = 0;
745
}
746
protected final int engineGetDigestLength() {
747
return digestBuffer.length;
748
}
749
}
750
751
private Raw(boolean p1363Format) throws NoSuchAlgorithmException {
752
super(new NullDigest20(), p1363Format);
753
}
754
755
}
756
757
/**
758
* Standard Raw DSA implementation.
759
*/
760
public static final class RawDSA extends Raw {
761
public RawDSA() throws NoSuchAlgorithmException {
762
super(false);
763
}
764
}
765
766
/**
767
* Raw DSA implementation that uses the IEEE P1363 format.
768
*/
769
public static final class RawDSAinP1363Format extends Raw {
770
public RawDSAinP1363Format() throws NoSuchAlgorithmException {
771
super(true);
772
}
773
}
774
}
775
776