使用 OpenSSL 1.0.2g(OS X 上的 MacPorts),我可以检查 Google 的证书(我必须指定证书包,因为 OS X 通常将其存储在钥匙串中)
$ echo Q | /opt/local/bin/openssl s_client -connect www.google.com:443 -servername www.google.com -verify 6 -CAfile test/cabundle.crt > /dev/null
verify depth is 6
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
verify return:1
DONE
一切还好。现在如果我使用系统的版本(0.9.8zg)具有完全相同的 CA 捆绑包我收到错误:
$ echo Q | /usr/bin/openssl s_client -connect www.google.com:443 -servername www.google.com -verify 6 -CAfile test/cabundle.crt > /dev/null
verify depth is 6
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=27:certificate not trusted
verify return:1
depth=1 /C=US/O=Google Inc/CN=Google Internet Authority G2
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
verify return:1
DONE
由于我手动指定 CA 捆绑包,所以我不明白问题可能出在哪里。
答案1
从https://trac.macports.org/ticket/47805
问题在于,Apple 删除了 Yosemite 中的 1024 位根,该根被用作 Google(以及可能的其他网站)证书的信任锚。通常,这不会影响证书的有效性,因为其链中的中间证书之一不是 OS X 中受信任的根 CA(对于 Google,它是 GeoTrust Global CA)。
然而,1.0.2 之前的 OpenSSL 并没有像它应该的那样检测到这种情况(通过检查任何中间体是否是受信任的根 CA),并且始终遵循信任链到底。在这种情况下,它无法验证证书,因为证书链的末端实际上不受信任。 OpenSSL 1.0.2 添加了一个开关来解决这个问题(由 openssl s_client 中的 -trusted_first 激活),但该选项需要由每个软件单独启用。