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
18package org.apache.harmony.security.tests.java.security;
19
20import java.math.BigInteger;
21import java.nio.ByteBuffer;
22import java.security.AlgorithmParameters;
23import java.security.InvalidKeyException;
24import java.security.InvalidParameterException;
25import java.security.KeyPair;
26import java.security.KeyPairGenerator;
27import java.security.NoSuchAlgorithmException;
28import java.security.NoSuchProviderException;
29import java.security.PrivateKey;
30import java.security.Provider;
31import java.security.PublicKey;
32import java.security.SecureRandom;
33import java.security.Security;
34import java.security.Signature;
35import java.security.SignatureException;
36import java.security.cert.Certificate;
37import java.security.spec.DSAParameterSpec;
38import java.util.HashSet;
39import java.util.Set;
40import libcore.java.security.StandardNames;
41
42public class Signature2Test extends junit.framework.TestCase {
43
44    private static final String MESSAGE = "abc";
45
46    private static KeyPair DSA_KEYS;
47    private static KeyPair RSA_KEYS;
48
49    private static KeyPair getDsaKeys() throws Exception {
50        if (DSA_KEYS == null) {
51            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
52            keyGen.initialize(1024);
53            DSA_KEYS = keyGen.generateKeyPair();
54        }
55        return DSA_KEYS;
56    }
57
58    private static KeyPair getRsaKeys() throws Exception {
59        if (RSA_KEYS == null) {
60            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
61            keyGen.initialize(1024);
62            RSA_KEYS = keyGen.generateKeyPair();
63        }
64        return RSA_KEYS;
65    }
66
67    /**
68     * java.security.Signature#clone()
69     */
70    public void test_clone() throws Exception {
71        Signature s = Signature.getInstance("DSA");
72        try {
73            s.clone();
74            fail();
75        } catch (CloneNotSupportedException expected) {
76        }
77    }
78
79    /**
80     * java.security.Signature#getAlgorithm()
81     */
82    public void test_getAlgorithm() throws Exception {
83        String alg = Signature.getInstance("DSA").getAlgorithm();
84        assertTrue("getAlgorithm did not get DSA (" + alg + ")", alg
85                .indexOf("DSA") != -1);
86    }
87
88    /**
89     * java.security.Signature#getInstance(java.lang.String)
90     */
91    public void test_getInstanceLjava_lang_String() throws Exception {
92        Signature.getInstance("DSA");
93
94        try {
95            Signature.getInstance("bogus");
96            fail();
97        } catch (NoSuchAlgorithmException expected) {
98        }
99    }
100
101    /**
102     * java.security.Signature#getInstance(java.lang.String,
103     *        java.security.Provider)
104     */
105    public void test_getInstanceLjava_lang_StringLjava_lang_String_java_security_Provider()
106            throws Exception {
107        Provider[] providers = Security.getProviders("Signature.DSA");
108
109        for (int i = 0; i < providers.length; i++) {
110            Signature signature = Signature.getInstance("DSA", providers[i]);
111            assertEquals("DSA", signature.getAlgorithm());
112            assertEquals(providers[i], signature.getProvider());
113        }
114
115        try {
116            Signature.getInstance((String) null, (Provider) null);
117            fail();
118        } catch (NullPointerException expected) {
119        }
120
121        try {
122            Signature.getInstance("DSA", (Provider) null);
123            fail();
124        } catch (IllegalArgumentException expected) {
125        }
126
127        try {
128            Signature.getInstance((String) null, providers[0]);
129            fail();
130        } catch (NullPointerException expected) {
131        }
132
133        try {
134            Signature.getInstance("bogus", providers[0]);
135            fail();
136        } catch (NoSuchAlgorithmException expected) {
137        }
138    }
139
140    /**
141     * java.security.Signature#getInstance(java.lang.String,
142     *        java.lang.String)
143     */
144    public void test_getInstanceLjava_lang_StringLjava_lang_String()
145            throws Exception {
146        Provider[] providers = Security.getProviders("Signature.DSA");
147
148        for (int i = 0; i < providers.length; i++) {
149            Signature.getInstance("DSA", providers[i].getName());
150        }
151
152        try {
153            Signature.getInstance("bogus", providers[0].getName());
154            fail();
155        } catch (NoSuchAlgorithmException expected) {
156        }
157
158        Provider[] pp = Security.getProviders();
159        for (int i = 0; i < pp.length; i++) {
160            try {
161                Signature.getInstance("DSA", pp[i].toString());
162                fail(pp[i].toString());
163            } catch (NoSuchProviderException expected) {
164            }
165        }
166
167        String[] sp = {null, ""};
168        for (int i = 0; i < sp.length; i++) {
169            try {
170                Signature.getInstance("DSA", sp[i]);
171                fail(sp[i]);
172            } catch (IllegalArgumentException expected) {
173            }
174        }
175    }
176
177    /**
178     * java.security.Signature#getParameters()
179     */
180    public void test_getParameters() throws Exception {
181        Signature sig = Signature.getInstance("DSA");
182        try {
183            sig.getParameters();
184        } catch (UnsupportedOperationException e) {
185            // Could be that the operation is not supported
186        }
187
188        try {
189            MySignature sig2 = new MySignature("test");
190            sig2.getParameters();
191            fail();
192        } catch (UnsupportedOperationException expected) {
193        }
194
195        MySignature sig2 = new MySignature("ABC");
196        sig2.getParameters();
197    }
198
199    /**
200     * java.security.Signature#getParameter(java.lang.String)
201     */
202    @SuppressWarnings("deprecation")
203    public void test_getParameterLjava_lang_String() throws Exception {
204        Signature sig = Signature.getInstance("DSA");
205
206        try {
207            sig.getParameter("r");
208            sig.getParameter("s");
209        } catch (UnsupportedOperationException e) {
210        }
211    }
212
213    /**
214     * java.security.Signature#getProvider()
215     */
216    public void test_getProvider() throws Exception {
217        Provider p = Signature.getInstance("DSA").getProvider();
218        assertNotNull("provider is null", p);
219    }
220
221    /**
222     * java.security.Signature#initSign(java.security.PrivateKey)
223     */
224    public void test_initSignLjava_security_PrivateKey() throws Exception {
225        Signature.getInstance("DSA").initSign(getDsaKeys().getPrivate());
226
227        try {
228            Signature.getInstance("DSA").initSign(getRsaKeys().getPrivate());
229            fail();
230        } catch (InvalidKeyException expected) {
231        }
232    }
233
234    public void test_initSignLjava_security_PrivateKeyLjava_security_SecureRandom()
235            throws Exception {
236        Signature sig = Signature.getInstance("DSA");
237        sig.initSign(getDsaKeys().getPrivate(), new SecureRandom());
238    }
239
240    public void test_initSignLjava_security_PrivateKeyLjava_security_SecureRandom_mismatch()
241            throws Exception {
242        try {
243            Signature sig = Signature.getInstance("DSA");
244            sig.initSign(getRsaKeys().getPrivate(), new SecureRandom());
245            fail();
246        } catch (InvalidKeyException expected) {
247        }
248    }
249
250    /**
251     * java.security.Signature#initVerify(java.security.PublicKey)
252     */
253    public void test_initVerifyLjava_security_PublicKey() throws Exception {
254        Signature.getInstance("DSA").initVerify(getDsaKeys().getPublic());
255
256        try {
257            Signature.getInstance("DSA").initVerify(getRsaKeys().getPublic());
258            fail();
259        } catch (InvalidKeyException expected) {
260        }
261    }
262
263    /**
264     * java.security.Signature#initVerify(java.security.cert.Certificate)
265     */
266    public void test_initVerifyLjava_security_Certificate() throws Exception {
267        Provider p = new MyProvider();
268        p.put("DSA", "tests.java.security.support.cert.MyCertificate$1");
269
270        Provider myProvider = new MyProvider();
271        Security.addProvider(myProvider);
272
273        try {
274            Provider[] pp = Security.getProviders();
275            if (pp == null) {
276                return;
277            }
278
279            try {
280                Signature.getInstance("DSA").initVerify((Certificate) null);
281                fail();
282            } catch (NullPointerException expected) {
283            }
284        } finally {
285            Security.removeProvider(myProvider.getName());
286        }
287    }
288
289    /**
290     * java.security.Signature#setParameter(java.lang.String,
291     *        java.lang.Object)
292     */
293    @SuppressWarnings("deprecation")
294    public void test_setParameterLjava_lang_StringLjava_lang_Object()
295            throws Exception {
296        Signature sig = Signature.getInstance("DSA");
297
298        try {
299            sig.setParameter("r", BigInteger.ONE);
300            sig.setParameter("s", BigInteger.ONE);
301        } catch (InvalidParameterException e) {
302            // Could be that it's an invalid param for the found algorithm
303        } catch (UnsupportedOperationException e) {
304            // Could be that the operation is not supported
305        }
306    }
307
308    /**
309     * java.security.Signature#setParameter(java.security.spec.AlgorithmParameterSpec)
310     */
311    public void test_setParameterLjava_security_spec_AlgorithmParameterSpec()
312            throws Exception {
313        Signature sig = Signature.getInstance("DSA");
314
315        try {
316            DSAParameterSpec spec = new DSAParameterSpec(BigInteger.ONE,
317                    BigInteger.ONE, BigInteger.ONE);
318            sig.setParameter(spec);
319        } catch (InvalidParameterException e) {
320            // Could be that it's an invalid param for the found algorithm
321        } catch (UnsupportedOperationException e) {
322            // Could be that the operation is not supported
323        }
324    }
325
326    /**
327     * java.security.Signature#sign()
328     */
329    public void test_sign() throws Exception {
330        Signature sig = Signature.getInstance("DSA");
331        sig.initSign(getDsaKeys().getPrivate());
332        sig.update(MESSAGE.getBytes());
333        sig.sign();
334    }
335
336    /**
337     * java.security.Signature#toString()
338     */
339    public void test_toString() throws Exception {
340        String str = Signature.getInstance("DSA").toString();
341        assertNotNull("toString is null", str);
342    }
343
344    /**
345     * java.security.Signature#update(byte[])
346     */
347    public void test_update$B() throws Exception {
348        Signature sig = Signature.getInstance("DSA");
349        sig.initSign(getDsaKeys().getPrivate());
350
351        byte[] bytes = MESSAGE.getBytes();
352        sig.update(bytes);
353
354        try {
355            Signature sig2 = Signature.getInstance("DSA");
356            sig2.update(MESSAGE.getBytes());
357            fail();
358        } catch (SignatureException expected) {
359        }
360    }
361
362    /**
363     * java.security.Signature#update(byte[], int, int)
364     */
365    public void test_update$BII() throws Exception {
366        Signature sig = Signature.getInstance("DSA");
367        byte[] bytes = MESSAGE.getBytes();
368
369        try {
370            sig.update(bytes, 0, bytes.length);
371            fail();
372        } catch (SignatureException expected) {
373        }
374
375        sig.initSign(getDsaKeys().getPrivate());
376
377
378        sig.update(bytes, 0, bytes.length);
379
380        sig.update(bytes, bytes.length - 2, 2);
381
382        try {
383            sig.update(bytes, bytes.length -3, 4);
384            fail();
385        } catch (IllegalArgumentException expected) {
386        }
387
388        try {
389            sig.update(null, 0, 5);
390            fail();
391        } catch (IllegalArgumentException expected) {
392        }
393    }
394
395    /**
396     * java.security.Signature#update(byte)
397     */
398    public void test_updateB() throws Exception {
399        Signature sig = Signature.getInstance("DSA");
400        sig.initSign(getDsaKeys().getPrivate());
401
402        sig.update(MESSAGE.getBytes()[0]);
403
404    }
405
406    /**
407     * java.security.Signature#update(ByteBuffer data)
408     */
409    public void test_updateLjava_nio_ByteBuffer() throws Exception {
410        Signature sig = Signature.getInstance("DSA");
411        ByteBuffer buffer = ByteBuffer.allocate(10);
412
413        try {
414            sig.update(buffer);
415            fail();
416        } catch (SignatureException expected) {
417        }
418
419        sig.initSign(getDsaKeys().getPrivate());
420        sig.update(buffer);
421
422    }
423
424    /**
425     * java.security.Signature#verify(byte[])
426     */
427    public void test_verify$B() throws Exception {
428        Signature sig = Signature.getInstance("DSA");
429
430        try {
431            sig.verify(new byte[] { 0,1,2,3 });
432            fail();
433        } catch (SignatureException expected) {
434        }
435
436        sig.initSign(getDsaKeys().getPrivate());
437        sig.update(MESSAGE.getBytes());
438        byte[] signature = sig.sign();
439
440        sig.initVerify(getDsaKeys().getPublic());
441        sig.update(MESSAGE.getBytes());
442        assertTrue("Sign/Verify does not pass", sig.verify(signature));
443    }
444
445    /**
446     * java.security.Signature#verify(byte[], int, int)
447     */
448    public void test_verify$BII() throws Exception {
449        Signature sig = Signature.getInstance("DSA");
450        sig.initSign(getDsaKeys().getPrivate());
451        sig.update(MESSAGE.getBytes());
452        byte[] signature = sig.sign();
453
454        sig.initVerify(getDsaKeys().getPublic());
455        sig.update(MESSAGE.getBytes());
456        assertTrue("Sign/Verify does not pass", sig.verify(signature, 0,
457                signature.length));
458
459        try {
460            sig.verify(null, 0, signature.length);
461            fail();
462        } catch (IllegalArgumentException expected) {
463        }
464
465        try {
466            sig.verify(signature, -5, signature.length);
467            fail();
468        } catch (IllegalArgumentException expected) {
469        }
470
471        if (StandardNames.IS_RI) {
472            try {
473                sig.verify(signature, signature.length, 0);
474                fail();
475            } catch (SignatureException expected) {
476            }
477        } else {
478            // Calling Signature.verify a second time should not throw
479            // http://code.google.com/p/android/issues/detail?id=34933
480            boolean verified = sig.verify(signature, signature.length, 0);
481            assertFalse(verified);
482        }
483
484        try {
485            sig.verify(signature, 0, signature.length * 2);
486            fail();
487        } catch (IllegalArgumentException expected) {
488        }
489    }
490
491    class MyProvider extends Provider {
492        private Set<Provider.Service> services = null;
493
494        MyProvider() {
495            super("MyProvider", 1.0, "Provider for testing");
496            put("MessageDigest.SHA-1", "SomeClassName");
497            put("MessageDigest.abc", "SomeClassName");
498            put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
499            if (services != null) {
500                services.clear();
501            } else {
502                services = new HashSet<Service>();
503            }
504        }
505
506        MyProvider(String name, double version, String info) {
507            super(name, version, info);
508            if (services != null) {
509                services.clear();
510            } else {
511                services = new HashSet<Service>();
512            }
513        }
514
515        public void putService(Provider.Service s) {
516            super.putService(s);
517            services.add(s);
518        }
519
520        public void removeService(Provider.Service s) {
521            super.removeService(s);
522            services.remove(s);
523        }
524
525        public int getNumServices() {
526            return services.size();
527        }
528    }
529
530    @SuppressWarnings("unused")
531    private class MySignature extends Signature {
532
533        protected MySignature(String algorithm) {
534            super(algorithm);
535        }
536
537        @Override
538        protected Object engineGetParameter(String param)
539                throws InvalidParameterException {
540            return null;
541        }
542
543        @Override
544        protected void engineInitSign(PrivateKey privateKey)
545                throws InvalidKeyException {
546
547        }
548
549        @Override
550        protected void engineInitVerify(PublicKey publicKey)
551                throws InvalidKeyException {
552        }
553
554        @Override
555        protected void engineSetParameter(String param, Object value)
556                throws InvalidParameterException {
557
558        }
559
560        @Override
561        protected byte[] engineSign() throws SignatureException {
562            return null;
563        }
564
565        @Override
566        protected void engineUpdate(byte b) throws SignatureException {
567
568        }
569
570        @Override
571        protected void engineUpdate(byte[] b, int off, int len)
572                throws SignatureException {
573
574        }
575
576        @Override
577        protected boolean engineVerify(byte[] sigBytes)
578                throws SignatureException {
579            return false;
580        }
581
582        @Override
583        protected AlgorithmParameters engineGetParameters() {
584            if (this.getAlgorithm().equals("test")) {
585                return super.engineGetParameters();
586            } else {
587                return null;
588            }
589        }
590
591    }
592}
593