From e1e451f8b0c3490bddbd3d6ee3d0fe5105639bad Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Thu, 31 Jan 2013 14:59:53 +0000
Subject: [PATCH] CR-1234 Fix for OPENDJ-638: Describe how to authenticate with client certificates

---
 opendj3/src/main/docbkx/admin-guide/chap-listeners.xml       |  372 ++++++++++++++++++++-
 opendj3/src/main/docbkx/admin-guide/chap-ldap-operations.xml |  592 ++++++++++++++++++++++++++++++++++
 2 files changed, 945 insertions(+), 19 deletions(-)

diff --git a/opendj3/src/main/docbkx/admin-guide/chap-ldap-operations.xml b/opendj3/src/main/docbkx/admin-guide/chap-ldap-operations.xml
index a0d73b9..f6848a4 100644
--- a/opendj3/src/main/docbkx/admin-guide/chap-ldap-operations.xml
+++ b/opendj3/src/main/docbkx/admin-guide/chap-ldap-operations.xml
@@ -20,7 +20,7 @@
   !
   ! CCPL HEADER END
   !
-  !      Copyright 2011-2012 ForgeRock AS
+  !      Copyright 2011-2013 ForgeRock AS
   !    
 -->
 <chapter xml:id='chap-ldap-operations'
@@ -1133,4 +1133,594 @@
    </step>
   </procedure>
  </section>
