| opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/LDAPKeyManagerProviderConfiguration.xml | ●●●●● patch | view | raw | blame | history | |
| opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/LDAPTrustManagerProviderConfiguration.xml | ●●●●● patch | view | raw | blame | history | |
| opendj-server-legacy/resource/schema/02-config.ldif | ●●●●● patch | view | raw | blame | history | |
| opendj-server-legacy/src/main/java/org/opends/server/extensions/LDAPKeyManagerProvider.java | ●●●●● patch | view | raw | blame | history | |
| opendj-server-legacy/src/main/java/org/opends/server/extensions/LDAPTrustManagerProvider.java | ●●●●● patch | view | raw | blame | history | |
| opendj-server-legacy/src/messages/org/opends/messages/extension.properties | ●●●●● patch | view | raw | blame | history |
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/LDAPKeyManagerProviderConfiguration.xml
New file @@ -0,0 +1,58 @@ <?xml version="1.0" encoding="utf-8"?> <!-- The contents of this file are subject to the terms of the Common Development and Distribution License (the License). You may not use this file except in compliance with the License. You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the specific language governing permission and limitations under the License. When distributing Covered Software, include this CDDL Header Notice in each file and include the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL Header, with the fields enclosed by brackets [] replaced by your own identifying information: "Portions copyright [year] [name of copyright owner]". Copyright 2016 ForgeRock AS. --> <adm:managed-object name="ldap-key-manager-provider" plural-name="ldap-key-manager-providers" package="org.forgerock.opendj.server.config" extends="key-manager-provider" xmlns:adm="http://opendj.forgerock.org/admin" xmlns:ldap="http://opendj.forgerock.org/admin-ldap" advanced="true"> <adm:synopsis> The LDAP key manager provider uses an LDAP key store managed by the server to obtain server certificates. </adm:synopsis> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-ldap-key-manager-provider</ldap:name> <ldap:superior>ds-cfg-key-manager-provider</ldap:superior> </ldap:object-class> </adm:profile> <adm:property-override name="java-class" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value> org.opends.server.extensions.LDAPKeyManagerProvider </adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property name="base-dn" mandatory="true"> <adm:synopsis> The base DN beneath which LDAP key store entries are located. </adm:synopsis> <adm:syntax> <adm:dn /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:name>ds-cfg-base-dn</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property-reference name="key-store-pin" /> <adm:property-reference name="key-store-pin-property" /> <adm:property-reference name="key-store-pin-environment-variable" /> <adm:property-reference name="key-store-pin-file" /> </adm:managed-object> opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/LDAPTrustManagerProviderConfiguration.xml
New file @@ -0,0 +1,59 @@ <?xml version="1.0" encoding="utf-8"?> <!-- The contents of this file are subject to the terms of the Common Development and Distribution License (the License). You may not use this file except in compliance with the License. You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the specific language governing permission and limitations under the License. When distributing Covered Software, include this CDDL Header Notice in each file and include the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL Header, with the fields enclosed by brackets [] replaced by your own identifying information: "Portions Copyright [year] [name of copyright owner]". Copyright 2016 ForgeRock AS. ! --> <adm:managed-object name="ldap-trust-manager-provider" plural-name="ldap-trust-manager-providers" package="org.forgerock.opendj.server.config" extends="trust-manager-provider" xmlns:adm="http://opendj.forgerock.org/admin" xmlns:ldap="http://opendj.forgerock.org/admin-ldap" advanced="true"> <adm:synopsis> The LDAP trust manager provider determines whether to trust a presented certificate based on whether that certificate exists in an LDAP key store managed by the server. </adm:synopsis> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-ldap-trust-manager-provider</ldap:name> <ldap:superior>ds-cfg-trust-manager-provider</ldap:superior> </ldap:object-class> </adm:profile> <adm:property-override name="java-class" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value> org.opends.server.extensions.LDAPTrustManagerProvider </adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property name="base-dn" mandatory="true"> <adm:synopsis> The base DN beneath which LDAP key store entries are located. </adm:synopsis> <adm:syntax> <adm:dn /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:name>ds-cfg-base-dn</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property-reference name="trust-store-pin" /> <adm:property-reference name="trust-store-pin-property" /> <adm:property-reference name="trust-store-pin-environment-variable" /> <adm:property-reference name="trust-store-pin-file" /> </adm:managed-object> opendj-server-legacy/resource/schema/02-config.ldif
@@ -6073,6 +6073,26 @@ MAY ( ds-cfg-rotation-policy $ ds-cfg-retention-policy ) X-ORIGIN 'OpenDJ Directory Server' ) objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.51 NAME 'ds-cfg-ldap-key-manager-provider' SUP ds-cfg-key-manager-provider STRUCTURAL MUST ds-cfg-base-dn MAY ( ds-cfg-key-store-pin $ ds-cfg-key-store-pin-property $ ds-cfg-key-store-pin-environment-variable $ ds-cfg-key-store-pin-file ) X-ORIGIN 'OpenDJ Directory Server' ) objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.52 NAME 'ds-cfg-ldap-trust-manager-provider' SUP ds-cfg-trust-manager-provider STRUCTURAL MUST ds-cfg-base-dn MAY ( ds-cfg-trust-store-pin $ ds-cfg-trust-store-pin-property $ ds-cfg-trust-store-pin-environment-variable $ ds-cfg-trust-store-pin-file ) X-ORIGIN 'OpenDJ Directory Server' ) objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.53 NAME 'ds-cfg-json-schema' SUP ds-cfg-schema-provider opendj-server-legacy/src/main/java/org/opends/server/extensions/LDAPKeyManagerProvider.java
New file @@ -0,0 +1,196 @@ /* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. */ package org.opends.server.extensions; import static org.forgerock.opendj.adapter.server3x.Adapters.newRootConnectionFactory; import static org.forgerock.opendj.security.KeyStoreParameters.GLOBAL_PASSWORD; import static org.forgerock.opendj.security.OpenDJProvider.newLDAPKeyStore; import static org.forgerock.opendj.security.OpenDJProvider.newClearTextPasswordFactory; import static org.forgerock.util.Options.defaultOptions; import static org.opends.messages.ExtensionMessages.*; import static org.opends.server.util.StaticUtils.getExceptionMessage; import java.security.KeyStore; import java.security.KeyStore.PrivateKeyEntry; import java.security.KeyStoreException; import java.util.List; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.config.server.ConfigChangeResult; import org.forgerock.opendj.config.server.ConfigurationChangeListener; import org.forgerock.opendj.server.config.server.LDAPKeyManagerProviderCfg; import org.forgerock.util.Factory; import org.forgerock.util.Options; import org.opends.server.api.KeyManagerProvider; import org.opends.server.core.DirectoryServer; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; /** This class defines a key manager provider that will access keys stored in an LDAP backend. */ public class LDAPKeyManagerProvider extends KeyManagerProvider<LDAPKeyManagerProviderCfg> implements ConfigurationChangeListener<LDAPKeyManagerProviderCfg> { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The configuration for this key manager provider. */ private LDAPKeyManagerProviderCfg currentConfig; private Factory<char[]> passwordFactory; /** Lazily initialized key store (some services are unavailable at server startup). */ private KeyStore keyStore; /** Creates a new LDAP key manager provider. */ public LDAPKeyManagerProvider() { // No implementation is required. } @Override public void initializeKeyManagerProvider(LDAPKeyManagerProviderCfg cfg) throws InitializationException { configure(cfg); cfg.addLDAPChangeListener(this); } private synchronized void configure(final LDAPKeyManagerProviderCfg cfg) throws InitializationException { keyStore = null; passwordFactory = newClearTextPasswordFactory(getKeyStorePIN(cfg)); currentConfig = cfg; } private synchronized KeyStore getKeyStore() { if (keyStore == null) { final Options options = defaultOptions().set(GLOBAL_PASSWORD, passwordFactory); keyStore = newLDAPKeyStore(newRootConnectionFactory(), currentConfig.getBaseDN(), options); } return keyStore; } @Override public synchronized void finalizeKeyManagerProvider() { keyStore = null; currentConfig.removeLDAPChangeListener(this); } @Override public boolean containsKeyWithAlias(String alias) { try { return getKeyStore().entryInstanceOf(alias, PrivateKeyEntry.class); } catch (KeyStoreException e) { // Ignore. logger.traceException(e); } return false; } @Override public KeyManager[] getKeyManagers() throws DirectoryException { try { String keyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); keyManagerFactory.init(getKeyStore(), passwordFactory.newInstance()); return keyManagerFactory.getKeyManagers(); } catch (Exception e) { LocalizableMessage message = ERR_LDAP_KEYMANAGER_CANNOT_CREATE_FACTORY.get(currentConfig.getBaseDN(), getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } @Override public boolean containsAtLeastOneKey() { try { // Not strictly correct since this test includes trusted certs and secret keys, but it should be sufficient. // A more accurate approach is to query each alias, but this could be expensive when the key store is large. return getKeyStore().size() > 0; } catch (Exception e) { logger.traceException(e); } return false; } @Override public boolean isConfigurationAcceptable(LDAPKeyManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { return isConfigurationChangeAcceptable(cfg, unacceptableReasons); } @Override public boolean isConfigurationChangeAcceptable(LDAPKeyManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { try { getKeyStorePIN(cfg); return true; } catch (InitializationException e) { unacceptableReasons.add(e.getMessageObject()); return false; } } @Override public ConfigChangeResult applyConfigurationChange(LDAPKeyManagerProviderCfg cfg) { final ConfigChangeResult ccr = new ConfigChangeResult(); try { configure(cfg); } catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(e.getMessageObject()); } return ccr; } private static char[] getKeyStorePIN(LDAPKeyManagerProviderCfg cfg) throws InitializationException { return FileBasedKeyManagerProvider.getKeyStorePIN(cfg.getKeyStorePinProperty(), cfg.getKeyStorePinEnvironmentVariable(), cfg.getKeyStorePinFile(), cfg.getKeyStorePin(), cfg.dn(), ERR_LDAP_KEYMANAGER_PIN_PROPERTY_NOT_SET, ERR_LDAP_KEYMANAGER_PIN_ENVAR_NOT_SET, ERR_LDAP_KEYMANAGER_PIN_NO_SUCH_FILE, ERR_LDAP_KEYMANAGER_PIN_FILE_CANNOT_READ, ERR_LDAP_KEYMANAGER_PIN_FILE_EMPTY); } } opendj-server-legacy/src/main/java/org/opends/server/extensions/LDAPTrustManagerProvider.java
New file @@ -0,0 +1,170 @@ /* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. */ package org.opends.server.extensions; import static org.forgerock.opendj.adapter.server3x.Adapters.newRootConnectionFactory; import static org.forgerock.opendj.security.KeyStoreParameters.GLOBAL_PASSWORD; import static org.forgerock.opendj.security.OpenDJProvider.newLDAPKeyStore; import static org.forgerock.opendj.security.OpenDJProvider.newClearTextPasswordFactory; import static org.forgerock.util.Options.defaultOptions; import static org.opends.messages.ExtensionMessages.*; import static org.opends.server.extensions.FileBasedKeyManagerProvider.getKeyStorePIN; import static org.opends.server.util.StaticUtils.getExceptionMessage; import java.security.KeyStore; import java.util.List; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.config.server.ConfigChangeResult; import org.forgerock.opendj.config.server.ConfigurationChangeListener; import org.forgerock.opendj.server.config.server.LDAPTrustManagerProviderCfg; import org.forgerock.opendj.server.config.server.TrustManagerProviderCfg; import org.forgerock.util.Factory; import org.forgerock.util.Options; import org.opends.server.api.TrustManagerProvider; import org.opends.server.core.DirectoryServer; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; import org.opends.server.util.ExpirationCheckTrustManager; /** This class defines a trust manager provider that will reference certificates stored in an LDAP backend. */ public class LDAPTrustManagerProvider extends TrustManagerProvider<LDAPTrustManagerProviderCfg> implements ConfigurationChangeListener<LDAPTrustManagerProviderCfg> { /** The handle to the configuration for this trust manager. */ private LDAPTrustManagerProviderCfg currentConfig; private Factory<char[]> passwordFactory; /** Lazily initialized key store (some services are unavailable at server startup). */ private KeyStore keyStore; /** Creates a new LDAP trust manager provider. */ public LDAPTrustManagerProvider() { // No implementation is required. } @Override public void initializeTrustManagerProvider(LDAPTrustManagerProviderCfg cfg) throws InitializationException { configure(cfg); cfg.addLDAPChangeListener(this); } private synchronized void configure(final LDAPTrustManagerProviderCfg cfg) throws InitializationException { keyStore = null; passwordFactory = newClearTextPasswordFactory(getTrustStorePIN(cfg)); currentConfig = cfg; } private synchronized KeyStore getKeyStore() { if (keyStore == null) { final Options options = defaultOptions().set(GLOBAL_PASSWORD, passwordFactory); keyStore = newLDAPKeyStore(newRootConnectionFactory(), currentConfig.getBaseDN(), options); } return keyStore; } @Override public synchronized void finalizeTrustManagerProvider() { keyStore = null; currentConfig.removeLDAPChangeListener(this); } @Override public TrustManager[] getTrustManagers() throws DirectoryException { try { String trustManagerAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgorithm); trustManagerFactory.init(getKeyStore()); 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]); } return newTrustManagers; } catch (Exception e) { LocalizableMessage message = ERR_LDAP_TRUSTMANAGER_CANNOT_CREATE_FACTORY.get(currentConfig.getBaseDN(), getExceptionMessage(e)); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e); } } @Override public boolean isConfigurationAcceptable(TrustManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { return isConfigurationChangeAcceptable((LDAPTrustManagerProviderCfg) cfg, unacceptableReasons); } @Override public boolean isConfigurationChangeAcceptable(LDAPTrustManagerProviderCfg cfg, List<LocalizableMessage> unacceptableReasons) { try { getTrustStorePIN(cfg); return true; } catch (InitializationException e) { unacceptableReasons.add(e.getMessageObject()); return false; } } @Override public ConfigChangeResult applyConfigurationChange(LDAPTrustManagerProviderCfg cfg) { final ConfigChangeResult ccr = new ConfigChangeResult(); try { configure(cfg); } catch (InitializationException e) { ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); ccr.addMessage(e.getMessageObject()); } return ccr; } private static char[] getTrustStorePIN(LDAPTrustManagerProviderCfg cfg) throws InitializationException { return getKeyStorePIN(cfg.getTrustStorePinProperty(), cfg.getTrustStorePinEnvironmentVariable(), cfg.getTrustStorePinFile(), cfg.getTrustStorePin(), cfg.dn(), ERR_LDAP_TRUSTMANAGER_PIN_PROPERTY_NOT_SET, ERR_LDAP_TRUSTMANAGER_PIN_ENVAR_NOT_SET, ERR_LDAP_TRUSTMANAGER_PIN_NO_SUCH_FILE, ERR_LDAP_TRUSTMANAGER_PIN_FILE_CANNOT_READ, ERR_LDAP_TRUSTMANAGER_PIN_FILE_EMPTY); } } opendj-server-legacy/src/messages/org/opends/messages/extension.properties
@@ -953,8 +953,50 @@ definition '%s' is invalid because the range '%s' is too short ERR_NO_KEY_ENTRY_IN_KEYSTORE_636=There is no private key entry in keystore %s INFO_MISSING_KEY_TYPE_IN_ALIASES_637=Handshake for '%s': cipher requires \ the aliase(s) '%s' \ to contain key(s) of type(s) '%s'. the alias(es) '%s' to contain key(s) of type(s) '%s'. ERR_PWSCHEME_INVALID_STORED_PASSWORD_638=An error occurred while attempting \ to match a bcrypt hashed password value: %s ERR_LDAP_PTA_INVALID_FILTER_TEMPLATE_639=The mapped search filter template "%s" \ could not be parsed as a valid LDAP filter ERR_LDAP_KEYMANAGER_CANNOT_CREATE_FACTORY_640=An error occurred while \ trying to create a key manager factory to access the contents of LDAP keystore \ with base DN '%s': %s ERR_LDAP_TRUSTMANAGER_CANNOT_CREATE_FACTORY_641=An error occurred while \ trying to create a trust manager factory to access the contents of LDAP keystore \ with base DN '%s': %s ERR_LDAP_KEYMANAGER_PIN_PROPERTY_NOT_SET_642=Java property %s which is \ specified in attribute ds-cfg-key-store-pin-property of configuration entry \ %s should contain the PIN needed to access the LDAP key manager, but \ this property is not set ERR_LDAP_KEYMANAGER_PIN_ENVAR_NOT_SET_643=Environment variable %s which \ is specified in attribute ds-cfg-key-store-pin-environment-variable of \ configuration entry %s should contain the PIN needed to access the LDAP \ key manager, but this property is not set ERR_LDAP_KEYMANAGER_PIN_NO_SUCH_FILE_644=File %s specified in attribute \ ds-cfg-key-store-pin-file of configuration entry %s should contain the PIN \ needed to access the LDAP key manager, but this file does not exist ERR_LDAP_KEYMANAGER_PIN_FILE_CANNOT_READ_645=An error occurred while \ trying to read the keystore PIN from file %s specified in configuration \ attribute ds-cfg-key-store-pin-file of configuration entry %s: %s ERR_LDAP_KEYMANAGER_PIN_FILE_EMPTY_646=File %s specified in attribute \ ds-cfg-key-store-pin-file of configuration entry %s should contain the PIN \ needed to access the LDAP key manager, but this file is empty ERR_LDAP_TRUSTMANAGER_PIN_PROPERTY_NOT_SET_647=Java property %s which \ is specified in attribute ds-cfg-trust-store-pin-property of configuration \ entry %s should contain the PIN needed to access the LDAP trust \ manager, but this property is not set ERR_LDAP_TRUSTMANAGER_PIN_ENVAR_NOT_SET_648=Environment variable %s \ which is specified in attribute ds-cfg-trust-store-pin-environment-variable \ of configuration entry %s should contain the PIN needed to access the \ LDAP trust manager, but this property is not set ERR_LDAP_TRUSTMANAGER_PIN_NO_SUCH_FILE_649=File %s specified in \ attribute ds-cfg-trust-store-pin-file of configuration entry %s should \ contain the PIN needed to access the LDAP trust manager, but this file \ does not exist ERR_LDAP_TRUSTMANAGER_PIN_FILE_CANNOT_READ_650=An error occurred while \ trying to read the trust store PIN from file %s specified in configuration \ attribute ds-cfg-trust-store-pin-file of configuration entry %s: %s ERR_LDAP_TRUSTMANAGER_PIN_FILE_EMPTY_651=File %s specified in \ attribute ds-cfg-trust-store-pin-file of configuration entry %s should \ contain the PIN needed to access the LDAP trust manager, but this file \ is empty