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