Ssl

如何強制 Open Directory 伺服器向連接的客戶端提供其完整的證書鏈?

  • December 18, 2014

問題

我們在 OSX 10.10 Yosemite + Server.app v4 上創建了一個 Open Directory master:

$ 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 = a@b.c.
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = a@b.c
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = a@b.c
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=a.b.c/C=GB/emailAddress=a@b.c
  i:/CN=IntermediateCA_A.B.C_1/O=b/OU=MACOSX OpenDirectory Intermediate CA/emailAddress=a@b.c
---

當然,這是一個問題,因為客戶端(僅信任根 CA)無法驗證主機證書併中止連接。

記錄在案的解決方案

根據OpenLDAP Software 2.4 Administrator’s Guide,第 16 章“使用 TLS”

16.2.1.1。TLSCACertificateFile <文件名>

該指令指定 PEM 格式文件,其中包含 slapd 將信任的 CA 的證書。簽署伺服器證書的 CA 的證書必須包含在這些證書中。如果簽名 CA 不是頂級(根)CA,則應該存在從簽名 CA 到頂級 CA 的整個 CA 序列的證書。多個證書只是附加到文件中;順序不重要。

(為避免疑義,最近在 openldap-technical 郵件列表上確認了slapd隨後將向連接客戶端提供證書鏈的事實——儘管之前已經註意到這會導致使用不同信任錨的問題衝突對於 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 忽略。

SecureTransport是 Apple 的 SSL 庫)。

我們的嘗試……

令人驚訝的是,雖然主機證書在(相關)olcTLSTrustedCerts命名,但並未在我們的目錄中創建。也就是說,無論如何都忽略了系統鑰匙串中的偏好:slapconfig``olcTLSIdentity``slapd``olcTLSIdentity``OPENDIRECTORY_SSL_IDENTITY

TLS:OPENDIRECTORY_SSL_IDENTITY 身份首選項覆蓋配置的 olcTLSIdentity “abc”

因此,我們嘗試了以下方法(獨立和一起):

  1. 添加olcTLSTrustedCerts. slapd清楚地解析此選項中列出的 CN 並在系統鑰匙串中找到 CA 證書,因為它記錄了故意提供不正確值的情況:

TLS:SecItemCopyMatching(foo.bar) 失敗(檢查 olcTLSTrustedCerts 設置):在鑰匙串中找不到指定的項目。(-25300)

  1. OPENDIRECTORY_SSL_IDENTITY從系統鑰匙串中刪除首選項。 slapd不再抱怨olcTLSIdentity已被覆蓋(並且它只繼續支持 SSL,只要該配置選項的值與系統鑰匙串中證書的 CN 匹配,否則它會抱怨類似於上面引用的錯誤 - 表明它正在使用該預期的配置選項)。

然而,完整的證書鏈仍然沒有提供給連接的客戶端。如何解決這個問題?

問題是雙重的:

  1. 安全傳輸使用 API 客戶端提供給它的證書鏈。API 文件和原始碼註釋都暗示(沒有明確表示)這是一個錯誤:在這種情況下,安全傳輸似乎應該嘗試從系統鑰匙串建構證書鏈。
  2. Apple 的 slapd始終**只為 Secure Transport 提供主機身份證書,而不是證書鏈。請參閱從以下摘錄的片段libraries/libldap/tls_st.c
[ctx-&gt;identity_certs =](https://github.com/aosm/OpenLDAP/blob/ed3398e553abcb349419fdb038e489283feca6cd/OpenLDAP/libraries/libldap/tls_st.c#L1026) /*
*/ [CFArrayCreate(NULL, (const void **) &identRef, 1, &kCFTypeArrayCallBacks);](https://github.com/aosm/OpenLDAP/blob/ed3398e553abcb349419fdb038e489283feca6cd/OpenLDAP/libraries/libldap/tls_st.c#L578)

[SSLSetCertificate(ssl, ctx-&gt;identity_certs);](https://github.com/aosm/OpenLDAP/blob/ed3398e553abcb349419fdb038e489283feca6cd/OpenLDAP/libraries/libldap/tls_st.c#L1120)

因此,就目前情況而言,Apple 的 slapd無法發送完整的證書鏈。

引用自:https://serverfault.com/questions/653419