為什麼 openssl s_client 針對不匹配的 CAfile 驗證證書?
我試圖產生一個證書驗證錯誤,
openssl s_client
如下所示:$ openssl s_client -crlf -verify 9 \ -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \ -starttls smtp -host mx-ha03.web.de -port 25
web.de 伺服器的證書是由 Deutsche Telekom CA 認證的,而不是 TURKTRUST,因此上面的命令應該會失敗,對吧?
但它報告:
Verify return code: 0 (ok)
為什麼?
我的意思是模擬 gnutls-cli 命令按預期失敗:
$ { echo -e 'ehlo example.org\nstarttls' ; sleep 1 } | \ gnutls-cli --starttls --crlf \ --x509cafile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.pem \ --port 25 mx-ha03.web.de [..] *** Verifying server certificate failed...
做一個交叉檢查,即使用
--x509cafile /etc/ssl/certs/ca-certificates.crt
gnutls-cli 我得到:[..] - The hostname in the certificate matches 'mx-ha03.web.de'. - Peer's certificate is trusted
(這也是預期的)
Openssl s_client 列印 ca-certificates.crt:
Verify return code: 0 (ok)
與 TURKTRUST 相同的結果…
首先,我懷疑 openssl 使用了
-CApath
(即 /etc/ssl/certs)的預設設置 - 但是當我處理strace
這個過程時,我只看到.open``CAfile
(所有測試都在 Ubuntu 10.04 伺服器上完成)
**更新:**我已將 TURKTRUST 證書複製到 Fedora 20 系統並執行了第一個 openssl 語句 - 我得到了不同的結果:
Verify return code: 19 (self signed certificate in certificate chain)
事實證明,
openssl s_client
Ubuntu 10.04 上的 仍然查詢系統安裝證書的預設位置,即使指定了-CApath
和-CAfile
:8466 open("/usr/lib/ssl/certs/4e18c148.0", O_RDONLY) = 4
(跟踪輸出)
在哪裡:
$ ls -l /usr/lib/ssl/certs/4e18c148.0 lrwxrwxrwx 1 root root 30 2014-04-11 21:50 /usr/lib/ssl/certs/4e18c148.0 -> Deutsche_Telekom_Root_CA_2.pem
該目錄是Ubuntu 10.04 上
/usr/lib/ssl/certs
的符號連結,因此當 grepping for ‘/etc/ssl’ …/etc/ssl/certs``open
來源
查看openssl-0.9.8k,這個問題的根源位於
crypto/x509/by_dir.c
,dir_ctrl()
:dir=(char *)Getenv(X509_get_default_cert_dir_env()); if (dir) ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); else ret=add_cert_dir(ld,X509_get_default_cert_dir(), X509_FILETYPE_PEM);
哪裡
X509_get_default_cert_dir
退貨/usr/lib/ssl/certs
和X509_get_default_cert_dir_env
退貨SSL_CERT_DIR
。解決方法
因此,可以在 Ubuntu 10.04/openssl 0.9.8k 下使用以下解決方法來獲得預期的行為:
$ SSL_CERT_DIR="" openssl s_client -crlf -verify 9 \ -CAfile /etc/ssl/certs/TURKTRUST_Certificate_Services_Provider_Root_1.crt \ -starttls smtp -host mx-ha03.web.de -port 25
並且驗證失敗:
Verify return code: 19 (self signed certificate in certificate chain)
現在的情況
這是一個 Ubuntu 問題。例如,對於 Fedora 20 的 openssl 1.0.1e 或 Fedora 29 的 openssl 1.1.1,此變通方法不是必需的,因為該問題無法重現。這意味著當指定類似
-CAfile
or的選項時-CApath
,不會將預設證書系統目錄添加到 Fedora 系統上的目錄搜尋列表中。在帶有 openssl 1.0.2g 的 Ubuntu 16 上,問題仍然存在。
它也存在於帶有 openssl-1.0.2k-16 的 CentOS 7 上 - 不幸的是,上述解決方法在那裡沒有幫助,並且 gnutls-3.3.29-8 由於未知/意外的 TLS 數據包類型而失敗。