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