PHP, SSL, and cURL SSL3_GET_SERVER_CERTIFICATE Errors
I recently developed a complex system for a customer that involved PHP, cURL, and a SSL connection to a third party vendor. The third party vendor would validate the security certificate of the source (the system I created) and either allow or reject access. My code looked like this:
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,'https://thirdparty.com/token.php'); //not the actual site
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,'customer_id='.$cid.'&password='.$pass);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_CAINFO,'ca-bundle.crt'); /* problem here! */
$result = curl_exec($ch);
if(empty($result)) { /* error: nothing returned */ } else { /* success! */ }
curl_close($ch);
Unfortunately I was persistently receiving the following error message:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
It turns out that the SSL bundle file I was using was old, as was the default bundle that came with the old version of cURL the shared hosting server. Essentially the third party didn't trust that the system's SSL certificate was valid. I downloaded Mozilla's bundle file, named it mozilla.pem and changed my PHP code to:
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,'https://thirdparty.com/token.php'); //not the actual site
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,'customer_id='.$cid.'&password='.$pass);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_CAINFO,'mozilla.pem'); /* fixed! */
$result = curl_exec($ch);
if(empty($result)) { /* error: nothing returned */ } else { /* success! */ }
curl_close($ch);
I share this with you because it cost me over three hours. Hopefully this will save someone time and frustration in the future.
Comments
Be Heard!
Share your thoughts without being a jerk! And wrap your code in <code> tags, f00!
Thanks for sharing. That’s going to same someone a great deal of time.
Great post. Thanks…
“Hopefully this will save someone time and frustration in the future.”
Yes, it has saved many time to me. There is, however, a point that you don’t explain in your article: where to put the Mozilla’s bundle file? I develop using WAMP, and this is the code I use:
curl_setopt($rRequest, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($rRequest, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($rRequest, CURLOPT_CAINFO, “C:\path\sub-path\wamp\www\php\mozilla.pem”);
The “CURLOPT_SSL_VERIFYHOST” option verify that the name field matches the host name of the server.
More information:
Using cURL in PHP to access HTTPS (SSL/TLS) protected sites
I still can’t get mine to work. I’m getting this problem with my Facebook app.
My code
$url ='https://somesecureurl';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/cacert.pem");
still i cant get the code to work getting error
SSL peer certificate or SSH remote key was not OK
Dude, you saved my life! ;o)
Very helpful. Thank you!
i am getting this now.
error setting certificate verify locations:
Thanks david… But I don’t understand How its working for common cert file ,that I downloaded from above link..
THANKS YOU SOOOOO MUCH.
This _did_ save me hours of time!