Link to home
Start Free TrialLog in
Avatar of amitnepal
amitnepalFlag for United States of America

asked on

php curl issue with ssl

Hello,
  I am running the following in two servers, one of them works fine, however on the other server I get an error :

"Peer Certificate cannot be authenticated with given CA certificates"

However, if I run the command :
curl -v 'https://www.google.com' 

Open in new window


 , it will work fine. I am only having problem when i call that through the following php script :

<?php

$c = curl_init('https://www.google.com);
$response = curl_exec($c);
if($response)
	echo  response;
else
	echo curl_error($c);
curl_close($c)

?>

Open in new window


Any Ideas ?

Thanks
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Punctuation errors and it seems to need the curl_setopt() to work.

<?php

$c = curl_init("https://www.google.com");
// set url
curl_setopt($c, CURLOPT_URL, "www.google.com");
$response = curl_exec($c);
if($response)
	echo  $response;
else
	echo curl_error($c);
curl_close($c)

?>

Open in new window

Avatar of amitnepal

ASKER

Well,
  I have that ok, that is not the problem , I can load the non https sites fine.

Thank you
Try this, info from this page.  http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
<?php

$c = curl_init();
// set url
curl_setopt($c, CURLOPT_URL, "https://www.google.com");
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($c);
if($response)
	echo  $response;
else
	echo curl_error($c);
curl_close($c)

?>

Open in new window

Thank you Dave, I have already tried setting verifypeer to false, that works, however I cannot do that, because i have to verify peer.  It has something to do with curl not using the default ca certificates. I am not seeming to figure out where that setting is.

Thank you
That page I linked showed how to do that.
In your link   "The proper fix involves setting the CURLOPT_CAINFO parameter. This is used to point towards a CA certificate that cURL should trust." , however, I am looking to do that without passing CAINFO in the curl options. As I mentioned in my question, the curl in other machine works with the same code without passing CAINFO. So actually I am trying to fix the root cause, rather than fixing it for that particular call.


Thanks
Also,
  I have done a lot of google search and probably I have gone through 200 results already with no avail.

Thanks
What operating systems are the two machines?  And which version of curl?  On my XP machine, your command line above says that "(1) Protocol 'https not supported or disabled in libcurl."  If I use double quotes, it tries to connect and says: "(60) SSL certificate problem..."  I had a similar problem with single and double quotes in the PHP code.
User generated image
Both are in unix machines (Centos)

Curl Version : curl 7.15.5

Protocols: tftp ftp telnet dict ldap http file https ftps
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

If i run :  curl -v "https://www.google.com" , it works fine, which I had already verified, that's why i mentioned php curl issue in the title, because this problem is only when run through php. If I run direct from command line , it works.

Thanks
That explains one thing.  cURL up to version 7.18 had certificates built-in which PHP does not.  http://curl.haxx.se/docs/sslcerts.html  I just downloaded curl 7.29 (for Windows) and it has a program to get or generate a cert file that curl can use at the command line.  I used that and it works except that it names it wrong.  The docs give the correct name for curl to find it and use it.  So that command now works on my XP computers.
I actually downloaded the certificate bundle too :(

http://curl.haxx.se/docs/caextract.html  ( as per this document )

still nothing..
To make things more interesting, this file works on my Ubuntu 8.04 system and does Not work on this Windows XP computer.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>PHP curl test</title>
</head>
<body>

<?php
        // create curl resource
        $ch2 = curl_init();

        // set url
        curl_setopt($ch2, CURLOPT_URL, "https://www.google.com");

        //return the transfer as a string
        curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);

        // $output contains the output string
        $output = curl_exec($ch2);

        // close curl resource to free up system resources
        curl_close($ch2);
				echo $output;      
?>

</body>
</html>

Open in new window


And even more interesting, PHP on Ubuntu uses libcurl/7.18 (with the certs) and PHP on XP uses libcurl/7.21 which is without the certs.  I'm going to check some other computers with newer versions of PHP.  These are PHP 5.2.4 and PHP 5.2.17.
Mine is php 5.4.12
By the way, when you mean does not work, do you get the same error as I do ?

"Peer Certificate cannot be authenticated with given CA certificates"
You might have to do this , to get the error :

echo curl_error($c);

Open in new window

No, I'm getting...

SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

My other machines have PHP 5.3.18 and PHP 5.4.8.

I have concluded that the problem is that libcurl up to 7.18 contains a old set of certs according to the documentation and it is not included in the versions after that.  All the PHP versions I have that do not work have either curl version 7.21 or 7.24 which do not carry their own certs.
This page http://php.net/manual/en/book.curl.php talks about your error message in the second comment and what to do about it.  I don't understand it but maybe you will.
And this page http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/ enabled me to use curl in PHP to get "https://www.google.com" without turning off the Peer verify.

And this page http://stackoverflow.com/questions/521418/reading-ssl-page-with-curl-php showed using a line in 'php.ini' to enable the certificates.  I tried it on another computer with both PHP 5.3 and PHP 5.4 and it worked.

curl.cainfo=C:/path/to/cacert.pem  Make sure and download 'cacert.pem'.
Dave,
  I appreciate you taking time in this. I actually tried using curl.cainfo in the php.ini  , but that didn't help either in centos. I restarted apache to apply changes in php.ini , but no help either. I will be out for today. I will check back into it tomorrow and let you know what I find. The other machine that works for me is in its default setup and still works.

Thank you
Check the PHP_curl version (not the standalone version) on that other machine.  If it is 7.18 or below, then the certs are included.  If it is higher, they are not and someone has added them somewhere.

CentOS 5.0 contained PHP 5.1.6 which would have included a version of PHP_curl less than 7.18 which included the certs.   CentOS 5.6 moved to PHP 5.3.3 which would have inluded a later version of PHP_curl which would not have included the certs.  It all revolves around the version of curl/PHP_curl that you have.  After 7.18, you have to add the certs because they are not included.  That includes the standalone command line versions too by the way.

http://wiki.centos.org/FAQ/CentOS5#head-8b85501ca7f023bc0eeb0fef98143e10fb6adefc
Dave,
  I have been running strace on the two machines and I can see that in the machine that works has php 5.2 and it is reading the ca-bundle.crt , however on the other machine the php is 5.4 and curl is not reading ca-bundle.crt. Any thoughts ?

Thanks
Dave,
   your above post makes sense , because I can see that the two machines have different versions of php curl , however, where and how do I add the certificates to the new curl ?

Thanks
I tried this :

curl_setopt($c, CURLOPT_CAINFO, "/etc/php.d/cacert.pem");

also , put ca info in php.ini doesnot work . I still get the same :

Peer certificate cannot be authenticated with given CA certificates
ASKER CERTIFIED SOLUTION
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey,
  Actually I got the issue fixed. It was nothing to do with all these settings. The version of libcurl I had installed had a bug with nss database. So I Installed another version and all is well.

Thank you very much for your efforts.

Thanks
Amit
Well yes, recompiling libcurl and installing another version probably would do the same thing. Changing the version fixed my problem.

Thanks
You're welcome, thanks for the points.