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