0

我很好奇单行openssl命令行接口的调用是否有能力执行完整的OCSP验证协议,例如查询链中的所有OCSP响应服务器以确认证书的当前有效性。

为了查看是否是这样,我将-CAfile选项指定为/dev/null希望这样可以避免使用任何缓存的证书来代替查找: 正如@pepo 的回答中所解释的,服务器证书链是在 RFC 5246 中指定的基本 TLS1.2 握手的一部分发送的(下面的更新中有更多详细信息)

# openssl s_client -CAfile /dev/null -connect www.equifaxsecurity2017.com:443

这给出了输出:

CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = GeoTrust Inc., OU = Domain Validated SSL, CN = GeoTrust DV SSL CA - G3
verify return:1
depth=0 CN = www.equifaxsecurity2017.com
verify return:1
---
Certificate chain
 0 s:/CN=www.equifaxsecurity2017.com
   i:/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
 1 s:/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
<omitted>
-----END CERTIFICATE-----
subject=/CN=www.equifaxsecurity2017.com
issuer=/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
---
No client certificate CA names sent
....

看起来好像openssl在没有任何缓存文件帮助的情况下找到了链中的所有三个链接,因此必须通过 Internet 与代理 (1) GeoTrust DV SSL CA - G3和 (2) GeoTrust Global CA进行通信,以构建链。那是对的吗? 不!这是不正确的!

是否openssl还通过向三个 OCSP 响应者中的每一个发出适当的 OCSP 请求来验证链?

(我的猜测是“不”。我也知道它openssl ocsp ...可以与证书上的手动文本操作结合使用,以一次执行一个链接的 OSCP 验证。但是,这似乎是合理的,甚至更可取的是,这openssl将被写入执行完整的 OCSP 验证,这就是我要问的原因。)

2017 年 9 月 14 日更新:

感谢@pepo 的回答“SSL 服务器(如果配置正确)将发送证书链(根 CA 证书除外)”,我查找了 RFC 5246 并找到了“7.4.2 服务器证书”部分,它解释了“服务器”的内容证书”部分的 TLS1.2 握手:

这是证书的序列(链)。发件人的
证书必须在列表中排在第一位。后面的每个证书必须直接证明它前面的证书。因为证书验证要求根密钥是独立分发的,所以可以从链中省略指定根证书颁发机构的自签名证书,假设远程端必须已经拥有它才能在任何情况下验证它。

此外,感谢@pepo 对该-crl_check_all选项的回答,我尝试了这一点并得到了以下输出:

CONNECTED(00000003)
depth=0 CN = www.equifaxsecurity2017.com
verify error:num=3:unable to get certificate CRL
verify return:1
depth=1 C = US, O = GeoTrust Inc., OU = Domain Validated SSL, CN = GeoTrust DV SSL CA - G3
verify error:num=3:unable to get certificate CRL

它因错误而失败unable to get certificate CRL。事实证明这并不重要,因为所选网站启用 了OCSP 装订。

如果我们不-crl_check_all执行CRL 检查,而是 添加-status 请求OCSP 装订的选项,则会收到以下输出:

CONNECTED(00000003)
<stuff omitted omitted>
OCSP response: 
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: CE2C8B1E8BD2300FD1B15446E9B594254949321B
    Produced At: Sep 10 11:12:45 2017 GMT
    Responses:
    Certificate ID: ...
    Cert Status: good
    This Update: Sep 10 11:12:45 2017 GMT
    Next Update: Sep 17 11:12:45 2017 GMT
    Signature Algorithm: sha1WithRSAEncryption
<stuff omitted>

这表明在服务器端启用了 OCSP 装订,但它似乎只对第一个(叶)证书启用,而不是对第二个证书启用。(无论如何,必须独立验证自签名的第三个证书)。因此,要验证第二个证书,必须使用CRL-checkingOCSP-request-response。由于此特定授权链未启用CRL 检查,因此只剩下OCSP-request-response

感谢@pepo 的回复,让我更了解TLS1.2协议和这些验证授权的方法(按历史顺序列出)之间openssl的关系:

  • CRL(证书撤销列表)检查
  • OSCP 请求和响应
  • OCSP 装订

但是,也提出了一个新问题:

  • 关于在“服务器证书”消息步骤期间服务器发送的OCSP 装订响应以及链中的证书 - 这具有需要验证的签名信息(从下一级开始)。这个签名信息在处理过程中是否真的得到了验证openssl ... -status

更新:2017 年 9 月 15 日

根据这个答案 以及下面@dave_thompson_085 的评论(他已经查看了源代码) ,对“在处理过程中是否真的验证了这个签名信息openssl ... -status?”这个问题的安全答案似乎是否定 的。

是否令人困惑?是的!奇怪的是,“OpenSSL Cookbook (feistyduck, Ivan Ristić)” 对这个问题异常不清楚, 没有显示验证签名的明确方法,同时也没有明确说明签名是否已被验证。相反,对于其他两种类型的撤销检查:

“OpenSSL Cookbook”显示了明确的方法(食谱),以进一步使用openssl. 推断“OpenSSL Cookbok”不包含完全验证装订的 OCSP 响应的配方是一个非常人为的错误,因为它没有必要。

恕我直言,OpenSSL(或任何类似库)将非常负责按照以下优先顺序包含顶级文档

  • (1) 说明 OpenSSL 不提供对 TLS+授权的黑盒解决方案,
  • (2) 关于它提供的解决方案的有限部分的解释(例如,没有授权检查的 TLS 握手),
  • (3) 有关组装 OpenSSL 组件以完成授权检查解决方案的配方的文档。

误解很容易传播。就在几天前,我正在尝试编写一个简单的程序来从我的 Linux Ubuntu PC 发送通知邮件。标准 Python 版本(版本 2 和 3)包括一个 SMTP 和一个“实现”TLS1.2 的 SSL 库。我可以在 10 分钟内编写程序并在调试器中完成它。我可以看到从 python SSL 库到 OpenSSLhandshake()函数的调用,并假设handshake()必须处理所有授权检查,基于 SSL 库和 SMTP 库在不包括授权检查的情况下不会被释放的假设。奇怪的是,SSL 库中的调用代码包含一个后handshake()检查,以确保接收到的证书名称与被调用服务器的名称匹配。"handshake()已经处理了所有的签名验证,等等?”,我想。这个疑问开始了剥离 TLS 安全洋葱层的旅程,从那以后我一直哭泣不已。

我不想尝试重新发明轮子,无论如何这可能会摇摆不定。然而,我似乎找不到任何可用的轮子。然后去哪儿?

4

1 回答 1

2

SSL 服务器(如果配置正确)将发送证书链(根 CA 证书除外)。您可以在此处进行验证。

Openssl 没有获取这些证书,但它在启动 ssl 连接时得到了服务。您可以在openssl 文档中阅读有关 s_client 行为的更多信息

我不知道它是否执行 OCSP 验证,但我对此表示怀疑。恕我直言(基于The s_client utility is a test tool and is designed to continue the handshake after any certificate verification errors.)它默认情况下根本不执行任何验证,但您至少可以通过指定参数启用 CRL 检查-crl_check_all

openssl s_client -connect www.equifaxsecurity2017.com:443 -crl_check_all
于 2017-09-14T07:26:50.860 回答