Source Code Cross Referenced for KeyStore.java in  » 6.0-JDK-Core » security » java » security » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » java.security 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.security;
0027
0028        import java.io.*;
0029        import java.security.cert.Certificate;
0030        import java.security.cert.X509Certificate;
0031        import java.security.cert.CertificateException;
0032        import java.util.*;
0033        import javax.crypto.SecretKey;
0034
0035        import javax.security.auth.callback.*;
0036
0037        /**
0038         * This class represents a storage facility for cryptographic
0039         * keys and certificates.
0040         *
0041         * <p> A <code>KeyStore</code> manages different types of entries.
0042         * Each type of entry implements the <code>KeyStore.Entry</code> interface.
0043         * Three basic <code>KeyStore.Entry</code> implementations are provided:
0044         *
0045         * <ul>
0046         * <li><b>KeyStore.PrivateKeyEntry</b>
0047         * <p> This type of entry holds a cryptographic <code>PrivateKey</code>,
0048         * which is optionally stored in a protected format to prevent
0049         * unauthorized access.  It is also accompanied by a certificate chain
0050         * for the corresponding public key.
0051         *
0052         * <p> Private keys and certificate chains are used by a given entity for
0053         * self-authentication. Applications for this authentication include software
0054         * distribution organizations which sign JAR files as part of releasing
0055         * and/or licensing software.
0056         *
0057         * <li><b>KeyStore.SecretKeyEntry</b>
0058         * <p> This type of entry holds a cryptographic <code>SecretKey</code>,
0059         * which is optionally stored in a protected format to prevent
0060         * unauthorized access.
0061         *
0062         * <li><b>KeyStore.TrustedCertificateEntry</b>
0063         * <p> This type of entry contains a single public key <code>Certificate</code>
0064         * belonging to another party. It is called a <i>trusted certificate</i>
0065         * because the keystore owner trusts that the public key in the certificate
0066         * indeed belongs to the identity identified by the <i>subject</i> (owner)
0067         * of the certificate.
0068         *
0069         * <p>This type of entry can be used to authenticate other parties.
0070         * </ul>
0071         *
0072         * <p> Each entry in a keystore is identified by an "alias" string. In the
0073         * case of private keys and their associated certificate chains, these strings
0074         * distinguish among the different ways in which the entity may authenticate
0075         * itself. For example, the entity may authenticate itself using different
0076         * certificate authorities, or using different public key algorithms.
0077         *
0078         * <p> Whether aliases are case sensitive is implementation dependent. In order
0079         * to avoid problems, it is recommended not to use aliases in a KeyStore that
0080         * only differ in case.
0081         *
0082         * <p> Whether keystores are persistent, and the mechanisms used by the
0083         * keystore if it is persistent, are not specified here. This allows
0084         * use of a variety of techniques for protecting sensitive (e.g., private or
0085         * secret) keys. Smart cards or other integrated cryptographic engines
0086         * (SafeKeyper) are one option, and simpler mechanisms such as files may also
0087         * be used (in a variety of formats).
0088         *
0089         * <p> Typical ways to request a KeyStore object include
0090         * relying on the default type and providing a specific keystore type.
0091         *
0092         * <ul>
0093         * <li>To rely on the default type:
0094         * <pre>
0095         *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
0096         * </pre>
0097         * The system will return a keystore implementation for the default type.
0098         * <p>
0099         *
0100         * <li>To provide a specific keystore type:
0101         * <pre>
0102         *      KeyStore ks = KeyStore.getInstance("JKS");
0103         * </pre>
0104         * The system will return the most preferred implementation of the
0105         * specified keystore type available in the environment. <p>
0106         * </ul>
0107         *
0108         * <p> Before a keystore can be accessed, it must be
0109         * {@link #load(java.io.InputStream, char[]) loaded}.
0110         * <pre>
0111         *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
0112         *
0113         *    // get user password and file input stream
0114         *    char[] password = getPassword();
0115         *
0116         *    java.io.FileInputStream fis = null;
0117         *    try {
0118         *        fis = new java.io.FileInputStream("keyStoreName");
0119         *        ks.load(fis, password);
0120         *    } finally {
0121         *        if (fis != null) {
0122         *            fis.close();
0123         *        }
0124         *    }
0125         * </pre>
0126         *
0127         * To create an empty keystore using the above <code>load</code> method,
0128         * pass <code>null</code> as the <code>InputStream</code> argument.
0129         *
0130         * <p> Once the keystore has been loaded, it is possible
0131         * to read existing entries from the keystore, or to write new entries
0132         * into the keystore:
0133         * <pre>
0134         *    // get my private key
0135         *    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
0136         *        ks.getEntry("privateKeyAlias", password);
0137         *    PrivateKey myPrivateKey = pkEntry.getPrivateKey();
0138         *
0139         *    // save my secret key
0140         *    javax.crypto.SecretKey mySecretKey;
0141         *    KeyStore.SecretKeyEntry skEntry =
0142         *        new KeyStore.SecretKeyEntry(mySecretKey);
0143         *    ks.setEntry("secretKeyAlias", skEntry, 
0144         *        new KeyStore.PasswordProtection(password));
0145         *
0146         *    // store away the keystore
0147         *    java.io.FileOutputStream fos = null;
0148         *    try {
0149         *        fos = new java.io.FileOutputStream("newKeyStoreName");
0150         *        ks.store(fos, password);
0151         *    } finally {
0152         *        if (fos != null) {
0153         *            fos.close();
0154         *        }
0155         *    }
0156         * </pre>
0157         *
0158         * Note that although the same password may be used to
0159         * load the keystore, to protect the private key entry,
0160         * to protect the secret key entry, and to store the keystore
0161         * (as is shown in the sample code above),
0162         * different passwords or other protection parameters
0163         * may also be used.
0164         *
0165         * @author Jan Luehe
0166         *
0167         * @version 1.61, 05/05/07
0168         *
0169         * @see java.security.PrivateKey
0170         * @see javax.crypto.SecretKey
0171         * @see java.security.cert.Certificate
0172         *
0173         * @since 1.2
0174         */
0175
0176        public class KeyStore {
0177
0178            /*
0179             * Constant to lookup in the Security properties file to determine
0180             * the default keystore type.
0181             * In the Security properties file, the default keystore type is given as:
0182             * <pre>
0183             * keystore.type=jks
0184             * </pre>
0185             */
0186            private static final String KEYSTORE_TYPE = "keystore.type";
0187
0188            // The keystore type
0189            private String type;
0190
0191            // The provider
0192            private Provider provider;
0193
0194            // The provider implementation
0195            private KeyStoreSpi keyStoreSpi;
0196
0197            // Has this keystore been initialized (loaded)?
0198            private boolean initialized = false;
0199
0200            /**
0201             * A marker interface for <code>KeyStore</code>
0202             * {@link #load(KeyStore.LoadStoreParameter) load}
0203             * and
0204             * {@link #store(KeyStore.LoadStoreParameter) store}
0205             * parameters.
0206             *
0207             * @since 1.5
0208             */
0209            public static interface LoadStoreParameter {
0210                /**
0211                 * Gets the parameter used to protect keystore data.
0212                 *
0213                 * @return the parameter used to protect keystore data, or null
0214                 */
0215                public ProtectionParameter getProtectionParameter();
0216            }
0217
0218            /**
0219             * A marker interface for keystore protection parameters.
0220             *
0221             * <p> The information stored in a <code>ProtectionParameter</code>
0222             * object protects the contents of a keystore.
0223             * For example, protection parameters may be used to check
0224             * the integrity of keystore data, or to protect the
0225             * confidentiality of sensitive keystore data
0226             * (such as a <code>PrivateKey</code>).
0227             *
0228             * @since 1.5
0229             */
0230            public static interface ProtectionParameter {
0231            }
0232
0233            /**
0234             * A password-based implementation of <code>ProtectionParameter</code>.
0235             *
0236             * @since 1.5
0237             */
0238            public static class PasswordProtection implements 
0239                    ProtectionParameter, javax.security.auth.Destroyable {
0240
0241                private final char[] password;
0242                private volatile boolean destroyed = false;
0243
0244                /**
0245                 * Creates a password parameter.
0246                 *
0247                 * <p> The specified <code>password</code> is cloned before it is stored
0248                 * in the new <code>PasswordProtection</code> object.
0249                 *
0250                 * @param password the password, which may be <code>null</code>
0251                 */
0252                public PasswordProtection(char[] password) {
0253                    this .password = (password == null) ? null
0254                            : (char[]) password.clone();
0255                }
0256
0257                /**
0258                 * Gets the password.
0259                 *
0260                 * <p>Note that this method returns a reference to the password.
0261                 * If a clone of the array is created it is the caller's
0262                 * responsibility to zero out the password information
0263                 * after it is no longer needed.
0264                 *
0265                 * @see #destroy()
0266                 * @return the password, which may be <code>null</code>
0267                 * @exception IllegalStateException if the password has
0268                 *		been cleared (destroyed)
0269                 */
0270                public synchronized char[] getPassword() {
0271                    if (destroyed) {
0272                        throw new IllegalStateException(
0273                                "password has been cleared");
0274                    }
0275                    return password;
0276                }
0277
0278                /**
0279                 * Clears the password.
0280                 *
0281                 * @exception DestroyFailedException if this method was unable
0282                 *	to clear the password
0283                 */
0284                public synchronized void destroy()
0285                        throws javax.security.auth.DestroyFailedException {
0286                    destroyed = true;
0287                    if (password != null) {
0288                        Arrays.fill(password, ' ');
0289                    }
0290                }
0291
0292                /**
0293                 * Determines if password has been cleared.
0294                 *
0295                 * @return true if the password has been cleared, false otherwise
0296                 */
0297                public synchronized boolean isDestroyed() {
0298                    return destroyed;
0299                }
0300            }
0301
0302            /**
0303             * A ProtectionParameter encapsulating a CallbackHandler.
0304             *
0305             * @since 1.5
0306             */
0307            public static class CallbackHandlerProtection implements 
0308                    ProtectionParameter {
0309
0310                private final CallbackHandler handler;
0311
0312                /**
0313                 * Constructs a new CallbackHandlerProtection from a
0314                 * CallbackHandler.
0315                 *
0316                 * @param handler the CallbackHandler
0317                 * @exception NullPointerException if handler is null
0318                 */
0319                public CallbackHandlerProtection(CallbackHandler handler) {
0320                    if (handler == null) {
0321                        throw new NullPointerException(
0322                                "handler must not be null");
0323                    }
0324                    this .handler = handler;
0325                }
0326
0327                /**
0328                 * Returns the CallbackHandler.
0329                 *
0330                 * @return the CallbackHandler.
0331                 */
0332                public CallbackHandler getCallbackHandler() {
0333                    return handler;
0334                }
0335
0336            }
0337
0338            /**
0339             * A marker interface for <code>KeyStore</code> entry types.
0340             *
0341             * @since 1.5
0342             */
0343            public static interface Entry {
0344            }
0345
0346            /**
0347             * A <code>KeyStore</code> entry that holds a <code>PrivateKey</code>
0348             * and corresponding certificate chain.
0349             *
0350             * @since 1.5
0351             */
0352            public static final class PrivateKeyEntry implements  Entry {
0353
0354                private final PrivateKey privKey;
0355                private final Certificate[] chain;
0356
0357                /**
0358                 * Constructs a <code>PrivateKeyEntry</code> with a
0359                 * <code>PrivateKey</code> and corresponding certificate chain.
0360                 *
0361                 * <p> The specified <code>chain</code> is cloned before it is stored
0362                 * in the new <code>PrivateKeyEntry</code> object.
0363                 *
0364                 * @param privateKey the <code>PrivateKey</code>
0365                 * @param chain an array of <code>Certificate</code>s
0366                 *	representing the certificate chain.
0367                 *	The chain must be ordered and contain a
0368                 *	<code>Certificate</code> at index 0
0369                 *	corresponding to the private key.
0370                 *
0371                 * @exception NullPointerException if
0372                 *	<code>privateKey</code> or <code>chain</code>
0373                 *	is <code>null</code>
0374                 * @exception IllegalArgumentException if the specified chain has a
0375                 *	length of 0, if the specified chain does not contain
0376                 *	<code>Certificate</code>s of the same type,
0377                 *	or if the <code>PrivateKey</code> algorithm
0378                 *	does not match the algorithm of the <code>PublicKey</code>
0379                 *	in the end entity <code>Certificate</code> (at index 0)
0380                 */
0381                public PrivateKeyEntry(PrivateKey privateKey,
0382                        Certificate[] chain) {
0383                    if (privateKey == null || chain == null) {
0384                        throw new NullPointerException("invalid null input");
0385                    }
0386                    if (chain.length == 0) {
0387                        throw new IllegalArgumentException(
0388                                "invalid zero-length input chain");
0389                    }
0390
0391                    Certificate[] clonedChain = (Certificate[]) chain.clone();
0392                    String certType = clonedChain[0].getType();
0393                    for (int i = 1; i < clonedChain.length; i++) {
0394                        if (!certType.equals(clonedChain[i].getType())) {
0395                            throw new IllegalArgumentException(
0396                                    "chain does not contain certificates "
0397                                            + "of the same type");
0398                        }
0399                    }
0400                    if (!privateKey.getAlgorithm().equals(
0401                            clonedChain[0].getPublicKey().getAlgorithm())) {
0402                        throw new IllegalArgumentException(
0403                                "private key algorithm does not match "
0404                                        + "algorithm of public key in end entity "
0405                                        + "certificate (at index 0)");
0406                    }
0407                    this .privKey = privateKey;
0408
0409                    if (clonedChain[0] instanceof  X509Certificate
0410                            && !(clonedChain instanceof  X509Certificate[])) {
0411
0412                        this .chain = new X509Certificate[clonedChain.length];
0413                        System.arraycopy(clonedChain, 0, this .chain, 0,
0414                                clonedChain.length);
0415                    } else {
0416                        this .chain = clonedChain;
0417                    }
0418                }
0419
0420                /**
0421                 * Gets the <code>PrivateKey</code> from this entry.
0422                 *
0423                 * @return the <code>PrivateKey</code> from this entry
0424                 */
0425                public PrivateKey getPrivateKey() {
0426                    return privKey;
0427                }
0428
0429                /**
0430                 * Gets the <code>Certificate</code> chain from this entry.
0431                 *
0432                 * <p> The stored chain is cloned before being returned.
0433                 *
0434                 * @return an array of <code>Certificate</code>s corresponding
0435                 *	to the certificate chain for the public key.
0436                 *	If the certificates are of type X.509,
0437                 *	the runtime type of the returned array is
0438                 *	<code>X509Certificate[]</code>.
0439                 */
0440                public Certificate[] getCertificateChain() {
0441                    return (Certificate[]) chain.clone();
0442                }
0443
0444                /**
0445                 * Gets the end entity <code>Certificate</code>
0446                 * from the certificate chain in this entry.
0447                 *
0448                 * @return the end entity <code>Certificate</code> (at index 0)
0449                 *	from the certificate chain in this entry.
0450                 *	If the certificate is of type X.509,
0451                 *	the runtime type of the returned certificate is
0452                 *	<code>X509Certificate</code>.
0453                 */
0454                public Certificate getCertificate() {
0455                    return chain[0];
0456                }
0457
0458                /**
0459                 * Returns a string representation of this PrivateKeyEntry.
0460                 * @return a string representation of this PrivateKeyEntry.
0461                 */
0462                public String toString() {
0463                    StringBuilder sb = new StringBuilder();
0464                    sb.append("Private key entry and certificate chain with "
0465                            + chain.length + " elements:\r\n");
0466                    for (Certificate cert : chain) {
0467                        sb.append(cert);
0468                        sb.append("\r\n");
0469                    }
0470                    return sb.toString();
0471                }
0472
0473            }
0474
0475            /**
0476             * A <code>KeyStore</code> entry that holds a <code>SecretKey</code>.
0477             *
0478             * @since 1.5
0479             */
0480            public static final class SecretKeyEntry implements  Entry {
0481
0482                private final SecretKey sKey;
0483
0484                /**
0485                 * Constructs a <code>SecretKeyEntry</code> with a
0486                 * <code>SecretKey</code>.
0487                 *
0488                 * @param secretKey the <code>SecretKey</code>
0489                 *
0490                 * @exception NullPointerException if <code>secretKey</code>
0491                 *	is <code>null</code>
0492                 */
0493                public SecretKeyEntry(SecretKey secretKey) {
0494                    if (secretKey == null) {
0495                        throw new NullPointerException("invalid null input");
0496                    }
0497                    this .sKey = secretKey;
0498                }
0499
0500                /**
0501                 * Gets the <code>SecretKey</code> from this entry.
0502                 *
0503                 * @return the <code>SecretKey</code> from this entry
0504                 */
0505                public SecretKey getSecretKey() {
0506                    return sKey;
0507                }
0508
0509                /**
0510                 * Returns a string representation of this SecretKeyEntry.
0511                 * @return a string representation of this SecretKeyEntry.
0512                 */
0513                public String toString() {
0514                    return "Secret key entry with algorithm "
0515                            + sKey.getAlgorithm();
0516                }
0517            }
0518
0519            /**
0520             * A <code>KeyStore</code> entry that holds a trusted
0521             * <code>Certificate</code>.
0522             *
0523             * @since 1.5
0524             */
0525            public static final class TrustedCertificateEntry implements  Entry {
0526
0527                private final Certificate cert;
0528
0529                /**
0530                 * Constructs a <code>TrustedCertificateEntry</code> with a
0531                 * trusted <code>Certificate</code>.
0532                 *
0533                 * @param trustedCert the trusted <code>Certificate</code>
0534                 *
0535                 * @exception NullPointerException if
0536                 *	<code>trustedCert</code> is <code>null</code>
0537                 */
0538                public TrustedCertificateEntry(Certificate trustedCert) {
0539                    if (trustedCert == null) {
0540                        throw new NullPointerException("invalid null input");
0541                    }
0542                    this .cert = trustedCert;
0543                }
0544
0545                /**
0546                 * Gets the trusted <code>Certficate</code> from this entry.
0547                 *
0548                 * @return the trusted <code>Certificate</code> from this entry
0549                 */
0550                public Certificate getTrustedCertificate() {
0551                    return cert;
0552                }
0553
0554                /**
0555                 * Returns a string representation of this TrustedCertificateEntry.
0556                 * @return a string representation of this TrustedCertificateEntry.
0557                 */
0558                public String toString() {
0559                    return "Trusted certificate entry:\r\n" + cert.toString();
0560                }
0561            }
0562
0563            /**
0564             * Creates a KeyStore object of the given type, and encapsulates the given
0565             * provider implementation (SPI object) in it.
0566             *
0567             * @param keyStoreSpi the provider implementation.
0568             * @param provider the provider.
0569             * @param type the keystore type.
0570             */
0571            protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider,
0572                    String type) {
0573                this .keyStoreSpi = keyStoreSpi;
0574                this .provider = provider;
0575                this .type = type;
0576            }
0577
0578            /**
0579             * Returns a keystore object of the specified type.
0580             * 
0581             * <p> This method traverses the list of registered security Providers,
0582             * starting with the most preferred Provider.
0583             * A new KeyStore object encapsulating the
0584             * KeyStoreSpi implementation from the first
0585             * Provider that supports the specified type is returned.
0586             *
0587             * <p> Note that the list of registered providers may be retrieved via
0588             * the {@link Security#getProviders() Security.getProviders()} method.
0589             *
0590             * @param type the type of keystore. 
0591             * See Appendix A in the <a href=
0592             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0593             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0594             * for information about standard keystore types.
0595             *
0596             * @return a keystore object of the specified type.
0597             *
0598             * @exception KeyStoreException if no Provider supports a
0599             *          KeyStoreSpi implementation for the
0600             *          specified type.
0601             *
0602             * @see Provider
0603             */
0604            public static KeyStore getInstance(String type)
0605                    throws KeyStoreException {
0606                try {
0607                    Object[] objs = Security.getImpl(type, "KeyStore",
0608                            (String) null);
0609                    return new KeyStore((KeyStoreSpi) objs[0],
0610                            (Provider) objs[1], type);
0611                } catch (NoSuchAlgorithmException nsae) {
0612                    throw new KeyStoreException(type + " not found", nsae);
0613                } catch (NoSuchProviderException nspe) {
0614                    throw new KeyStoreException(type + " not found", nspe);
0615                }
0616            }
0617
0618            /**
0619             * Returns a keystore object of the specified type.
0620             * 
0621             * <p> A new KeyStore object encapsulating the
0622             * KeyStoreSpi implementation from the specified provider
0623             * is returned.  The specified provider must be registered
0624             * in the security provider list.
0625             *
0626             * <p> Note that the list of registered providers may be retrieved via
0627             * the {@link Security#getProviders() Security.getProviders()} method.
0628             *
0629             * @param type the type of keystore.
0630             * See Appendix A in the <a href=
0631             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0632             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0633             * for information about standard keystore types.
0634             *
0635             * @param provider the name of the provider.
0636             *
0637             * @return a keystore object of the specified type.
0638             *
0639             * @exception KeyStoreException if a KeyStoreSpi
0640             *          implementation for the specified type is not
0641             *          available from the specified provider.
0642             * 
0643             * @exception NoSuchProviderException if the specified provider is not
0644             *          registered in the security provider list.
0645             *
0646             * @exception IllegalArgumentException if the provider name is null
0647             *		or empty.
0648             *
0649             * @see Provider
0650             */
0651            public static KeyStore getInstance(String type, String provider)
0652                    throws KeyStoreException, NoSuchProviderException {
0653                if (provider == null || provider.length() == 0)
0654                    throw new IllegalArgumentException("missing provider");
0655                try {
0656                    Object[] objs = Security
0657                            .getImpl(type, "KeyStore", provider);
0658                    return new KeyStore((KeyStoreSpi) objs[0],
0659                            (Provider) objs[1], type);
0660                } catch (NoSuchAlgorithmException nsae) {
0661                    throw new KeyStoreException(type + " not found", nsae);
0662                }
0663            }
0664
0665            /**
0666             * Returns a keystore object of the specified type.
0667             * 
0668             * <p> A new KeyStore object encapsulating the
0669             * KeyStoreSpi implementation from the specified Provider
0670             * object is returned.  Note that the specified Provider object
0671             * does not have to be registered in the provider list.
0672             *
0673             * @param type the type of keystore.
0674             * See Appendix A in the <a href=
0675             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0676             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0677             * for information about standard keystore types.
0678             *
0679             * @param provider the provider.
0680             *
0681             * @return a keystore object of the specified type.
0682             *
0683             * @exception KeyStoreException if KeyStoreSpi
0684             *          implementation for the specified type is not available
0685             *          from the specified Provider object.
0686             *
0687             * @exception IllegalArgumentException if the specified provider is null.
0688             *
0689             * @see Provider
0690             *
0691             * @since 1.4
0692             */
0693            public static KeyStore getInstance(String type, Provider provider)
0694                    throws KeyStoreException {
0695                if (provider == null)
0696                    throw new IllegalArgumentException("missing provider");
0697                try {
0698                    Object[] objs = Security
0699                            .getImpl(type, "KeyStore", provider);
0700                    return new KeyStore((KeyStoreSpi) objs[0],
0701                            (Provider) objs[1], type);
0702                } catch (NoSuchAlgorithmException nsae) {
0703                    throw new KeyStoreException(type + " not found", nsae);
0704                }
0705            }
0706
0707            /**
0708             * Returns the default keystore type as specified in the Java security
0709             * properties file, or the string
0710             * &quot;jks&quot; (acronym for &quot;Java keystore&quot;)
0711             * if no such property exists.
0712             * The Java security properties file is located in the file named
0713             * &lt;JAVA_HOME&gt;/lib/security/java.security.
0714             * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
0715             * and specifies the directory where the JRE is installed.
0716             *
0717             * <p>The default keystore type can be used by applications that do not
0718             * want to use a hard-coded keystore type when calling one of the
0719             * <code>getInstance</code> methods, and want to provide a default keystore
0720             * type in case a user does not specify its own.
0721             *
0722             * <p>The default keystore type can be changed by setting the value of the
0723             * "keystore.type" security property (in the Java security properties
0724             * file) to the desired keystore type.
0725             *
0726             * @return the default keystore type as specified in the 
0727             * Java security properties file, or the string &quot;jks&quot;
0728             * if no such property exists.
0729             */
0730            public final static String getDefaultType() {
0731                String kstype;
0732                kstype = AccessController
0733                        .doPrivileged(new PrivilegedAction<String>() {
0734                            public String run() {
0735                                return Security.getProperty(KEYSTORE_TYPE);
0736                            }
0737                        });
0738                if (kstype == null) {
0739                    kstype = "jks";
0740                }
0741                return kstype;
0742            }
0743
0744            /** 
0745             * Returns the provider of this keystore.
0746             * 
0747             * @return the provider of this keystore.
0748             */
0749            public final Provider getProvider() {
0750                return this .provider;
0751            }
0752
0753            /**
0754             * Returns the type of this keystore.
0755             *
0756             * @return the type of this keystore.
0757             */
0758            public final String getType() {
0759                return this .type;
0760            }
0761
0762            /**
0763             * Returns the key associated with the given alias, using the given
0764             * password to recover it.  The key must have been associated with
0765             * the alias by a call to <code>setKeyEntry</code>,
0766             * or by a call to <code>setEntry</code> with a
0767             * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
0768             *
0769             * @param alias the alias name
0770             * @param password the password for recovering the key
0771             *
0772             * @return the requested key, or null if the given alias does not exist
0773             * or does not identify a key-related entry.
0774             *
0775             * @exception KeyStoreException if the keystore has not been initialized
0776             * (loaded).
0777             * @exception NoSuchAlgorithmException if the algorithm for recovering the
0778             * key cannot be found
0779             * @exception UnrecoverableKeyException if the key cannot be recovered
0780             * (e.g., the given password is wrong).
0781             */
0782            public final Key getKey(String alias, char[] password)
0783                    throws KeyStoreException, NoSuchAlgorithmException,
0784                    UnrecoverableKeyException {
0785                if (!initialized) {
0786                    throw new KeyStoreException("Uninitialized keystore");
0787                }
0788                return keyStoreSpi.engineGetKey(alias, password);
0789            }
0790
0791            /**
0792             * Returns the certificate chain associated with the given alias.
0793             * The certificate chain must have been associated with the alias
0794             * by a call to <code>setKeyEntry</code>,
0795             * or by a call to <code>setEntry</code> with a
0796             * <code>PrivateKeyEntry</code>.
0797             *
0798             * @param alias the alias name
0799             *
0800             * @return the certificate chain (ordered with the user's certificate first
0801             * and the root certificate authority last), or null if the given alias
0802             * does not exist or does not contain a certificate chain
0803             *
0804             * @exception KeyStoreException if the keystore has not been initialized
0805             * (loaded).
0806             */
0807            public final Certificate[] getCertificateChain(String alias)
0808                    throws KeyStoreException {
0809                if (!initialized) {
0810                    throw new KeyStoreException("Uninitialized keystore");
0811                }
0812                return keyStoreSpi.engineGetCertificateChain(alias);
0813            }
0814
0815            /**
0816             * Returns the certificate associated with the given alias.
0817             *
0818             * <p> If the given alias name identifies an entry
0819             * created by a call to <code>setCertificateEntry</code>,
0820             * or created by a call to <code>setEntry</code> with a
0821             * <code>TrustedCertificateEntry</code>,
0822             * then the trusted certificate contained in that entry is returned.
0823             *
0824             * <p> If the given alias name identifies an entry
0825             * created by a call to <code>setKeyEntry</code>,
0826             * or created by a call to <code>setEntry</code> with a
0827             * <code>PrivateKeyEntry</code>,
0828             * then the first element of the certificate chain in that entry
0829             * is returned.
0830             * 
0831             * @param alias the alias name
0832             *
0833             * @return the certificate, or null if the given alias does not exist or
0834             * does not contain a certificate.
0835             *
0836             * @exception KeyStoreException if the keystore has not been initialized
0837             * (loaded).
0838             */
0839            public final Certificate getCertificate(String alias)
0840                    throws KeyStoreException {
0841                if (!initialized) {
0842                    throw new KeyStoreException("Uninitialized keystore");
0843                }
0844                return keyStoreSpi.engineGetCertificate(alias);
0845            }
0846
0847            /**
0848             * Returns the creation date of the entry identified by the given alias.
0849             *
0850             * @param alias the alias name
0851             *
0852             * @return the creation date of this entry, or null if the given alias does
0853             * not exist
0854             *
0855             * @exception KeyStoreException if the keystore has not been initialized
0856             * (loaded).
0857             */
0858            public final Date getCreationDate(String alias)
0859                    throws KeyStoreException {
0860                if (!initialized) {
0861                    throw new KeyStoreException("Uninitialized keystore");
0862                }
0863                return keyStoreSpi.engineGetCreationDate(alias);
0864            }
0865
0866            /**
0867             * Assigns the given key to the given alias, protecting it with the given
0868             * password.
0869             *
0870             * <p>If the given key is of type <code>java.security.PrivateKey</code>,
0871             * it must be accompanied by a certificate chain certifying the
0872             * corresponding public key.
0873             *
0874             * <p>If the given alias already exists, the keystore information
0875             * associated with it is overridden by the given key (and possibly
0876             * certificate chain).
0877             *
0878             * @param alias the alias name
0879             * @param key the key to be associated with the alias
0880             * @param password the password to protect the key
0881             * @param chain the certificate chain for the corresponding public
0882             * key (only required if the given key is of type
0883             * <code>java.security.PrivateKey</code>).
0884             *
0885             * @exception KeyStoreException if the keystore has not been initialized
0886             * (loaded), the given key cannot be protected, or this operation fails
0887             * for some other reason
0888             */
0889            public final void setKeyEntry(String alias, Key key,
0890                    char[] password, Certificate[] chain)
0891                    throws KeyStoreException {
0892                if (!initialized) {
0893                    throw new KeyStoreException("Uninitialized keystore");
0894                }
0895                if ((key instanceof  PrivateKey)
0896                        && (chain == null || chain.length == 0)) {
0897                    throw new IllegalArgumentException("Private key must be "
0898                            + "accompanied by certificate " + "chain");
0899                }
0900                keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
0901            }
0902
0903            /**
0904             * Assigns the given key (that has already been protected) to the given
0905             * alias.
0906             * 
0907             * <p>If the protected key is of type
0908             * <code>java.security.PrivateKey</code>, it must be accompanied by a
0909             * certificate chain certifying the corresponding public key. If the
0910             * underlying keystore implementation is of type <code>jks</code>,
0911             * <code>key</code> must be encoded as an
0912             * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
0913             *
0914             * <p>If the given alias already exists, the keystore information
0915             * associated with it is overridden by the given key (and possibly
0916             * certificate chain).
0917             *
0918             * @param alias the alias name
0919             * @param key the key (in protected format) to be associated with the alias
0920             * @param chain the certificate chain for the corresponding public
0921             *		key (only useful if the protected key is of type
0922             *		<code>java.security.PrivateKey</code>).
0923             *
0924             * @exception KeyStoreException if the keystore has not been initialized
0925             * (loaded), or if this operation fails for some other reason.
0926             */
0927            public final void setKeyEntry(String alias, byte[] key,
0928                    Certificate[] chain) throws KeyStoreException {
0929                if (!initialized) {
0930                    throw new KeyStoreException("Uninitialized keystore");
0931                }
0932                keyStoreSpi.engineSetKeyEntry(alias, key, chain);
0933            }
0934
0935            /**
0936             * Assigns the given trusted certificate to the given alias.
0937             *
0938             * <p> If the given alias identifies an existing entry
0939             * created by a call to <code>setCertificateEntry</code>,
0940             * or created by a call to <code>setEntry</code> with a
0941             * <code>TrustedCertificateEntry</code>,
0942             * the trusted certificate in the existing entry
0943             * is overridden by the given certificate.
0944             *
0945             * @param alias the alias name
0946             * @param cert the certificate
0947             *
0948             * @exception KeyStoreException if the keystore has not been initialized,
0949             * or the given alias already exists and does not identify an
0950             * entry containing a trusted certificate,
0951             * or this operation fails for some other reason.
0952             */
0953            public final void setCertificateEntry(String alias, Certificate cert)
0954                    throws KeyStoreException {
0955                if (!initialized) {
0956                    throw new KeyStoreException("Uninitialized keystore");
0957                }
0958                keyStoreSpi.engineSetCertificateEntry(alias, cert);
0959            }
0960
0961            /**
0962             * Deletes the entry identified by the given alias from this keystore.
0963             *
0964             * @param alias the alias name
0965             *
0966             * @exception KeyStoreException if the keystore has not been initialized,
0967             * or if the entry cannot be removed.
0968             */
0969            public final void deleteEntry(String alias)
0970                    throws KeyStoreException {
0971                if (!initialized) {
0972                    throw new KeyStoreException("Uninitialized keystore");
0973                }
0974                keyStoreSpi.engineDeleteEntry(alias);
0975            }
0976
0977            /**
0978             * Lists all the alias names of this keystore.
0979             *
0980             * @return enumeration of the alias names
0981             *
0982             * @exception KeyStoreException if the keystore has not been initialized
0983             * (loaded).
0984             */
0985            public final Enumeration<String> aliases() throws KeyStoreException {
0986                if (!initialized) {
0987                    throw new KeyStoreException("Uninitialized keystore");
0988                }
0989                return keyStoreSpi.engineAliases();
0990            }
0991
0992            /**
0993             * Checks if the given alias exists in this keystore.
0994             *
0995             * @param alias the alias name
0996             *
0997             * @return true if the alias exists, false otherwise
0998             *
0999             * @exception KeyStoreException if the keystore has not been initialized
1000             * (loaded).
1001             */
1002            public final boolean containsAlias(String alias)
1003                    throws KeyStoreException {
1004                if (!initialized) {
1005                    throw new KeyStoreException("Uninitialized keystore");
1006                }
1007                return keyStoreSpi.engineContainsAlias(alias);
1008            }
1009
1010            /**
1011             * Retrieves the number of entries in this keystore.
1012             *
1013             * @return the number of entries in this keystore
1014             *
1015             * @exception KeyStoreException if the keystore has not been initialized
1016             * (loaded).
1017             */
1018            public final int size() throws KeyStoreException {
1019                if (!initialized) {
1020                    throw new KeyStoreException("Uninitialized keystore");
1021                }
1022                return keyStoreSpi.engineSize();
1023            }
1024
1025            /**
1026             * Returns true if the entry identified by the given alias
1027             * was created by a call to <code>setKeyEntry</code>,
1028             * or created by a call to <code>setEntry</code> with a
1029             * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
1030             *
1031             * @param alias the alias for the keystore entry to be checked
1032             *
1033             * @return true if the entry identified by the given alias is a
1034             * key-related entry, false otherwise.
1035             *
1036             * @exception KeyStoreException if the keystore has not been initialized
1037             * (loaded).
1038             */
1039            public final boolean isKeyEntry(String alias)
1040                    throws KeyStoreException {
1041                if (!initialized) {
1042                    throw new KeyStoreException("Uninitialized keystore");
1043                }
1044                return keyStoreSpi.engineIsKeyEntry(alias);
1045            }
1046
1047            /**
1048             * Returns true if the entry identified by the given alias
1049             * was created by a call to <code>setCertificateEntry</code>,
1050             * or created by a call to <code>setEntry</code> with a
1051             * <code>TrustedCertificateEntry</code>.
1052             *
1053             * @param alias the alias for the keystore entry to be checked
1054             *
1055             * @return true if the entry identified by the given alias contains a
1056             * trusted certificate, false otherwise.
1057             *
1058             * @exception KeyStoreException if the keystore has not been initialized
1059             * (loaded).
1060             */
1061            public final boolean isCertificateEntry(String alias)
1062                    throws KeyStoreException {
1063                if (!initialized) {
1064                    throw new KeyStoreException("Uninitialized keystore");
1065                }
1066                return keyStoreSpi.engineIsCertificateEntry(alias);
1067            }
1068
1069            /**
1070             * Returns the (alias) name of the first keystore entry whose certificate
1071             * matches the given certificate.
1072             *
1073             * <p> This method attempts to match the given certificate with each
1074             * keystore entry. If the entry being considered was
1075             * created by a call to <code>setCertificateEntry</code>,
1076             * or created by a call to <code>setEntry</code> with a
1077             * <code>TrustedCertificateEntry</code>,
1078             * then the given certificate is compared to that entry's certificate.
1079             *
1080             * <p> If the entry being considered was
1081             * created by a call to <code>setKeyEntry</code>,
1082             * or created by a call to <code>setEntry</code> with a
1083             * <code>PrivateKeyEntry</code>,
1084             * then the given certificate is compared to the first
1085             * element of that entry's certificate chain.
1086             *
1087             * @param cert the certificate to match with.
1088             *
1089             * @return the alias name of the first entry with a matching certificate,
1090             * or null if no such entry exists in this keystore.
1091             *
1092             * @exception KeyStoreException if the keystore has not been initialized
1093             * (loaded).
1094             */
1095            public final String getCertificateAlias(Certificate cert)
1096                    throws KeyStoreException {
1097                if (!initialized) {
1098                    throw new KeyStoreException("Uninitialized keystore");
1099                }
1100                return keyStoreSpi.engineGetCertificateAlias(cert);
1101            }
1102
1103            /**
1104             * Stores this keystore to the given output stream, and protects its
1105             * integrity with the given password.
1106             *
1107             * @param stream the output stream to which this keystore is written.
1108             * @param password the password to generate the keystore integrity check
1109             *
1110             * @exception KeyStoreException if the keystore has not been initialized
1111             * (loaded).
1112             * @exception IOException if there was an I/O problem with data
1113             * @exception NoSuchAlgorithmException if the appropriate data integrity
1114             * algorithm could not be found
1115             * @exception CertificateException if any of the certificates included in
1116             * the keystore data could not be stored
1117             */
1118            public final void store(OutputStream stream, char[] password)
1119                    throws KeyStoreException, IOException,
1120                    NoSuchAlgorithmException, CertificateException {
1121                if (!initialized) {
1122                    throw new KeyStoreException("Uninitialized keystore");
1123                }
1124                keyStoreSpi.engineStore(stream, password);
1125            }
1126
1127            /**
1128             * Stores this keystore using the given <code>LoadStoreParameter</code>.
1129             *
1130             * @param param the <code>LoadStoreParameter</code>
1131             *		that specifies how to store the keystore,
1132             *		which may be <code>null</code>
1133             *
1134             * @exception IllegalArgumentException if the given
1135             *		<code>LoadStoreParameter</code>
1136             *		input is not recognized
1137             * @exception KeyStoreException if the keystore has not been initialized
1138             *		(loaded)
1139             * @exception IOException if there was an I/O problem with data
1140             * @exception NoSuchAlgorithmException if the appropriate data integrity
1141             *		algorithm could not be found
1142             * @exception CertificateException if any of the certificates included in
1143             *		the keystore data could not be stored
1144             *
1145             * @since 1.5
1146             */
1147            public final void store(LoadStoreParameter param)
1148                    throws KeyStoreException, IOException,
1149                    NoSuchAlgorithmException, CertificateException {
1150                if (!initialized) {
1151                    throw new KeyStoreException("Uninitialized keystore");
1152                }
1153                keyStoreSpi.engineStore(param);
1154            }
1155
1156            /**
1157             * Loads this KeyStore from the given input stream.
1158             *
1159             * <p>A password may be given to unlock the keystore
1160             * (e.g. the keystore resides on a hardware token device),
1161             * or to check the integrity of the keystore data.
1162             * If a password is not given for integrity checking,
1163             * then integrity checking is not performed.
1164             *
1165             * <p>In order to create an empty keystore, or if the keystore cannot
1166             * be initialized from a stream, pass <code>null</code>
1167             * as the <code>stream</code> argument.
1168             *
1169             * <p> Note that if this keystore has already been loaded, it is
1170             * reinitialized and loaded again from the given input stream.
1171             *
1172             * @param stream the input stream from which the keystore is loaded,
1173             * or <code>null</code>
1174             * @param password the password used to check the integrity of
1175             * the keystore, the password used to unlock the keystore,
1176             * or <code>null</code>
1177             *
1178             * @exception IOException if there is an I/O or format problem with the
1179             * keystore data, if a password is required but not given,
1180             * or if the given password was incorrect. If the error is due to a
1181             * wrong password, the {@link Throwable#getCause cause} of the 
1182             * <code>IOException</code> should be an 
1183             * <code>UnrecoverableKeyException</code>
1184             * @exception NoSuchAlgorithmException if the algorithm used to check
1185             * the integrity of the keystore cannot be found
1186             * @exception CertificateException if any of the certificates in the
1187             * keystore could not be loaded
1188             */
1189            public final void load(InputStream stream, char[] password)
1190                    throws IOException, NoSuchAlgorithmException,
1191                    CertificateException {
1192                keyStoreSpi.engineLoad(stream, password);
1193                initialized = true;
1194            }
1195
1196            /**
1197             * Loads this keystore using the given <code>LoadStoreParameter</code>.
1198             *
1199             * <p> Note that if this KeyStore has already been loaded, it is
1200             * reinitialized and loaded again from the given parameter.
1201             *
1202             * @param param the <code>LoadStoreParameter</code>
1203             *		that specifies how to load the keystore,
1204             *		which may be <code>null</code>
1205             *
1206             * @exception IllegalArgumentException if the given
1207             *		<code>LoadStoreParameter</code>
1208             *		input is not recognized
1209             * @exception IOException if there is an I/O or format problem with the
1210             *		keystore data. If the error is due to an incorrect 
1211             *         <code>ProtectionParameter</code> (e.g. wrong password)
1212             *         the {@link Throwable#getCause cause} of the 
1213             *         <code>IOException</code> should be an 
1214             *         <code>UnrecoverableKeyException</code>
1215             * @exception NoSuchAlgorithmException if the algorithm used to check
1216             *		the integrity of the keystore cannot be found
1217             * @exception CertificateException if any of the certificates in the
1218             *		keystore could not be loaded
1219             *
1220             * @since 1.5
1221             */
1222            public final void load(LoadStoreParameter param)
1223                    throws IOException, NoSuchAlgorithmException,
1224                    CertificateException {
1225
1226                keyStoreSpi.engineLoad(param);
1227                initialized = true;
1228            }
1229
1230            /**
1231             * Gets a keystore <code>Entry</code> for the specified alias
1232             * with the specified protection parameter.
1233             *
1234             * @param alias get the keystore <code>Entry</code> for this alias
1235             * @param protParam the <code>ProtectionParameter</code>
1236             *		used to protect the <code>Entry</code>,
1237             *		which may be <code>null</code>
1238             *
1239             * @return the keystore <code>Entry</code> for the specified alias,
1240             *		or <code>null</code> if there is no such entry
1241             *
1242             * @exception NullPointerException if
1243             *		<code>alias</code> is <code>null</code>
1244             * @exception NoSuchAlgorithmException if the algorithm for recovering the
1245             *		entry cannot be found
1246             * @exception UnrecoverableEntryException if the specified
1247             *		<code>protParam</code> were insufficient or invalid
1248             * @exception UnrecoverableKeyException if the entry is a 
1249             *          <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>
1250             *          and the specified <code>protParam</code> does not contain
1251             *          the information needed to recover the key (e.g. wrong password)
1252             * @exception KeyStoreException if the keystore has not been initialized
1253             *		(loaded).
1254             * @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter)
1255             *
1256             * @since 1.5
1257             */
1258            public final Entry getEntry(String alias,
1259                    ProtectionParameter protParam)
1260                    throws NoSuchAlgorithmException,
1261                    UnrecoverableEntryException, KeyStoreException {
1262
1263                if (alias == null) {
1264                    throw new NullPointerException("invalid null input");
1265                }
1266                if (!initialized) {
1267                    throw new KeyStoreException("Uninitialized keystore");
1268                }
1269                return keyStoreSpi.engineGetEntry(alias, protParam);
1270            }
1271
1272            /**
1273             * Saves a keystore <code>Entry</code> under the specified alias.
1274             * The protection parameter is used to protect the
1275             * <code>Entry</code>.
1276             *
1277             * <p> If an entry already exists for the specified alias,
1278             * it is overridden.
1279             *
1280             * @param alias save the keystore <code>Entry</code> under this alias
1281             * @param entry the <code>Entry</code> to save
1282             * @param protParam the <code>ProtectionParameter</code>
1283             *		used to protect the <code>Entry</code>,
1284             *		which may be <code>null</code>
1285             *
1286             * @exception NullPointerException if
1287             *		<code>alias</code> or <code>entry</code>
1288             *		is <code>null</code>
1289             * @exception KeyStoreException if the keystore has not been initialized
1290             *		(loaded), or if this operation fails for some other reason
1291             *
1292             * @see #getEntry(String, KeyStore.ProtectionParameter)
1293             *
1294             * @since 1.5
1295             */
1296            public final void setEntry(String alias, Entry entry,
1297                    ProtectionParameter protParam) throws KeyStoreException {
1298                if (alias == null || entry == null) {
1299                    throw new NullPointerException("invalid null input");
1300                }
1301                if (!initialized) {
1302                    throw new KeyStoreException("Uninitialized keystore");
1303                }
1304                keyStoreSpi.engineSetEntry(alias, entry, protParam);
1305            }
1306
1307            /**
1308             * Determines if the keystore <code>Entry</code> for the specified
1309             * <code>alias</code> is an instance or subclass of the specified
1310             * <code>entryClass</code>.
1311             *
1312             * @param alias the alias name
1313             * @param entryClass the entry class 
1314             *
1315             * @return true if the keystore <code>Entry</code> for the specified
1316             *		<code>alias</code> is an instance or subclass of the
1317             *		specified <code>entryClass</code>, false otherwise
1318             *
1319             * @exception NullPointerException if
1320             *		<code>alias</code> or <code>entryClass</code>
1321             *		is <code>null</code>
1322             * @exception KeyStoreException if the keystore has not been
1323             *		initialized (loaded)
1324             *
1325             * @since 1.5
1326             */
1327            public final boolean entryInstanceOf(String alias,
1328                    Class<? extends KeyStore.Entry> entryClass)
1329                    throws KeyStoreException {
1330
1331                if (alias == null || entryClass == null) {
1332                    throw new NullPointerException("invalid null input");
1333                }
1334                if (!initialized) {
1335                    throw new KeyStoreException("Uninitialized keystore");
1336                }
1337                return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
1338            }
1339
1340            /**
1341             * A description of a to-be-instantiated KeyStore object.
1342             *
1343             * <p>An instance of this class encapsulates the information needed to
1344             * instantiate and initialize a KeyStore object. That process is
1345             * triggered when the {@linkplain #getKeyStore} method is called.
1346             *
1347             * <p>This makes it possible to decouple configuration from KeyStore
1348             * object creation and e.g. delay a password prompt until it is
1349             * needed.
1350             *
1351             * @see KeyStore
1352             * @see javax.net.ssl.KeyStoreBuilderParameters
1353             * @since 1.5
1354             */
1355            public static abstract class Builder {
1356
1357                // maximum times to try the callbackhandler if the password is wrong
1358                static final int MAX_CALLBACK_TRIES = 3;
1359
1360                /**
1361                 * Construct a new Builder.
1362                 */
1363                protected Builder() {
1364                    // empty
1365                }
1366
1367                /**
1368                 * Returns the KeyStore described by this object.
1369                 *
1370                 * @exception KeyStoreException if an error occured during the
1371                 *   operation, for example if the KeyStore could not be
1372                 *   instantiated or loaded
1373                 */
1374                public abstract KeyStore getKeyStore() throws KeyStoreException;
1375
1376                /**
1377                 * Returns the ProtectionParameters that should be used to obtain
1378                 * the {@link KeyStore.Entry Entry} with the given alias.
1379                 * The <code>getKeyStore</code> method must be invoked before this
1380                 * method may be called.
1381                 *
1382                 * @return the ProtectionParameters that should be used to obtain
1383                 *   the {@link KeyStore.Entry Entry} with the given alias.
1384                 * @param alias the alias of the KeyStore entry
1385                 * @throws NullPointerException if alias is null
1386                 * @throws KeyStoreException if an error occured during the
1387                 *   operation
1388                 * @throws IllegalStateException if the getKeyStore method has
1389                 *   not been invoked prior to calling this method
1390                 */
1391                public abstract ProtectionParameter getProtectionParameter(
1392                        String alias) throws KeyStoreException;
1393
1394                /**
1395                 * Returns a new Builder that encapsulates the given KeyStore.
1396                 * The {@linkplain #getKeyStore} method of the returned object 
1397                 * will return <code>keyStore</code>, the {@linkplain 
1398                 * #getProtectionParameter getProtectionParameter()} method will 
1399                 * return <code>protectionParameters</code>.
1400                 *
1401                 * <p> This is useful if an existing KeyStore object needs to be
1402                 * used with Builder-based APIs.
1403                 *
1404                 * @return a new Builder object
1405                 * @param keyStore the KeyStore to be encapsulated
1406                 * @param protectionParameter the ProtectionParameter used to
1407                 *   protect the KeyStore entries
1408                 * @throws NullPointerException if keyStore or
1409                 *   protectionParameters is null
1410                 * @throws IllegalArgumentException if the keyStore has not been
1411                 *   initialized
1412                 */
1413                public static Builder newInstance(final KeyStore keyStore,
1414                        final ProtectionParameter protectionParameter) {
1415                    if ((keyStore == null) || (protectionParameter == null)) {
1416                        throw new NullPointerException();
1417                    }
1418                    if (keyStore.initialized == false) {
1419                        throw new IllegalArgumentException(
1420                                "KeyStore not initialized");
1421                    }
1422                    return new Builder() {
1423                        private volatile boolean getCalled;
1424
1425                        public KeyStore getKeyStore() {
1426                            getCalled = true;
1427                            return keyStore;
1428                        }
1429
1430                        public ProtectionParameter getProtectionParameter(
1431                                String alias) {
1432                            if (alias == null) {
1433                                throw new NullPointerException();
1434                            }
1435                            if (getCalled == false) {
1436                                throw new IllegalStateException(
1437                                        "getKeyStore() must be called first");
1438                            }
1439                            return protectionParameter;
1440                        }
1441                    };
1442                }
1443
1444                /**
1445                 * Returns a new Builder object.
1446                 *
1447                 * <p>The first call to the {@link #getKeyStore} method on the returned
1448                 * builder will create a KeyStore of type <code>type</code> and call
1449                 * its {@link KeyStore#load load()} method. 
1450                 * The <code>inputStream</code> argument is constructed from
1451                 * <code>file</code>. 
1452                 * If <code>protection</code> is a
1453                 * <code>PasswordProtection</code>, the password is obtained by
1454                 * calling the <code>getPassword</code> method.
1455                 * Otherwise, if <code>protection</code> is a 
1456                 * <code>CallbackHandlerProtection</code>, the password is obtained
1457                 * by invoking the CallbackHandler.
1458                 *
1459                 * <p>Subsequent calls to {@link #getKeyStore} return the same object 
1460                 * as the initial call. If the initial call to failed with a
1461                 * KeyStoreException, subsequent calls also throw a 
1462                 * KeyStoreException.
1463                 *
1464                 * <p>The KeyStore is instantiated from <code>provider</code> if
1465                 * non-null. Otherwise, all installed providers are searched.
1466                 *
1467                 * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
1468                 * will return a {@link KeyStore.PasswordProtection PasswordProtection}
1469                 * object encapsulating the password that was used to invoke the
1470                 * <code>load</code> method.
1471                 *
1472                 * <p><em>Note</em> that the {@link #getKeyStore} method is executed 
1473                 * within the {@link AccessControlContext} of the code invoking this 
1474                 * method.
1475                 *
1476                 * @return a new Builder object
1477                 * @param type the type of KeyStore to be constructed
1478                 * @param provider the provider from which the KeyStore is to
1479                 *   be instantiated (or null)
1480                 * @param file the File that contains the KeyStore data
1481                 * @param protection the ProtectionParameter securing the KeyStore data
1482                 * @throws NullPointerException if type, file or protection is null
1483                 * @throws IllegalArgumentException if protection is not an instance
1484                 *   of either PasswordProtection or CallbackHandlerProtection; or
1485                 *   if file does not exist or does not refer to a normal file
1486                 */
1487                public static Builder newInstance(String type,
1488                        Provider provider, File file,
1489                        ProtectionParameter protection) {
1490                    if ((type == null) || (file == null)
1491                            || (protection == null)) {
1492                        throw new NullPointerException();
1493                    }
1494                    if ((protection instanceof  PasswordProtection == false)
1495                            && (protection instanceof  CallbackHandlerProtection == false)) {
1496                        throw new IllegalArgumentException(
1497                                "Protection must be PasswordProtection or "
1498                                        + "CallbackHandlerProtection");
1499                    }
1500                    if (file.isFile() == false) {
1501                        throw new IllegalArgumentException(
1502                                "File does not exist or it does not refer "
1503                                        + "to a normal file: " + file);
1504                    }
1505                    return new FileBuilder(type, provider, file, protection,
1506                            AccessController.getContext());
1507                }
1508
1509                private static final class FileBuilder extends Builder {
1510
1511                    private final String type;
1512                    private final Provider provider;
1513                    private final File file;
1514                    private ProtectionParameter protection;
1515                    private ProtectionParameter keyProtection;
1516                    private final AccessControlContext context;
1517
1518                    private KeyStore keyStore;
1519
1520                    private Throwable oldException;
1521
1522                    FileBuilder(String type, Provider provider, File file,
1523                            ProtectionParameter protection,
1524                            AccessControlContext context) {
1525                        this .type = type;
1526                        this .provider = provider;
1527                        this .file = file;
1528                        this .protection = protection;
1529                        this .context = context;
1530                    }
1531
1532                    public synchronized KeyStore getKeyStore()
1533                            throws KeyStoreException {
1534                        if (keyStore != null) {
1535                            return keyStore;
1536                        }
1537                        if (oldException != null) {
1538                            throw new KeyStoreException(
1539                                    "Previous KeyStore instantiation failed",
1540                                    oldException);
1541                        }
1542                        PrivilegedExceptionAction<KeyStore> action = new PrivilegedExceptionAction<KeyStore>() {
1543                            public KeyStore run() throws Exception {
1544                                if (protection instanceof  CallbackHandlerProtection == false) {
1545                                    return run0();
1546                                }
1547                                // when using a CallbackHandler,
1548                                // reprompt if the password is wrong
1549                                int tries = 0;
1550                                while (true) {
1551                                    tries++;
1552                                    try {
1553                                        return run0();
1554                                    } catch (IOException e) {
1555                                        if ((tries < MAX_CALLBACK_TRIES)
1556                                                && (e.getCause() instanceof  UnrecoverableKeyException)) {
1557                                            continue;
1558                                        }
1559                                        throw e;
1560                                    }
1561                                }
1562                            }
1563
1564                            public KeyStore run0() throws Exception {
1565                                KeyStore ks;
1566                                if (provider == null) {
1567                                    ks = KeyStore.getInstance(type);
1568                                } else {
1569                                    ks = KeyStore.getInstance(type, provider);
1570                                }
1571                                InputStream in = null;
1572                                char[] password = null;
1573                                try {
1574                                    in = new FileInputStream(file);
1575                                    if (protection instanceof  PasswordProtection) {
1576                                        password = ((PasswordProtection) protection)
1577                                                .getPassword();
1578                                        keyProtection = protection;
1579                                    } else {
1580                                        CallbackHandler handler = ((CallbackHandlerProtection) protection)
1581                                                .getCallbackHandler();
1582                                        PasswordCallback callback = new PasswordCallback(
1583                                                "Password for keystore "
1584                                                        + file.getName(), false);
1585                                        handler
1586                                                .handle(new Callback[] { callback });
1587                                        password = callback.getPassword();
1588                                        if (password == null) {
1589                                            throw new KeyStoreException(
1590                                                    "No password" + " provided");
1591                                        }
1592                                        callback.clearPassword();
1593                                        keyProtection = new PasswordProtection(
1594                                                password);
1595                                    }
1596                                    ks.load(in, password);
1597                                    return ks;
1598                                } finally {
1599                                    if (in != null) {
1600                                        in.close();
1601                                    }
1602                                }
1603                            }
1604                        };
1605                        try {
1606                            keyStore = AccessController.doPrivileged(action,
1607                                    context);
1608                            return keyStore;
1609                        } catch (PrivilegedActionException e) {
1610                            oldException = e.getCause();
1611                            throw new KeyStoreException(
1612                                    "KeyStore instantiation failed",
1613                                    oldException);
1614                        }
1615                    }
1616
1617                    public synchronized ProtectionParameter getProtectionParameter(
1618                            String alias) {
1619                        if (alias == null) {
1620                            throw new NullPointerException();
1621                        }
1622                        if (keyStore == null) {
1623                            throw new IllegalStateException(
1624                                    "getKeyStore() must be called first");
1625                        }
1626                        return keyProtection;
1627                    }
1628                }
1629
1630                /**
1631                 * Returns a new Builder object.
1632                 *
1633                 * <p>Each call to the {@link #getKeyStore} method on the returned
1634                 * builder will return a new KeyStore object of type <code>type</code>.
1635                 * Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()} 
1636                 * method is invoked using a
1637                 * <code>LoadStoreParameter</code> that encapsulates 
1638                 * <code>protection</code>.
1639                 *
1640                 * <p>The KeyStore is instantiated from <code>provider</code> if
1641                 * non-null. Otherwise, all installed providers are searched.
1642                 *
1643                 * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
1644                 * will return <code>protection</code>.
1645                 *
1646                 * <p><em>Note</em> that the {@link #getKeyStore} method is executed 
1647                 * within the {@link AccessControlContext} of the code invoking this 
1648                 * method.
1649                 *
1650                 * @return a new Builder object
1651                 * @param type the type of KeyStore to be constructed
1652                 * @param provider the provider from which the KeyStore is to
1653                 *   be instantiated (or null)
1654                 * @param protection the ProtectionParameter securing the Keystore
1655                 * @throws NullPointerException if type or protection is null
1656                 */
1657                public static Builder newInstance(final String type,
1658                        final Provider provider,
1659                        final ProtectionParameter protection) {
1660                    if ((type == null) || (protection == null)) {
1661                        throw new NullPointerException();
1662                    }
1663                    final AccessControlContext context = AccessController
1664                            .getContext();
1665                    return new Builder() {
1666                        private volatile boolean getCalled;
1667                        private IOException oldException;
1668
1669                        private final PrivilegedExceptionAction<KeyStore> action = new PrivilegedExceptionAction<KeyStore>() {
1670
1671                            public KeyStore run() throws Exception {
1672                                KeyStore ks;
1673                                if (provider == null) {
1674                                    ks = KeyStore.getInstance(type);
1675                                } else {
1676                                    ks = KeyStore.getInstance(type, provider);
1677                                }
1678                                LoadStoreParameter param = new SimpleLoadStoreParameter(
1679                                        protection);
1680                                if (protection instanceof  CallbackHandlerProtection == false) {
1681                                    ks.load(param);
1682                                } else {
1683                                    // when using a CallbackHandler,
1684                                    // reprompt if the password is wrong
1685                                    int tries = 0;
1686                                    while (true) {
1687                                        tries++;
1688                                        try {
1689                                            ks.load(param);
1690                                            break;
1691                                        } catch (IOException e) {
1692                                            if (e.getCause() instanceof  UnrecoverableKeyException) {
1693                                                if (tries < MAX_CALLBACK_TRIES) {
1694                                                    continue;
1695                                                } else {
1696                                                    oldException = e;
1697                                                }
1698                                            }
1699                                            throw e;
1700                                        }
1701                                    }
1702                                }
1703                                getCalled = true;
1704                                return ks;
1705                            }
1706                        };
1707
1708                        public synchronized KeyStore getKeyStore()
1709                                throws KeyStoreException {
1710                            if (oldException != null) {
1711                                throw new KeyStoreException(
1712                                        "Previous KeyStore instantiation failed",
1713                                        oldException);
1714                            }
1715                            try {
1716                                return AccessController.doPrivileged(action);
1717                            } catch (PrivilegedActionException e) {
1718                                Throwable cause = e.getCause();
1719                                throw new KeyStoreException(
1720                                        "KeyStore instantiation failed", cause);
1721                            }
1722                        }
1723
1724                        public ProtectionParameter getProtectionParameter(
1725                                String alias) {
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 protection;
1734                        }
1735                    };
1736                }
1737
1738            }
1739
1740            static class SimpleLoadStoreParameter implements  LoadStoreParameter {
1741
1742                private final ProtectionParameter protection;
1743
1744                SimpleLoadStoreParameter(ProtectionParameter protection) {
1745                    this .protection = protection;
1746                }
1747
1748                public ProtectionParameter getProtectionParameter() {
1749                    return protection;
1750                }
1751            }
1752
1753        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.