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.java.security; 18 19import java.math.BigInteger; 20import java.security.Key; 21import java.security.KeyFactory; 22import java.security.KeyPair; 23import java.security.KeyPairGenerator; 24import java.security.PrivateKey; 25import java.security.Provider; 26import java.security.Provider.Service; 27import java.security.PublicKey; 28import java.security.SecureRandom; 29import java.security.Security; 30import java.security.interfaces.DSAParams; 31import java.security.interfaces.DSAPrivateKey; 32import java.security.interfaces.DSAPublicKey; 33import java.security.spec.DSAParameterSpec; 34import java.security.spec.PKCS8EncodedKeySpec; 35import java.security.spec.X509EncodedKeySpec; 36import java.util.ArrayList; 37import java.util.Arrays; 38import java.util.HashMap; 39import java.util.List; 40import java.util.Map; 41import java.util.Set; 42 43import junit.framework.TestCase; 44 45public class KeyPairGeneratorTest extends TestCase { 46 47 public void test_getInstance() throws Exception { 48 Provider[] providers = Security.getProviders(); 49 for (Provider provider : providers) { 50 Set<Provider.Service> services = provider.getServices(); 51 for (Provider.Service service : services) { 52 String type = service.getType(); 53 if (!type.equals("KeyPairGenerator")) { 54 continue; 55 } 56 String algorithm = service.getAlgorithm(); 57 try { 58 // KeyPairGenerator.getInstance(String) 59 KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm); 60 assertEquals(algorithm, kpg1.getAlgorithm()); 61 test_KeyPairGenerator(kpg1); 62 63 // KeyPairGenerator.getInstance(String, Provider) 64 KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider); 65 assertEquals(algorithm, kpg2.getAlgorithm()); 66 assertEquals(provider, kpg2.getProvider()); 67 test_KeyPairGenerator(kpg2); 68 69 // KeyPairGenerator.getInstance(String, String) 70 KeyPairGenerator kpg3 = KeyPairGenerator.getInstance(algorithm, 71 provider.getName()); 72 assertEquals(algorithm, kpg3.getAlgorithm()); 73 assertEquals(provider, kpg3.getProvider()); 74 test_KeyPairGenerator(kpg3); 75 } catch (Exception e) { 76 throw new Exception("Problem testing KeyPairGenerator." + algorithm, e); 77 } 78 } 79 } 80 } 81 82 private static final Map<String, List<Integer>> KEY_SIZES 83 = new HashMap<String, List<Integer>>(); 84 private static void putKeySize(String algorithm, int keySize) { 85 algorithm = algorithm.toUpperCase(); 86 List<Integer> keySizes = KEY_SIZES.get(algorithm); 87 if (keySizes == null) { 88 keySizes = new ArrayList<Integer>(); 89 KEY_SIZES.put(algorithm, keySizes); 90 } 91 keySizes.add(keySize); 92 } 93 private static List<Integer> getKeySizes(String algorithm) throws Exception { 94 algorithm = algorithm.toUpperCase(); 95 List<Integer> keySizes = KEY_SIZES.get(algorithm); 96 if (keySizes == null) { 97 throw new Exception("Unknown key sizes for KeyPairGenerator." + algorithm); 98 } 99 return keySizes; 100 } 101 static { 102 putKeySize("DSA", 512); 103 putKeySize("DSA", 512+64); 104 putKeySize("DSA", 1024); 105 putKeySize("RSA", 512); 106 putKeySize("DH", 512); 107 putKeySize("DH", 512+64); 108 putKeySize("DH", 1024); 109 putKeySize("DiffieHellman", 512); 110 putKeySize("DiffieHellman", 512+64); 111 putKeySize("DiffieHellman", 1024); 112 putKeySize("EC", 256); 113 } 114 115 private void test_KeyPairGenerator(KeyPairGenerator kpg) throws Exception { 116 // without a call to initialize 117 test_KeyPair(kpg, kpg.genKeyPair()); 118 test_KeyPair(kpg, kpg.generateKeyPair()); 119 120 String algorithm = kpg.getAlgorithm(); 121 List<Integer> keySizes = getKeySizes(algorithm); 122 for (int keySize : keySizes) { 123 kpg.initialize(keySize); 124 test_KeyPair(kpg, kpg.genKeyPair()); 125 test_KeyPair(kpg, kpg.generateKeyPair()); 126 127 kpg.initialize(keySize, (SecureRandom) null); 128 test_KeyPair(kpg, kpg.genKeyPair()); 129 test_KeyPair(kpg, kpg.generateKeyPair()); 130 131 kpg.initialize(keySize, new SecureRandom()); 132 test_KeyPair(kpg, kpg.genKeyPair()); 133 test_KeyPair(kpg, kpg.generateKeyPair()); 134 } 135 } 136 137 private void test_KeyPair(KeyPairGenerator kpg, KeyPair kp) throws Exception { 138 assertNotNull(kp); 139 test_Key(kpg, kp.getPrivate()); 140 test_Key(kpg, kp.getPublic()); 141 } 142 143 private void test_Key(KeyPairGenerator kpg, Key k) throws Exception { 144 String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(); 145 if (StandardNames.IS_RI && expectedAlgorithm.equals("DIFFIEHELLMAN")) { 146 expectedAlgorithm = "DH"; 147 } 148 assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase()); 149 assertNotNull(k.getEncoded()); 150 assertNotNull(k.getFormat()); 151 152 test_KeyWithAllKeyFactories(k); 153 } 154 155 private void test_KeyWithAllKeyFactories(Key k) throws Exception { 156 byte[] encoded = k.getEncoded(); 157 158 String keyAlgo = k.getAlgorithm(); 159 160 Provider[] providers = Security.getProviders(); 161 for (Provider p : providers) { 162 Set<Provider.Service> services = p.getServices(); 163 for (Provider.Service service : services) { 164 if (!"KeyFactory".equals(service.getType())) { 165 continue; 166 } 167 if (!service.getAlgorithm().equals(keyAlgo)) { 168 continue; 169 } 170 171 if ("PKCS#8".equals(k.getFormat())) { 172 PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded); 173 KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p); 174 PrivateKey privKey = kf.generatePrivate(spec); 175 assertNotNull(privKey); 176 assertTrue(Arrays.equals(privKey.getEncoded(), encoded)); 177 } else if ("X.509".equals(k.getFormat())) { 178 X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded); 179 KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p); 180 PublicKey pubKey = kf.generatePublic(spec); 181 assertNotNull(pubKey); 182 assertTrue(Arrays.equals(encoded, pubKey.getEncoded())); 183 } 184 } 185 } 186 } 187 188 private static final BigInteger DSA_P = new BigInteger(new byte[] { 189 (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9, 190 (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe, 191 (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e, 192 (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c, 193 (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85, 194 (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8, 195 (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6, 196 (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44, 197 (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8, 198 (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c, 199 (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9, 200 (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3, 201 (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c, 202 (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58, 203 (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b, 204 (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40, 205 (byte) 0x23, 206 }); 207 208 private static final BigInteger DSA_Q = new BigInteger(new byte[] { 209 (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50, 210 (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01, 211 (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f, 212 }); 213 214 private static final BigInteger DSA_G = new BigInteger(new byte[] { 215 (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e, 216 (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10, 217 (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21, 218 (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e, 219 (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b, 220 (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc, 221 (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80, 222 (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e, 223 (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a, 224 (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8, 225 (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31, 226 (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e, 227 (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b, 228 (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81, 229 (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e, 230 (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51, 231 }); 232 233 public void testDSAGeneratorWithParams() throws Exception { 234 final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G); 235 236 boolean failure = false; 237 238 final Provider[] providers = Security.getProviders(); 239 for (final Provider p : providers) { 240 Service s = p.getService("KeyPairGenerator", "DSA"); 241 if (s == null) { 242 continue; 243 } 244 245 final KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", p); 246 kpg.initialize(dsaSpec); 247 KeyPair pair = kpg.generateKeyPair(); 248 DSAPrivateKey privKey = (DSAPrivateKey) pair.getPrivate(); 249 DSAPublicKey pubKey = (DSAPublicKey) pair.getPublic(); 250 251 DSAParams actualParams = privKey.getParams(); 252 assertNotNull("DSA params should not be null", actualParams); 253 254 assertEquals("DSA P should be the same as supplied with provider " + p.getName(), 255 DSA_P, actualParams.getP()); 256 assertEquals("DSA Q should be the same as supplied with provider " + p.getName(), 257 DSA_Q, actualParams.getQ()); 258 assertEquals("DSA G should be the same as supplied with provider " + p.getName(), 259 DSA_G, actualParams.getG()); 260 261 actualParams = pubKey.getParams(); 262 assertNotNull("DSA params should not be null", actualParams); 263 264 assertEquals("DSA P should be the same as supplied with provider " + p.getName(), 265 DSA_P, actualParams.getP()); 266 assertEquals("DSA Q should be the same as supplied with provider " + p.getName(), 267 DSA_Q, actualParams.getQ()); 268 assertEquals("DSA G should be the same as supplied with provider " + p.getName(), 269 DSA_G, actualParams.getG()); 270 } 271 } 272} 273