Java tutorial
/* * Copyright (C) 2005-2011 Alfresco Software Limited. * * This file is part of Alfresco * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */ package org.alfresco.encryption; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.management.openmbean.KeyAlreadyExistsException; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import org.alfresco.encryption.EncryptionKeysRegistry.KEY_STATUS; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.util.PropertyCheck; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This wraps a Java Keystore and caches the encryption keys. It manages the loading and caching of the encryption keys * and their registration with and validation against the encryption key registry. * * @since 4.0 * */ public class AlfrescoKeyStoreImpl implements AlfrescoKeyStore { private static final Log logger = LogFactory.getLog(AlfrescoKeyStoreImpl.class); protected KeyStoreParameters keyStoreParameters; protected KeyStoreParameters backupKeyStoreParameters; protected KeyResourceLoader keyResourceLoader; protected EncryptionKeysRegistry encryptionKeysRegistry; protected KeyMap keys; protected KeyMap backupKeys; protected final WriteLock writeLock; protected final ReadLock readLock; private static Set<String> keysToValidate; protected boolean validateKeyChanges = false; static { keysToValidate = Collections.singleton(KeyProvider.ALIAS_METADATA); } public AlfrescoKeyStoreImpl() { ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); writeLock = lock.writeLock(); readLock = lock.readLock(); this.keys = new KeyMap(); this.backupKeys = new KeyMap(); } public AlfrescoKeyStoreImpl(KeyStoreParameters keyStoreParameters, KeyResourceLoader keyResourceLoader) { this(); this.keyResourceLoader = keyResourceLoader; this.keyStoreParameters = keyStoreParameters; safeInit(); } public void init() { writeLock.lock(); try { safeInit(); } finally { writeLock.unlock(); } } public void setEncryptionKeysRegistry(EncryptionKeysRegistry encryptionKeysRegistry) { this.encryptionKeysRegistry = encryptionKeysRegistry; } public void setValidateKeyChanges(boolean validateKeyChanges) { this.validateKeyChanges = validateKeyChanges; } public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters) { this.keyStoreParameters = keyStoreParameters; } public void setBackupKeyStoreParameters(KeyStoreParameters backupKeyStoreParameters) { this.backupKeyStoreParameters = backupKeyStoreParameters; } public void setKeyResourceLoader(KeyResourceLoader keyResourceLoader) { this.keyResourceLoader = keyResourceLoader; } public KeyStoreParameters getKeyStoreParameters() { return keyStoreParameters; } public KeyStoreParameters getBackupKeyStoreParameters() { return backupKeyStoreParameters; } public KeyResourceLoader getKeyResourceLoader() { return keyResourceLoader; } /** * {@inheritDoc} */ @Override public String getName() { return keyStoreParameters.getName(); } /** * {@inheritDoc} */ @Override public void validateKeys() throws InvalidKeystoreException, MissingKeyException { validateKeys(keys, backupKeys); } /** * {@inheritDoc} */ @Override public boolean exists() { return keyStoreExists(getKeyStoreParameters().getLocation()); } /** * {@inheritDoc} */ @Override public void reload() throws InvalidKeystoreException, MissingKeyException { KeyMap keys = loadKeyStore(getKeyStoreParameters()); KeyMap backupKeys = loadKeyStore(getBackupKeyStoreParameters()); validateKeys(keys, backupKeys); // all ok, reload the keys writeLock.lock(); try { this.keys = keys; this.backupKeys = backupKeys; } finally { writeLock.unlock(); } } /** * {@inheritDoc} */ @Override public Set<String> getKeyAliases() { return new HashSet<String>(keys.getKeyAliases()); } /** * {@inheritDoc} */ @Override public void backup() { writeLock.lock(); try { for (String keyAlias : keys.getKeyAliases()) { backupKeys.setKey(keyAlias, keys.getKey(keyAlias)); } createKeyStore(backupKeyStoreParameters, backupKeys); } finally { writeLock.unlock(); } } /** * {@inheritDoc} */ @Override public void create() { createKeyStore(keyStoreParameters, keys); } /** * {@inheritDoc} */ @Override public Key getKey(String keyAlias) { readLock.lock(); try { return keys.getCachedKey(keyAlias).getKey(); } finally { readLock.unlock(); } } /** * {@inheritDoc} */ @Override public long getKeyTimestamp(String keyAlias) { readLock.lock(); try { CachedKey cachedKey = keys.getCachedKey(keyAlias); return cachedKey.getTimestamp(); } finally { readLock.unlock(); } } /** * {@inheritDoc} */ @Override public Key getBackupKey(String keyAlias) { readLock.lock(); try { return backupKeys.getCachedKey(keyAlias).getKey(); } finally { readLock.unlock(); } } /** * {@inheritDoc} */ @Override public KeyManager[] createKeyManagers() { KeyInfoManager keyInfoManager = null; try { keyInfoManager = getKeyInfoManager(getKeyMetaDataFileLocation()); KeyStore ks = loadKeyStore(keyStoreParameters, keyInfoManager); logger.debug("Initializing key managers"); KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); String keyStorePassword = keyInfoManager.getKeyStorePassword(); kmfactory.init(ks, keyStorePassword != null ? keyStorePassword.toCharArray() : null); return kmfactory.getKeyManagers(); } catch (Throwable e) { throw new AlfrescoRuntimeException("Unable to create key manager", e); } finally { if (keyInfoManager != null) { keyInfoManager.clear(); } } } /** * {@inheritDoc} */ @Override public TrustManager[] createTrustManagers() { KeyInfoManager keyInfoManager = null; try { keyInfoManager = getKeyInfoManager(getKeyMetaDataFileLocation()); KeyStore ks = loadKeyStore(getKeyStoreParameters(), keyInfoManager); logger.debug("Initializing trust managers"); TrustManagerFactory tmfactory = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmfactory.init(ks); return tmfactory.getTrustManagers(); } catch (Throwable e) { throw new AlfrescoRuntimeException("Unable to create key manager", e); } finally { if (keyInfoManager != null) { keyInfoManager.clear(); } } } protected String getKeyMetaDataFileLocation() { return keyStoreParameters.getKeyMetaDataFileLocation(); } protected InputStream getKeyStoreStream(String location) throws FileNotFoundException { if (location == null) { return null; } return keyResourceLoader.getKeyStore(location); } protected KeyInfoManager getKeyInfoManager(String metadataFileLocation) throws FileNotFoundException, IOException { return new KeyInfoManager(metadataFileLocation, keyResourceLoader); } protected KeyMap cacheKeys(KeyStore ks, KeyInfoManager keyInfoManager) throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException { KeyMap keys = new KeyMap(); // load and cache the keys for (Entry<String, KeyInformation> keyEntry : keyInfoManager.getKeyInfo().entrySet()) { String keyAlias = keyEntry.getKey(); KeyInformation keyInfo = keyInfoManager.getKeyInformation(keyAlias); String passwordStr = keyInfo != null ? keyInfo.getPassword() : null; // Null is an acceptable value (means no key) Key key = null; // Attempt to get the key key = ks.getKey(keyAlias, passwordStr == null ? null : passwordStr.toCharArray()); if (key != null) { keys.setKey(keyAlias, key); } // Key loaded if (logger.isDebugEnabled()) { logger.debug( "Retrieved key from keystore: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType() + "\n" + " Alias: " + keyAlias + "\n" + " Password?: " + (passwordStr != null)); Certificate[] certs = ks.getCertificateChain(keyAlias); if (certs != null) { logger.debug("Certificate chain '" + keyAlias + "':"); for (int c = 0; c < certs.length; c++) { if (certs[c] instanceof X509Certificate) { X509Certificate cert = (X509Certificate) certs[c]; logger.debug(" Certificate " + (c + 1) + ":"); logger.debug(" Subject DN: " + cert.getSubjectDN()); logger.debug(" Signature Algorithm: " + cert.getSigAlgName()); logger.debug(" Valid from: " + cert.getNotBefore()); logger.debug(" Valid until: " + cert.getNotAfter()); logger.debug(" Issuer: " + cert.getIssuerDN()); } } } } } return keys; } protected KeyStore initialiseKeyStore(String type, String provider) { KeyStore ks = null; try { if (provider == null || provider.equals("")) { ks = KeyStore.getInstance(type); } else { ks = KeyStore.getInstance(type, provider); } ks.load(null, null); return ks; } catch (Throwable e) { throw new AlfrescoRuntimeException("Unable to intialise key store", e); } } protected KeyStore loadKeyStore(KeyStoreParameters keyStoreParameters, KeyInfoManager keyInfoManager) { String pwdKeyStore = null; try { KeyStore ks = initialiseKeyStore(keyStoreParameters.getType(), keyStoreParameters.getProvider()); // Load it up InputStream is = getKeyStoreStream(keyStoreParameters.getLocation()); if (is != null) { try { // Get the keystore password pwdKeyStore = keyInfoManager.getKeyStorePassword(); ks.load(is, pwdKeyStore == null ? null : pwdKeyStore.toCharArray()); } finally { try { is.close(); } catch (Throwable e) { } } } else { // this is ok, the keystore will contain no keys. logger.warn("Keystore file doesn't exist: " + keyStoreParameters.getLocation()); } return ks; } catch (Throwable e) { throw new AlfrescoRuntimeException("Unable to load key store: " + keyStoreParameters.getLocation(), e); } finally { pwdKeyStore = null; } } /** * Initializes class */ private void safeInit() { PropertyCheck.mandatory(this, "location", getKeyStoreParameters().getLocation()); // Make sure we choose the default type, if required if (getKeyStoreParameters().getType() == null) { keyStoreParameters.setType(KeyStore.getDefaultType()); } writeLock.lock(); try { keys = loadKeyStore(keyStoreParameters); backupKeys = loadKeyStore(backupKeyStoreParameters); } finally { writeLock.unlock(); } } private KeyMap loadKeyStore(KeyStoreParameters keyStoreParameters) { InputStream is = null; KeyInfoManager keyInfoManager = null; KeyStore ks = null; if (keyStoreParameters == null) { // empty key map return new KeyMap(); } try { keyInfoManager = getKeyInfoManager(keyStoreParameters.getKeyMetaDataFileLocation()); ks = loadKeyStore(keyStoreParameters, keyInfoManager); // Loaded } catch (Throwable e) { throw new AlfrescoRuntimeException( "Failed to initialize keystore: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType(), e); } finally { if (keyInfoManager != null) { keyInfoManager.clearKeyStorePassword(); } if (is != null) { try { is.close(); } catch (Throwable e) { } } } try { // cache the keys from the keystore KeyMap keys = cacheKeys(ks, keyInfoManager); if (logger.isDebugEnabled()) { logger.debug("Initialized keystore: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType() + "\n" + keys.numKeys() + " keys found"); } return keys; } catch (Throwable e) { throw new AlfrescoRuntimeException("Failed to retrieve keys from keystore: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType() + "\n", e); } finally { // Clear key information keyInfoManager.clear(); } } protected void createKey(String keyAlias) { KeyInfoManager keyInfoManager = null; try { keyInfoManager = getKeyInfoManager(getKeyMetaDataFileLocation()); Key key = getSecretKey(keyInfoManager.getKeyInformation(keyAlias)); encryptionKeysRegistry.registerKey(keyAlias, key); keys.setKey(keyAlias, key); logger.info("Created key: " + keyAlias + "\n in key store: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType()); } catch (Throwable e) { throw new AlfrescoRuntimeException("Failed to create key: " + keyAlias + "\n in key store: \n" + " Location: " + getKeyStoreParameters().getLocation() + "\n" + " Provider: " + getKeyStoreParameters().getProvider() + "\n" + " Type: " + getKeyStoreParameters().getType(), e); } finally { if (keyInfoManager != null) { keyInfoManager.clear(); } } } protected void createKeyStore(KeyStoreParameters keyStoreParameters, KeyMap keys) { KeyInfoManager keyInfoManager = null; try { if (!keyStoreExists(keyStoreParameters.getLocation())) { keyInfoManager = getKeyInfoManager(keyStoreParameters.getKeyMetaDataFileLocation()); KeyStore ks = initialiseKeyStore(keyStoreParameters.getType(), keyStoreParameters.getProvider()); String keyStorePassword = keyInfoManager.getKeyStorePassword(); if (keyStorePassword == null) { throw new AlfrescoRuntimeException("Key store password is null for keystore at location " + getKeyStoreParameters().getLocation() + ", key store meta data location" + getKeyMetaDataFileLocation()); } for (String keyAlias : keys.getKeyAliases()) { KeyInformation keyInfo = keyInfoManager.getKeyInformation(keyAlias); Key key = keys.getKey(keyAlias); if (key == null) { logger.warn("Key with alias " + keyAlias + " is null when creating keystore at location " + keyStoreParameters.getLocation()); } else { ks.setKeyEntry(keyAlias, key, keyInfo.getPassword().toCharArray(), null); } } // try // { // throw new Exception("Keystore creation: " + ); // } // catch(Throwable e) // { // logger.debug(e.getMessage()); // e.printStackTrace(); // } ks.store(new FileOutputStream(keyStoreParameters.getLocation()), keyStorePassword.toCharArray()); } else { logger.warn("Can't create key store " + keyStoreParameters.getLocation() + ", already exists."); } } catch (Throwable e) { throw new AlfrescoRuntimeException("Failed to create keystore: \n" + " Location: " + keyStoreParameters.getLocation() + "\n" + " Provider: " + keyStoreParameters.getProvider() + "\n" + " Type: " + keyStoreParameters.getType(), e); } finally { if (keyInfoManager != null) { keyInfoManager.clear(); } } } /* * For testing */ // void createBackup() // { // createKeyStore(backupKeyStoreParameters, backupKeys); // } private byte[] generateKeyData() { try { SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(System.currentTimeMillis()); byte bytes[] = new byte[DESedeKeySpec.DES_EDE_KEY_LEN]; random.nextBytes(bytes); return bytes; } catch (Exception e) { throw new RuntimeException("Unable to generate secret key", e); } } protected Key getSecretKey(KeyInformation keyInformation) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException { byte[] keyData = keyInformation.getKeyData(); if (keyData == null) { if (keyInformation.getKeyAlgorithm().equals("DESede")) { // no key data provided, generate key data automatically keyData = generateKeyData(); } else { throw new AlfrescoRuntimeException( "Unable to generate secret key: key algorithm is not DESede and no keyData provided"); } } DESedeKeySpec keySpec = new DESedeKeySpec(keyData); SecretKeyFactory kf = SecretKeyFactory.getInstance(keyInformation.getKeyAlgorithm()); SecretKey secretKey = kf.generateSecret(keySpec); return secretKey; } void importPrivateKey(String keyAlias, String keyPassword, InputStream fl, InputStream certstream) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, CertificateException, KeyStoreException { KeyInfoManager keyInfoManager = null; writeLock.lock(); try { keyInfoManager = getKeyInfoManager(getKeyMetaDataFileLocation()); KeyStore ks = loadKeyStore(getKeyStoreParameters(), keyInfoManager); // loading Key byte[] keyBytes = new byte[fl.available()]; KeyFactory kf = KeyFactory.getInstance("RSA"); fl.read(keyBytes, 0, fl.available()); fl.close(); PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(keyBytes); PrivateKey key = kf.generatePrivate(keysp); // loading CertificateChain CertificateFactory cf = CertificateFactory.getInstance("X.509"); @SuppressWarnings("rawtypes") Collection c = cf.generateCertificates(certstream); Certificate[] certs = new Certificate[c.toArray().length]; certs = (Certificate[]) c.toArray(new Certificate[0]); // storing keystore ks.setKeyEntry(keyAlias, key, keyPassword.toCharArray(), certs); if (logger.isDebugEnabled()) { logger.debug("Key and certificate stored."); logger.debug("Alias:" + keyAlias); } ks.store(new FileOutputStream(getKeyStoreParameters().getLocation()), keyPassword.toCharArray()); } finally { if (keyInfoManager != null) { keyInfoManager.clear(); } writeLock.unlock(); } } public boolean backupExists() { return keyStoreExists(getBackupKeyStoreParameters().getLocation()); } protected boolean keyStoreExists(String location) { try { InputStream is = getKeyStoreStream(location); if (is == null) { return false; } else { try { is.close(); } catch (Throwable e) { } return true; } } catch (FileNotFoundException e) { return false; } } /* * Validates the keystore keys against the key registry, throwing exceptions if the keys have been unintentionally changed. * * For each key to validate: * * (i) no main key, no backup key, the key is registered for the main keystore -> error, must re-instate the keystore * (ii) no main key, no backup key, the key is not registered -> create the main key store and register the key * (iii) main key exists but is not registered -> register the key * (iv) main key exists, no backup key, the key is registered -> check that the key has not changed - if it has, throw an exception * (v) main key exists, backup key exists, the key is registered -> check in the registry that the backup key has not changed and then re-register main key */ protected void validateKeys(KeyMap keys, KeyMap backupKeys) throws InvalidKeystoreException, MissingKeyException { if (!validateKeyChanges) { return; } writeLock.lock(); try { // check for the existence of a key store first for (String keyAlias : keysToValidate) { if (keys.getKey(keyAlias) == null) { if (backupKeys.getKey(keyAlias) == null) { if (encryptionKeysRegistry.isKeyRegistered(keyAlias)) { // The key is registered and neither key nor backup key exist -> throw // an exception indicating that the key is missing and the keystore should // be re-instated. throw new MissingKeyException(keyAlias, getKeyStoreParameters().getLocation()); } else { // Neither the key nor the backup key exist, so create the key createKey(keyAlias); } } } else { if (!encryptionKeysRegistry.isKeyRegistered(keyAlias)) { // The key is not registered, so register it encryptionKeysRegistry.registerKey(keyAlias, keys.getKey(keyAlias)); } else if (backupKeys.getKey(keyAlias) == null && encryptionKeysRegistry.checkKey(keyAlias, keys.getKey(keyAlias)) == KEY_STATUS.CHANGED) { // A key has been changed, indicating that the keystore has been un-intentionally changed. // Note: this will halt the application bootstrap. throw new InvalidKeystoreException("The key with alias " + keyAlias + " has been changed, re-instate the previous keystore"); } else if (backupKeys.getKey(keyAlias) != null && encryptionKeysRegistry.isKeyRegistered(keyAlias)) { // Both key and backup key exist and the key is registered. if (encryptionKeysRegistry.checkKey(keyAlias, backupKeys.getKey(keyAlias)) == KEY_STATUS.OK) { // The registered key is the backup key so lets re-register the key in the main key store. // Unregister the existing (now backup) key and re-register the main key. encryptionKeysRegistry.unregisterKey(keyAlias); encryptionKeysRegistry.registerKey(keyAlias, keys.getKey(keyAlias)); } } } } } finally { writeLock.unlock(); } } public static class KeyInformation { protected String alias; protected byte[] keyData; protected String password; protected String keyAlgorithm; public KeyInformation(String alias, byte[] keyData, String password, String keyAlgorithm) { super(); this.alias = alias; this.keyData = keyData; this.password = password; this.keyAlgorithm = keyAlgorithm; } public String getAlias() { return alias; } public byte[] getKeyData() { return keyData; } public String getPassword() { return password; } public String getKeyAlgorithm() { return keyAlgorithm; } } /* * Caches key meta data information such as password, seed. * */ public static class KeyInfoManager { private KeyResourceLoader keyResourceLoader; private String metadataFileLocation; private Properties keyProps; private String keyStorePassword = null; private Map<String, KeyInformation> keyInfo; /** * For testing. * * @param passwords */ KeyInfoManager(Map<String, String> passwords, KeyResourceLoader keyResourceLoader) { this.keyResourceLoader = keyResourceLoader; keyInfo = new HashMap<String, KeyInformation>(2); for (Map.Entry<String, String> password : passwords.entrySet()) { keyInfo.put(password.getKey(), new KeyInformation(password.getKey(), null, password.getValue(), null)); } } KeyInfoManager(String metadataFileLocation, KeyResourceLoader keyResourceLoader) throws IOException, FileNotFoundException { this.keyResourceLoader = keyResourceLoader; this.metadataFileLocation = metadataFileLocation; keyInfo = new HashMap<String, KeyInformation>(2); loadKeyMetaData(); } public Map<String, KeyInformation> getKeyInfo() { // TODO defensively copy return keyInfo; } /** * Set the map of key meta data (including passwords to access the keystore). * <p/> * Where required, <tt>null</tt> values must be inserted into the map to indicate the presence * of a key that is not protected by a password. They entry for {@link #KEY_KEYSTORE_PASSWORD} * is required if the keystore is password protected. */ protected void loadKeyMetaData() throws IOException, FileNotFoundException { keyProps = keyResourceLoader.loadKeyMetaData(metadataFileLocation); if (keyProps != null) { String aliases = keyProps.getProperty("aliases"); if (aliases == null) { throw new AlfrescoRuntimeException("Passwords file must contain an aliases key"); } this.keyStorePassword = keyProps.getProperty(KEY_KEYSTORE_PASSWORD); StringTokenizer st = new StringTokenizer(aliases, ","); while (st.hasMoreTokens()) { String keyAlias = st.nextToken(); keyInfo.put(keyAlias, loadKeyInformation(keyAlias)); } } else { // TODO //throw new FileNotFoundException("Cannot find key metadata file " + getKeyMetaDataFileLocation()); } } public void clear() { this.keyStorePassword = null; if (this.keyProps != null) { this.keyProps.clear(); } } public void removeKeyInformation(String keyAlias) { this.keyProps.remove(keyAlias); } protected KeyInformation loadKeyInformation(String keyAlias) { String keyPassword = keyProps.getProperty(keyAlias + ".password"); String keyData = keyProps.getProperty(keyAlias + ".keyData"); String keyAlgorithm = keyProps.getProperty(keyAlias + ".algorithm"); byte[] keyDataBytes = null; if (keyData != null && !keyData.equals("")) { keyDataBytes = Base64.decodeBase64(keyData); } KeyInformation keyInfo = new KeyInformation(keyAlias, keyDataBytes, keyPassword, keyAlgorithm); return keyInfo; } public String getKeyStorePassword() { return keyStorePassword; } public void clearKeyStorePassword() { this.keyStorePassword = null; } public KeyInformation getKeyInformation(String keyAlias) { return keyInfo.get(keyAlias); } } }