+
+ <section xml:id="client-cert-auth">
+  <title>Authenticating Using a Certificate</title>
+  <indexterm><primary>Certificates</primary></indexterm>
+  <indexterm><primary>StartTLS</primary></indexterm>
+  <indexterm><primary>SSL</primary></indexterm>
+
+  <para>One alternative to simple binds with user name/password combinations
+  consists in storing a digital certificate on the user entry, and then using
+  the certificate as credentials during the bind. You can use this mechanism for
+  example to let applications bind without using passwords.</para>
+
+  <para>Simply by setting up a secure connection with a certificate, the client
+  is in effect authenticating to the server. The server must close the
+  connection if it cannot trust the client certificate. However, the process
+  of establishing a secure connection does not in itself identify the client
+  to OpenDJ directory server.</para>
+
+  <para>Instead when binding with a certificate, the client must request the
+  SASL External mechanism by which OpenDJ directory server maps the certificate
+  to the client entry in the directory. When it finds a match, OpenDJ sets the
+  authorization identity for the connection to that of the client, and the bind
+  is successful.</para>
+
+  <para>For the whole process of authenticating with a certificate to work
+  smoothly, OpenDJ and the client must trust each others' certificates, the
+  client certificate must be stored on the client entry in the directory, and
+  OpenDJ must be configured to map the certificate to the client entry.</para>
+
+  <procedure xml:id="add-client-cert">
+   <title>To Add Certificate Information to an Entry</title>
+
+   <para>Before trying to bind to OpenDJ directory server using a certificate,
+   create a certificate, and then add the certificate attributes to the
+   entry.</para>
+
+   <para><link xlink:href="http://opendj.forgerock.org/Example.ldif"
+   xlink:show="new">Example.ldif</link> includes an entry for
+   <literal>cn=My App,ou=Apps,dc=example,dc=com</literal>. Examples in this
+   section use that entry, and use the Java <command>keytool</command> command
+   to manage the certificate.</para>
+
+   <step>
+    <para>Create a certificate using the DN of the client entry as the
+    distinguished name string.</para>
+
+    <screen>$ keytool
+ -genkey
+ -alias myapp-cert
+ -keyalg rsa
+ -dname "cn=My App,ou=Apps,dc=example,dc=com"
+ -keystore keystore
+ -storepass changeit
+ -keypass changeit</screen>
+   </step>
+
+   <step>
+    <para>Get the certificate signed.</para>
+
+    <para>If you cannot get the certificate signed by a Certificate Authority,
+    self-sign the certificate.</para>
+
+    <screen>$ keytool
+ -selfcert
+ -alias myapp-cert
+ -validity 7300
+ -keystore keystore
+ -storepass changeit
+ -keypass changeit</screen>
+   </step>
+
+   <step>
+    <para>Make note of the certificate fingerprints.</para>
+
+    <para>Later in this procedure you update the client application entry with
+    the MD5 fingerprint, which in this example is
+    <literal>48:AC:F9:13:11:E0:AB:C4:65:A2:83:9E:DB:FE:0C:37</literal>.</para>
+    <screen>$ keytool
+ -list
+ -v
+ -alias myapp-cert
+ -keystore keystore
+ -storepass changeit
+Alias name: myapp-cert
+Creation date: Jan 18, 2013
+Entry type: PrivateKeyEntry
+Certificate chain length: 1
+Certificate[1]:
+Owner: CN=My App, OU=Apps, DC=example, DC=com
+Issuer: CN=My App, OU=Apps, DC=example, DC=com
+Serial number: 5ae2277
+Valid from: Fri Jan 18 18:27:09 CET 2013 until: Thu Jan 13 18:27:09 CET 2033
+Certificate fingerprints:
+	 MD5:  48:AC:F9:13:11:E0:AB:C4:65:A2:83:9E:DB:FE:0C:37
+	 SHA1: F9:61:54:37:AA:C1:BC:92:45:07:64:4B:23:6C:BC:C9:CD:1D:44:0F
+	 SHA256: 2D:B1:58:CD:33:40:E9:...:FD:61:EA:C9:FF:6A:19:93:FE:E4:84:E3
+	 Signature algorithm name: SHA256withRSA
+	 Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 54 C0 C5 9C 73 37 85 4B   F2 3B D3 37 FD 45 0A AB  T...s7.K.;.7.E..
+0010: C9 6B 32 95                                        .k2.
+]
+]</screen>
+   </step>
+
+   <step>
+    <para>Export the certificate to a file in binary format.</para>
+
+    <screen>$ keytool
+ -export
+ -alias myapp-cert
+ -keystore keystore
+ -storepass changeit
+ -keypass changeit
+ -file myapp-cert.crt
+Certificate stored in file &lt;/path/to/myapp-cert.crt&gt;</screen>
+   </step>
+
+   <step>
+    <para>Modify the entry to add attributes related to the certificate.</para>
+
+    <para>By default, you need the <literal>userCertificate</literal>
+    value.</para>
+
+    <para>If you want OpenDJ to map the certificate to its fingerprint, use
+    <literal>ds-certificate-fingerprint</literal>. This example uses the MD5
+    fingerprint, which corresponds to the default setting for the Fingerprint
+    Certificate Mapper.</para>
+
+    <para>If you want to map the certificate subject DN to an attribute of the
+    entry, use <literal>ds-certificate-subject-dn</literal>.</para>
+
+    <screen>$ cat addcert.ldif
+dn: cn=My App,ou=Apps,dc=example,dc=com
+changetype: modify
+add: objectclass
+objectclass: ds-certificate-user
+-
+add: ds-certificate-fingerprint
+ds-certificate-fingerprint: 48:AC:F9:13:11:E0:AB:C4:65:A2:83:9E:DB:FE:0C:37
+-
+add: ds-certificate-subject-dn
+ds-certificate-subject-dn: CN=My App, OU=Apps, DC=example, DC=com
+-
+add: userCertificate;binary
+userCertificate;binary:&lt;file:///path/to/myapp-cert.crt
+
+$ ldapmodify
+ --port 1389
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --filename addcert.ldif
+Processing MODIFY request for cn=My App,ou=Apps,dc=example,dc=com
+MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com</screen>
+   </step>
+
+   <step>
+    <para>Check your work.</para>
+
+    <screen>$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ "(cn=My App)"
+dn: cn=My App,ou=Apps,dc=example,dc=com
+ds-certificate-fingerprint: 4B:F5:CF:2C:2D:B3:86:14:FF:43:A8:37:17:DD:E7:55
+userCertificate;binary:: MIIDOzCCAiOgAwIBAgIESfC6IjANBgkqhkiG9w0BAQsFADBOMRMwEQY
+ KCZImiZPyLGQBGRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTENMAsGA1UECxMEQXBwczEPMA
+ 0GA1UEAxMGTXkgQXBwMB4XDTEzMDExNzE3MTEwM1oXDTEzMDQxNzE3MTEwM1owTjETMBEGCgmSJomT8
+ ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxDTALBgNVBAsTBEFwcHMxDzANBgNVBAMT
+ Bk15IEFwcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJQYq+jG4ZQdNkyBT4OQBZ0sFkl
+ X5o2yBViDMGl1sSWIRGLpFwu6iq1chndPBJYTC+FkT66yEEOwWOpSfcYdFHkMQP0qp5A8mgP6bYkeH1
+ ROvQ1nhLs0ILuksR10CVIQ5b1zv6bGEFhA9gSKmpHfQOSt9PXq8+kuz+4RgZk9Il28tgDNMm91wSJr7
+ kqi5g7a2a7Io5s9L2FeLhVSBYwinWQnASk8nENrhcE0hHkrpGsaxdhIQBQQvm+SRC0dI4E9iwBGI3Lw
+ lV3a4KTa5DlYD6cDREI6B8XlSdc1DaIhwC8CbsE0WJQoCERSURdjkuHrPck6f69HKUFRiC7JMT3dFbs
+ CAwEAAaMhMB8wHQYDVR0OBBYEFFTAxZxzN4VL8jvTN/1FCqvJazKVMA0GCSqGSIb3DQEBCwUAA4IBAQ
+ BXsAIEw7I5XUzLFHvXb2N0hmW/Vmhb/Vlv9LTT8JcCRJy4zaiyS9Q+Sp9zQUkrXauFnNAhJLwpAymjZ
+ MCOq1Th1bw9LnIzbccPQ/1+ZHLKDU5pgnc5BcvaV6Zl6COLLH2OOt0XMZ/OrODBV1M6STfhChqcowff
+ xp72pWMQe+kpZfzjeDBk4kK2hUNTZsimB9qRyrDAMCIXdmdmFv1o07orxjy8c/6S1329swiiVqFckBR
+ aXIa8wCcXjpQbZacDODeKk6wZIKxw4miLg1YByCMa7vkUfz+Jj+JHgbHjyoT/G82mtDbX02chLgXbDm
+ xJPFN3mwAC7NEkSPbqd35nJlf3
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: ds-certificate-user
+objectClass: top
+ds-certificate-subject-dn: CN=My App, OU=Apps, DC=example, DC=com
+cn: My App
+sn: App</screen>
+   </step>
+
+   <step>
+    <para>When using a self-signed certificate, import the client certificate
+    into the trust store for OpenDJ.</para>
+
+    <para>When the client presents its certificate to OpenDJ, by default OpenDJ
+    has to be able to trust the client certificate before it can accept the
+    connection.</para>
+
+    <screen>$ keytool
+ -import
+ -alias myapp-cert
+ -file /path/to/myapp-cert.crt
+ -keystore /path/to/OpenDJ/config/truststore
+ -storepass `cat /path/to/OpenDJ/config/keystore.pin`
+Owner: CN=My App, OU=Apps, DC=example, DC=com
+Issuer: CN=My App, OU=Apps, DC=example, DC=com
+Serial number: 5ae2277
+Valid from: Fri Jan 18 18:27:09 CET 2013 until: Thu Jan 13 18:27:09 CET 2033
+Certificate fingerprints:
+	 MD5:  48:AC:F9:13:11:E0:AB:C4:65:A2:83:9E:DB:FE:0C:37
+	 SHA1: F9:61:54:37:AA:C1:BC:92:45:07:64:4B:23:6C:BC:C9:CD:1D:44:0F
+	 SHA256: 2D:B1:58:CD:33:40:E9:...:FD:61:EA:C9:FF:6A:19:93:FE:E4:84:E3
+	 Signature algorithm name: SHA256withRSA
+	 Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 54 C0 C5 9C 73 37 85 4B   F2 3B D3 37 FD 45 0A AB  T...s7.K.;.7.E..
+0010: C9 6B 32 95                                        .k2.
+]
+]
+
+Trust this certificate? [no]:  yes
+Certificate was added to keystore</screen>
+   </step>
+
+   <step>
+    <para>When using a certificate signed by a CA whose certificate is not
+    delivered with the Java runtime environment<footnote>
+     <para><filename>$JAVA_HOME/jre/lib/security/cacerts</filename> holds the
+     certificates for many CAs. To get the full list, use the following
+     command.</para>
+     <screen>$ keytool
+ -list
+ -v
+ -keystore $JAVA_HOME/jre/lib/security/cacerts
+ -storepass changeit</screen></footnote>, import the CA certificate either
+     into the Java runtime environment trust store, or into the OpenDJ trust
+     store as shown in the following example.</para>
+
+    <screen>$ keytool
+ -import
+ -alias ca-cert
+ -file ca.crt
+ -keystore /path/to/OpenDJ/config/truststore
+ -storepass `cat /path/to/OpenDJ/config/keystore.pin`
+Owner: EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR
+Issuer: EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR
+Serial number: d4586ea05c878b0c
+Valid from: Tue Jan 29 09:30:31 CET 2013 until: Mon Jan 24 09:30:31 CET 2033
+Certificate fingerprints:
+	 MD5:  8A:83:61:9B:E7:18:A2:21:CE:92:94:96:59:68:60:FA
+	 SHA1: 01:99:18:38:3A:57:D7:92:7B:D6:03:8C:7B:E4:1D:37:45:0E:29:DA
+	 SHA256: 5D:20:F1:86:CC:CD:64:50:1E:54:...:DF:15:43:07:69:44:00:FB:36:CF
+	 Signature algorithm name: SHA1withRSA
+	 Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.35 Criticality=false
+AuthorityKeyIdentifier [
+KeyIdentifier [
+0000: 30 07 67 7D 1F 09 B6 E6   90 85 95 58 94 37 FD 31  0.g........X.7.1
+0010: 03 D4 56 7B                                        ..V.
+]
+[EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR]
+SerialNumber: [    d4586ea0 5c878b0c]
+]
+
+#2: ObjectId: 2.5.29.19 Criticality=false
+BasicConstraints:[
+  CA:true
+  PathLen:2147483647
+]
+
+#3: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 30 07 67 7D 1F 09 B6 E6   90 85 95 58 94 37 FD 31  0.g........X.7.1
+0010: 03 D4 56 7B                                        ..V.
+]
+]
+
+Trust this certificate? [no]:  yes
+Certificate was added to keystore</screen>
+   </step>
+
+   <step>
+    <para>If you updated the OpenDJ trust store to add a certificate, restart
+    OpenDJ to make sure it reads the updated trust store and can recognize the
+    certificate.</para>
+
+    <screen>$ stop-ds --restart
+Stopping Server...
+...
+... The Directory Server has started successfully</screen>
+   </step>
+  </procedure>
+
+  <procedure xml:id="config-cert-mappers">
+   <title>To Configure Certificate Mappers</title>
+
+   <variablelist>
+    <para>OpenDJ uses certificate mappers during binds to establish a mapping
+     between a client certificate and the entry that corresponds to that
+     certificate. The certificate mappers provided out of the box include the
+     following.</para>
+
+    <varlistentry>
+     <term>Fingerprint Certificate Mapper</term>
+     <listitem>
+      <para>Looks for the MD5 (default) or SHA1 certificate fingerprint in an
+      attribute of the entry (default:
+      <literal>ds-certificate-fingerprint</literal>).</para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term>Subject Attribute To User Attribute Mapper</term>
+     <listitem>
+      <para>Looks for a match between an attribute of the certificate subject
+      and an attribute of the entry (default: match <literal>cn</literal> in
+      the certificate to <literal>cn</literal> on the entry, or match
+      <literal>e</literal> in the certificate to <literal>mail</literal> on
+      the entry).</para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term>Subject DN to User Attribute Certificate Mapper</term>
+     <listitem>
+      <para>Looks for the certificate subject DN in an attribute of the entry
+      (default: <literal>ds-certificate-subject-dn</literal>).</para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term>Subject Equals DN Certificate Mapper</term>
+     <listitem>
+      <para>Looks for an entry whose DN matches the certificate subject DN.</para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+
+   <para>If the default configurations for the certificate mappers are
+   acceptable, you do not need to change them. They are enabled by
+   default.</para>
+
+   <para>The following steps demonstrate how to change the Fingerprint Mapper
+   default algorithm of MD5 to SHA1.</para>
+
+   <step>
+    <para>List the certificate mappers to retrieve the correct name.</para>
+
+    <screen width="83">$ dsconfig
+ list-certificate-mappers
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+
+Certificate Mapper                  : Type                                : enabled
+------------------------------------:-------------------------------------:--------
+Fingerprint Mapper                  : fingerprint                         : true
+Subject Attribute to User Attribute : subject-attribute-to-user-attribute : true
+Subject DN to User Attribute        : subject-dn-to-user-attribute        : true
+Subject Equals DN                   : subject-equals-dn                   : true</screen>
+   </step>
+
+   <step>
+    <para>Examine the current configuration.</para>
+
+    <screen>$ dsconfig
+ get-certificate-mapper-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --mapper-name "Fingerprint Mapper"
+
+Property              : Value(s)
+----------------------:---------------------------
+enabled               : true
+fingerprint-algorithm : md5
+fingerprint-attribute : ds-certificate-fingerprint
+user-base-dn          : -</screen>
+   </step>
+
+   <step>
+    <para>Change the configuration as necessary.</para>
+
+    <screen>$ dsconfig
+ set-certificate-mapper-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --mapper-name "Fingerprint Mapper"
+ --set fingerprint-algorithm:sha1
+ --no-prompt</screen>
+   </step>
+
+   <step>
+    <para>Set the External SASL Mechanism Handler to use the appropriate
+    certificate mapper (default: Subject Equals DN).</para>
+
+    <para>Clients applications use the SASL External mechanism during the bind
+    to have OpenDJ set the authorization identifier based on the entry that
+    matches the client certificate.</para>
+
+    <screen>$ dsconfig
+ set-sasl-mechanism-handler-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --handler-name External
+ --set certificate-mapper:"Fingerprint Mapper"
+ --no-prompt</screen>
+   </step>
+  </procedure>
+
+  <example xml:id="auth-with-client-cert"><?dbfo keep-together="auto"?>
+   <title>Authenticate With Client Certificate</title>
+
+   <para>Instead of providing a bind DN and password as for simple
+   authentication, use the SASL EXTERNAL authentication mechanism, and provide
+   the certificate. As a test with example data you can try an anonymous search,
+   and then try with certificate-based authentication.</para>
+
+   <para>Before you try this example, make sure OpenDJ is set up to accept
+   StartTLS from clients, and that you have set up the client certificate
+   as described above. Next, create a password .pin file for your client key
+   store.</para>
+
+   <screen>$ echo changeit &gt; keystore.pin
+$ chmod 400 keystore.pin</screen>
+
+   <para>Also, if OpenDJ directory server uses a certificate for StartTLS that
+   was not signed by a well-known CA, import the appropriate certificate into
+   the client key store, which can then double as a trust store. For example,
+   if OpenDJ uses a self-signed certificate, import the server certificate into
+   the key store.</para>
+
+   <screen>$ keytool
+ -export
+ -alias server-cert
+ -file server-cert.crt
+ -keystore /path/to/OpenDJ/config/keystore
+ -storepass `cat /path/to/OpenDJ/config/keystore.pin`
+$ keytool
+ -import
+ -trustcacerts
+ -alias server-cert
+ -file server-cert.crt
+ -keystore keystore
+ -storepass `cat keystore.pin`</screen>
+
+   <para>If OpenDJ directory server uses a CA-signed certificate, but the CA is
+   not well known, import the CA certificate into your keystore.</para>
+
+   <screen>$ keytool
+ -import
+ -trustcacerts
+ -alias ca-cert
+ -file ca-cert.crt
+ -keystore keystore
+ -storepass `cat keystore.pin`</screen>
+
+   <para>Now that you can try the example, notice that OpenDJ does not return
+   the <literal>userPassword</literal> value for an anonymous search.</para>
+
+   <screen>$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ --useStartTLS
+ --trustStorePath keystore
+ --trustStorePasswordFile keystore.pin
+ "(cn=My App)" userPassword
+dn: cn=My App,ou=Apps,dc=example,dc=com
+</screen>
+
+   <para>OpenDJ does let users read the values of their own
+   <literal>userPassword</literal> attributes after they bind
+   successfully.</para>
+
+   <screen>$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ --useStartTLS
+ --useSASLExternal
+ --certNickName myapp-cert
+ --keyStorePath keystore
+ --keyStorePasswordFile keystore.pin
+ --trustStorePath keystore
+ --trustStorePasswordFile keystore.pin
+ "(cn=My App)" userPassword
+dn: cn=My App,ou=Apps,dc=example,dc=com
+userPassword: {SSHA}vy/vTthOQoV/wH3MciTOBKKR4OX+0dSN/a09Ew==</screen>
+
+   <para>You can also try the same test with other certificate mappers.</para>
+
+   <screen># Fingerprint mapper
+$ dsconfig
+ set-sasl-mechanism-handler-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --handler-name External
+ --set certificate-mapper:"Fingerprint Mapper"
+ --no-prompt
+$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ --useStartTLS
+ --useSASLExternal
+ --certNickName myapp-cert
+ --keyStorePath keystore
+ --keyStorePasswordFile keystore.pin
+ --trustStorePath keystore
+ --trustStorePasswordFile keystore.pin
+ "(cn=My App)" userPassword
+dn: cn=My App,ou=Apps,dc=example,dc=com
+userPassword: {SSHA}vy/vTthOQoV/wH3MciTOBKKR4OX+0dSN/a09Ew==
+
+# Subject Attribute to User Attribute mapper
+$ dsconfig
+ set-sasl-mechanism-handler-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --handler-name External
+ --set certificate-mapper:"Subject Attribute to User Attribute"
+ --no-prompt
+$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ --useStartTLS
+ --useSASLExternal
+ --certNickName myapp-cert
+ --keyStorePath keystore
+ --keyStorePasswordFile keystore.pin
+ --trustStorePath keystore
+ --trustStorePasswordFile keystore.pin
+ "(cn=My App)" userPassword
+dn: cn=My App,ou=Apps,dc=example,dc=com
+userPassword: {SSHA}vy/vTthOQoV/wH3MciTOBKKR4OX+0dSN/a09Ew==
+
+# Subject DN to User Attribute mapper
+$ dsconfig
+ set-sasl-mechanism-handler-prop
+ --port 4444
+ --hostname opendj.example.com
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --handler-name External
+ --set certificate-mapper:"Subject DN to User Attribute"
+ --no-prompt
+$ ldapsearch
+ --port 1389
+ --hostname opendj.example.com
+ --baseDN dc=example,dc=com
+ --useStartTLS
+ --useSASLExternal
+ --certNickName myapp-cert
+ --keyStorePath keystore
+ --keyStorePasswordFile keystore.pin
+ --trustStorePath keystore
+ --trustStorePasswordFile keystore.pin
+ "(cn=My App)" userPassword
+dn: cn=My App,ou=Apps,dc=example,dc=com
+userPassword: {SSHA}vy/vTthOQoV/wH3MciTOBKKR4OX+0dSN/a09Ew==</screen>
+  </example>
+ </section>
 </chapter>
