/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import javax.crypto.SecretKey;
import javax.security.auth.DestroyFailedException;
import javax.security.auth.Destroyable;
import javax.security.auth.callback.CallbackHandler;
import libcore.io.IoUtils;
import org.apache.harmony.security.fortress.Engine;

/**
 * {@code KeyStore} is responsible for maintaining cryptographic keys and their
 * owners.
 * <p>
 * The type of the system key store can be changed by setting the {@code
 * 'keystore.type'} property in the file named {@code
 * JAVA_HOME/lib/security/java.security}.
 *
 * @see Certificate
 * @see PrivateKey
 */
public class KeyStore {

    // Store KeyStore SERVICE name
    private static final String SERVICE = "KeyStore";

    // Used to access common engine functionality
    private static final Engine ENGINE = new Engine(SERVICE);

    //  Store KeyStore property name
    private static final String PROPERTY_NAME = "keystore.type";

    //  Store default KeyStore type
    private static final String DEFAULT_KEYSTORE_TYPE = "jks";

    // Store KeyStore state (initialized or not)
    private boolean isInit;

    // Store used KeyStoreSpi
    private final KeyStoreSpi implSpi;

    // Store used provider
    private final Provider provider;

    // Store used type
    private final String type;

    /**
     * Constructs a new instance of {@code KeyStore} with the given arguments.
     *
     * @param keyStoreSpi
     *            the concrete key store.
     * @param provider
     *            the provider.
     * @param type
     *            the type of the {@code KeyStore} to be constructed.
     */
    protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type) {
        this.type = type;
        this.provider = provider;
        this.implSpi = keyStoreSpi;
        isInit = false;
    }

    /**
     * Throws the standard "keystore not initialized" exception.
     */
    private static void throwNotInitialized() throws KeyStoreException {
        throw new KeyStoreException("KeyStore was not initialized");
    }

    /**
     * Returns a new instance of {@code KeyStore} with the specified type.
     *
     * @param type
     *            the type of the returned {@code KeyStore}.
     * @return a new instance of {@code KeyStore} with the specified type.
     * @throws KeyStoreException
     *             if an error occurred during the creation of the new {@code
     *             KeyStore}.
     * @throws NullPointerException if {@code type == null}
     * @see #getDefaultType
     */
    public static KeyStore getInstance(String type) throws KeyStoreException {
        if (type == null) {
            throw new NullPointerException("type == null");
        }
        try {
            Engine.SpiAndProvider sap = ENGINE.getInstance(type, null);
            return new KeyStore((KeyStoreSpi) sap.spi, sap.provider, type);
        } catch (NoSuchAlgorithmException e) {
            throw new KeyStoreException(e);
        }
    }

    /**
     * Returns a new instance of {@code KeyStore} from the specified provider
     * with the given type.
     *
     * @param type
     *            the type of the returned {@code KeyStore}.
     * @param provider
     *            name of the provider of the {@code KeyStore}.
     * @return a new instance of {@code KeyStore} from the specified provider
     *         with the given type.
     * @throws KeyStoreException
     *             if an error occurred during the creation of the new {@code
     *             KeyStore}.
     * @throws NoSuchProviderException
     *             if the specified provider is not available.
     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
     * @throws NullPointerException
     *             if {@code type} is {@code null} (instead of
     *             NoSuchAlgorithmException) as in 1.4 release
     * @see #getDefaultType
     */
    public static KeyStore getInstance(String type, String provider)
            throws KeyStoreException, NoSuchProviderException {
        if (provider == null || provider.isEmpty()) {
            throw new IllegalArgumentException();
        }
        Provider impProvider = Security.getProvider(provider);
        if (impProvider == null) {
            throw new NoSuchProviderException(provider);
        }
        try {
            return getInstance(type, impProvider);
        } catch (Exception e) {
            throw new KeyStoreException(e);
        }
    }

    /**
     * Returns a new instance of {@code KeyStore} from the specified provider
     * with the given type.
     *
     * @param type
     *            the type of the returned {@code KeyStore}.
     * @param provider
     *            the provider of the {@code KeyStore}.
     * @return a new instance of {@code KeyStore} from the specified provider
     *         with the given type.
     * @throws KeyStoreException
     *             if an error occurred during the creation of the new {@code
     *             KeyStore}.
     * @throws IllegalArgumentException
     *             if {@code provider} is {@code null} or the empty string.
     * @throws NullPointerException if {@code type == null} (instead of
     *             NoSuchAlgorithmException) as in 1.4 release
     * @see #getDefaultType
     */
    public static KeyStore getInstance(String type, Provider provider) throws KeyStoreException {
        // check parameters
        if (provider == null) {
            throw new IllegalArgumentException("provider == null");
        }
        if (type == null) {
            throw new NullPointerException("type == null");
        }
        // return KeyStore instance
        try {
            Object spi = ENGINE.getInstance(type, provider, null);
            return new KeyStore((KeyStoreSpi) spi, provider, type);
        } catch (Exception e) {
            // override exception
            throw new KeyStoreException(e);
        }
    }

    /**
     * Returns the default type for {@code KeyStore} instances.
     *
     * <p>The default is specified in the {@code 'keystore.type'} property in the
     * file named {@code java.security} properties file. If this property
     * is not set, {@code "jks"} will be used.
     *
     * @return the default type for {@code KeyStore} instances
     */
    public static final String getDefaultType() {
        String dt = Security.getProperty(PROPERTY_NAME);
        return (dt == null ? DEFAULT_KEYSTORE_TYPE : dt);
    }

    /**
     * Returns the provider associated with this {@code KeyStore}.
     *
     * @return the provider associated with this {@code KeyStore}.
     */
    public final Provider getProvider() {
        return provider;
    }

    /**
     * Returns the type of this {@code KeyStore}.
     *
     * @return the type of this {@code KeyStore}.
     */
    public final String getType() {
        return type;
    }

    /**
     * Returns the key with the given alias, using the password to recover the
     * key from the store.
     *
     * @param alias
     *            the alias for the entry.
     * @param password
     *            the password used to recover the key.
     * @return the key with the specified alias, or {@code null} if the
     *         specified alias is not bound to an entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws NoSuchAlgorithmException
     *             if the algorithm for recovering the key is not available.
     * @throws UnrecoverableKeyException
     *             if the key can not be recovered.
     */
    public final Key getKey(String alias, char[] password)
            throws KeyStoreException, NoSuchAlgorithmException,
            UnrecoverableKeyException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetKey(alias, password);
    }

    /**
     * Returns the certificate chain for the entry with the given alias.
     *
     * @param alias
     *            the alias for the entry.
     * @return the certificate chain for the entry with the given alias, or
     *         {@code null} if the specified alias is not bound to an entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final Certificate[] getCertificateChain(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetCertificateChain(alias);
    }

    /**
     * Returns the trusted certificate for the entry with the given alias.
     *
     * @param alias
     *            the alias for the entry.
     * @return the trusted certificate for the entry with the given alias, or
     *         {@code null} if the specified alias is not bound to an entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final Certificate getCertificate(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetCertificate(alias);
    }

    /**
     * Returns the creation date of the entry with the given alias.
     *
     * @param alias
     *            the alias for the entry.
     * @return the creation date, or {@code null} if the specified alias is not
     *         bound to an entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final Date getCreationDate(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetCreationDate(alias);
    }

    /**
     * Associates the given alias with the key, password and certificate chain.
     * <p>
     * If the specified alias already exists, it will be reassigned.
     *
     * @param alias
     *            the alias for the key.
     * @param key
     *            the key.
     * @param password
     *            the password.
     * @param chain
     *            the certificate chain.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws IllegalArgumentException
     *             if {@code key} is a {@code PrivateKey} and {@code chain} does
     *             not contain any certificates.
     * @throws NullPointerException
     *             if {@code alias} is {@code null}.
     */
    public final void setKeyEntry(String alias, Key key, char[] password,
            Certificate[] chain) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }

        // Certificate chain is required for PrivateKey
        if (key != null && key instanceof PrivateKey && (chain == null || chain.length == 0)) {
            throw new IllegalArgumentException("Certificate chain is not defined for Private key");
        }
        implSpi.engineSetKeyEntry(alias, key, password, chain);
    }

    /**
     * Associates the given alias with a key and a certificate chain.
     * <p>
     * If the specified alias already exists, it will be reassigned.
     * <p>
     * If this {@code KeyStore} is of type {@code "jks"}, {@code key} must be
     * encoded conform to the PKS#8 standard as an
     * {@link javax.crypto.EncryptedPrivateKeyInfo}.
     *
     * @param alias
     *            the alias for the key.
     * @param key
     *            the key in an encoded format.
     * @param chain
     *            the certificate chain.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized or if {@code key}
     *             is null.
     * @throws IllegalArgumentException
     *             if {@code key} is a {@code PrivateKey} and {@code chain}
     *             does.
     * @throws NullPointerException
     *             if {@code alias} is {@code null}.
     */
    public final void setKeyEntry(String alias, byte[] key, Certificate[] chain)
            throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        implSpi.engineSetKeyEntry(alias, key, chain);
    }

    /**
     * Associates the given alias with a certificate.
     * <p>
     * If the specified alias already exists, it will be reassigned.
     *
     * @param alias
     *            the alias for the certificate.
     * @param cert
     *            the certificate.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized, or an existing
     *             alias is not associated to an entry containing a trusted
     *             certificate, or this method fails for any other reason.
     * @throws NullPointerException
     *             if {@code alias} is {@code null}.
     */
    public final void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        implSpi.engineSetCertificateEntry(alias, cert);
    }

    /**
     * Deletes the entry identified with the given alias from this {@code
     * KeyStore}.
     *
     * @param alias
     *            the alias for the entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized, or if the entry
     *             can not be deleted.
     */
    public final void deleteEntry(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        implSpi.engineDeleteEntry(alias);
    }

    /**
     * Returns an {@code Enumeration} over all alias names stored in this
     * {@code KeyStore}.
     *
     * @return an {@code Enumeration} over all alias names stored in this
     *         {@code KeyStore}.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final Enumeration<String> aliases() throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineAliases();
    }

    /**
     * Indicates whether the given alias is present in this {@code KeyStore}.
     *
     * @param alias
     *            the alias of an entry.
     * @return {@code true} if the alias exists, {@code false} otherwise.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final boolean containsAlias(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineContainsAlias(alias);
    }

    /**
     * Returns the number of entries stored in this {@code KeyStore}.
     *
     * @return the number of entries stored in this {@code KeyStore}.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final int size() throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineSize();
    }

    /**
     * Indicates whether the specified alias is associated with either a
     * {@link PrivateKeyEntry} or a {@link SecretKeyEntry}.
     *
     * @param alias
     *            the alias of an entry.
     * @return {@code true} if the given alias is associated with a key entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final boolean isKeyEntry(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineIsKeyEntry(alias);
    }

    /**
     * Indicates whether the specified alias is associated with a
     * {@link TrustedCertificateEntry}.
     *
     * @param alias
     *            the alias of an entry.
     * @return {@code true} if the given alias is associated with a certificate
     *         entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final boolean isCertificateEntry(String alias) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineIsCertificateEntry(alias);
    }

    /**
     * Returns the alias associated with the first entry whose certificate
     * matches the specified certificate.
     *
     * @param cert
     *            the certificate to find the associated entry's alias for.
     * @return the alias or {@code null} if no entry with the specified
     *         certificate can be found.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final String getCertificateAlias(Certificate cert) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetCertificateAlias(cert);
    }

    /**
     * Writes this {@code KeyStore} to the specified {@code OutputStream}. The
     * data written to the {@code OutputStream} is protected by the specified
     * password.
     *
     * @param stream
     *            the {@code OutputStream} to write the store's data to.
     * @param password
     *            the password to protect the data.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws IOException
     *             if a problem occurred while writing to the stream.
     * @throws NoSuchAlgorithmException
     *             if the required algorithm is not available.
     * @throws CertificateException
     *             if an exception occurred while storing the certificates of
     *             this {@code KeyStore}.
     */
    public final void store(OutputStream stream, char[] password)
            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        if (!isInit) {
            throwNotInitialized();
        }

        //Just delegate stream and password to implSpi
        implSpi.engineStore(stream, password);
    }

    /**
     * Stores this {@code KeyStore} using the specified {@code
     * LoadStoreParameter}.
     *
     * @param param
     *            the {@code LoadStoreParameter} that specifies how to store
     *            this {@code KeyStore}, maybe {@code null}.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws IOException
     *             if a problem occurred while writing to the stream.
     * @throws NoSuchAlgorithmException
     *             if the required algorithm is not available.
     * @throws CertificateException
     *             if an exception occurred while storing the certificates of
     *             this {@code KeyStore}.
     * @throws IllegalArgumentException
     *             if the given {@link LoadStoreParameter} is not recognized.
     */
    public final void store(LoadStoreParameter param) throws KeyStoreException,
            IOException, NoSuchAlgorithmException, CertificateException {
        if (!isInit) {
            throwNotInitialized();
        }
        implSpi.engineStore(param);
    }

    /**
     * Initializes this {@code KeyStore} from the provided {@code InputStream}.
     * Pass {@code null} as the {@code stream} argument to initialize an empty
     * {@code KeyStore} or to initialize a {@code KeyStore} which does not rely
     * on an {@code InputStream}. This {@code KeyStore} utilizes the given
     * password to verify the stored data.
     *
     * @param stream
     *            the {@code InputStream} to load this {@code KeyStore}'s data
     *            from or {@code null}.
     * @param password
     *            the password to verify the stored data, maybe {@code null}.
     * @throws IOException
     *             if a problem occurred while reading from the stream.
     * @throws NoSuchAlgorithmException
     *             if the required algorithm is not available.
     * @throws CertificateException
     *             if an exception occurred while loading the certificates of
     *             this {@code KeyStore}.
     */
    public final void load(InputStream stream, char[] password)
            throws IOException, NoSuchAlgorithmException, CertificateException {
        implSpi.engineLoad(stream, password);
        isInit = true;
    }

    /**
     * Loads this {@code KeyStore} using the specified {@code
     * LoadStoreParameter}.
     *
     * @param param
     *            the {@code LoadStoreParameter} that specifies how to load this
     *            {@code KeyStore}, maybe {@code null}.
     * @throws IOException
     *             if a problem occurred while reading from the stream.
     * @throws NoSuchAlgorithmException
     *             if the required algorithm is not available.
     * @throws CertificateException
     *             if an exception occurred while loading the certificates of
     *             this {@code KeyStore}.
     * @throws IllegalArgumentException
     *             if the given {@link LoadStoreParameter} is not recognized.
     */
    public final void load(LoadStoreParameter param) throws IOException,
            NoSuchAlgorithmException, CertificateException {
        implSpi.engineLoad(param);
        isInit = true;
    }

    /**
     * Returns the {@code Entry} with the given alias, using the specified
     * {@code ProtectionParameter}.
     *
     * @param alias
     *            the alias of the requested entry.
     * @param param
     *            the {@code ProtectionParameter} used to protect the requested
     *            entry, maybe {@code null}.
     * @return he {@code Entry} with the given alias, using the specified
     *         {@code ProtectionParameter}.
     * @throws NoSuchAlgorithmException
     *             if the required algorithm is not available.
     * @throws UnrecoverableEntryException
     *             if the entry can not be recovered.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws NullPointerException
     *             if {@code alias} is {@code null}.
     */
    public final Entry getEntry(String alias, ProtectionParameter param)
            throws NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }
        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineGetEntry(alias, param);
    }

    /**
     * Stores the given {@code Entry} in this {@code KeyStore} and associates
     * the entry with the given {@code alias}. The entry is protected by the
     * specified {@code ProtectionParameter}.
     * <p>
     * If the specified alias already exists, it will be reassigned.
     *
     * @param alias
     *            the alias for the entry.
     * @param entry
     *            the entry to store.
     * @param param
     *            the {@code ProtectionParameter} to protect the entry.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     * @throws NullPointerException
     *             if {@code alias} is {@code null} or {@code entry} is {@code
     *             null}.
     */
    public final void setEntry(String alias, Entry entry,
            ProtectionParameter param) throws KeyStoreException {
        if (!isInit) {
            throwNotInitialized();
        }
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }
        if (entry == null) {
            throw new NullPointerException("entry == null");
        }
        implSpi.engineSetEntry(alias, entry, param);
    }

    /**
     * Indicates whether the entry for the given alias is assignable to the
     * provided {@code Class}.
     *
     * @param alias
     *            the alias for the entry.
     * @param entryClass
     *            the type of the entry.
     * @return {@code true} if the {@code Entry} for the alias is assignable to
     *         the specified {@code entryClass}.
     * @throws KeyStoreException
     *             if this {@code KeyStore} is not initialized.
     */
    public final boolean entryInstanceOf(String alias,
            Class<? extends KeyStore.Entry> entryClass)
            throws KeyStoreException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }
        if (entryClass == null) {
            throw new NullPointerException("entryClass == null");
        }

        if (!isInit) {
            throwNotInitialized();
        }
        return implSpi.engineEntryInstanceOf(alias, entryClass);
    }

    /**
     * {@code Builder} is used to construct new instances of {@code KeyStore}.
     */
    public abstract static class Builder {
        /**
         * Constructs a new instance of {@code Builder}.
         */
        protected Builder() {
        }

        /**
         * Returns the {@code KeyStore} created by this {@code Builder}.
         *
         * @return the {@code KeyStore} created by this {@code Builder}.
         * @throws KeyStoreException
         *             if an error occurred during construction.
         */
        public abstract KeyStore getKeyStore() throws KeyStoreException;

        /**
         * Returns the {@code ProtectionParameter} to be used when a {@code
         * Entry} with the specified alias is requested. Before this method is
         * invoked, {@link #getKeyStore()} must be called.
         *
         * @param alias
         *            the alias for the entry.
         * @return the {@code ProtectionParameter} to be used when a {@code
         *         Entry} with the specified alias is requested.
         * @throws KeyStoreException
         *             if an error occurred during the lookup for the protection
         *             parameter.
         * @throws IllegalStateException
         *             if {@link #getKeyStore()} is not called prior the
         *             invocation of this method.
         * @throws NullPointerException
         *             if {@code alias} is {@code null}.
         */
        public abstract ProtectionParameter getProtectionParameter(String alias)
                throws KeyStoreException;

        /**
         * Returns a new {@code Builder} that holds the given {@code KeyStore}
         * and the given {@code ProtectionParameter}.
         *
         * @param keyStore
         *            the {@code KeyStore} to be held.
         * @param protectionParameter
         *            the {@code ProtectionParameter} to be held.
         * @return a new instance of {@code Builder} that holds the specified
         *         {@code KeyStore} and the specified {@code
         *         ProtectionParameter}.
         * @throws NullPointerException
         *             if {@code keyStore} or {@code protectionParameter} is
         *             {@code null}.
         * @throws IllegalArgumentException
         *             if the given {@code KeyStore} is not initialized.
         */
        public static Builder newInstance(KeyStore keyStore,
                ProtectionParameter protectionParameter) {
            if (keyStore == null) {
                throw new NullPointerException("keyStore == null");
            }
            if (protectionParameter == null) {
                throw new NullPointerException("protectionParameter == null");
            }
            if (!keyStore.isInit) {
                throw new IllegalArgumentException("KeyStore was not initialized");
            }
            return new BuilderImpl(keyStore, protectionParameter, null, null, null);
        }

        /**
         * Returns a new {@code Builder} that creates a new {@code KeyStore}
         * based on the provided arguments.
         * <p>
         * If {@code provider} is {@code null}, all installed providers are
         * searched, otherwise the key store from the specified provider is
         * used.
         *
         * @param type
         *            the type of the {@code KeyStore} to be constructed.
         * @param provider
         *            the provider of the {@code KeyStore} to be constructed,
         *            maybe {@code null}.
         * @param file
         *            the {@code File} that contains the data for the {@code
         *            KeyStore}.
         * @param protectionParameter
         *            the {@code ProtectionParameter} used to protect the stored
         *            keys.
         * @return a new {@code Builder} that creates a new {@code KeyStore}
         *         based on the provided arguments.
         * @throws NullPointerException
         *             if {@code type, protectionParameter} or {@code file} is
         *             {@code null}.
         * @throws IllegalArgumentException
         *             {@code protectionParameter} not an instance of either
         *             {@code PasswordProtection} or {@code
         *             CallbackHandlerProtection}, {@code file} is not a file or
         *             does not exist at all.
         */
        public static Builder newInstance(String type, Provider provider,
                File file, ProtectionParameter protectionParameter) {
            // check null parameters
            if (type == null) {
                throw new NullPointerException("type == null");
            }
            if (protectionParameter == null) {
                throw new NullPointerException("protectionParameter == null");
            }
            if (file == null) {
                throw new NullPointerException("file == null");
            }
            // protection parameter should be PasswordProtection or
            // CallbackHandlerProtection
            if (!(protectionParameter instanceof PasswordProtection)
                    && !(protectionParameter instanceof CallbackHandlerProtection)) {
                throw new IllegalArgumentException("protectionParameter is neither "
                        + "PasswordProtection nor CallbackHandlerProtection instance");
            }
            // check file parameter
            if (!file.exists()) {
                throw new IllegalArgumentException("File does not exist: " + file.getName());
            }
            if (!file.isFile()) {
                throw new IllegalArgumentException("Not a regular file: " + file.getName());
            }
            // create new instance
            return new BuilderImpl(null, protectionParameter, file, type, provider);
        }

        /**
         * Returns a new {@code Builder} that creates a new {@code KeyStore}
         * based on the provided arguments.
         * <p>
         * If {@code provider} is {@code null}, all installed providers are
         * searched, otherwise the key store from the specified provider is
         * used.
         *
         * @param type
         *            the type of the {@code KeyStore} to be constructed.
         * @param provider
         *            the provider of the {@code KeyStore} to be constructed,
         *            maybe {@code null}.
         * @param protectionParameter
         *            the {@code ProtectionParameter} used to protect the stored
         *            keys.
         * @return a new {@code Builder} that creates a new {@code KeyStore}
         *         based on the provided arguments.
         * @throws NullPointerException
         *             if {@code type} or {@code protectionParameter} is {@code
         *             null}.
         * @throws IllegalArgumentException
         *             {@code protectionParameter} not an instance of either
         *             {@code PasswordProtection} or {@code
         *             CallbackHandlerProtection}, {@code file} is not a file or
         *             does not exist at all.
         */
        public static Builder newInstance(String type, Provider provider,
                ProtectionParameter protectionParameter) {
            if (type == null) {
                throw new NullPointerException("type == null");
            }
            if (protectionParameter == null) {
                throw new NullPointerException("protectionParameter == null");
            }
            return new BuilderImpl(null, protectionParameter, null, type, provider);
        }

        /*
         * This class is implementation of abstract class KeyStore.Builder
         *
         * @author Vera Petrashkova
         *
         */
        private static class BuilderImpl extends Builder {
            // Store used KeyStore
            private KeyStore keyStore;

            // Store used ProtectionParameter
            private ProtectionParameter protParameter;

            // Store used KeyStore type
            private final String typeForKeyStore;

            // Store used KeyStore provider
            private final Provider providerForKeyStore;

            // Store used file for KeyStore loading
            private final File fileForLoad;

            // Store getKeyStore method was invoked or not for KeyStoreBuilder
            private boolean isGetKeyStore = false;

            // Store last Exception in getKeyStore()
            private KeyStoreException lastException;

            /**
             * Constructor BuilderImpl initializes private fields: keyStore,
             * protParameter, typeForKeyStore providerForKeyStore fileForLoad,
             * isGetKeyStore
             */
            BuilderImpl(KeyStore ks, ProtectionParameter pp, File file,
                        String type, Provider provider) {
                keyStore = ks;
                protParameter = pp;
                fileForLoad = file;
                typeForKeyStore = type;
                providerForKeyStore = provider;
                isGetKeyStore = false;
                lastException = null;
            }

            /**
             * Implementation of abstract getKeyStore() method If
             * KeyStoreBuilder encapsulates KeyStore object then this object is
             * returned
             *
             * If KeyStoreBuilder encapsulates KeyStore type and provider then
             * KeyStore is created using these parameters. If KeyStoreBuilder
             * encapsulates file and ProtectionParameter then KeyStore data are
             * loaded from FileInputStream that is created on file. If file is
             * not defined then KeyStore object is initialized with null
             * InputStream and null password.
             *
             * Result KeyStore object is returned.
             */
            @Override
            public synchronized KeyStore getKeyStore() throws KeyStoreException {
                // If KeyStore was created but in final block some exception was
                // thrown
                // then it was stored in lastException variable and will be
                // thrown
                // all subsequent calls of this method.
                if (lastException != null) {
                    throw lastException;
                }
                if (keyStore != null) {
                    isGetKeyStore = true;
                    return keyStore;
                }

                try {
                    // get KeyStore instance using type or type and provider
                    final KeyStore ks = (providerForKeyStore == null ? KeyStore
                            .getInstance(typeForKeyStore) : KeyStore
                            .getInstance(typeForKeyStore, providerForKeyStore));
                    // protection parameter should be PasswordProtection
                    // or CallbackHandlerProtection
                    final char[] passwd;
                    if (protParameter instanceof PasswordProtection) {
                        passwd = ((PasswordProtection) protParameter)
                                .getPassword();
                    } else if (protParameter instanceof CallbackHandlerProtection) {
                        passwd = KeyStoreSpi
                                .getPasswordFromCallBack(protParameter);
                    } else {
                        throw new KeyStoreException("protectionParameter is neither "
                                + "PasswordProtection nor CallbackHandlerProtection instance");
                    }

                    // load KeyStore from file
                    if (fileForLoad != null) {
                        FileInputStream fis = null;
                        try {
                            fis = new FileInputStream(fileForLoad);
                            ks.load(fis, passwd);
                        } finally {
                            IoUtils.closeQuietly(fis);
                        }
                    } else {
                        ks.load(new TmpLSParameter(protParameter));
                    }

                    isGetKeyStore = true;
                    return ks;
                } catch (KeyStoreException e) {
                    // Store exception
                    throw lastException = e;
                } catch (Exception e) {
                    // Override exception
                    throw lastException = new KeyStoreException(e);
                }
            }

            /**
             * This is implementation of abstract method
             * getProtectionParameter(String alias)
             *
             * Return: ProtectionParameter to get Entry which was saved in
             * KeyStore with defined alias
             */
            @Override
            public synchronized ProtectionParameter getProtectionParameter(
                    String alias) throws KeyStoreException {
                if (alias == null) {
                    throw new NullPointerException("alias == null");
                }
                if (!isGetKeyStore) {
                    throw new IllegalStateException("getKeyStore() was not invoked");
                }
                return protParameter;
            }
        }

        /*
         * Implementation of LoadStoreParameter interface
         */
        private static class TmpLSParameter implements LoadStoreParameter {

            // Store used protection parameter
            private final ProtectionParameter protPar;

            /**
             * Creates TmpLoadStoreParameter object
             * @param protPar protection parameter
             */
            public TmpLSParameter(ProtectionParameter protPar) {
                this.protPar = protPar;
            }

            /**
             * This method returns protection parameter
             */
            public ProtectionParameter getProtectionParameter() {
                return protPar;
            }
        }
    }

    /**
     * {@code CallbackHandlerProtection} is a {@code ProtectionParameter} that
     * encapsulates a {@link CallbackHandler}.
     */
    public static class CallbackHandlerProtection implements
            ProtectionParameter {
        // Store CallbackHandler
        private final CallbackHandler callbackHandler;

        /**
         * Constructs a new instance of {@code CallbackHandlerProtection} with
         * the {@code CallbackHandler}.
         *
         * @param handler
         *            the {@code CallbackHandler}.
         * @throws NullPointerException
         *             if {@code handler} is {@code null}.
         */
        public CallbackHandlerProtection(CallbackHandler handler) {
            if (handler == null) {
                throw new NullPointerException("handler == null");
            }
            this.callbackHandler = handler;
        }

        /**
         * Returns the {@code CallbackHandler}.
         *
         * @return the {@code CallbackHandler}.
         */
        public CallbackHandler getCallbackHandler() {
            return callbackHandler;
        }
    }

    /**
     * {@code Entry} is the common marker interface for a {@code KeyStore}
     * entry.
     */
    public static interface Entry {
    }

    /**
     * {@code LoadStoreParameter} represents a parameter that specifies how a
     * {@code KeyStore} can be loaded and stored.
     *
     * @see KeyStore#load(LoadStoreParameter)
     * @see KeyStore#store(LoadStoreParameter)
     */
    public static interface LoadStoreParameter {
        /**
         * Returns the {@code ProtectionParameter} which is used to protect data
         * in the {@code KeyStore}.
         *
         * @return the {@code ProtectionParameter} which is used to protect data
         *         in the {@code KeyStore}, maybe {@code null}.
         */
        public ProtectionParameter getProtectionParameter();
    }

    /**
     * {@code PasswordProtection} is a {@code ProtectionParameter} that protects
     * a {@code KeyStore} using a password.
     */
    public static class PasswordProtection implements ProtectionParameter,
            Destroyable {

        // Store password
        private char[] password;

        private boolean isDestroyed = false;

        /**
         * Constructs a new instance of {@code PasswordProtection} with a
         * password. A copy of the password is stored in the new {@code
         * PasswordProtection} object.
         *
         * @param password
         *            the password, maybe {@code null}.
         */
        public PasswordProtection(char[] password) {
            if (password != null) {
                this.password = password.clone();
            }
        }

        /**
         * Returns the password.
         *
         * @return the password.
         * @throws IllegalStateException
         *             if the password has been destroyed.
         */
        public synchronized char[] getPassword() {
            if (isDestroyed) {
                throw new IllegalStateException("Password was destroyed");
            }
            return password;
        }

        /**
         * Destroys / invalidates the password.
         *
         * @throws DestroyFailedException
         *             if the password could not be invalidated.
         */
        public synchronized void destroy() throws DestroyFailedException {
            isDestroyed = true;
            if (password != null) {
                Arrays.fill(password, '\u0000');
                password = null;
            }
        }

        /**
         * Indicates whether the password is invalidated.
         *
         * @return {@code true} if the password is invalidated, {@code false}
         *         otherwise.
         */
        public synchronized boolean isDestroyed() {
            return isDestroyed;
        }
    }

    /**
     * {@code ProtectionParameter} is a marker interface for protection
     * parameters. A protection parameter is used to protect the content of a
     * {@code KeyStore}.
     */
    public static interface ProtectionParameter {
    }

    /**
     * {@code PrivateKeyEntry} represents a {@code KeyStore} entry that
     * holds a private key.
     */
    public static final class PrivateKeyEntry implements Entry {
        // Store Certificate chain
        private Certificate[] chain;

        // Store PrivateKey
        private PrivateKey privateKey;

        /**
         * Constructs a new instance of {@code PrivateKeyEntry} with the given
         * {@code PrivateKey} and the provided certificate chain.
         *
         * @param privateKey
         *            the private key.
         * @param chain
         *            the ordered certificate chain with the certificate
         *            corresponding to the private key at index 0.
         * @throws NullPointerException
         *             if {@code privateKey} or {@code chain} is {@code null}.
         * @throws IllegalArgumentException
         *             if {@code chain.length == 0}, the algorithm of the
         *             private key does not match the algorithm of the public
         *             key of the first certificate or the certificates are not
         *             all of the same type.
         */
        public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
            if (privateKey == null) {
                throw new NullPointerException("privateKey == null");
            }
            if (chain == null) {
                throw new NullPointerException("chain == null");
            }

            if (chain.length == 0) {
                throw new IllegalArgumentException("chain.length == 0");
            }
            // Match algorithm of private key and algorithm of public key from
            // the end certificate
            String s = chain[0].getType();
            if (!(chain[0].getPublicKey().getAlgorithm()).equals(privateKey.getAlgorithm())) {
                throw new IllegalArgumentException("Algorithm of private key does not match "
                        + "algorithm of public key in end certificate of entry "
                        + "(with index number: 0)");
            }
            // Match certificate types
            for (int i = 1; i < chain.length; i++) {
                if (!s.equals(chain[i].getType())) {
                    throw new IllegalArgumentException("Certificates from the given chain have "
                                                       + "different types");
                }
            }
            // clone chain - this.chain = (Certificate[])chain.clone();
            boolean isAllX509Certificates = true;
            // assert chain length > 0
            for (Certificate cert: chain) {
                if (!(cert instanceof X509Certificate)) {
                    isAllX509Certificates = false;
                    break;
                }
            }

            if(isAllX509Certificates){
                this.chain = new X509Certificate[chain.length];
            } else {
                this.chain = new Certificate[chain.length];
            }
            System.arraycopy(chain, 0, this.chain, 0, chain.length);
            this.privateKey = privateKey;
        }

        /**
         * Returns the private key.
         *
         * @return the private key.
         */
        public PrivateKey getPrivateKey() {
            return privateKey;
        }

        /**
         * Returns the certificate chain.
         *
         * @return the certificate chain.
         */
        public Certificate[] getCertificateChain() {
            return chain.clone();
        }

        /**
         * Returns the certificate corresponding to the private key.
         *
         * @return the certificate corresponding to the private key.
         */
        public Certificate getCertificate() {
            return chain[0];
        }

        /**
         * Returns a string containing a concise, human-readable description of
         * this {@code PrivateKeyEntry}.
         *
         * @return a printable representation for this {@code PrivateKeyEntry}.
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(
                    "PrivateKeyEntry: number of elements in certificate chain is ");
            sb.append(Integer.toString(chain.length));
            sb.append("\n");
            for (int i = 0; i < chain.length; i++) {
                sb.append(chain[i].toString());
                sb.append("\n");
            }
            return sb.toString();
        }
    }

    /**
     * {@code SecretKeyEntry} represents a {@code KeyStore} entry that
     * holds a secret key.
     */
    public static final class SecretKeyEntry implements Entry {

        // Store SecretKey
        private final SecretKey secretKey;

        /**
         * Constructs a new instance of {@code SecretKeyEntry} with the given
         * {@code SecretKey}.
         *
         * @param secretKey
         *            the secret key.
         * @throws NullPointerException
         *             if {@code secretKey} is {@code null}.
         */
        public SecretKeyEntry(SecretKey secretKey) {
            if (secretKey == null) {
                throw new NullPointerException("secretKey == null");
            }
            this.secretKey = secretKey;
        }

        /**
         * Returns the secret key.
         *
         * @return the secret key.
         */
        public SecretKey getSecretKey() {
            return secretKey;
        }

        /**
         * Returns a string containing a concise, human-readable description of
         * this {@code SecretKeyEntry}.
         *
         * @return a printable representation for this {@code
         *         SecretKeyEntry}.
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder("SecretKeyEntry: algorithm - ");
            sb.append(secretKey.getAlgorithm());
            return sb.toString();
        }
    }

    /**
     * {@code TrustedCertificateEntry} represents a {@code KeyStore} entry that
     * holds a trusted certificate.
     */
    public static final class TrustedCertificateEntry implements Entry {

        // Store trusted Certificate
        private final Certificate trustCertificate;

        /**
         * Constructs a new instance of {@code TrustedCertificateEntry} with the
         * given {@code Certificate}.
         *
         * @param trustCertificate
         *            the trusted certificate.
         * @throws NullPointerException
         *             if {@code trustCertificate} is {@code null}.
         */
        public TrustedCertificateEntry(Certificate trustCertificate) {
            if (trustCertificate == null) {
                throw new NullPointerException("trustCertificate == null");
            }
            this.trustCertificate = trustCertificate;
        }

        /**
         * Returns the trusted certificate.
         *
         * @return the trusted certificate.
         */
        public Certificate getTrustedCertificate() {
            return trustCertificate;
        }

        /**
         * Returns a string containing a concise, human-readable description of
         * this {@code TrustedCertificateEntry}.
         *
         * @return a printable representation for this {@code
         *         TrustedCertificateEntry}.
         */
        @Override
        public String toString() {
            return "Trusted certificate entry:\n" + trustCertificate;
        }
    }
}
