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* @author Boris V. Kuznetsov
20* @version $Revision$
21*/
22
23package org.apache.harmony.security.tests.java.security;
24
25import dalvik.annotation.KnownFailure;
26
27import java.security.InvalidParameterException;
28import java.security.NoSuchAlgorithmException;
29import java.security.Provider;
30import java.security.Security;
31import java.security.Signature;
32import java.security.InvalidAlgorithmParameterException;
33import java.security.InvalidKeyException;
34import java.security.Key;
35import java.security.PrivateKey;
36import java.security.PublicKey;
37import java.security.SecureRandom;
38import java.security.SignatureException;
39import java.security.cert.Certificate;
40import java.security.spec.AlgorithmParameterSpec;
41
42import org.apache.harmony.security.tests.support.MySignature1;
43
44import junit.framework.TestCase;
45
46/**
47 * Tests for <code>Signature</code> constructor and methods
48 *
49 */
50public class SignatureTest extends TestCase {
51
52    /*
53     * Class under test for Signature(String)
54     */
55    public void testConstructor() {
56        String [] algorithms = { "SHA256WITHRSA", "NONEWITHDSA", "SHA384WITHRSA",
57            "MD5ANDSHA1WITHRSA", "SHA512WITHRSA",
58            "SHA1WITHRSA", "SHA1WITHDSA", "MD5WITHRSA" };
59        for (int i = 0; i < algorithms.length; i ++) {
60            MySignature1 s = new MySignature1(algorithms[i]);
61            assertEquals(algorithms[i],s.getAlgorithm());
62            assertNull(s.getProvider());
63            assertEquals(0, s.getState());
64        }
65
66        MySignature1 s1 = new MySignature1(null);
67        assertNull(s1.getAlgorithm());
68        assertNull(s1.getProvider());
69        assertEquals(0, s1.getState());
70
71        MySignature1 s2 = new MySignature1("ABCD@#&^%$)(*&");
72        assertEquals("ABCD@#&^%$)(*&", s2.getAlgorithm());
73        assertNull(s2.getProvider());
74        assertEquals(0, s2.getState());
75    }
76
77    /*
78     * Class under test for Object clone()
79     */
80    public void testClone() {
81        MySignature1 s = new MySignature1("ABC");
82        try {
83            s.clone();
84            fail("No expected CloneNotSupportedException");
85        } catch (CloneNotSupportedException e) {
86        }
87
88        MySignature sc = new MySignature();
89        try {
90            sc.clone();
91        } catch (CloneNotSupportedException e) {
92            fail("unexpected exception: " + e);
93        }
94
95    }
96
97    public void testGetProvider() {
98        MySignature1 s = new MySignature1("ABC");
99
100        assertEquals("state", MySignature1.UNINITIALIZED, s.getState());
101        assertNull("provider", s.getProvider());
102    }
103
104    public void testGetAlgorithm() {
105        MySignature1 s = new MySignature1("ABC");
106
107        assertEquals("state", MySignature1.UNINITIALIZED, s.getState());
108        assertEquals("algorithm", "ABC", s.getAlgorithm());
109    }
110
111    /*
112     * Class under test for void initVerify(PublicKey)
113     */
114    public void testInitVerifyPublicKey() throws InvalidKeyException {
115        MySignature1 s = new MySignature1("ABC");
116
117        s.initVerify(new MyPublicKey());
118        assertEquals("state", MySignature1.VERIFY, s.getState());
119        assertTrue("initVerify() failed", s.runEngineInitVerify);
120
121        try {
122            Signature sig = getTestSignature();
123            sig.initVerify((PublicKey)null);
124        } catch (InvalidKeyException e) {
125            // ok
126        } catch (NoSuchAlgorithmException e) {
127            fail("unexpected : " + e);
128        }
129    }
130
131    /*
132     * Class under test for void initVerify(Certificate)
133     */
134    public void testInitVerifyCertificate() throws InvalidKeyException {
135        MySignature1 s = new MySignature1("ABC");
136
137        s.initVerify(new MyCertificate());
138        assertEquals("state", MySignature1.VERIFY, s.getState());
139        assertTrue("initVerify() failed", s.runEngineInitVerify);
140
141        try {
142            Signature sig = getTestSignature();
143            sig.initVerify(new MyCertificate());
144            fail("expected InvalidKeyException");
145        } catch (InvalidKeyException e) {
146            // ok
147        } catch (NoSuchAlgorithmException e) {
148            fail("unexpected : " + e);
149        }
150    }
151
152    /*
153     * Class under test for void initSign(PrivateKey)
154     */
155    public void testInitSignPrivateKey() throws InvalidKeyException {
156        MySignature1 s = new MySignature1("ABC");
157
158        s.initSign(new MyPrivateKey());
159        assertEquals("state", MySignature1.SIGN, s.getState());
160        assertTrue("initSign() failed", s.runEngineInitSign);
161
162        try {
163            Signature signature = getTestSignature();
164            signature.initSign(null);
165            fail("expected InvalidKeyException");
166        } catch (InvalidKeyException e) {
167            // ok
168        } catch (NoSuchAlgorithmException e) {
169            fail("unexpected: " + e);
170        }
171    }
172
173    private Signature getTestSignature() throws NoSuchAlgorithmException {
174        Provider provider = new MyProvider("TestProvider", 1.0, "Test Provider", "Signature.ABC", MySignature.class.getName());
175        Security.insertProviderAt(provider, 1);
176
177        try {
178            return Signature.getInstance("ABC");
179        }
180        finally {
181           Security.removeProvider("TestProvider");
182        }
183
184    }
185
186    /*
187     * Class under test for void initSign(PrivateKey, SecureRandom)
188     */
189    public void testInitSignPrivateKeySecureRandom() throws InvalidKeyException {
190        MySignature1 s = new MySignature1("ABC");
191
192        s.initSign(new MyPrivateKey(), new SecureRandom());
193        assertEquals("state", MySignature1.SIGN, s.getState());
194        assertTrue("initSign() failed", s.runEngineInitSign);
195
196        try {
197            Signature sig = getTestSignature();
198            sig.initSign(null, null);
199            fail("expected InvalidKeyException");
200        } catch (InvalidKeyException e) {
201            // ok
202        } catch (NoSuchAlgorithmException e) {
203            fail("unexpected : " + e);
204        }
205    }
206
207    /*
208     * Class under test for byte[] sign()
209     */
210    public void testSign() throws Exception {
211        MySignature1 s = new MySignature1("ABC");
212        try {
213            s.sign();
214            fail("No expected SignatureException");
215        } catch (SignatureException e) {
216        }
217
218        s.initVerify(new MyPublicKey());
219
220        try {
221            s.sign();
222            fail("No expected SignatureException");
223        } catch (SignatureException e) {
224        }
225
226        s.initSign(new MyPrivateKey());
227        s.sign();
228        assertEquals("state", MySignature1.SIGN, s.getState());
229        assertTrue("sign() failed", s.runEngineSign);
230    }
231
232    /*
233     * Class under test for sign(byte[], offset, len)
234     */
235    public void testSignbyteintint() throws Exception {
236        MySignature1 s = new MySignature1("ABC");
237        byte[] outbuf = new byte [10];
238        try {
239            s.sign(outbuf, 0, outbuf.length);
240            fail("No expected SignatureException");
241        } catch (SignatureException e) {
242        }
243
244        s.initVerify(new MyPublicKey());
245
246        try {
247            s.sign(outbuf, 0, outbuf.length);
248            fail("No expected SignatureException");
249        } catch (SignatureException e) {
250        }
251
252        s.initSign(new MyPrivateKey());
253        assertEquals(s.getBufferLength(), s.sign(outbuf, 0, outbuf.length));
254        assertEquals("state", MySignature1.SIGN, s.getState());
255        assertTrue("sign() failed", s.runEngineSign);
256
257        try {
258            s.initSign(new MyPrivateKey());
259            s.sign(outbuf, outbuf.length, 0);
260            fail("expected SignatureException");
261        } catch (SignatureException e) {
262            // ok
263        }
264
265        try {
266            s.initSign(new MyPrivateKey());
267            s.sign(outbuf, outbuf.length, 3);
268            fail("expected IllegalArgumentException");
269        } catch (IllegalArgumentException e) {
270            // ok
271        }
272
273    }
274
275
276    /*
277     * Class under test for boolean verify(byte[])
278     */
279    public void testVerifybyteArray() throws Exception {
280        MySignature1 s = new MySignature1("ABC");
281        byte[] b = {1, 2, 3, 4};
282        try {
283            s.verify(b);
284            fail("No expected SignatureException");
285        } catch (SignatureException e) {
286        }
287
288        s.initSign(new MyPrivateKey());
289        try {
290            s.verify(b);
291            fail("No expected SignatureException");
292        } catch (SignatureException e) {
293        }
294
295        s.initVerify(new MyPublicKey());
296        s.verify(b);
297        assertEquals("state", MySignature1.VERIFY, s.getState());
298        assertTrue("verify() failed", s.runEngineVerify);
299    }
300
301    /*
302     * Class under test for boolean verify(byte[], int, int)
303     */
304    public void testVerifybyteArrayintint() throws Exception {
305        MySignature1 s = new MySignature1("ABC");
306        byte[] b = {1, 2, 3, 4};
307        try {
308            s.verify(b, 0, 3);
309            fail("No expected SignatureException");
310        } catch (SignatureException e) {
311        }
312
313        s.initSign(new MyPrivateKey());
314
315        try {
316            s.verify(b, 0, 3);
317            fail("No expected SignatureException");
318        } catch (SignatureException e) {
319        }
320
321        s.initVerify(new MyPublicKey());
322
323        try {
324            s.verify(b, 0, 5);
325            fail("No expected IllegalArgumentException");
326        } catch (IllegalArgumentException e) {
327        }
328
329        s.verify(b, 0, 3);
330        assertEquals("state", MySignature1.VERIFY, s.getState());
331        assertTrue("verify() failed", s.runEngineVerify);
332    }
333
334    /*
335     * Class under test for void update(byte)
336     */
337    public void testUpdatebyte() throws Exception {
338        MySignature1 s = new MySignature1("ABC");
339        try {
340            s.update((byte)1);
341            fail("No expected SignatureException");
342        } catch (SignatureException e) {
343        }
344
345        s.initVerify(new MyPublicKey());
346        s.update((byte) 1);
347        s.initSign(new MyPrivateKey());
348        s.update((byte) 1);
349
350        assertEquals("state", MySignature1.SIGN, s.getState());
351        assertTrue("update() failed", s.runEngineUpdate1);
352
353        try {
354            Signature sig = getTestSignature();
355            sig.update((byte) 42);
356            fail("expected SignatureException");
357        } catch (SignatureException e) {
358            // ok
359        }
360    }
361
362    /*
363     * Class under test for void update(byte[])
364     */
365    public void testUpdatebyteArray() throws Exception {
366        MySignature1 s = new MySignature1("ABC");
367        byte[] b = {1, 2, 3, 4};
368        try {
369            s.update(b);
370            fail("No expected SignatureException");
371        } catch (SignatureException e) {
372        }
373
374        s.initVerify(new MyPublicKey());
375        s.update(b);
376        s.initSign(new MyPrivateKey());
377        s.update(b);
378
379        assertEquals("state", MySignature1.SIGN, s.getState());
380        assertTrue("update() failed", s.runEngineUpdate2);
381
382        try {
383            Signature sig = getTestSignature();
384            sig.update(b);
385            fail("expected SignatureException");
386        } catch (SignatureException e) {
387            // ok
388        }
389
390        try {
391            Signature sig = getTestSignature();
392            sig.update((byte[])null);
393            fail("expected NullPointerException");
394        } catch (SignatureException e) {
395            // ok
396        } catch (NullPointerException e) {
397            // ok
398        }
399    }
400
401    /*
402     * Class under test for void update(byte[], int, int)
403     */
404    public void testUpdatebyteArrayintint() throws Exception {
405        MySignature1 s = new MySignature1("ABC");
406        byte[] b = {1, 2, 3, 4};
407        try {
408            s.update(b, 0, 3);
409            fail("No expected SignatureException");
410        } catch (SignatureException e) {
411        }
412
413        s.initVerify(new MyPublicKey());
414        s.update(b, 0, 3);
415        s.initSign(new MyPrivateKey());
416        s.update(b, 0, 3);
417
418        assertEquals("state", MySignature1.SIGN, s.getState());
419        assertTrue("update() failed", s.runEngineUpdate2);
420
421        try {
422            s.update(b, 3, 0);
423            fail("expected IllegalArgumentException");
424        } catch (IllegalArgumentException e) {
425            // ok
426        }
427
428        try {
429            s.update(b, 0, b.length + 1);
430            fail("expected IllegalArgumentException");
431        } catch (IllegalArgumentException e) {
432            // ok
433        }
434
435        try {
436            s.update(b, -1, b.length);
437            fail("expected IllegalArgumentException");
438        } catch (IllegalArgumentException e) {
439            // ok
440        }
441
442    }
443
444    /*
445     * Class under test for void update(byte[], int, int)
446     */
447    @KnownFailure("Android throws IllegalArgumentException, RI throws NullpointerException")
448    public void testUpdatebyteArrayintint2() throws Exception {
449        MySignature1 s = new MySignature1("ABC");
450        byte[] b = {1, 2, 3, 4};
451
452        s.initVerify(new MyPublicKey());
453        s.update(b, 0, 3);
454        s.initSign(new MyPrivateKey());
455        s.update(b, 0, 3);
456
457        assertEquals("state", MySignature1.SIGN, s.getState());
458        assertTrue("update() failed", s.runEngineUpdate2);
459
460        try {
461            s.update(null, 0, 3);
462            fail("NullPointerException wasn't thrown");
463        } catch (NullPointerException npe) {
464            // ok
465        }
466    }
467
468
469    /*
470     * Class under test for void setParameter(String, Object)
471     */
472    @SuppressWarnings("deprecation")
473    public void testSetParameterStringObject() {
474        MySignature1 s = new MySignature1("ABC");
475        s.setParameter("aaa", new Object());
476
477        try {
478            Signature sig = getTestSignature();
479            sig.setParameter("TestParam", new Integer(42));
480            fail("expected InvalidParameterException");
481        } catch (InvalidParameterException e) {
482            // expected
483        } catch (NoSuchAlgorithmException e) {
484            fail("unexpected: " + e);
485        }
486    }
487
488    /*
489     * Class under test for void setParameter(AlgorithmParameterSpec)
490     */
491    public void testSetParameterAlgorithmParameterSpec() throws InvalidAlgorithmParameterException {
492        MySignature1 s = new MySignature1("ABC");
493        try {
494            s.setParameter((java.security.spec.AlgorithmParameterSpec)null);
495            fail("No expected UnsupportedOperationException");
496        } catch (UnsupportedOperationException e){
497        }
498
499        try {
500            Signature sig = getTestSignature();
501            sig.setParameter(new AlgorithmParameterSpec() {});
502        } catch (InvalidAlgorithmParameterException e) {
503            fail("unexpected: " + e);
504        } catch (NoSuchAlgorithmException e) {
505            fail("unexpected: " + e);
506        }
507    }
508
509    @SuppressWarnings("deprecation")
510    public void testGetParameter() {
511        MySignature1 s = new MySignature1("ABC");
512        s.getParameter("aaa");
513
514        try {
515            MySignature se = new MySignature();
516            se.getParameter("test");
517        } catch (InvalidParameterException e) {
518            // ok
519        }
520
521    }
522
523    private class MyKey implements Key {
524        public String getFormat() {
525            return "123";
526        }
527        public byte[] getEncoded() {
528            return null;
529        }
530        public String getAlgorithm() {
531            return "aaa";
532        }
533    }
534
535    private class MyPublicKey extends MyKey implements PublicKey {}
536
537    private class MyPrivateKey extends MyKey implements PrivateKey {}
538
539    private class MyCertificate extends java.security.cert.Certificate {
540        public  MyCertificate() {
541            super("MyCertificateType");
542        }
543
544        public PublicKey getPublicKey() {
545            return new MyPublicKey();
546        }
547
548        public byte[] getEncoded() {
549            return null;
550        }
551        public void verify(PublicKey key) {}
552
553        public void verify(PublicKey key, String sigProvider) {}
554
555        public String toString() {
556            return "MyCertificate";
557        }
558    }
559
560    @SuppressWarnings("unused")
561    protected static class MySignature extends Signature implements Cloneable {
562
563        public MySignature() {
564            super("TestSignature");
565        }
566
567        @Override
568        protected Object engineGetParameter(String param)
569                throws InvalidParameterException {
570            throw new InvalidParameterException();
571        }
572
573        @Override
574        protected void engineInitSign(PrivateKey privateKey)
575                throws InvalidKeyException {
576            throw new InvalidKeyException();
577        }
578
579        @Override
580        protected void engineInitVerify(PublicKey publicKey)
581                throws InvalidKeyException {
582            throw new InvalidKeyException();
583        }
584
585        @Override
586        protected void engineSetParameter(String param, Object value)
587                throws InvalidParameterException {
588            throw new InvalidParameterException();
589        }
590
591        @Override
592        protected byte[] engineSign() throws SignatureException {
593            return null;
594        }
595
596        @Override
597        protected void engineUpdate(byte b) throws SignatureException {
598            throw new SignatureException();
599        }
600
601        @Override
602        protected void engineUpdate(byte[] b, int off, int len)
603                throws SignatureException {
604
605        }
606
607        @Override
608        protected boolean engineVerify(byte[] sigBytes)
609                throws SignatureException {
610            return false;
611        }
612
613        @Override
614        protected void engineSetParameter(AlgorithmParameterSpec params)
615                throws InvalidAlgorithmParameterException {
616            if (params == null) {
617                throw new InvalidAlgorithmParameterException();
618            }
619        }
620    }
621
622    private class MyProvider extends Provider {
623
624        protected MyProvider(String name, double version, String info, String signame, String className) {
625            super(name, version, info);
626            put(signame, className);
627        }
628
629    }
630}
631