Openssl

為什麼 openssl s_client 針對不匹配的 CAfile 驗證證書?

  • January 15, 2019

我試圖產生一個證書驗證錯誤,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.crtgnutls-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_clientUbuntu 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.cdir_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/certsX509_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,此變通方法不是必需的,因為該問題無法重現。這意味著當指定類似-CAfileor的選項時-CApath,不會將預設證書系統目錄添加到 Fedora 系統上的目錄搜尋列表中。

在帶有 openssl 1.0.2g 的 Ubuntu 16 上,問題仍然存在。

它也存在於帶有 openssl-1.0.2k-16 的 CentOS 7 上 - 不幸的是,上述解決方法在那裡沒有幫助,並且 gnutls-3.3.29-8 由於未知/意外的 TLS 數據包類型而失敗。

引用自:https://unix.stackexchange.com/questions/162969