我试图产生一个证书验证错误,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 服务器的证书是由德国电信 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)
答案1
事实证明,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
符号链接,因此在 grep '/etc/ssl' 时不会选择 strace 日志中的行.../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
或之类的选项时-CApath
,不会将默认证书系统目录添加到 Fedora 系统上的目录搜索列表中。
在带有 openssl 1.0.2g 的 Ubuntu 16 上,问题仍然存在。
它也存在于带有 openssl-1.0.2k-16 的 CentOS 7 上 - 不幸的是,上述解决方法对此没有帮助,并且 gnutls-3.3.29-8 由于未知/意外的 TLS 数据包类型而失败。