3261N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class provides the keystore implementation referred to as "JKS". 0N/A * @author David Brownell 0N/A * @see java.security.KeyStoreSpi 0N/A // special JKS that uses case sensitive aliases 0N/A private static final int MAGIC =
0xfeedfeed;
0N/A // Private keys and their supporting certificate chains 0N/A // Trusted certificates 0N/A * Private keys and certificates are stored in a hashtable. 0N/A * Hash entries are keyed by alias names. 0N/A // convert an alias to internal form, overridden in subclasses: 0N/A // lower case for regular JKS 0N/A // original string for CaseExactJKS 0N/A * Returns the key associated with the given alias, using the given 0N/A * password to recover it. 0N/A * @param alias the alias name 0N/A * @param password the password for recovering the key 0N/A * @return the requested key, or null if the given alias does not exist 0N/A * or does not identify a <i>key entry</i>. 0N/A * @exception NoSuchAlgorithmException if the algorithm for recovering the 0N/A * key cannot be found 0N/A * @exception UnrecoverableKeyException if the key cannot be recovered 0N/A * (e.g., the given password is wrong). 0N/A +
"EncryptedPrivateKeyInfo");
0N/A * Returns the certificate chain associated with the given alias. 0N/A * @param alias the alias name 0N/A * @return the certificate chain (ordered with the user's certificate first 0N/A * and the root certificate authority last), or null if the given alias 0N/A * does not exist or does not contain a certificate chain (i.e., the given 0N/A * alias identifies either a <i>trusted certificate entry</i> or a 0N/A * <i>key entry</i> without a certificate chain). 0N/A * Returns the certificate associated with the given alias. 0N/A * <p>If the given alias name identifies a 0N/A * <i>trusted certificate entry</i>, the certificate associated with that 0N/A * entry is returned. If the given alias name identifies a 0N/A * <i>key entry</i>, the first element of the certificate chain of that 0N/A * entry is returned, or null if that entry does not have a certificate 0N/A * @param alias the alias name 0N/A * @return the certificate, or null if the given alias does not exist or 0N/A * does not contain a certificate. 0N/A * Returns the creation date of the entry identified by the given alias. 0N/A * @param alias the alias name 0N/A * @return the creation date of this entry, or null if the given alias does 0N/A * Assigns the given private key to the given alias, protecting 0N/A * it with the given password as defined in PKCS8. 0N/A * <p>The given java.security.PrivateKey <code>key</code> must 0N/A * be accompanied by a certificate chain certifying the 0N/A * corresponding public key. 0N/A * <p>If the given alias already exists, the keystore information 0N/A * associated with it is overridden by the given key and certificate 0N/A * @param alias the alias name 0N/A * @param key the private key to be associated with the alias 0N/A * @param password the password to protect the key 0N/A * @param chain the certificate chain for the corresponding public 0N/A * key (only required if the given key is of type 0N/A * <code>java.security.PrivateKey</code>). 0N/A * @exception KeyStoreException if the given key is not a private key, 0N/A * cannot be protected, or this operation fails for some other reason 0N/A // Protect the encoding of the key 0N/A * Assigns the given key (that has already been protected) to the given 0N/A * <p>If the protected key is of type 0N/A * <code>java.security.PrivateKey</code>, it must be accompanied by a 0N/A * certificate chain certifying the corresponding public key. If the 0N/A * underlying keystore implementation is of type <code>jks</code>, 0N/A * <code>key</code> must be encoded as an 0N/A * <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard. 0N/A * <p>If the given alias already exists, the keystore information 0N/A * associated with it is overridden by the given key (and possibly 0N/A * certificate chain). 0N/A * @param alias the alias name 0N/A * @param key the key (in protected format) to be associated with the alias 0N/A * @param chain the certificate chain for the corresponding public 0N/A * key (only useful if the protected key is of type 0N/A * <code>java.security.PrivateKey</code>). 0N/A * @exception KeyStoreException if this operation fails. 0N/A // key must be encoded as EncryptedPrivateKeyInfo as defined in 0N/A +
"EncryptedPrivateKeyInfo");
0N/A * Assigns the given certificate to the given alias. 0N/A * <p>If the given alias already exists in this keystore and identifies a 0N/A * <i>trusted certificate entry</i>, the certificate associated with it is 0N/A * overridden by the given certificate. 0N/A * @param alias the alias name 0N/A * @param cert the certificate 0N/A * @exception KeyStoreException if the given alias already exists and does 0N/A * not identify a <i>trusted certificate entry</i>, or this operation 0N/A * fails for some other reason. 0N/A (
"Cannot overwrite own certificate");
0N/A * Deletes the entry identified by the given alias from this keystore. 0N/A * @param alias the alias name 0N/A * @exception KeyStoreException if the entry cannot be removed. 0N/A * Lists all the alias names of this keystore. 0N/A * @return enumeration of the alias names 0N/A * Checks if the given alias exists in this keystore. 0N/A * @param alias the alias name 0N/A * @return true if the alias exists, false otherwise 0N/A * Retrieves the number of entries in this keystore. 0N/A * @return the number of entries in this keystore 0N/A * Returns true if the entry identified by the given alias is a 0N/A * <i>key entry</i>, and false otherwise. 0N/A * @return true if the entry identified by the given alias is a 0N/A * <i>key entry</i>, false otherwise. 0N/A * Returns true if the entry identified by the given alias is a 0N/A * <i>trusted certificate entry</i>, and false otherwise. 0N/A * @return true if the entry identified by the given alias is a 0N/A * <i>trusted certificate entry</i>, false otherwise. 0N/A * Returns the (alias) name of the first keystore entry whose certificate 0N/A * matches the given certificate. 0N/A * <p>This method attempts to match the given certificate with each 0N/A * keystore entry. If the entry being considered 0N/A * is a <i>trusted certificate entry</i>, the given certificate is 0N/A * compared to that entry's certificate. If the entry being considered is 0N/A * a <i>key entry</i>, the given certificate is compared to the first 0N/A * element of that entry's certificate chain (if a chain exists). 0N/A * @param cert the certificate to match with. 0N/A * @return the (alias) name of the first entry with matching certificate, 0N/A * or null if no such entry exists in this keystore. 0N/A * Stores this keystore to the given output stream, and protects its 0N/A * integrity with the given password. 0N/A * @param stream the output stream to which this keystore is written. 0N/A * @param password the password to generate the keystore integrity check 0N/A * @exception IOException if there was an I/O problem with data 0N/A * @exception NoSuchAlgorithmException if the appropriate data integrity 0N/A * algorithm could not be found 0N/A * @exception CertificateException if any of the certificates included in 0N/A * the keystore data could not be stored 0N/A * Magic number (big-endian integer), 0N/A * Version of this file format (big-endian integer), 0N/A * Count (big-endian integer), 0N/A * followed by "count" instances of either: 0N/A * tag=1 (big-endian integer), 0N/A * alias (UTF string) 0N/A * encrypted private-key info according to PKCS #8 0N/A * (integer length followed by encoding) 0N/A * cert chain (integer count, then certs; for each cert, 0N/A * integer length followed by encoding) 0N/A * tag=2 (big-endian integer) 0N/A * alias (UTF string) 0N/A * cert (integer length followed by encoding) 0N/A * ended by a keyed SHA1 hash (bytes only) of 0N/A * { password + whitener + preceding body } 0N/A // password is mandatory when storing 0N/A // always write the latest version 0N/A // Store this entry as a KeyEntry 0N/A // Write the (entry creation) date 0N/A // Write the protected private key 0N/A // Write the certificate chain 0N/A // Store this entry as a certificate 0N/A // Write the (entry creation) date 0N/A // Write the trusted certificate 0N/A * Write the keyed hash which is used to detect tampering with 0N/A * the keystore (such as deleting or modifying key or 0N/A * certificate entries). 0N/A * Loads the keystore from the given input stream. 0N/A * <p>If a password is given, it is used to check the integrity of the 0N/A * keystore data. Otherwise, the integrity of the keystore is not checked. 0N/A * @param stream the input stream from which the keystore is loaded 0N/A * @param password the (optional) password used to check the integrity of 0N/A * @exception IOException if there is an I/O or format problem with the 0N/A * @exception NoSuchAlgorithmException if the algorithm used to check 0N/A * the integrity of the keystore cannot be found 0N/A * @exception CertificateException if any of the certificates in the 0N/A * keystore could not be loaded 0N/A // Body format: see store method 0N/A if (
tag ==
1) {
// private key entry 0N/A // Read the (entry creation) date 0N/A // Read the private key 0N/A // Read the certificate chain 2201N/A // read the certificate type, and instantiate a 2201N/A // certificate factory of that type (reuse 2201N/A // existing factory if possible) 2201N/A // reuse certificate factory 2201N/A // create new certificate factory 2201N/A // store the certificate factory so we can 2201N/A // instantiate the certificate 2201N/A // We can be sure now that numOfCerts of certs are read 0N/A // Add the entry to the list 0N/A }
else if (
tag ==
2) {
// trusted certificate entry 0N/A // Read the (entry creation) date 0N/A // Read the trusted certificate 0N/A // read the certificate type, and instantiate a 0N/A // certificate factory of that type (reuse 0N/A // existing factory if possible) 0N/A // reuse certificate factory 0N/A // create new certificate factory 0N/A // store the certificate factory so we can 0N/A // Add the entry to the list 0N/A * If a password has been provided, we check the keyed digest 0N/A * at the end. If this check fails, the store has been tampered 0N/A (
"Password verification failed");
0N/A (
"Keystore was tampered with, or " 0N/A * To guard against tampering with the keystore, we append a keyed 0N/A * hash with a bit of whitener.