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 java.io.IOException;
26import java.math.BigInteger;
27import java.security.AlgorithmParameters;
28import java.security.AlgorithmParametersSpi;
29import java.security.Provider;
30import java.security.Security;
31import java.security.spec.AlgorithmParameterSpec;
32import java.security.spec.DSAParameterSpec;
33import java.security.spec.InvalidParameterSpecException;
34import java.util.Arrays;
35import java.security.NoSuchAlgorithmException;
36import java.security.NoSuchProviderException;
37
38import junit.framework.TestCase;
39
40import org.apache.harmony.security.tests.support.MyAlgorithmParameterGeneratorSpi;
41
42/**
43 * Tests for <code>AlgorithmParameters</code> class constructors and
44 * methods.
45 *
46 */
47public class AlgorithmParametersTest extends TestCase {
48
49    /**
50     * Provider
51     */
52    Provider p;
53
54    /*
55     * @see TestCase#setUp()
56     */
57    protected void setUp() throws Exception {
58        super.setUp();
59        p = new MyProvider();
60        Security.insertProviderAt(p, 1);
61    }
62
63    /*
64     * @see TestCase#tearDown()
65     */
66    protected void tearDown() throws Exception {
67        super.tearDown();
68        Security.removeProvider(p.getName());
69    }
70
71    /**
72     * java.security.AlgorithmParameters#getAlgorithm()
73     */
74    public void test_getAlgorithm() throws Exception {
75
76        // test: null value
77        AlgorithmParameters ap = new DummyAlgorithmParameters(null, p, null);
78        assertNull(ap.getAlgorithm());
79
80        // test: not null value
81        ap = new DummyAlgorithmParameters(null, p, "AAA");
82        assertEquals("AAA", ap.getAlgorithm());
83    }
84
85    /**
86     * java.security.AlgorithmParameters#getEncoded()
87     */
88    public void test_getEncoded() throws Exception {
89
90        final byte[] enc = new byte[] { 0x02, 0x01, 0x03 };
91
92        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
93            protected byte[] engineGetEncoded() throws IOException {
94                return enc;
95            }
96        };
97
98        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
99                "algorithm");
100
101        //
102        // test: IOException if not initialized
103        //
104        try {
105            params.getEncoded();
106            fail("should not get encoded from un-initialized instance");
107        } catch (IOException e) {
108            // expected
109        }
110
111        //
112        // test: corresponding spi method is invoked
113        //
114        params.init(new MyAlgorithmParameterSpec());
115        assertSame(enc, params.getEncoded());
116    }
117
118    /**
119     * java.security.AlgorithmParameters#getEncoded(String)
120     */
121    public void test_getEncodedLjava_lang_String() throws Exception {
122
123        final byte[] enc = new byte[] { 0x02, 0x01, 0x03 };
124
125        final String strFormatParam = "format";
126
127        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
128            protected byte[] engineGetEncoded(String format) throws IOException {
129                assertEquals(strFormatParam, format);
130                return enc;
131            }
132        };
133
134        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
135                "algorithm");
136
137        //
138        // test: IOException if not initialized
139        //
140        try {
141            params.getEncoded(strFormatParam);
142            fail("should not get encoded from un-initialized instance");
143        } catch (IOException e) {
144            // expected
145        }
146
147        //
148        // test: corresponding spi method is invoked
149        //
150        params.init(new MyAlgorithmParameterSpec());
151        assertSame(enc, params.getEncoded(strFormatParam));
152
153        //
154        // test: if format param is null
155        // Regression test for HARMONY-2680
156        //
157        paramSpi = new MyAlgorithmParameters() {
158            protected byte[] engineGetEncoded(String format) throws IOException {
159                assertNull(format); // null is passed to spi-provider
160                return enc;
161            }
162        };
163
164        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
165        params.init(new MyAlgorithmParameterSpec());
166        assertSame(enc, params.getEncoded(null));
167    }
168
169    /**
170     * java.security.AlgorithmParameters#getInstance(String)
171     */
172    public void test_getInstanceLjava_lang_String() {
173        String[] str = {"", "qwertyu", "!@#$%^&*()"};
174        try {
175            AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC");
176            checkUnititialized(ap);
177            ap.init(new MyAlgorithmParameterSpec());
178            checkAP(ap, p);
179        } catch (Exception e) {
180            fail("Unexpected exception");
181        }
182
183        for(int i = 0; i < str.length; i++) {
184            try {
185                AlgorithmParameters ap = AlgorithmParameters.getInstance(str[i]);
186                fail("NoSuchAlgorithmException was not thrown for parameter " + str[i]);
187            } catch (NoSuchAlgorithmException nsae) {
188                //expected
189            }
190        }
191    }
192
193    /**
194     * java.security.AlgorithmParameters#getInstance(String, String)
195     */
196    public void test_getInstanceLjava_lang_StringLjava_lang_String() {
197        String[] alg = {"", "qwertyu", "!@#$%^&*()"};
198        String[] prv = {"", null};
199        String[] prv1 = {"1234567890", "qwertyu", "!@#$%^&*()"};
200        try {
201            AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC", "MyProvider");
202            checkUnititialized(ap);
203            ap.init(new byte[6]);
204            checkAP(ap, p);
205        } catch (Exception e) {
206            fail("Unexpected exception");
207        }
208
209        for (int i = 0; i < alg.length; i++) {
210            try {
211                AlgorithmParameters ap = AlgorithmParameters.getInstance(alg[i], "MyProvider");
212                fail("NoSuchAlgorithmException was not thrown for parameter " + alg[i]);
213            } catch (NoSuchAlgorithmException nsae) {
214                //expected
215            } catch (Exception e) {
216                fail("Incorrect exception " + e + " was thrown for " + alg[i]);
217            }
218        }
219
220        for (int i = 0; i < prv.length; i++) {
221            try {
222                AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC", prv[i]);
223                fail("IllegalArgumentException was not thrown for parameter " + prv[i]);
224            } catch (IllegalArgumentException iae) {
225                //expected
226            } catch (Exception e) {
227                fail("Incorrect exception " + e + " was thrown for " + prv[i]);
228            }
229        }
230
231        for (int i = 0; i < prv1.length; i++) {
232            try {
233                AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC", prv1[i]);
234                fail("NoSuchProviderException was not thrown for parameter " + prv1[i]);
235            } catch (NoSuchProviderException nspe) {
236                //expected
237            } catch (Exception e) {
238                fail("Incorrect exception " + e + " was thrown for " + prv1[i]);
239            }
240        }
241    }
242
243    /**
244     * java.security.AlgorithmParameters#getParameterSpec(Class)
245     */
246    public void test_getParameterSpecLjava_lang_Class() throws Exception {
247
248        final MyAlgorithmParameterSpec myParamSpec = new MyAlgorithmParameterSpec();
249
250        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
251            protected AlgorithmParameterSpec engineGetParameterSpec(
252                    Class paramSpec) {
253                return myParamSpec;
254            }
255        };
256
257        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
258                "algorithm");
259
260        //
261        // test: InvalidParameterSpecException if not initialized
262        //
263        try {
264            params.getParameterSpec(null);
265            fail("No expected InvalidParameterSpecException");
266        } catch (InvalidParameterSpecException e) {
267            // expected
268        }
269        try {
270            params.getParameterSpec(MyAlgorithmParameterSpec.class);
271            fail("No expected InvalidParameterSpecException");
272        } catch (InvalidParameterSpecException e) {
273            // expected
274        }
275
276        //
277        // test: corresponding spi method is invoked
278        //
279        params.init(new MyAlgorithmParameterSpec());
280        assertSame(myParamSpec, params
281                .getParameterSpec(MyAlgorithmParameterSpec.class));
282
283        //
284        // test: if paramSpec is null
285        // Regression test for HARMONY-2733
286        //
287        paramSpi = new MyAlgorithmParameters() {
288
289            protected AlgorithmParameterSpec engineGetParameterSpec(
290                    Class paramSpec) {
291                assertNull(paramSpec); // null is passed to spi-provider
292                return null;
293            }
294        };
295
296        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
297        params.init(new MyAlgorithmParameterSpec());
298        assertNull(params.getParameterSpec(null));
299    }
300
301    /**
302     * java.security.AlgorithmParameters#getInstance(String, Provider)
303     */
304    public void test_getInstanceLjava_lang_StringLjava_security_Provider() {
305        String[] alg = {"", "qwertyu", "!@#$%^&*()"};
306        Provider pp = null;
307
308        try {
309            AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC", p);
310            checkUnititialized(ap);
311            ap.init(new byte[6], "aaa");
312            checkAP(ap, p);
313        } catch (Exception e){
314            fail("Unexpected exception");
315        }
316
317        for (int i = 0; i < alg.length; i++) {
318            try {
319                AlgorithmParameters ap = AlgorithmParameters.getInstance(alg[i], p);
320                fail("NoSuchAlgorithmException was not thrown for parameter " + alg[i]);
321            } catch (NoSuchAlgorithmException nsae) {
322                //expected
323            } catch (Exception e) {
324                fail("Incorrect exception " + e + " was thrown for " + alg[i]);
325            }
326        }
327
328        try {
329            AlgorithmParameters ap = AlgorithmParameters.getInstance("ABC", pp);
330            fail("IllegalArgumentException was not thrown for NULL provider");
331        } catch (IllegalArgumentException iae) {
332            //expected
333        } catch (Exception e){
334            fail("Incorrect exception " + e + " was thrown");
335        }
336    }
337
338    /**
339     * java.security.AlgorithmParameters#getProvider()
340     */
341    public void test_getProvider() throws Exception {
342        // test: null value
343        AlgorithmParameters ap = new DummyAlgorithmParameters(null, null, "AAA");
344        assertNull(ap.getProvider());
345
346        // test: not null value
347        ap = new DummyAlgorithmParameters(null, p, "AAA");
348        assertSame(p, ap.getProvider());
349    }
350
351    /**
352     * java.security.AlgorithmParameters#init(java.security.spec.AlgorithmParameterSpec)
353     */
354    public void test_initLjava_security_spec_AlgorithmParameterSpec()
355            throws Exception {
356
357        //
358        // test: corresponding spi method is invoked
359        //
360        final MyAlgorithmParameterSpec spec = new MyAlgorithmParameterSpec();
361
362        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
363            protected void engineInit(AlgorithmParameterSpec paramSpec)
364                    throws InvalidParameterSpecException {
365                assertSame(spec, paramSpec);
366                runEngineInit_AlgParamSpec = true;
367            }
368        };
369
370        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
371                "algorithm");
372
373        params.init(spec);
374        assertTrue(paramSpi.runEngineInit_AlgParamSpec);
375
376        //
377        // test: InvalidParameterSpecException if already initialized
378        //
379        try {
380            params.init(spec);
381            fail("No expected InvalidParameterSpecException");
382        } catch (InvalidParameterSpecException e) {
383            // expected
384        }
385
386        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
387        params.init(new byte[0]);
388        try {
389            params.init(spec);
390            fail("No expected InvalidParameterSpecException");
391        } catch (InvalidParameterSpecException e) {
392            // expected
393        }
394
395        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
396        params.init(new byte[0], "format");
397        try {
398            params.init(spec);
399            fail("No expected InvalidParameterSpecException");
400        } catch (InvalidParameterSpecException e) {
401            // expected
402        }
403
404        //
405        // test: if paramSpec is null
406        //
407        paramSpi = new MyAlgorithmParameters() {
408
409            protected void engineInit(AlgorithmParameterSpec paramSpec)
410                    throws InvalidParameterSpecException {
411                assertNull(paramSpec);// null is passed to spi-provider
412                runEngineInit_AlgParamSpec = true;
413            }
414        };
415
416        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
417        params.init((AlgorithmParameterSpec) null);
418        assertTrue(paramSpi.runEngineInit_AlgParamSpec);
419    }
420
421    /**
422     * java.security.AlgorithmParameters#init(byte[])
423     */
424    public void test_init$B() throws Exception {
425
426        //
427        // test: corresponding spi method is invoked
428        //
429        final byte[] enc = new byte[] { 0x02, 0x01, 0x03 };
430
431        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
432            protected void engineInit(byte[] params) throws IOException {
433                runEngineInitB$ = true;
434                assertSame(enc, params);
435            }
436        };
437
438        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
439                "algorithm");
440
441        params.init(enc);
442        assertTrue(paramSpi.runEngineInitB$);
443
444        //
445        // test: IOException if already initialized
446        //
447        try {
448            params.init(enc);
449            fail("No expected IOException");
450        } catch (IOException e) {
451            // expected
452        }
453
454        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
455        params.init(new MyAlgorithmParameterSpec());
456        try {
457            params.init(enc);
458            fail("No expected IOException");
459        } catch (IOException e) {
460            // expected
461        }
462
463        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
464        params.init(enc, "format");
465        try {
466            params.init(enc);
467            fail("No expected IOException");
468        } catch (IOException e) {
469            // expected
470        }
471
472        //
473        // test: if params is null
474        //
475        paramSpi = new MyAlgorithmParameters() {
476
477            protected void engineInit(byte[] params) throws IOException {
478                runEngineInitB$ = true;
479                assertNull(params); // null is passed to spi-provider
480            }
481        };
482
483        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
484        params.init((byte[]) null);
485        assertTrue(paramSpi.runEngineInitB$);
486    }
487
488    /**
489     * java.security.AlgorithmParameters#init(byte[],String)
490     */
491    public void test_init$BLjava_lang_String() throws Exception {
492
493        //
494        // test: corresponding spi method is invoked
495        //
496        final byte[] enc = new byte[] { 0x02, 0x01, 0x03 };
497        final String strFormatParam = "format";
498
499        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
500            protected void engineInit(byte[] params, String format)
501                    throws IOException {
502
503                runEngineInitB$String = true;
504                assertSame(enc, params);
505                assertSame(strFormatParam, format);
506            }
507        };
508
509        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
510                "algorithm");
511
512        params.init(enc, strFormatParam);
513        assertTrue(paramSpi.runEngineInitB$String);
514
515        //
516        // test: IOException if already initialized
517        //
518        try {
519            params.init(enc, strFormatParam);
520            fail("No expected IOException");
521        } catch (IOException e) {
522            // expected
523        }
524
525        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
526        params.init(new MyAlgorithmParameterSpec());
527        try {
528            params.init(enc, strFormatParam);
529            fail("No expected IOException");
530        } catch (IOException e) {
531            // expected
532        }
533
534        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
535        params.init(enc);
536        try {
537            params.init(enc, strFormatParam);
538            fail("No expected IOException");
539        } catch (IOException e) {
540            // expected
541        }
542
543        //
544        // test: if params and format are null
545        // Regression test for HARMONY-2724
546        //
547        paramSpi = new MyAlgorithmParameters() {
548
549            protected void engineInit(byte[] params, String format)
550                    throws IOException {
551
552                runEngineInitB$String = true;
553
554                // null is passed to spi-provider
555                assertNull(params);
556                assertNull(format);
557            }
558        };
559
560        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
561        params.init(null, null);
562        assertTrue(paramSpi.runEngineInitB$String);
563    }
564
565    /**
566     * java.security.AlgorithmParameters#toString()
567     */
568    public void test_toString() throws Exception {
569
570        final String str = "AlgorithmParameters";
571
572        MyAlgorithmParameters paramSpi = new MyAlgorithmParameters() {
573            protected String engineToString() {
574                return str;
575            }
576        };
577
578        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
579                "algorithm");
580
581        assertNull("unititialized", params.toString());
582
583        params.init(new byte[0]);
584
585        assertSame(str, params.toString());
586    }
587
588    /**
589     * Tests DSA AlgorithmParameters provider
590     */
591    public void testDSAProvider() throws Exception {
592        AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
593
594        assertEquals("Algorithm", "DSA", params.getAlgorithm());
595
596        // init(AlgorithmParameterSpec)
597        BigInteger p = BigInteger.ONE;
598        BigInteger q = BigInteger.TEN;
599        BigInteger g = BigInteger.ZERO;
600        params.init(new DSAParameterSpec(p, q, g));
601
602        // getEncoded() and getEncoded(String) (TODO verify returned encoding)
603        byte[] enc = params.getEncoded();
604        assertNotNull(enc);
605        assertNotNull(params.getEncoded("ASN.1"));
606        // TODO assertNotNull(params.getEncoded(null)); // HARMONY-2680
607
608        // getParameterSpec(Class)
609        DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class);
610        assertEquals("p is wrong ", p, spec.getP());
611        assertEquals("q is wrong ", q, spec.getQ());
612        assertEquals("g is wrong ", g, spec.getG());
613
614        // init(byte[])
615        params = AlgorithmParameters.getInstance("DSA");
616        params.init(enc);
617        assertTrue("param encoded is different", Arrays.equals(enc, params
618                .getEncoded()));
619
620        // init(byte[], String)
621        params = AlgorithmParameters.getInstance("DSA");
622        params.init(enc, "ASN.1");
623        assertTrue("param encoded is different", Arrays.equals(enc, params
624                .getEncoded()));
625
626        params = AlgorithmParameters.getInstance("DSA");
627        try {
628            params.init(enc, "DOUGLASMAWSON");
629            fail("unsupported format should have raised IOException");
630        } catch (IOException e) {
631            // expected
632        }
633    }
634
635    /**
636     * Tests OAEP AlgorithmParameters provider
637     */
638    public void testOAEPProvider() throws Exception {
639        AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
640
641        assertEquals("Algorithm", "OAEP", params.getAlgorithm());
642    }
643
644    /**
645     * Test for <code>AlgorithmParameters</code> constructor
646     * Assertion: returns AlgorithmParameters object
647     */
648    public void testAlgorithmParametersConst() throws Exception {
649        AlgorithmParametersSpi spi = new MyAlgorithmParameters();
650        AlgorithmParameters ap = new myAlgP(spi, p, "ABC");
651
652        checkUnititialized(ap);
653        ap.init(new byte[6], "aaa");
654        checkAP(ap, p);
655
656        //NULL parameters
657        try {
658            ap = new myAlgP(null, null, null);
659        } catch (Exception e){
660            fail("Exception should be not thrown");
661        }
662    }
663
664    private void checkUnititialized(AlgorithmParameters ap) {
665        assertNull("Uninitialized: toString() failed", ap.toString());
666    }
667
668    private void checkAP(AlgorithmParameters ap, Provider p) throws Exception {
669
670        assertSame("getProvider() failed", p, ap.getProvider());
671        assertEquals("getAlgorithm() failed", "ABC", ap.getAlgorithm());
672
673        assertEquals("AlgorithmParameters", ap.toString());
674        assertTrue("toString() failed", MyAlgorithmParameters.runEngineToString);
675    }
676
677    @SuppressWarnings("serial")
678    private class MyProvider extends Provider {
679        MyProvider() {
680            super("MyProvider", 1.0, "Provider for testing");
681            put("AlgorithmParameters.ABC", MyAlgorithmParameters.class
682                    .getName());
683        }
684
685        MyProvider(String name, double version, String info) {
686            super(name, version, info);
687        }
688    }
689
690    private class MyAlgorithmParameterSpec implements java.security.spec.AlgorithmParameterSpec{
691    }
692
693    private class DummyAlgorithmParameters extends AlgorithmParameters {
694        public DummyAlgorithmParameters(AlgorithmParametersSpi paramSpi,
695                Provider provider, String algorithm) {
696            super(paramSpi, provider, algorithm);
697        }
698    }
699
700    public static class MyAlgorithmParameters extends AlgorithmParametersSpi {
701
702        public boolean runEngineInit_AlgParamSpec = false;
703
704        public boolean runEngineInitB$ = false;
705
706        public boolean runEngineInitB$String = false;
707
708        public static boolean runEngineToString = false;
709
710        protected void engineInit(AlgorithmParameterSpec paramSpec)
711                throws InvalidParameterSpecException {
712        }
713
714        protected void engineInit(byte[] params) throws IOException {
715        }
716
717        protected void engineInit(byte[] params, String format)
718                throws IOException {
719        }
720
721        protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
722                throws InvalidParameterSpecException {
723            return null;
724        }
725
726        protected byte[] engineGetEncoded() throws IOException {
727            return null;
728        }
729
730        protected byte[] engineGetEncoded(String format) throws IOException {
731            return null;
732        }
733
734        protected String engineToString() {
735            runEngineToString = true;
736            return "AlgorithmParameters";
737        }
738    }
739
740    /**
741     * Additional class to verify AlgorithmParameters constructor
742     */
743    class myAlgP extends AlgorithmParameters {
744        public myAlgP(AlgorithmParametersSpi spi, Provider prov, String alg) {
745            super(spi, prov, alg);
746        }
747    }
748}
749