问题

问题

问题

我们在 OSX 10.10 Yosemite + Server.app v4 上创建了一个 Open Directory 主服务器:

$ sudo slapconfig -createldapmasterandadmin admin Administrator 1000

这会生成一个根 CA、一个中间 CA 和一个主机 SSL 证书(所有证书均正确放置在系统钥匙串和目录中/etc/certificates)。但是,当通过 SSL 连接时,slapd提供仅主机证书,而不是整个证书链:

$ openssl s_client -connect a.b.c:636                        
CONNECTED(00000003)
depth=0 CN = a.b.c, C = GB, emailAddress = [email protected].
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = [email protected]
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = [email protected]
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/CN=a.b.c/C=GB/[email protected]
   i:/CN=IntermediateCA_A.B.C_1/O=b/OU=MACOSX OpenDirectory Intermediate CA/[email protected]
---

当然,这是一个问题,因为客户端(仅信任根 CA)无法验证主机证书并中止连接。

记录解决方案

根据OpenLDAP 软件 2.4 管理员指南,第 16 章“使用 TLS”

16.2.1.1. TLSCACertificateFile <文件名>

此指令指定包含 slapd 将信任的 CA 证书的 PEM 格式文件。签署服务器证书的 CA 的证书必须包含在这些证书中。如果签署 CA 不是顶级(根)CA,则应存在从签署 CA 到顶级 CA 的整个 CA 序列的证书。多个证书只需附加到文件即可;顺序并不重要。

(为避免疑问,slapd随后将向连接客户端提供证书链的事实最近被在 openldap-technical 邮件列表上确认—尽管先前指出这会导致有问题的冲突,因为不同的信任锚用于 TLS 客户端证书)。

苹果的特色

由于 Apple 的构建使用了slapd.d,人们通常会期望通过 — 来配置此选项olcTLSCACertificateFile,但是,根据slapd-config(5)(强调添加):

olcTLSCACertificateFile:<文件名>

指定包含 slapd 可以识别的所有证书颁发机构的证书的文件。

使用 SecureTransport 时此选项无效。请改用 olcTLSTrustedCerts 选项。

[德莱蒂亚]

olcTLSTrustedCerts

列出系统钥匙串中受信任的证书,以“|”分隔。例如:olcTLSTrustedCerts Frobozz, Inc.|Widgets R Us|www.example.com

由 SecureTransport 使用,而不是 olcTLSCACertificateFile 和 olcTLSCACertificatePath。被 OpenSSL、GnuTLS 和 Mozilla NSS 忽略。

安全传输是 Apple 的 SSL 库)。

我们的尝试…

令人惊讶的是,olcTLSTrustedCerts并没有在我们的目录中创建slapconfig,尽管主机证书曾是在(相关)中命名olcTLSIdentity。也就是说,slapd无论如何都会忽略系统钥匙串中的偏好olcTLSIdentityOPENDIRECTORY_SSL_IDENTITY

TLS:OPENDIRECTORY_SSL_IDENTITY 身份偏好覆盖了配置的 olcTLSIdentity“abc”

因此,我们尝试了以下方法(独立和共同尝试):

  1. 正在添加olcTLSTrustedCerts slapd清楚地解析此选项中列出的 CN 并在系统钥匙串中找到 CA 证书,因为它记录了故意提供不正确值的情况:

    TLS:SecItemCopyMatching(foo.bar)失败(检查 olcTLSTrustedCerts 设置):在钥匙串中找不到指定的项目。(-25300)

  2. OPENDIRECTORY_SSL_IDENTITY从系统钥匙串中删除偏好设置. slapd不再抱怨olcTLSIdentity已被覆盖(并且只要该配置选项的值与系统钥匙串中的证书的 CN 匹配,它就会继续支持 SSL,否则它会抱怨类似于上面引用的错误 - 表明它正在按预期使用该配置选项)。

但完整的证书链仍未提供给连接客户端。如何解决这个问题?

答案1

问题有两个方面:

  1. 安全传输使用证书链确切地由 API 客户端提供。API 文档和源代码注释都暗示(没有明确)这是一个错误:在这种情况下,安全传输似乎应该尝试从系统钥匙串构建证书链。

  2. 苹果的打击总是为安全传输提供主机身份证书仅有的绝不证书链。请参阅以下摘录自的片段libraries/libldap/tls_st.c

    ctx->identity_certs = /*
    */ CFArrayCreate(NULL, (const void **) &identRef, 1, &kCFTypeArrayCallBacks);
    
    SSLSetCertificate(ssl, ctx->identity_certs);
    

因此,就目前情况而言,苹果的不能发送完整的证书链。

相关内容