1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.security; 27 28 import java.io.*; 29 import java.net.URI; 30 import java.security.cert.Certificate; 31 import java.security.cert.X509Certificate; 32 import java.security.cert.CertificateException; 33 import java.security.spec.AlgorithmParameterSpec; 34 import java.util.*; 35 import javax.crypto.SecretKey; 36 37 import javax.security.auth.DestroyFailedException; 38 import javax.security.auth.callback.*; 39 40 import sun.security.util.Debug; 41 42 /** 43 * This class represents a storage facility for cryptographic 44 * keys and certificates. 45 * 46 * <p> A {@code KeyStore} manages different types of entries. 47 * Each type of entry implements the {@code KeyStore.Entry} interface. 48 * Three basic {@code KeyStore.Entry} implementations are provided: 49 * 50 * <ul> 51 * <li><b>KeyStore.PrivateKeyEntry</b> 52 * <p> This type of entry holds a cryptographic {@code PrivateKey}, 53 * which is optionally stored in a protected format to prevent 54 * unauthorized access. It is also accompanied by a certificate chain 55 * for the corresponding public key. 56 * 57 * <p> Private keys and certificate chains are used by a given entity for 58 * self-authentication. Applications for this authentication include software 59 * distribution organizations which sign JAR files as part of releasing 60 * and/or licensing software. 61 * 62 * <li><b>KeyStore.SecretKeyEntry</b> 63 * <p> This type of entry holds a cryptographic {@code SecretKey}, 64 * which is optionally stored in a protected format to prevent 65 * unauthorized access. 66 * 67 * <li><b>KeyStore.TrustedCertificateEntry</b> 68 * <p> This type of entry contains a single public key {@code Certificate} 69 * belonging to another party. It is called a <i>trusted certificate</i> 70 * because the keystore owner trusts that the public key in the certificate 71 * indeed belongs to the identity identified by the <i>subject</i> (owner) 72 * of the certificate. 73 * 74 * <p>This type of entry can be used to authenticate other parties. 75 * </ul> 76 * 77 * <p> Each entry in a keystore is identified by an "alias" string. In the 78 * case of private keys and their associated certificate chains, these strings 79 * distinguish among the different ways in which the entity may authenticate 80 * itself. For example, the entity may authenticate itself using different 81 * certificate authorities, or using different public key algorithms. 82 * 83 * <p> Whether aliases are case sensitive is implementation dependent. In order 84 * to avoid problems, it is recommended not to use aliases in a KeyStore that 85 * only differ in case. 86 * 87 * <p> Whether keystores are persistent, and the mechanisms used by the 88 * keystore if it is persistent, are not specified here. This allows 89 * use of a variety of techniques for protecting sensitive (e.g., private or 90 * secret) keys. Smart cards or other integrated cryptographic engines 91 * (SafeKeyper) are one option, and simpler mechanisms such as files may also 92 * be used (in a variety of formats). 93 * 94 * <p> Typical ways to request a KeyStore object include 95 * relying on the default type and providing a specific keystore type. 96 * 97 * <ul> 98 * <li>To rely on the default type: 99 * <pre> 100 * KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 101 * </pre> 102 * The system will return a keystore implementation for the default type. 103 * 104 * <li>To provide a specific keystore type: 105 * <pre> 106 * KeyStore ks = KeyStore.getInstance("JKS"); 107 * </pre> 108 * The system will return the most preferred implementation of the 109 * specified keystore type available in the environment. <p> 110 * </ul> 111 * 112 * <p> Before a keystore can be accessed, it must be 113 * {@link #load(java.io.InputStream, char[]) loaded}. 114 * <pre> 115 * KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 116 * 117 * // get user password and file input stream 118 * char[] password = getPassword(); 119 * 120 * try (FileInputStream fis = new FileInputStream("keyStoreName")) { 121 * ks.load(fis, password); 122 * } 123 * </pre> 124 * 125 * To create an empty keystore using the above {@code load} method, 126 * pass {@code null} as the {@code InputStream} argument. 127 * 128 * <p> Once the keystore has been loaded, it is possible 129 * to read existing entries from the keystore, or to write new entries 130 * into the keystore: 131 * <pre> 132 * KeyStore.ProtectionParameter protParam = 133 * new KeyStore.PasswordProtection(password); 134 * 135 * // get my private key 136 * KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) 137 * ks.getEntry("privateKeyAlias", protParam); 138 * PrivateKey myPrivateKey = pkEntry.getPrivateKey(); 139 * 140 * // save my secret key 141 * javax.crypto.SecretKey mySecretKey; 142 * KeyStore.SecretKeyEntry skEntry = 143 * new KeyStore.SecretKeyEntry(mySecretKey); 144 * ks.setEntry("secretKeyAlias", skEntry, protParam); 145 * 146 * // store away the keystore 147 * try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) { 148 * ks.store(fos, password); 149 * } 150 * </pre> 151 * 152 * Note that although the same password may be used to 153 * load the keystore, to protect the private key entry, 154 * to protect the secret key entry, and to store the keystore 155 * (as is shown in the sample code above), 156 * different passwords or other protection parameters 157 * may also be used. 158 * 159 * <p> Every implementation of the Java platform is required to support 160 * the following standard {@code KeyStore} type: 161 * <ul> 162 * <li>{@code PKCS12}</li> 163 * </ul> 164 * This type is described in the <a href= 165 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore"> 166 * KeyStore section</a> of the 167 * Java Cryptography Architecture Standard Algorithm Name Documentation. 168 * Consult the release documentation for your implementation to see if any 169 * other types are supported. 170 * 171 * @author Jan Luehe 172 * 173 * @see java.security.PrivateKey 174 * @see javax.crypto.SecretKey 175 * @see java.security.cert.Certificate 176 * 177 * @since 1.2 178 */ 179 180 public class KeyStore { 181 182 private static final Debug pdebug = 183 Debug.getInstance("provider", "Provider"); 184 private static final boolean skipDebug = 185 Debug.isOn("engine=") && !Debug.isOn("keystore"); 186 187 /* 188 * Constant to lookup in the Security properties file to determine 189 * the default keystore type. 190 * In the Security properties file, the default keystore type is given as: 191 * <pre> 192 * keystore.type=jks 193 * </pre> 194 */ 195 private static final String KEYSTORE_TYPE = "keystore.type"; 196 197 // The keystore type 198 private String type; 199 200 // The provider 201 private Provider provider; 202 203 // The provider implementation 204 private KeyStoreSpi keyStoreSpi; 205 206 // Has this keystore been initialized (loaded)? 207 private boolean initialized = false; 208 209 /** 210 * A marker interface for {@code KeyStore} 211 * {@link #load(KeyStore.LoadStoreParameter) load} 212 * and 213 * {@link #store(KeyStore.LoadStoreParameter) store} 214 * parameters. 215 * 216 * @since 1.5 217 */ 218 public static interface LoadStoreParameter { 219 /** 220 * Gets the parameter used to protect keystore data. 221 * 222 * @return the parameter used to protect keystore data, or null 223 */ getProtectionParameter()224 public ProtectionParameter getProtectionParameter(); 225 } 226 227 /** 228 * A marker interface for keystore protection parameters. 229 * 230 * <p> The information stored in a {@code ProtectionParameter} 231 * object protects the contents of a keystore. 232 * For example, protection parameters may be used to check 233 * the integrity of keystore data, or to protect the 234 * confidentiality of sensitive keystore data 235 * (such as a {@code PrivateKey}). 236 * 237 * @since 1.5 238 */ 239 public static interface ProtectionParameter { } 240 241 /** 242 * A password-based implementation of {@code ProtectionParameter}. 243 * 244 * @since 1.5 245 */ 246 public static class PasswordProtection implements 247 ProtectionParameter, javax.security.auth.Destroyable { 248 249 private final char[] password; 250 private final String protectionAlgorithm; 251 private final AlgorithmParameterSpec protectionParameters; 252 private volatile boolean destroyed = false; 253 254 /** 255 * Creates a password parameter. 256 * 257 * <p> The specified {@code password} is cloned before it is stored 258 * in the new {@code PasswordProtection} object. 259 * 260 * @param password the password, which may be {@code null} 261 */ PasswordProtection(char[] password)262 public PasswordProtection(char[] password) { 263 this.password = (password == null) ? null : password.clone(); 264 this.protectionAlgorithm = null; 265 this.protectionParameters = null; 266 } 267 268 /** 269 * Creates a password parameter and specifies the protection algorithm 270 * and associated parameters to use when encrypting a keystore entry. 271 * <p> 272 * The specified {@code password} is cloned before it is stored in the 273 * new {@code PasswordProtection} object. 274 * 275 * @param password the password, which may be {@code null} 276 * @param protectionAlgorithm the encryption algorithm name, for 277 * example, {@code PBEWithHmacSHA256AndAES_256}. 278 * See the Cipher section in the <a href= 279 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher"> 280 * Java Cryptography Architecture Standard Algorithm Name 281 * Documentation</a> 282 * for information about standard encryption algorithm names. 283 * @param protectionParameters the encryption algorithm parameter 284 * specification, which may be {@code null} 285 * @exception NullPointerException if {@code protectionAlgorithm} is 286 * {@code null} 287 * 288 * @since 1.8 289 */ PasswordProtection(char[] password, String protectionAlgorithm, AlgorithmParameterSpec protectionParameters)290 public PasswordProtection(char[] password, String protectionAlgorithm, 291 AlgorithmParameterSpec protectionParameters) { 292 if (protectionAlgorithm == null) { 293 throw new NullPointerException("invalid null input"); 294 } 295 this.password = (password == null) ? null : password.clone(); 296 this.protectionAlgorithm = protectionAlgorithm; 297 this.protectionParameters = protectionParameters; 298 } 299 300 /** 301 * Gets the name of the protection algorithm. 302 * If none was set then the keystore provider will use its default 303 * protection algorithm. The name of the default protection algorithm 304 * for a given keystore type is set using the 305 * {@code 'keystore.<type>.keyProtectionAlgorithm'} security property. 306 * For example, the 307 * {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the 308 * name of the default key protection algorithm used for PKCS12 309 * keystores. If the security property is not set, an 310 * implementation-specific algorithm will be used. 311 * 312 * @return the algorithm name, or {@code null} if none was set 313 * 314 * @since 1.8 315 */ getProtectionAlgorithm()316 public String getProtectionAlgorithm() { 317 return protectionAlgorithm; 318 } 319 320 /** 321 * Gets the parameters supplied for the protection algorithm. 322 * 323 * @return the algorithm parameter specification, or {@code null}, 324 * if none was set 325 * 326 * @since 1.8 327 */ getProtectionParameters()328 public AlgorithmParameterSpec getProtectionParameters() { 329 return protectionParameters; 330 } 331 332 /** 333 * Gets the password. 334 * 335 * <p>Note that this method returns a reference to the password. 336 * If a clone of the array is created it is the caller's 337 * responsibility to zero out the password information 338 * after it is no longer needed. 339 * 340 * @see #destroy() 341 * @return the password, which may be {@code null} 342 * @exception IllegalStateException if the password has 343 * been cleared (destroyed) 344 */ getPassword()345 public synchronized char[] getPassword() { 346 if (destroyed) { 347 throw new IllegalStateException("password has been cleared"); 348 } 349 return password; 350 } 351 352 /** 353 * Clears the password. 354 * 355 * @exception DestroyFailedException if this method was unable 356 * to clear the password 357 */ destroy()358 public synchronized void destroy() throws DestroyFailedException { 359 destroyed = true; 360 if (password != null) { 361 Arrays.fill(password, ' '); 362 } 363 } 364 365 /** 366 * Determines if password has been cleared. 367 * 368 * @return true if the password has been cleared, false otherwise 369 */ isDestroyed()370 public synchronized boolean isDestroyed() { 371 return destroyed; 372 } 373 } 374 375 /** 376 * A ProtectionParameter encapsulating a CallbackHandler. 377 * 378 * @since 1.5 379 */ 380 public static class CallbackHandlerProtection 381 implements ProtectionParameter { 382 383 private final CallbackHandler handler; 384 385 /** 386 * Constructs a new CallbackHandlerProtection from a 387 * CallbackHandler. 388 * 389 * @param handler the CallbackHandler 390 * @exception NullPointerException if handler is null 391 */ CallbackHandlerProtection(CallbackHandler handler)392 public CallbackHandlerProtection(CallbackHandler handler) { 393 if (handler == null) { 394 throw new NullPointerException("handler must not be null"); 395 } 396 this.handler = handler; 397 } 398 399 /** 400 * Returns the CallbackHandler. 401 * 402 * @return the CallbackHandler. 403 */ getCallbackHandler()404 public CallbackHandler getCallbackHandler() { 405 return handler; 406 } 407 408 } 409 410 /** 411 * A marker interface for {@code KeyStore} entry types. 412 * 413 * @since 1.5 414 */ 415 public static interface Entry { 416 417 /** 418 * Retrieves the attributes associated with an entry. 419 * <p> 420 * The default implementation returns an empty {@code Set}. 421 * 422 * @return an unmodifiable {@code Set} of attributes, possibly empty 423 * 424 * @since 1.8 425 */ getAttributes()426 public default Set<Attribute> getAttributes() { 427 return Collections.<Attribute>emptySet(); 428 } 429 430 /** 431 * An attribute associated with a keystore entry. 432 * It comprises a name and one or more values. 433 * 434 * @since 1.8 435 */ 436 public interface Attribute { 437 /** 438 * Returns the attribute's name. 439 * 440 * @return the attribute name 441 */ getName()442 public String getName(); 443 444 /** 445 * Returns the attribute's value. 446 * Multi-valued attributes encode their values as a single string. 447 * 448 * @return the attribute value 449 */ getValue()450 public String getValue(); 451 } 452 } 453 454 /** 455 * A {@code KeyStore} entry that holds a {@code PrivateKey} 456 * and corresponding certificate chain. 457 * 458 * @since 1.5 459 */ 460 public static final class PrivateKeyEntry implements Entry { 461 462 private final PrivateKey privKey; 463 private final Certificate[] chain; 464 private final Set<Attribute> attributes; 465 466 /** 467 * Constructs a {@code PrivateKeyEntry} with a 468 * {@code PrivateKey} and corresponding certificate chain. 469 * 470 * <p> The specified {@code chain} is cloned before it is stored 471 * in the new {@code PrivateKeyEntry} object. 472 * 473 * @param privateKey the {@code PrivateKey} 474 * @param chain an array of {@code Certificate}s 475 * representing the certificate chain. 476 * The chain must be ordered and contain a 477 * {@code Certificate} at index 0 478 * corresponding to the private key. 479 * 480 * @exception NullPointerException if 481 * {@code privateKey} or {@code chain} 482 * is {@code null} 483 * @exception IllegalArgumentException if the specified chain has a 484 * length of 0, if the specified chain does not contain 485 * {@code Certificate}s of the same type, 486 * or if the {@code PrivateKey} algorithm 487 * does not match the algorithm of the {@code PublicKey} 488 * in the end entity {@code Certificate} (at index 0) 489 */ PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)490 public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) { 491 this(privateKey, chain, Collections.<Attribute>emptySet()); 492 } 493 494 /** 495 * Constructs a {@code PrivateKeyEntry} with a {@code PrivateKey} and 496 * corresponding certificate chain and associated entry attributes. 497 * 498 * <p> The specified {@code chain} and {@code attributes} are cloned 499 * before they are stored in the new {@code PrivateKeyEntry} object. 500 * 501 * @param privateKey the {@code PrivateKey} 502 * @param chain an array of {@code Certificate}s 503 * representing the certificate chain. 504 * The chain must be ordered and contain a 505 * {@code Certificate} at index 0 506 * corresponding to the private key. 507 * @param attributes the attributes 508 * 509 * @exception NullPointerException if {@code privateKey}, {@code chain} 510 * or {@code attributes} is {@code null} 511 * @exception IllegalArgumentException if the specified chain has a 512 * length of 0, if the specified chain does not contain 513 * {@code Certificate}s of the same type, 514 * or if the {@code PrivateKey} algorithm 515 * does not match the algorithm of the {@code PublicKey} 516 * in the end entity {@code Certificate} (at index 0) 517 * 518 * @since 1.8 519 */ PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain, Set<Attribute> attributes)520 public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain, 521 Set<Attribute> attributes) { 522 523 if (privateKey == null || chain == null || attributes == null) { 524 throw new NullPointerException("invalid null input"); 525 } 526 if (chain.length == 0) { 527 throw new IllegalArgumentException 528 ("invalid zero-length input chain"); 529 } 530 531 Certificate[] clonedChain = chain.clone(); 532 String certType = clonedChain[0].getType(); 533 for (int i = 1; i < clonedChain.length; i++) { 534 if (!certType.equals(clonedChain[i].getType())) { 535 throw new IllegalArgumentException 536 ("chain does not contain certificates " + 537 "of the same type"); 538 } 539 } 540 if (!privateKey.getAlgorithm().equals 541 (clonedChain[0].getPublicKey().getAlgorithm())) { 542 throw new IllegalArgumentException 543 ("private key algorithm does not match " + 544 "algorithm of public key in end entity " + 545 "certificate (at index 0)"); 546 } 547 this.privKey = privateKey; 548 549 if (clonedChain[0] instanceof X509Certificate && 550 !(clonedChain instanceof X509Certificate[])) { 551 552 this.chain = new X509Certificate[clonedChain.length]; 553 System.arraycopy(clonedChain, 0, 554 this.chain, 0, clonedChain.length); 555 } else { 556 this.chain = clonedChain; 557 } 558 559 this.attributes = 560 Collections.unmodifiableSet(new HashSet<>(attributes)); 561 } 562 563 /** 564 * Gets the {@code PrivateKey} from this entry. 565 * 566 * @return the {@code PrivateKey} from this entry 567 */ getPrivateKey()568 public PrivateKey getPrivateKey() { 569 return privKey; 570 } 571 572 /** 573 * Gets the {@code Certificate} chain from this entry. 574 * 575 * <p> The stored chain is cloned before being returned. 576 * 577 * @return an array of {@code Certificate}s corresponding 578 * to the certificate chain for the public key. 579 * If the certificates are of type X.509, 580 * the runtime type of the returned array is 581 * {@code X509Certificate[]}. 582 */ getCertificateChain()583 public Certificate[] getCertificateChain() { 584 return chain.clone(); 585 } 586 587 /** 588 * Gets the end entity {@code Certificate} 589 * from the certificate chain in this entry. 590 * 591 * @return the end entity {@code Certificate} (at index 0) 592 * from the certificate chain in this entry. 593 * If the certificate is of type X.509, 594 * the runtime type of the returned certificate is 595 * {@code X509Certificate}. 596 */ getCertificate()597 public Certificate getCertificate() { 598 return chain[0]; 599 } 600 601 /** 602 * Retrieves the attributes associated with an entry. 603 * <p> 604 * 605 * @return an unmodifiable {@code Set} of attributes, possibly empty 606 * 607 * @since 1.8 608 */ 609 @Override getAttributes()610 public Set<Attribute> getAttributes() { 611 return attributes; 612 } 613 614 /** 615 * Returns a string representation of this PrivateKeyEntry. 616 * @return a string representation of this PrivateKeyEntry. 617 */ toString()618 public String toString() { 619 StringBuilder sb = new StringBuilder(); 620 sb.append("Private key entry and certificate chain with " 621 + chain.length + " elements:\r\n"); 622 for (Certificate cert : chain) { 623 sb.append(cert); 624 sb.append("\r\n"); 625 } 626 return sb.toString(); 627 } 628 629 } 630 631 /** 632 * A {@code KeyStore} entry that holds a {@code SecretKey}. 633 * 634 * @since 1.5 635 */ 636 public static final class SecretKeyEntry implements Entry { 637 638 private final SecretKey sKey; 639 private final Set<Attribute> attributes; 640 641 /** 642 * Constructs a {@code SecretKeyEntry} with a 643 * {@code SecretKey}. 644 * 645 * @param secretKey the {@code SecretKey} 646 * 647 * @exception NullPointerException if {@code secretKey} 648 * is {@code null} 649 */ SecretKeyEntry(SecretKey secretKey)650 public SecretKeyEntry(SecretKey secretKey) { 651 if (secretKey == null) { 652 throw new NullPointerException("invalid null input"); 653 } 654 this.sKey = secretKey; 655 this.attributes = Collections.<Attribute>emptySet(); 656 } 657 658 /** 659 * Constructs a {@code SecretKeyEntry} with a {@code SecretKey} and 660 * associated entry attributes. 661 * 662 * <p> The specified {@code attributes} is cloned before it is stored 663 * in the new {@code SecretKeyEntry} object. 664 * 665 * @param secretKey the {@code SecretKey} 666 * @param attributes the attributes 667 * 668 * @exception NullPointerException if {@code secretKey} or 669 * {@code attributes} is {@code null} 670 * 671 * @since 1.8 672 */ SecretKeyEntry(SecretKey secretKey, Set<Attribute> attributes)673 public SecretKeyEntry(SecretKey secretKey, Set<Attribute> attributes) { 674 675 if (secretKey == null || attributes == null) { 676 throw new NullPointerException("invalid null input"); 677 } 678 this.sKey = secretKey; 679 this.attributes = 680 Collections.unmodifiableSet(new HashSet<>(attributes)); 681 } 682 683 /** 684 * Gets the {@code SecretKey} from this entry. 685 * 686 * @return the {@code SecretKey} from this entry 687 */ getSecretKey()688 public SecretKey getSecretKey() { 689 return sKey; 690 } 691 692 /** 693 * Retrieves the attributes associated with an entry. 694 * <p> 695 * 696 * @return an unmodifiable {@code Set} of attributes, possibly empty 697 * 698 * @since 1.8 699 */ 700 @Override getAttributes()701 public Set<Attribute> getAttributes() { 702 return attributes; 703 } 704 705 /** 706 * Returns a string representation of this SecretKeyEntry. 707 * @return a string representation of this SecretKeyEntry. 708 */ toString()709 public String toString() { 710 return "Secret key entry with algorithm " + sKey.getAlgorithm(); 711 } 712 } 713 714 /** 715 * A {@code KeyStore} entry that holds a trusted 716 * {@code Certificate}. 717 * 718 * @since 1.5 719 */ 720 public static final class TrustedCertificateEntry implements Entry { 721 722 private final Certificate cert; 723 private final Set<Attribute> attributes; 724 725 /** 726 * Constructs a {@code TrustedCertificateEntry} with a 727 * trusted {@code Certificate}. 728 * 729 * @param trustedCert the trusted {@code Certificate} 730 * 731 * @exception NullPointerException if 732 * {@code trustedCert} is {@code null} 733 */ TrustedCertificateEntry(Certificate trustedCert)734 public TrustedCertificateEntry(Certificate trustedCert) { 735 if (trustedCert == null) { 736 throw new NullPointerException("invalid null input"); 737 } 738 this.cert = trustedCert; 739 this.attributes = Collections.<Attribute>emptySet(); 740 } 741 742 /** 743 * Constructs a {@code TrustedCertificateEntry} with a 744 * trusted {@code Certificate} and associated entry attributes. 745 * 746 * <p> The specified {@code attributes} is cloned before it is stored 747 * in the new {@code TrustedCertificateEntry} object. 748 * 749 * @param trustedCert the trusted {@code Certificate} 750 * @param attributes the attributes 751 * 752 * @exception NullPointerException if {@code trustedCert} or 753 * {@code attributes} is {@code null} 754 * 755 * @since 1.8 756 */ TrustedCertificateEntry(Certificate trustedCert, Set<Attribute> attributes)757 public TrustedCertificateEntry(Certificate trustedCert, 758 Set<Attribute> attributes) { 759 if (trustedCert == null || attributes == null) { 760 throw new NullPointerException("invalid null input"); 761 } 762 this.cert = trustedCert; 763 this.attributes = 764 Collections.unmodifiableSet(new HashSet<>(attributes)); 765 } 766 767 /** 768 * Gets the trusted {@code Certficate} from this entry. 769 * 770 * @return the trusted {@code Certificate} from this entry 771 */ getTrustedCertificate()772 public Certificate getTrustedCertificate() { 773 return cert; 774 } 775 776 /** 777 * Retrieves the attributes associated with an entry. 778 * <p> 779 * 780 * @return an unmodifiable {@code Set} of attributes, possibly empty 781 * 782 * @since 1.8 783 */ 784 @Override getAttributes()785 public Set<Attribute> getAttributes() { 786 return attributes; 787 } 788 789 /** 790 * Returns a string representation of this TrustedCertificateEntry. 791 * @return a string representation of this TrustedCertificateEntry. 792 */ toString()793 public String toString() { 794 return "Trusted certificate entry:\r\n" + cert.toString(); 795 } 796 } 797 798 /** 799 * Creates a KeyStore object of the given type, and encapsulates the given 800 * provider implementation (SPI object) in it. 801 * 802 * @param keyStoreSpi the provider implementation. 803 * @param provider the provider. 804 * @param type the keystore type. 805 */ KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)806 protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type) 807 { 808 this.keyStoreSpi = keyStoreSpi; 809 this.provider = provider; 810 this.type = type; 811 812 if (!skipDebug && pdebug != null) { 813 pdebug.println("KeyStore." + type.toUpperCase() + " type from: " + 814 this.provider.getName()); 815 } 816 } 817 818 /** 819 * Returns a keystore object of the specified type. 820 * 821 * <p> This method traverses the list of registered security Providers, 822 * starting with the most preferred Provider. 823 * A new KeyStore object encapsulating the 824 * KeyStoreSpi implementation from the first 825 * Provider that supports the specified type is returned. 826 * 827 * <p> Note that the list of registered providers may be retrieved via 828 * the {@link Security#getProviders() Security.getProviders()} method. 829 * 830 * @param type the type of keystore. 831 * See the KeyStore section in the <a href= 832 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore"> 833 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 834 * for information about standard keystore types. 835 * 836 * @return a keystore object of the specified type. 837 * 838 * @exception KeyStoreException if no Provider supports a 839 * KeyStoreSpi implementation for the 840 * specified type. 841 * 842 * @see Provider 843 */ getInstance(String type)844 public static KeyStore getInstance(String type) 845 throws KeyStoreException 846 { 847 try { 848 Object[] objs = Security.getImpl(type, "KeyStore", (String)null); 849 return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); 850 } catch (NoSuchAlgorithmException nsae) { 851 throw new KeyStoreException(type + " not found", nsae); 852 } catch (NoSuchProviderException nspe) { 853 throw new KeyStoreException(type + " not found", nspe); 854 } 855 } 856 857 /** 858 * Returns a keystore object of the specified type. 859 * 860 * <p> A new KeyStore object encapsulating the 861 * KeyStoreSpi implementation from the specified provider 862 * is returned. The specified provider must be registered 863 * in the security provider list. 864 * 865 * <p> Note that the list of registered providers may be retrieved via 866 * the {@link Security#getProviders() Security.getProviders()} method. 867 * 868 * @param type the type of keystore. 869 * See the KeyStore section in the <a href= 870 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore"> 871 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 872 * for information about standard keystore types. 873 * 874 * @param provider the name of the provider. 875 * 876 * @return a keystore object of the specified type. 877 * 878 * @exception KeyStoreException if a KeyStoreSpi 879 * implementation for the specified type is not 880 * available from the specified provider. 881 * 882 * @exception NoSuchProviderException if the specified provider is not 883 * registered in the security provider list. 884 * 885 * @exception IllegalArgumentException if the provider name is null 886 * or empty. 887 * 888 * @see Provider 889 */ getInstance(String type, String provider)890 public static KeyStore getInstance(String type, String provider) 891 throws KeyStoreException, NoSuchProviderException 892 { 893 if (provider == null || provider.length() == 0) 894 throw new IllegalArgumentException("missing provider"); 895 try { 896 Object[] objs = Security.getImpl(type, "KeyStore", provider); 897 return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); 898 } catch (NoSuchAlgorithmException nsae) { 899 throw new KeyStoreException(type + " not found", nsae); 900 } 901 } 902 903 /** 904 * Returns a keystore object of the specified type. 905 * 906 * <p> A new KeyStore object encapsulating the 907 * KeyStoreSpi implementation from the specified Provider 908 * object is returned. Note that the specified Provider object 909 * does not have to be registered in the provider list. 910 * 911 * @param type the type of keystore. 912 * See the KeyStore section in the <a href= 913 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore"> 914 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 915 * for information about standard keystore types. 916 * 917 * @param provider the provider. 918 * 919 * @return a keystore object of the specified type. 920 * 921 * @exception KeyStoreException if KeyStoreSpi 922 * implementation for the specified type is not available 923 * from the specified Provider object. 924 * 925 * @exception IllegalArgumentException if the specified provider is null. 926 * 927 * @see Provider 928 * 929 * @since 1.4 930 */ getInstance(String type, Provider provider)931 public static KeyStore getInstance(String type, Provider provider) 932 throws KeyStoreException 933 { 934 if (provider == null) 935 throw new IllegalArgumentException("missing provider"); 936 try { 937 Object[] objs = Security.getImpl(type, "KeyStore", provider); 938 return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); 939 } catch (NoSuchAlgorithmException nsae) { 940 throw new KeyStoreException(type + " not found", nsae); 941 } 942 } 943 944 /** 945 * Returns the default keystore type as specified by the 946 * {@code keystore.type} security property, or the string 947 * {@literal "jks"} (acronym for {@literal "Java keystore"}) 948 * if no such property exists. 949 * 950 * <p>The default keystore type can be used by applications that do not 951 * want to use a hard-coded keystore type when calling one of the 952 * {@code getInstance} methods, and want to provide a default keystore 953 * type in case a user does not specify its own. 954 * 955 * <p>The default keystore type can be changed by setting the value of the 956 * {@code keystore.type} security property to the desired keystore type. 957 * 958 * @return the default keystore type as specified by the 959 * {@code keystore.type} security property, or the string {@literal "jks"} 960 * if no such property exists. 961 * @see java.security.Security security properties 962 */ getDefaultType()963 public final static String getDefaultType() { 964 String kstype; 965 kstype = AccessController.doPrivileged(new PrivilegedAction<String>() { 966 public String run() { 967 return Security.getProperty(KEYSTORE_TYPE); 968 } 969 }); 970 if (kstype == null) { 971 kstype = "jks"; 972 } 973 return kstype; 974 } 975 976 /** 977 * Returns the provider of this keystore. 978 * 979 * @return the provider of this keystore. 980 */ getProvider()981 public final Provider getProvider() 982 { 983 return this.provider; 984 } 985 986 /** 987 * Returns the type of this keystore. 988 * 989 * @return the type of this keystore. 990 */ getType()991 public final String getType() 992 { 993 return this.type; 994 } 995 996 /** 997 * Returns the key associated with the given alias, using the given 998 * password to recover it. The key must have been associated with 999 * the alias by a call to {@code setKeyEntry}, 1000 * or by a call to {@code setEntry} with a 1001 * {@code PrivateKeyEntry} or {@code SecretKeyEntry}. 1002 * 1003 * @param alias the alias name 1004 * @param password the password for recovering the key 1005 * 1006 * @return the requested key, or null if the given alias does not exist 1007 * or does not identify a key-related entry. 1008 * 1009 * @exception KeyStoreException if the keystore has not been initialized 1010 * (loaded). 1011 * @exception NoSuchAlgorithmException if the algorithm for recovering the 1012 * key cannot be found 1013 * @exception UnrecoverableKeyException if the key cannot be recovered 1014 * (e.g., the given password is wrong). 1015 */ getKey(String alias, char[] password)1016 public final Key getKey(String alias, char[] password) 1017 throws KeyStoreException, NoSuchAlgorithmException, 1018 UnrecoverableKeyException 1019 { 1020 if (!initialized) { 1021 throw new KeyStoreException("Uninitialized keystore"); 1022 } 1023 return keyStoreSpi.engineGetKey(alias, password); 1024 } 1025 1026 /** 1027 * Returns the certificate chain associated with the given alias. 1028 * The certificate chain must have been associated with the alias 1029 * by a call to {@code setKeyEntry}, 1030 * or by a call to {@code setEntry} with a 1031 * {@code PrivateKeyEntry}. 1032 * 1033 * @param alias the alias name 1034 * 1035 * @return the certificate chain (ordered with the user's certificate first 1036 * followed by zero or more certificate authorities), or null if the given alias 1037 * does not exist or does not contain a certificate chain 1038 * 1039 * @exception KeyStoreException if the keystore has not been initialized 1040 * (loaded). 1041 */ getCertificateChain(String alias)1042 public final Certificate[] getCertificateChain(String alias) 1043 throws KeyStoreException 1044 { 1045 if (!initialized) { 1046 throw new KeyStoreException("Uninitialized keystore"); 1047 } 1048 return keyStoreSpi.engineGetCertificateChain(alias); 1049 } 1050 1051 /** 1052 * Returns the certificate associated with the given alias. 1053 * 1054 * <p> If the given alias name identifies an entry 1055 * created by a call to {@code setCertificateEntry}, 1056 * or created by a call to {@code setEntry} with a 1057 * {@code TrustedCertificateEntry}, 1058 * then the trusted certificate contained in that entry is returned. 1059 * 1060 * <p> If the given alias name identifies an entry 1061 * created by a call to {@code setKeyEntry}, 1062 * or created by a call to {@code setEntry} with a 1063 * {@code PrivateKeyEntry}, 1064 * then the first element of the certificate chain in that entry 1065 * is returned. 1066 * 1067 * @param alias the alias name 1068 * 1069 * @return the certificate, or null if the given alias does not exist or 1070 * does not contain a certificate. 1071 * 1072 * @exception KeyStoreException if the keystore has not been initialized 1073 * (loaded). 1074 */ getCertificate(String alias)1075 public final Certificate getCertificate(String alias) 1076 throws KeyStoreException 1077 { 1078 if (!initialized) { 1079 throw new KeyStoreException("Uninitialized keystore"); 1080 } 1081 return keyStoreSpi.engineGetCertificate(alias); 1082 } 1083 1084 /** 1085 * Returns the creation date of the entry identified by the given alias. 1086 * 1087 * @param alias the alias name 1088 * 1089 * @return the creation date of this entry, or null if the given alias does 1090 * not exist 1091 * 1092 * @exception KeyStoreException if the keystore has not been initialized 1093 * (loaded). 1094 */ getCreationDate(String alias)1095 public final Date getCreationDate(String alias) 1096 throws KeyStoreException 1097 { 1098 if (!initialized) { 1099 throw new KeyStoreException("Uninitialized keystore"); 1100 } 1101 return keyStoreSpi.engineGetCreationDate(alias); 1102 } 1103 1104 /** 1105 * Assigns the given key to the given alias, protecting it with the given 1106 * password. 1107 * 1108 * <p>If the given key is of type {@code java.security.PrivateKey}, 1109 * it must be accompanied by a certificate chain certifying the 1110 * corresponding public key. 1111 * 1112 * <p>If the given alias already exists, the keystore information 1113 * associated with it is overridden by the given key (and possibly 1114 * certificate chain). 1115 * 1116 * @param alias the alias name 1117 * @param key the key to be associated with the alias 1118 * @param password the password to protect the key 1119 * @param chain the certificate chain for the corresponding public 1120 * key (only required if the given key is of type 1121 * {@code java.security.PrivateKey}). 1122 * 1123 * @exception KeyStoreException if the keystore has not been initialized 1124 * (loaded), the given key cannot be protected, or this operation fails 1125 * for some other reason 1126 */ setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)1127 public final void setKeyEntry(String alias, Key key, char[] password, 1128 Certificate[] chain) 1129 throws KeyStoreException 1130 { 1131 if (!initialized) { 1132 throw new KeyStoreException("Uninitialized keystore"); 1133 } 1134 if ((key instanceof PrivateKey) && 1135 (chain == null || chain.length == 0)) { 1136 throw new IllegalArgumentException("Private key must be " 1137 + "accompanied by certificate " 1138 + "chain"); 1139 } 1140 keyStoreSpi.engineSetKeyEntry(alias, key, password, chain); 1141 } 1142 1143 /** 1144 * Assigns the given key (that has already been protected) to the given 1145 * alias. 1146 * 1147 * <p>If the protected key is of type 1148 * {@code java.security.PrivateKey}, it must be accompanied by a 1149 * certificate chain certifying the corresponding public key. If the 1150 * underlying keystore implementation is of type {@code jks}, 1151 * {@code key} must be encoded as an 1152 * {@code EncryptedPrivateKeyInfo} as defined in the PKCS #8 standard. 1153 * 1154 * <p>If the given alias already exists, the keystore information 1155 * associated with it is overridden by the given key (and possibly 1156 * certificate chain). 1157 * 1158 * @param alias the alias name 1159 * @param key the key (in protected format) to be associated with the alias 1160 * @param chain the certificate chain for the corresponding public 1161 * key (only useful if the protected key is of type 1162 * {@code java.security.PrivateKey}). 1163 * 1164 * @exception KeyStoreException if the keystore has not been initialized 1165 * (loaded), or if this operation fails for some other reason. 1166 */ setKeyEntry(String alias, byte[] key, Certificate[] chain)1167 public final void setKeyEntry(String alias, byte[] key, 1168 Certificate[] chain) 1169 throws KeyStoreException 1170 { 1171 if (!initialized) { 1172 throw new KeyStoreException("Uninitialized keystore"); 1173 } 1174 keyStoreSpi.engineSetKeyEntry(alias, key, chain); 1175 } 1176 1177 /** 1178 * Assigns the given trusted certificate to the given alias. 1179 * 1180 * <p> If the given alias identifies an existing entry 1181 * created by a call to {@code setCertificateEntry}, 1182 * or created by a call to {@code setEntry} with a 1183 * {@code TrustedCertificateEntry}, 1184 * the trusted certificate in the existing entry 1185 * is overridden by the given certificate. 1186 * 1187 * @param alias the alias name 1188 * @param cert the certificate 1189 * 1190 * @exception KeyStoreException if the keystore has not been initialized, 1191 * or the given alias already exists and does not identify an 1192 * entry containing a trusted certificate, 1193 * or this operation fails for some other reason. 1194 */ setCertificateEntry(String alias, Certificate cert)1195 public final void setCertificateEntry(String alias, Certificate cert) 1196 throws KeyStoreException 1197 { 1198 if (!initialized) { 1199 throw new KeyStoreException("Uninitialized keystore"); 1200 } 1201 keyStoreSpi.engineSetCertificateEntry(alias, cert); 1202 } 1203 1204 /** 1205 * Deletes the entry identified by the given alias from this keystore. 1206 * 1207 * @param alias the alias name 1208 * 1209 * @exception KeyStoreException if the keystore has not been initialized, 1210 * or if the entry cannot be removed. 1211 */ deleteEntry(String alias)1212 public final void deleteEntry(String alias) 1213 throws KeyStoreException 1214 { 1215 if (!initialized) { 1216 throw new KeyStoreException("Uninitialized keystore"); 1217 } 1218 keyStoreSpi.engineDeleteEntry(alias); 1219 } 1220 1221 /** 1222 * Lists all the alias names of this keystore. 1223 * 1224 * @return enumeration of the alias names 1225 * 1226 * @exception KeyStoreException if the keystore has not been initialized 1227 * (loaded). 1228 */ aliases()1229 public final Enumeration<String> aliases() 1230 throws KeyStoreException 1231 { 1232 if (!initialized) { 1233 throw new KeyStoreException("Uninitialized keystore"); 1234 } 1235 return keyStoreSpi.engineAliases(); 1236 } 1237 1238 /** 1239 * Checks if the given alias exists in this keystore. 1240 * 1241 * @param alias the alias name 1242 * 1243 * @return true if the alias exists, false otherwise 1244 * 1245 * @exception KeyStoreException if the keystore has not been initialized 1246 * (loaded). 1247 */ containsAlias(String alias)1248 public final boolean containsAlias(String alias) 1249 throws KeyStoreException 1250 { 1251 if (!initialized) { 1252 throw new KeyStoreException("Uninitialized keystore"); 1253 } 1254 return keyStoreSpi.engineContainsAlias(alias); 1255 } 1256 1257 /** 1258 * Retrieves the number of entries in this keystore. 1259 * 1260 * @return the number of entries in this keystore 1261 * 1262 * @exception KeyStoreException if the keystore has not been initialized 1263 * (loaded). 1264 */ size()1265 public final int size() 1266 throws KeyStoreException 1267 { 1268 if (!initialized) { 1269 throw new KeyStoreException("Uninitialized keystore"); 1270 } 1271 return keyStoreSpi.engineSize(); 1272 } 1273 1274 /** 1275 * Returns true if the entry identified by the given alias 1276 * was created by a call to {@code setKeyEntry}, 1277 * or created by a call to {@code setEntry} with a 1278 * {@code PrivateKeyEntry} or a {@code SecretKeyEntry}. 1279 * 1280 * @param alias the alias for the keystore entry to be checked 1281 * 1282 * @return true if the entry identified by the given alias is a 1283 * key-related entry, false otherwise. 1284 * 1285 * @exception KeyStoreException if the keystore has not been initialized 1286 * (loaded). 1287 */ isKeyEntry(String alias)1288 public final boolean isKeyEntry(String alias) 1289 throws KeyStoreException 1290 { 1291 if (!initialized) { 1292 throw new KeyStoreException("Uninitialized keystore"); 1293 } 1294 return keyStoreSpi.engineIsKeyEntry(alias); 1295 } 1296 1297 /** 1298 * Returns true if the entry identified by the given alias 1299 * was created by a call to {@code setCertificateEntry}, 1300 * or created by a call to {@code setEntry} with a 1301 * {@code TrustedCertificateEntry}. 1302 * 1303 * @param alias the alias for the keystore entry to be checked 1304 * 1305 * @return true if the entry identified by the given alias contains a 1306 * trusted certificate, false otherwise. 1307 * 1308 * @exception KeyStoreException if the keystore has not been initialized 1309 * (loaded). 1310 */ isCertificateEntry(String alias)1311 public final boolean isCertificateEntry(String alias) 1312 throws KeyStoreException 1313 { 1314 if (!initialized) { 1315 throw new KeyStoreException("Uninitialized keystore"); 1316 } 1317 return keyStoreSpi.engineIsCertificateEntry(alias); 1318 } 1319 1320 /** 1321 * Returns the (alias) name of the first keystore entry whose certificate 1322 * matches the given certificate. 1323 * 1324 * <p> This method attempts to match the given certificate with each 1325 * keystore entry. If the entry being considered was 1326 * created by a call to {@code setCertificateEntry}, 1327 * or created by a call to {@code setEntry} with a 1328 * {@code TrustedCertificateEntry}, 1329 * then the given certificate is compared to that entry's certificate. 1330 * 1331 * <p> If the entry being considered was 1332 * created by a call to {@code setKeyEntry}, 1333 * or created by a call to {@code setEntry} with a 1334 * {@code PrivateKeyEntry}, 1335 * then the given certificate is compared to the first 1336 * element of that entry's certificate chain. 1337 * 1338 * @param cert the certificate to match with. 1339 * 1340 * @return the alias name of the first entry with a matching certificate, 1341 * or null if no such entry exists in this keystore. 1342 * 1343 * @exception KeyStoreException if the keystore has not been initialized 1344 * (loaded). 1345 */ getCertificateAlias(Certificate cert)1346 public final String getCertificateAlias(Certificate cert) 1347 throws KeyStoreException 1348 { 1349 if (!initialized) { 1350 throw new KeyStoreException("Uninitialized keystore"); 1351 } 1352 return keyStoreSpi.engineGetCertificateAlias(cert); 1353 } 1354 1355 /** 1356 * Stores this keystore to the given output stream, and protects its 1357 * integrity with the given password. 1358 * 1359 * @param stream the output stream to which this keystore is written. 1360 * @param password the password to generate the keystore integrity check 1361 * 1362 * @exception KeyStoreException if the keystore has not been initialized 1363 * (loaded). 1364 * @exception IOException if there was an I/O problem with data 1365 * @exception NoSuchAlgorithmException if the appropriate data integrity 1366 * algorithm could not be found 1367 * @exception CertificateException if any of the certificates included in 1368 * the keystore data could not be stored 1369 */ store(OutputStream stream, char[] password)1370 public final void store(OutputStream stream, char[] password) 1371 throws KeyStoreException, IOException, NoSuchAlgorithmException, 1372 CertificateException 1373 { 1374 if (!initialized) { 1375 throw new KeyStoreException("Uninitialized keystore"); 1376 } 1377 keyStoreSpi.engineStore(stream, password); 1378 } 1379 1380 /** 1381 * Stores this keystore using the given {@code LoadStoreParameter}. 1382 * 1383 * @param param the {@code LoadStoreParameter} 1384 * that specifies how to store the keystore, 1385 * which may be {@code null} 1386 * 1387 * @exception IllegalArgumentException if the given 1388 * {@code LoadStoreParameter} 1389 * input is not recognized 1390 * @exception KeyStoreException if the keystore has not been initialized 1391 * (loaded) 1392 * @exception IOException if there was an I/O problem with data 1393 * @exception NoSuchAlgorithmException if the appropriate data integrity 1394 * algorithm could not be found 1395 * @exception CertificateException if any of the certificates included in 1396 * the keystore data could not be stored 1397 * 1398 * @since 1.5 1399 */ store(LoadStoreParameter param)1400 public final void store(LoadStoreParameter param) 1401 throws KeyStoreException, IOException, 1402 NoSuchAlgorithmException, CertificateException { 1403 if (!initialized) { 1404 throw new KeyStoreException("Uninitialized keystore"); 1405 } 1406 keyStoreSpi.engineStore(param); 1407 } 1408 1409 /** 1410 * Loads this KeyStore from the given input stream. 1411 * 1412 * <p>A password may be given to unlock the keystore 1413 * (e.g. the keystore resides on a hardware token device), 1414 * or to check the integrity of the keystore data. 1415 * If a password is not given for integrity checking, 1416 * then integrity checking is not performed. 1417 * 1418 * <p>In order to create an empty keystore, or if the keystore cannot 1419 * be initialized from a stream, pass {@code null} 1420 * as the {@code stream} argument. 1421 * 1422 * <p> Note that if this keystore has already been loaded, it is 1423 * reinitialized and loaded again from the given input stream. 1424 * 1425 * @param stream the input stream from which the keystore is loaded, 1426 * or {@code null} 1427 * @param password the password used to check the integrity of 1428 * the keystore, the password used to unlock the keystore, 1429 * or {@code null} 1430 * 1431 * @exception IOException if there is an I/O or format problem with the 1432 * keystore data, if a password is required but not given, 1433 * or if the given password was incorrect. If the error is due to a 1434 * wrong password, the {@link Throwable#getCause cause} of the 1435 * {@code IOException} should be an 1436 * {@code UnrecoverableKeyException} 1437 * @exception NoSuchAlgorithmException if the algorithm used to check 1438 * the integrity of the keystore cannot be found 1439 * @exception CertificateException if any of the certificates in the 1440 * keystore could not be loaded 1441 */ load(InputStream stream, char[] password)1442 public final void load(InputStream stream, char[] password) 1443 throws IOException, NoSuchAlgorithmException, CertificateException 1444 { 1445 keyStoreSpi.engineLoad(stream, password); 1446 initialized = true; 1447 } 1448 1449 /** 1450 * Loads this keystore using the given {@code LoadStoreParameter}. 1451 * 1452 * <p> Note that if this KeyStore has already been loaded, it is 1453 * reinitialized and loaded again from the given parameter. 1454 * 1455 * @param param the {@code LoadStoreParameter} 1456 * that specifies how to load the keystore, 1457 * which may be {@code null} 1458 * 1459 * @exception IllegalArgumentException if the given 1460 * {@code LoadStoreParameter} 1461 * input is not recognized 1462 * @exception IOException if there is an I/O or format problem with the 1463 * keystore data. If the error is due to an incorrect 1464 * {@code ProtectionParameter} (e.g. wrong password) 1465 * the {@link Throwable#getCause cause} of the 1466 * {@code IOException} should be an 1467 * {@code UnrecoverableKeyException} 1468 * @exception NoSuchAlgorithmException if the algorithm used to check 1469 * the integrity of the keystore cannot be found 1470 * @exception CertificateException if any of the certificates in the 1471 * keystore could not be loaded 1472 * 1473 * @since 1.5 1474 */ load(LoadStoreParameter param)1475 public final void load(LoadStoreParameter param) 1476 throws IOException, NoSuchAlgorithmException, 1477 CertificateException { 1478 1479 keyStoreSpi.engineLoad(param); 1480 initialized = true; 1481 } 1482 1483 /** 1484 * Gets a keystore {@code Entry} for the specified alias 1485 * with the specified protection parameter. 1486 * 1487 * @param alias get the keystore {@code Entry} for this alias 1488 * @param protParam the {@code ProtectionParameter} 1489 * used to protect the {@code Entry}, 1490 * which may be {@code null} 1491 * 1492 * @return the keystore {@code Entry} for the specified alias, 1493 * or {@code null} if there is no such entry 1494 * 1495 * @exception NullPointerException if 1496 * {@code alias} is {@code null} 1497 * @exception NoSuchAlgorithmException if the algorithm for recovering the 1498 * entry cannot be found 1499 * @exception UnrecoverableEntryException if the specified 1500 * {@code protParam} were insufficient or invalid 1501 * @exception UnrecoverableKeyException if the entry is a 1502 * {@code PrivateKeyEntry} or {@code SecretKeyEntry} 1503 * and the specified {@code protParam} does not contain 1504 * the information needed to recover the key (e.g. wrong password) 1505 * @exception KeyStoreException if the keystore has not been initialized 1506 * (loaded). 1507 * @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter) 1508 * 1509 * @since 1.5 1510 */ getEntry(String alias, ProtectionParameter protParam)1511 public final Entry getEntry(String alias, ProtectionParameter protParam) 1512 throws NoSuchAlgorithmException, UnrecoverableEntryException, 1513 KeyStoreException { 1514 1515 if (alias == null) { 1516 throw new NullPointerException("invalid null input"); 1517 } 1518 if (!initialized) { 1519 throw new KeyStoreException("Uninitialized keystore"); 1520 } 1521 return keyStoreSpi.engineGetEntry(alias, protParam); 1522 } 1523 1524 /** 1525 * Saves a keystore {@code Entry} under the specified alias. 1526 * The protection parameter is used to protect the 1527 * {@code Entry}. 1528 * 1529 * <p> If an entry already exists for the specified alias, 1530 * it is overridden. 1531 * 1532 * @param alias save the keystore {@code Entry} under this alias 1533 * @param entry the {@code Entry} to save 1534 * @param protParam the {@code ProtectionParameter} 1535 * used to protect the {@code Entry}, 1536 * which may be {@code null} 1537 * 1538 * @exception NullPointerException if 1539 * {@code alias} or {@code entry} 1540 * is {@code null} 1541 * @exception KeyStoreException if the keystore has not been initialized 1542 * (loaded), or if this operation fails for some other reason 1543 * 1544 * @see #getEntry(String, KeyStore.ProtectionParameter) 1545 * 1546 * @since 1.5 1547 */ setEntry(String alias, Entry entry, ProtectionParameter protParam)1548 public final void setEntry(String alias, Entry entry, 1549 ProtectionParameter protParam) 1550 throws KeyStoreException { 1551 if (alias == null || entry == null) { 1552 throw new NullPointerException("invalid null input"); 1553 } 1554 if (!initialized) { 1555 throw new KeyStoreException("Uninitialized keystore"); 1556 } 1557 keyStoreSpi.engineSetEntry(alias, entry, protParam); 1558 } 1559 1560 /** 1561 * Determines if the keystore {@code Entry} for the specified 1562 * {@code alias} is an instance or subclass of the specified 1563 * {@code entryClass}. 1564 * 1565 * @param alias the alias name 1566 * @param entryClass the entry class 1567 * 1568 * @return true if the keystore {@code Entry} for the specified 1569 * {@code alias} is an instance or subclass of the 1570 * specified {@code entryClass}, false otherwise 1571 * 1572 * @exception NullPointerException if 1573 * {@code alias} or {@code entryClass} 1574 * is {@code null} 1575 * @exception KeyStoreException if the keystore has not been 1576 * initialized (loaded) 1577 * 1578 * @since 1.5 1579 */ 1580 public final boolean entryInstanceOf(String alias, Class<? extends KeyStore.Entry> entryClass)1581 entryInstanceOf(String alias, 1582 Class<? extends KeyStore.Entry> entryClass) 1583 throws KeyStoreException 1584 { 1585 1586 if (alias == null || entryClass == null) { 1587 throw new NullPointerException("invalid null input"); 1588 } 1589 if (!initialized) { 1590 throw new KeyStoreException("Uninitialized keystore"); 1591 } 1592 return keyStoreSpi.engineEntryInstanceOf(alias, entryClass); 1593 } 1594 1595 /** 1596 * A description of a to-be-instantiated KeyStore object. 1597 * 1598 * <p>An instance of this class encapsulates the information needed to 1599 * instantiate and initialize a KeyStore object. That process is 1600 * triggered when the {@linkplain #getKeyStore} method is called. 1601 * 1602 * <p>This makes it possible to decouple configuration from KeyStore 1603 * object creation and e.g. delay a password prompt until it is 1604 * needed. 1605 * 1606 * @see KeyStore 1607 * @see javax.net.ssl.KeyStoreBuilderParameters 1608 * @since 1.5 1609 */ 1610 public static abstract class Builder { 1611 1612 // maximum times to try the callbackhandler if the password is wrong 1613 static final int MAX_CALLBACK_TRIES = 3; 1614 1615 /** 1616 * Construct a new Builder. 1617 */ Builder()1618 protected Builder() { 1619 // empty 1620 } 1621 1622 /** 1623 * Returns the KeyStore described by this object. 1624 * 1625 * @return the {@code KeyStore} described by this object 1626 * @exception KeyStoreException if an error occurred during the 1627 * operation, for example if the KeyStore could not be 1628 * instantiated or loaded 1629 */ getKeyStore()1630 public abstract KeyStore getKeyStore() throws KeyStoreException; 1631 1632 /** 1633 * Returns the ProtectionParameters that should be used to obtain 1634 * the {@link KeyStore.Entry Entry} with the given alias. 1635 * The {@code getKeyStore} method must be invoked before this 1636 * method may be called. 1637 * 1638 * @return the ProtectionParameters that should be used to obtain 1639 * the {@link KeyStore.Entry Entry} with the given alias. 1640 * @param alias the alias of the KeyStore entry 1641 * @throws NullPointerException if alias is null 1642 * @throws KeyStoreException if an error occurred during the 1643 * operation 1644 * @throws IllegalStateException if the getKeyStore method has 1645 * not been invoked prior to calling this method 1646 */ getProtectionParameter(String alias)1647 public abstract ProtectionParameter getProtectionParameter(String alias) 1648 throws KeyStoreException; 1649 1650 /** 1651 * Returns a new Builder that encapsulates the given KeyStore. 1652 * The {@linkplain #getKeyStore} method of the returned object 1653 * will return {@code keyStore}, the {@linkplain 1654 * #getProtectionParameter getProtectionParameter()} method will 1655 * return {@code protectionParameters}. 1656 * 1657 * <p> This is useful if an existing KeyStore object needs to be 1658 * used with Builder-based APIs. 1659 * 1660 * @return a new Builder object 1661 * @param keyStore the KeyStore to be encapsulated 1662 * @param protectionParameter the ProtectionParameter used to 1663 * protect the KeyStore entries 1664 * @throws NullPointerException if keyStore or 1665 * protectionParameters is null 1666 * @throws IllegalArgumentException if the keyStore has not been 1667 * initialized 1668 */ newInstance(final KeyStore keyStore, final ProtectionParameter protectionParameter)1669 public static Builder newInstance(final KeyStore keyStore, 1670 final ProtectionParameter protectionParameter) { 1671 if ((keyStore == null) || (protectionParameter == null)) { 1672 throw new NullPointerException(); 1673 } 1674 if (keyStore.initialized == false) { 1675 throw new IllegalArgumentException("KeyStore not initialized"); 1676 } 1677 return new Builder() { 1678 private volatile boolean getCalled; 1679 1680 public KeyStore getKeyStore() { 1681 getCalled = true; 1682 return keyStore; 1683 } 1684 1685 public ProtectionParameter getProtectionParameter(String alias) 1686 { 1687 if (alias == null) { 1688 throw new NullPointerException(); 1689 } 1690 if (getCalled == false) { 1691 throw new IllegalStateException 1692 ("getKeyStore() must be called first"); 1693 } 1694 return protectionParameter; 1695 } 1696 }; 1697 } 1698 1699 /** 1700 * Returns a new Builder object. 1701 * 1702 * <p>The first call to the {@link #getKeyStore} method on the returned 1703 * builder will create a KeyStore of type {@code type} and call 1704 * its {@link KeyStore#load load()} method. 1705 * The {@code inputStream} argument is constructed from 1706 * {@code file}. 1707 * If {@code protection} is a 1708 * {@code PasswordProtection}, the password is obtained by 1709 * calling the {@code getPassword} method. 1710 * Otherwise, if {@code protection} is a 1711 * {@code CallbackHandlerProtection}, the password is obtained 1712 * by invoking the CallbackHandler. 1713 * 1714 * <p>Subsequent calls to {@link #getKeyStore} return the same object 1715 * as the initial call. If the initial call to failed with a 1716 * KeyStoreException, subsequent calls also throw a 1717 * KeyStoreException. 1718 * 1719 * <p>The KeyStore is instantiated from {@code provider} if 1720 * non-null. Otherwise, all installed providers are searched. 1721 * 1722 * <p>Calls to {@link #getProtectionParameter getProtectionParameter()} 1723 * will return a {@link KeyStore.PasswordProtection PasswordProtection} 1724 * object encapsulating the password that was used to invoke the 1725 * {@code load} method. 1726 * 1727 * <p><em>Note</em> that the {@link #getKeyStore} method is executed 1728 * within the {@link AccessControlContext} of the code invoking this 1729 * method. 1730 * 1731 * @return a new Builder object 1732 * @param type the type of KeyStore to be constructed 1733 * @param provider the provider from which the KeyStore is to 1734 * be instantiated (or null) 1735 * @param file the File that contains the KeyStore data 1736 * @param protection the ProtectionParameter securing the KeyStore data 1737 * @throws NullPointerException if type, file or protection is null 1738 * @throws IllegalArgumentException if protection is not an instance 1739 * of either PasswordProtection or CallbackHandlerProtection; or 1740 * if file does not exist or does not refer to a normal file 1741 */ newInstance(String type, Provider provider, File file, ProtectionParameter protection)1742 public static Builder newInstance(String type, Provider provider, 1743 File file, ProtectionParameter protection) { 1744 if ((type == null) || (file == null) || (protection == null)) { 1745 throw new NullPointerException(); 1746 } 1747 if ((protection instanceof PasswordProtection == false) && 1748 (protection instanceof CallbackHandlerProtection == false)) { 1749 throw new IllegalArgumentException 1750 ("Protection must be PasswordProtection or " + 1751 "CallbackHandlerProtection"); 1752 } 1753 if (file.isFile() == false) { 1754 throw new IllegalArgumentException 1755 ("File does not exist or it does not refer " + 1756 "to a normal file: " + file); 1757 } 1758 return new FileBuilder(type, provider, file, protection, 1759 AccessController.getContext()); 1760 } 1761 1762 private static final class FileBuilder extends Builder { 1763 1764 private final String type; 1765 private final Provider provider; 1766 private final File file; 1767 private ProtectionParameter protection; 1768 private ProtectionParameter keyProtection; 1769 private final AccessControlContext context; 1770 1771 private KeyStore keyStore; 1772 1773 private Throwable oldException; 1774 FileBuilder(String type, Provider provider, File file, ProtectionParameter protection, AccessControlContext context)1775 FileBuilder(String type, Provider provider, File file, 1776 ProtectionParameter protection, 1777 AccessControlContext context) { 1778 this.type = type; 1779 this.provider = provider; 1780 this.file = file; 1781 this.protection = protection; 1782 this.context = context; 1783 } 1784 getKeyStore()1785 public synchronized KeyStore getKeyStore() throws KeyStoreException 1786 { 1787 if (keyStore != null) { 1788 return keyStore; 1789 } 1790 if (oldException != null) { 1791 throw new KeyStoreException 1792 ("Previous KeyStore instantiation failed", 1793 oldException); 1794 } 1795 PrivilegedExceptionAction<KeyStore> action = 1796 new PrivilegedExceptionAction<KeyStore>() { 1797 public KeyStore run() throws Exception { 1798 if (protection instanceof CallbackHandlerProtection == false) { 1799 return run0(); 1800 } 1801 // when using a CallbackHandler, 1802 // reprompt if the password is wrong 1803 int tries = 0; 1804 while (true) { 1805 tries++; 1806 try { 1807 return run0(); 1808 } catch (IOException e) { 1809 if ((tries < MAX_CALLBACK_TRIES) 1810 && (e.getCause() instanceof UnrecoverableKeyException)) { 1811 continue; 1812 } 1813 throw e; 1814 } 1815 } 1816 } 1817 public KeyStore run0() throws Exception { 1818 KeyStore ks; 1819 if (provider == null) { 1820 ks = KeyStore.getInstance(type); 1821 } else { 1822 ks = KeyStore.getInstance(type, provider); 1823 } 1824 InputStream in = null; 1825 char[] password = null; 1826 try { 1827 in = new FileInputStream(file); 1828 if (protection instanceof PasswordProtection) { 1829 password = 1830 ((PasswordProtection)protection).getPassword(); 1831 keyProtection = protection; 1832 } else { 1833 CallbackHandler handler = 1834 ((CallbackHandlerProtection)protection) 1835 .getCallbackHandler(); 1836 PasswordCallback callback = new PasswordCallback 1837 ("Password for keystore " + file.getName(), 1838 false); 1839 handler.handle(new Callback[] {callback}); 1840 password = callback.getPassword(); 1841 if (password == null) { 1842 throw new KeyStoreException("No password" + 1843 " provided"); 1844 } 1845 callback.clearPassword(); 1846 keyProtection = new PasswordProtection(password); 1847 } 1848 ks.load(in, password); 1849 return ks; 1850 } finally { 1851 if (in != null) { 1852 in.close(); 1853 } 1854 } 1855 } 1856 }; 1857 try { 1858 keyStore = AccessController.doPrivileged(action, context); 1859 return keyStore; 1860 } catch (PrivilegedActionException e) { 1861 oldException = e.getCause(); 1862 throw new KeyStoreException 1863 ("KeyStore instantiation failed", oldException); 1864 } 1865 } 1866 1867 public synchronized ProtectionParameter getProtectionParameter(String alias)1868 getProtectionParameter(String alias) { 1869 if (alias == null) { 1870 throw new NullPointerException(); 1871 } 1872 if (keyStore == null) { 1873 throw new IllegalStateException 1874 ("getKeyStore() must be called first"); 1875 } 1876 return keyProtection; 1877 } 1878 } 1879 1880 /** 1881 * Returns a new Builder object. 1882 * 1883 * <p>Each call to the {@link #getKeyStore} method on the returned 1884 * builder will return a new KeyStore object of type {@code type}. 1885 * Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()} 1886 * method is invoked using a 1887 * {@code LoadStoreParameter} that encapsulates 1888 * {@code protection}. 1889 * 1890 * <p>The KeyStore is instantiated from {@code provider} if 1891 * non-null. Otherwise, all installed providers are searched. 1892 * 1893 * <p>Calls to {@link #getProtectionParameter getProtectionParameter()} 1894 * will return {@code protection}. 1895 * 1896 * <p><em>Note</em> that the {@link #getKeyStore} method is executed 1897 * within the {@link AccessControlContext} of the code invoking this 1898 * method. 1899 * 1900 * @return a new Builder object 1901 * @param type the type of KeyStore to be constructed 1902 * @param provider the provider from which the KeyStore is to 1903 * be instantiated (or null) 1904 * @param protection the ProtectionParameter securing the Keystore 1905 * @throws NullPointerException if type or protection is null 1906 */ newInstance(final String type, final Provider provider, final ProtectionParameter protection)1907 public static Builder newInstance(final String type, 1908 final Provider provider, final ProtectionParameter protection) { 1909 if ((type == null) || (protection == null)) { 1910 throw new NullPointerException(); 1911 } 1912 final AccessControlContext context = AccessController.getContext(); 1913 return new Builder() { 1914 private volatile boolean getCalled; 1915 private IOException oldException; 1916 1917 private final PrivilegedExceptionAction<KeyStore> action 1918 = new PrivilegedExceptionAction<KeyStore>() { 1919 1920 public KeyStore run() throws Exception { 1921 KeyStore ks; 1922 if (provider == null) { 1923 ks = KeyStore.getInstance(type); 1924 } else { 1925 ks = KeyStore.getInstance(type, provider); 1926 } 1927 LoadStoreParameter param = new SimpleLoadStoreParameter(protection); 1928 if (protection instanceof CallbackHandlerProtection == false) { 1929 ks.load(param); 1930 } else { 1931 // when using a CallbackHandler, 1932 // reprompt if the password is wrong 1933 int tries = 0; 1934 while (true) { 1935 tries++; 1936 try { 1937 ks.load(param); 1938 break; 1939 } catch (IOException e) { 1940 if (e.getCause() instanceof UnrecoverableKeyException) { 1941 if (tries < MAX_CALLBACK_TRIES) { 1942 continue; 1943 } else { 1944 oldException = e; 1945 } 1946 } 1947 throw e; 1948 } 1949 } 1950 } 1951 getCalled = true; 1952 return ks; 1953 } 1954 }; 1955 1956 public synchronized KeyStore getKeyStore() 1957 throws KeyStoreException { 1958 if (oldException != null) { 1959 throw new KeyStoreException 1960 ("Previous KeyStore instantiation failed", 1961 oldException); 1962 } 1963 try { 1964 return AccessController.doPrivileged(action, context); 1965 } catch (PrivilegedActionException e) { 1966 Throwable cause = e.getCause(); 1967 throw new KeyStoreException 1968 ("KeyStore instantiation failed", cause); 1969 } 1970 } 1971 1972 public ProtectionParameter getProtectionParameter(String alias) 1973 { 1974 if (alias == null) { 1975 throw new NullPointerException(); 1976 } 1977 if (getCalled == false) { 1978 throw new IllegalStateException 1979 ("getKeyStore() must be called first"); 1980 } 1981 return protection; 1982 } 1983 }; 1984 } 1985 1986 } 1987 1988 static class SimpleLoadStoreParameter implements LoadStoreParameter { 1989 1990 private final ProtectionParameter protection; 1991 1992 SimpleLoadStoreParameter(ProtectionParameter protection) { 1993 this.protection = protection; 1994 } 1995 1996 public ProtectionParameter getProtectionParameter() { 1997 return protection; 1998 } 1999 } 2000 2001 } 2002