We've created an Open Directory master on OSX 10.10 Yosemite + Server.app v4:
$ sudo slapconfig -createldapmasterandadmin admin Administrator 1000
Which generates a root CA, an intermediate CA and a host SSL certificate (all correctly placed in both the system keychain and in the
/etc/certificates directory). However, when connecting over SSL,
slapd provides only the host certificate, rather than the entire certificate chain:
$ openssl s_client -connect a.b.c:636 CONNECTED(00000003) depth=0 CN = a.b.c, C = GB, emailAddress = firstname.lastname@example.org. verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 CN = a.b.c, C = GB, emailAddress = email@example.com verify error:num=27:certificate not trusted verify return:1 depth=0 CN = a.b.c, C = GB, emailAddress = firstname.lastname@example.org verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/CN=a.b.c/C=GB/emailAddressemail@example.com i:/CN=IntermediateCA_A.B.C_1/O=b/OU=MACOSX OpenDirectory Intermediate CA/emailAddressfirstname.lastname@example.org ---
This is a problem, of course, because clients (who trust only the root CA) fail to validate the host certificate and abort the connection.
22.214.171.124. TLSCACertificateFile <filename>
This directive specifies the PEM-format file containing certificates for the CA's that slapd will trust. The certificate for the CA that signed the server certificate must be included among these certificates. If the signing CA was not a top-level (root) CA, certificates for the entire sequence of CA's from the signing CA to the top-level CA should be present. Multiple certificates are simply appended to the file; the order is not significant.
(For the avoidance of doubt, the fact that
slapd will then provide the certificate chain to connecting clients was recently confirmed on the openldap-technical mailing list—although it has been previously noted that this gives rise to a problematic conflict where different trust anchors are used for TLS client certificates).
Since Apple's build uses
slapd.d, one would normally expect this option to be configured via
olcTLSCACertificateFile—however, according to
slapd-config(5) (emphasis added):
Specifies the file that contains certificates for all of the Certificate Authorities that slapd will recognize.
When using SecureTransport this option is not valid. Instead use the olcTLSTrustedCerts option.[ deletia ]
Lists the trusted certificates in the system keychain separated by '|'. For example: olcTLSTrustedCerts Frobozz, Inc.|Widgets R Us|www.example.com
Used by SecureTransport instead of olcTLSCACertificateFile and olcTLSCACertificatePath. Ignored by OpenSSL, GnuTLS and Mozilla NSS.
(SecureTransport is Apple's SSL library).
olcTLSTrustedCerts was not created in our directory by
slapconfig, although the host certificate was named in (the related)
olcTLSIdentity. That said,
slapd was in any event ignoring
olcTLSIdentity in favour of the
OPENDIRECTORY_SSL_IDENTITY preference in the system keychain:
TLS: OPENDIRECTORY_SSL_IDENTITY identity preference overrode configured olcTLSIdentity "a.b.c"
So, we have tried the following (both independently and together):
slapdclearly parses the CNs listed in this option and locates the CA certificates in the system keychain, as it logs cases where a deliberately incorrect value is provided:
TLS: SecItemCopyMatching(foo.bar) failed (check olcTLSTrustedCerts setting): The specified item could not be found in the keychain. (-25300)
OPENDIRECTORY_SSL_IDENTITYpreference from the system keychain.
slapdno longer complains that
olcTLSIdentityhas been overridden (and it only continues to support SSL so long as the value of that configuration option matches the CN of a certificate in the system keychain, else it complains similarly to the error quoted above—suggesting that it's using that configuration option as expected).
Yet the full certificate chain is still not provided to connecting clients. How can this be fixed?