s_client Windows 中 login.live.com 的证书验证失败

s_client certificate validation fails in Windows for login.live.com

我将 Win32OpenSSL_Light-1_0_2.exe from Shining Light Productions and installed it to the default location C:\OpenSSL-Win32. I copied the file ca-bundle.crt 下载到 C:\OpenSSL-Win32\bin 和 运行:

C:\OpenSSL-Win32\bin>openssl s_client -connect login.live.com:443 -CAfile ca-bundle.crt

证书链验证失败并显示消息:

Verify return code: 20 (unable to get local issuer certificate)

在带有 OpenSSL 版本 1.0.1e 的 Debian Wheezy 上对相同的 ca-bundle.crt 文件使用相同的命令 returns:

Verify return code: 0 (ok)

如果我将主机名更改为 api.onedrive.com(相同的命令),我会在 Windows 和 Linux.

上得到 Verify return code: 0 (ok)

我是做错了什么还是存在已知错误?我怎样才能让它在 Windows 上为 login.live.com 工作?

(最初我在 trying to connect to login.live.com with PHP's cURL extension under Windows XAMPP 时偶然发现了这个问题,但现在它看起来更像是一个 OpenSSL 问题。)

s_client 有未记录的 属性 (或者可能是一个长期存在的错误),如果您提供 -CAfile 选项,它不仅会检查给定的 CA 文件,还会检查也反对系统默认(/usr/lib/ssl/certs 在 Debian 上)。如果您 运行 openssl s_clientstrace 检查验证期间使用了哪些文件,您将看到以下内容:

$ strace -e open openssl s_client -connect login.live.com:443 -CAfile ca-bundle.crt
...
open("ca-bundle.crt", O_RDONLY)         = 3
open("/usr/lib/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
...
open("/usr/lib/ssl/certs/415660c1.0", O_RDONLY) = 4
open("/usr/lib/ssl/certs/415660c1.1", O_RDONLY) = 4

从这个输出中你可以看到它不仅使用给定的 CA 文件进行验证,而且还尝试使用 /usr/lib/ssl/cert.pem(不存在)然后查看 /usr/lib/ssl/certs 以找到所需的CA 由主题哈希 415660c1。它最终在 415660c1.1:

中找到了它正在寻找的根 CA
 $ openssl x509 -in /usr/lib/ssl/certs/415660c1.1 -text
 ...
 Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
 ...
 Subject: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority

由于 OpenSSL 没有可用的 Windows 系统默认值(它不能使用 Windows CA 存储),验证将在那里失败。

至于api.onedrive.com:这有另一个信任链,可以用给定的 CA 包完全验证。 strace 的输出显示它不会尝试访问 /usr/lib/ssl/certs.

中的任何文件