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
26package java.security;
27
28import java.io.*;
29import java.net.URI;
30import java.security.cert.Certificate;
31import java.security.cert.X509Certificate;
32import java.security.cert.CertificateException;
33import java.security.spec.AlgorithmParameterSpec;
34import java.util.*;
35import javax.crypto.SecretKey;
36
37import javax.security.auth.DestroyFailedException;
38import 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
211public 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         */
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         */
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}/openjdk-redirect.html?v=8&path=/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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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             */
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             */
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         */
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         */
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         */
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         */
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         */
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
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         */
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         */
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         */
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         */
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
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         */
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         */
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         */
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         */
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
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         */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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         */
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         */
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         */
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         */
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         */
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
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
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
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         */
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