1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.File;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileInputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.Certificate;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException;
272f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughesimport java.security.cert.X509Certificate;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Date;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.crypto.SecretKey;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.DestroyFailedException;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.Destroyable;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.callback.CallbackHandler;
35a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilsonimport libcore.io.IoUtils;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code KeyStore} is responsible for maintaining cryptographic keys and their
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * owners.
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>
422f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * The type of the system key store can be changed by setting the {@code
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 'keystore.type'} property in the file named {@code
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JAVA_HOME/lib/security/java.security}.
452f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes *
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Certificate
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see PrivateKey
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class KeyStore {
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store KeyStore SERVICE name
52f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private static final String SERVICE = "KeyStore";
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Used to access common engine functionality
550a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom    private static final Engine ENGINE = new Engine(SERVICE);
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //  Store KeyStore property name
58c934a095e1f863f00bf6f7c0b37fbd05ebeaaff5Brian Carlstrom    private static final String PROPERTY_NAME = "keystore.type";
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //  Store default KeyStore type
61f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private static final String DEFAULT_KEYSTORE_TYPE = "jks";
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store KeyStore state (initialized or not)
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isInit;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used KeyStoreSpi
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final KeyStoreSpi implSpi;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used provider
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Provider provider;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used type
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final String type;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code KeyStore} with the given arguments.
772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keyStoreSpi
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the concrete key store.
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider.
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the {@code KeyStore} to be constructed.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type) {
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.type = type;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.provider = provider;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.implSpi = keyStoreSpi;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInit = false;
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Throws the standard "keystore not initialized" exception.
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void throwNotInitialized() throws KeyStoreException {
96897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes        throw new KeyStoreException("KeyStore was not initialized");
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code KeyStore} with the specified type.
1012f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the returned {@code KeyStore}.
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code KeyStore} with the specified type.
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurred during the creation of the new {@code
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             KeyStore}.
108897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws NullPointerException if {@code type == null}
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getDefaultType
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static KeyStore getInstance(String type) throws KeyStoreException {
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (type == null) {
113d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root            throw new NullPointerException("type == null");
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1156cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        try {
1166cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom            Engine.SpiAndProvider sap = ENGINE.getInstance(type, null);
1176cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom            return new KeyStore((KeyStoreSpi) sap.spi, sap.provider, type);
1186cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        } catch (NoSuchAlgorithmException e) {
119347b2a604114602da9bc4ae040278f74d11c2f51Brian Carlstrom            throw new KeyStoreException(e);
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code KeyStore} from the specified provider
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with the given type.
1262f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the returned {@code KeyStore}.
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            name of the provider of the {@code KeyStore}.
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code KeyStore} from the specified provider
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         with the given type.
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurred during the creation of the new {@code
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             KeyStore}.
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchProviderException
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified provider is not available.
138897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
1392f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
1402f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code type} is {@code null} (instead of
1412f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             NoSuchAlgorithmException) as in 1.4 release
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getDefaultType
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static KeyStore getInstance(String type, String provider)
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws KeyStoreException, NoSuchProviderException {
146897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes        if (provider == null || provider.isEmpty()) {
147897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider impProvider = Security.getProvider(provider);
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (impProvider == null) {
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NoSuchProviderException(provider);
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getInstance(type, impProvider);
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (Exception e) {
156347b2a604114602da9bc4ae040278f74d11c2f51Brian Carlstrom            throw new KeyStoreException(e);
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code KeyStore} from the specified provider
1620a64887ae9127d081fc6e312ba1f06f727453800Kenny Root     * with the given type. The {@code provider} supplied does not have to be
1630a64887ae9127d081fc6e312ba1f06f727453800Kenny Root     * registered.
1642f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the returned {@code KeyStore}.
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider of the {@code KeyStore}.
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code KeyStore} from the specified provider
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         with the given type.
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurred during the creation of the new {@code
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             KeyStore}.
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code provider} is {@code null} or the empty string.
176897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws NullPointerException if {@code type == null} (instead of
1772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             NoSuchAlgorithmException) as in 1.4 release
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getDefaultType
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
180ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes    public static KeyStore getInstance(String type, Provider provider) throws KeyStoreException {
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // check parameters
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (provider == null) {
183cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            throw new IllegalArgumentException("provider == null");
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (type == null) {
186d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root            throw new NullPointerException("type == null");
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // return KeyStore instance
1896cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        try {
1906cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom            Object spi = ENGINE.getInstance(type, provider, null);
1916cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom            return new KeyStore((KeyStoreSpi) spi, provider, type);
1926cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        } catch (Exception e) {
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // override exception
194347b2a604114602da9bc4ae040278f74d11c2f51Brian Carlstrom            throw new KeyStoreException(e);
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the default type for {@code KeyStore} instances.
200ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes     *
201ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes     * <p>The default is specified in the {@code 'keystore.type'} property in the
202ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes     * file named {@code java.security} properties file. If this property
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is not set, {@code "jks"} will be used.
2042f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the default type for {@code KeyStore} instances
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final String getDefaultType() {
208c934a095e1f863f00bf6f7c0b37fbd05ebeaaff5Brian Carlstrom        String dt = Security.getProperty(PROPERTY_NAME);
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (dt == null ? DEFAULT_KEYSTORE_TYPE : dt);
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the provider associated with this {@code KeyStore}.
2142f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the provider associated with this {@code KeyStore}.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Provider getProvider() {
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return provider;
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the type of this {@code KeyStore}.
2232f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the type of this {@code KeyStore}.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getType() {
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return type;
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the key with the given alias, using the password to recover the
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * key from the store.
2332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param password
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the password used to recover the key.
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the key with the specified alias, or {@code null} if the
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified alias is not bound to an entry.
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the algorithm for recovering the key is not available.
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnrecoverableKeyException
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the key can not be recovered.
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Key getKey(String alias, char[] password)
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws KeyStoreException, NoSuchAlgorithmException,
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            UnrecoverableKeyException {
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetKey(alias, password);
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the certificate chain for the entry with the given alias.
2582f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the certificate chain for the entry with the given alias, or
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if the specified alias is not bound to an entry.
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
266fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes    public final Certificate[] getCertificateChain(String alias) throws KeyStoreException {
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetCertificateChain(alias);
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the trusted certificate for the entry with the given alias.
2752f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the trusted certificate for the entry with the given alias, or
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if the specified alias is not bound to an entry.
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes    public final Certificate getCertificate(String alias) throws KeyStoreException {
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetCertificate(alias);
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the creation date of the entry with the given alias.
2922f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the creation date, or {@code null} if the specified alias is not
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         bound to an entry.
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Date getCreationDate(String alias) throws KeyStoreException {
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetCreationDate(alias);
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Associates the given alias with the key, password and certificate chain.
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the specified alias already exists, it will be reassigned.
3112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the key.
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key.
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param password
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the password.
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param chain
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate chain.
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code key} is a {@code PrivateKey} and {@code chain} does
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             not contain any certificates.
3252f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
3262f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code alias} is {@code null}.
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void setKeyEntry(String alias, Key key, char[] password,
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Certificate[] chain) throws KeyStoreException {
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Certificate chain is required for PrivateKey
335b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (key != null && key instanceof PrivateKey && (chain == null || chain.length == 0)) {
336897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException("Certificate chain is not defined for Private key");
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineSetKeyEntry(alias, key, password, chain);
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Associates the given alias with a key and a certificate chain.
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the specified alias already exists, it will be reassigned.
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If this {@code KeyStore} is of type {@code "jks"}, {@code key} must be
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * encoded conform to the PKS#8 standard as an
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link javax.crypto.EncryptedPrivateKeyInfo}.
3492f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the key.
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key in an encoded format.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param chain
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate chain.
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
3572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if this {@code KeyStore} is not initialized or if {@code key}
3582f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             is null.
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code key} is a {@code PrivateKey} and {@code chain}
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             does.
3622f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
3632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code alias} is {@code null}.
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void setKeyEntry(String alias, byte[] key, Certificate[] chain)
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws KeyStoreException {
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineSetKeyEntry(alias, key, chain);
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Associates the given alias with a certificate.
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the specified alias already exists, it will be reassigned.
3772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the certificate.
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param cert
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate.
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized, or an existing
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             alias is not associated to an entry containing a trusted
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             certificate, or this method fails for any other reason.
3862f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
3872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code alias} is {@code null}.
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
389fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes    public final void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineSetCertificateEntry(alias, cert);
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Deletes the entry identified with the given alias from this {@code
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * KeyStore}.
3992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized, or if the entry
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             can not be deleted.
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void deleteEntry(String alias) throws KeyStoreException {
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
4092f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        }
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineDeleteEntry(alias);
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an {@code Enumeration} over all alias names stored in this
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code KeyStore}.
4162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return an {@code Enumeration} over all alias names stored in this
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code KeyStore}.
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Enumeration<String> aliases() throws KeyStoreException {
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineAliases();
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether the given alias is present in this {@code KeyStore}.
4312f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias of an entry.
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the alias exists, {@code false} otherwise.
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean containsAlias(String alias) throws KeyStoreException {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineContainsAlias(alias);
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the number of entries stored in this {@code KeyStore}.
4472f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of entries stored in this {@code KeyStore}.
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int size() throws KeyStoreException {
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineSize();
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether the specified alias is associated with either a
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link PrivateKeyEntry} or a {@link SecretKeyEntry}.
4622f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias of an entry.
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the given alias is associated with a key entry.
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean isKeyEntry(String alias) throws KeyStoreException {
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
4722f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        }
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineIsKeyEntry(alias);
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether the specified alias is associated with a
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link TrustedCertificateEntry}.
4792f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias of an entry.
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the given alias is associated with a certificate
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         entry.
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
487fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes    public final boolean isCertificateEntry(String alias) throws KeyStoreException {
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
4902f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        }
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineIsCertificateEntry(alias);
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the alias associated with the first entry whose certificate
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * matches the specified certificate.
4972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param cert
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate to find the associated entry's alias for.
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the alias or {@code null} if no entry with the specified
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         certificate can be found.
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
505fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes    public final String getCertificateAlias(Certificate cert) throws KeyStoreException {
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetCertificateAlias(cert);
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes this {@code KeyStore} to the specified {@code OutputStream}. The
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * data written to the {@code OutputStream} is protected by the specified
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * password.
5162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param stream
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code OutputStream} to write the store's data to.
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param password
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the password to protect the data.
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a problem occurred while writing to the stream.
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the required algorithm is not available.
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an exception occurred while storing the certificates of
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this {@code KeyStore}.
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void store(OutputStream stream, char[] password)
532fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
5362f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
5372f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        //Just delegate stream and password to implSpi
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineStore(stream, password);
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Stores this {@code KeyStore} using the specified {@code
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * LoadStoreParameter}.
5442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param param
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code LoadStoreParameter} that specifies how to store
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            this {@code KeyStore}, maybe {@code null}.
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a problem occurred while writing to the stream.
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the required algorithm is not available.
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an exception occurred while storing the certificates of
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this {@code KeyStore}.
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given {@link LoadStoreParameter} is not recognized.
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void store(LoadStoreParameter param) throws KeyStoreException,
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            IOException, NoSuchAlgorithmException, CertificateException {
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineStore(param);
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this {@code KeyStore} from the provided {@code InputStream}.
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Pass {@code null} as the {@code stream} argument to initialize an empty
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code KeyStore} or to initialize a {@code KeyStore} which does not rely
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * on an {@code InputStream}. This {@code KeyStore} utilizes the given
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * password to verify the stored data.
5742f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param stream
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code InputStream} to load this {@code KeyStore}'s data
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            from or {@code null}.
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param password
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the password to verify the stored data, maybe {@code null}.
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a problem occurred while reading from the stream.
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the required algorithm is not available.
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an exception occurred while loading the certificates of
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this {@code KeyStore}.
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void load(InputStream stream, char[] password)
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, NoSuchAlgorithmException, CertificateException {
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineLoad(stream, password);
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInit = true;
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Loads this {@code KeyStore} using the specified {@code
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * LoadStoreParameter}.
5972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param param
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code LoadStoreParameter} that specifies how to load this
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code KeyStore}, maybe {@code null}.
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a problem occurred while reading from the stream.
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the required algorithm is not available.
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CertificateException
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an exception occurred while loading the certificates of
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this {@code KeyStore}.
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given {@link LoadStoreParameter} is not recognized.
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void load(LoadStoreParameter param) throws IOException,
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            NoSuchAlgorithmException, CertificateException {
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineLoad(param);
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInit = true;
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code Entry} with the given alias, using the specified
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code ProtectionParameter}.
6202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias of the requested entry.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param param
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ProtectionParameter} used to protect the requested
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            entry, maybe {@code null}.
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return he {@code Entry} with the given alias, using the specified
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code ProtectionParameter}.
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the required algorithm is not available.
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnrecoverableEntryException
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the entry can not be recovered.
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
6342f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
6352f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code alias} is {@code null}.
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Entry getEntry(String alias, ProtectionParameter param)
638fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes            throws NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException {
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (alias == null) {
640897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("alias == null");
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineGetEntry(alias, param);
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Stores the given {@code Entry} in this {@code KeyStore} and associates
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the entry with the given {@code alias}. The entry is protected by the
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified {@code ProtectionParameter}.
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the specified alias already exists, it will be reassigned.
6542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param entry
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the entry to store.
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param param
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ProtectionParameter} to protect the entry.
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
6632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * @throws NullPointerException
6642f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             if {@code alias} is {@code null} or {@code entry} is {@code
6652f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *             null}.
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void setEntry(String alias, Entry entry,
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ProtectionParameter param) throws KeyStoreException {
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (alias == null) {
673897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("alias == null");
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (entry == null) {
676897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("entry == null");
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implSpi.engineSetEntry(alias, entry, param);
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether the entry for the given alias is assignable to the
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * provided {@code Class}.
6842f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alias
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the alias for the entry.
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param entryClass
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the entry.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code Entry} for the alias is assignable to
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         the specified {@code entryClass}.
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyStoreException
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code KeyStore} is not initialized.
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
694f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public final boolean entryInstanceOf(String alias,
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Class<? extends KeyStore.Entry> entryClass)
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws KeyStoreException {
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (alias == null) {
698897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("alias == null");
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (entryClass == null) {
701897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("entryClass == null");
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInit) {
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throwNotInitialized();
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return implSpi.engineEntryInstanceOf(alias, entryClass);
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Builder} is used to construct new instances of {@code KeyStore}.
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract static class Builder {
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code Builder}.
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected Builder() {
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the {@code KeyStore} created by this {@code Builder}.
7222f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the {@code KeyStore} created by this {@code Builder}.
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws KeyStoreException
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurred during construction.
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract KeyStore getKeyStore() throws KeyStoreException;
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the {@code ProtectionParameter} to be used when a {@code
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Entry} with the specified alias is requested. Before this method is
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * invoked, {@link #getKeyStore()} must be called.
7332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param alias
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the alias for the entry.
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the {@code ProtectionParameter} to be used when a {@code
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         Entry} with the specified alias is requested.
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws KeyStoreException
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if an error occurred during the lookup for the protection
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             parameter.
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalStateException
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@link #getKeyStore()} is not called prior the
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             invocation of this method.
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code alias} is {@code null}.
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public abstract ProtectionParameter getProtectionParameter(String alias)
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws KeyStoreException;
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a new {@code Builder} that holds the given {@code KeyStore}
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * and the given {@code ProtectionParameter}.
7532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param keyStore
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code KeyStore} to be held.
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param protectionParameter
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code ProtectionParameter} to be held.
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a new instance of {@code Builder} that holds the specified
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         {@code KeyStore} and the specified {@code
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         ProtectionParameter}.
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code keyStore} or {@code protectionParameter} is
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code null}.
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the given {@code KeyStore} is not initialized.
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public static Builder newInstance(KeyStore keyStore,
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ProtectionParameter protectionParameter) {
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (keyStore == null) {
770897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("keyStore == null");
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (protectionParameter == null) {
773897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("protectionParameter == null");
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!keyStore.isInit) {
776897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("KeyStore was not initialized");
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
778ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes            return new BuilderImpl(keyStore, protectionParameter, null, null, null);
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a new {@code Builder} that creates a new {@code KeyStore}
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * based on the provided arguments.
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * <p>
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * If {@code provider} is {@code null}, all installed providers are
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * searched, otherwise the key store from the specified provider is
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * used.
7882f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param type
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the type of the {@code KeyStore} to be constructed.
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param provider
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the provider of the {@code KeyStore} to be constructed,
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            maybe {@code null}.
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param file
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code File} that contains the data for the {@code
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            KeyStore}.
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param protectionParameter
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code ProtectionParameter} used to protect the stored
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            keys.
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a new {@code Builder} that creates a new {@code KeyStore}
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         based on the provided arguments.
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code type, protectionParameter} or {@code file} is
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code null}.
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code protectionParameter} not an instance of either
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code PasswordProtection} or {@code
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             CallbackHandlerProtection}, {@code file} is not a file or
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             does not exist at all.
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public static Builder newInstance(String type, Provider provider,
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                File file, ProtectionParameter protectionParameter) {
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // check null parameters
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (type == null) {
815897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("type == null");
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (protectionParameter == null) {
818897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("protectionParameter == null");
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (file == null) {
821897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("file == null");
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // protection parameter should be PasswordProtection or
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // CallbackHandlerProtection
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(protectionParameter instanceof PasswordProtection)
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && !(protectionParameter instanceof CallbackHandlerProtection)) {
8270a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                throw new IllegalArgumentException("protectionParameter is neither "
8280a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                        + "PasswordProtection nor CallbackHandlerProtection instance");
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // check file parameter
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!file.exists()) {
832897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("File does not exist: " + file.getName());
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!file.isFile()) {
835897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("Not a regular file: " + file.getName());
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // create new instance
838ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes            return new BuilderImpl(null, protectionParameter, file, type, provider);
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a new {@code Builder} that creates a new {@code KeyStore}
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * based on the provided arguments.
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * <p>
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * If {@code provider} is {@code null}, all installed providers are
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * searched, otherwise the key store from the specified provider is
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * used.
8482f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param type
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the type of the {@code KeyStore} to be constructed.
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param provider
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the provider of the {@code KeyStore} to be constructed,
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            maybe {@code null}.
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param protectionParameter
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code ProtectionParameter} used to protect the stored
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            keys.
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a new {@code Builder} that creates a new {@code KeyStore}
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         based on the provided arguments.
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code type} or {@code protectionParameter} is {@code
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             null}.
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code protectionParameter} not an instance of either
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code PasswordProtection} or {@code
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             CallbackHandlerProtection}, {@code file} is not a file or
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             does not exist at all.
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public static Builder newInstance(String type, Provider provider,
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ProtectionParameter protectionParameter) {
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (type == null) {
871897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("type == null");
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (protectionParameter == null) {
874897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("protectionParameter == null");
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
876ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes            return new BuilderImpl(null, protectionParameter, null, type, provider);
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * This class is implementation of abstract class KeyStore.Builder
881f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes         *
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @author Vera Petrashkova
883f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes         *
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private static class BuilderImpl extends Builder {
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used KeyStore
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private KeyStore keyStore;
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used ProtectionParameter
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private ProtectionParameter protParameter;
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used KeyStore type
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private final String typeForKeyStore;
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used KeyStore provider
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private final Provider providerForKeyStore;
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used file for KeyStore loading
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private final File fileForLoad;
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store getKeyStore method was invoked or not for KeyStoreBuilder
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private boolean isGetKeyStore = false;
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store last Exception in getKeyStore()
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private KeyStoreException lastException;
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9070a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            /**
9080a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * Constructor BuilderImpl initializes private fields: keyStore,
9090a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * protParameter, typeForKeyStore providerForKeyStore fileForLoad,
9100a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * isGetKeyStore
9110a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             */
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BuilderImpl(KeyStore ks, ProtectionParameter pp, File file,
913ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        String type, Provider provider) {
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                keyStore = ks;
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                protParameter = pp;
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                fileForLoad = file;
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                typeForKeyStore = type;
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                providerForKeyStore = provider;
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isGetKeyStore = false;
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                lastException = null;
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9230a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            /**
9240a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * Implementation of abstract getKeyStore() method If
9250a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * KeyStoreBuilder encapsulates KeyStore object then this object is
9260a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * returned
9270a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             *
9280a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * If KeyStoreBuilder encapsulates KeyStore type and provider then
9290a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * KeyStore is created using these parameters. If KeyStoreBuilder
9300a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * encapsulates file and ProtectionParameter then KeyStore data are
9310a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * loaded from FileInputStream that is created on file. If file is
9320a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * not defined then KeyStore object is initialized with null
9330a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * InputStream and null password.
9340a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             *
9350a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * Result KeyStore object is returned.
9360a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             */
9372f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            @Override
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public synchronized KeyStore getKeyStore() throws KeyStoreException {
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // If KeyStore was created but in final block some exception was
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // thrown
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // then it was stored in lastException variable and will be
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // thrown
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // all subsequent calls of this method.
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (lastException != null) {
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw lastException;
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (keyStore != null) {
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isGetKeyStore = true;
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return keyStore;
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // get KeyStore instance using type or type and provider
954ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    final KeyStore ks = (providerForKeyStore == null ? KeyStore
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getInstance(typeForKeyStore) : KeyStore
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getInstance(typeForKeyStore, providerForKeyStore));
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // protection parameter should be PasswordProtection
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // or CallbackHandlerProtection
959ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    final char[] passwd;
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (protParameter instanceof PasswordProtection) {
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        passwd = ((PasswordProtection) protParameter)
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                .getPassword();
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else if (protParameter instanceof CallbackHandlerProtection) {
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        passwd = KeyStoreSpi
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                .getPasswordFromCallBack(protParameter);
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else {
9670a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                        throw new KeyStoreException("protectionParameter is neither "
9680a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                                + "PasswordProtection nor CallbackHandlerProtection instance");
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // load KeyStore from file
972ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    if (fileForLoad != null) {
973ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        FileInputStream fis = null;
974ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        try {
975ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                            fis = new FileInputStream(fileForLoad);
976ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                            ks.load(fis, passwd);
977ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        } finally {
978ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                            IoUtils.closeQuietly(fis);
979ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        }
980ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    } else {
981ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                        ks.load(new TmpLSParameter(protParameter));
982ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    }
983f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isGetKeyStore = true;
9852f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    return ks;
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (KeyStoreException e) {
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Store exception
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw lastException = e;
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (Exception e) {
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Override exception
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw lastException = new KeyStoreException(e);
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
9950a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            /**
9960a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * This is implementation of abstract method
9970a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * getProtectionParameter(String alias)
9980a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             *
9990a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * Return: ProtectionParameter to get Entry which was saved in
10000a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             * KeyStore with defined alias
10010a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom             */
10022f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            @Override
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public synchronized ProtectionParameter getProtectionParameter(
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String alias) throws KeyStoreException {
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (alias == null) {
1006897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                    throw new NullPointerException("alias == null");
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!isGetKeyStore) {
1009897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                    throw new IllegalStateException("getKeyStore() was not invoked");
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return protParameter;
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Implementation of LoadStoreParameter interface
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private static class TmpLSParameter implements LoadStoreParameter {
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Store used protection parameter
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            private final ProtectionParameter protPar;
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /**
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * Creates TmpLoadStoreParameter object
10252f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes             * @param protPar protection parameter
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public TmpLSParameter(ProtectionParameter protPar) {
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.protPar = protPar;
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /**
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * This method returns protection parameter
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public ProtectionParameter getProtectionParameter() {
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return protPar;
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code CallbackHandlerProtection} is a {@code ProtectionParameter} that
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * encapsulates a {@link CallbackHandler}.
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class CallbackHandlerProtection implements
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ProtectionParameter {
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store CallbackHandler
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final CallbackHandler callbackHandler;
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code CallbackHandlerProtection} with
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * the {@code CallbackHandler}.
10522f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param handler
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the {@code CallbackHandler}.
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code handler} is {@code null}.
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public CallbackHandlerProtection(CallbackHandler handler) {
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (handler == null) {
1060897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("handler == null");
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.callbackHandler = handler;
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the {@code CallbackHandler}.
10672f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the {@code CallbackHandler}.
1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public CallbackHandler getCallbackHandler() {
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return callbackHandler;
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Entry} is the common marker interface for a {@code KeyStore}
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * entry.
1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static interface Entry {
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code LoadStoreParameter} represents a parameter that specifies how a
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code KeyStore} can be loaded and stored.
10852f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see KeyStore#load(LoadStoreParameter)
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see KeyStore#store(LoadStoreParameter)
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static interface LoadStoreParameter {
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the {@code ProtectionParameter} which is used to protect data
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * in the {@code KeyStore}.
10932f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the {@code ProtectionParameter} which is used to protect data
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         in the {@code KeyStore}, maybe {@code null}.
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public ProtectionParameter getProtectionParameter();
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code PasswordProtection} is a {@code ProtectionParameter} that protects
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * a {@code KeyStore} using a password.
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class PasswordProtection implements ProtectionParameter,
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Destroyable {
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store password
1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private char[] password;
1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private boolean isDestroyed = false;
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code PasswordProtection} with a
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * password. A copy of the password is stored in the new {@code
1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * PasswordProtection} object.
11162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param password
1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the password, maybe {@code null}.
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public PasswordProtection(char[] password) {
1121d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes            if (password != null) {
1122d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes                this.password = password.clone();
1123d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes            }
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the password.
11282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the password.
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalStateException
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the password has been destroyed.
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public synchronized char[] getPassword() {
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isDestroyed) {
1135897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalStateException("Password was destroyed");
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return password;
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Destroys / invalidates the password.
11422f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws DestroyFailedException
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the password could not be invalidated.
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public synchronized void destroy() throws DestroyFailedException {
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isDestroyed = true;
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (password != null) {
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Arrays.fill(password, '\u0000');
1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                password = null;
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Indicates whether the password is invalidated.
11562f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return {@code true} if the password is invalidated, {@code false}
1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         otherwise.
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public synchronized boolean isDestroyed() {
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return isDestroyed;
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code ProtectionParameter} is a marker interface for protection
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parameters. A protection parameter is used to protect the content of a
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code KeyStore}.
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static interface ProtectionParameter {
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code PrivateKeyEntry} represents a {@code KeyStore} entry that
1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * holds a private key.
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final class PrivateKeyEntry implements Entry {
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store Certificate chain
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private Certificate[] chain;
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store PrivateKey
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private PrivateKey privateKey;
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code PrivateKeyEntry} with the given
1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * {@code PrivateKey} and the provided certificate chain.
11872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param privateKey
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the private key.
1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param chain
1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the ordered certificate chain with the certificate
1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            corresponding to the private key at index 0.
1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code privateKey} or {@code chain} is {@code null}.
1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws IllegalArgumentException
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code chain.length == 0}, the algorithm of the
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             private key does not match the algorithm of the public
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             key of the first certificate or the certificates are not
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             all of the same type.
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (privateKey == null) {
1203897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("privateKey == null");
1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (chain == null) {
1206897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("chain == null");
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (chain.length == 0) {
1210897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IllegalArgumentException("chain.length == 0");
1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Match algorithm of private key and algorithm of public key from
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // the end certificate
1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String s = chain[0].getType();
1215897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            if (!(chain[0].getPublicKey().getAlgorithm()).equals(privateKey.getAlgorithm())) {
12160a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                throw new IllegalArgumentException("Algorithm of private key does not match "
12170a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                        + "algorithm of public key in end certificate of entry "
12180a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                        + "(with index number: 0)");
1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Match certificate types
1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 1; i < chain.length; i++) {
1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!s.equals(chain[i].getType())) {
12230a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                    throw new IllegalArgumentException("Certificates from the given chain have "
12240a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom                                                       + "different types");
1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // clone chain - this.chain = (Certificate[])chain.clone();
12282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            boolean isAllX509Certificates = true;
12292f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            // assert chain length > 0
12300d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes            for (Certificate cert: chain) {
12310d4daefcf389b6433a0af481ef44a84a2546541aElliott Hughes                if (!(cert instanceof X509Certificate)) {
12322f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    isAllX509Certificates = false;
12332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    break;
12342f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                }
12352f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            }
1236f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
12372f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            if(isAllX509Certificates){
12382f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                this.chain = new X509Certificate[chain.length];
1239e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom            } else {
12402f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                this.chain = new Certificate[chain.length];
12412f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            }
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(chain, 0, this.chain, 0, chain.length);
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.privateKey = privateKey;
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the private key.
12482f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the private key.
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public PrivateKey getPrivateKey() {
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return privateKey;
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the certificate chain.
12572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the certificate chain.
1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Certificate[] getCertificateChain() {
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return chain.clone();
1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the certificate corresponding to the private key.
12662f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the certificate corresponding to the private key.
1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Certificate getCertificate() {
1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return chain[0];
1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a string containing a concise, human-readable description of
1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this {@code PrivateKeyEntry}.
12762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a printable representation for this {@code PrivateKeyEntry}.
1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
12792f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
12812f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            StringBuilder sb = new StringBuilder(
1282f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    "PrivateKeyEntry: number of elements in certificate chain is ");
1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            sb.append(Integer.toString(chain.length));
1284f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            sb.append("\n");
1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < chain.length; i++) {
1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                sb.append(chain[i].toString());
1287f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                sb.append("\n");
1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return sb.toString();
1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code SecretKeyEntry} represents a {@code KeyStore} entry that
1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * holds a secret key.
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final class SecretKeyEntry implements Entry {
1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store SecretKey
1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final SecretKey secretKey;
1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code SecretKeyEntry} with the given
1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * {@code SecretKey}.
13052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param secretKey
1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the secret key.
1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code secretKey} is {@code null}.
1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public SecretKeyEntry(SecretKey secretKey) {
1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (secretKey == null) {
1313897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("secretKey == null");
1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.secretKey = secretKey;
1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the secret key.
13202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the secret key.
1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public SecretKey getSecretKey() {
1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return secretKey;
1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a string containing a concise, human-readable description of
1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this {@code SecretKeyEntry}.
13302f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a printable representation for this {@code
1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         SecretKeyEntry}.
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
13342f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
1336f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            StringBuilder sb = new StringBuilder("SecretKeyEntry: algorithm - ");
1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            sb.append(secretKey.getAlgorithm());
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return sb.toString();
1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code TrustedCertificateEntry} represents a {@code KeyStore} entry that
1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * holds a trusted certificate.
1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final class TrustedCertificateEntry implements Entry {
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Store trusted Certificate
1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Certificate trustCertificate;
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code TrustedCertificateEntry} with the
1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * given {@code Certificate}.
13542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param trustCertificate
1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the trusted certificate.
1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code trustCertificate} is {@code null}.
1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public TrustedCertificateEntry(Certificate trustCertificate) {
1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (trustCertificate == null) {
1362897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new NullPointerException("trustCertificate == null");
1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.trustCertificate = trustCertificate;
1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the trusted certificate.
13692f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the trusted certificate.
1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Certificate getTrustedCertificate() {
1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return trustCertificate;
1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a string containing a concise, human-readable description of
1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this {@code TrustedCertificateEntry}.
13792f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a printable representation for this {@code
1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         TrustedCertificateEntry}.
1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
13832f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
1384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
1385f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return "Trusted certificate entry:\n" + trustCertificate;
1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1389