0N/A/*
3909N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.security;
0N/A
0N/Aimport java.io.*;
0N/Aimport java.security.cert.Certificate;
0N/Aimport java.security.cert.X509Certificate;
0N/Aimport java.security.cert.CertificateException;
0N/Aimport java.util.*;
0N/Aimport javax.crypto.SecretKey;
0N/A
0N/Aimport javax.security.auth.callback.*;
0N/A
0N/A/**
0N/A * This class represents a storage facility for cryptographic
0N/A * keys and certificates.
0N/A *
0N/A * <p> A <code>KeyStore</code> manages different types of entries.
0N/A * Each type of entry implements the <code>KeyStore.Entry</code> interface.
0N/A * Three basic <code>KeyStore.Entry</code> implementations are provided:
0N/A *
0N/A * <ul>
0N/A * <li><b>KeyStore.PrivateKeyEntry</b>
0N/A * <p> This type of entry holds a cryptographic <code>PrivateKey</code>,
0N/A * which is optionally stored in a protected format to prevent
0N/A * unauthorized access. It is also accompanied by a certificate chain
0N/A * for the corresponding public key.
0N/A *
0N/A * <p> Private keys and certificate chains are used by a given entity for
0N/A * self-authentication. Applications for this authentication include software
0N/A * distribution organizations which sign JAR files as part of releasing
0N/A * and/or licensing software.
0N/A *
0N/A * <li><b>KeyStore.SecretKeyEntry</b>
0N/A * <p> This type of entry holds a cryptographic <code>SecretKey</code>,
0N/A * which is optionally stored in a protected format to prevent
0N/A * unauthorized access.
0N/A *
0N/A * <li><b>KeyStore.TrustedCertificateEntry</b>
0N/A * <p> This type of entry contains a single public key <code>Certificate</code>
0N/A * belonging to another party. It is called a <i>trusted certificate</i>
0N/A * because the keystore owner trusts that the public key in the certificate
0N/A * indeed belongs to the identity identified by the <i>subject</i> (owner)
0N/A * of the certificate.
0N/A *
0N/A * <p>This type of entry can be used to authenticate other parties.
0N/A * </ul>
0N/A *
0N/A * <p> Each entry in a keystore is identified by an "alias" string. In the
0N/A * case of private keys and their associated certificate chains, these strings
0N/A * distinguish among the different ways in which the entity may authenticate
0N/A * itself. For example, the entity may authenticate itself using different
0N/A * certificate authorities, or using different public key algorithms.
0N/A *
0N/A * <p> Whether aliases are case sensitive is implementation dependent. In order
0N/A * to avoid problems, it is recommended not to use aliases in a KeyStore that
0N/A * only differ in case.
0N/A *
0N/A * <p> Whether keystores are persistent, and the mechanisms used by the
0N/A * keystore if it is persistent, are not specified here. This allows
0N/A * use of a variety of techniques for protecting sensitive (e.g., private or
0N/A * secret) keys. Smart cards or other integrated cryptographic engines
0N/A * (SafeKeyper) are one option, and simpler mechanisms such as files may also
0N/A * be used (in a variety of formats).
0N/A *
0N/A * <p> Typical ways to request a KeyStore object include
0N/A * relying on the default type and providing a specific keystore type.
0N/A *
0N/A * <ul>
0N/A * <li>To rely on the default type:
0N/A * <pre>
0N/A * KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
0N/A * </pre>
0N/A * The system will return a keystore implementation for the default type.
0N/A * <p>
0N/A *
0N/A * <li>To provide a specific keystore type:
0N/A * <pre>
0N/A * KeyStore ks = KeyStore.getInstance("JKS");
0N/A * </pre>
0N/A * The system will return the most preferred implementation of the
0N/A * specified keystore type available in the environment. <p>
0N/A * </ul>
0N/A *
0N/A * <p> Before a keystore can be accessed, it must be
0N/A * {@link #load(java.io.InputStream, char[]) loaded}.
0N/A * <pre>
0N/A * KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
0N/A *
0N/A * // get user password and file input stream
0N/A * char[] password = getPassword();
0N/A *
0N/A * java.io.FileInputStream fis = null;
0N/A * try {
0N/A * fis = new java.io.FileInputStream("keyStoreName");
0N/A * ks.load(fis, password);
0N/A * } finally {
0N/A * if (fis != null) {
0N/A * fis.close();
0N/A * }
0N/A * }
0N/A * </pre>
0N/A *
0N/A * To create an empty keystore using the above <code>load</code> method,
0N/A * pass <code>null</code> as the <code>InputStream</code> argument.
0N/A *
0N/A * <p> Once the keystore has been loaded, it is possible
0N/A * to read existing entries from the keystore, or to write new entries
0N/A * into the keystore:
0N/A * <pre>
2647N/A * KeyStore.ProtectionParameter protParam =
2647N/A * new KeyStore.PasswordProtection(password);
2647N/A *
0N/A * // get my private key
0N/A * KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
2647N/A * ks.getEntry("privateKeyAlias", protParam);
0N/A * PrivateKey myPrivateKey = pkEntry.getPrivateKey();
0N/A *
0N/A * // save my secret key
0N/A * javax.crypto.SecretKey mySecretKey;
0N/A * KeyStore.SecretKeyEntry skEntry =
0N/A * new KeyStore.SecretKeyEntry(mySecretKey);
2647N/A * ks.setEntry("secretKeyAlias", skEntry, protParam);
0N/A *
0N/A * // store away the keystore
0N/A * java.io.FileOutputStream fos = null;
0N/A * try {
0N/A * fos = new java.io.FileOutputStream("newKeyStoreName");
0N/A * ks.store(fos, password);
0N/A * } finally {
0N/A * if (fos != null) {
0N/A * fos.close();
0N/A * }
0N/A * }
0N/A * </pre>
0N/A *
0N/A * Note that although the same password may be used to
0N/A * load the keystore, to protect the private key entry,
0N/A * to protect the secret key entry, and to store the keystore
0N/A * (as is shown in the sample code above),
0N/A * different passwords or other protection parameters
0N/A * may also be used.
0N/A *
3465N/A * <p> Every implementation of the Java platform is required to support
3465N/A * the following standard <code>KeyStore</code> type:
3465N/A * <ul>
3465N/A * <li><tt>PKCS12</tt></li>
3465N/A * </ul>
3465N/A * This type is described in the <a href=
3465N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
3465N/A * KeyStore section</a> of the
3465N/A * Java Cryptography Architecture Standard Algorithm Name Documentation.
3465N/A * Consult the release documentation for your implementation to see if any
3465N/A * other types are supported.
3465N/A *
0N/A * @author Jan Luehe
0N/A *
0N/A * @see java.security.PrivateKey
0N/A * @see javax.crypto.SecretKey
0N/A * @see java.security.cert.Certificate
0N/A *
0N/A * @since 1.2
0N/A */
0N/A
0N/Apublic class KeyStore {
0N/A
0N/A /*
0N/A * Constant to lookup in the Security properties file to determine
0N/A * the default keystore type.
0N/A * In the Security properties file, the default keystore type is given as:
0N/A * <pre>
0N/A * keystore.type=jks
0N/A * </pre>
0N/A */
0N/A private static final String KEYSTORE_TYPE = "keystore.type";
0N/A
0N/A // The keystore type
0N/A private String type;
0N/A
0N/A // The provider
0N/A private Provider provider;
0N/A
0N/A // The provider implementation
0N/A private KeyStoreSpi keyStoreSpi;
0N/A
0N/A // Has this keystore been initialized (loaded)?
0N/A private boolean initialized = false;
0N/A
0N/A /**
0N/A * A marker interface for <code>KeyStore</code>
0N/A * {@link #load(KeyStore.LoadStoreParameter) load}
0N/A * and
0N/A * {@link #store(KeyStore.LoadStoreParameter) store}
0N/A * parameters.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static interface LoadStoreParameter {
0N/A /**
0N/A * Gets the parameter used to protect keystore data.
0N/A *
0N/A * @return the parameter used to protect keystore data, or null
0N/A */
0N/A public ProtectionParameter getProtectionParameter();
0N/A }
0N/A
0N/A /**
0N/A * A marker interface for keystore protection parameters.
0N/A *
0N/A * <p> The information stored in a <code>ProtectionParameter</code>
0N/A * object protects the contents of a keystore.
0N/A * For example, protection parameters may be used to check
0N/A * the integrity of keystore data, or to protect the
0N/A * confidentiality of sensitive keystore data
0N/A * (such as a <code>PrivateKey</code>).
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static interface ProtectionParameter { }
0N/A
0N/A /**
0N/A * A password-based implementation of <code>ProtectionParameter</code>.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static class PasswordProtection implements
0N/A ProtectionParameter, javax.security.auth.Destroyable {
0N/A
0N/A private final char[] password;
0N/A private volatile boolean destroyed = false;
0N/A
0N/A /**
0N/A * Creates a password parameter.
0N/A *
0N/A * <p> The specified <code>password</code> is cloned before it is stored
0N/A * in the new <code>PasswordProtection</code> object.
0N/A *
0N/A * @param password the password, which may be <code>null</code>
0N/A */
0N/A public PasswordProtection(char[] password) {
0N/A this.password = (password == null) ? null : password.clone();
0N/A }
0N/A
0N/A /**
0N/A * Gets the password.
0N/A *
0N/A * <p>Note that this method returns a reference to the password.
0N/A * If a clone of the array is created it is the caller's
0N/A * responsibility to zero out the password information
0N/A * after it is no longer needed.
0N/A *
0N/A * @see #destroy()
0N/A * @return the password, which may be <code>null</code>
0N/A * @exception IllegalStateException if the password has
0N/A * been cleared (destroyed)
0N/A */
0N/A public synchronized char[] getPassword() {
0N/A if (destroyed) {
0N/A throw new IllegalStateException("password has been cleared");
0N/A }
0N/A return password;
0N/A }
0N/A
0N/A /**
0N/A * Clears the password.
0N/A *
0N/A * @exception DestroyFailedException if this method was unable
0N/A * to clear the password
0N/A */
0N/A public synchronized void destroy()
0N/A throws javax.security.auth.DestroyFailedException {
0N/A destroyed = true;
0N/A if (password != null) {
0N/A Arrays.fill(password, ' ');
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Determines if password has been cleared.
0N/A *
0N/A * @return true if the password has been cleared, false otherwise
0N/A */
0N/A public synchronized boolean isDestroyed() {
0N/A return destroyed;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * A ProtectionParameter encapsulating a CallbackHandler.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static class CallbackHandlerProtection
0N/A implements ProtectionParameter {
0N/A
0N/A private final CallbackHandler handler;
0N/A
0N/A /**
0N/A * Constructs a new CallbackHandlerProtection from a
0N/A * CallbackHandler.
0N/A *
0N/A * @param handler the CallbackHandler
0N/A * @exception NullPointerException if handler is null
0N/A */
0N/A public CallbackHandlerProtection(CallbackHandler handler) {
0N/A if (handler == null) {
0N/A throw new NullPointerException("handler must not be null");
0N/A }
0N/A this.handler = handler;
0N/A }
0N/A
0N/A /**
0N/A * Returns the CallbackHandler.
0N/A *
0N/A * @return the CallbackHandler.
0N/A */
0N/A public CallbackHandler getCallbackHandler() {
0N/A return handler;
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * A marker interface for <code>KeyStore</code> entry types.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static interface Entry { }
0N/A
0N/A /**
0N/A * A <code>KeyStore</code> entry that holds a <code>PrivateKey</code>
0N/A * and corresponding certificate chain.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static final class PrivateKeyEntry implements Entry {
0N/A
0N/A private final PrivateKey privKey;
0N/A private final Certificate[] chain;
0N/A
0N/A /**
0N/A * Constructs a <code>PrivateKeyEntry</code> with a
0N/A * <code>PrivateKey</code> and corresponding certificate chain.
0N/A *
0N/A * <p> The specified <code>chain</code> is cloned before it is stored
0N/A * in the new <code>PrivateKeyEntry</code> object.
0N/A *
0N/A * @param privateKey the <code>PrivateKey</code>
0N/A * @param chain an array of <code>Certificate</code>s
0N/A * representing the certificate chain.
0N/A * The chain must be ordered and contain a
0N/A * <code>Certificate</code> at index 0
0N/A * corresponding to the private key.
0N/A *
0N/A * @exception NullPointerException if
0N/A * <code>privateKey</code> or <code>chain</code>
0N/A * is <code>null</code>
0N/A * @exception IllegalArgumentException if the specified chain has a
0N/A * length of 0, if the specified chain does not contain
0N/A * <code>Certificate</code>s of the same type,
0N/A * or if the <code>PrivateKey</code> algorithm
0N/A * does not match the algorithm of the <code>PublicKey</code>
0N/A * in the end entity <code>Certificate</code> (at index 0)
0N/A */
0N/A public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
0N/A if (privateKey == null || chain == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A if (chain.length == 0) {
0N/A throw new IllegalArgumentException
0N/A ("invalid zero-length input chain");
0N/A }
0N/A
0N/A Certificate[] clonedChain = chain.clone();
0N/A String certType = clonedChain[0].getType();
0N/A for (int i = 1; i < clonedChain.length; i++) {
0N/A if (!certType.equals(clonedChain[i].getType())) {
0N/A throw new IllegalArgumentException
0N/A ("chain does not contain certificates " +
0N/A "of the same type");
0N/A }
0N/A }
0N/A if (!privateKey.getAlgorithm().equals
0N/A (clonedChain[0].getPublicKey().getAlgorithm())) {
0N/A throw new IllegalArgumentException
0N/A ("private key algorithm does not match " +
0N/A "algorithm of public key in end entity " +
0N/A "certificate (at index 0)");
0N/A }
0N/A this.privKey = privateKey;
0N/A
0N/A if (clonedChain[0] instanceof X509Certificate &&
0N/A !(clonedChain instanceof X509Certificate[])) {
0N/A
0N/A this.chain = new X509Certificate[clonedChain.length];
0N/A System.arraycopy(clonedChain, 0,
0N/A this.chain, 0, clonedChain.length);
0N/A } else {
0N/A this.chain = clonedChain;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Gets the <code>PrivateKey</code> from this entry.
0N/A *
0N/A * @return the <code>PrivateKey</code> from this entry
0N/A */
0N/A public PrivateKey getPrivateKey() {
0N/A return privKey;
0N/A }
0N/A
0N/A /**
0N/A * Gets the <code>Certificate</code> chain from this entry.
0N/A *
0N/A * <p> The stored chain is cloned before being returned.
0N/A *
0N/A * @return an array of <code>Certificate</code>s corresponding
0N/A * to the certificate chain for the public key.
0N/A * If the certificates are of type X.509,
0N/A * the runtime type of the returned array is
0N/A * <code>X509Certificate[]</code>.
0N/A */
0N/A public Certificate[] getCertificateChain() {
0N/A return chain.clone();
0N/A }
0N/A
0N/A /**
0N/A * Gets the end entity <code>Certificate</code>
0N/A * from the certificate chain in this entry.
0N/A *
0N/A * @return the end entity <code>Certificate</code> (at index 0)
0N/A * from the certificate chain in this entry.
0N/A * If the certificate is of type X.509,
0N/A * the runtime type of the returned certificate is
0N/A * <code>X509Certificate</code>.
0N/A */
0N/A public Certificate getCertificate() {
0N/A return chain[0];
0N/A }
0N/A
0N/A /**
0N/A * Returns a string representation of this PrivateKeyEntry.
0N/A * @return a string representation of this PrivateKeyEntry.
0N/A */
0N/A public String toString() {
0N/A StringBuilder sb = new StringBuilder();
0N/A sb.append("Private key entry and certificate chain with "
0N/A + chain.length + " elements:\r\n");
0N/A for (Certificate cert : chain) {
0N/A sb.append(cert);
0N/A sb.append("\r\n");
0N/A }
0N/A return sb.toString();
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * A <code>KeyStore</code> entry that holds a <code>SecretKey</code>.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static final class SecretKeyEntry implements Entry {
0N/A
0N/A private final SecretKey sKey;
0N/A
0N/A /**
0N/A * Constructs a <code>SecretKeyEntry</code> with a
0N/A * <code>SecretKey</code>.
0N/A *
0N/A * @param secretKey the <code>SecretKey</code>
0N/A *
0N/A * @exception NullPointerException if <code>secretKey</code>
0N/A * is <code>null</code>
0N/A */
0N/A public SecretKeyEntry(SecretKey secretKey) {
0N/A if (secretKey == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A this.sKey = secretKey;
0N/A }
0N/A
0N/A /**
0N/A * Gets the <code>SecretKey</code> from this entry.
0N/A *
0N/A * @return the <code>SecretKey</code> from this entry
0N/A */
0N/A public SecretKey getSecretKey() {
0N/A return sKey;
0N/A }
0N/A
0N/A /**
0N/A * Returns a string representation of this SecretKeyEntry.
0N/A * @return a string representation of this SecretKeyEntry.
0N/A */
0N/A public String toString() {
0N/A return "Secret key entry with algorithm " + sKey.getAlgorithm();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * A <code>KeyStore</code> entry that holds a trusted
0N/A * <code>Certificate</code>.
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static final class TrustedCertificateEntry implements Entry {
0N/A
0N/A private final Certificate cert;
0N/A
0N/A /**
0N/A * Constructs a <code>TrustedCertificateEntry</code> with a
0N/A * trusted <code>Certificate</code>.
0N/A *
0N/A * @param trustedCert the trusted <code>Certificate</code>
0N/A *
0N/A * @exception NullPointerException if
0N/A * <code>trustedCert</code> is <code>null</code>
0N/A */
0N/A public TrustedCertificateEntry(Certificate trustedCert) {
0N/A if (trustedCert == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A this.cert = trustedCert;
0N/A }
0N/A
0N/A /**
0N/A * Gets the trusted <code>Certficate</code> from this entry.
0N/A *
0N/A * @return the trusted <code>Certificate</code> from this entry
0N/A */
0N/A public Certificate getTrustedCertificate() {
0N/A return cert;
0N/A }
0N/A
0N/A /**
0N/A * Returns a string representation of this TrustedCertificateEntry.
0N/A * @return a string representation of this TrustedCertificateEntry.
0N/A */
0N/A public String toString() {
0N/A return "Trusted certificate entry:\r\n" + cert.toString();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a KeyStore object of the given type, and encapsulates the given
0N/A * provider implementation (SPI object) in it.
0N/A *
0N/A * @param keyStoreSpi the provider implementation.
0N/A * @param provider the provider.
0N/A * @param type the keystore type.
0N/A */
0N/A protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
0N/A {
0N/A this.keyStoreSpi = keyStoreSpi;
0N/A this.provider = provider;
0N/A this.type = type;
0N/A }
0N/A
0N/A /**
0N/A * Returns a keystore object of the specified type.
0N/A *
0N/A * <p> This method traverses the list of registered security Providers,
0N/A * starting with the most preferred Provider.
0N/A * A new KeyStore object encapsulating the
0N/A * KeyStoreSpi implementation from the first
0N/A * Provider that supports the specified type is returned.
0N/A *
0N/A * <p> Note that the list of registered providers may be retrieved via
0N/A * the {@link Security#getProviders() Security.getProviders()} method.
0N/A *
0N/A * @param type the type of keystore.
3465N/A * See the KeyStore section in the <a href=
3465N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
3465N/A * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
0N/A * for information about standard keystore types.
0N/A *
0N/A * @return a keystore object of the specified type.
0N/A *
0N/A * @exception KeyStoreException if no Provider supports a
0N/A * KeyStoreSpi implementation for the
0N/A * specified type.
0N/A *
0N/A * @see Provider
0N/A */
0N/A public static KeyStore getInstance(String type)
0N/A throws KeyStoreException
0N/A {
0N/A try {
0N/A Object[] objs = Security.getImpl(type, "KeyStore", (String)null);
0N/A return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A throw new KeyStoreException(type + " not found", nsae);
0N/A } catch (NoSuchProviderException nspe) {
0N/A throw new KeyStoreException(type + " not found", nspe);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a keystore object of the specified type.
0N/A *
0N/A * <p> A new KeyStore object encapsulating the
0N/A * KeyStoreSpi implementation from the specified provider
0N/A * is returned. The specified provider must be registered
0N/A * in the security provider list.
0N/A *
0N/A * <p> Note that the list of registered providers may be retrieved via
0N/A * the {@link Security#getProviders() Security.getProviders()} method.
0N/A *
0N/A * @param type the type of keystore.
3465N/A * See the KeyStore section in the <a href=
3465N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
3465N/A * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
0N/A * for information about standard keystore types.
0N/A *
0N/A * @param provider the name of the provider.
0N/A *
0N/A * @return a keystore object of the specified type.
0N/A *
0N/A * @exception KeyStoreException if a KeyStoreSpi
0N/A * implementation for the specified type is not
0N/A * available from the specified provider.
0N/A *
0N/A * @exception NoSuchProviderException if the specified provider is not
0N/A * registered in the security provider list.
0N/A *
0N/A * @exception IllegalArgumentException if the provider name is null
0N/A * or empty.
0N/A *
0N/A * @see Provider
0N/A */
0N/A public static KeyStore getInstance(String type, String provider)
0N/A throws KeyStoreException, NoSuchProviderException
0N/A {
0N/A if (provider == null || provider.length() == 0)
0N/A throw new IllegalArgumentException("missing provider");
0N/A try {
0N/A Object[] objs = Security.getImpl(type, "KeyStore", provider);
0N/A return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A throw new KeyStoreException(type + " not found", nsae);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a keystore object of the specified type.
0N/A *
0N/A * <p> A new KeyStore object encapsulating the
0N/A * KeyStoreSpi implementation from the specified Provider
0N/A * object is returned. Note that the specified Provider object
0N/A * does not have to be registered in the provider list.
0N/A *
0N/A * @param type the type of keystore.
3465N/A * See the KeyStore section in the <a href=
3465N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyStore">
3465N/A * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
0N/A * for information about standard keystore types.
0N/A *
0N/A * @param provider the provider.
0N/A *
0N/A * @return a keystore object of the specified type.
0N/A *
0N/A * @exception KeyStoreException if KeyStoreSpi
0N/A * implementation for the specified type is not available
0N/A * from the specified Provider object.
0N/A *
0N/A * @exception IllegalArgumentException if the specified provider is null.
0N/A *
0N/A * @see Provider
0N/A *
0N/A * @since 1.4
0N/A */
0N/A public static KeyStore getInstance(String type, Provider provider)
0N/A throws KeyStoreException
0N/A {
0N/A if (provider == null)
0N/A throw new IllegalArgumentException("missing provider");
0N/A try {
0N/A Object[] objs = Security.getImpl(type, "KeyStore", provider);
0N/A return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A throw new KeyStoreException(type + " not found", nsae);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the default keystore type as specified in the Java security
0N/A * properties file, or the string
0N/A * &quot;jks&quot; (acronym for &quot;Java keystore&quot;)
0N/A * if no such property exists.
0N/A * The Java security properties file is located in the file named
0N/A * &lt;JAVA_HOME&gt;/lib/security/java.security.
0N/A * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
0N/A * and specifies the directory where the JRE is installed.
0N/A *
0N/A * <p>The default keystore type can be used by applications that do not
0N/A * want to use a hard-coded keystore type when calling one of the
0N/A * <code>getInstance</code> methods, and want to provide a default keystore
0N/A * type in case a user does not specify its own.
0N/A *
0N/A * <p>The default keystore type can be changed by setting the value of the
0N/A * "keystore.type" security property (in the Java security properties
0N/A * file) to the desired keystore type.
0N/A *
0N/A * @return the default keystore type as specified in the
0N/A * Java security properties file, or the string &quot;jks&quot;
0N/A * if no such property exists.
0N/A */
0N/A public final static String getDefaultType() {
0N/A String kstype;
0N/A kstype = AccessController.doPrivileged(new PrivilegedAction<String>() {
0N/A public String run() {
0N/A return Security.getProperty(KEYSTORE_TYPE);
0N/A }
0N/A });
0N/A if (kstype == null) {
0N/A kstype = "jks";
0N/A }
0N/A return kstype;
0N/A }
0N/A
0N/A /**
0N/A * Returns the provider of this keystore.
0N/A *
0N/A * @return the provider of this keystore.
0N/A */
0N/A public final Provider getProvider()
0N/A {
0N/A return this.provider;
0N/A }
0N/A
0N/A /**
0N/A * Returns the type of this keystore.
0N/A *
0N/A * @return the type of this keystore.
0N/A */
0N/A public final String getType()
0N/A {
0N/A return this.type;
0N/A }
0N/A
0N/A /**
0N/A * Returns the key associated with the given alias, using the given
0N/A * password to recover it. The key must have been associated with
0N/A * the alias by a call to <code>setKeyEntry</code>,
0N/A * or by a call to <code>setEntry</code> with a
0N/A * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
0N/A *
0N/A * @param alias the alias name
0N/A * @param password the password for recovering the key
0N/A *
0N/A * @return the requested key, or null if the given alias does not exist
0N/A * or does not identify a key-related entry.
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A * @exception NoSuchAlgorithmException if the algorithm for recovering the
0N/A * key cannot be found
0N/A * @exception UnrecoverableKeyException if the key cannot be recovered
0N/A * (e.g., the given password is wrong).
0N/A */
0N/A public final Key getKey(String alias, char[] password)
0N/A throws KeyStoreException, NoSuchAlgorithmException,
0N/A UnrecoverableKeyException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetKey(alias, password);
0N/A }
0N/A
0N/A /**
0N/A * Returns the certificate chain associated with the given alias.
0N/A * The certificate chain must have been associated with the alias
0N/A * by a call to <code>setKeyEntry</code>,
0N/A * or by a call to <code>setEntry</code> with a
0N/A * <code>PrivateKeyEntry</code>.
0N/A *
0N/A * @param alias the alias name
0N/A *
0N/A * @return the certificate chain (ordered with the user's certificate first
69N/A * followed by zero or more certificate authorities), or null if the given alias
0N/A * does not exist or does not contain a certificate chain
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final Certificate[] getCertificateChain(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetCertificateChain(alias);
0N/A }
0N/A
0N/A /**
0N/A * Returns the certificate associated with the given alias.
0N/A *
0N/A * <p> If the given alias name identifies an entry
0N/A * created by a call to <code>setCertificateEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>TrustedCertificateEntry</code>,
0N/A * then the trusted certificate contained in that entry is returned.
0N/A *
0N/A * <p> If the given alias name identifies an entry
0N/A * created by a call to <code>setKeyEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>PrivateKeyEntry</code>,
0N/A * then the first element of the certificate chain in that entry
0N/A * is returned.
0N/A *
0N/A * @param alias the alias name
0N/A *
0N/A * @return the certificate, or null if the given alias does not exist or
0N/A * does not contain a certificate.
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final Certificate getCertificate(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetCertificate(alias);
0N/A }
0N/A
0N/A /**
0N/A * Returns the creation date of the entry identified by the given alias.
0N/A *
0N/A * @param alias the alias name
0N/A *
0N/A * @return the creation date of this entry, or null if the given alias does
0N/A * not exist
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final Date getCreationDate(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetCreationDate(alias);
0N/A }
0N/A
0N/A /**
0N/A * Assigns the given key to the given alias, protecting it with the given
0N/A * password.
0N/A *
0N/A * <p>If the given key is of type <code>java.security.PrivateKey</code>,
0N/A * it must be accompanied by a certificate chain certifying the
0N/A * corresponding public key.
0N/A *
0N/A * <p>If the given alias already exists, the keystore information
0N/A * associated with it is overridden by the given key (and possibly
0N/A * certificate chain).
0N/A *
0N/A * @param alias the alias name
0N/A * @param key the key to be associated with the alias
0N/A * @param password the password to protect the key
0N/A * @param chain the certificate chain for the corresponding public
0N/A * key (only required if the given key is of type
0N/A * <code>java.security.PrivateKey</code>).
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded), the given key cannot be protected, or this operation fails
0N/A * for some other reason
0N/A */
0N/A public final void setKeyEntry(String alias, Key key, char[] password,
0N/A Certificate[] chain)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A if ((key instanceof PrivateKey) &&
0N/A (chain == null || chain.length == 0)) {
0N/A throw new IllegalArgumentException("Private key must be "
0N/A + "accompanied by certificate "
0N/A + "chain");
0N/A }
0N/A keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
0N/A }
0N/A
0N/A /**
0N/A * Assigns the given key (that has already been protected) to the given
0N/A * alias.
0N/A *
0N/A * <p>If the protected key is of type
0N/A * <code>java.security.PrivateKey</code>, it must be accompanied by a
0N/A * certificate chain certifying the corresponding public key. If the
0N/A * underlying keystore implementation is of type <code>jks</code>,
0N/A * <code>key</code> must be encoded as an
0N/A * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
0N/A *
0N/A * <p>If the given alias already exists, the keystore information
0N/A * associated with it is overridden by the given key (and possibly
0N/A * certificate chain).
0N/A *
0N/A * @param alias the alias name
0N/A * @param key the key (in protected format) to be associated with the alias
0N/A * @param chain the certificate chain for the corresponding public
0N/A * key (only useful if the protected key is of type
0N/A * <code>java.security.PrivateKey</code>).
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded), or if this operation fails for some other reason.
0N/A */
0N/A public final void setKeyEntry(String alias, byte[] key,
0N/A Certificate[] chain)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineSetKeyEntry(alias, key, chain);
0N/A }
0N/A
0N/A /**
0N/A * Assigns the given trusted certificate to the given alias.
0N/A *
0N/A * <p> If the given alias identifies an existing entry
0N/A * created by a call to <code>setCertificateEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>TrustedCertificateEntry</code>,
0N/A * the trusted certificate in the existing entry
0N/A * is overridden by the given certificate.
0N/A *
0N/A * @param alias the alias name
0N/A * @param cert the certificate
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized,
0N/A * or the given alias already exists and does not identify an
0N/A * entry containing a trusted certificate,
0N/A * or this operation fails for some other reason.
0N/A */
0N/A public final void setCertificateEntry(String alias, Certificate cert)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineSetCertificateEntry(alias, cert);
0N/A }
0N/A
0N/A /**
0N/A * Deletes the entry identified by the given alias from this keystore.
0N/A *
0N/A * @param alias the alias name
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized,
0N/A * or if the entry cannot be removed.
0N/A */
0N/A public final void deleteEntry(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineDeleteEntry(alias);
0N/A }
0N/A
0N/A /**
0N/A * Lists all the alias names of this keystore.
0N/A *
0N/A * @return enumeration of the alias names
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final Enumeration<String> aliases()
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineAliases();
0N/A }
0N/A
0N/A /**
0N/A * Checks if the given alias exists in this keystore.
0N/A *
0N/A * @param alias the alias name
0N/A *
0N/A * @return true if the alias exists, false otherwise
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final boolean containsAlias(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineContainsAlias(alias);
0N/A }
0N/A
0N/A /**
0N/A * Retrieves the number of entries in this keystore.
0N/A *
0N/A * @return the number of entries in this keystore
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final int size()
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineSize();
0N/A }
0N/A
0N/A /**
0N/A * Returns true if the entry identified by the given alias
0N/A * was created by a call to <code>setKeyEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
0N/A *
0N/A * @param alias the alias for the keystore entry to be checked
0N/A *
0N/A * @return true if the entry identified by the given alias is a
0N/A * key-related entry, false otherwise.
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final boolean isKeyEntry(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineIsKeyEntry(alias);
0N/A }
0N/A
0N/A /**
0N/A * Returns true if the entry identified by the given alias
0N/A * was created by a call to <code>setCertificateEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>TrustedCertificateEntry</code>.
0N/A *
0N/A * @param alias the alias for the keystore entry to be checked
0N/A *
0N/A * @return true if the entry identified by the given alias contains a
0N/A * trusted certificate, false otherwise.
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final boolean isCertificateEntry(String alias)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineIsCertificateEntry(alias);
0N/A }
0N/A
0N/A /**
0N/A * Returns the (alias) name of the first keystore entry whose certificate
0N/A * matches the given certificate.
0N/A *
0N/A * <p> This method attempts to match the given certificate with each
0N/A * keystore entry. If the entry being considered was
0N/A * created by a call to <code>setCertificateEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>TrustedCertificateEntry</code>,
0N/A * then the given certificate is compared to that entry's certificate.
0N/A *
0N/A * <p> If the entry being considered was
0N/A * created by a call to <code>setKeyEntry</code>,
0N/A * or created by a call to <code>setEntry</code> with a
0N/A * <code>PrivateKeyEntry</code>,
0N/A * then the given certificate is compared to the first
0N/A * element of that entry's certificate chain.
0N/A *
0N/A * @param cert the certificate to match with.
0N/A *
0N/A * @return the alias name of the first entry with a matching certificate,
0N/A * or null if no such entry exists in this keystore.
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A */
0N/A public final String getCertificateAlias(Certificate cert)
0N/A throws KeyStoreException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetCertificateAlias(cert);
0N/A }
0N/A
0N/A /**
0N/A * Stores this keystore to the given output stream, and protects its
0N/A * integrity with the given password.
0N/A *
0N/A * @param stream the output stream to which this keystore is written.
0N/A * @param password the password to generate the keystore integrity check
0N/A *
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A * @exception IOException if there was an I/O problem with data
0N/A * @exception NoSuchAlgorithmException if the appropriate data integrity
0N/A * algorithm could not be found
0N/A * @exception CertificateException if any of the certificates included in
0N/A * the keystore data could not be stored
0N/A */
0N/A public final void store(OutputStream stream, char[] password)
0N/A throws KeyStoreException, IOException, NoSuchAlgorithmException,
0N/A CertificateException
0N/A {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineStore(stream, password);
0N/A }
0N/A
0N/A /**
0N/A * Stores this keystore using the given <code>LoadStoreParameter</code>.
0N/A *
0N/A * @param param the <code>LoadStoreParameter</code>
0N/A * that specifies how to store the keystore,
0N/A * which may be <code>null</code>
0N/A *
0N/A * @exception IllegalArgumentException if the given
0N/A * <code>LoadStoreParameter</code>
0N/A * input is not recognized
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded)
0N/A * @exception IOException if there was an I/O problem with data
0N/A * @exception NoSuchAlgorithmException if the appropriate data integrity
0N/A * algorithm could not be found
0N/A * @exception CertificateException if any of the certificates included in
0N/A * the keystore data could not be stored
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public final void store(LoadStoreParameter param)
0N/A throws KeyStoreException, IOException,
0N/A NoSuchAlgorithmException, CertificateException {
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineStore(param);
0N/A }
0N/A
0N/A /**
0N/A * Loads this KeyStore from the given input stream.
0N/A *
0N/A * <p>A password may be given to unlock the keystore
0N/A * (e.g. the keystore resides on a hardware token device),
0N/A * or to check the integrity of the keystore data.
0N/A * If a password is not given for integrity checking,
0N/A * then integrity checking is not performed.
0N/A *
0N/A * <p>In order to create an empty keystore, or if the keystore cannot
0N/A * be initialized from a stream, pass <code>null</code>
0N/A * as the <code>stream</code> argument.
0N/A *
0N/A * <p> Note that if this keystore has already been loaded, it is
0N/A * reinitialized and loaded again from the given input stream.
0N/A *
0N/A * @param stream the input stream from which the keystore is loaded,
0N/A * or <code>null</code>
0N/A * @param password the password used to check the integrity of
0N/A * the keystore, the password used to unlock the keystore,
0N/A * or <code>null</code>
0N/A *
0N/A * @exception IOException if there is an I/O or format problem with the
0N/A * keystore data, if a password is required but not given,
0N/A * or if the given password was incorrect. If the error is due to a
0N/A * wrong password, the {@link Throwable#getCause cause} of the
0N/A * <code>IOException</code> should be an
0N/A * <code>UnrecoverableKeyException</code>
0N/A * @exception NoSuchAlgorithmException if the algorithm used to check
0N/A * the integrity of the keystore cannot be found
0N/A * @exception CertificateException if any of the certificates in the
0N/A * keystore could not be loaded
0N/A */
0N/A public final void load(InputStream stream, char[] password)
0N/A throws IOException, NoSuchAlgorithmException, CertificateException
0N/A {
0N/A keyStoreSpi.engineLoad(stream, password);
0N/A initialized = true;
0N/A }
0N/A
0N/A /**
0N/A * Loads this keystore using the given <code>LoadStoreParameter</code>.
0N/A *
0N/A * <p> Note that if this KeyStore has already been loaded, it is
0N/A * reinitialized and loaded again from the given parameter.
0N/A *
0N/A * @param param the <code>LoadStoreParameter</code>
0N/A * that specifies how to load the keystore,
0N/A * which may be <code>null</code>
0N/A *
0N/A * @exception IllegalArgumentException if the given
0N/A * <code>LoadStoreParameter</code>
0N/A * input is not recognized
0N/A * @exception IOException if there is an I/O or format problem with the
0N/A * keystore data. If the error is due to an incorrect
0N/A * <code>ProtectionParameter</code> (e.g. wrong password)
0N/A * the {@link Throwable#getCause cause} of the
0N/A * <code>IOException</code> should be an
0N/A * <code>UnrecoverableKeyException</code>
0N/A * @exception NoSuchAlgorithmException if the algorithm used to check
0N/A * the integrity of the keystore cannot be found
0N/A * @exception CertificateException if any of the certificates in the
0N/A * keystore could not be loaded
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public final void load(LoadStoreParameter param)
0N/A throws IOException, NoSuchAlgorithmException,
0N/A CertificateException {
0N/A
0N/A keyStoreSpi.engineLoad(param);
0N/A initialized = true;
0N/A }
0N/A
0N/A /**
0N/A * Gets a keystore <code>Entry</code> for the specified alias
0N/A * with the specified protection parameter.
0N/A *
0N/A * @param alias get the keystore <code>Entry</code> for this alias
0N/A * @param protParam the <code>ProtectionParameter</code>
0N/A * used to protect the <code>Entry</code>,
0N/A * which may be <code>null</code>
0N/A *
0N/A * @return the keystore <code>Entry</code> for the specified alias,
0N/A * or <code>null</code> if there is no such entry
0N/A *
0N/A * @exception NullPointerException if
0N/A * <code>alias</code> is <code>null</code>
0N/A * @exception NoSuchAlgorithmException if the algorithm for recovering the
0N/A * entry cannot be found
0N/A * @exception UnrecoverableEntryException if the specified
0N/A * <code>protParam</code> were insufficient or invalid
0N/A * @exception UnrecoverableKeyException if the entry is a
0N/A * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>
0N/A * and the specified <code>protParam</code> does not contain
0N/A * the information needed to recover the key (e.g. wrong password)
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded).
0N/A * @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public final Entry getEntry(String alias, ProtectionParameter protParam)
0N/A throws NoSuchAlgorithmException, UnrecoverableEntryException,
0N/A KeyStoreException {
0N/A
0N/A if (alias == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineGetEntry(alias, protParam);
0N/A }
0N/A
0N/A /**
0N/A * Saves a keystore <code>Entry</code> under the specified alias.
0N/A * The protection parameter is used to protect the
0N/A * <code>Entry</code>.
0N/A *
0N/A * <p> If an entry already exists for the specified alias,
0N/A * it is overridden.
0N/A *
0N/A * @param alias save the keystore <code>Entry</code> under this alias
0N/A * @param entry the <code>Entry</code> to save
0N/A * @param protParam the <code>ProtectionParameter</code>
0N/A * used to protect the <code>Entry</code>,
0N/A * which may be <code>null</code>
0N/A *
0N/A * @exception NullPointerException if
0N/A * <code>alias</code> or <code>entry</code>
0N/A * is <code>null</code>
0N/A * @exception KeyStoreException if the keystore has not been initialized
0N/A * (loaded), or if this operation fails for some other reason
0N/A *
0N/A * @see #getEntry(String, KeyStore.ProtectionParameter)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public final void setEntry(String alias, Entry entry,
0N/A ProtectionParameter protParam)
0N/A throws KeyStoreException {
0N/A if (alias == null || entry == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A keyStoreSpi.engineSetEntry(alias, entry, protParam);
0N/A }
0N/A
0N/A /**
0N/A * Determines if the keystore <code>Entry</code> for the specified
0N/A * <code>alias</code> is an instance or subclass of the specified
0N/A * <code>entryClass</code>.
0N/A *
0N/A * @param alias the alias name
0N/A * @param entryClass the entry class
0N/A *
0N/A * @return true if the keystore <code>Entry</code> for the specified
0N/A * <code>alias</code> is an instance or subclass of the
0N/A * specified <code>entryClass</code>, false otherwise
0N/A *
0N/A * @exception NullPointerException if
0N/A * <code>alias</code> or <code>entryClass</code>
0N/A * is <code>null</code>
0N/A * @exception KeyStoreException if the keystore has not been
0N/A * initialized (loaded)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public final boolean
0N/A entryInstanceOf(String alias,
0N/A Class<? extends KeyStore.Entry> entryClass)
0N/A throws KeyStoreException
0N/A {
0N/A
0N/A if (alias == null || entryClass == null) {
0N/A throw new NullPointerException("invalid null input");
0N/A }
0N/A if (!initialized) {
0N/A throw new KeyStoreException("Uninitialized keystore");
0N/A }
0N/A return keyStoreSpi.engineEntryInstanceOf(alias, entryClass);
0N/A }
0N/A
0N/A /**
0N/A * A description of a to-be-instantiated KeyStore object.
0N/A *
0N/A * <p>An instance of this class encapsulates the information needed to
0N/A * instantiate and initialize a KeyStore object. That process is
0N/A * triggered when the {@linkplain #getKeyStore} method is called.
0N/A *
0N/A * <p>This makes it possible to decouple configuration from KeyStore
0N/A * object creation and e.g. delay a password prompt until it is
0N/A * needed.
0N/A *
0N/A * @see KeyStore
0N/A * @see javax.net.ssl.KeyStoreBuilderParameters
0N/A * @since 1.5
0N/A */
0N/A public static abstract class Builder {
0N/A
0N/A // maximum times to try the callbackhandler if the password is wrong
0N/A static final int MAX_CALLBACK_TRIES = 3;
0N/A
0N/A /**
0N/A * Construct a new Builder.
0N/A */
0N/A protected Builder() {
0N/A // empty
0N/A }
0N/A
0N/A /**
0N/A * Returns the KeyStore described by this object.
0N/A *
0N/A * @exception KeyStoreException if an error occured during the
0N/A * operation, for example if the KeyStore could not be
0N/A * instantiated or loaded
0N/A */
0N/A public abstract KeyStore getKeyStore() throws KeyStoreException;
0N/A
0N/A /**
0N/A * Returns the ProtectionParameters that should be used to obtain
0N/A * the {@link KeyStore.Entry Entry} with the given alias.
0N/A * The <code>getKeyStore</code> method must be invoked before this
0N/A * method may be called.
0N/A *
0N/A * @return the ProtectionParameters that should be used to obtain
0N/A * the {@link KeyStore.Entry Entry} with the given alias.
0N/A * @param alias the alias of the KeyStore entry
0N/A * @throws NullPointerException if alias is null
0N/A * @throws KeyStoreException if an error occured during the
0N/A * operation
0N/A * @throws IllegalStateException if the getKeyStore method has
0N/A * not been invoked prior to calling this method
0N/A */
0N/A public abstract ProtectionParameter getProtectionParameter(String alias)
0N/A throws KeyStoreException;
0N/A
0N/A /**
0N/A * Returns a new Builder that encapsulates the given KeyStore.
0N/A * The {@linkplain #getKeyStore} method of the returned object
0N/A * will return <code>keyStore</code>, the {@linkplain
0N/A * #getProtectionParameter getProtectionParameter()} method will
0N/A * return <code>protectionParameters</code>.
0N/A *
0N/A * <p> This is useful if an existing KeyStore object needs to be
0N/A * used with Builder-based APIs.
0N/A *
0N/A * @return a new Builder object
0N/A * @param keyStore the KeyStore to be encapsulated
0N/A * @param protectionParameter the ProtectionParameter used to
0N/A * protect the KeyStore entries
0N/A * @throws NullPointerException if keyStore or
0N/A * protectionParameters is null
0N/A * @throws IllegalArgumentException if the keyStore has not been
0N/A * initialized
0N/A */
0N/A public static Builder newInstance(final KeyStore keyStore,
0N/A final ProtectionParameter protectionParameter) {
0N/A if ((keyStore == null) || (protectionParameter == null)) {
0N/A throw new NullPointerException();
0N/A }
0N/A if (keyStore.initialized == false) {
0N/A throw new IllegalArgumentException("KeyStore not initialized");
0N/A }
0N/A return new Builder() {
0N/A private volatile boolean getCalled;
0N/A
0N/A public KeyStore getKeyStore() {
0N/A getCalled = true;
0N/A return keyStore;
0N/A }
0N/A
0N/A public ProtectionParameter getProtectionParameter(String alias)
0N/A {
0N/A if (alias == null) {
0N/A throw new NullPointerException();
0N/A }
0N/A if (getCalled == false) {
0N/A throw new IllegalStateException
0N/A ("getKeyStore() must be called first");
0N/A }
0N/A return protectionParameter;
0N/A }
0N/A };
0N/A }
0N/A
0N/A /**
0N/A * Returns a new Builder object.
0N/A *
0N/A * <p>The first call to the {@link #getKeyStore} method on the returned
0N/A * builder will create a KeyStore of type <code>type</code> and call
0N/A * its {@link KeyStore#load load()} method.
0N/A * The <code>inputStream</code> argument is constructed from
0N/A * <code>file</code>.
0N/A * If <code>protection</code> is a
0N/A * <code>PasswordProtection</code>, the password is obtained by
0N/A * calling the <code>getPassword</code> method.
0N/A * Otherwise, if <code>protection</code> is a
0N/A * <code>CallbackHandlerProtection</code>, the password is obtained
0N/A * by invoking the CallbackHandler.
0N/A *
0N/A * <p>Subsequent calls to {@link #getKeyStore} return the same object
0N/A * as the initial call. If the initial call to failed with a
0N/A * KeyStoreException, subsequent calls also throw a
0N/A * KeyStoreException.
0N/A *
0N/A * <p>The KeyStore is instantiated from <code>provider</code> if
0N/A * non-null. Otherwise, all installed providers are searched.
0N/A *
0N/A * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
0N/A * will return a {@link KeyStore.PasswordProtection PasswordProtection}
0N/A * object encapsulating the password that was used to invoke the
0N/A * <code>load</code> method.
0N/A *
0N/A * <p><em>Note</em> that the {@link #getKeyStore} method is executed
0N/A * within the {@link AccessControlContext} of the code invoking this
0N/A * method.
0N/A *
0N/A * @return a new Builder object
0N/A * @param type the type of KeyStore to be constructed
0N/A * @param provider the provider from which the KeyStore is to
0N/A * be instantiated (or null)
0N/A * @param file the File that contains the KeyStore data
0N/A * @param protection the ProtectionParameter securing the KeyStore data
0N/A * @throws NullPointerException if type, file or protection is null
0N/A * @throws IllegalArgumentException if protection is not an instance
0N/A * of either PasswordProtection or CallbackHandlerProtection; or
0N/A * if file does not exist or does not refer to a normal file
0N/A */
0N/A public static Builder newInstance(String type, Provider provider,
0N/A File file, ProtectionParameter protection) {
0N/A if ((type == null) || (file == null) || (protection == null)) {
0N/A throw new NullPointerException();
0N/A }
0N/A if ((protection instanceof PasswordProtection == false) &&
0N/A (protection instanceof CallbackHandlerProtection == false)) {
0N/A throw new IllegalArgumentException
0N/A ("Protection must be PasswordProtection or " +
0N/A "CallbackHandlerProtection");
0N/A }
0N/A if (file.isFile() == false) {
0N/A throw new IllegalArgumentException
0N/A ("File does not exist or it does not refer " +
0N/A "to a normal file: " + file);
0N/A }
0N/A return new FileBuilder(type, provider, file, protection,
0N/A AccessController.getContext());
0N/A }
0N/A
0N/A private static final class FileBuilder extends Builder {
0N/A
0N/A private final String type;
0N/A private final Provider provider;
0N/A private final File file;
0N/A private ProtectionParameter protection;
0N/A private ProtectionParameter keyProtection;
0N/A private final AccessControlContext context;
0N/A
0N/A private KeyStore keyStore;
0N/A
0N/A private Throwable oldException;
0N/A
0N/A FileBuilder(String type, Provider provider, File file,
0N/A ProtectionParameter protection,
0N/A AccessControlContext context) {
0N/A this.type = type;
0N/A this.provider = provider;
0N/A this.file = file;
0N/A this.protection = protection;
0N/A this.context = context;
0N/A }
0N/A
0N/A public synchronized KeyStore getKeyStore() throws KeyStoreException
0N/A {
0N/A if (keyStore != null) {
0N/A return keyStore;
0N/A }
0N/A if (oldException != null) {
0N/A throw new KeyStoreException
0N/A ("Previous KeyStore instantiation failed",
0N/A oldException);
0N/A }
0N/A PrivilegedExceptionAction<KeyStore> action =
0N/A new PrivilegedExceptionAction<KeyStore>() {
0N/A public KeyStore run() throws Exception {
0N/A if (protection instanceof CallbackHandlerProtection == false) {
0N/A return run0();
0N/A }
0N/A // when using a CallbackHandler,
0N/A // reprompt if the password is wrong
0N/A int tries = 0;
0N/A while (true) {
0N/A tries++;
0N/A try {
0N/A return run0();
0N/A } catch (IOException e) {
0N/A if ((tries < MAX_CALLBACK_TRIES)
0N/A && (e.getCause() instanceof UnrecoverableKeyException)) {
0N/A continue;
0N/A }
0N/A throw e;
0N/A }
0N/A }
0N/A }
0N/A public KeyStore run0() throws Exception {
0N/A KeyStore ks;
0N/A if (provider == null) {
0N/A ks = KeyStore.getInstance(type);
0N/A } else {
0N/A ks = KeyStore.getInstance(type, provider);
0N/A }
0N/A InputStream in = null;
0N/A char[] password = null;
0N/A try {
0N/A in = new FileInputStream(file);
0N/A if (protection instanceof PasswordProtection) {
0N/A password =
0N/A ((PasswordProtection)protection).getPassword();
0N/A keyProtection = protection;
0N/A } else {
0N/A CallbackHandler handler =
0N/A ((CallbackHandlerProtection)protection)
0N/A .getCallbackHandler();
0N/A PasswordCallback callback = new PasswordCallback
0N/A ("Password for keystore " + file.getName(),
0N/A false);
0N/A handler.handle(new Callback[] {callback});
0N/A password = callback.getPassword();
0N/A if (password == null) {
0N/A throw new KeyStoreException("No password" +
0N/A " provided");
0N/A }
0N/A callback.clearPassword();
0N/A keyProtection = new PasswordProtection(password);
0N/A }
0N/A ks.load(in, password);
0N/A return ks;
0N/A } finally {
0N/A if (in != null) {
0N/A in.close();
0N/A }
0N/A }
0N/A }
0N/A };
0N/A try {
0N/A keyStore = AccessController.doPrivileged(action, context);
0N/A return keyStore;
0N/A } catch (PrivilegedActionException e) {
0N/A oldException = e.getCause();
0N/A throw new KeyStoreException
0N/A ("KeyStore instantiation failed", oldException);
0N/A }
0N/A }
0N/A
0N/A public synchronized ProtectionParameter
0N/A getProtectionParameter(String alias) {
0N/A if (alias == null) {
0N/A throw new NullPointerException();
0N/A }
0N/A if (keyStore == null) {
0N/A throw new IllegalStateException
0N/A ("getKeyStore() must be called first");
0N/A }
0N/A return keyProtection;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a new Builder object.
0N/A *
0N/A * <p>Each call to the {@link #getKeyStore} method on the returned
0N/A * builder will return a new KeyStore object of type <code>type</code>.
0N/A * Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()}
0N/A * method is invoked using a
0N/A * <code>LoadStoreParameter</code> that encapsulates
0N/A * <code>protection</code>.
0N/A *
0N/A * <p>The KeyStore is instantiated from <code>provider</code> if
0N/A * non-null. Otherwise, all installed providers are searched.
0N/A *
0N/A * <p>Calls to {@link #getProtectionParameter getProtectionParameter()}
0N/A * will return <code>protection</code>.
0N/A *
0N/A * <p><em>Note</em> that the {@link #getKeyStore} method is executed
0N/A * within the {@link AccessControlContext} of the code invoking this
0N/A * method.
0N/A *
0N/A * @return a new Builder object
0N/A * @param type the type of KeyStore to be constructed
0N/A * @param provider the provider from which the KeyStore is to
0N/A * be instantiated (or null)
0N/A * @param protection the ProtectionParameter securing the Keystore
0N/A * @throws NullPointerException if type or protection is null
0N/A */
0N/A public static Builder newInstance(final String type,
0N/A final Provider provider, final ProtectionParameter protection) {
0N/A if ((type == null) || (protection == null)) {
0N/A throw new NullPointerException();
0N/A }
0N/A final AccessControlContext context = AccessController.getContext();
0N/A return new Builder() {
0N/A private volatile boolean getCalled;
0N/A private IOException oldException;
0N/A
0N/A private final PrivilegedExceptionAction<KeyStore> action
0N/A = new PrivilegedExceptionAction<KeyStore>() {
0N/A
0N/A public KeyStore run() throws Exception {
0N/A KeyStore ks;
0N/A if (provider == null) {
0N/A ks = KeyStore.getInstance(type);
0N/A } else {
0N/A ks = KeyStore.getInstance(type, provider);
0N/A }
0N/A LoadStoreParameter param = new SimpleLoadStoreParameter(protection);
0N/A if (protection instanceof CallbackHandlerProtection == false) {
0N/A ks.load(param);
0N/A } else {
0N/A // when using a CallbackHandler,
0N/A // reprompt if the password is wrong
0N/A int tries = 0;
0N/A while (true) {
0N/A tries++;
0N/A try {
0N/A ks.load(param);
0N/A break;
0N/A } catch (IOException e) {
0N/A if (e.getCause() instanceof UnrecoverableKeyException) {
0N/A if (tries < MAX_CALLBACK_TRIES) {
0N/A continue;
0N/A } else {
0N/A oldException = e;
0N/A }
0N/A }
0N/A throw e;
0N/A }
0N/A }
0N/A }
0N/A getCalled = true;
0N/A return ks;
0N/A }
0N/A };
0N/A
0N/A public synchronized KeyStore getKeyStore()
0N/A throws KeyStoreException {
0N/A if (oldException != null) {
0N/A throw new KeyStoreException
0N/A ("Previous KeyStore instantiation failed",
0N/A oldException);
0N/A }
0N/A try {
6294N/A return AccessController.doPrivileged(action, context);
0N/A } catch (PrivilegedActionException e) {
0N/A Throwable cause = e.getCause();
0N/A throw new KeyStoreException
0N/A ("KeyStore instantiation failed", cause);
0N/A }
0N/A }
0N/A
0N/A public ProtectionParameter getProtectionParameter(String alias)
0N/A {
0N/A if (alias == null) {
0N/A throw new NullPointerException();
0N/A }
0N/A if (getCalled == false) {
0N/A throw new IllegalStateException
0N/A ("getKeyStore() must be called first");
0N/A }
0N/A return protection;
0N/A }
0N/A };
0N/A }
0N/A
0N/A }
0N/A
0N/A static class SimpleLoadStoreParameter implements LoadStoreParameter {
0N/A
0N/A private final ProtectionParameter protection;
0N/A
0N/A SimpleLoadStoreParameter(ProtectionParameter protection) {
0N/A this.protection = protection;
0N/A }
0N/A
0N/A public ProtectionParameter getProtectionParameter() {
0N/A return protection;
0N/A }
0N/A }
0N/A
0N/A}