/** Create LockssKeystores from config subtree below {@link #PARAM_KEYSTORE} */ void configureKeyStores(Configuration config) { Configuration allKs = config.getConfigTree(PARAM_KEYSTORE); for (Iterator iter = allKs.nodeIterator(); iter.hasNext(); ) { String id = (String) iter.next(); Configuration oneKs = allKs.getConfigTree(id); try { LockssKeyStore lk = createLockssKeyStore(oneKs); String name = lk.getName(); if (name == null) { log.error("KeyStore definition missing name: " + oneKs); continue; } LockssKeyStore old = keystoreMap.get(name); if (old != null && !lk.equals(old)) { log.warning( "Keystore " + name + " redefined. " + "New definition may not take effect until daemon restart"); } log.debug("Adding keystore " + name); keystoreMap.put(name, lk); } catch (Exception e) { log.error("Couldn't create keystore: " + oneKs, e); } } }
/** Create LockssKeystore from a config subtree */ LockssKeyStore createLockssKeyStore(Configuration config) { log.debug2("Creating LockssKeyStore from config: " + config); String name = config.get(KEYSTORE_PARAM_NAME); LockssKeyStore lk = new LockssKeyStore(name); String file = config.get(KEYSTORE_PARAM_FILE); String resource = config.get(KEYSTORE_PARAM_RESOURCE); String url = config.get(KEYSTORE_PARAM_URL); if (!StringUtil.isNullString(file)) { lk.setLocation(file, LocationType.File); } else if (!StringUtil.isNullString(resource)) { lk.setLocation(resource, LocationType.Resource); } else if (!StringUtil.isNullString(url)) { lk.setLocation(url, LocationType.Url); } lk.setType(config.get(KEYSTORE_PARAM_TYPE, defaultKeyStoreType)); lk.setProvider(config.get(KEYSTORE_PARAM_PROVIDER, defaultKeyStoreProvider)); lk.setPassword(config.get(KEYSTORE_PARAM_PASSWORD)); lk.setKeyPassword(config.get(KEYSTORE_PARAM_KEY_PASSWORD)); lk.setKeyPasswordFile(config.get(KEYSTORE_PARAM_KEY_PASSWORD_FILE)); lk.setMayCreate(config.getBoolean(KEYSTORE_PARAM_CREATE, DEFAULT_CREATE)); return lk; }
void loadKeyStores() { List<LockssKeyStore> lst = new ArrayList<LockssKeyStore>(keystoreMap.values()); for (LockssKeyStore lk : lst) { try { lk.load(); } catch (Exception e) { log.error("Can't load keystore " + lk.getName(), e); keystoreMap.remove(lk.getName()); } } }
private void checkFact(Object fact, String name, String criticalServiceName, String message) { if (fact == null && criticalServiceName != null) { String msg = StringUtil.isNullString(name) ? ("No keystore name given for critical keystore" + " needed for service " + criticalServiceName + ", daemon exiting") : ("Critical keystore " + name + " " + ((message != null) ? message : "not found or not loadable") + " for service " + criticalServiceName + ", daemon exiting"); log.critical(msg); if (paramExitIfMissingKeyStore) { System.exit(Constants.EXIT_CODE_KEYSTORE_MISSING); } else { throw new IllegalArgumentException(msg); } } }
/** Central repository of loaded keystores */ public class LockssKeyStoreManager extends BaseLockssDaemonManager implements ConfigurableManager { protected static Logger log = Logger.getLogger("LockssKeyStoreManager"); static final String PREFIX = Configuration.PREFIX + "keyMgr."; /** Default type for newly created keystores. */ public static final String PARAM_DEFAULT_KEYSTORE_TYPE = PREFIX + "defaultKeyStoreType"; public static final String DEFAULT_DEFAULT_KEYSTORE_TYPE = "JCEKS"; /** Default keystore provider. */ public static final String PARAM_DEFAULT_KEYSTORE_PROVIDER = PREFIX + "defaultKeyStoreProvider"; public static final String DEFAULT_DEFAULT_KEYSTORE_PROVIDER = null; /** * Root of keystore definitions. For each keystore, pick a unique identifier and use it in place * of <id> in the following */ public static final String PARAM_KEYSTORE = PREFIX + "keystore"; /** If true the daemon will exit if a critical keystore is missing. */ public static final String PARAM_EXIT_IF_MISSING_KEYSTORE = PREFIX + "exitIfMissingKeystore"; public static final boolean DEFAULT_EXIT_IF_MISSING_KEYSTORE = true; /** keystore name, used by clients to refer to it */ public static final String KEYSTORE_PARAM_NAME = "name"; /** keystore file. Only one of file, resource or url should be set */ public static final String KEYSTORE_PARAM_FILE = "file"; /** keystore resource. Only one of file, resource or url should be set */ public static final String KEYSTORE_PARAM_RESOURCE = "resource"; /** keystore url. Only one of file, resource or url should be set */ public static final String KEYSTORE_PARAM_URL = "url"; /** keystore type */ public static final String KEYSTORE_PARAM_TYPE = "type"; /** keystore provider */ public static final String KEYSTORE_PARAM_PROVIDER = "provider"; /** keystore password */ public static final String KEYSTORE_PARAM_PASSWORD = "******"; /** private key password */ public static final String KEYSTORE_PARAM_KEY_PASSWORD = "******"; /** private key password file */ public static final String KEYSTORE_PARAM_KEY_PASSWORD_FILE = "keyPasswordFile"; /** * If true, and the keystore doesn't exist, a keystore with a self-signed certificate will be be * created. */ public static final String KEYSTORE_PARAM_CREATE = "create"; protected String defaultKeyStoreType = DEFAULT_DEFAULT_KEYSTORE_TYPE; protected String defaultKeyStoreProvider = DEFAULT_DEFAULT_KEYSTORE_PROVIDER; protected boolean paramExitIfMissingKeyStore = DEFAULT_EXIT_IF_MISSING_KEYSTORE; // Pseudo params for param doc public static final String DOC_PREFIX = PARAM_KEYSTORE + ".<id>."; /** Name by which daemon component(s) refer to this keystore */ public static final String PARAM_KEYSTORE_NAME = DOC_PREFIX + KEYSTORE_PARAM_NAME; /** Keystore filename. Only one of file, resource or url should be set */ public static final String PARAM_KEYSTORE_FILE = DOC_PREFIX + KEYSTORE_PARAM_FILE; /** Keystore resource. Only one of file, resource or url should be set */ public static final String PARAM_KEYSTORE_RESOURCE = DOC_PREFIX + KEYSTORE_PARAM_RESOURCE; /** Keystore url. Only one of file, resource or url should be set */ public static final String PARAM_KEYSTORE_URL = DOC_PREFIX + KEYSTORE_PARAM_URL; /** Keystore type (JKS, JCEKS, etc.) */ public static final String PARAM_KEYSTORE_TYPE = DOC_PREFIX + KEYSTORE_PARAM_TYPE; /** Keystore provider (SunJCE, etc.) */ public static final String PARAM_KEYSTORE_PROVIDER = DOC_PREFIX + KEYSTORE_PARAM_PROVIDER; /** Keystore password. Default is machine's fqdn */ public static final String PARAM_KEYSTORE_PASSWORD = DOC_PREFIX + KEYSTORE_PARAM_PASSWORD; /** Private key password */ public static final String PARAM_KEYSTORE_KEY_PASSWORD = DOC_PREFIX + KEYSTORE_PARAM_KEY_PASSWORD; /** private key password file */ public static final String PARAM_KEYSTORE_KEY_PASSWORD_FILE = DOC_PREFIX + KEYSTORE_PARAM_KEY_PASSWORD_FILE; /** * If true, and the keystore doesn't exist, a keystore with a self-signed certificate will be be * created. */ public static final String PARAM_KEYSTORE_CREATE = DOC_PREFIX + KEYSTORE_PARAM_CREATE; public static boolean DEFAULT_CREATE = false; protected Map<String, LockssKeyStore> keystoreMap = new HashMap<String, LockssKeyStore>(); public void startService() { super.startService(); loadKeyStores(); } public synchronized void setConfig( Configuration config, Configuration prevConfig, Configuration.Differences changedKeys) { if (changedKeys.contains(PREFIX)) { defaultKeyStoreType = config.get(PARAM_DEFAULT_KEYSTORE_TYPE, DEFAULT_DEFAULT_KEYSTORE_TYPE); defaultKeyStoreProvider = config.get(PARAM_DEFAULT_KEYSTORE_PROVIDER, DEFAULT_DEFAULT_KEYSTORE_PROVIDER); paramExitIfMissingKeyStore = config.getBoolean(PARAM_EXIT_IF_MISSING_KEYSTORE, DEFAULT_EXIT_IF_MISSING_KEYSTORE); if (changedKeys.contains(PARAM_KEYSTORE)) { configureKeyStores(config); // defer initial set of keystore loading until startService if (isInited()) { // load any newly added keystores loadKeyStores(); } } } } /** * Return the named LockssKeyStore or null * * @param name the keystore name */ public LockssKeyStore getLockssKeyStore(String name) { return getLockssKeyStore(name, null); } /** * Return the named LockssKeyStore * * @param name the keystore name * @param criticalServiceName if non-null, this is a criticial keystore whose unavailability * should cause the daemon to exit (if org.lockss.keyMgr.exitIfMissingKeystore is true) */ public LockssKeyStore getLockssKeyStore(String name, String criticalServiceName) { LockssKeyStore res = keystoreMap.get(name); checkFact(res, name, criticalServiceName, null); return res; } /** * Convenience method to return the KeyManagerFactory from the named LockssKeyStore, or null * * @param name the keystore name */ public KeyManagerFactory getKeyManagerFactory(String name) { return getKeyManagerFactory(name, null); } /** * Convenience method to return the KeyManagerFactory from the named LockssKeyStore. * * @param name the keystore name * @param criticalServiceName if non-null, this is a criticial keystore whose unavailability * should cause the daemon to exit (if org.lockss.keyMgr.exitIfMissingKeystore is true) */ public KeyManagerFactory getKeyManagerFactory(String name, String criticalServiceName) { LockssKeyStore lk = getLockssKeyStore(name, criticalServiceName); if (lk != null) { KeyManagerFactory fact = lk.getKeyManagerFactory(); checkFact(fact, name, criticalServiceName, "found but contains no private keys"); return fact; } return null; } /** Convenience method to return the TrustManagerFactory from the named LockssKeyStore, or null */ public TrustManagerFactory getTrustManagerFactory(String name) { return getTrustManagerFactory(name, null); } /** * Convenience method to return the TrustManagerFactory from the named LockssKeyStore. * * @param name the keystore name * @param criticalServiceName if non-null, this is a criticial keystore whose unavailability * should cause the daemon to exit (if org.lockss.keyMgr.exitIfMissingKeystore is true) */ public TrustManagerFactory getTrustManagerFactory(String name, String criticalServiceName) { LockssKeyStore lk = getLockssKeyStore(name, criticalServiceName); if (lk != null) { TrustManagerFactory fact = lk.getTrustManagerFactory(); checkFact(fact, name, criticalServiceName, "found but contains no trusted certificates"); return fact; } return null; } private void checkFact(Object fact, String name, String criticalServiceName, String message) { if (fact == null && criticalServiceName != null) { String msg = StringUtil.isNullString(name) ? ("No keystore name given for critical keystore" + " needed for service " + criticalServiceName + ", daemon exiting") : ("Critical keystore " + name + " " + ((message != null) ? message : "not found or not loadable") + " for service " + criticalServiceName + ", daemon exiting"); log.critical(msg); if (paramExitIfMissingKeyStore) { System.exit(Constants.EXIT_CODE_KEYSTORE_MISSING); } else { throw new IllegalArgumentException(msg); } } } /** Create LockssKeystores from config subtree below {@link #PARAM_KEYSTORE} */ void configureKeyStores(Configuration config) { Configuration allKs = config.getConfigTree(PARAM_KEYSTORE); for (Iterator iter = allKs.nodeIterator(); iter.hasNext(); ) { String id = (String) iter.next(); Configuration oneKs = allKs.getConfigTree(id); try { LockssKeyStore lk = createLockssKeyStore(oneKs); String name = lk.getName(); if (name == null) { log.error("KeyStore definition missing name: " + oneKs); continue; } LockssKeyStore old = keystoreMap.get(name); if (old != null && !lk.equals(old)) { log.warning( "Keystore " + name + " redefined. " + "New definition may not take effect until daemon restart"); } log.debug("Adding keystore " + name); keystoreMap.put(name, lk); } catch (Exception e) { log.error("Couldn't create keystore: " + oneKs, e); } } } /** Create LockssKeystore from a config subtree */ LockssKeyStore createLockssKeyStore(Configuration config) { log.debug2("Creating LockssKeyStore from config: " + config); String name = config.get(KEYSTORE_PARAM_NAME); LockssKeyStore lk = new LockssKeyStore(name); String file = config.get(KEYSTORE_PARAM_FILE); String resource = config.get(KEYSTORE_PARAM_RESOURCE); String url = config.get(KEYSTORE_PARAM_URL); if (!StringUtil.isNullString(file)) { lk.setLocation(file, LocationType.File); } else if (!StringUtil.isNullString(resource)) { lk.setLocation(resource, LocationType.Resource); } else if (!StringUtil.isNullString(url)) { lk.setLocation(url, LocationType.Url); } lk.setType(config.get(KEYSTORE_PARAM_TYPE, defaultKeyStoreType)); lk.setProvider(config.get(KEYSTORE_PARAM_PROVIDER, defaultKeyStoreProvider)); lk.setPassword(config.get(KEYSTORE_PARAM_PASSWORD)); lk.setKeyPassword(config.get(KEYSTORE_PARAM_KEY_PASSWORD)); lk.setKeyPasswordFile(config.get(KEYSTORE_PARAM_KEY_PASSWORD_FILE)); lk.setMayCreate(config.getBoolean(KEYSTORE_PARAM_CREATE, DEFAULT_CREATE)); return lk; } void loadKeyStores() { List<LockssKeyStore> lst = new ArrayList<LockssKeyStore>(keystoreMap.values()); for (LockssKeyStore lk : lst) { try { lk.load(); } catch (Exception e) { log.error("Can't load keystore " + lk.getName(), e); keystoreMap.remove(lk.getName()); } } } }