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