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