diff --git a/opendj3/src/main/docbkx/admin-guide/chap-listeners.xml b/opendj3/src/main/docbkx/admin-guide/chap-listeners.xml
index 6ca45b6..7b2ccee 100644
--- a/opendj3/src/main/docbkx/admin-guide/chap-listeners.xml
+++ b/opendj3/src/main/docbkx/admin-guide/chap-listeners.xml
@@ -20,7 +20,7 @@
   !
   ! CCPL HEADER END
   !
-  !      Copyright 2011-2012 ForgeRock AS
+  !      Copyright 2011-2013 ForgeRock AS
   !    
 -->
 <chapter xml:id='chap-listeners'
@@ -99,20 +99,356 @@
   <title>Preparing For Secure Communications</title>
   <subtitle>Setting Up a Self-Signed Certificate</subtitle>
   <indexterm><primary>Certificates</primary></indexterm>
-  <para>You can set up a self-signed certificate as part of the OpenDJ
-  installation process. You can also choose to import your own CA-signed
-  certificate as part of the installation process.</para>
-  
-  <para>Other applications recognize certificates signed by CAs whose root
-  certificates are installed already. If you need your server certificate to
-  be recognized automagically by applications configured to use SSL out of the
-  box, then use a CA-signed certificate.</para>
-  
-  <para>Yet for testing purposes self-signed certificates can be a cheap
-  alternative. This section covers how to set up a self-signed certificate
-  after installation. With the self-signed certificate you can set up, for
-  example, secure communications with StartTLS and over LDAPS.</para>
-  
+
+  <para>One common way to protect connections between OpenDJ and client
+  applications involves using StartTLS for LDAP or LDAPS to secure
+  connections. OpenDJ and client applications use X.509 digital certificates
+  to set up secure connections.</para>
+
+  <para>Both OpenDJ and client applications check that certificates are signed
+  by a trusted party before accepting them. Merely setting up a secure
+  connection therefore involves a sort of authentication using certificates.
+  If either OpenDJ or the client application cannot trust the peer certificate,
+  then the attempt to set up a secure connection must fail.</para>
+
+  <para>By default OpenDJ client tools prompt you if they do not recognize the
+  server certificate. Other clients might not prompt you. OpenDJ server has no
+  one to prompt when a client presents a certificate that cannot be
+  trusted, so it must simply refuse to set up the
+  connection.<footnote><para>Unless you use the Blind Trust Manager
+  Provider, which is recommended only for test purposes.</para></footnote>
+  In other words, it is important for both OpenDJ and client applications
+  to be able to verify that peer certificates exchanged have been signed by
+  a trusted party.</para>
+
+  <para>In practice this means that both OpenDJ and client applications must
+  have the certificates used to sign each others' certificates in their
+  respective trust stores. Conventionally, certificates are therefore signed by
+  a Certificate Authority (CA). A CA is trusted to sign other certificates. The
+  Java runtime environment for example comes with a trust store holding
+  certificates from many well-known CAs.<footnote><para><filename
+   >$JAVA_HOME/jre/lib/security/cacerts</filename> holds the CA certificates.
+   To read the full list, use the following command.</para>
+   <screen>$ keytool
+ -list
+ -v
+ -keystore $JAVA_HOME/jre/lib/security/cacerts
+ -storepass changeit</screen></footnote> If your client uses a valid
+  certificate signed by one of these CAs, then OpenDJ can verify the
+  certificate without additional configuration, because OpenDJ can find
+  the CA certificate in the Java CA certificate trust store. Likewise if
+  you set up StartTLS or LDAPS in OpenDJ using a valid certificate signed
+  by one of these CAs, then many client applications can verify the OpenDJ
+  server certificate without further configuration.</para>
+
+  <para>In summary, if you need a certificate to be recognized automatically,
+  then use a CA-signed certificate from a well-known CA.</para>
+
+  <para>You can, however, choose to have your certificates signed some other
+  way. You can set up your own CA. You can use a CA whose signing certificate
+  is not widely distributed. You can also use self-signed certificates. In each
+  case, you must add the signing certificates into the trust store of each
+  peer making secure connections.</para>
+
+  <para>For OpenDJ directory server, you can choose to import your own CA-signed
+  certificate as part of the installation process, or later using command-line
+  tools. Alternatively, you can let the OpenDJ installation program create a
+  self-signed certificate as part of the OpenDJ installation process. In
+  addition, you can add a signing certificate to the OpenDJ trust store using
+  the Java <command>keytool</command> command.</para>
+
+  <para>The following example shows the <command>keytool</command> command to
+  add a client application's binary format, self-signed certificate to the
+  OpenDJ trust store (assuming OpenDJ is already configured to use secure
+  connections). This enables OpenDJ to recognize the self-signed client
+  application certificate. (By definition a self-signed certificate is itself
+  the signing certificate. Notice that the Owner and the Issuer are the
+  same.)</para>
+
+  <screen>$ keytool
+ -import
+ -alias myapp-cert
+ -file myapp-cert.crt
+ -keystore /path/to/OpenDJ/config/truststore
+ -storepass `cat /path/to/OpenDJ/config/keystore.pin`
+Owner: CN=My App, OU=Apps, DC=example, DC=com
+Issuer: CN=My App, OU=Apps, DC=example, DC=com
+Serial number: 5ae2277
+Valid from: Fri Jan 18 18:27:09 CET 2013 until: Thu Jan 13 18:27:09 CET 2033
+Certificate fingerprints:
+	 MD5:  48:AC:F9:13:11:E0:AB:C4:65:A2:83:9E:DB:FE:0C:37
+	 SHA1: F9:61:54:37:AA:C1:BC:92:45:07:64:4B:23:6C:BC:C9:CD:1D:44:0F
+	 SHA256: 2D:B1:58:CD:33:40:E9:ED:...:EA:C9:FF:6A:19:93:FE:E4:84:E3
+	 Signature algorithm name: SHA256withRSA
+	 Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 54 C0 C5 9C 73 37 85 4B   F2 3B D3 37 FD 45 0A AB  T...s7.K.;.7.E..
+0010: C9 6B 32 95                                        .k2.
+]
+]
+
+Trust this certificate? [no]:  yes
+Certificate was added to keystore</screen>
+
+  <para>When working with a certificate in printable encoding format (.pem)
+  rather than binary format, use the keytool <option>-rfc</option> option,
+  too.</para>
+
+  <para>Restart OpenDJ after adding certificates to the trust store to make
+  sure that OpenDJ reads the updated trust store file.</para>
+
+  <para>On the client side, if your applications are also Java applications,
+  then you can also import the OpenDJ signing certificate into the trust
+  store for the applications using the <command>keytool</command>
+  command.</para>
+
+  <para>The following example shows the <command>keytool</command> command
+  to export the OpenDJ self-signed certificate in binary format.</para>
+
+  <screen>$ keytool
+ -export
+ -alias server-cert
+ -file server-cert.crt
+ -keystore /path/to/OpenDJ/config/keystore
+ -storepass `cat /path/to/OpenDJ/config/keystore.pin`
+Certificate stored in file &lt;server-cert.crt&gt;</screen>
+
+  <para>Importing the server certificate is similar to importing the client
+  certificate, as shown above.</para>
+
+  <para>The following sections describe how to get and install certificates
+  for OpenDJ directory server on the command line, for use when setting up
+  StartTLS or LDAPS.</para>
+
+  <procedure xml:id="new-ca-signed-cert">
+   <title>To Request and Install a CA-Signed Certificate</title>
+
+   <para>First you create a server certificate in a Java Key Store. Next you
+   issue a signing request to the CA, and get the CA-signed certificate as a
+   reply. Then you set up the Key Manager Provider and Trust Manager Provider
+   to rely on your new server certificate stored in the OpenDJ key store.</para>
+
+   <step>
+    <para>Generate the server certificate by using the Java
+    <command>keytool</command> command.</para>
+
+    <para>The CN attribute value is the FQDN for OpenDJ directory server, which
+    you can see under Server Details in the OpenDJ Control Panel.</para>
+
+    <screen>$ keytool
+ -genkey
+ -alias server-cert
+ -keyalg rsa
+ -dname "CN=opendj.example.com,O=Example Corp,C=FR"
+ -keystore /path/to/OpenDJ/config/keystore
+ -storepass changeit
+ -keypass changeit</screen>
+
+    <note><para>Notice that the <option>-storepass</option> and
+    <option>-keypass</option> options take identical password arguments.
+    OpenDJ requires that you use the same password to protect both the keystore
+    and also the private key.</para></note>
+   </step>
+
+   <step>
+    <para>Create a certificate signing request file for the certificate you
+    generated.</para>
+
+    <screen>$ keytool
+ -certreq
+ -alias server-cert
+ -keystore /path/to/OpenDJ/config/keystore
+ -storepass changeit
+ -file server-cert.csr</screen>
+   </step>
+
+   <step>
+    <para>Have the CA sign the request
+    (<filename>server-cert.csr</filename>).</para>
+    <para>See the instructions from your CA on how to provide the
+    request.</para>
+    <para>The CA returns the signed certificate.</para>
+
+    <!-- Create a CA cert for signing certificates.
+
+Not part of the procedure, but helpful when trying this out:
+http://social.rocho.org/jan/selfsign.html
+
+$ openssl genrsa -des3 -out ca.key 4096
+Generating RSA private key, 4096 bit long modulus
+.....++
+.......................++
+e is 65537 (0x10001)
+Enter pass phrase for ca.key:
+Verifying - Enter pass phrase for ca.key:
+
+$ openssl req -new -x509 -days 7300 -key ca.key -out ca.crt
+Enter pass phrase for ca.key:
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+
+Country Name (2 letter code) [AU]:FR
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:Grenoble
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Corp
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Example CA
+Email Address []:mark.craig@forgerock.com
+
+$ openssl x509 -req -in server-cert.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server-cert.crt
+Signature ok
+subject=/C=FR/O=Example Corp/CN=openam.example.com
+Getting CA Private Key
+Enter pass phrase for ca.key:
+
+$ openssl x509 -req -in myapp-cert.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out myapp-cert.crt
+Signature ok
+subject=/DC=com/DC=example/OU=Apps/CN=My App
+Getting CA Private Key
+Enter pass phrase for ca.key:
+
+-->
+   </step>
+
+   <step>
+    <para>If you have set up your own CA and signed the certificate, or are
+    using a CA whose signing certificate is not included in the Java runtime
+    environment, import the CA certificate into the key store so that it can be
+    trusted.</para>
+
+    <para>Otherwise, when you import the signed certificate in the reply from
+    the (unknown) CA, <command>keytool</command> fails to import the signed
+    certificate with the message <literal>keytool error: java.lang.Exception:
+    Failed to establish chain from reply</literal>.</para>
+
+    <para>The following example illustrates import of a CA certificate created
+    with the <command>openssl</command> command. See the
+    <command>openssl</command> documentation for instructions on creating CAs
+    and on signing other certificates with the CA you created.</para>
+
+    <screen>$ keytool
+ -import
+ -keystore /path/to/OpenDJ/config/keystore
+ -file ca.crt
+ -alias ca-cert
+ -storepass changeit
+Owner: EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR
+Issuer: EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR
+Serial number: d4586ea05c878b0c
+Valid from: Tue Jan 29 09:30:31 CET 2013 until: Mon Jan 24 09:30:31 CET 2033
+Certificate fingerprints:
+	 MD5:  8A:83:61:9B:E7:18:A2:21:CE:92:94:96:59:68:60:FA
+	 SHA1: 01:99:18:38:3A:57:D7:92:7B:D6:03:8C:7B:E4:1D:37:45:0E:29:DA
+	 SHA256: 5D:20:F1:86:CC:CD:64:50:...:DF:15:43:07:69:44:00:FB:36:CF
+	 Signature algorithm name: SHA1withRSA
+	 Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.35 Criticality=false
+AuthorityKeyIdentifier [
+KeyIdentifier [
+0000: 30 07 67 7D 1F 09 B6 E6   90 85 95 58 94 37 FD 31  0.g........X.7.1
+0010: 03 D4 56 7B                                        ..V.
+]
+[EMAILADDRESS=admin@example.com, CN=Example CA, O=Example Corp, C=FR]
+SerialNumber: [    d4586ea0 5c878b0c]
+]
+
+#2: ObjectId: 2.5.29.19 Criticality=false
+BasicConstraints:[
+  CA:true
+  PathLen:2147483647
+]
+
+#3: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 30 07 67 7D 1F 09 B6 E6   90 85 95 58 94 37 FD 31  0.g........X.7.1
+0010: 03 D4 56 7B                                        ..V.
+]
+]
+
+Trust this certificate? [no]:  yes
+Certificate was added to keystore</screen>
+   </step>
+
+   <step>
+    <para>Import the signed certificate from the CA reply into the keystore
+    where you generated the server certificate.</para>
+
+    <para>In this example the certificate from the reply is
+    <filename>~/Downloads/server-cert.crt</filename>.</para>
+
+    <screen>$ keytool
+ -import
+ -trustcacerts
+ -alias server-cert
+ -file ~/Downloads/server-cert.crt
+ -keystore /path/to/OpenDJ/config/keystore
+ -storepass changeit
+ -keypass changeit
+Certificate reply was installed in keystore</screen>
+   </step>
+
+   <step>
+    <para>Configure the File Based Key Manager Provider for JKS to use the file
+    name and key store PIN that you set up with the <command>keytool</command>
+    command.</para>
+
+    <screen>$ dsconfig
+ set-key-manager-provider-prop
+ --hostname opendj.example.com
+ --port 4444
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --provider-name JKS
+ --set enabled:true
+ --set key-store-pin:changeit
+ --remove key-store-pin-file:config/keystore.pin
+ --trustAll
+ --no-prompt</screen>
+   </step>
+
+   <step>
+    <para>Configure the File Based Trust Manager Provider for JKS to use the
+    key store and PIN as well.</para>
+
+    <screen>$ dsconfig
+ set-trust-manager-provider-prop
+ --hostname opendj.example.com
+ --port 4444
+ --bindDN "cn=Directory Manager"
+ --bindPassword password
+ --provider-name JKS
+ --set enabled:true
+ --set trust-store-file:config/keystore
+ --set trust-store-pin:changeit
+ --trustAll
+ --no-prompt</screen>
+
+    <para>At this point, OpenDJ directory server can use your new CA-signed
+    certificate, for example for StartTLS and LDAPS connection handlers.</para>
+   </step>
+
+   <step>
+    <para>If you use a CA certificate that is not known to clients, such as a
+    CA that you set up yourself rather than a well-known CA whose certificate
+    is included with the client system, import the CA certificate into the
+    client application trust store. Otherwise the client application cannot
+    trust the signature on the OpenDJ CA-signed server certificate.</para>
+   </step>
+  </procedure>
+
   <procedure xml:id="new-self-signed-cert">
    <title>To Create &amp; Install a Self-Signed Certificate</title>
    
@@ -128,7 +464,7 @@
  -alias server-cert
  -keyalg rsa
  -dname "CN=opendj.example.com,O=Example Corp,C=FR"
- -keystore OpenDJ/config/keystore
+ -keystore /path/to/OpenDJ/config/keystore
  -storepass changeit
  -keypass changeit</screen>
     <para>In this example, OpenDJ is running on a system with fully qualified
@@ -148,12 +484,12 @@
     <screen>$ keytool
  -selfcert
  -alias server-cert
- -keystore OpenDJ/config/keystore
+ -keystore /path/to/OpenDJ/config/keystore
  -storepass changeit</screen>
    </step>
    <step>
     <para>Configure the File Based Key Manager Provider for JKS to use the
-    filename and key store PIN that you set up with the
+    file name and key store PIN that you set up with the
     <command>keytool</command> command.</para>
     <screen>$ dsconfig
  set-key-manager-provider-prop

--
Gitblit v1.10.0