SHA1withDSA_SignatureTest.java revision e98fbf8686c5289bf03fe5c3de7ff82d3a77104d
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/*
19 * Notes.
20 * 1. The class doesn't contain tests against "update(..)" methods
21 *    invoked on a Signature objects whose state is "INIT" or "VERIFY".
22 *    Relevant checks are in tests against MessageDigest class methods.
23 *
24 * 2. The testSignbyteArrayintint03() is commented out
25 *    because of compatibility with RI issue in current implementation of the Signature class.
26 */
27
28package org.apache.harmony.security.tests.provider.crypto;
29
30import java.math.BigInteger;
31
32import java.security.InvalidKeyException;
33import java.security.KeyPair;
34import java.security.KeyPairGenerator;
35import java.security.PrivateKey;
36import java.security.PublicKey;
37import java.security.SecureRandom;
38import java.security.Signature;
39import java.security.SignatureException;
40
41import java.security.interfaces.DSAParams;
42import java.security.interfaces.DSAPrivateKey;
43import java.security.interfaces.DSAPublicKey;
44import java.security.interfaces.RSAPrivateKey;
45import java.security.interfaces.RSAPublicKey;
46
47import java.security.spec.DSAParameterSpec;
48
49import junit.framework.Test;
50import junit.framework.TestCase;
51import junit.framework.TestSuite;
52
53public class SHA1withDSA_SignatureTest extends TestCase {
54
55    private static final String algorithm = "SHA1withDSA";
56
57    private static final String provider = "Crypto";
58
59    private static final String provider1 = "BC"; // see testVerifybyteArray04()
60
61    private Signature signs[];
62
63    private Signature signingSigns[];
64
65    private Signature verifyingSign;
66
67    private static KeyPair keys;
68
69    private static KeyPairGenerator keyPairGenerator;
70
71    private static final BigInteger MINUS_ONE = BigInteger.valueOf(-1);
72
73    private static final BigInteger params[][] = new BigInteger[][] {
74            { BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO },
75            { BigInteger.ZERO, BigInteger.ZERO, BigInteger.ONE },
76            { BigInteger.ZERO, BigInteger.ONE, BigInteger.ONE },
77            { BigInteger.ONE, BigInteger.ZERO, BigInteger.ONE },
78            { BigInteger.ONE, BigInteger.ONE, BigInteger.ONE },
79            { MINUS_ONE, MINUS_ONE, MINUS_ONE },
80            { BigInteger.ONE, BigInteger.ONE, MINUS_ONE },
81            { MINUS_ONE, BigInteger.ONE, BigInteger.ONE },
82            { BigInteger.ONE, MINUS_ONE, BigInteger.ONE }, };
83
84    private static PrivateKey privateKey;
85
86    private static PublicKey publicKey;
87
88    private static PrivateKey privateKey2;
89
90    private static PublicKey publicKey2;
91
92    private static PrivateKey myRSAPrivateKey;
93
94    private static PublicKey myRSAPublicKey;
95
96    private static SecureRandom mySecureRandom;
97
98    private static byte signature[];
99
100    private static byte bytes1[] = new byte[1000];
101
102    private static byte bytes2[] = new byte[10];
103
104    private static byte message[] = new byte[1000];
105
106    // offset to use in corresponding methods
107    private static int offset;
108
109    private static boolean flag;
110
111    static {
112        try {
113            keyPairGenerator = KeyPairGenerator.getInstance("DSA");
114
115            keyPairGenerator.initialize(1024);
116            keys = keyPairGenerator.generateKeyPair();
117
118            privateKey = keys.getPrivate();
119            publicKey = keys.getPublic();
120
121            privateKey2 = Predefined.getPrivateKey();
122            publicKey2 = Predefined.getPublicKey();
123
124            myRSAPrivateKey = getRSAPrivateKey();
125            myRSAPublicKey = getRSAPublicKey();
126
127            mySecureRandom = new SecureRandom();
128
129            mySecureRandom.nextBytes(bytes1);
130            mySecureRandom.nextBytes(bytes2);
131            mySecureRandom.nextBytes(message);
132
133            byte myByte[] = new byte[1];
134            mySecureRandom.nextBytes(myByte);
135            offset = myByte[0] & 037;
136
137            flag = true;
138        } catch (Exception e) {
139            flag = false;
140        }
141    }
142
143    /*
144     * @see TestCase#setUp()
145     */
146    protected void setUp() throws Exception {
147
148        if (!flag) {
149            throw new Exception("some problem in static initializer");
150        }
151
152        super.setUp();
153
154        signs = new Signature[] { Signature.getInstance(algorithm, provider),
155                Signature.getInstance(algorithm, provider),
156                Signature.getInstance(algorithm, provider),
157                Signature.getInstance(algorithm, provider),
158                Signature.getInstance(algorithm, provider) };
159
160        signs[1].initSign(privateKey);
161        signs[2].initSign(privateKey, null);
162        signs[3].initSign(privateKey, mySecureRandom);
163        signs[4].initVerify(publicKey);
164
165        signingSigns = new Signature[] { signs[1], signs[2], signs[3] };
166        verifyingSign = signs[4];
167    }
168
169    static private DSAPrivateKey getDSAPrivateKey(BigInteger p, BigInteger q,
170            BigInteger g, BigInteger x) {
171        final BigInteger pp = p;
172        final BigInteger qq = q;
173        final BigInteger gg = g;
174        final BigInteger xx = x;
175
176        return new DSAPrivateKey() {
177
178            public BigInteger getX() {
179                return xx;
180            }
181
182            public DSAParams getParams() {
183                BigInteger p = pp;
184                BigInteger q = qq;
185                BigInteger g = gg;
186                return new DSAParameterSpec(p, q, g);
187            }
188
189            public String getAlgorithm() {
190                return "dummy";
191            }
192
193            public byte[] getEncoded() {
194                return new byte[0];
195            }
196
197            public String getFormat() {
198                return "dummy";
199            }
200        };
201    }
202
203    static private DSAPublicKey getDSAPublicKey(BigInteger p, BigInteger q,
204            BigInteger g, BigInteger y) {
205        final BigInteger pp = p;
206        final BigInteger qq = q;
207        final BigInteger gg = g;
208        final BigInteger yy = y;
209
210        return new DSAPublicKey() {
211
212            public BigInteger getY() {
213                return yy;
214            }
215
216            public DSAParams getParams() {
217                BigInteger p = pp;
218                BigInteger q = qq;
219                BigInteger g = gg;
220                return new DSAParameterSpec(p, q, g);
221            }
222
223            public String getAlgorithm() {
224                return "dummy";
225            }
226
227            public byte[] getEncoded() {
228                return new byte[0];
229            }
230
231            public String getFormat() {
232                return "dummy";
233            }
234        };
235    }
236
237    static private RSAPrivateKey getRSAPrivateKey() {
238
239        return new RSAPrivateKey() {
240
241            public BigInteger getPrivateExponent() {
242                return BigInteger.ZERO;
243            }
244
245            public BigInteger getModulus() {
246                return BigInteger.ZERO;
247            }
248
249            public String getAlgorithm() {
250                return "RSA";
251            }
252
253            public byte[] getEncoded() {
254                return new byte[] { 0 };
255            }
256
257            public String getFormat() {
258                return "fff";
259            }
260        };
261    }
262
263    static private RSAPublicKey getRSAPublicKey() {
264
265        return new RSAPublicKey() {
266
267            public BigInteger getPublicExponent() {
268                return BigInteger.ZERO;
269            }
270
271            public BigInteger getModulus() {
272                return BigInteger.ZERO;
273            }
274
275            public String getAlgorithm() {
276                return "RSA";
277            }
278
279            public byte[] getEncoded() {
280                return new byte[] { 0 };
281            }
282
283            public String getFormat() {
284                return "fff";
285            }
286        };
287    }
288
289    /**
290     * The test against "initSign(PrivateKey)" method.
291     * It checks out that regardless of a Signature object's state
292     * the method throws InvalidKeyException if PrivateKey is null or not DSAPrivateKey
293     */
294    public final void testInitSignPrivateKey01() {
295
296        for (int i = 0; i < signs.length; i++) {
297            try {
298                signs[i].initSign(null);
299                fail("case1: no InvalidKeyException : i=" + i);
300            } catch (InvalidKeyException e) {}
301            try {
302                signs[i].initSign(myRSAPrivateKey);
303                fail("case: no InvalidKeyException : i=" + i);
304            } catch (InvalidKeyException e) {}
305        }
306    }
307
308    /**
309     * The test against "initSign(PrivateKey)" method.
310     * It checks out that regardless of a Signature object's state
311     * the method throws InvalidKeyException if
312     * PrivateKey is DSAPrivateKey and the key is invalid, that is,
313     * BigIntegers constituting the key have incorrect values.
314     */
315    public final void testInitSignPrivateKey02() throws Exception {
316
317        for (int i = 0; i < signs.length; i++) {
318            for (int j = 0; j < params.length; j++) {
319                try {
320                    signs[i].initSign(getDSAPrivateKey(params[j][0],
321                            params[j][1], params[j][2], BigInteger.ZERO));
322                    fail("no InvalidKeyException : i =" + i + " j=" + j);
323                } catch (InvalidKeyException e) {}
324            }
325        }
326    }
327
328    /**
329     * The test against the "initSign(PrivateKey)" method.
330     * It checks out that the method negates the effect of previous call
331     * if it is invoked with a different argument.
332     *
333     * Note.
334     * In RI, negating effect of previous call includes
335     * discarding updates done before calling the method.
336     */
337    public final void testInitSignPrivateKey03() throws Exception {
338
339        // Initially all signing Signature objects are initialized with some PublicKey
340        // and the "verifyingSign" object with corresponding PrivateKey.
341
342        verifyingSign.initVerify(publicKey2);
343
344        for (int i = 0; i < signingSigns.length; i++) {
345
346            signingSigns[i].update(bytes1, 0, bytes1.length);
347
348            signingSigns[i].initSign(privateKey2); // another PrivateKey
349
350            signingSigns[i].update(bytes2, 0, bytes2.length);
351            signature = signingSigns[i].sign();
352
353            // it is expected that "signature" is one generated only for "bytes2" update
354
355            verifyingSign.update(bytes2, 0, bytes2.length);
356            assertTrue("returned 'false' : i=" + i, verifyingSign
357                    .verify(signature));
358        }
359    }
360
361    /**
362     * The test against the "initSign(PrivateKey)" method.
363     * It checks out that the method negates the effect of previous call
364     * if it is invoked with the same argument.
365     *
366     * Notes.
367     * 1. In RI, negating effect of previous call includes
368     *    discarding updates done before calling the method.
369     * 2.
370     * The specification for the method contains the following clause:
371     *     "If this method is called again with a different argument,
372     *     it negates the effect of this call."
373     * which meaning requires certainty in case of sequence
374     *    initSign - update - initSign
375     * RI behavior is such that with respect to "update"
376     * it doesn't matter whether argument is the same or different.
377     */
378    public final void testInitSignPrivateKey04() throws Exception {
379
380        for (int i = 0; i < signingSigns.length; i++) {
381
382            signingSigns[i].update(bytes1, 0, bytes1.length);
383
384            signingSigns[i].initSign(privateKey); // the same PrivateKey
385
386            signingSigns[i].update(bytes2, 0, bytes2.length);
387            signature = signingSigns[i].sign();
388
389            // it is expected that "signature" is one generated only for "bytes2" update
390
391            verifyingSign.update(bytes2, 0, bytes2.length);
392            assertTrue("returned 'false' : i=" + i, verifyingSign
393                    .verify(signature));
394        }
395    }
396
397    /**
398     * The test against "initVerify(PublicKey)" methods
399     * It checks out that regardless of a Signature object's state
400     * the method throws InvalidKeyException if
401     * PublicKey is null or is not DSAPublicKey
402     */
403    public final void testInitVerifyPublicKey01() {
404
405        PublicKey pk = null;
406
407        for (int i = 0; i < signs.length; i++) {
408            try {
409                signs[i].initVerify(pk);
410                fail("case1 : no InvalidKeyException i=" + i);
411            } catch (InvalidKeyException e) {}
412            try {
413                signs[i].initVerify(myRSAPublicKey);
414                fail("case2 : no InvalidKeyException i=" + i);
415            } catch (InvalidKeyException e) {}
416        }
417    }
418
419    /**
420     * The test against "initSign(PrivateKey)" method.
421     * It checks out that regardless of a Signature object's state
422     * the method throws InvalidKeyException if
423     * PublicKey is DSAPublicKey and the key is invalid, that is,
424     * BigIntegers constituting the key have incorrect values.
425     */
426    public final void testInitVerifyPublicKey02() throws Exception {
427
428        for (int i = 0; i < signs.length; i++) {
429            for (int j = 0; j < params.length; j++) {
430                try {
431                    signs[i].initVerify(getDSAPublicKey(params[j][0],
432                            params[j][1], params[j][2], BigInteger.ZERO));
433                    fail("no InvalidKeyException : i=" + i + " j=" + j);
434                } catch (InvalidKeyException e) {}
435            }
436        }
437    }
438
439    /**
440     * The test against the "initVerify(PublicKey)" method.
441     * It checks out that the method negates the effect of previous call
442     * if it is invoked with a different argument,
443     * that is, after initializing with PublicKey from another KeyPair
444     * the "verify" method returns "false".
445     */
446    public final void testInitVerifyPublicKey03() throws Exception {
447
448        signingSigns[0].update(bytes1, 0, bytes1.length);
449        signature = signingSigns[0].sign();
450
451        verifyingSign.initVerify(publicKey2); // another key
452        verifyingSign.update(bytes1, 0, bytes1.length);
453        assertFalse("case1: returned 'true'", verifyingSign.verify(signature));
454    }
455
456    /**
457     * The test against the "initVerify(PublicKey)" method.
458     * It checks out that the method negates the effect of previous call
459     * if it is invoked with the same argument.
460     * Like it is for "initSign", RI behavior is such that with respect to "update"
461     * it doesn't matter whether argument is the same or different.
462     *
463     * Note.
464     * In RI negating effect of previous call includes
465     * discarding updates done before calling the method.
466     */
467    public final void testInitVerifyPublicKey04() throws Exception {
468
469        signingSigns[0].update(bytes1, 0, bytes1.length);
470        signature = signingSigns[0].sign();
471
472        verifyingSign.update(bytes2, 0, bytes2.length);
473
474        verifyingSign.initVerify(publicKey); // the same key
475        verifyingSign.update(bytes1, 0, bytes1.length);
476        assertTrue("case2: returned 'false'", verifyingSign.verify(signature));
477    }
478
479    /*
480     * The method returns
481     * -  -1 if a signature's syntax is incorrect
482     * -  length of the signature otherwise.
483     */
484    private int checkSignature(byte sig[], int offset) {
485
486        int n1 = sig[offset + 3];
487        int n2 = sig[offset + n1 + 5];
488
489        if (sig[offset] != 0x30 || sig[offset + 1] != (n1 + n2 + 4)
490                || sig[offset + 2] != 2 || sig[offset + n1 + 4] != 2 || n1 > 21
491                || n2 > 21) {
492            return -1;
493        }
494        return (n1 + n2 + 6);
495    }
496
497    /**
498     * The test against the "sign()" method.
499     * It checks out that Signature object returned by the method has correct ASN1 encoding.
500     */
501    public final void testSign01() throws Exception {
502
503        byte sig[];
504
505        for (int i = 0; i < signingSigns.length; i++) {
506
507            signingSigns[i].update(message);
508
509            sig = signingSigns[i].sign();
510
511            try {
512                int n = checkSignature(sig, 0);
513                if (n < 0) {
514                    fail("incorrect signature : i=" + i);
515                }
516                if (n != sig.length) {
517                    fail("incorrect signature's length : n=" + n
518                            + " sig.length= " + sig.length);
519                }
520            } catch (ArrayIndexOutOfBoundsException e) {
521                fail("incorrect signature: " + e);
522            }
523        }
524    }
525
526    /**
527     * The test against the "sign(byte[], int, int)" method.
528     * It checks out that Signature object returned by the method has correct ASN1 encoding.
529     */
530    public final void testSignbyteArrayintint01() throws Exception {
531
532        byte sig[] = new byte[offset + 100];
533
534        for (int i = 0; i < signingSigns.length; i++) {
535            int n1;
536
537            signingSigns[i].update(message);
538
539            n1 = signingSigns[i].sign(sig, offset, 50);
540
541            try {
542                int n2 = checkSignature(sig, offset);
543                if (n2 < 0) {
544                    fail("signature bytes have invalid encoding");
545                }
546                if (n1 != n2) {
547                    fail("incorrect signature's length : n1=" + n1 + " n2="
548                            + n2);
549                }
550            } catch (ArrayIndexOutOfBoundsException e) {
551                fail("incorrect signature: " + e);
552            }
553        }
554    }
555
556    /**
557     * The test agains the "sign(byte[], int, int)" method.
558     * It checks out that if a Signature object's state is SIGN
559     * passing to the object "offset" and "len" arguments that satisfy the condition:
560     *     "offset + len <= outbuf.length"
561     * but "len" < actual length of signature results in throwing SignatureException.
562     *
563     * Note.
564     * As signature's length varies we use length value of 44 which is certainly less than signature's length,
565     */
566    public final void testSignbyteArrayintint02() throws Exception {
567
568        byte sig[] = new byte[50];
569
570        for (int i = 0; i < signingSigns.length; i++) {
571
572            signingSigns[i].update(message);
573
574            try {
575                signingSigns[i].sign(sig, 0, 44);
576                fail("case1 : no SignatureException : i=" + i);
577            } catch (SignatureException e) {}
578        }
579    }
580
581    /**
582     * The test agains the "sign(byte[], int, int)" method.
583     * It checks out that if a Signature object's state is SIGN
584     * passing to the object "offset" and "len" arguments that satisfy the condition:
585     *     "offset < 0" and "len" >= actual length of signature
586     * results in throwing ArrayIndexOutOfBoundsException.
587     */
588    //     public final void testSignbyteArrayintint03() throws Exception {
589    //
590    //        byte sig[] = new byte[50];
591    //
592    //        for ( int i = 0; i < signingSigns.length; i++ ) {
593    //
594    //            signingSigns[i].update(message);
595    //
596    //            // because 50 is more than length of any signature,
597    //            // for offset==-1 and len==50 ArrayIndexOutOfBoundsException is expected
598    //            //
599    //            try {
600    //                signingSigns[i].sign(sig, -1, 50);
601    //                fail("no ArrayIndexOutOfBoundsException");
602    //            } catch (ArrayIndexOutOfBoundsException e) {
603    //            }
604    //
605    //            // because 40 is less than length of any signature",
606    //            //for offset==-1 and len==40 ArrayIndexOutOfBoundsException is not expected
607    //            //
608    //            try {
609    //                signingSigns[i].sign(sig, -1, 40);
610    //                fail("no SignatureException");
611    //            } catch (ArrayIndexOutOfBoundsException e) {
612    //                fail("ArrayIndexOutOfBoundsException");
613    //            } catch (SignatureException e) {
614    //            }
615    //        }
616    //    }
617
618    /**
619     * The test against the "verify(byte[])" method.
620     * It checks out that for given message and signature signed with some PrivateKey
621     * (1) the method returns "true" if PublicKey is from the same KeyPair,
622     * (2) the method returns "false" otherwise.
623     */
624    public final void testVerifybyteArray01() throws Exception {
625
626        byte sigBytes[];
627
628        signingSigns[0].update(message);
629        sigBytes = signingSigns[0].sign();
630
631        verifyingSign.update(message);
632        assertTrue("case1: test failure", verifyingSign.verify(sigBytes));
633
634        verifyingSign.initVerify(publicKey2);
635
636        verifyingSign.update(message);
637        assertFalse("case2: test failure", verifyingSign.verify(sigBytes));
638    }
639
640    /**
641     * The test is against the pair "sign() - verify(byte[])" method.
642     * It checks out that the "verify" method returns "true"
643     * if a verifying Signature object was updated with the same message
644     * which was used to update a signing Signature object.
645     */
646    public final void testVerifybyteArray02() throws Exception {
647
648        byte sig1[];
649        byte sig2[];
650
651        for (int i = 0; i < signingSigns.length; i++) {
652
653            signingSigns[i].update(bytes1);
654            verifyingSign.update(bytes1);
655
656            sig1 = signingSigns[i].sign();
657
658            assertTrue("case 1: test failure : i=" + i, verifyingSign
659                    .verify(sig1));
660
661            signingSigns[i].update(bytes1);
662            signingSigns[i].update(bytes2);
663            verifyingSign.update(bytes1);
664            verifyingSign.update(bytes2);
665
666            sig2 = signingSigns[i].sign();
667
668            assertTrue("case 2: test failure : i=" + i, verifyingSign
669                    .verify(sig2));
670
671            verifyingSign.update(bytes1);
672            verifyingSign.update(bytes2);
673            assertFalse("case 3: test failure : i=" + i, verifyingSign
674                    .verify(sig1));
675        }
676    }
677
678    /**
679     * The compatibility with RI test.
680     * It checks out that
681     * for the predefined message and signature signed with PrivateKey from RI
682     * the method invoked on a Signature object initialized with corresponding PublicKey from RI
683     * returns "true".
684     */
685    public final void testVerifybyteArray03() throws Exception {
686
687        verifyingSign.initVerify(publicKey2);
688        verifyingSign.update(Predefined.getMessage());
689        assertTrue("not verified", verifyingSign.verify(Predefined
690                .getSignature()));
691    }
692
693    /**
694     * The test against the pair "sign - verify" methods.
695     * Its specific is that signing and verifying are performed by two providers,
696     * provider and provider1;
697     * so, the test checks up on compatibility signing-verifying between implementations.
698     */
699    public final void testVerifybyteArray04() throws Exception {
700
701        Signature signingSign, verifyingSign;
702
703        byte sigBytes[];
704
705        byte message[] = new byte[1000];
706
707        // testcase1 - signing with "provider", verifying with "provider1"
708
709        signingSign = Signature.getInstance(algorithm, provider);
710        verifyingSign = Signature.getInstance(algorithm, provider1);
711
712        mySecureRandom.nextBytes(message);
713
714        signingSign.initSign(privateKey);
715        signingSign.update(message);
716        sigBytes = signingSign.sign();
717
718        verifyingSign.initVerify(publicKey);
719        verifyingSign.update(message);
720        assertTrue("case1: test failure", verifyingSign.verify(sigBytes));
721
722        // testcase2 - signing with "provider1", verifying with "provider"
723
724        signingSign = Signature.getInstance(algorithm, provider1);
725        verifyingSign = Signature.getInstance(algorithm, provider);
726
727        mySecureRandom.nextBytes(message);
728
729        signingSign.initSign(privateKey);
730        signingSign.update(message);
731        sigBytes = signingSign.sign();
732
733        verifyingSign.initVerify(publicKey);
734        verifyingSign.update(message);
735        assertTrue("case2: test failure", verifyingSign.verify(sigBytes));
736    }
737
738    /**
739     * The test against the "verify(byte[], int, int)" method.
740     * It checks out that if Signature object's state is VERIFY
741     * the method throws IllegalArgumentException in case of the following arguments :
742     *       outbufs == null or
743     *       offset < 0      or
744     *       length < 0      or
745     *       offset+length > outbuf.length
746     */
747    public final void testVerifybyteArrayintint01() throws Exception {
748
749        byte bArray[] = new byte[100];
750
751        // case1 : null byte array
752        try {
753            verifyingSign.verify(null, 0, 48);
754            fail("case1 : no IllegalArgumentException");
755        } catch (IllegalArgumentException e) {}
756
757        // case2 : len < 0
758        try {
759            verifyingSign.verify(bArray, 0, -1);
760            fail("case2 : no IllegalArgumentException");
761        } catch (IllegalArgumentException e) {}
762
763        // case3 : offset < 0
764        try {
765            verifyingSign.verify(bArray, -1, 48);
766            fail("case3: no IllegalArgumentException");
767        } catch (IllegalArgumentException e) {}
768
769        // case4 : offset+len > outbuf.length
770        try {
771            int k = bArray.length / 2;
772            verifyingSign.verify(bArray, k, bArray.length - k + 1);
773            fail("case4: no IllegalArgumentException");
774        } catch (IllegalArgumentException e) {}
775    }
776
777    /**
778     * The test against the "verify(byte[], int, int)" method.
779     * It checks out that if Signature object's state is VERIFY
780     * the method throws up SignatureException if
781     * (1) offset+length < 0
782     * (2) offset > signature.length
783     * (3) SignatureException if outbuf's lentgh is correct
784     *     whereas a signature doesn't meet ASN1 syntax.
785     */
786    public final void testVerifybyteArrayintint02() throws Exception {
787
788        byte sigBytes[] = new byte[100]; // wrong signature
789
790        try {
791            verifyingSign.verify(sigBytes, Integer.MAX_VALUE, 2);
792            fail("testcase1 : no SignatureException");
793        } catch (SignatureException e) {}
794
795        try {
796            verifyingSign.verify(sigBytes, 2, Integer.MAX_VALUE);
797            fail("testcase2 : no SignatureException");
798        } catch (SignatureException e) {}
799
800        verifyingSign.update(message);
801        try {
802            verifyingSign.verify(sigBytes, 0, 50);
803            fail("testcase3 : SignatureException");
804        } catch (SignatureException e) {}
805    }
806
807    /**
808     * The test is against the "verify(byte[], int, int)" method.
809     * It checks out that in case of correct signature the method throws SignatureException
810     * if value of "length" is less than signature's length
811     */
812    public final void testVerifybyteArrayintint03() throws Exception {
813
814        byte sig[] = new byte[offset + 100];
815
816        verifyingSign.update(message);
817
818        for (int i = 0; i < signingSigns.length; i++) {
819            int n;
820
821            signingSigns[i].update(message);
822            n = signingSigns[i].sign(sig, offset, 50);
823
824            try {
825                verifyingSign.verify(sig, offset, n - 1);
826                fail("test failure : i=" + i + " offset=" + offset);
827            } catch (SignatureException e) {
828                verifyingSign.verify(sig, offset, n);
829            }
830        }
831    }
832
833    /**
834     * The test against the "verify(byte[], int, int)" method.
835     * It check out that if a call to the method returns normally
836     * a Signature object resets itself.
837     */
838    public final void testVerifybyteArrayintint04() throws Exception {
839
840        byte sig[] = new byte[100];
841        int n = 0;
842        ;
843
844        byte sigBytes[] = new byte[100]; // bytes for correct signature
845
846        // the signature has correct ASN1 syntax but its value is negative;
847        // so, the "verify(...)" methods should return "false" without throwing an exception
848        sig[0] = 48;
849        sig[1] = 44;
850        sig[2] = 2;
851        sig[3] = 20;
852        sig[4] = (byte) 0x8f; // negative value
853        sig[24] = 2;
854        sig[25] = 20;
855        sig[26] = (byte) 0x8f; // negative value
856
857        signingSigns[0].update(message);
858        n = signingSigns[0].sign(sigBytes, 0, 50);
859
860        // testcase1: first call returns true,
861        // second returns false though signature is the same
862
863        verifyingSign.update(message);
864
865        assertTrue("case1: test failure", verifyingSign.verify(sigBytes, 0, n));
866        assertFalse("case2: test failure", verifyingSign.verify(sigBytes, 0, n));
867
868        // testcase2: first call returns false (incorrect signature),
869        // second returns false too, in spite of correct signature (!),
870        // because Signature object was reset in first call
871
872        verifyingSign.update(message);
873
874        assertFalse("case3: test failure", verifyingSign.verify(sig, 0, 46));
875        assertFalse("case4: test failure", verifyingSign.verify(sigBytes, 0, n));
876    }
877
878    /**
879     * The test against the "verify(byte[], int, int)" method.
880     * It check out that a Signature object doesn't reset itself if
881     * the method throws up an exception.
882     */
883    public final void testVerifybyteArrayintint05() throws Exception {
884
885        byte sig[] = new byte[100]; //incorrect signature
886
887        byte sigBytes[] = new byte[100];
888        int n = 0;
889
890        signingSigns[0].update(message);
891        n = signingSigns[0].sign(sigBytes, 0, 50);
892
893        verifyingSign.update(message);
894
895        try {
896            verifyingSign.verify(null, 0, n);
897        } catch (IllegalArgumentException e) {}
898
899        try {
900            verifyingSign.verify(sigBytes, -1, n);
901        } catch (IllegalArgumentException e) {}
902
903        try {
904            verifyingSign.verify(sigBytes, 0, -1);
905        } catch (IllegalArgumentException e) {}
906
907        try {
908            verifyingSign.verify(sigBytes, sigBytes.length - 10, 30);
909        } catch (IllegalArgumentException e) {}
910
911        try {
912            verifyingSign.verify(sigBytes, Integer.MAX_VALUE, n);
913        } catch (SignatureException e) {}
914
915        try {
916            verifyingSign.verify(sig, 0, n);
917        } catch (SignatureException e) {}
918
919        // if the method doesn't reset the expected result of verificaton is "true"
920
921        assertTrue("test failure : n=" + n, verifyingSign
922                .verify(sigBytes, 0, n));
923    }
924
925    /**
926     * The test is against the pair "sign(byte[],int,int) - verify(byte[],int,int)" method.
927     * It checks out that the "verify" method returns "true"
928     * if a verifying Signature object was updated with the same message
929     * which was used to update a signing Signature object.
930     */
931    public final void testVerifybyteArrayintint06() throws Exception {
932
933        byte sig1[] = new byte[offset + 100];
934        byte sig2[] = new byte[offset + 100];
935
936        int n1, n2;
937
938        for (int i = 0; i < signingSigns.length; i++) {
939
940            signingSigns[i].update(bytes1);
941            verifyingSign.update(bytes1);
942
943            n1 = signingSigns[i].sign(sig1, offset, 50);
944
945            assertTrue("case 1: test failure : i=" + i + " offset=" + offset,
946                    verifyingSign.verify(sig1, offset, n1));
947
948            signingSigns[i].update(bytes1);
949            signingSigns[i].update(bytes2);
950            verifyingSign.update(bytes1);
951            verifyingSign.update(bytes2);
952
953            n2 = signingSigns[i].sign(sig2, offset, 50);
954
955            assertTrue("case 2: test failure : i=" + i + " offset=" + offset,
956                    verifyingSign.verify(sig2, offset, n2));
957
958            verifyingSign.update(bytes1);
959            verifyingSign.update(bytes2);
960            assertFalse("case 3: test failure : i=" + i + " offset=" + offset,
961                    verifyingSign.verify(sig1, offset, n1));
962        }
963    }
964
965    public static Test suite() {
966        return new TestSuite(SHA1withDSA_SignatureTest.class);
967    }
968
969}
970
971class Predefined {
972
973    static DSAPublicKey publicKey = new DSAPublicKey() {
974
975        byte yb[] = new byte[] { 91, 91, -5, 113, -35, 61, -111, -29, -59, -5,
976                -53, -72, 93, 38, 81, 10, -75, 122, -60, -88, -74, -91, -108,
977                88, 55, -57, 119, -2, -104, -71, 83, 45, -55, -111, 46, -23,
978                -113, -34, 105, 18, -36, -33, 3, 21, 23, 93, -128, -52, 42,
979                -11, 55, 50, -27, 51, 49, 50, -20, -92, -120, -56, 28, -114,
980                -30, 36, -91, -102, 39, -50, -104, -73, -94, -34, -99, -25, 76,
981                -40, 4, -89, 1, -107, -66, -87, -112, 22, -40, -118, 59, -26,
982                90, -90, -103, -75, -104, 26, -31, 54, -95, 105, 67, -4, -44,
983                35, -75, 0, -69, 60, 65, -78, 49, 5, 1, 111, -122, 83, 22, -35,
984                -65, 122, 120, -104, -78, -25, -35, 12, -106, 101, 21, 33 };
985
986        byte pb[] = new byte[] { 0, -3, 127, 83, -127, 29, 117, 18, 41, 82,
987                -33, 74, -100, 46, -20, -28, -25, -10, 17, -73, 82, 60, -17,
988                68, 0, -61, 30, 63, -128, -74, 81, 38, 105, 69, 93, 64, 34, 81,
989                -5, 89, 61, -115, 88, -6, -65, -59, -11, -70, 48, -10, -53,
990                -101, 85, 108, -41, -127, 59, -128, 29, 52, 111, -14, 102, 96,
991                -73, 107, -103, 80, -91, -92, -97, -97, -24, 4, 123, 16, 34,
992                -62, 79, -69, -87, -41, -2, -73, -58, 27, -8, 59, 87, -25, -58,
993                -88, -90, 21, 15, 4, -5, -125, -10, -45, -59, 30, -61, 2, 53,
994                84, 19, 90, 22, -111, 50, -10, 117, -13, -82, 43, 97, -41, 42,
995                -17, -14, 34, 3, 25, -99, -47, 72, 1, -57 };
996
997        byte qb[] = new byte[] { 0, -105, 96, 80, -113, 21, 35, 11, -52, -78,
998                -110, -71, -126, -94, -21, -124, 11, -16, 88, 28, -11 };
999
1000        byte gb[] = new byte[] { 0, -9, -31, -96, -123, -42, -101, 61, -34,
1001                -53, -68, -85, 92, 54, -72, 87, -71, 121, -108, -81, -69, -6,
1002                58, -22, -126, -7, 87, 76, 11, 61, 7, -126, 103, 81, 89, 87,
1003                -114, -70, -44, 89, 79, -26, 113, 7, 16, -127, -128, -76, 73,
1004                22, 113, 35, -24, 76, 40, 22, 19, -73, -49, 9, 50, -116, -56,
1005                -90, -31, 60, 22, 122, -117, 84, 124, -115, 40, -32, -93, -82,
1006                30, 43, -77, -90, 117, -111, 110, -93, 127, 11, -6, 33, 53, 98,
1007                -15, -5, 98, 122, 1, 36, 59, -52, -92, -15, -66, -88, 81, -112,
1008                -119, -88, -125, -33, -31, 90, -27, -97, 6, -110, -117, 102,
1009                94, -128, 123, 85, 37, 100, 1, 76, 59, -2, -49, 73, 42 };
1010
1011        public BigInteger getY() {
1012            return new BigInteger(yb);
1013        }
1014
1015        public DSAParams getParams() {
1016            BigInteger p = new BigInteger(pb);
1017            BigInteger q = new BigInteger(qb);
1018            BigInteger g = new BigInteger(gb);
1019            return (DSAParams) (new DSAParameterSpec(p, q, g));
1020        }
1021
1022        public String getAlgorithm() {
1023            return "DSA";
1024        }
1025
1026        public byte[] getEncoded() {
1027            return null;
1028        }
1029
1030        public String getFormat() {
1031            return null;
1032        }
1033    };
1034
1035    static DSAPrivateKey privateKey = new DSAPrivateKey() {
1036
1037        byte xb[] = new byte[] { 12, 31, -39, 65, -61, -54, -91, 37, -93, -115,
1038                81, 122, -24, -104, -31, -106, 113, -39, -69, 34 };
1039
1040        byte pb[] = new byte[] { 0, -3, 127, 83, -127, 29, 117, 18, 41, 82,
1041                -33, 74, -100, 46, -20, -28, -25, -10, 17, -73, 82, 60, -17,
1042                68, 0, -61, 30, 63, -128, -74, 81, 38, 105, 69, 93, 64, 34, 81,
1043                -5, 89, 61, -115, 88, -6, -65, -59, -11, -70, 48, -10, -53,
1044                -101, 85, 108, -41, -127, 59, -128, 29, 52, 111, -14, 102, 96,
1045                -73, 107, -103, 80, -91, -92, -97, -97, -24, 4, 123, 16, 34,
1046                -62, 79, -69, -87, -41, -2, -73, -58, 27, -8, 59, 87, -25, -58,
1047                -88, -90, 21, 15, 4, -5, -125, -10, -45, -59, 30, -61, 2, 53,
1048                84, 19, 90, 22, -111, 50, -10, 117, -13, -82, 43, 97, -41, 42,
1049                -17, -14, 34, 3, 25, -99, -47, 72, 1, -57 };
1050
1051        byte qb[] = new byte[] { 0, -105, 96, 80, -113, 21, 35, 11, -52, -78,
1052                -110, -71, -126, -94, -21, -124, 11, -16, 88, 28, -11 };
1053
1054        byte gb[] = new byte[] { 0, -9, -31, -96, -123, -42, -101, 61, -34,
1055                -53, -68, -85, 92, 54, -72, 87, -71, 121, -108, -81, -69, -6,
1056                58, -22, -126, -7, 87, 76, 11, 61, 7, -126, 103, 81, 89, 87,
1057                -114, -70, -44, 89, 79, -26, 113, 7, 16, -127, -128, -76, 73,
1058                22, 113, 35, -24, 76, 40, 22, 19, -73, -49, 9, 50, -116, -56,
1059                -90, -31, 60, 22, 122, -117, 84, 124, -115, 40, -32, -93, -82,
1060                30, 43, -77, -90, 117, -111, 110, -93, 127, 11, -6, 33, 53, 98,
1061                -15, -5, 98, 122, 1, 36, 59, -52, -92, -15, -66, -88, 81, -112,
1062                -119, -88, -125, -33, -31, 90, -27, -97, 6, -110, -117, 102,
1063                94, -128, 123, 85, 37, 100, 1, 76, 59, -2, -49, 73, 42 };
1064
1065        public BigInteger getX() {
1066            return new BigInteger(xb);
1067        }
1068
1069        public DSAParams getParams() {
1070            BigInteger p = new BigInteger(pb);
1071            BigInteger q = new BigInteger(qb);
1072            BigInteger g = new BigInteger(gb);
1073            return (DSAParams) (new DSAParameterSpec(p, q, g));
1074        }
1075
1076        public String getAlgorithm() {
1077            return "DSA";
1078        }
1079
1080        public byte[] getEncoded() {
1081            return null;
1082        }
1083
1084        public String getFormat() {
1085            return null;
1086        }
1087    };
1088
1089    static byte msg[] = new byte[] { -126, -74, -45, -105, 31, 30, 76, -78, 56,
1090            31, -67, -7, 40, 36, -59, -1, -41, -46, -63, -98, -10, -56, 18, 69,
1091            107, -118, -70, -9, -32, 49, -48, 11, -73, 98, -67, 82, 96, 126,
1092            24, -40, -15, 20, 81, 103, 119, -114, -9, -85, 56, 20, -98, 89,
1093            -37, 34, -44, 19, -19, -126, -87, -40, -102, -96, 102, -30, 30,
1094            115, -68, -108, -44, 88, -65, 35, 85, 123, -1, -82, 110, 67, 99,
1095            84, -32, 44, 67, 75, -121, 28, -128, 49, -54, 52, 53, 119, -114,
1096            -99, -61, -58, -119, -97, 91, 66 };
1097
1098    static byte sig[] = new byte[] { 48, 44, 2, 20, 33, -6, -66, -52, 17, -91,
1099            -90, 83, -128, 73, -114, 49, 118, 82, -65, 123, -19, 94, -26, 106,
1100            2, 20, 59, 75, -86, -115, 94, -125, 80, -91, -57, 61, -73, -5,
1101            -109, -93, 103, -10, -73, -21, 99, 81 };
1102
1103    static byte[] getMessage() {
1104        return msg;
1105    }
1106
1107    static byte[] getSignature() {
1108        return sig;
1109    }
1110
1111    static int getSignatureLength() {
1112        return sig.length;
1113    }
1114
1115    static DSAPublicKey getPublicKey() {
1116        return publicKey;
1117    }
1118
1119    static DSAPrivateKey getPrivateKey() {
1120        return privateKey;
1121    }
1122}
1123