opendj-server-legacy/src/main/java/org/opends/server/backends/TrustStoreBackend.java
@@ -101,7 +101,6 @@ implements ConfigurationChangeListener<TrustStoreBackendCfg> { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The current configuration state. */ private TrustStoreBackendCfg configuration; /** The set of base DNs for this backend. */ @@ -178,12 +177,9 @@ trustStoreType, configEntryDN, getExceptionMessage(kse))); } trustStorePIN = getTrustStorePIN(configEntryDN); certificateManager = new CertificateManager(getFileForPath(trustStoreFile).getPath(), trustStoreType, new String(trustStorePIN)); trustStorePIN = getTrustStorePIN(configuration, true); final String keyStorePath = getFileForPath(trustStoreFile).getPath(); certificateManager = new CertificateManager(keyStorePath, trustStoreType, trustStorePIN); // Generate a self-signed certificate, if there is none. generateInstanceCertificateIfAbsent(); @@ -218,71 +214,85 @@ } /** * Get the PIN needed to access the contents of the trust store file. We will offer several places * to look for the PIN, and we will do so in the following order: * Returns the PIN needed to access the contents of a key store. We will offer several places to look for the PIN, * and we will do so in the following order: * <ol> * <li>In a specified Java property</li> * <li>In a specified environment variable</li> * <li>In a specified file on the server filesystem</li> * <li>As the value of a configuration attribute</li> * <li>In a specified Java property</li> * <li>In a specified environment variable</li> * <li>In a specified file on the server filesystem</li> * <li>As the value of a configuration attribute.</li> * </ol> * In any case, the PIN must be in the clear. If no PIN is provided, then it will be assumed that * none is required to access the information in the trust store. * In any case, the PIN must be in the clear. * <p> * It is acceptable to have no PIN (OPENDJ-18). */ private char[] getTrustStorePIN(DN configEntryDN) throws InitializationException { final String pinProperty = configuration.getTrustStorePinProperty(); private static char[] getTrustStorePIN(TrustStoreBackendCfg cfg, boolean createPinFileIfNeeded) throws InitializationException { final String pinProperty = cfg.getTrustStorePinProperty(); if (pinProperty != null) { String pinStr = System.getProperty(pinProperty); if (pinStr == null) { throw new InitializationException(ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(pinProperty, configEntryDN)); } return pinStr.toCharArray(); final String pin = System.getProperty(pinProperty); if (pin == null) { throw new InitializationException(ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(pinProperty, cfg.dn())); } return pin.toCharArray(); } final String pinEnVar = configuration.getTrustStorePinEnvironmentVariable(); if (pinEnVar != null) final String pinEnvVar = cfg.getTrustStorePinEnvironmentVariable(); if (pinEnvVar != null) { String pinStr = System.getenv(pinEnVar); if (pinStr == null) { throw new InitializationException(ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(pinProperty, configEntryDN)); } return pinStr.toCharArray(); final String pin = System.getenv(pinEnvVar); if (pin == null) { throw new InitializationException(ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(pinEnvVar, cfg.dn())); } return pin.toCharArray(); } final String pinFilePath = configuration.getTrustStorePinFile(); if (pinFilePath != null) final String pinFileName = cfg.getTrustStorePinFile(); if (pinFileName != null) { File pinFile = getFileForPath(pinFilePath); final File pinFile = getFileForPath(pinFileName); if (pinFile.exists()) { String pinStr = readPinFromFile(pinFile, configEntryDN); if (pinStr == null) String pin; try (BufferedReader br = new BufferedReader(new FileReader(pinFile))) { throw new InitializationException(ERR_TRUSTSTORE_PIN_FILE_EMPTY.get(pinFilePath, configEntryDN)); pin = br.readLine(); } return pinStr.toCharArray(); catch (IOException e) { final LocalizableMessage msg = ERR_TRUSTSTORE_PIN_FILE_CANNOT_READ.get(pinFileName, cfg.dn(), getExceptionMessage(e)); throw new InitializationException(msg, e); } if (pin == null) { throw new InitializationException(ERR_TRUSTSTORE_PIN_FILE_EMPTY.get(pinFileName, cfg.dn())); } return pin.toCharArray(); } try else if (createPinFileIfNeeded) { // Generate and store the PIN in the pin file. final char[] trustStorePIN = createKeystorePassword(); createPINFile(pinFile.getPath(), new String(trustStorePIN)); return trustStorePIN; try { // Generate and store the PIN in the pin file. final char[] trustStorePIN1 = createKeystorePassword(); createPINFile(pinFile.getPath(), new String(trustStorePIN1)); return trustStorePIN1; } catch (Exception e) { throw new InitializationException(ERR_TRUSTSTORE_PIN_FILE_CANNOT_CREATE.get(pinFileName, cfg.dn())); } } catch (Exception e) else { throw new InitializationException(ERR_TRUSTSTORE_PIN_FILE_CANNOT_CREATE.get(pinFilePath, configEntryDN)); return null; } } String pinStr = configuration.getTrustStorePin(); // else branch should be an Error. Otherwise, programs fails. Is there a Unit Test? return pinStr != null ? pinStr.toCharArray() : null; return cfg.getTrustStorePin() != null ? cfg.getTrustStorePin().toCharArray() : null; } @Override @@ -663,7 +673,6 @@ public boolean isConfigurationChangeAcceptable( TrustStoreBackendCfg configuration, List<LocalizableMessage> unacceptableReasons) { final ConfigChangeResult ccr = new ConfigChangeResult(); final DN cfgEntryDN = configuration.dn(); // Get the path to the trust store file. @@ -673,14 +682,14 @@ File f = getFileForPath(newTrustStoreFile); if (!f.exists() || !f.isFile()) { ccr.addMessage(ERR_TRUSTSTORE_NO_SUCH_FILE.get(newTrustStoreFile, cfgEntryDN)); unacceptableReasons.add(ERR_TRUSTSTORE_NO_SUCH_FILE.get(newTrustStoreFile, cfgEntryDN)); } } catch (Exception e) { logger.traceException(e); ccr.addMessage(ERR_TRUSTSTORE_CANNOT_DETERMINE_FILE.get(cfgEntryDN, getExceptionMessage(e))); unacceptableReasons.add(ERR_TRUSTSTORE_CANNOT_DETERMINE_FILE.get(cfgEntryDN, getExceptionMessage(e))); } // Check to see if the trust store type is acceptable. @@ -695,44 +704,20 @@ { logger.traceException(kse); ccr.addMessage(ERR_TRUSTSTORE_INVALID_TYPE.get(storeType, cfgEntryDN, getExceptionMessage(kse))); unacceptableReasons.add(ERR_TRUSTSTORE_INVALID_TYPE.get(storeType, cfgEntryDN, getExceptionMessage(kse))); } } // If there is a PIN property, then make sure the corresponding // property is set. String pinProp = configuration.getTrustStorePinProperty(); if (pinProp != null && System.getProperty(pinProp) == null) try { ccr.addMessage(ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(pinProp, cfgEntryDN)); getTrustStorePIN(configuration, false); } catch (InitializationException e) { unacceptableReasons.add(e.getMessageObject()); } // If there is a PIN environment variable, then make sure the corresponding // environment variable is set. String pinEnVar = configuration.getTrustStorePinEnvironmentVariable(); if (pinEnVar != null && System.getenv(pinEnVar) == null) { ccr.addMessage(ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(pinEnVar, cfgEntryDN)); } // If there is a PIN file, then make sure the file is readable if it exists. String pinFile = configuration.getTrustStorePinFile(); if (pinFile != null) { File f = new File(pinFile); if (f.exists()) { String pinStr = readPinFromFile2(f, cfgEntryDN, ccr); if (pinStr == null) { ccr.addMessage(ERR_TRUSTSTORE_PIN_FILE_EMPTY.get(pinFile, cfgEntryDN)); } } } final List<LocalizableMessage> messages = ccr.getMessages(); unacceptableReasons.addAll(messages); return messages.isEmpty(); return unacceptableReasons.isEmpty(); } @Override @@ -770,7 +755,16 @@ ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); } char[] newPIN = getTrustStorePIN2(cfg, ccr); char[] newPIN = null; try { newPIN = getTrustStorePIN(cfg, true); } catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(e.getMessageObject()); } if (ccr.getResultCode() == ResultCode.SUCCESS) { @@ -778,142 +772,14 @@ trustStoreType = newTrustStoreType; trustStorePIN = newPIN; configuration = cfg; certificateManager = new CertificateManager(getFileForPath(trustStoreFile).getPath(), trustStoreType, new String(trustStorePIN)); final String keyStorePath = getFileForPath(trustStoreFile).getPath(); certificateManager = new CertificateManager(keyStorePath, trustStoreType, trustStorePIN); } return ccr; } /** * Get the PIN needed to access the contents of the trust store file. We will offer several places * to look for the PIN, and we will do so in the following order: * <ol> * <li>In a specified Java property</li> * <li>In a specified environment variable</li> * <li>In a specified file on the server filesystem.</li> * <li>As the value of a configuration attribute.</li> * </ol> * In any case, the PIN must be in the clear. If no PIN is provided, then it will be assumed that * none is required to access the information in the trust store. */ private char[] getTrustStorePIN2(TrustStoreBackendCfg cfg, ConfigChangeResult ccr) { String newPINProperty = cfg.getTrustStorePinProperty(); if (newPINProperty == null) { String newPINEnVar = cfg.getTrustStorePinEnvironmentVariable(); if (newPINEnVar == null) { String newPINFile = cfg.getTrustStorePinFile(); if (newPINFile == null) { String pinStr = cfg.getTrustStorePin(); return pinStr != null ? pinStr.toCharArray() : null; } else { File pinFile = getFileForPath(newPINFile); if (! pinFile.exists()) { try { // Generate and store a PIN in the pin file. final char[] newPIN = createKeystorePassword(); createPINFile(pinFile.getPath(), new String(newPIN)); return newPIN; } catch (Exception e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_TRUSTSTORE_PIN_FILE_CANNOT_CREATE.get(newPINFile, cfg.dn())); } } else { String pinStr = readPinFromFile2(pinFile, cfg.dn(), ccr); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_TRUSTSTORE_PIN_FILE_EMPTY.get(newPINFile, cfg.dn())); } else { return pinStr.toCharArray(); } } } } else { String pinStr = System.getenv(newPINEnVar); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_TRUSTSTORE_PIN_ENVAR_NOT_SET.get(newPINEnVar, cfg.dn())); } else { return pinStr.toCharArray(); } } } else { String pinStr = System.getProperty(newPINProperty); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_TRUSTSTORE_PIN_PROPERTY_NOT_SET.get(newPINProperty, cfg.dn())); } else { return pinStr.toCharArray(); } } return null; } private String readPinFromFile(File pinFile, DN cfgEntryDN) throws InitializationException { try (BufferedReader br = new BufferedReader(new FileReader(pinFile))) { return br.readLine(); } catch (IOException ioe) { LocalizableMessage message = ERR_TRUSTSTORE_PIN_FILE_CANNOT_READ.get(pinFile, cfgEntryDN, getExceptionMessage(ioe)); throw new InitializationException(message, ioe); } } private String readPinFromFile2(File pinFile, DN cfgEntryDN, ConfigChangeResult ccr) { try (BufferedReader br = new BufferedReader(new FileReader(pinFile))) { return br.readLine(); } catch (IOException ioe) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_TRUSTSTORE_PIN_FILE_CANNOT_READ.get(pinFile, cfgEntryDN, getExceptionMessage(ioe))); return null; } } /** * Create a new child DN from a given parent DN. The child RDN is formed * from a given attribute type and string value. * @param parentDN The DN of the parent. * @param rdnAttrType The attribute type of the RDN. * @param rdnStringValue The string value of the RDN. * @return A new child DN. */ public static DN makeChildDN(DN parentDN, AttributeType rdnAttrType, String rdnStringValue) private static DN makeChildDN(DN parentDN, AttributeType rdnAttrType, String rdnStringValue) { ByteString attrValue = ByteString.valueOfUtf8(rdnStringValue); return parentDN.child(new RDN(rdnAttrType, attrValue)); @@ -1264,13 +1130,7 @@ return random.nextInt() & modulo; } /** * Creates a PIN file on the specified path. * @param path the path where the PIN file will be created. * @param pin The PIN to store in the file. * @throws IOException if something goes wrong. */ public static void createPINFile(String path, String pin) private static void createPINFile(String path, String pin) throws IOException { try (final FileWriter file = new FileWriter(path); @@ -1281,8 +1141,7 @@ } try { if (!FilePermission.setPermissions(new File(path), new FilePermission(0600))) if (!FilePermission.setPermissions(new File(path), new FilePermission(0600))) { // Log a warning that the permissions were not set. logger.warn(WARN_TRUSTSTORE_SET_PERMISSIONS_FAILED, path); opendj-server-legacy/src/main/java/org/opends/server/extensions/FileBasedKeyManagerProvider.java
@@ -33,15 +33,17 @@ import javax.net.ssl.KeyManagerFactory; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg2; import org.forgerock.i18n.LocalizableMessageDescriptor.Arg3; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigChangeResult; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.config.server.ConfigurationChangeListener; import org.forgerock.opendj.server.config.server.FileBasedKeyManagerProviderCfg; import org.opends.server.api.KeyManagerProvider; import org.opends.server.core.DirectoryServer; import org.forgerock.opendj.ldap.DN; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; @@ -55,8 +57,6 @@ { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The DN of the configuration entry for this key manager provider. */ private DN configEntryDN; /** The configuration for this key manager provider. */ private FileBasedKeyManagerProviderCfg currentConfig; @@ -78,21 +78,21 @@ } @Override public void initializeKeyManagerProvider( FileBasedKeyManagerProviderCfg configuration) throws ConfigException, InitializationException { // Store the DN of the configuration entry and register as a change listener currentConfig = configuration; configEntryDN = configuration.dn(); configuration.addFileBasedChangeListener(this); public void initializeKeyManagerProvider(FileBasedKeyManagerProviderCfg cfg) throws ConfigException, InitializationException { final ConfigChangeResult ccr = new ConfigChangeResult(); keyStoreFile = getKeyStoreFile(configuration, configEntryDN, ccr); keyStoreType = getKeyStoreType(configuration, configEntryDN, ccr); keyStorePIN = getKeyStorePIN(configuration, configEntryDN, ccr); if (!ccr.getMessages().isEmpty()) { currentConfig = cfg; keyStoreFile = getKeyStoreFile(cfg, ccr); keyStoreType = getKeyStoreType(cfg, ccr); keyStorePIN = getKeyStorePIN(cfg, ccr); if (!ccr.getMessages().isEmpty()) { throw new InitializationException(ccr.getMessages().get(0)); } cfg.addFileBasedChangeListener(this); } @Override @@ -102,20 +102,26 @@ } @Override public boolean containsKeyWithAlias(String alias) { try { public boolean containsKeyWithAlias(String alias) { try { KeyStore keyStore = getKeystore(); Enumeration<String> aliases = keyStore.aliases(); while (aliases.hasMoreElements()) { while (aliases.hasMoreElements()) { String theAlias = aliases.nextElement(); if (alias.equals(theAlias) && keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) { if (alias.equals(theAlias) && keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) { return true; } } } catch (DirectoryException | KeyStoreException e) { catch (DirectoryException | KeyStoreException e) { // Ignore. logger.traceException(e); } return false; } @@ -133,10 +139,7 @@ } catch (Exception e) { logger.traceException(e); LocalizableMessage message = ERR_FILE_KEYMANAGER_CANNOT_LOAD.get( keyStoreFile, getExceptionMessage(e)); LocalizableMessage message = ERR_FILE_KEYMANAGER_CANNOT_LOAD.get(keyStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } @@ -155,8 +158,7 @@ } String keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); keyManagerFactory.init(keyStore, keyStorePIN); return keyManagerFactory.getKeyManagers(); } @@ -164,8 +166,7 @@ { logger.traceException(e); LocalizableMessage message = ERR_FILE_KEYMANAGER_CANNOT_CREATE_FACTORY.get( keyStoreFile, getExceptionMessage(e)); LocalizableMessage message = ERR_FILE_KEYMANAGER_CANNOT_CREATE_FACTORY.get(keyStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } @@ -198,42 +199,38 @@ } @Override public boolean isConfigurationAcceptable( FileBasedKeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) public boolean isConfigurationAcceptable(FileBasedKeyManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { return isConfigurationChangeAcceptable(configuration, unacceptableReasons); return isConfigurationChangeAcceptable(cfg, unacceptableReasons); } @Override public boolean isConfigurationChangeAcceptable( FileBasedKeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) public boolean isConfigurationChangeAcceptable(FileBasedKeyManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { int startSize = unacceptableReasons.size(); DN cfgEntryDN = configuration.dn(); final ConfigChangeResult ccr = new ConfigChangeResult(); getKeyStoreFile(configuration, cfgEntryDN, ccr); getKeyStoreType(configuration, cfgEntryDN, ccr); getKeyStorePIN(configuration, cfgEntryDN, ccr); getKeyStoreFile(cfg, ccr); getKeyStoreType(cfg, ccr); getKeyStorePIN(cfg, ccr); unacceptableReasons.addAll(ccr.getMessages()); return startSize == unacceptableReasons.size(); } @Override public ConfigChangeResult applyConfigurationChange( FileBasedKeyManagerProviderCfg configuration) public ConfigChangeResult applyConfigurationChange(FileBasedKeyManagerProviderCfg cfg) { final ConfigChangeResult ccr = new ConfigChangeResult(); String newKeyStoreFile = getKeyStoreFile(configuration, configEntryDN, ccr); String newKeyStoreType = getKeyStoreType(configuration, configEntryDN, ccr); char[] newPIN = getKeyStorePIN(configuration, configEntryDN, ccr); String newKeyStoreFile = getKeyStoreFile(cfg, ccr); String newKeyStoreType = getKeyStoreType(cfg, ccr); char[] newPIN = getKeyStorePIN(cfg, ccr); if (ccr.getResultCode() == ResultCode.SUCCESS) { currentConfig = configuration; currentConfig = cfg; keyStorePIN = newPIN; keyStoreFile = newKeyStoreFile; keyStoreType = newKeyStoreType; @@ -243,141 +240,127 @@ } /** Get the path to the key store file. */ private String getKeyStoreFile(FileBasedKeyManagerProviderCfg configuration, DN cfgEntryDN, final ConfigChangeResult ccr) private String getKeyStoreFile(FileBasedKeyManagerProviderCfg cfg, ConfigChangeResult ccr) { String keyStoreFile = configuration.getKeyStoreFile(); try String keyStoreFile = cfg.getKeyStoreFile(); File f = getFileForPath(keyStoreFile); if (!f.exists() || !f.isFile()) { File f = getFileForPath(keyStoreFile); if (!f.exists() || !f.isFile()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_NO_SUCH_FILE.get(keyStoreFile, cfgEntryDN)); } } catch (Exception e) { logger.traceException(e); ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE.get(cfgEntryDN, getExceptionMessage(e))); ccr.addMessage(ERR_FILE_KEYMANAGER_NO_SUCH_FILE.get(keyStoreFile, cfg.dn())); } return keyStoreFile; } /** Get the keystore type. If none is specified, then use the default type. */ private String getKeyStoreType(FileBasedKeyManagerProviderCfg configuration, DN cfgEntryDN, final ConfigChangeResult ccr) private String getKeyStoreType(FileBasedKeyManagerProviderCfg cfg, ConfigChangeResult ccr) { if (configuration.getKeyStoreType() != null) if (cfg.getKeyStoreType() != null) { try { KeyStore.getInstance(configuration.getKeyStoreType()); return configuration.getKeyStoreType(); KeyStore.getInstance(cfg.getKeyStoreType()); return cfg.getKeyStoreType(); } catch (KeyStoreException kse) catch (KeyStoreException e) { logger.traceException(kse); logger.traceException(e); ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_INVALID_TYPE.get( configuration.getKeyStoreType(), cfgEntryDN, getExceptionMessage(kse))); ccr.addMessage(ERR_FILE_KEYMANAGER_INVALID_TYPE.get(cfg.getKeyStoreType(), cfg.dn(), getExceptionMessage(e))); } } return KeyStore.getDefaultType(); } /** * Get the PIN needed to access the contents of the keystore file. * <p> * We will offer several places to look for the PIN, and we will do so in the following order: * <ol> * <li>In a specified Java property</li> * <li>In a specified environment variable</li> * <li>In a specified file on the server filesystem</li> * <li>As the value of a configuration attribute.</li> * <ol> * In any case, the PIN must be in the clear. * <p> * It is acceptable to have no PIN (OPENDJ-18) */ private char[] getKeyStorePIN(FileBasedKeyManagerProviderCfg configuration, DN cfgEntryDN, final ConfigChangeResult ccr) private char[] getKeyStorePIN(FileBasedKeyManagerProviderCfg cfg, ConfigChangeResult ccr) { if (configuration.getKeyStorePinProperty() != null) try { String propertyName = configuration.getKeyStorePinProperty(); String pinStr = System.getProperty(propertyName); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET.get(propertyName, cfgEntryDN)); } else { return pinStr.toCharArray(); } return getKeyStorePIN(cfg.getKeyStorePinProperty(), cfg.getKeyStorePinEnvironmentVariable(), cfg.getKeyStorePinFile(), cfg.getKeyStorePin(), cfg.dn(), ERR_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET, ERR_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET, ERR_FILE_KEYMANAGER_PIN_NO_SUCH_FILE, ERR_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ, ERR_FILE_KEYMANAGER_PIN_FILE_EMPTY); } else if (configuration.getKeyStorePinEnvironmentVariable() != null) { String enVarName = configuration.getKeyStorePinEnvironmentVariable(); String pinStr = System.getenv(enVarName); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET.get(enVarName, cfgEntryDN)); } else { return pinStr.toCharArray(); } } else if (configuration.getKeyStorePinFile() != null) { String fileName = configuration.getKeyStorePinFile(); File pinFile = getFileForPath(fileName); if (!pinFile.exists()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_PIN_NO_SUCH_FILE.get(fileName, cfgEntryDN)); } else { String pinStr = readPinFromFile(pinFile, fileName, ccr); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_PIN_FILE_EMPTY.get(fileName, cfgEntryDN)); } else { return pinStr.toCharArray(); } } } else if (configuration.getKeyStorePin() != null) { return configuration.getKeyStorePin().toCharArray(); } return null; } private String readPinFromFile(File pinFile, String fileName, ConfigChangeResult ccr) { try (BufferedReader br = new BufferedReader(new FileReader(pinFile))) { return br.readLine(); } catch (IOException ioe) catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ.get(fileName, configEntryDN, getExceptionMessage(ioe))); ccr.addMessage(e.getMessageObject()); return null; } } /** * Returns the PIN needed to access the contents of a key store. We will offer several places to look for the PIN, * and we will do so in the following order: * <ol> * <li>In a specified Java property</li> * <li>In a specified environment variable</li> * <li>In a specified file on the server filesystem</li> * <li>As the value of a configuration attribute.</li> * </ol> * In any case, the PIN must be in the clear. * <p> * It is acceptable to have no PIN (OPENDJ-18). */ static char[] getKeyStorePIN(final String pinProperty, final String pinEnvVar, final String pinFileName, final String pinString, final DN cfgDN, final Arg2<Object, Object> propertyNotSetMsg, final Arg2<Object, Object> envVarNotSetMsg, final Arg2<Object, Object> noSuchFileMsg, final Arg3<Object, Object, Object> fileCannotReadMsg, final Arg2<Object, Object> fileEmptyMsg) throws InitializationException { if (pinProperty != null) { final String pin = System.getProperty(pinProperty); if (pin == null) { throw new InitializationException(propertyNotSetMsg.get(pinProperty, cfgDN)); } return pin.toCharArray(); } if (pinEnvVar != null) { final String pin = System.getenv(pinEnvVar); if (pin == null) { throw new InitializationException(envVarNotSetMsg.get(pinEnvVar, cfgDN)); } return pin.toCharArray(); } if (pinFileName != null) { final File pinFile = getFileForPath(pinFileName); if (pinFile.exists()) { String pin; try (BufferedReader br = new BufferedReader(new FileReader(pinFile))) { pin = br.readLine(); } catch (IOException e) { final LocalizableMessage msg = fileCannotReadMsg.get(pinFileName, cfgDN, getExceptionMessage(e)); throw new InitializationException(msg, e); } if (pin == null) { throw new InitializationException(fileEmptyMsg.get(pinFileName, cfgDN)); } return pin.toCharArray(); } else { throw new InitializationException(noSuchFileMsg.get(pinFileName, cfgDN)); } } return pinString != null ? pinString.toCharArray() : null; } } opendj-server-legacy/src/main/java/org/opends/server/extensions/FileBasedTrustManagerProvider.java
@@ -17,12 +17,10 @@ package org.opends.server.extensions; import org.forgerock.i18n.LocalizableMessage; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.security.*; import java.security.KeyStore; import java.security.KeyStoreException; import java.util.List; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -36,13 +34,13 @@ import org.opends.server.core.DirectoryServer; import org.forgerock.opendj.config.server.ConfigChangeResult; import org.opends.server.types.DirectoryException; import org.forgerock.opendj.ldap.DN; import org.opends.server.types.InitializationException; import org.forgerock.opendj.ldap.ResultCode; import org.opends.server.util.ExpirationCheckTrustManager; import org.forgerock.i18n.slf4j.LocalizedLogger; import static org.opends.messages.ExtensionMessages.*; import static org.opends.server.extensions.FileBasedKeyManagerProvider.getKeyStorePIN; import static org.opends.server.util.StaticUtils.*; /** @@ -55,9 +53,6 @@ { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The DN of the configuration entry for this trust manager provider. */ private DN configEntryDN; /** The PIN needed to access the trust store. */ private char[] trustStorePIN; @@ -81,143 +76,21 @@ } @Override public void initializeTrustManagerProvider( FileBasedTrustManagerProviderCfg configuration) throws ConfigException, InitializationException public void initializeTrustManagerProvider(FileBasedTrustManagerProviderCfg cfg) throws ConfigException, InitializationException { // Store the DN of the configuration entry and register to listen for any // changes to the configuration entry. currentConfig = configuration; configEntryDN = configuration.dn(); configuration.addFileBasedChangeListener(this); final ConfigChangeResult ccr = new ConfigChangeResult(); // Get the path to the trust store file. trustStoreFile = configuration.getTrustStoreFile(); File f = getFileForPath(trustStoreFile); if (!f.exists() || !f.isFile()) currentConfig = cfg; trustStoreFile = getTrustStoreFile(cfg, ccr); trustStoreType = getTrustStoreType(cfg, ccr); trustStorePIN = getTrustStorePIN(cfg, ccr); if (!ccr.getMessages().isEmpty()) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_NO_SUCH_FILE.get(trustStoreFile, configEntryDN); throw new InitializationException(message); throw new InitializationException(ccr.getMessages().get(0)); } // Get the trust store type. If none is specified, then use the default // type. trustStoreType = configuration.getTrustStoreType(); if (trustStoreType == null) { trustStoreType = KeyStore.getDefaultType(); } try { KeyStore.getInstance(trustStoreType); } catch (KeyStoreException kse) { logger.traceException(kse); LocalizableMessage message = ERR_FILE_TRUSTMANAGER_INVALID_TYPE. get(trustStoreType, configEntryDN, getExceptionMessage(kse)); throw new InitializationException(message); } // Get the PIN needed to access the contents of the trust store file. We // will offer several places to look for the PIN, and we will do so in the // following order: // - In a specified Java property // - In a specified environment variable // - In a specified file on the server filesystem. // - As the value of a configuration attribute. // In any case, the PIN must be in the clear. If no PIN is provided, then // it will be assumed that none is required to access the information in the // trust store. String pinProperty = configuration.getTrustStorePinProperty(); if (pinProperty == null) { String pinEnVar = configuration.getTrustStorePinEnvironmentVariable(); if (pinEnVar == null) { String pinFilePath = configuration.getTrustStorePinFile(); if (pinFilePath == null) { String pinStr = configuration.getTrustStorePin(); if (pinStr == null) { trustStorePIN = null; } else { trustStorePIN = pinStr.toCharArray(); } } else { File pinFile = getFileForPath(pinFilePath); if (! pinFile.exists()) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE.get(pinFilePath, configEntryDN); throw new InitializationException(message); } else { String pinStr; BufferedReader br = null; try { br = new BufferedReader(new FileReader(pinFile)); pinStr = br.readLine(); } catch (IOException ioe) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ. get(pinFilePath, configEntryDN, getExceptionMessage(ioe)); throw new InitializationException(message, ioe); } finally { close(br); } if (pinStr == null) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_FILE_EMPTY.get(pinFilePath, configEntryDN); throw new InitializationException(message); } else { trustStorePIN = pinStr.toCharArray(); } } } } else { String pinStr = System.getenv(pinEnVar); if (pinStr == null) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET.get(pinProperty, configEntryDN); throw new InitializationException(message); } else { trustStorePIN = pinStr.toCharArray(); } } } else { String pinStr = System.getProperty(pinProperty); if (pinStr == null) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET.get(pinProperty, configEntryDN); throw new InitializationException(message); } else { trustStorePIN = pinStr.toCharArray(); } } cfg.addFileBasedChangeListener(this); } @Override @@ -227,41 +100,31 @@ } @Override public TrustManager[] getTrustManagers() throws DirectoryException public TrustManager[] getTrustManagers() throws DirectoryException { KeyStore trustStore; try try (FileInputStream inputStream = new FileInputStream(getFileForPath(trustStoreFile))) { trustStore = KeyStore.getInstance(trustStoreType); FileInputStream inputStream = new FileInputStream(getFileForPath(trustStoreFile)); trustStore.load(inputStream, trustStorePIN); inputStream.close(); } catch (Exception e) { logger.traceException(e); LocalizableMessage message = ERR_FILE_TRUSTMANAGER_CANNOT_LOAD.get( trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); LocalizableMessage message = ERR_FILE_TRUSTMANAGER_CANNOT_LOAD.get(trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } try { String trustManagerAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgorithm); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgorithm); trustManagerFactory.init(trustStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); TrustManager[] newTrustManagers = new TrustManager[trustManagers.length]; for (int i=0; i < trustManagers.length; i++) { newTrustManagers[i] = new ExpirationCheckTrustManager( (X509TrustManager) trustManagers[i]); newTrustManagers[i] = new ExpirationCheckTrustManager((X509TrustManager) trustManagers[i]); } return newTrustManagers; } @@ -269,272 +132,107 @@ { logger.traceException(e); LocalizableMessage message = ERR_FILE_TRUSTMANAGER_CANNOT_CREATE_FACTORY.get( trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); LocalizableMessage message = ERR_FILE_TRUSTMANAGER_CANNOT_CREATE_FACTORY.get(trustStoreFile, getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } @Override public boolean isConfigurationAcceptable( TrustManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) public boolean isConfigurationAcceptable(TrustManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { FileBasedTrustManagerProviderCfg config = (FileBasedTrustManagerProviderCfg) configuration; FileBasedTrustManagerProviderCfg config = (FileBasedTrustManagerProviderCfg) cfg; return isConfigurationChangeAcceptable(config, unacceptableReasons); } @Override public boolean isConfigurationChangeAcceptable( FileBasedTrustManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) public boolean isConfigurationChangeAcceptable(FileBasedTrustManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { boolean configAcceptable = true; DN cfgEntryDN = configuration.dn(); int startSize = unacceptableReasons.size(); // Get the path to the trust store file. String newTrustStoreFile = configuration.getTrustStoreFile(); try { File f = getFileForPath(newTrustStoreFile); if (!f.exists() || !f.isFile()) { unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_NO_SUCH_FILE.get(newTrustStoreFile, cfgEntryDN)); configAcceptable = false; } } catch (Exception e) { logger.traceException(e); final ConfigChangeResult ccr = new ConfigChangeResult(); getTrustStoreFile(cfg, ccr); getTrustStoreType(cfg, ccr); getTrustStorePIN(cfg, ccr); unacceptableReasons.addAll(ccr.getMessages()); unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_CANNOT_DETERMINE_FILE.get(cfgEntryDN, getExceptionMessage(e))); configAcceptable = false; } // Check to see if the trust store type is acceptable. String storeType = configuration.getTrustStoreType(); if (storeType != null) { try { KeyStore.getInstance(storeType); } catch (KeyStoreException kse) { logger.traceException(kse); unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_INVALID_TYPE.get( storeType, cfgEntryDN, getExceptionMessage(kse))); configAcceptable = false; } } // If there is a PIN property, then make sure the corresponding // property is set. String pinProp = configuration.getTrustStorePinProperty(); if (pinProp != null && System.getProperty(pinProp) == null) { unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET.get(pinProp, cfgEntryDN)); configAcceptable = false; } // If there is a PIN environment variable, then make sure the corresponding // environment variable is set. String pinEnVar = configuration.getTrustStorePinEnvironmentVariable(); if (pinEnVar != null && System.getenv(pinEnVar) == null) { unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET.get(pinEnVar, cfgEntryDN)); configAcceptable = false; } // If there is a PIN file, then make sure the file exists and is readable. String pinFile = configuration.getTrustStorePinFile(); if (pinFile != null) { File f = getFileForPath(pinFile); if (f.exists()) { String pinStr = null; BufferedReader br = null; try { br = new BufferedReader(new FileReader(f)); pinStr = br.readLine(); } catch (IOException ioe) { unacceptableReasons.add(ERR_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ.get( pinFile, cfgEntryDN, getExceptionMessage(ioe))); configAcceptable = false; } finally { close(br); } if (pinStr == null) { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_FILE_EMPTY.get(pinFile, cfgEntryDN); unacceptableReasons.add(message); configAcceptable = false; } } else { LocalizableMessage message = ERR_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE.get(pinFile, cfgEntryDN); unacceptableReasons.add(message); configAcceptable = false; } } return configAcceptable; return startSize == unacceptableReasons.size(); } @Override public ConfigChangeResult applyConfigurationChange( FileBasedTrustManagerProviderCfg configuration) public ConfigChangeResult applyConfigurationChange(FileBasedTrustManagerProviderCfg cfg) { final ConfigChangeResult ccr = new ConfigChangeResult(); // Get the path to the trust store file. String newTrustStoreFile = configuration.getTrustStoreFile(); File f = getFileForPath(newTrustStoreFile); if (!f.exists() || !f.isFile()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_NO_SUCH_FILE.get(newTrustStoreFile, configEntryDN)); } // Get the trust store type. If none is specified, then use the default type. String newTrustStoreType = configuration.getTrustStoreType(); if (newTrustStoreType == null) { newTrustStoreType = KeyStore.getDefaultType(); } try { KeyStore.getInstance(newTrustStoreType); } catch (KeyStoreException kse) { logger.traceException(kse); ccr.addMessage(ERR_FILE_TRUSTMANAGER_INVALID_TYPE.get( newTrustStoreType, configEntryDN, getExceptionMessage(kse))); ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); } // Get the PIN needed to access the contents of the trust store file. We // will offer several places to look for the PIN, and we will do so in the // following order: // - In a specified Java property // - In a specified environment variable // - In a specified file on the server filesystem. // - As the value of a configuration attribute. // In any case, the PIN must be in the clear. If no PIN is provided, then // it will be assumed that none is required to access the information in the // trust store. char[] newPIN = null; String newPINProperty = configuration.getTrustStorePinProperty(); if (newPINProperty == null) { String newPINEnVar = configuration.getTrustStorePinEnvironmentVariable(); if (newPINEnVar == null) { String newPINFile = configuration.getTrustStorePinFile(); if (newPINFile == null) { String pinStr = configuration.getTrustStorePin(); if (pinStr == null) { newPIN = null; } else { newPIN = pinStr.toCharArray(); } } else { File pinFile = getFileForPath(newPINFile); if (! pinFile.exists()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE.get(newPINFile, configEntryDN)); } else { String pinStr = null; BufferedReader br = null; try { br = new BufferedReader(new FileReader(pinFile)); pinStr = br.readLine(); } catch (IOException ioe) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ.get( newPINFile, configEntryDN, getExceptionMessage(ioe))); } finally { close(br); } if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_PIN_FILE_EMPTY.get(newPINFile, configEntryDN)); } else { newPIN = pinStr.toCharArray(); } } } } else { String pinStr = System.getenv(newPINEnVar); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET.get(newPINEnVar, configEntryDN)); } else { newPIN = pinStr.toCharArray(); } } } else { String pinStr = System.getProperty(newPINProperty); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET.get(newPINProperty, configEntryDN)); } else { newPIN = pinStr.toCharArray(); } } String newTrustStoreFile = getTrustStoreFile(cfg, ccr); String newTrustStoreType = getTrustStoreType(cfg, ccr); char[] newPIN = getTrustStorePIN(cfg, ccr); if (ccr.getResultCode() == ResultCode.SUCCESS) { trustStoreFile = newTrustStoreFile; trustStoreType = newTrustStoreType; trustStorePIN = newPIN; currentConfig = configuration; currentConfig = cfg; trustStorePIN = newPIN; trustStoreFile = newTrustStoreFile; trustStoreType = newTrustStoreType; } return ccr; } /** Get the path to the key store file. */ private String getTrustStoreFile(FileBasedTrustManagerProviderCfg cfg, ConfigChangeResult ccr) { final String keyStoreFile = cfg.getTrustStoreFile(); final File f = getFileForPath(keyStoreFile); if (!f.exists() || !f.isFile()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_NO_SUCH_FILE.get(keyStoreFile, cfg.dn())); } return keyStoreFile; } /** Get the keystore type. If none is specified, then use the default type. */ private String getTrustStoreType(FileBasedTrustManagerProviderCfg cfg, ConfigChangeResult ccr) { final String trustStoreType = cfg.getTrustStoreType(); if (trustStoreType != null) { try { KeyStore.getInstance(trustStoreType); return trustStoreType; } catch (KeyStoreException e) { logger.traceException(e); ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_FILE_TRUSTMANAGER_INVALID_TYPE.get(trustStoreType, cfg.dn(), getExceptionMessage(e))); } } return KeyStore.getDefaultType(); } private char[] getTrustStorePIN(FileBasedTrustManagerProviderCfg cfg, ConfigChangeResult ccr) { try { return getKeyStorePIN(cfg.getTrustStorePinProperty(), cfg.getTrustStorePinEnvironmentVariable(), cfg.getTrustStorePinFile(), cfg.getTrustStorePin(), cfg.dn(), ERR_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET, ERR_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET, ERR_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE, ERR_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ, ERR_FILE_TRUSTMANAGER_PIN_FILE_EMPTY); } catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(e.getMessageObject()); return null; } } } opendj-server-legacy/src/main/java/org/opends/server/extensions/PKCS11KeyManagerProvider.java
@@ -19,10 +19,6 @@ import static org.opends.messages.ExtensionMessages.*; import static org.opends.server.util.StaticUtils.*; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.KeyStore; import java.util.List; @@ -34,377 +30,136 @@ import org.forgerock.opendj.config.server.ConfigChangeResult; import org.forgerock.opendj.config.server.ConfigException; import org.forgerock.opendj.config.server.ConfigurationChangeListener; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.server.config.server.PKCS11KeyManagerProviderCfg; import org.opends.server.api.KeyManagerProvider; import org.opends.server.core.DirectoryServer; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; import org.opends.server.util.StaticUtils; /** * This class defines a key manager provider that will access keys stored on a * PKCS#11 device. It will use the Java PKCS#11 interface, which may need to be * configured on the underlying system. */ public class PKCS11KeyManagerProvider extends KeyManagerProvider<PKCS11KeyManagerProviderCfg> implements ConfigurationChangeListener<PKCS11KeyManagerProviderCfg> public class PKCS11KeyManagerProvider extends KeyManagerProvider<PKCS11KeyManagerProviderCfg> implements ConfigurationChangeListener<PKCS11KeyManagerProviderCfg> { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The keystore type to use when accessing the PKCS#11 keystore. */ private static final String PKCS11_KEYSTORE_TYPE = "PKCS11"; /** The PIN needed to access the keystore. */ private char[] keyStorePIN; /** The current configuration for this key manager provider. */ private PKCS11KeyManagerProviderCfg currentConfig; /** The keystore type to use when accessing the PKCS#11 keystore. */ public static final String PKCS11_KEYSTORE_TYPE = "PKCS11"; /** The DN of the configuration entry for this key manager provider. */ private DN configEntryDN; /** The PIN needed to access the keystore. */ private char[] keyStorePIN; /** The current configuration for this key manager provider. */ private PKCS11KeyManagerProviderCfg currentConfig; /** * Creates a new instance of this PKCS#11 key manager provider. The * <CODE>initializeKeyManagerProvider</CODE> method must be called on the * resulting object before it may be used. */ public PKCS11KeyManagerProvider() { // No implementation is required. } @Override public void initializeKeyManagerProvider( PKCS11KeyManagerProviderCfg configuration) throws ConfigException, InitializationException { // Store the DN of the configuration entry and register to be notified of // configuration changes. currentConfig = configuration; configEntryDN = configuration.dn(); configuration.addPKCS11ChangeListener(this); // Get the PIN needed to access the contents of the PKCS#11 // keystore. We will offer several places to look for the PIN, and // we will do so in the following order: // // - In a specified Java property // - In a specified environment variable // - In a specified file on the server filesystem. // - As the value of a configuration attribute. // // In any case, the PIN must be in the clear. keyStorePIN = null; if (configuration.getKeyStorePinProperty() != null) { String propertyName = configuration.getKeyStorePinProperty(); String pinStr = System.getProperty(propertyName); if (pinStr == null) { LocalizableMessage message = ERR_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET.get( propertyName, configEntryDN); throw new InitializationException(message); } keyStorePIN = pinStr.toCharArray(); } else if (configuration.getKeyStorePinEnvironmentVariable() != null) { String enVarName = configuration .getKeyStorePinEnvironmentVariable(); String pinStr = System.getenv(enVarName); if (pinStr == null) { LocalizableMessage message = ERR_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET.get( enVarName, configEntryDN); throw new InitializationException(message); } keyStorePIN = pinStr.toCharArray(); } else if (configuration.getKeyStorePinFile() != null) { String fileName = configuration.getKeyStorePinFile(); File pinFile = getFileForPath(fileName); if (!pinFile.exists()) { LocalizableMessage message = ERR_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE.get(fileName, configEntryDN); throw new InitializationException(message); } String pinStr; try { BufferedReader br = new BufferedReader( new FileReader(pinFile)); pinStr = br.readLine(); br.close(); } catch (IOException ioe) { logger.traceException(ioe); LocalizableMessage message = ERR_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ. get(fileName, configEntryDN, getExceptionMessage(ioe)); throw new InitializationException(message, ioe); } if (pinStr == null) { LocalizableMessage message = ERR_PKCS11_KEYMANAGER_PIN_FILE_EMPTY.get(fileName, configEntryDN); throw new InitializationException(message); } keyStorePIN = pinStr.toCharArray(); } else if (configuration.getKeyStorePin() != null) { keyStorePIN = configuration.getKeyStorePin().toCharArray(); } } @Override public void finalizeKeyManagerProvider() { currentConfig.removePKCS11ChangeListener(this); } @Override public KeyManager[] getKeyManagers() throws DirectoryException { KeyStore keyStore; try { keyStore = KeyStore.getInstance(PKCS11_KEYSTORE_TYPE); keyStore.load(null, keyStorePIN); } catch (Exception e) { logger.traceException(e); LocalizableMessage message = ERR_PKCS11_KEYMANAGER_CANNOT_LOAD.get(getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); /** * Creates a new instance of this PKCS#11 key manager provider. The * <CODE>initializeKeyManagerProvider</CODE> method must be called on the * resulting object before it may be used. */ public PKCS11KeyManagerProvider() { // No implementation is required. } try @Override public void initializeKeyManagerProvider(PKCS11KeyManagerProviderCfg configuration) throws ConfigException, InitializationException { String keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); keyManagerFactory.init(keyStore, keyStorePIN); return keyManagerFactory.getKeyManagers(); currentConfig = configuration; keyStorePIN = getKeyStorePIN(configuration); configuration.addPKCS11ChangeListener(this); } catch (Exception e) { logger.traceException(e); LocalizableMessage message = ERR_PKCS11_KEYMANAGER_CANNOT_CREATE_FACTORY.get( getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); private char[] getKeyStorePIN(PKCS11KeyManagerProviderCfg cfg) throws InitializationException { return FileBasedKeyManagerProvider.getKeyStorePIN(cfg.getKeyStorePinProperty(), cfg.getKeyStorePinEnvironmentVariable(), cfg.getKeyStorePinFile(), cfg.getKeyStorePin(), cfg.dn(), ERR_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET, ERR_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET, ERR_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE, ERR_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ, ERR_PKCS11_KEYMANAGER_PIN_FILE_EMPTY); } } @Override public boolean isConfigurationAcceptable( PKCS11KeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) { return isConfigurationChangeAcceptable(configuration, unacceptableReasons); } @Override public boolean isConfigurationChangeAcceptable( PKCS11KeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) { boolean configAcceptable = true; DN cfgEntryDN = configuration.dn(); // Get the PIN needed to access the contents of the keystore file. // // We will offer several places to look for the PIN, and we will // do so in the following order: // // - In a specified Java property // - In a specified environment variable // - In a specified file on the server filesystem. // - As the value of a configuration attribute. // // In any case, the PIN must be in the clear. // // It is acceptable to have no PIN (OPENDJ-18) if (configuration.getKeyStorePinProperty() != null) @Override public void finalizeKeyManagerProvider() { String propertyName = configuration.getKeyStorePinProperty(); String pinStr = System.getProperty(propertyName); if (pinStr == null) { unacceptableReasons.add(ERR_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET.get(propertyName, cfgEntryDN)); configAcceptable = false; } currentConfig.removePKCS11ChangeListener(this); } else if (configuration.getKeyStorePinEnvironmentVariable() != null) { String enVarName = configuration.getKeyStorePinEnvironmentVariable(); String pinStr = System.getenv(enVarName); if (pinStr == null) { unacceptableReasons.add(ERR_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET.get(enVarName, configEntryDN)); configAcceptable = false; } } else if (configuration.getKeyStorePinFile() != null) @Override public KeyManager[] getKeyManagers() throws DirectoryException { String fileName = configuration.getKeyStorePinFile(); File pinFile = getFileForPath(fileName); if (!pinFile.exists()) { unacceptableReasons.add(ERR_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE.get(fileName, configEntryDN)); configAcceptable = false; } else { String pinStr = null; BufferedReader br = null; try { br = new BufferedReader(new FileReader(pinFile)); pinStr = br.readLine(); } catch (IOException ioe) KeyStore keyStore; try { unacceptableReasons.add( ERR_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ.get( fileName, cfgEntryDN, getExceptionMessage(ioe))); configAcceptable = false; keyStore = KeyStore.getInstance(PKCS11_KEYSTORE_TYPE); keyStore.load(null, keyStorePIN); } finally catch (Exception e) { StaticUtils.close(br); logger.traceException(e); LocalizableMessage message = ERR_PKCS11_KEYMANAGER_CANNOT_LOAD.get(getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } if (pinStr == null) try { unacceptableReasons.add(ERR_PKCS11_KEYMANAGER_PIN_FILE_EMPTY.get(fileName, configEntryDN)); configAcceptable = false; String keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); keyManagerFactory.init(keyStore, keyStorePIN); return keyManagerFactory.getKeyManagers(); } } } else if (configuration.getKeyStorePin() != null) { String pinStr = configuration.getKeyStorePin(); if (pinStr == null) { // We should have a pin from the configuration, but no. unacceptableReasons.add( ERR_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR.get(cfgEntryDN, null)); configAcceptable = false; } } return configAcceptable; } @Override public ConfigChangeResult applyConfigurationChange( PKCS11KeyManagerProviderCfg configuration) { final ConfigChangeResult ccr = new ConfigChangeResult(); // Get the PIN needed to access the contents of the keystore file. // // We will offer several places to look for the PIN, and we will // do so in the following order: // // - In a specified Java property // - In a specified environment variable // - In a specified file on the server filesystem. // - As the value of a configuration attribute. // // In any case, the PIN must be in the clear. char[] newPIN = null; if (configuration.getKeyStorePinProperty() != null) { String propertyName = configuration.getKeyStorePinProperty(); String pinStr = System.getProperty(propertyName); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET.get(propertyName, configEntryDN)); } else { newPIN = pinStr.toCharArray(); } } else if (configuration.getKeyStorePinEnvironmentVariable() != null) { String enVarName = configuration.getKeyStorePinEnvironmentVariable(); String pinStr = System.getenv(enVarName); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET.get(enVarName, configEntryDN)); } else { newPIN = pinStr.toCharArray(); } } else if (configuration.getKeyStorePinFile() != null) { String fileName = configuration.getKeyStorePinFile(); File pinFile = getFileForPath(fileName); if (!pinFile.exists()) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE.get(fileName, configEntryDN)); } else { String pinStr = null; BufferedReader br = null; try { br = new BufferedReader(new FileReader(pinFile)); pinStr = br.readLine(); } catch (IOException ioe) catch (Exception e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ.get( fileName, configEntryDN, getExceptionMessage(ioe))); } finally { StaticUtils.close(br); } logger.traceException(e); if (pinStr == null) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(ERR_PKCS11_KEYMANAGER_PIN_FILE_EMPTY.get(fileName, configEntryDN)); LocalizableMessage message = ERR_PKCS11_KEYMANAGER_CANNOT_CREATE_FACTORY.get(getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } else { newPIN = pinStr.toCharArray(); } } } else if (configuration.getKeyStorePin() != null) @Override public boolean isConfigurationAcceptable(PKCS11KeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) { newPIN = configuration.getKeyStorePin().toCharArray(); return isConfigurationChangeAcceptable(configuration, unacceptableReasons); } if (ccr.getResultCode() == ResultCode.SUCCESS) @Override public boolean isConfigurationChangeAcceptable(PKCS11KeyManagerProviderCfg configuration, List<LocalizableMessage> unacceptableReasons) { currentConfig = configuration; keyStorePIN = newPIN; try { getKeyStorePIN(configuration); return true; } catch (InitializationException e) { unacceptableReasons.add(e.getMessageObject()); return false; } } return ccr; } @Override public ConfigChangeResult applyConfigurationChange(PKCS11KeyManagerProviderCfg configuration) { final ConfigChangeResult ccr = new ConfigChangeResult(); try { keyStorePIN = getKeyStorePIN(configuration); currentConfig = configuration; } catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(e.getMessageObject()); } return ccr; } } opendj-server-legacy/src/main/java/org/opends/server/util/CertificateManager.java
@@ -12,12 +12,14 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS. * Portions Copyright 2013-2016 ForgeRock AS. */ package org.opends.server.util; import java.io.*; import java.security.*; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Enumeration; @@ -95,7 +97,32 @@ return true; } /** * Creates a new certificate manager instance with the provided information. * * @param keyStorePath The path to the key store file, or "NONE" if the key * store type is "PKCS11". For the other key store * types, the file does not need to exist if a new * self-signed certificate or certificate signing * request is to be generated, although the directory * containing the file must exist. The key store file * must exist if import or export operations are to be * performed. * @param keyStoreType The key store type to use. It should be one of * {@code KEY_STORE_TYPE_JKS}, * {@code KEY_STORE_TYPE_JCEKS}, * {@code KEY_STORE_TYPE_PKCS11}, or * {@code KEY_STORE_TYPE_PKCS12}. * @param keyStorePassword The password required to access the key store. * It may be {@code null}. * @throws IllegalArgumentException If an argument is invalid or {@code null}. * */ public CertificateManager(String keyStorePath, String keyStoreType, String keyStorePassword) throws IllegalArgumentException { this(keyStorePath, keyStoreType, keyStorePassword == null ? null : keyStorePassword.toCharArray()); } /** * Creates a new certificate manager instance with the provided information. @@ -114,13 +141,12 @@ * {@code KEY_STORE_TYPE_PKCS11}, or * {@code KEY_STORE_TYPE_PKCS12}. * @param keyStorePassword The password required to access the key store. * It must not be {@code null}. * It may be {@code null}. * @throws IllegalArgumentException If an argument is invalid or {@code null}. * */ public CertificateManager(String keyStorePath, String keyStoreType, String keyStorePassword) throws IllegalArgumentException { public CertificateManager(String keyStorePath, String keyStoreType, char[] keyStorePassword) throws IllegalArgumentException { ensureValid(keyStorePath, KEYSTORE_PATH_MSG); ensureValid(keyStoreType, KEYSTORE_TYPE_MSG); if (keyStoreType.equals(KEY_STORE_TYPE_PKCS11)) { @@ -153,9 +179,8 @@ } this.keyStorePath = keyStorePath; this.keyStoreType = keyStoreType; this.password = keyStorePassword == null ? null : keyStorePassword.toCharArray(); keyStore = null; this.password = keyStorePassword; this.keyStore = null; } @@ -418,8 +443,7 @@ } else { CertificateManager certManager2 = new CertificateManager(keyStorePath, keyStoreType, new String(password)); CertificateManager certManager2 = new CertificateManager(keyStorePath, keyStoreType, password); String[] aliases2 = certManager2.getCertificateAliases(); if (aliases2 != null && aliases2.length == 1) { opendj-server-legacy/src/test/java/org/opends/server/util/CertificateManagerTestCase.java
@@ -12,7 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS. * Portions Copyright 2013-2016 ForgeRock AS. */ package org.opends.server.util; @@ -230,7 +230,7 @@ public void testConstructorNullPIN() throws Exception { assertNotNull(new CertificateManager(JKS_KEY_STORE_PATH, "JKS", null)); assertNotNull(new CertificateManager(JKS_KEY_STORE_PATH, "JKS", (String) null)); }