为什么openssl s_client针对不匹配的CAfile验证证书?


10

我正在尝试产生证书验证错误,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.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该过程时,我只看到opensyscall作为参数CAfile

(所有测试均在Ubuntu 10.04服务器上完成)

更新:我已经将TURKTRUST证书复制到Fedora 20系统并执行了第一个openssl语句-在那里我得到了不同的结果:

Verify return code: 19 (self signed certificate in certificate chain)

Answers:


10

事实openssl s_client证明,即使指定了-CApath ,在Ubuntu 10.04上,仍然会在默认位置查询系统安装的证书-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

该目录/usr/lib/ssl/certs/etc/ssl/certsUbuntu 10.04上的符号链接,因此在open对'/ etc / ssl'进行grepping时,不会选择strace日志中的行。

资源

综观的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/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数据包类型而失败。


我的版本为1.0.2g,但仍然存在此错误。更糟的是,-verify_return_error标志没有任何作用,即使证书错误,TLS连接也会继续进行。
takumar

@takumar,我在Ubuntu 16下使用openssl 1.0.2g-1ubuntu4.14对其进行了重新测试,并且可以确认,但没有解决方法,openssl测试仍然失败。但是至少有了解决方法后,我得到了预期的错误消息-有了解决方法,-verify_return_error命令以退出状态1终止。使用Fedora 29和openssl-1.1.1-3.fc29.x86_64,一切仍然按预期进行,即,解决方法没必要
maxschlepzig

在2019年,macOS似乎仍然如此。此外,某些系统可能支持-no-CAfile不要从默认文件位置加载受信任的CA证书)和-no-CApath不要从默认目录位置加载受信任的CA证书),但是我的系统不支持,因此我没有对其进行测试。
Arjan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.