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