LDAP-Based Keystore

Interface Stability: Evolving

DS servers implement an OpenDJ security provider as an LDAP and LDIF-based keystore. Its keystore type is LDAP.

An LDAP keystore can store trusted certificates, private keys, and secret keys. It stores key entries in the directory under a base DN that you specify. It protects private and secret keys by encrypting them with the keystore password.

You can store keys in a database backend or in an LDIF file. By storing keys in a database backend, you let replication distribute the keys securely to all replicas. LDIF storage can be useful for testing purposes.

You access an LDAP keystore with the keytool command, or any tools that work with Java keystores. The tool must have access to the security provider implementation in the server libraries, and to a configuration file for connecting to the LDAP or LDIF storage.

LDAP Keystore Base DN

The following command adds a base DN for an LDAP keystore:

$ ldapmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password << EOF
dn: ou=keystore,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
aci: (target = "ldap:///ou=keystore,dc=example,dc=com")(targetattr = "*")
 (version 3.0;acl "Insecure LDAP to keystore only on localhost";
 deny(all)(ip != "127.0.0.1" and ssf <= "1");)
ou: keystore
EOF

LDAP Keystore Configuration Files

External tools that access an LDAP keystore require a configuration file.

If the LDAP keystore stores keys in the directory, the tools require a configuration file such as the following:

# Configuration file for LDAP keystore using the directory
org.forgerock.opendj.security.keyStoreBaseDn=ou=keystore,dc=example,dc=com
org.forgerock.opendj.security.host=localhost
org.forgerock.opendj.security.port=1389
org.forgerock.opendj.security.bindDn=uid=admin
org.forgerock.opendj.security.bindPassword=password

The keyStoreBaseDn must exist before it is used.

The LDAP keystore does not support LDAPS. Allow simple binds over LDAP to use the keystore:

$ dsconfig \
 set-global-configuration-prop \
 --set unauthenticated-requests-policy:allow \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

$ dsconfig \
 set-password-policy-prop \
 --policy-name "Root Password Policy" \
 --set require-secure-authentication:false \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

If the LDAP keystore is backed by an LDIF file, the configuration file must specify the file to use:

# Configuration file for LDAP keystore using LDIF
org.forgerock.opendj.security.ldif=/path/to/keystore.ldif
org.forgerock.opendj.security.keyStoreBaseDn=ou=keystore,dc=example,dc=com

LDAP Keystore PIN

Examples that follow use an LDAP keystore PIN stored in an LDAP_PIN environment variable:

Generate a Key Pair

The following example generates a public-private key pair in the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -genkeypair \
 -keyalg EC \
 -alias "private-key" \
 -ext "san=dns:ds.example.com" \
 -dname "CN=ds.example.com,O=Example Corp,C=FR" \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN

Generate a Certificate Signing Request

The following example generates a certificate signing request (CSR) for a private key in the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -certreq \
 -alias "private-key" \
 -file private-key.csr \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN

Self-Sign a Private Key

The following example self signs a public key certificate associated with a private key in the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -selfcert \
 -alias "private-key" \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN

Generate Secret Key

The following example generates an AES secret key in the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -genseckey \
 -alias "secret-key" \
 -keyalg AES \
 -keysize 256 \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN

Import Trusted Certificate

The following examples import trusted certificates into the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable.

The following example imports a certificate in binary format:

$ keytool \
 -importcert \
 -alias "trusted-cert" \
 -file cert.crt \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN \
 -noprompt

Certificate was added to keystore

The following example imports a certificate in PEM format. The only difference with the previous command is the certificate file name:

$ keytool \
 -importcert \
 -alias "trusted-cert" \
 -file cert.pem \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN \
 -noprompt

Certificate was added to keystore

List Contents

The following example lists the contents of the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -list \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN \
 -noprompt

Keystore type: LDAP
Keystore provider: OpenDJ

Your keystore contains 3 entries

private-key, <date>, PrivateKeyEntry,
...
secret-key, <date>, SecretKeyEntry,
trusted-cert, <date>, trustedCertEntry,
...

Delete Key

The following example deletes a key from the LDAP keystore.

Notice the classpath settings (with -J) that require access to the server libraries, the reference to a configuration file, and the password in the LDAP_PIN environment variable:

$ keytool \
 -delete \
 -alias "private-key" \
 -J-cp -J/path/to/opendj/lib/bootstrap-client.jar \
 -providerName OpenDJ \
 -providerClass org.forgerock.opendj.security.OpenDjSecurityProvider \
 -providerArg keystore.conf \
 -storetype LDAP \
 -keystore NONE \
 -storepass:env LDAP_PIN \
 -keypass:env LDAP_PIN \
 -noprompt

Create Key Manager Provider

The following example creates a key manager provider for the LDAP keystore:

$ dsconfig \
 create-key-manager-provider \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --provider-name LDAP \
 --type ldap \
 --set enabled:true \
 --set base-dn:ou=keystore,dc=example,dc=com \
 --set key-store-pin:"&{ldap.pin}" \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

You can reference this key manager provider in connection handler configurations:

$ dsconfig \
 set-connection-handler-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --handler-name LDAPS \
 --set key-manager-provider:LDAP \
 --set ssl-cert-nickname:private-key \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Create Trust Manager Provider

The following example creates a trust manager provider for the LDAP keystore:

$ dsconfig \
 create-trust-manager-provider \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --provider-name LDAP \
 --type ldap \
 --set enabled:true \
 --set base-dn:ou=keystore,dc=example,dc=com \
 --set trust-store-pin:"&{ldap.pin}" \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

You can reference this trust manager provider in connection handler configurations:

$ dsconfig \
 set-connection-handler-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --handler-name LDAPS \
 --set trust-manager-provider:LDAP \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt