openssl 为过期证书返回 "Verify return code: 0 (ok)"

openssl returning "Verify return code: 0 (ok)" for expired certficiate

我正在使用 openssl 查看似乎已过期的证书:

# Write the certificate chain to a file
</dev/null openssl s_client -showcerts -connect testauth.assurity.com:443 > cert-chain.pem
# Separate chain into individual certificate files
csplit -z -f chain-link- cert-chain.pem '/--BEGIN CERT/' '{*}'
# Output the hash and dates for each certificate
for f in chain-link-01 chain-link-02 chain-link-03; do
  openssl x509 -noout -enddate -hash -subject -in $f
done

chain-link-03 的 openssl 输出包括行 notAfter=May 30 10:48:38 2020 GMT;这是一个过期的证书。然而,当我从两台不同的机器 运行 openssl s_client -showcerts -connect testauth.assurity.com:443 得到两个不同的结果:

  1. 从我的工作站,openssl 输出 Verify return code: 0 (ok)
  2. 从我的服务器,openssl 输出 Verify return code: 10 (certificate has expired)

这是怎么回事? 运行 我的工作站和服务器上的上述脚本输出每个证书的散列和主题,表明两台机器从 testauth.assurity.com:443 接收 相同的证书我想知道为什么两台机器中只有一台 returns 是非零的,我是否需要联系 Assurity 让他们更新他们的证书。

底线:我正在 运行ning 一个 ruby-on-rails 应用程序,该应用程序成功请求 testauth.assurity.com 来自我的工作站,但不是来自我的服务器。在服务器上,ruby-on-rails 应用程序拒绝发出请求,声明:

SSL_connect returned=1 errno=0 state=error: certificate verify failed (certificate has expired).

TLDR:可能是另一条路径

今天大多数 publicly 颁发的证书使用一个中间 CA,因此 01 将是您的叶证书,02 是中间 CA,而 03 可以是根证书(这是多余的) 'bridge' aka 'cross' 来自different 根的证书。这通常在创建新 CA 时完成,并且最初不在现有系统、平台和库的信任库中;它是 'cross-signed' 由不同的、现有的且已经受信任的 CA。然而,即使新的 CA 随后确实有其(自己的)根证书受信任,服务器通常会继续提供(过时的)网桥证书,因为它没有损坏。

举个方便的例子,两次 Google。 Google 用于在 GeoTrust 下为其站点获取证书,该站点在本世纪初在 Equifax 下桥接;参见示例
https://security.stackexchange.com/questions/93081/gmail-x-509-certificate-chain
https://security.stackexchange.com/questions/171983/server-certificate-terminates-in-removed-ca-certificate-still-works
https://serverfault.com/questions/841036/openssl-unable-to-get-local-issuer-certificate-for-accounts-google-com
在 GeoTrust 因 Symantec 错误发布问题(绕口令!)而受到污染后,Google 转为 GlobalSign,但 开始在信任程序中扎根,今天 https://www.ssllabs.com/ssltest/analyze.html?d=www.google.com&s=216.58.195.68&hideResults=on&ignoreMismatch=on 显示在 GTS CA 1C3 下使用了两个叶证书(一个 RSA,一个 EC),这又可以由 GlobalSign Root CA 的桥验证,也可以直接由 GTS Root R1 验证( SSLLabs 令人困惑地显示 both 为 'in trust store' and 'extra download'!)“GTS” 表示 Google 信任服务,即他们的 CA。

如果 02 是到旧根 03 的桥,并且与 02 相同的 CA 的较新根可用(如果存在相同的主题和 SKI),则可能会发生类似的情况,但这意味着叶证书是由root直接发布,违反CABforum规则;这可能是不遵循 public 规则的内部或私人 CA,但我希望它在您使用的 所有 系统中手动维护,并且不会改变。

因此,我追溯说您的工作站在其信任库中有一个(可能是更新的)直接根目录,用于与您的 03 证书中相同的 CA,但您的服务器没有,因此继续使用过期和无效的桥。也可以想象服务器有根但是使用旧的(pre-1.0.2)版本的 OpenSSL 没有实现备用链逻辑,但是在 2021 年这不太可能。

我无法验证自己,因为我的系统和SSLLabs都无法连接到testauth.assurity.com(解析为216.229.15.88)。