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_client
和 strace
检查验证期间使用了哪些文件,您将看到以下内容:
$ 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
.
中的任何文件
我将 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_client
和 strace
检查验证期间使用了哪些文件,您将看到以下内容:
$ 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
:
$ 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
.