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.crypto.tests.javax.crypto;
19
20import dalvik.annotation.SideEffect;
21
22import java.math.BigInteger;
23import java.security.AlgorithmParameters;
24import java.security.InvalidAlgorithmParameterException;
25import java.security.InvalidKeyException;
26import java.security.Key;
27import java.security.NoSuchAlgorithmException;
28import java.security.NoSuchProviderException;
29import java.security.Provider;
30import java.security.SecureRandom;
31import java.security.spec.AlgorithmParameterSpec;
32import java.security.spec.RSAKeyGenParameterSpec;
33import java.util.Vector;
34
35import javax.crypto.ExemptionMechanism;
36import javax.crypto.ExemptionMechanismException;
37import javax.crypto.ExemptionMechanismSpi;
38import javax.crypto.KeyGenerator;
39import javax.crypto.ShortBufferException;
40
41import org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi;
42import org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi.tmpKey;
43import org.apache.harmony.security.tests.support.SpiEngUtils;
44
45import junit.framework.TestCase;
46
47/**
48 * Tests for <code>ExemptionMechanism</code> class constructors and methods
49 *
50 */
51public class ExemptionMechanismTest extends TestCase {
52
53    private static final String srvExemptionMechanism = "ExemptionMechanism";
54
55    private static final String defaultAlg = "EMech";
56
57    private static final String ExemptionMechanismProviderClass = "org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi";
58
59    /**
60     * Test for <code>ExemptionMechanism</code> constructor
61     * Assertion: creates new object using provider and mechanism name
62     */
63    public void testExemptionMechanism() throws Exception {
64        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
65                "Provider for ExemptionMechanism testing",
66                srvExemptionMechanism.concat(".").concat(defaultAlg),
67                ExemptionMechanismProviderClass);
68
69        ExemptionMechanismSpi spi = new MyExemptionMechanismSpi();
70
71        ExemptionMechanism em = new ExemptionMechanism(spi, mProv, defaultAlg) {};
72        assertEquals("Incorrect provider", em.getProvider(), mProv);
73        assertEquals("Incorrect algorithm", em.getName(), defaultAlg);
74        try {
75            em.init(null);
76            fail("InvalidKeyException must be thrown");
77        } catch (InvalidKeyException e) {}
78
79        try {
80            em.getOutputSize(100);
81            fail("IllegalStateException must be thrown");
82        } catch (IllegalStateException e) {}
83
84
85        em = new ExemptionMechanism(null, null, null) {};
86        assertNull("Incorrect mechanism", em.getName());
87        assertNull("Incorrect provider", em.getProvider());
88        try {
89            em.init(null);
90            fail("NullPointerException must be thrown");
91        } catch (NullPointerException e) {}
92        try {
93            em.getOutputSize(100);
94            fail("IllegalStateException must be thrown");
95        } catch (IllegalStateException e) {}
96    }
97
98    /**
99     * javax/crypto/ExemptionMechanism#getInstance(String algorithm, String provider)
100     * Checks exception order
101     */
102    public void testGetInstance() throws Exception {
103        //Regression for HARMONY-762
104        try {
105            ExemptionMechanism.getInstance((String) null, "aaa");
106            fail("NoSuchProviderException must be thrown");
107        } catch (NoSuchProviderException pe) {
108            //expected
109        }
110        try {
111            ExemptionMechanism.getInstance("AlgName", (String)null);
112            fail("IllegalArgumentException expected");
113        } catch (IllegalArgumentException e) {
114            //expected
115        }
116    }
117
118    /**
119     * Test for <code>isCryptoAllowed(Key key)</code> method
120     */
121    public void testIsCryptoAllowed() throws Exception {
122
123        //Regression for HARMONY-1029
124        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
125                "Provider for ExemptionMechanism testing",
126                srvExemptionMechanism.concat(".").concat(defaultAlg),
127                ExemptionMechanismProviderClass);
128
129        ExemptionMechanism em = new ExemptionMechanism(
130                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
131        };
132
133        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
134
135        assertFalse(em.isCryptoAllowed(key));
136
137        em.init(key);
138        assertFalse(em.isCryptoAllowed(key));
139
140        em.genExemptionBlob();
141        assertTrue(em.isCryptoAllowed(key));
142
143        Key key1 = new MyExemptionMechanismSpi().new tmpKey("Proba",
144                new byte[] { 1 });
145        assertFalse(em.isCryptoAllowed(key1));
146
147        em.init(key1);
148        assertFalse(em.isCryptoAllowed(key));
149    }
150
151    /**
152     * Test for <code>genExemptionBlob((byte[] output, int outputOffset)</code> method
153     */
154    public void testGenExemptionBlob() throws Exception {
155        //Regression for HARMONY-1029
156        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
157                "Provider for ExemptionMechanism testing",
158                srvExemptionMechanism.concat(".").concat(defaultAlg),
159                ExemptionMechanismProviderClass);
160
161        ExemptionMechanism em = new ExemptionMechanism(
162                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
163        };
164
165        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
166
167        em.init(key);
168        // ExemptionMechanism doesn't check parameters
169        // it is a responsibility of ExemptionMechanismSpi
170        em.genExemptionBlob(null, 0);
171        em.genExemptionBlob(new byte[0], 0);
172        em.genExemptionBlob(new byte[10], -5);
173    }
174
175    static boolean flag = false;
176
177    class Mock_ExemptionMechanism extends  ExemptionMechanism  {
178        protected Mock_ExemptionMechanism(ExemptionMechanismSpi exmechSpi, Provider provider, String mechanism) {
179            super(exmechSpi, provider, mechanism);
180        }
181
182        @Override
183        protected void finalize() {
184            flag = true;
185            super.finalize();
186        }
187    }
188
189    @SideEffect("Causes OutOfMemoryError to test finalization")
190    public void test_finalize () {
191        Mock_ExemptionMechanism mem = new Mock_ExemptionMechanism(null, null, "Name");
192        assertNotNull(mem);
193        mem = null;
194        assertFalse(flag);
195        Vector v = new Vector();
196        int capacity;
197        try {
198            while(true) {
199                v.add(this);
200            }
201        } catch (OutOfMemoryError e) {
202            capacity = v.size();
203            v = null;
204        }
205
206        v = new Vector();
207        for (int i = 0; i < capacity/2; i++) {
208            v.add(this);
209        }
210        v = null;
211        assertTrue(flag);
212    }
213
214    class Mock_ExemptionMechanismSpi extends MyExemptionMechanismSpi {
215        @Override
216        protected byte[] engineGenExemptionBlob()
217        throws ExemptionMechanismException {
218            throw new ExemptionMechanismException();
219        }
220
221        @Override
222        protected int engineGenExemptionBlob(byte[] output, int outputOffset)
223        throws ShortBufferException, ExemptionMechanismException {
224            if (output.length - outputOffset <
225                    super.engineGenExemptionBlob(output, outputOffset)) {
226                throw new ShortBufferException();
227            }
228            if (output[outputOffset + 3] == 33) {
229                throw new ExemptionMechanismException();
230            }
231            return super.engineGenExemptionBlob(output, outputOffset);
232        }
233    }
234
235    public void test_genExemptionBlob() throws InvalidKeyException,
236    ExemptionMechanismException {
237        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
238                "Provider for ExemptionMechanism testing",
239                srvExemptionMechanism.concat(".").concat(defaultAlg),
240                ExemptionMechanismProviderClass);
241
242        ExemptionMechanism em = new ExemptionMechanism(
243                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
244        };
245
246        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
247
248        try {
249            em.genExemptionBlob();
250            fail("IllegalStateException expected");
251        } catch (IllegalStateException e) {
252            //failed
253        }
254
255        em.init(key);
256
257        assertNotNull(em.genExemptionBlob());
258
259        em = new ExemptionMechanism(
260                new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
261        };
262        key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
263        em.init(key);
264
265        try {
266            em.genExemptionBlob();
267            fail("ExemptionMechanismException expected");
268        } catch (ExemptionMechanismException e) {
269            //failed
270        }
271    }
272
273    public void test_genExemptionBlob$B() throws InvalidKeyException,
274    ExemptionMechanismException, ShortBufferException {
275        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
276                "Provider for ExemptionMechanism testing",
277                srvExemptionMechanism.concat(".").concat(defaultAlg),
278                ExemptionMechanismProviderClass);
279
280        ExemptionMechanism em = new ExemptionMechanism(
281                new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
282        };
283
284        Key key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
285
286        try {
287            em.genExemptionBlob(new byte[10]);
288            fail("IllegalStateException expected");
289        } catch (IllegalStateException e) {
290            //failed
291        }
292
293        em.init(key);
294
295        assertEquals(5, (em.genExemptionBlob(new byte[10])));
296
297        try {
298            em.genExemptionBlob(new byte[2]);
299            fail("ShortBufferException expected");
300        } catch (ShortBufferException e) {
301            //failed
302        }
303        byte[] b = new byte[] {0,0,0,33,0};
304
305        try {
306            em.genExemptionBlob(b);
307            fail("ExemptionMechanismException expected");
308        } catch (ExemptionMechanismException e) {
309            //failed
310        }
311    }
312
313    public void test_genExemptionBlob$BI() throws InvalidKeyException,
314    ExemptionMechanismException, ShortBufferException {
315        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
316                "Provider for ExemptionMechanism testing",
317                srvExemptionMechanism.concat(".").concat(defaultAlg),
318                ExemptionMechanismProviderClass);
319
320        ExemptionMechanism em = new ExemptionMechanism(
321                new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
322        };
323
324        Key key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
325
326        try {
327            em.genExemptionBlob(new byte[10], 2);
328            fail("IllegalStateException expected");
329        } catch (IllegalStateException e) {
330            //failed
331        }
332
333        em.init(key);
334
335        assertEquals(5, (em.genExemptionBlob(new byte[10], 5)));
336
337        try {
338            em.genExemptionBlob(new byte[7], 3);
339            fail("ShortBufferException expected");
340        } catch (ShortBufferException e) {
341            //failed
342        }
343        byte[] b = new byte[] {0, 0, 0, 1, 2, 3, 33, 0};
344
345        try {
346            em.genExemptionBlob(b, 3);
347            fail("ExemptionMechanismException expected");
348        } catch (ExemptionMechanismException e) {
349            //failed
350        }
351    }
352
353    public void test_getInstanceLjava_lang_String() throws Exception {
354        try {
355            ExemptionMechanism.getInstance((String) null);
356            fail("NullPointerException expected");
357        } catch (NullPointerException e) {
358            //expected
359        }
360
361        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
362                "Provider for ExemptionMechanism testing",
363                srvExemptionMechanism.concat(".").concat(defaultAlg),
364                ExemptionMechanismProviderClass);
365
366        ExemptionMechanism em = new ExemptionMechanism(
367                new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
368        };
369
370        try {
371            em.getInstance("WrongAlgName");
372            fail("NoSuchAlgorithmException expected");
373        } catch (NoSuchAlgorithmException e) {
374            //expected
375        }
376    }
377
378    public void test_getInstanceLjava_lang_StringLjava_security_Provider()
379    throws Exception {
380        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
381                "Provider for ExemptionMechanism testing",
382                srvExemptionMechanism.concat(".").concat(defaultAlg),
383                ExemptionMechanismProviderClass);
384
385        try {
386            ExemptionMechanism.getInstance((String) null, mProv);
387            fail("NullPointerException expected");
388        } catch (NullPointerException e) {
389            //expected
390        }
391
392        ExemptionMechanism em = new ExemptionMechanism(
393                new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
394        };
395
396        try {
397            em.getInstance("WrongAlgName", mProv);
398            fail("NoSuchAlgorithmException expected");
399        } catch (NoSuchAlgorithmException e) {
400            //expected
401        }
402
403        try {
404            em.getInstance("WrongAlgName", (Provider)null);
405            fail("IllegalArgumentException expected");
406        } catch (IllegalArgumentException e) {
407            //expected
408        }
409    }
410
411    public void test_getName() throws Exception {
412        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
413                "Provider for ExemptionMechanism testing",
414                srvExemptionMechanism.concat(".").concat(defaultAlg),
415                ExemptionMechanismProviderClass);
416
417        ExemptionMechanism em = new ExemptionMechanism(
418                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
419        };
420
421        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
422
423        assertEquals(defaultAlg, em.getName());
424    }
425
426    public void test_getOutputSizeI() throws Exception {
427        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
428                "Provider for ExemptionMechanism testing",
429                srvExemptionMechanism.concat(".").concat(defaultAlg),
430                ExemptionMechanismProviderClass);
431
432        ExemptionMechanism em = new ExemptionMechanism(
433                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
434        };
435
436        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
437
438        try {
439            em.getOutputSize(10);
440            fail("IllegalStateException expected");
441        } catch (IllegalStateException e) {
442            //failed
443        }
444
445        em.init(key);
446        assertEquals(10, em.getOutputSize(10));
447    }
448
449    public void test_getProvider() throws Exception {
450        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
451                "Provider for ExemptionMechanism testing",
452                srvExemptionMechanism.concat(".").concat(defaultAlg),
453                ExemptionMechanismProviderClass);
454
455        ExemptionMechanism em = new ExemptionMechanism(
456                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
457        };
458
459        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
460
461        assertEquals(mProv, em.getProvider());
462    }
463
464    public void test_initLjava_security_Key() throws Exception {
465        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
466                "Provider for ExemptionMechanism testing",
467                srvExemptionMechanism.concat(".").concat(defaultAlg),
468                ExemptionMechanismProviderClass);
469
470        ExemptionMechanism em = new ExemptionMechanism(
471                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
472        };
473
474        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
475
476        em.init(key);
477
478        KeyGenerator kg = KeyGenerator.getInstance("DES");
479        kg.init(56, new SecureRandom());
480        key = kg.generateKey();
481
482        try {
483            em.init(null);
484            fail("InvalidKeyException expected");
485        } catch (InvalidKeyException e) {
486            //expected
487        }
488
489        try {
490            em.init(key);
491            fail("ExemptionMechanismException expected");
492        } catch (ExemptionMechanismException e) {
493            //expected
494        }
495    }
496
497    public void test_initLjava_security_KeyLjava_security_AlgorithmParameters()
498            throws Exception {
499        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
500                "Provider for ExemptionMechanism testing",
501                srvExemptionMechanism.concat(".").concat(defaultAlg),
502                ExemptionMechanismProviderClass);
503
504        ExemptionMechanism em = new ExemptionMechanism(
505                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
506        };
507
508        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
509
510        em.init(key, AlgorithmParameters.getInstance("DES"));
511
512        try {
513            em.init(key, (AlgorithmParameters)null);
514            fail("InvalidAlgorithmParameterException expected");
515        } catch (InvalidAlgorithmParameterException e) {
516            //expected
517        }
518
519        KeyGenerator kg = KeyGenerator.getInstance("DES");
520        kg.init(56, new SecureRandom());
521        key = kg.generateKey();
522
523        try {
524            em.init(null, AlgorithmParameters.getInstance("DES"));
525            fail("InvalidKeyException expected");
526        } catch (InvalidKeyException e) {
527            //expected
528        }
529
530        try {
531            em.init(key, AlgorithmParameters.getInstance("DES"));
532            fail("ExemptionMechanismException expected");
533        } catch (ExemptionMechanismException e) {
534            //expected
535        }
536    }
537
538    public void test_initLjava_security_KeyLjava_security_spec_AlgorithmParameterSpec()
539            throws Exception{
540        Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
541                "Provider for ExemptionMechanism testing",
542                srvExemptionMechanism.concat(".").concat(defaultAlg),
543                ExemptionMechanismProviderClass);
544
545        ExemptionMechanism em = new ExemptionMechanism(
546                new MyExemptionMechanismSpi(), mProv, defaultAlg) {
547        };
548
549        Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
550
551        em.init(key, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
552
553        try {
554            em.init(key, (AlgorithmParameterSpec)null);
555            fail("InvalidAlgorithmParameterException expected");
556        } catch (InvalidAlgorithmParameterException e) {
557            //expected
558        }
559
560        KeyGenerator kg = KeyGenerator.getInstance("DES");
561        kg.init(56, new SecureRandom());
562        key = kg.generateKey();
563
564        try {
565            em.init(null, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
566            fail("InvalidKeyException expected");
567        } catch (InvalidKeyException e) {
568            //expected
569        }
570
571        try {
572            em.init(key, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
573            fail("ExemptionMechanismException expected");
574        } catch (ExemptionMechanismException e) {
575            //expected
576        }
577    }
578}
579
580
581