PHP
--
Questions
--
Followers
Top Experts
Failure to verify host certificate with cURL call
Some back-story: I was running a server with Ubuntu 10.04 and used `apt-get upgrade` to move to 12.04. Â The upgrade was successful, but I had a custom ppa in sources (ondrej/PHP5 for PHP 5.5). Â The custom ppa also upgraded Apache from 2.2 to 2.4, which was undesirable. Â It ended up being a painful mess to revert Apache/PHP back to 2.2/5.3.10. Â That is complete, with everything appearing to be running OK.
Concurrently, I have started seeing a failure in an e-commerce site on the server. Â For credit card processing, the application uses PHP's cURL library to call Authorize.net's AIM gateway. Â Some investigation found that cURL was returning a validation error on the peer certificate:
Any ideas for how I can resolve this issue? Â The short-term solution was to set CURL_SSL_VERIFYPEER to false, but I dislike. Â How can I properly validate Authorize.net's certificate chain?
Concurrently, I have started seeing a failure in an e-commerce site on the server. Â For credit card processing, the application uses PHP's cURL library to call Authorize.net's AIM gateway. Â Some investigation found that cURL was returning a validation error on the peer certificate:
[07-Aug-2014 04:21:03 UTC] -ELOG:1- (blindsusa:ddpjj4a23o9hk8sh1ka10fb265) curl exec err=60:SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I tested with openssl s_client, and saw something very similar:
#> openssl s_client -connect secure.authorize.net:443 -verify 3
verify depth is 3
CONNECTED(00000003)
depth=2 C = US, O = "Entrust, Inc.", OU = www.entrust.net/CPS is incorporated by reference, OU = "(c) 2006 Entrust, Inc.", CN = Entrust Root Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=2 C = US, O = "Entrust, Inc.", OU = www.entrust.net/CPS is incorporated by reference, OU = "(c) 2006 Entrust, Inc.", CN = Entrust Root Certification Authority
verify error:num=27:certificate not trusted
verify return:1
depth=1 C = US, O = "Entrust, Inc.", OU = www.entrust.net/rpa is incorporated by reference, OU = "(c) 2009 Entrust, Inc.", CN = Entrust Certification Authority - L1E
verify return:1
depth=0 C = US, ST = California, L = Mountain View, 1.3.6.1.4.1.311.60.2.1.3 = US, 1.3.6.1.4.1.311.60.2.1.2 = Delaware, O = Cybersource Corporation, businessCategory = Private Organization, serialNumber = 2838921 + CN = secure.authorize.net
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/O=Cybersource Corporation/businessCategory=Private Organization/serialNumber=2838921/CN=secure.authorize.net
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1E
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1E
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/CPS is incorporated by reference/OU=(c) 2006 Entrust, Inc./CN=Entrust Root Certification Authority
2 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/CPS is incorporated by reference/OU=(c) 2006 Entrust, Inc./CN=Entrust Root Certification Authority
i:/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority
Looking in /etc/ssl/certs, I can see what look to be the appropriate certificates. Â Using -CApath or -CAfile on openssl showed no change. Â I even tried downloading the current certs from Entrust's site, with no change.Any ideas for how I can resolve this issue? Â The short-term solution was to set CURL_SSL_VERIFYPEER to false, but I dislike. Â How can I properly validate Authorize.net's certificate chain?
Zero AI Policy
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
ASKER CERTIFIED SOLUTION
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
The entire routine is here:
Downloading the new certificate bundle worked, but I'm curious to know why. Â In my attempts yesterday, I updated the ca-certificates package through apt-get. Â I even downloaded the appropriate certs from the issuer, though I can't be certain they were the correct ones or that I installed their hashes correctly. Â How should I keep this updated in the future?
$ch = curl_init("https://secure.authorize.net/gateway/transact.dll");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$buffer = curl_exec($ch);
curl_close($ch);
The $fields variable is key1=value1&key2=value2 POST string. Â The commented line was put in to bypass this issue in the short term.Downloading the new certificate bundle worked, but I'm curious to know why. Â In my attempts yesterday, I updated the ca-certificates package through apt-get. Â I even downloaded the appropriate certs from the issuer, though I can't be certain they were the correct ones or that I installed their hashes correctly. Â How should I keep this updated in the future?
Normally, you don't have to update the bundle regularly, but if you really wanted to, you could set up a cron job to download that file once a month or something. It doesn't change that frequently.
Package managers like apt-get or yum will download pre-compiled packages that might still contain older components. So a package manager will always sacrifice the latest versions of things for ease of use.
If you do set up a cron job to download the file, don't download directly over top of the old file. Download it to a temporary file first and do some sanity checks (make sure the file hasn't drastically changed size, like doubled in size, or shrunk to a third, etc...) before swapping them out.
I wouldn't even bother updating the CA bundle automatically unless you have some situation where cURL is going to consistently encounter new domains and certificates. Really, the CA bundle is there to help YOU authenticate remote sources' certificates, so it is up to you to determine if you really need the latest bundle or not.
I know Entrust and Verisign both had some updates in the past year or two, so it's not a shock that the default CA bundle wouldn't have the latest updates that would validate a chain for a recently-issued certificate.
Package managers like apt-get or yum will download pre-compiled packages that might still contain older components. So a package manager will always sacrifice the latest versions of things for ease of use.
If you do set up a cron job to download the file, don't download directly over top of the old file. Download it to a temporary file first and do some sanity checks (make sure the file hasn't drastically changed size, like doubled in size, or shrunk to a third, etc...) before swapping them out.
I wouldn't even bother updating the CA bundle automatically unless you have some situation where cURL is going to consistently encounter new domains and certificates. Really, the CA bundle is there to help YOU authenticate remote sources' certificates, so it is up to you to determine if you really need the latest bundle or not.
I know Entrust and Verisign both had some updates in the past year or two, so it's not a shock that the default CA bundle wouldn't have the latest updates that would validate a chain for a recently-issued certificate.






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
PHP
--
Questions
--
Followers
Top Experts
PHP is a widely-used server-side scripting language especially suited for web development, powering tens of millions of sites from Facebook to personal WordPress blogs. PHP is often paired with the MySQL relational database, but includes support for most other mainstream databases. By utilizing different Server APIs, PHP can work on many different web servers as a server-side scripting language.