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 package org.apache.harmony.security.tests.java.security; 19 20 import java.security.InvalidKeyException; 21 import java.security.Key; 22 import java.security.KeyFactory; 23 import java.security.KeyFactorySpi; 24 import java.security.KeyPair; 25 import java.security.KeyPairGenerator; 26 import java.security.NoSuchAlgorithmException; 27 import java.security.NoSuchProviderException; 28 import java.security.PrivateKey; 29 import java.security.Provider; 30 import java.security.PublicKey; 31 import java.security.SecureRandom; 32 import java.security.Security; 33 import java.security.spec.InvalidKeySpecException; 34 import java.security.spec.KeySpec; 35 import java.security.spec.PKCS8EncodedKeySpec; 36 import java.security.spec.X509EncodedKeySpec; 37 import java.util.Arrays; 38 import java.util.Enumeration; 39 import java.util.Vector; 40 import libcore.java.security.StandardNames; 41 42 public class KeyFactory2Test extends junit.framework.TestCase { 43 44 private static final String KEYFACTORY_ID = "KeyFactory."; 45 46 private String[] keyfactAlgs = null; 47 48 private String providerName = null; 49 50 static class KeepAlive extends Thread { 51 int sleepTime, iterations; 52 53 public KeepAlive(int sleepTime, int iterations) { 54 this.sleepTime = sleepTime; 55 this.iterations = iterations; 56 } 57 58 public void run() { 59 synchronized (this) { 60 this.notify(); 61 } 62 for (int i = 0; i < iterations; i++) { 63 try { 64 Thread.sleep(sleepTime); 65 } catch (InterruptedException e) { 66 break; 67 } 68 } 69 } 70 } 71 72 private KeepAlive createKeepAlive(String alg) { 73 if (alg.equals("RSA")) { 74 // 32 minutes 75 KeepAlive keepalive = new KeepAlive(240000, 8); 76 synchronized (keepalive) { 77 keepalive.start(); 78 try { 79 keepalive.wait(); 80 } catch (InterruptedException e) { 81 // ignore 82 } 83 } 84 return keepalive; 85 } 86 return null; 87 } 88 89 public void test_constructor() throws Exception { 90 KeyFactorySpi kfs = new KeyFactorySpiStub(); 91 92 new KeyFactoryStub(null, null, null); 93 94 Provider[] providers = Security.getProviders("KeyFactory.DSA"); 95 if (providers != null) { 96 for (int i = 0; i < providers.length; i++) { 97 KeyFactoryStub kf = new KeyFactoryStub(kfs, providers[i], 98 "algorithm name"); 99 assertEquals("algorithm name", kf.getAlgorithm()); 100 assertEquals(providers[i], kf.getProvider()); 101 } 102 } else { 103 fail("No providers support KeyFactory.DSA"); 104 } 105 } 106 107 public void test_generatePrivateLjava_security_spec_KeySpec() throws Exception { 108 // Test for method java.security.PrivateKey 109 // java.security.KeyFactory.generatePrivate(java.security.spec.KeySpec) 110 for (int i = 0; i < keyfactAlgs.length; i++) { 111 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], providerName); 112 KeyPairGenerator keyGen = KeyPairGenerator.getInstance(keyfactAlgs[i]); 113 SecureRandom random = new SecureRandom(); // We don't use 114 // getInstance 115 keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random); 116 KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]); 117 KeyPair keys = keyGen.generateKeyPair(); 118 if (keepalive != null) { 119 keepalive.interrupt(); 120 } 121 122 KeySpec privateKeySpec = fact.getKeySpec(keys.getPrivate(), 123 StandardNames.getPrivateKeySpecClass(keyfactAlgs[i])); 124 PrivateKey privateKey = fact.generatePrivate(privateKeySpec); 125 assertEquals("generatePrivate generated different key for algorithm " + keyfactAlgs[i], 126 Arrays.toString(keys.getPrivate().getEncoded()), 127 Arrays.toString(privateKey.getEncoded())); 128 privateKey = fact.generatePrivate(new PKCS8EncodedKeySpec(keys.getPrivate().getEncoded())); 129 assertEquals("generatePrivate generated different key for algorithm " + keyfactAlgs[i], 130 Arrays.toString(keys.getPrivate().getEncoded()), 131 Arrays.toString(privateKey.getEncoded())); 132 } 133 } 134 135 public void test_generatePublicLjava_security_spec_KeySpec() throws Exception { 136 // Test for method java.security.PublicKey 137 // java.security.KeyFactory.generatePublic(java.security.spec.KeySpec) 138 for (int i = 0; i < keyfactAlgs.length; i++) { 139 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], 140 providerName); 141 KeyPairGenerator keyGen = KeyPairGenerator 142 .getInstance(keyfactAlgs[i]); 143 // We don't use getInstance 144 SecureRandom random = new SecureRandom(); 145 keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random); 146 KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]); 147 KeyPair keys = keyGen.generateKeyPair(); 148 if (keepalive != null) { 149 keepalive.interrupt(); 150 } 151 KeySpec publicKeySpec = fact.getKeySpec(keys.getPublic(), 152 StandardNames.getPublicKeySpecClass(keyfactAlgs[i])); 153 PublicKey publicKey = fact.generatePublic(publicKeySpec); 154 assertEquals( 155 "generatePublic generated different key for algorithm " 156 + keyfactAlgs[i] + " (provider=" 157 + fact.getProvider().getName() + ")", 158 Arrays.toString(keys.getPublic().getEncoded()), 159 Arrays.toString(publicKey.getEncoded())); 160 } 161 } 162 163 public void test_getAlgorithm() throws Exception { 164 // Test for method java.lang.String 165 // java.security.KeyFactory.getAlgorithm() 166 for (int i = 0; i < keyfactAlgs.length; i++) { 167 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], 168 providerName); 169 assertTrue("getAlgorithm ok for algorithm " + keyfactAlgs[i], 170 fact.getAlgorithm().equals(keyfactAlgs[i])); 171 } 172 } 173 174 public void test_getInstanceLjava_lang_String() throws Exception { 175 // Test for method java.security.KeyFactory 176 // java.security.KeyFactory.getInstance(java.lang.String) 177 for (int i = 0; i < keyfactAlgs.length; i++) { 178 assertNotNull(KeyFactory.getInstance(keyfactAlgs[i])); 179 } 180 } 181 182 public void test_getInstanceLjava_lang_StringLjava_lang_String() throws Exception { 183 // Test1: Test for method java.security.KeyFactory 184 // java.security.KeyFactory.getInstance(java.lang.String, 185 // java.lang.String) 186 Provider[] providers = Security.getProviders("KeyFactory.DSA"); 187 assertNotNull(providers); 188 189 for (int i = 0; i < providers.length; i++) { 190 KeyFactory.getInstance("DSA", providers[i].getName()); 191 } 192 193 194 // Test2: Test with null provider name 195 try { 196 KeyFactory.getInstance("DSA", (String) null); 197 fail("Expected IllegalArgumentException"); 198 } catch (IllegalArgumentException expected) { 199 } catch (Exception e) { 200 fail("Expected IllegalArgumentException, got " + e); 201 } 202 } 203 204 public void test_getInstanceLjava_lang_StringLjava_security_Provider() throws Exception { 205 // Test1: Test for method java.security.KeyFactory 206 // java.security.KeyFactory.getInstance(java.lang.String, 207 // java.security.Provider) 208 Provider[] providers = Security.getProviders("KeyFactory.DSA"); 209 assertNotNull(providers); 210 211 for (int i = 0; i < providers.length; i++) { 212 KeyFactory.getInstance("DSA", providers[i]); 213 } 214 215 // Test2: Test with null provider name 216 try { 217 KeyFactory.getInstance("DSA", (Provider) null); 218 fail("Expected IllegalArgumentException"); 219 } catch (IllegalArgumentException expected) { 220 } catch (Exception e) { 221 fail("Expected IllegalArgumentException, got " + e); 222 } 223 } 224 225 public void test_getKeySpecLjava_security_KeyLjava_lang_Class() throws Exception { 226 // Test for method java.security.spec.KeySpec 227 // java.security.KeyFactory.getKeySpec(java.security.Key, 228 // java.lang.Class) 229 for (int i = 0; i < keyfactAlgs.length; i++) { 230 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], 231 providerName); 232 KeyPairGenerator keyGen = KeyPairGenerator 233 .getInstance(keyfactAlgs[i]); 234 235 // We don't use getInstance 236 SecureRandom random = new SecureRandom(); 237 keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random); 238 KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]); 239 KeyPair keys = keyGen.generateKeyPair(); 240 if (keepalive != null) { 241 keepalive.interrupt(); 242 } 243 KeySpec privateKeySpec = fact.getKeySpec(keys.getPrivate(), 244 StandardNames.getPrivateKeySpecClass(keyfactAlgs[i])); 245 KeySpec publicKeySpec = fact.getKeySpec(keys.getPublic(), 246 StandardNames.getPublicKeySpecClass(keyfactAlgs[i])); 247 PrivateKey privateKey = fact.generatePrivate(privateKeySpec); 248 PublicKey publicKey = fact.generatePublic(publicKeySpec); 249 assertEquals( 250 "generatePrivate generated different key for algorithm " 251 + keyfactAlgs[i] + " (provider=" 252 + fact.getProvider().getName() + ")", 253 Arrays.toString(keys.getPrivate().getEncoded()), 254 Arrays.toString(privateKey.getEncoded())); 255 assertEquals( 256 "generatePublic generated different key for algorithm " 257 + keyfactAlgs[i] + " (provider=" 258 + fact.getProvider().getName() + ")", 259 Arrays.toString(keys.getPublic().getEncoded()), 260 Arrays.toString(publicKey.getEncoded())); 261 KeySpec encodedSpec = fact.getKeySpec(keys.getPublic(), 262 X509EncodedKeySpec.class); 263 assertTrue("improper key spec for encoded public key", 264 encodedSpec.getClass().equals(X509EncodedKeySpec.class)); 265 encodedSpec = fact.getKeySpec(keys.getPrivate(), 266 PKCS8EncodedKeySpec.class); 267 assertTrue("improper key spec for encoded private key", 268 encodedSpec.getClass() 269 .equals(PKCS8EncodedKeySpec.class)); 270 } 271 } 272 273 public void test_getProvider() throws Exception { 274 // Test for method java.security.Provider 275 // java.security.KeyFactory.getProvider() 276 for (int i = 0; i < keyfactAlgs.length; i++) { 277 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i]); 278 Provider p = fact.getProvider(); 279 assertNotNull("provider is null for algorithm " + keyfactAlgs[i], p); 280 } 281 } 282 283 public void test_translateKeyLjava_security_Key() throws Exception { 284 // Test for method java.security.Key 285 // java.security.KeyFactory.translateKey(java.security.Key) 286 for (int i = 0; i < keyfactAlgs.length; i++) { 287 KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], 288 providerName); 289 KeyPairGenerator keyGen = KeyPairGenerator 290 .getInstance(keyfactAlgs[i]); 291 292 // We don't use getInstance 293 SecureRandom random = new SecureRandom(); 294 keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random); 295 KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]); 296 KeyPair keys = keyGen.generateKeyPair(); 297 if (keepalive != null) { 298 keepalive.interrupt(); 299 } 300 fact.translateKey(keys.getPrivate()); 301 } 302 } 303 304 protected void setUp() { 305 if (keyfactAlgs == null) { 306 Provider[] providers = Security.getProviders(); 307 // Arbitrarily use the first provider that supports 308 // KeyFactory algorithms 309 for (Provider provider : providers) { 310 providerName = provider.getName(); 311 keyfactAlgs = getKeyFactoryAlgorithms(providerName); 312 if (keyfactAlgs.length != 0) { 313 break; 314 } 315 } 316 } 317 } 318 319 /* 320 * Returns the key algorithms that the given provider supports. 321 */ 322 private String[] getKeyFactoryAlgorithms(String providerName) { 323 Vector<String> algs = new Vector<String>(); 324 325 Provider provider = Security.getProvider(providerName); 326 if (provider == null) 327 return new String[0]; 328 Enumeration<Object> e = provider.keys(); 329 while (e.hasMoreElements()) { 330 String algorithm = (String) e.nextElement(); 331 if (algorithm.startsWith(KEYFACTORY_ID) && !algorithm.contains(" ")) { 332 algs.addElement(algorithm.substring(KEYFACTORY_ID.length())); 333 } 334 } 335 336 return algs.toArray(new String[algs.size()]); 337 } 338 339 public class KeyFactoryStub extends KeyFactory { 340 public KeyFactoryStub(KeyFactorySpi keyFacSpi, Provider provider, 341 String algorithm) { 342 super(keyFacSpi, provider, algorithm); 343 } 344 } 345 346 public class KeyFactorySpiStub extends KeyFactorySpi { 347 public KeyFactorySpiStub() { 348 super(); 349 } 350 351 public PrivateKey engineGeneratePrivate(KeySpec keySpec) { 352 return null; 353 } 354 355 public PublicKey engineGeneratePublic(KeySpec keySpec) { 356 return null; 357 } 358 359 public <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) { 360 return null; 361 } 362 363 public Key engineTranslateKey(Key key) { 364 return null; 365 } 366 } 367 } 368