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