1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.javax.crypto;
18
19import java.security.Provider;
20import java.security.SecureRandom;
21import java.security.Security;
22import java.util.HashMap;
23import java.util.Map;
24import java.util.List;
25import java.util.ArrayList;
26import java.util.Set;
27import javax.crypto.KeyGenerator;
28import javax.crypto.SecretKey;
29import junit.framework.TestCase;
30
31public class KeyGeneratorTest extends TestCase {
32
33    private static boolean isUnsupported(KeyGenerator kg) {
34        // Don't bother testing "Sun..." KeyGenerators
35        return (kg.getAlgorithm().startsWith("Sun"));
36    }
37
38    public void test_getInstance() throws Exception {
39        Provider[] providers = Security.getProviders();
40        for (Provider provider : providers) {
41            Set<Provider.Service> services = provider.getServices();
42            for (Provider.Service service : services) {
43                String type = service.getType();
44                if (!type.equals("KeyGenerator")) {
45                    continue;
46                }
47                String algorithm = service.getAlgorithm();
48                try {
49                    // KeyGenerator.getInstance(String)
50                    KeyGenerator kg1 = KeyGenerator.getInstance(algorithm);
51                    assertEquals(algorithm, kg1.getAlgorithm());
52                    test_KeyGenerator(kg1);
53
54                    // KeyGenerator.getInstance(String, Provider)
55                    KeyGenerator kg2 = KeyGenerator.getInstance(algorithm, provider);
56                    assertEquals(algorithm, kg2.getAlgorithm());
57                    assertEquals(provider, kg2.getProvider());
58                    test_KeyGenerator(kg2);
59
60                    // KeyGenerator.getInstance(String, String)
61                    KeyGenerator kg3 = KeyGenerator.getInstance(algorithm, provider.getName());
62                    assertEquals(algorithm, kg3.getAlgorithm());
63                    assertEquals(provider, kg3.getProvider());
64                    test_KeyGenerator(kg3);
65                } catch (Exception e) {
66                    throw new Exception("Problem testing KeyPairGenerator." + algorithm, e);
67                }
68            }
69        }
70    }
71
72    private static final Map<String, List<Integer>> KEY_SIZES
73            = new HashMap<String, List<Integer>>();
74    private static void putKeySize(String algorithm, int keySize) {
75        algorithm = algorithm.toUpperCase();
76        List<Integer> keySizes = KEY_SIZES.get(algorithm);
77        if (keySizes == null) {
78            keySizes = new ArrayList<Integer>();
79            KEY_SIZES.put(algorithm, keySizes);
80        }
81        keySizes.add(keySize);
82    }
83    private static List<Integer> getKeySizes(String algorithm) throws Exception {
84        algorithm = algorithm.toUpperCase();
85        List<Integer> keySizes = KEY_SIZES.get(algorithm);
86        if (keySizes == null) {
87            throw new Exception("Unknown key sizes for KeyGenerator." + algorithm);
88        }
89        return keySizes;
90    }
91    static {
92        putKeySize("AES", 128);
93        putKeySize("AES", 192);
94        putKeySize("AES", 256);
95        putKeySize("ARC4", 1024);
96        putKeySize("ARC4", 40);
97        putKeySize("ARC4", 41);
98        putKeySize("ARCFOUR", 1024);
99        putKeySize("ARCFOUR", 40);
100        putKeySize("ARCFOUR", 41);
101        putKeySize("Blowfish", 32);
102        putKeySize("Blowfish", 32+8);
103        putKeySize("Blowfish", 448);
104        putKeySize("DES", 56);
105        putKeySize("DESede", 112);
106        putKeySize("DESede", 168);
107        putKeySize("RC2", 40);
108        putKeySize("RC2", 41);
109        putKeySize("RC2", 1024);
110        putKeySize("RC4", 40);
111        putKeySize("RC4", 41);
112        putKeySize("RC4", 1024);
113        putKeySize("HmacMD5", 1);
114        putKeySize("HmacMD5", 1025);
115        putKeySize("HmacSHA1", 1);
116        putKeySize("HmacSHA1", 1025);
117        putKeySize("HmacSHA256", 40);
118        putKeySize("HmacSHA256", 1025);
119        putKeySize("HmacSHA384", 40);
120        putKeySize("HmacSHA384", 1025);
121        putKeySize("HmacSHA512", 40);
122        putKeySize("HmacSHA512", 1025);
123    }
124
125    private void test_KeyGenerator(KeyGenerator kg) throws Exception {
126        if (isUnsupported(kg)) {
127            return;
128        }
129
130        kg.init((SecureRandom) null);
131        test_SecretKey(kg, kg.generateKey());
132
133        kg.init(new SecureRandom());
134        test_SecretKey(kg, kg.generateKey());
135
136        String algorithm = kg.getAlgorithm();
137        List<Integer> keySizes = getKeySizes(algorithm);
138        for (int keySize : keySizes) {
139            kg.init(keySize);
140            test_SecretKey(kg, kg.generateKey());
141
142            kg.init(keySize, (SecureRandom) null);
143            test_SecretKey(kg, kg.generateKey());
144
145            kg.init(keySize, new SecureRandom());
146            test_SecretKey(kg, kg.generateKey());
147        }
148    }
149
150    private void test_SecretKey(KeyGenerator kg, SecretKey sk) throws Exception {
151        assertNotNull(sk);
152        assertEquals(kg.getAlgorithm().toUpperCase(), sk.getAlgorithm().toUpperCase());
153        assertNotNull(sk.getEncoded());
154        assertNotNull(sk.getFormat());
155    }
156}
157