PHP cURL and SSL certificate error - php

I have this error when using CURLOPT_SSL_VERIFYHOST:
Curl error: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
What I tried:
1 - turning off VERIFYHOST is not an option, I need this to login to https page
2 - downloaded certificate and I use it like this:
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_CAINFO, getcwd() . '/certificate.pl.crt');
And I still get the same error.
3 - I turned on ssl_module in Apache extensions (I use WAMP)
4 - I turned on php_openssl in PHP extensions
What else should I do? From phpinfo(); I know that I have:
mod_ssl/2.2.22
OpenSSL/0.9.8u
And it still doesn't work. What else should I do :( ?

had to edit this as I missed some comments before.
If you don't try to import your certificate and switch peer validation off, your transport should still be SSL secured if I'm not mistaking, so if the goal is to get it over ssl , then I wouldn't bother messing with the import of certificates. Of course if you do want some more peace of mind it's a different thing.

Related

Certificate Pinning with PHP cURL

I see there is tons of post in SO, about error:
SSL certificate problem: unable to get local issuer certificate
And which is the one I am getting.
All of their answer is just saying download root certificates from:
https://curl.haxx.se/ca/cacert.pem
And setting into the CURLOPT_CAINFO or setting php.ini's curl.cainfo.
But what this does is actually just telling cURL to trust the list of root CA and their trusted CA.
From my understanding, Certificate Pinning should ignore all these root CA and just trust the single certificate of a particular provider.
What is the correct way to fix this error?
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_CAINFO, '/etc/httpd/static.gc.apple.com.pem');
curl_setopt($ch, CURLOPT_CAPATH, '/etc/httpd/');
//curl_setopt($ch, CURLOPT_PINNEDPUBLICKEY, "sha256//TeyzGG/8dvpuksAeSCb3tsvLEHbY6w9q63tXhOIf0Tg=");
$sslCertificate = curl_exec($ch);
I know for libcurl itself, it has a option "CURLOPT_PINNEDPUBLICKEY" which do absolutely what I need, but currently PHP still not supporting it... (it doesn't have such constant in PHP and I have no idea what is the actual value of the constant)
Basically the issue is because the PHP itself installed with yum from Remi didn't compiled with the curl and openssl that support it.
So we have to update curl, openssl, compile PHP from source and it worked.

cURL error 60: Peer certificate cannot be authenticated with given CA certificates [duplicate]

For some reason I am unable to use CURL with HTTPS. Everything was working fine untill I ran upgrade of curl libraries. Now I am experiencing this response when trying to perform CURL requests: Problem with the SSL CA cert (path? access rights?)
Following suggestions posted here on related issues I have tried to do the following:
Disable verification for host and peer
curl_setopt($cHandler, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($cHandler, CURLOPT_SSL_VERIFYPEER, true);
Enable CURLOPT_SSL_VERIFYPEER and point to cacert.pem downloaded from http://curl.haxx.se/docs/caextract.html
curl_setopt($cHandler, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($cHandler, CURLOPT_CAINFO, getcwd() . "/positiveSSL.ca-bundle");
I also tried to do the same thing with positiveSSL.ca-bundle which was provided as bundle CA certificate for the server I am trying to connect to.
Edit php ini settings with curl.cainfo=cacert.pem (file in the same directory and accessible by apache)
Rename /etc/pki/nssdb to /etc/pki/nssdb.old
Unfortunatelly none of the above are able to solve my problem and I constantly get Problem with the SSL CA cert (path? access rights?) message.
And I don't need this verification in the first place (I am aware of security issues).
Does anybody have any other suggestions?
UPDATE
After updating to the latest libraries and restart of the whole box, not just apache which I was doing it all seems to be working now again!!!
According to documentation: to verify host or peer certificate you need to specify alternate certificates with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.
Also look at CURLOPT_SSL_VERIFYHOST:
1 to check the existence of a common name in the SSL peer certificate.
2 to check the existence of a common name and also verify that it matches the hostname provided.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Return data inplace of echoing on screen
curl_setopt($ch, CURLOPT_URL, $strURL);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // Skip SSL Verification
$rsData = curl_exec($ch);
curl_close($ch);
return $rsData;
We had the same problem on a CentOS7 machine. Disabling the VERIFYHOST VERIFYPEER did not solve the problem, we did not have the cURL error anymore but the response still was invalid. Doing a wget to the same link as the cURL was doing also resulted in a certificate error.
-> Our solution also was to reboot the VPS, this solved it and we were able to complete the request again.
For us this seemed to be a memory corruption problem. Rebooting the VPS reloaded the libary in the memory again and now it works. So if the above solution from #clover does not work try to reboot your machine.

Wamp & Mandrill: "error setting certificate verify locations"

I'm trying to test our Mandrill API from my localhost (on Windows). It seems like I need to configure a "local issuer certificate". So, I downloaded http://curl.haxx.se/ca/cacert.pem and saved it in my document root (c:\wamp\www). Then, in my php.ini file, I configured this: curl.cainfo = "/cacert.pem".
When I run the sample code for Mandrill, I get the following error:
A mandrill error occurred: Mandrill_HttpError - API call to
messages/send failed: error setting certificate verify locations:
CAfile: cacert.pem CApath: none
Any idea what's wrong?
I've seen others post about this with WampServer; though I cannot offer the reason or a real solution, if you're just testing on your localhost have you considered just turning off cURL's SSL verification?
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
To extend the #LeonardChallis answer if you're struggling with Google APIs on this one then adding the following to vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php and the create function will also fix it:
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = 0;

SSL decryption failed or bad record mac in NGINX Server with cacert.pem set

I am trying to connect to secure link using CURL.
I have set the following two parameters in CURL of PHP page
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt ($ch, CURLOPT_CAINFO, "/cacert.pem");
But still I am getting the below error :SSL error.
After Adding the pem file now in NGINX Server i am getting the error as below in NGINX
SSL3_GET_RECORD:decryption failed or bad record mac
The Same PEM file works on the Windows WAMP Server but its not working in NGINX Server.
Please let me know if anything else i am missing.
Basically curl used to include a list of accepted CAS, but it will not accept longer bundles ANY CA certs. So by default it will reject all SSL certificates as unverifiable.
You'll have to get your CA's cert and point curl at it. More details here
I think you are using self-signed certificate. You should add it to your CA bundle. So that, curl can trusted it.
Alternatively you can use
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
SSL3_GET_RECORD:decryption failed or bad record mac
The above error was fixed by forcing the SSL version to 3.
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
To aviod breaks in the transfer
curl_setopt ($ch, CURLOPT_TIMEOUT,0);
The above changes worked for me.

PHP CURL CURLOPT_SSL_VERIFYPEER ignored

For some reason I am unable to use CURL with HTTPS. Everything was working fine untill I ran upgrade of curl libraries. Now I am experiencing this response when trying to perform CURL requests: Problem with the SSL CA cert (path? access rights?)
Following suggestions posted here on related issues I have tried to do the following:
Disable verification for host and peer
curl_setopt($cHandler, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($cHandler, CURLOPT_SSL_VERIFYPEER, true);
Enable CURLOPT_SSL_VERIFYPEER and point to cacert.pem downloaded from http://curl.haxx.se/docs/caextract.html
curl_setopt($cHandler, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($cHandler, CURLOPT_CAINFO, getcwd() . "/positiveSSL.ca-bundle");
I also tried to do the same thing with positiveSSL.ca-bundle which was provided as bundle CA certificate for the server I am trying to connect to.
Edit php ini settings with curl.cainfo=cacert.pem (file in the same directory and accessible by apache)
Rename /etc/pki/nssdb to /etc/pki/nssdb.old
Unfortunatelly none of the above are able to solve my problem and I constantly get Problem with the SSL CA cert (path? access rights?) message.
And I don't need this verification in the first place (I am aware of security issues).
Does anybody have any other suggestions?
UPDATE
After updating to the latest libraries and restart of the whole box, not just apache which I was doing it all seems to be working now again!!!
According to documentation: to verify host or peer certificate you need to specify alternate certificates with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.
Also look at CURLOPT_SSL_VERIFYHOST:
1 to check the existence of a common name in the SSL peer certificate.
2 to check the existence of a common name and also verify that it matches the hostname provided.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Return data inplace of echoing on screen
curl_setopt($ch, CURLOPT_URL, $strURL);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // Skip SSL Verification
$rsData = curl_exec($ch);
curl_close($ch);
return $rsData;
We had the same problem on a CentOS7 machine. Disabling the VERIFYHOST VERIFYPEER did not solve the problem, we did not have the cURL error anymore but the response still was invalid. Doing a wget to the same link as the cURL was doing also resulted in a certificate error.
-> Our solution also was to reboot the VPS, this solved it and we were able to complete the request again.
For us this seemed to be a memory corruption problem. Rebooting the VPS reloaded the libary in the memory again and now it works. So if the above solution from #clover does not work try to reboot your machine.

Categories