"openssl s_client -connect" 的调用实际上是在查询 OCSP 响应服务器以确认证书的当前有效性吗?
Is this invocation of "openssl s_client -connect" actually querying OCSP responder servers to confirm the current validity of certificates?
我很好奇调用一行openssl
命令行接口是否有能力执行完整的OCSP验证协议,例如查询链中的所有 OCSP 响应服务器以确认证书的当前有效性。
为了查看是否可能如此,我将 -CAfile
选项指定为 /dev/null
,hoping 可以避免任何缓存正在使用证书代替查找: 正如@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
已经在没有任何缓存文件帮助的情况下找到链中的所有三个 link,因此必须通过 Internet 与代理进行通信 (1) GeoTrust DV SSL CA - G3,和 (2) GeoTrust Global CA,构建链。那是对的吗?
没有!不正确!
openssl
是否也通过向三个 OCSP 响应者中的每一个发出适当的 OCSP 请求来验证链?
(我的猜测是 "no"。我也知道 openssl ocsp ...
可以与证书上的手动文本操作结合使用,一次执行一个 link OSCP 验证。但是,openssl
应该被编写来执行完整的 OCSP 验证,这似乎是合理的,甚至更可取,这就是我要问的原因。)
2017 年 9 月 14 日更新:
感谢@pepo 的回答 "SSL server (if configured correctly) will send certificate chain (except root CA certificate)",我查阅了 RFC 5246 并找到了 "7.4.2 服务器证书"里面解释了TLS1.2握手的"Server Certificate"部分的内容:
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following certificate
MUST directly certify the one preceding it. Because certificate
validation requires that root keys be distributed independently, the
self-signed certificate that specifies the root certificate
authority MAY be omitted from the chain, under the assumption that
the remote end must already possess it in order to validate it in
any case.
此外,感谢@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 stapling。
如果不是 -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-checking 或 OCSP-request-response。由于此特定授权链未启用 CRL-checking,因此只剩下 OCSP-request-response。
感谢@pepo 的回复,让我明白了openssl
、TLS1.2协议和这些验证授权的方法之间的关系(已列出按历史顺序):
- CRL(证书撤销列表)检查
- OSCP 请求和响应
- OCSP 装订
不过,又提出了一个新问题:
- 关于服务器发送的 OCSP-stapling 响应以及 "Server Certificate" 消息步骤中链中的证书 - 这具有签名信息(从下一个升级)需要验证。这个签名信息在
openssl ... -status
的处理过程中真的被验证了吗?
更新:2017 年 9 月 15 日
问题 "Is this signature information actually verified during the processing of openssl ... -status
? " 的安全答案似乎是否定的,根据这个
回答
以及下面@dave_thompson_085 的评论(他查看了源代码)。
是不是很迷惑?是的!奇怪,
"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 和一个 SSL 库 "implementing" TLS1.2。在 10 分钟内,我可以编写程序并在调试器中运行它。我可以看到从 python SSL 库调用 OpenSSL 的 handshake()
函数,并假设 handshake()
必须处理所有授权检查,基于 SSL 库和 SMTP 库的假设如果不包括授权检查,则不会发布。奇怪的是,SSL 库中的调用代码包含 post-handshake()
检查以确保接收到的证书名称与被调用服务器的名称相匹配。 "Why would such a primitive check be necessary if handshake()
already handled all the signature verifications, etc.?",我想。那个怀疑开始了剥开 TLS 安全洋葱层的旅程,从那以后我一直无法停止哭泣。
我不想重新发明轮子,反正这可能会摇摇欲坠。然而,我似乎找不到任何可用的轮子。从这里去哪里?
SSL 服务器(如果配置正确)将发送证书链(根 CA 证书除外)。你可以验证一下here。
Openssl 没有获取这些证书,但它在启动 ssl 连接时提供了它们。您可以在 openssl documentation
中阅读有关 s_client 行为的更多信息
我不知道它是否进行了OCSP验证,但我对此表示怀疑。恕我直言(基于 The s_client utility is a test tool and is designed to continue the handshake after any certificate verification errors.
)默认情况下它根本不执行任何验证,但您至少可以通过指定参数 -crl_check_all
来启用 CRL 检查
openssl s_client -connect www.equifaxsecurity2017.com:443 -crl_check_all
我很好奇调用一行openssl
命令行接口是否有能力执行完整的OCSP验证协议,例如查询链中的所有 OCSP 响应服务器以确认证书的当前有效性。
为了查看是否可能如此,我将 正如@pepo 的回答中所解释的,服务器证书链被发送到 RFC 5246 中指定的基本 TLS1.2 握手的一部分(更多细节在下面更新)-CAfile
选项指定为 /dev/null
,hoping 可以避免任何缓存正在使用证书代替查找:
# 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
已经在没有任何缓存文件帮助的情况下找到链中的所有三个 link,因此必须通过 Internet 与代理进行通信 (1) GeoTrust DV SSL CA - G3,和 (2) GeoTrust Global CA,构建链。那是对的吗?
openssl
是否也通过向三个 OCSP 响应者中的每一个发出适当的 OCSP 请求来验证链?
(我的猜测是 "no"。我也知道 openssl ocsp ...
可以与证书上的手动文本操作结合使用,一次执行一个 link OSCP 验证。但是,openssl
应该被编写来执行完整的 OCSP 验证,这似乎是合理的,甚至更可取,这就是我要问的原因。)
2017 年 9 月 14 日更新:
感谢@pepo 的回答 "SSL server (if configured correctly) will send certificate chain (except root CA certificate)",我查阅了 RFC 5246 并找到了 "7.4.2 服务器证书"里面解释了TLS1.2握手的"Server Certificate"部分的内容:
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following certificate MUST directly certify the one preceding it. Because certificate validation requires that root keys be distributed independently, the self-signed certificate that specifies the root certificate authority MAY be omitted from the chain, under the assumption that the remote end must already possess it in order to validate it in any case.
此外,感谢@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 stapling。
如果不是 -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-checking 或 OCSP-request-response。由于此特定授权链未启用 CRL-checking,因此只剩下 OCSP-request-response。
感谢@pepo 的回复,让我明白了openssl
、TLS1.2协议和这些验证授权的方法之间的关系(已列出按历史顺序):
- CRL(证书撤销列表)检查
- OSCP 请求和响应
- OCSP 装订
不过,又提出了一个新问题:
- 关于服务器发送的 OCSP-stapling 响应以及 "Server Certificate" 消息步骤中链中的证书 - 这具有签名信息(从下一个升级)需要验证。这个签名信息在
openssl ... -status
的处理过程中真的被验证了吗?
更新:2017 年 9 月 15 日
问题 "Is this signature information actually verified during the processing of openssl ... -status
? " 的安全答案似乎是否定的,根据这个
回答
以及下面@dave_thompson_085 的评论(他查看了源代码)。
是不是很迷惑?是的!奇怪, "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 和一个 SSL 库 "implementing" TLS1.2。在 10 分钟内,我可以编写程序并在调试器中运行它。我可以看到从 python SSL 库调用 OpenSSL 的 handshake()
函数,并假设 handshake()
必须处理所有授权检查,基于 SSL 库和 SMTP 库的假设如果不包括授权检查,则不会发布。奇怪的是,SSL 库中的调用代码包含 post-handshake()
检查以确保接收到的证书名称与被调用服务器的名称相匹配。 "Why would such a primitive check be necessary if handshake()
already handled all the signature verifications, etc.?",我想。那个怀疑开始了剥开 TLS 安全洋葱层的旅程,从那以后我一直无法停止哭泣。
我不想重新发明轮子,反正这可能会摇摇欲坠。然而,我似乎找不到任何可用的轮子。从这里去哪里?
SSL 服务器(如果配置正确)将发送证书链(根 CA 证书除外)。你可以验证一下here。
Openssl 没有获取这些证书,但它在启动 ssl 连接时提供了它们。您可以在 openssl documentation
中阅读有关 s_client 行为的更多信息我不知道它是否进行了OCSP验证,但我对此表示怀疑。恕我直言(基于 The s_client utility is a test tool and is designed to continue the handshake after any certificate verification errors.
)默认情况下它根本不执行任何验证,但您至少可以通过指定参数 -crl_check_all
openssl s_client -connect www.equifaxsecurity2017.com:443 -crl_check_all