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  * "{@docRoot}openjdk-redirect.html?v=8&path=/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          * "{@docRoot}/../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      * "{@docRoot}openjdk-redirect.html?v=8&path=/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      * "{@docRoot}openjdk-redirect.html?v=8&path=/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      * "{@docRoot}openjdk-redirect.html?v=8&path=/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