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 Vera Y. Petrashkova
20*/
21
22package org.apache.harmony.crypto.tests.javax.crypto;
23
24import java.security.InvalidKeyException;
25import java.security.NoSuchAlgorithmException;
26import java.security.NoSuchProviderException;
27import java.security.Provider;
28import java.security.spec.InvalidKeySpecException;
29import java.security.spec.KeySpec;
30
31import javax.crypto.SecretKey;
32import javax.crypto.SecretKeyFactory;
33import javax.crypto.SecretKeyFactorySpi;
34import javax.crypto.spec.DESKeySpec;
35import javax.crypto.spec.DESedeKeySpec;
36import javax.crypto.spec.SecretKeySpec;
37
38import org.apache.harmony.crypto.tests.support.MySecretKeyFactorySpi;
39import org.apache.harmony.security.tests.support.SpiEngUtils;
40
41import junit.framework.TestCase;
42
43
44/**
45 * Tests for <code>SecretKeyFactory</code> class constructors and methods.
46 *
47 */
48
49public class SecretKeyFactoryTest extends TestCase {
50
51    public static final String srvSecretKeyFactory = "SecretKeyFactory";
52
53    private static String defaultAlgorithm1 = "DESede";
54    private static String defaultAlgorithm2 = "DES";
55
56    public static String defaultAlgorithm = null;
57
58    private static String defaultProviderName = null;
59
60    private static Provider defaultProvider = null;
61
62    private static final String[] invalidValues = SpiEngUtils.invalidValues;
63
64    public static final String[] validValues = new String[2];
65    private static boolean DEFSupported = false;
66
67    private static final String NotSupportMsg = "Default algorithm is not supported";
68
69    static {
70        defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm1,
71                srvSecretKeyFactory);
72        DEFSupported = (defaultProvider != null);
73        if (DEFSupported) {
74            defaultAlgorithm = defaultAlgorithm1;
75            validValues[0] = defaultAlgorithm.toUpperCase();
76            validValues[1] = defaultAlgorithm.toLowerCase();
77            defaultProviderName = defaultProvider.getName();
78        } else {
79            defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm2,
80                    srvSecretKeyFactory);
81            DEFSupported = (defaultProvider != null);
82            if (DEFSupported) {
83                defaultAlgorithm = defaultAlgorithm2;
84                validValues[0] = defaultAlgorithm.toUpperCase();
85                validValues[2] = defaultAlgorithm.toLowerCase();
86                defaultProviderName = defaultProvider.getName();
87            } else {
88                defaultAlgorithm = null;
89                defaultProviderName = null;
90                defaultProvider = null;
91            }
92        }
93    }
94
95    protected SecretKeyFactory[] createSKFac() {
96        if (!DEFSupported) {
97            fail(defaultAlgorithm + " algorithm is not supported");
98            return null;
99        }
100        SecretKeyFactory[] skF = new SecretKeyFactory[3];
101        try {
102            skF[0] = SecretKeyFactory.getInstance(defaultAlgorithm);
103            skF[1] = SecretKeyFactory.getInstance(defaultAlgorithm,
104                    defaultProvider);
105            skF[2] = SecretKeyFactory.getInstance(defaultAlgorithm,
106                    defaultProviderName);
107            return skF;
108        } catch (Exception e) {
109            e.printStackTrace();
110            return null;
111        }
112    }
113
114    /**
115     * Test for <code>SecretKeyFactory</code> constructor
116     * Assertion: returns SecretKeyFactory object
117     */
118    public void testSecretKeyFactory01() throws NoSuchAlgorithmException,
119            InvalidKeySpecException, InvalidKeyException {
120        if (!DEFSupported) {
121            fail(NotSupportMsg);
122            return;
123        }
124        SecretKeyFactorySpi spi = new MySecretKeyFactorySpi();
125        SecretKeyFactory secKF = new mySecretKeyFactory(spi, defaultProvider,
126                defaultAlgorithm);
127        assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
128                defaultAlgorithm);
129        assertEquals("Incorrect provider", secKF.getProvider(), defaultProvider);
130        assertNull("Incorrect result", secKF.generateSecret(null));
131        assertNull("Incorrect result", secKF.getKeySpec(null, null));
132        assertNull("Incorrect result", secKF.translateKey(null));
133        secKF = new mySecretKeyFactory(null, null, null);
134        assertNull("Algorithm must be null", secKF.getAlgorithm());
135        assertNull("Provider must be null", secKF.getProvider());
136        try {
137            secKF.translateKey(null);
138            fail("NullPointerException must be thrown");
139        } catch (NullPointerException e) {
140        }
141    }
142
143    /**
144     * Test for <code>getInstance(String algorithm)</code> method
145     * Assertions:
146     * throws NullPointerException when algorithm is null;
147     * throws NoSuchAlgorithmException when algorithm has invalid value
148     */
149    public void testSecretKeyFactory02() throws NoSuchAlgorithmException {
150        try {
151            SecretKeyFactory.getInstance(null);
152            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
153        } catch (NullPointerException e) {
154        } catch (NoSuchAlgorithmException e) {
155        }
156        for (int i = 0; i < invalidValues.length; i++) {
157            try {
158                SecretKeyFactory.getInstance(invalidValues[i]);
159                fail("NoSuchAlgorithmException was not thrown as expected");
160            } catch (NoSuchAlgorithmException e) {
161            }
162        }
163    }
164
165    /**
166     * Test for <code>getInstance(String algorithm)</code> method
167     * Assertion: returns SecretKeyObject
168     */
169    public void testSecretKeyFactory03() throws NoSuchAlgorithmException {
170        if (!DEFSupported) {
171            fail(NotSupportMsg);
172            return;
173        }
174        for (int i = 0; i < validValues.length; i++) {
175            SecretKeyFactory secKF = SecretKeyFactory
176                    .getInstance(validValues[i]);
177            assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
178                    validValues[i]);
179        }
180    }
181
182    /**
183     * Test for <code>getInstance(String algorithm, String provider)</code>
184     * method
185     * Assertion:
186     * throws NullPointerException when algorithm is null;
187     * throws NoSuchAlgorithmException when algorithm is invalid
188     */
189    public void testSecretKeyFactory04() throws NoSuchAlgorithmException,
190            NoSuchProviderException {
191        if (!DEFSupported) {
192            fail(NotSupportMsg);
193            return;
194        }
195        try {
196            SecretKeyFactory.getInstance(null, defaultProviderName);
197            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
198        } catch (NullPointerException e) {
199        } catch (NoSuchAlgorithmException e) {
200        }
201        for (int i = 0; i < invalidValues.length; i++) {
202            try {
203                SecretKeyFactory.getInstance(invalidValues[i],
204                        defaultProviderName);
205                fail("NoSuchAlgorithmException was not thrown as expected (algorithm: "
206                        .concat(invalidValues[i]).concat(")"));
207            } catch (NoSuchAlgorithmException e) {
208            }
209        }
210    }
211
212    /**
213     * Test for <code>getInstance(String algorithm, String provider)</code>
214     * method
215     * Assertion:
216     * throws IllegalArgumentException when provider is null or empty;
217     * throws NoSuchProviderException when provider has invalid value
218     */
219    public void testSecretKeyFactory05() throws NoSuchAlgorithmException,
220            NoSuchProviderException {
221        if (!DEFSupported) {
222            fail(NotSupportMsg);
223            return;
224        }
225        String prov = null;
226        for (int i = 0; i < validValues.length; i++) {
227            try {
228                SecretKeyFactory.getInstance(validValues[i], prov);
229                fail("IllegalArgumentException was not thrown as expected (algorithm: "
230                        .concat(validValues[i]).concat(" provider: null"));
231            } catch (IllegalArgumentException e) {
232            }
233            try {
234                SecretKeyFactory.getInstance(validValues[i], "");
235                fail("IllegalArgumentException was not thrown as expected (algorithm: "
236                        .concat(validValues[i]).concat(" provider: empty"));
237            } catch (IllegalArgumentException e) {
238            }
239            for (int j = 1; j < invalidValues.length; j++) {
240                try {
241                    SecretKeyFactory.getInstance(validValues[i],
242                            invalidValues[j]);
243                    fail("NoSuchProviderException was not thrown as expected (algorithm: "
244                            .concat(validValues[i]).concat(" provider: ")
245                            .concat(invalidValues[j]).concat(")"));
246                } catch (NoSuchProviderException e) {
247                }
248            }
249        }
250    }
251
252    /**
253     * Test for <code>getInstance(String algorithm, String provider)</code>
254     * method
255     * Assertion: returns SecretKeyFactory object
256     */
257    public void testSecretKeyFactory06() throws NoSuchProviderException,
258            NoSuchAlgorithmException {
259        if (!DEFSupported) {
260            fail(NotSupportMsg);
261            return;
262        }
263        for (int i = 0; i < validValues.length; i++) {
264            SecretKeyFactory secKF = SecretKeyFactory.getInstance(
265                    validValues[i], defaultProviderName);
266            assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
267                    validValues[i]);
268            assertEquals("Incorrect provider", secKF.getProvider().getName(),
269                    defaultProviderName);
270        }
271    }
272
273    /**
274     * Test for <code>getInstance(String algorithm, Provider provider)</code>
275     * method
276     * Assertion: throws NullPointerException when algorithm is null;
277     * throws NoSuchAlgorithmException when algorithm is invalid
278     */
279    public void testSecretKeyFactory07() throws NoSuchAlgorithmException {
280        if (!DEFSupported) {
281            fail(NotSupportMsg);
282            return;
283        }
284        try {
285            SecretKeyFactory.getInstance(null, defaultProvider);
286            fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
287        } catch (NullPointerException e) {
288        } catch (NoSuchAlgorithmException e) {
289        }
290        for (int i = 0; i < invalidValues.length; i++) {
291            try {
292                SecretKeyFactory.getInstance(invalidValues[i], defaultProvider);
293                fail("NoSuchAlgorithmException was not thrown as expected (algorithm: "
294                        .concat(invalidValues[i]).concat(")"));
295            } catch (NoSuchAlgorithmException e) {
296            }
297        }
298    }
299
300    /**
301     * Test for <code>getInstance(String algorithm, Provider provider)</code>
302     * method
303     * Assertion: throws IllegalArgumentException when provider is null
304     */
305    public void testSecretKeyFactory08() throws NoSuchAlgorithmException {
306        if (!DEFSupported) {
307            fail(NotSupportMsg);
308            return;
309        }
310        Provider prov = null;
311        for (int i = 0; i < validValues.length; i++) {
312            try {
313                SecretKeyFactory.getInstance(validValues[i], prov);
314                fail("IllegalArgumentException was not thrown as expected (provider is null, algorithm: "
315                        .concat(validValues[i]).concat(")"));
316            } catch (IllegalArgumentException e) {
317            }
318        }
319    }
320
321    /**
322     * Test for <code>getInstance(String algorithm, Provider provider)</code>
323     * method
324     * Assertion: returns SecretKeyFactory object
325     */
326    public void testSecretKeyFactory09() throws NoSuchAlgorithmException {
327        if (!DEFSupported) {
328            fail(NotSupportMsg);
329            return;
330        }
331        for (int i = 0; i < validValues.length; i++) {
332            SecretKeyFactory secKF = SecretKeyFactory.getInstance(
333                    validValues[i], defaultProvider);
334            assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
335                    validValues[i]);
336            assertEquals("Incorrect provider", secKF.getProvider(),
337                    defaultProvider);
338        }
339    }
340
341    /**
342     * Test for <code>generateSecret(KeySpec keySpec)</code> and
343     * <code>getKeySpec(SecretKey key, Class keySpec)
344     * methods
345     * Assertion:
346     * throw InvalidKeySpecException if parameter is inappropriate
347     */
348    public void testSecretKeyFactory10() throws InvalidKeyException,
349            InvalidKeySpecException {
350        if (!DEFSupported) {
351            fail(NotSupportMsg);
352            return;
353        }
354        byte[] bb = new byte[24];
355        KeySpec ks = (defaultAlgorithm.equals(defaultAlgorithm2) ? (KeySpec)new DESKeySpec(bb) :
356            (KeySpec)new DESedeKeySpec(bb));
357        KeySpec rks = null;
358        SecretKeySpec secKeySpec = new SecretKeySpec(bb, defaultAlgorithm);
359        SecretKey secKey = null;
360        SecretKeyFactory[] skF = createSKFac();
361        assertNotNull("SecretKeyFactory object were not created", skF);
362        for (int i = 0; i < skF.length; i++) {
363            try {
364                skF[i].generateSecret(null);
365                fail("generateSecret(null): InvalidKeySpecException must be thrown");
366            } catch (InvalidKeySpecException e) {
367            }
368
369            secKey = skF[i].generateSecret(ks);
370            try {
371                skF[i].getKeySpec(null, null);
372                fail("getKeySpec(null,null): InvalidKeySpecException must be thrown");
373            } catch (InvalidKeySpecException e) {
374            }
375            try {
376                skF[i].getKeySpec(null, ks.getClass());
377                fail("getKeySpec(null, Class): InvalidKeySpecException must be thrown");
378            } catch (InvalidKeySpecException e) {
379            }
380            try {
381                skF[i].getKeySpec(secKey, null);
382                fail("getKeySpec(secKey, null): NullPointerException or InvalidKeySpecException must be thrown");
383            } catch (InvalidKeySpecException e) {
384                // Expected
385            } catch (NullPointerException e) {
386                // Expected
387            }
388
389            try {
390                Class c;
391                if (defaultAlgorithm.equals(defaultAlgorithm2)) {
392                    c = DESedeKeySpec.class;
393                } else {
394                    c = DESKeySpec.class;
395                }
396                skF[i].getKeySpec(secKeySpec, c);
397                fail("getKeySpec(secKey, Class): InvalidKeySpecException must be thrown");
398            } catch (InvalidKeySpecException e) {
399            }
400            rks = skF[i].getKeySpec(secKeySpec, ks.getClass());
401            if (defaultAlgorithm.equals(defaultAlgorithm1)) {
402                assertTrue("Incorrect getKeySpec() result 1",
403                        rks instanceof DESedeKeySpec);
404            } else {
405                assertTrue("Incorrect getKeySpec() result 1",
406                        rks instanceof DESKeySpec);
407            }
408
409            rks = skF[i].getKeySpec(secKey, ks.getClass());
410            if (defaultAlgorithm.equals(defaultAlgorithm1)) {
411                assertTrue("Incorrect getKeySpec() result 2",
412                        rks instanceof DESedeKeySpec);
413            } else {
414                assertTrue("Incorrect getKeySpec() result 2",
415                        rks instanceof DESKeySpec);
416            }
417        }
418    }
419}
420
421class mySecretKeyFactory extends SecretKeyFactory {
422    public mySecretKeyFactory(SecretKeyFactorySpi spi, Provider prov, String alg) {
423        super(spi, prov, alg);
424    }
425}
426