📄 keystoremanager.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package com.sslexplorer.boot;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.maverick.crypto.asn1.ASN1Sequence;
import com.maverick.crypto.asn1.DERInputStream;
import com.maverick.crypto.asn1.x509.X509CertificateStructure;
import com.maverick.ssl.TrustedCACertStore;
/**
* <p>
* Manages one or more keystores. SSL-Explorer currently uses two keystores, one
* for the SSL server certificate and one for storing all of the client
* certificates.
* </p>
*
* <p>
* Before a keystore manager may be used, it must be registered using
* {@link #registerKeyStore(String, String, boolean, String)}
*
* <p>
* To obtain a keystore, use {@link #getInstance(String)}, passing the keystore
* name. If the named keystore has not yet been initialised then it is created
* and initialised, otherwise the last used instance is returned.
* </p>
*
* <p>
* The key store files are held and manipulated in the <i>conf</i> directory.
* All key stores are also updated to the
* {@link com.sslexplorer.boot.Repository} which is loaded at start up,
* replacing all the files.
* </p>
*
* @author Brett Smith <a href="mailto: brett@3sp.com"><brett@3sp.com></a>
* @author Lee David Painter <a href="mailto: brett@3sp.com"><lee@3sp.com></a>
* @version $Revision: 1.22 $
* @see com.sslexplorer.boot.Repository
*/
public class KeyStoreManager {
// Public statics
/**
* The default key store name. Used to store SSL-Explorers own server
* certificate
*/
public static final String DEFAULT_KEY_STORE = "default";
/**
* Key store name for Server authentication certificates used to store
* certificates to use to connect to other servers
*/
public static final String SERVER_AUTHENTICATION_CERTIFICATES_KEY_STORE = "serverAuthentication";
/**
* Key Store name for Server certificates that are trusted by SSL-Explorer
* making outgoing connections to it.
*/
public static final String TRUSTED_SERVER_CERTIFICATES_KEY_STORE = "trustedServer";
/**
* Default password used for storing the untrusted key
*/
public static final String DEFAULT_KEY_PASSWORD = "sslexplorer";
/**
* Repository name
*/
public static final String KEYSTORE_REPOSITORY = "keystore";
// Private instance variables
private boolean keyStoreExists;
private Date keystoreLastModified;
private KeyStore keyStore;
private boolean keyStoreEmpty;
private File keyStoreFile;
private Throwable keyStoreException;
private String keyStoreName;
private KeyStoreType keyStoreType;
private String bundle;
private boolean removeable;
private String storePassword;
// Private statics
final static Log log = LogFactory.getLog(KeyStoreManager.class);
static String KEY_TOOL = System.getProperty("java.home") + File.separator + "bin" + File.separator + "keytool";
private static HashMap instances = new HashMap();
public static final KeyStoreType TYPE_JKS = new KeyStoreType("JKS", "jks");
public static final KeyStoreType TYPE_PKCS12 = new KeyStoreType("PKCS12", "p12");
private static final List keyStoreTypes = Arrays.asList(new KeyStoreType[] { TYPE_JKS, TYPE_PKCS12 });
/**
* Constructor. Private to prevent direct instantiation
*
* @param keyStoreName name of key store
* @param bundle bundle key from which to get key store messages (title,
* description etc)
* @param removeable admin may remove certificates manually in the key store
* management page
* @param storePassword the keystore password
*/
private KeyStoreManager(String keyStoreName, String bundle, boolean removeable, String storePassword, KeyStoreType type) {
super();
this.keyStoreName = keyStoreName;
this.bundle = bundle;
this.removeable = removeable;
this.storePassword = storePassword;
this.keyStoreType = type;
initKeyStoreFile();
// Make sure that this keystore is synchronized with the repository
try {
synchronizeWithRepository();
} catch (IOException ex) {
log.error("The keystore could not be synchornized with the repository", ex);
}
}
/**
* Get an instance of a keystore manager given the keystore name
*
* @param keyStoreName
* @return keyStore instance
*/
public static KeyStoreManager getInstance(String keyStoreName) {
KeyStoreManager mgr = (KeyStoreManager) instances.get(keyStoreName);
if (mgr == null) {
throw new IllegalArgumentException("No keystore named " + keyStoreName);
}
return mgr;
}
public InputStream getInputStream() throws IOException {
return RepositoryFactory.getRepository().getStore(KEYSTORE_REPOSITORY).getEntryInputStream(keyStoreFile.getName());
}
/**
* Get a list of registered {@link KeyStoreManager}s.
*
* @return key stores
*/
public static List getKeyStores() {
List l = new ArrayList();
for (Iterator i = instances.entrySet().iterator(); i.hasNext();) {
l.add(((Map.Entry) i.next()).getValue());
}
return l;
}
/**
* Register a new keystore
*
* @param name name of keystore
* @param bundle bundle for messages
* @param removeable <code>true</code> if certificates may manually be
* removed
* @param storePassword key store password
*/
public static void registerKeyStore(String name, String bundle, boolean removeable, String storePassword, KeyStoreType type) {
if (log.isInfoEnabled())
log.info("Registering keystore " + name);
KeyStoreManager mgr = new KeyStoreManager(name, bundle, removeable, storePassword, type);
instances.put(name, mgr);
}
/**
* Set the new store password. Note, this only sets the password to use for
* reading the key store. It does not change the password of the key store
* itself.
*
* @param storePassword store password
*/
public void setStorePassword(String storePassword) {
this.storePassword = storePassword;
reloadKeystore();
}
/**
* Get if certificates are removeable by the administrator
*
* @return removeable
*/
public boolean getRemoveable() {
return removeable;
}
/**
* Get the bundle that contains messages for this key store
*
* @return bundle
*/
public String getBundle() {
return bundle;
}
/**
* Get the name that this key store was registered with
*
* @return name
*/
public String getName() {
return keyStoreName;
}
/**
* Get if the keystore currently exists
*
* @return keystore exists
*/
public boolean isKeyStoreExists() {
try {
checkKeyStore();
} catch (Exception e) {
log.error("Could not determine if key store exists.");
}
return keyStoreExists;
}
/**
* Get if the keystore is empty.
*
* @return keystore is empty
*/
public boolean isKeyStoreEmpty() {
try {
checkKeyStore();
} catch (Exception e) {
log.error("Could not determine if key store exists.");
}
return keyStoreEmpty;
}
/**
* Determine whether the certificate with the supplied alias is trusted or
* not.
*
* @param alias certificiate name
* @return trust certificate
*/
public boolean isCertificateTrusted(String alias) {
try {
checkKeyStore();
if (isKeyStoreExists() && !isKeyStoreEmpty()) {
return doIsCertificateTrused(alias, keyStore);
}
} catch (Exception e) {
log.error("Could not determine if certificate " + alias + " is trusted.", e);
}
return false;
}
/**
* If there were any errors loading or iniatilising the keystore, this
* method will a non-null exception object detailing the error. If the
* keystore was loaded successfully then <code>null</code> will be
* returned.
*
* @return exception caught whilst initialising the keystore
*/
public Throwable getKeyStoreException() {
checkKeyStore();
return keyStoreException;
}
/**
* Get the {@link KeyStore} this keystore manager is managing.
*
* @return keystore
*/
public KeyStore getKeyStore() {
if(keyStore==null)
this.reloadKeystore();
return keyStore;
}
/**
* Get a certificate given its alias.
*
* @param alias certificate alias.
* @return certificate
*/
public Certificate getCertificate(String alias) {
try {
checkKeyStore();
if (isKeyStoreExists() && !isKeyStoreEmpty()) {
return keyStore.getCertificate(alias);
}
} catch (Exception e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -