Smile 笑容

php curl Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE

curl-ca-bundle.crt

Fatal error: Uncaught exception 'Exception' with message 'SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3GETSERVER_CERTIFICATE:certificate verify failed' in oauthLogin.php:85 Stack trace: #0

这个错误是由 curl 的ca证书问题导致的,验证证书失败。

$ curl -v https://api.smugmug.com/ [...] curl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3GETSERVER_CERTIFICATE:certificate verify failed

More details here: http://curl.haxx.se/docs/sslcerts.html

In the case of “api.smugmug.com”, we can see the certificate is signed by “The Usertrust Network”:

$ openssl s_client -connect api.smugmug.com:443 < /dev/null | grep issuer depth=1 /C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware verify error:num=20:unable to get local issuer certificate

I recently found a great way to fix the problem of missing root certificates. The security team at Mozilla reviews root certificate requests to add to their master root database. The Curl team pulls the most recent database from Mozilla and provides an easily downloadable root certificate store at http://curl.haxx.se/ca/cacert.pem.

Updating your local curl store (usually at /usr/local/share/curl/curl-ca-bundle.crt) is easy:

$ mv /usr/local/share/curl/curl-ca-bundle.crt /usr/local/share/curl/curl-ca-bundle.crt.OLD $ curl http://curl.haxx.se/ca/cacert.pem > /usr/local/share/curl/curl-ca-bundle.crt

If all else fails, you can add the "-k" or "--insecure" flag to curl so it ignores invalid SSL certificates. This abandons the authentication aspect of SSL but preserves the point-to-point encryption. Authentication is half the point of SSL, so it’s worth taking the step above to update your root store.

上述方法适合 linux curl环境, 在 php环境的curl中,可以使用其他方式,最简单的、临时可以快速生效的是关闭证书验证和主机验证。需要注意其潜在的风险。

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);  
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

这两个可以关闭主机验证和证书验证。

参考资料: http://patrickmd.net/blog/2008/07/07/where-can-i-get-all-the-ssl-root-certificates/ http://www.cnblogs.com/ainiaa/archive/2011/11/08/2241385.html