1/* 2 * Copyright (C) 2007 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 org.apache.harmony.security.tests.java.security; 18 19import junit.framework.TestCase; 20 21import org.apache.harmony.security.tests.support.KeyStoreTestSupport; 22import org.apache.harmony.security.tests.support.tmpCallbackHandler; 23 24import java.io.File; 25import java.io.FileOutputStream; 26import java.io.IOException; 27import java.security.KeyStore; 28import java.security.KeyStoreException; 29import java.security.NoSuchAlgorithmException; 30import java.security.Provider; 31import java.security.Security; 32import java.security.cert.CertificateException; 33import java.util.Enumeration; 34 35public class KeyStoreBuilderTest extends TestCase { 36 37 protected void setUp() throws Exception { 38 super.setUp(); 39 } 40 41 protected void tearDown() throws Exception { 42 super.tearDown(); 43 } 44 45 private static char[] pass = { 's', 't', 'o', 'r', 'e', 'p', 'w', 'd' }; 46 47 private KeyStore.PasswordProtection protPass = new KeyStore.PasswordProtection( 48 pass); 49 50 private tmpCallbackHandler tmpCall = new tmpCallbackHandler(); 51 52 private KeyStore.CallbackHandlerProtection callbackHand = new KeyStore.CallbackHandlerProtection( 53 tmpCall); 54 55 private MyProtectionParameter myProtParam = new MyProtectionParameter( 56 new byte[5]); 57 58 public static String[] validValues = KeyStoreTestSupport.validValues; 59 60 private static String defaultType = KeyStoreTestSupport.defaultType; 61 62 63 private static Provider defaultProvider = null; 64 65 static { 66 defaultProvider = Security.getProviders( 67 "KeyStore." + KeyStore.getDefaultType())[0]; 68 } 69 70 /* 71 * test for constructor KeyStoreBuilder 72 */ 73 public void testConstructor() { 74 KeyStoreBuilder ksb; 75 try { 76 ksb = new KeyStoreBuilder(); 77 assertNotNull(ksb); 78 79 ksb.getKeyStore(); 80 ksb.getProtectionParameter("test"); 81 } catch (Exception e) { 82 fail("Unexpected exception " + e.getMessage()); 83 } 84 } 85 86 /* 87 * test for method newInstance(KeyStore, KeyStore.ProtectionParameter) 88 */ 89 public void testNewInstanceKeyStoreProtectionParameter() 90 throws KeyStoreException, NoSuchAlgorithmException, IOException, 91 CertificateException { 92 // exceptions verification 93 94 try { 95 KeyStore.Builder.newInstance(null, null); 96 fail("NullPointerException must be thrown"); 97 } catch (NullPointerException e) { 98 // expected 99 } 100 101 try { 102 KeyStore.Builder.newInstance(null, protPass); 103 fail("NullPointerException must be thrown"); 104 } catch (NullPointerException e) { 105 // expected 106 } 107 108 KeyStore.Builder ksB; 109 110 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 111 try { 112 KeyStore.Builder.newInstance(ks, null); 113 fail("NullPointerException must be thrown when ProtectionParameter is null"); 114 } catch (NullPointerException e) { 115 // expected 116 } 117 118 KeyStore.PasswordProtection protPass1 = new KeyStore.PasswordProtection( 119 pass); 120 KeyStore.ProtectionParameter[] pp = { protPass, protPass1, 121 callbackHand, myProtParam }; 122 for (int i = 0; i < pp.length; i++) { 123 ks = KeyStore.getInstance(KeyStore.getDefaultType()); 124 try { 125 KeyStore.Builder.newInstance(ks, pp[i]); 126 fail("IllegalArgumentException must be thrown because KeyStore was not initialized"); 127 } catch (IllegalArgumentException e) { 128 // expected 129 } 130 131 ks.load(null, pass); 132 ksB = KeyStore.Builder.newInstance(ks, pp[i]); 133 134 assertEquals("Incorrect KeyStore", ksB.getKeyStore().size(), 0); 135 136 ksB = KeyStore.Builder.newInstance(ks, pp[i]); 137 138 // verification getKeyStore() and getProtectionParameter(String 139 // alias) 140 assertEquals("Incorrect KeyStore", ks, ksB.getKeyStore()); 141 142 try { 143 ksB.getProtectionParameter(null); 144 fail("NullPointerException must be thrown"); 145 } catch (NullPointerException e) { 146 } 147 try { 148 assertEquals(ksB.getProtectionParameter("aaa"), pp[i]); 149 } catch (KeyStoreException e) { 150 fail("Unexpected: " + e.toString() + " was thrown"); 151 } 152 153 try { 154 assertEquals(ksB.getProtectionParameter("Bad alias"), pp[i]); 155 } catch (KeyStoreException e) { 156 // KeyStoreException might be thrown because there is no entry 157 // with such alias 158 } 159 160 try { 161 assertEquals(ksB.getProtectionParameter(""), pp[i]); 162 } catch (KeyStoreException e) { 163 // KeyStoreException might be thrown because there is no entry 164 // with such alias 165 } 166 167 KeyStore.ProtectionParameter pPar = ksB 168 .getProtectionParameter("aaa"); 169 170 switch (i) { 171 case 0: 172 assertTrue(pPar instanceof KeyStore.PasswordProtection); 173 break; 174 case 1: 175 assertTrue(pPar instanceof KeyStore.PasswordProtection); 176 break; 177 case 2: 178 assertTrue(pPar instanceof KeyStore.CallbackHandlerProtection); 179 break; 180 case 3: 181 assertTrue(pPar instanceof MyProtectionParameter); 182 break; 183 default: 184 fail("Incorrect protection parameter"); 185 } 186 assertEquals(pPar, pp[i]); 187 } 188 } 189 190 /* 191 * Test for methods: <code>newInstance(String type, Provider provider, File 192 * file, ProtectionParameter protectionParameter)</code> <code>getKeyStore()</code> 193 * <code>getProtectionParameter(String alias)</code> Assertions: throws 194 * NullPointerException if type, file or protectionParameter is null; throws 195 * IllegalArgumentException if file does not exist or is not file; throws 196 * IllegalArgumentException if ProtectionParameter is not PasswordProtection 197 * or CallbackHandlerProtection; returns new object 198 * 199 * getKeyStore() returns specified keystore; getProtectionParameter(String 200 * alias) throws NullPointerException when alias is null; throws 201 * KeyStoreException when alias is not available; returns 202 * ProtectionParameter which is used in newInstance(...) 203 * 204 */ 205 public void testNewInstanceStringProviderFileProtectionParameter() 206 throws Exception { 207 208 File fl = File.createTempFile("KSBuilder_ImplTest", "keystore"); 209 fl.deleteOnExit(); 210 KeyStore.Builder ksB; 211 KeyStore.Builder ksB1; 212 KeyStore ks = null; 213 KeyStore ks1 = null; 214 215 MyProtectionParameter myPP = new MyProtectionParameter(new byte[5]); 216 // check exceptions 217 try { 218 219 KeyStore.Builder.newInstance(null, defaultProvider, fl, protPass); 220 fail("NullPointerException must be thrown when type is null"); 221 } catch (NullPointerException e) { 222 } 223 try { 224 KeyStore.Builder.newInstance(KeyStore.getDefaultType(), defaultProvider, null, 225 protPass); 226 fail("NullPointerException must be thrown when file is null"); 227 } catch (NullPointerException e) { 228 } 229 try { 230 KeyStore.Builder 231 .newInstance(KeyStore.getDefaultType(), defaultProvider, fl, null); 232 fail("NullPointerException must be thrown when ProtectionParameter is null"); 233 } catch (NullPointerException e) { 234 } 235 try { 236 KeyStore.Builder 237 .newInstance(KeyStore.getDefaultType(), defaultProvider, fl, myPP); 238 fail("IllegalArgumentException must be thrown when ProtectionParameter is not correct"); 239 } catch (IllegalArgumentException e) { 240 } 241 try { 242 KeyStore.Builder.newInstance(KeyStore.getDefaultType(), defaultProvider, 243 new File(fl.getAbsolutePath().concat("should_absent")), 244 protPass); 245 fail("IllegalArgumentException must be thrown when file does not exist"); 246 } catch (IllegalArgumentException e) { 247 } 248 try { 249 // 'file' param points to directory 250 KeyStore.Builder.newInstance(KeyStore.getDefaultType(), defaultProvider, fl 251 .getParentFile(), protPass); 252 fail("IllegalArgumentException must be thrown when file does not exist"); 253 } catch (IllegalArgumentException e) { 254 } 255 ksB = KeyStore.Builder.newInstance(KeyStore.getDefaultType(), defaultProvider, fl, 256 protPass); 257 try { 258 ksB.getKeyStore(); 259 fail("KeyStoreException must be throw because file is empty"); 260 } catch (KeyStoreException e) { 261 } 262 263 fl = createKS(); 264 265 // Exception Tests with custom ProtectionParameter 266 try { 267 KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 268 null, fl, myPP); 269 fail("IllegalArgumentException must be " 270 + "thrown for incorrect ProtectionParameter"); 271 } catch (IllegalArgumentException e) { 272 } 273 try { 274 KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 275 defaultProvider, fl, myPP); 276 fail("IllegalArgumentException must be " 277 + "thrown for incorrect ProtectionParameter"); 278 } catch (IllegalArgumentException e) { 279 } 280 281 // Tests with PasswordProtection 282 ksB = KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 283 null, fl, protPass); 284 ksB1 = KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 285 defaultProvider, fl, protPass); 286 try { 287 ks = ksB.getKeyStore(); 288 } catch (KeyStoreException e) { 289 fail("Unexpected KeyException was thrown"); 290 } 291 try { 292 ks1 = ksB1.getKeyStore(); 293 } catch (KeyStoreException e) { 294 fail("Unexpected KeyException was thrown: " + e.getMessage()); 295 } 296 assertEquals("Incorrect KeyStore size", ks.size(), ks1.size()); 297 ; 298 299 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements(); ) { 300 String aName = aliases.nextElement(); 301 try { 302 assertEquals("Incorrect ProtectionParameter", ksB 303 .getProtectionParameter(aName), protPass); 304 } catch (Exception e) { 305 fail("Unexpected: " + e.toString() 306 + " was thrown for alias: " + aName); 307 } 308 } 309 310 ksB.getKeyStore(); 311 312 try { 313 assertEquals(ksB.getProtectionParameter("Bad alias"), protPass); 314 } catch (KeyStoreException e) { 315 // KeyStoreException might be thrown because there is no entry 316 // with such alias 317 } 318 319 320 for (Enumeration<String> aliases = ks1.aliases(); aliases.hasMoreElements(); ) { 321 String aName = aliases.nextElement(); 322 assertEquals("Incorrect ProtectionParameter", ksB1 323 .getProtectionParameter(aName), protPass); 324 } 325 326 try { 327 assertEquals(ksB1.getProtectionParameter("Bad alias"), protPass); 328 } catch (KeyStoreException e) { 329 // KeyStoreException might be thrown because there is no entry 330 // with such alias 331 } 332 333 334 // Tests with CallbackHandlerProtection 335 ksB = KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 336 null, fl, callbackHand); 337 ksB1 = KeyStore.Builder.newInstance(KeyStore.getDefaultType(), 338 defaultProvider, fl, callbackHand); 339 try { 340 ks = ksB.getKeyStore(); 341 fail("KeyStoreException must be thrown for incorrect " 342 + "ProtectionParameter"); 343 } catch (KeyStoreException e) { 344 } 345 try { 346 ks1 = ksB1.getKeyStore(); 347 fail("KeyStoreException must be thrown for incorrect " 348 + "ProtectionParameter"); 349 } catch (KeyStoreException e) { 350 } 351 assertEquals("Incorrect KeyStore size", ks.size(), ks1.size()); 352 353 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) { 354 String aName = aliases.nextElement(); 355 try { 356 assertEquals("Incorrect ProtectionParameter", ksB 357 .getProtectionParameter(aName), callbackHand); 358 } catch (Exception e) { 359 fail("Unexpected: " + e.toString() 360 + " was thrown for alias: " + aName); 361 } 362 } 363 364 for (Enumeration<String> iter = ks1.aliases(); iter.hasMoreElements();) { 365 String aName = iter.nextElement(); 366 assertEquals("Incorrect ProtectionParameter", ksB1 367 .getProtectionParameter(aName), callbackHand); 368 } 369 } 370 371 /* 372 * Test for method: <code>newInstance(String type, Provider provider, 373 * ProtectionParameter protectionParameter)</code> <code>getKeyStore()</code> 374 * <code>getProtectionParameter(String alias)</code> Assertions: throws 375 * NullPointerException if type, or protectionParameter is null; returns new 376 * object 377 * 378 * getKeyStore() returns empty keystore getProtectionParameter(String alias) 379 * throws NullPointerException when alias is null; throws KeyStoreException 380 * when alias is not available 381 * 382 */ 383 public void testNewInstanceStringProviderProtectionParameter() 384 throws KeyStoreException { 385 386 try { 387 KeyStore.Builder.newInstance(null, defaultProvider, protPass); 388 fail("NullPointerException must be thrown when type is null"); 389 } catch (NullPointerException e) { 390 } 391 try { 392 KeyStore.Builder.newInstance(defaultType, defaultProvider, null); 393 fail("NullPointerException must be thrown when ProtectionParameter is null"); 394 } catch (NullPointerException e) { 395 } 396 MyProtectionParameter myPP = new MyProtectionParameter(new byte[5]); 397 KeyStore.ProtectionParameter[] pp = { protPass, myPP, callbackHand }; 398 KeyStore.Builder ksB, ksB1; 399 KeyStore ks = null; 400 for (int i = 0; i < pp.length; i++) { 401 ksB = KeyStore.Builder.newInstance(defaultType, defaultProvider, 402 pp[i]); 403 ksB1 = KeyStore.Builder.newInstance(defaultType, null, pp[i]); 404 switch (i) { 405 case 0: 406 try { 407 ks = ksB.getKeyStore(); 408 assertNotNull("KeyStore is null", ks); 409 try { 410 assertEquals(ksB.getProtectionParameter("Bad alias"), 411 pp[i]); 412 } catch (KeyStoreException e) { 413 // KeyStoreException might be thrown because there is no 414 // entry with such alias 415 } 416 417 ks = ksB1.getKeyStore(); 418 assertNotNull("KeyStore is null", ks); 419 420 try { 421 assertEquals(ksB1.getProtectionParameter("Bad alias"), 422 pp[i]); 423 } catch (KeyStoreException e) { 424 // KeyStoreException might be thrown because there is no 425 // entry with such alias 426 } 427 } catch (KeyStoreException e) { 428 try { 429 ks = ksB.getKeyStore(); 430 } catch (KeyStoreException e1) { 431 assertEquals("Incorrect exception", e.getMessage(), e1 432 .getMessage()); 433 } 434 } 435 break; 436 case 1: 437 case 2: 438 Exception ex1 = null; 439 Exception ex2 = null; 440 try { 441 ks = ksB.getKeyStore(); 442 } catch (KeyStoreException e) { 443 ex1 = e; 444 } 445 try { 446 ks = ksB.getKeyStore(); 447 } catch (KeyStoreException e) { 448 ex2 = e; 449 } 450 assertEquals("Incorrect exception", ex1.getMessage(), ex2 451 .getMessage()); 452 453 try { 454 ksB.getProtectionParameter("aaa"); 455 fail("IllegalStateException must be thrown because getKeyStore() was not invoked"); 456 } catch (IllegalStateException e) { 457 } 458 459 try { 460 ks = ksB1.getKeyStore(); 461 } catch (KeyStoreException e) { 462 ex1 = e; 463 } 464 try { 465 ks = ksB1.getKeyStore(); 466 } catch (KeyStoreException e) { 467 ex2 = e; 468 } 469 assertEquals("Incorrect exception", ex1.getMessage(), ex2 470 .getMessage()); 471 472 try { 473 ksB1.getProtectionParameter("aaa"); 474 fail("IllegalStateException must be thrown because getKeyStore() was not invoked"); 475 } catch (IllegalStateException e) { 476 } 477 break; 478 479 } 480 } 481 } 482 483 /** 484 * Additional class for creating KeyStoreBuilder 485 */ 486 class MyProtectionParameter implements KeyStore.ProtectionParameter { 487 public MyProtectionParameter(byte[] param) { 488 if (param == null) { 489 throw new NullPointerException("param is null"); 490 } 491 } 492 } 493 494// Creates empty KeyStore and loads it to file 495 private File createKS() throws Exception { 496 FileOutputStream fos = null; 497 File ff = File.createTempFile("KSBuilder_ImplTest", "keystore"); 498 ff.deleteOnExit(); 499 try { 500 501 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 502 fos = new FileOutputStream(ff); 503 ks.load(null, null); 504 ks.store(fos, pass); 505 } finally { 506 if (fos != null) { 507 try { 508 fos.close(); 509 } catch (IOException e) { 510 } 511 } 512 } 513 return ff; 514 } 515 516 class KeyStoreBuilder extends KeyStore.Builder { 517 public KeyStoreBuilder() { 518 super(); 519 } 520 521 public KeyStore getKeyStore() { 522 return null; 523 } 524 525 public KeyStore.ProtectionParameter getProtectionParameter(String alias) { 526 return null; 527 } 528 } 529} 530