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