SSL peer certificate or SSH remote key was not OK - php

I'm testing an API that uses curl_exec php function and a CA certificate but something is going wrong and I'm a little lost.
I have configured SSL on my apache VirtualHost and looks ok ( opening https:://[myVHost]... works ).
However the API curl call give me back this message:
SSL peer certificate or SSH remote key was not OK
I'm not very experienced with SSL so I have few ideas about the cause of that.
UPDATE:
This is the code I'm using in my cURL request, I have commented 2 lines and changes their value (look at 'TODO' line ) and in this way it is working, however this is just a work arround ...
$opts[CURLOPT_URL] = $url;
$opts[CURLOPT_RETURNTRANSFER] = true;
$opts[CURLOPT_CONNECTTIMEOUT] = 50;
$opts[CURLOPT_TIMEOUT] = 100;
$headers = array(
'Accept: application/json',
"User-Agent: APIXXX-PHP-Client");
$opts[CURLOPT_HTTPHEADER] = $headers;
$opts[CURLOPT_USERPWD] = $env->getApiKey() . ':';
if (certificatePresent()) {
// $opts[CURLOPT_SSL_VERIFYPEER] = true;
// $opts[CURLOPT_SSL_VERIFYHOST] = 2;
// TODO: SET IT BACK
$opts[CURLOPT_SSL_VERIFYPEER] = 0;
$opts[CURLOPT_SSL_VERIFYHOST] = 0;
$opts[CURLOPT_CAINFO] = $path
}
curl_setopt_array($curl, $opts);
$response = curl_exec($curl);

You are probably using self-signed SSL certifiacate, which will not pass when the CURLOPT_SSL_VERIFYPEER options is set.
There are two solutions:
Set up valid SSL certificate.
Disable SSL verification in Curl. (add --insecure option)
If you disable verification, you can't be sure if you are really communicating with your host.
So it depends on level of security you need.

Beside CURLOPT_SSL_VERIFYPEER there are two other settings which might be changed to false/0:
CURLOPT_SSL_VERIFYHOST
CURLOPT_SSL_VERIFYSTATUS
Beware that you should fix your SSL certificates & settings instead of disable security!

Although I am answering an old post, I think it will help the new viewers-
You can check the problem by adding
$opts[CURLOPT_VERBOSE] = 1
For self signed certificate your client may connect with the server using IP address, because the host name is not available in DNS cache. In that case the COMMON NAME(CN) of your server certificate needs to match with the Server IP (put IP address as common name when generating the server certificate). When you do it correctly, you can see this message:
common name: 192.168.0.1 (matched)
Here 192.168.0.1 is an example.

You're right to want to enable SSL_VERIFYPEER if you are worried about man-in-the-middle attacks.
Is your $path set to point to the certificate (or certificate bundle) provided by the API owner? Is that certificate readable by the web server user? If so, have you verified that the certificate(s) is the same as when you visit the https address manually in a browser and inspect the certificate?
If you can't get it to work, and the API you are connecting to has a SSL certificate that works in your normal browser without warnings, you should be able to set $path to your CA root bundle on your server.

You can build a valid SSL certificate and ensure that it is stored in the trusted folder.
Valid SSL certificate can be created by including the following command in the developer command prompt of VS2012. (This can be obtained by typing developer in the start)
The following command creates a self-signed certificate that can be used to test a web application that uses Secure Sockets Layer (SSL) on a web server whose URL is www.example.com. The OID defined by the -eku option identifies that certificate as an SSL server certificate. The certificate is stored in the my store and is available at the machine (rather than user) level. The certificate's private key is exportable, and the certificate is valid from May 10, 2010 through December 22, 2011.
Makecert -r -pe -n CN="www.example.com" -b 05/10/2010 -e 12/22/2011 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
For more on how to create the SSL certificate
Now make sure that this certificate is trusted, this can be done by typing CERTMGR in the cmd..
now the cert created is in the PERSONAL folder.. copy it and paste it to the TRUSTED PEOPLE FOLDER.
This should do the trick. Let me know if that doesn't work.

I had the same issue. I follow the instruction here: http://siteber.com/download-failed-ssl-peer-certificate-or-ssh-remote-key-was-not-ok/ and it fixed mine.
basically I went to /etc/resolv.conf
and Replace any
OpenDNS server:
208.67.222.222
208.67.220.220
With
Google’s public DNS servers:
nameserver 8.8.8.8
nameserver 8.8.4.4

This error can also occur if you update packages on a linux server that has a self-signed certificate.
Solution:
Stop your existing Apache/nginx server.
Run certbot (if you are using lets encrypt)
Restart your Apache/nginx server.
Note: If you're using Springboot, add System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,TLSv1.3"); to your application.properties file
Voila!

I spent almost all day for this error, and problem was in using ipv6, and called api server does not support ipv6.
Solution:
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_VERSION_IPV4);

Related

curl error 60 while downloading https://www.phpmyadmin.net/packages.json: SSL certificate problem: unable to get local issuer certificate [duplicate]

I'm running PHP Version 5.6.3 as part of XAMPP on Windows 7.
When I try to use the Mandrill API, I'm getting the following error:
Uncaught exception 'Mandrill_HttpError' with message 'API call to messages/send-template failed: SSL certificate problem: unable to get local issuer certificate'
I already tried everything I read on StackOverflow, including adding the following to the php.ini file:
curl.cainfo = "C:\xampp\php\cacert.pem"
And ofcourse downloaded to that location the cacert.pem file from http://curl.haxx.se/docs/caextract.html
but after all that, restarted XAMPP and Apache server but still getting the same error.
I really don't know what else to try.
Can anyone advise on what else can I try?
Finally got this to work!
Download the certificate bundle.
Put it somewhere. In my case, that was c:\wamp\ directory (if you are using Wamp 64 bit then it's c:\wamp64\).
Enable mod_ssl in Apache and php_openssl.dll in php.ini (uncomment them by removing ; at the beginning). But be careful, my problem was that I had two php.ini files and I need to do this in both of them. One is the one you get from your WAMP taskbar icon, and another one is, in my case, in C:\wamp\bin\php\php5.5.12\
Add these lines to your cert in both php.ini files:
curl.cainfo="C:/wamp/cacert.pem"
openssl.cafile="C:/wamp/cacert.pem"
Restart Wamp services.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I had the same problem in Mandrill.php file after line number 65 where it says $this->ch = curl_init();
Add following two lines:
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
This solved my problem and also sent email using localhost but I suggest to NOT use it on live version live. On your live server the code should work without this code.
Thanks #Mladen Janjetovic,
Your suggestion worked for me in mac with ampps installed.
Copied: http://curl.haxx.se/ca/cacert.pem
To: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem
And updated php.ini with that path and restarted Apache:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
And applied same setting in windows AMPPS installation and it worked perfectly in it too.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"
:
Same for wamp.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
If you are looking for generating new SSL certificate using SAN for localhost, steps on this post worked for me on Centos 7 / Vagrant / Chrome Browser.
When you view the http://curl.haxx.se/docs/caextract.html page, you will notice in big letters a section called:
RSA-1024 removed
Read it, then download the version of the certificates that includes the 'RSA-1024' certificates.
https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt
Those will work with Mandrill.
Disabling SSL is a bad idea.
The above steps, though helpful, didnt work for me on Windows 8. I don't know the co-relation, but the below steps worked. Basically a change in the cacert.pem file. Hope this helps someone.
Download cacert.pem file from here:
http://curl.haxx.se/docs/caextract.html
Save the file in your PHP installation folder. (eg: If using xampp – save it in c:\Installation_Dir\xampp\php\cacert.pem).
Open your php.ini file and add these lines:
curl.cainfo=”C:\Installation_Dir\xampp\php\cacert.pem”
openssl.cafile=”C:\Installation_Dir\xampp\php\cacert.pem”
Restart your Apache server and that should fix it (Simply stop and start the
services as needed).
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I found new Solution without any required certification to call curl only add two line code.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
If you don't have access to php.ini, adding this code (after your $ch = curl_init(); line) works for me:
$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);
Then, you will just need to download ca-bundle.crt and save it to location you specified in $certificate_location.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I tried this it works
open
vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php
and change this
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
$conf[CURLOPT_SSL_VERIFYPEER] = true;
to this
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
elaborating on the above answers for server deployment.
$hostname = gethostname();
if($hostname=="mydevpc")
{
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
should do the trick for development environment without compromising the server when deployed.
I was facing a problem like this in my local system but not in the live server. I also mentioned another solution on this page its before, but that was not working in localhost.so find a new solution of this, that is working in the localhost-WAMP Server.
cURL Error #:SSL certificate problem: unable to get local issuer
certificate
sometimes system could not find your cacert.pem in your drive. so you can define this in your code where you are going to use CURL
Note that i am fulfilling all conditions for this like OPEN-SSL library active and other things.
check this code of CURL.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL =>$url,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER=> true,
));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);
but this solution may not work in live server. because of absolute path of cacert.pem
On Amazon Linux (CentOS / Red Hat etc) I did the following to fix this issue. First copy the cacert.pem downloaded from http://curl.haxx.se/ca/cacert.pem and put it in the /etc/pki/ca-trust/source/anchors/ directory. Then run the update-ca-trust command.
Here is a one liner taken from https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat
curl https://curl.se/ca/cacert.pem -o /etc/pki/ca-trust/source/anchors/curl-cacert-updated.pem && update-ca-trust
However since curl was broken I actually used this command to download the cacert.pem file.
wget --no-check-certificate http://curl.haxx.se/ca/cacert.pem
After running the update-ca-trust command you can restart the web server service httpd restart for apache or service nginx restart for nginx.
I have Very Simple Solution of this problem. You can do this without any certificate file.
Note that this solution is valid for local system not client server and Production server.
Go on Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src
open Client.php
find $defaults Array . that look like this way ..
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
Now main Job is to change value of verify key ..
'verify' => false,
So After this it will not check SSL Certificate for CURL Request... This Solution is work for me. I find this solution after many research ...
I had the same issue during building my app in AppVeyor.
Download https://curl.haxx.se/ca/cacert.pem to c:\php
Enable openssl echo extension=php_openssl.dll >> c:\php\php.ini
Locate certificateecho curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini
I have a proper solution of this problem, lets try and understand the root cause of this issue. This issue comes when remote servers ssl cannot be verified using root certificates in your system's certificate store or remote ssl is not installed along with chain certificates. If you have a linux system with root ssh access, then in this case you can try updating your certificate store with below command:
update-ca-certificates
If still, it doesn't work then you need to add root and interim certificate of remote server in your cert store. You can download root and intermediate certs and add them in /usr/local/share/ca-certificates directory and then run command update-ca-certificates. This should do the trick. Similarly for windows you can search how to add root and intermediate cert.
The other way you can solve this problem is by asking remote server team to add ssl certificate as a bundle of domain root cert, intermediate cert and root cert.
Another reason this error can occur is if a CA bundle has been removed from your system (and is no longer available in ca-certificates).
This is currently the situation with the GeoTrust Global CA which (among other things) is used to sign Apple's certificate for APNS used for Push Notifications.
Additional details can be found on the bug report here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596
You can manually add the GeoTrust Global CA certificate on your machine as suggested by Carlos Alberto Lopez Perez:
wget --no-check-certificate -c https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem \
&& mkdir /usr/local/share/ca-certificates/extra \
&& mv GeoTrust_Global_CA.pem /usr/local/share/ca-certificates/extra/GeoTrust_Global_CA.crt \
&& update-ca-certificates
If none of the solutions above are working for you try updating your XAMPP installation to a newer version.
I was running XAMPP with php 5.5.11, the same exact code didn't work, I upgraded to XAMPP with php 5.6.28 and the solutions above worked.
Additionally only updating PHP didn't work either seems like a combination of apache and php settings on that version of XAMPP.
Hope it helps someone.
I got the error like :
failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`
I am using windows machine. So I followed the below steps.
1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "
2. Then I kept the downloaded file inside "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".
3. I restarted XAMPP and cleared the cache.
4. It's done.
Hope it may help someone
simply put two more line on local to solve the issue and this worked for me fine.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
for guzzle you can try this :
$client = new Client(env('API_HOST'));
$client->setSslVerification(false);
tested on guzzle/guzzle 3.*

How to get a url link for Bitly v4 on PHP? [duplicate]

I'm running PHP Version 5.6.3 as part of XAMPP on Windows 7.
When I try to use the Mandrill API, I'm getting the following error:
Uncaught exception 'Mandrill_HttpError' with message 'API call to messages/send-template failed: SSL certificate problem: unable to get local issuer certificate'
I already tried everything I read on StackOverflow, including adding the following to the php.ini file:
curl.cainfo = "C:\xampp\php\cacert.pem"
And ofcourse downloaded to that location the cacert.pem file from http://curl.haxx.se/docs/caextract.html
but after all that, restarted XAMPP and Apache server but still getting the same error.
I really don't know what else to try.
Can anyone advise on what else can I try?
Finally got this to work!
Download the certificate bundle.
Put it somewhere. In my case, that was c:\wamp\ directory (if you are using Wamp 64 bit then it's c:\wamp64\).
Enable mod_ssl in Apache and php_openssl.dll in php.ini (uncomment them by removing ; at the beginning). But be careful, my problem was that I had two php.ini files and I need to do this in both of them. One is the one you get from your WAMP taskbar icon, and another one is, in my case, in C:\wamp\bin\php\php5.5.12\
Add these lines to your cert in both php.ini files:
curl.cainfo="C:/wamp/cacert.pem"
openssl.cafile="C:/wamp/cacert.pem"
Restart Wamp services.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I had the same problem in Mandrill.php file after line number 65 where it says $this->ch = curl_init();
Add following two lines:
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
This solved my problem and also sent email using localhost but I suggest to NOT use it on live version live. On your live server the code should work without this code.
Thanks #Mladen Janjetovic,
Your suggestion worked for me in mac with ampps installed.
Copied: http://curl.haxx.se/ca/cacert.pem
To: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem
And updated php.ini with that path and restarted Apache:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
And applied same setting in windows AMPPS installation and it worked perfectly in it too.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"
:
Same for wamp.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
If you are looking for generating new SSL certificate using SAN for localhost, steps on this post worked for me on Centos 7 / Vagrant / Chrome Browser.
When you view the http://curl.haxx.se/docs/caextract.html page, you will notice in big letters a section called:
RSA-1024 removed
Read it, then download the version of the certificates that includes the 'RSA-1024' certificates.
https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt
Those will work with Mandrill.
Disabling SSL is a bad idea.
The above steps, though helpful, didnt work for me on Windows 8. I don't know the co-relation, but the below steps worked. Basically a change in the cacert.pem file. Hope this helps someone.
Download cacert.pem file from here:
http://curl.haxx.se/docs/caextract.html
Save the file in your PHP installation folder. (eg: If using xampp – save it in c:\Installation_Dir\xampp\php\cacert.pem).
Open your php.ini file and add these lines:
curl.cainfo=”C:\Installation_Dir\xampp\php\cacert.pem”
openssl.cafile=”C:\Installation_Dir\xampp\php\cacert.pem”
Restart your Apache server and that should fix it (Simply stop and start the
services as needed).
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I found new Solution without any required certification to call curl only add two line code.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
If you don't have access to php.ini, adding this code (after your $ch = curl_init(); line) works for me:
$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);
Then, you will just need to download ca-bundle.crt and save it to location you specified in $certificate_location.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I tried this it works
open
vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php
and change this
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
$conf[CURLOPT_SSL_VERIFYPEER] = true;
to this
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
elaborating on the above answers for server deployment.
$hostname = gethostname();
if($hostname=="mydevpc")
{
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
should do the trick for development environment without compromising the server when deployed.
I was facing a problem like this in my local system but not in the live server. I also mentioned another solution on this page its before, but that was not working in localhost.so find a new solution of this, that is working in the localhost-WAMP Server.
cURL Error #:SSL certificate problem: unable to get local issuer
certificate
sometimes system could not find your cacert.pem in your drive. so you can define this in your code where you are going to use CURL
Note that i am fulfilling all conditions for this like OPEN-SSL library active and other things.
check this code of CURL.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL =>$url,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER=> true,
));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);
but this solution may not work in live server. because of absolute path of cacert.pem
On Amazon Linux (CentOS / Red Hat etc) I did the following to fix this issue. First copy the cacert.pem downloaded from http://curl.haxx.se/ca/cacert.pem and put it in the /etc/pki/ca-trust/source/anchors/ directory. Then run the update-ca-trust command.
Here is a one liner taken from https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat
curl https://curl.se/ca/cacert.pem -o /etc/pki/ca-trust/source/anchors/curl-cacert-updated.pem && update-ca-trust
However since curl was broken I actually used this command to download the cacert.pem file.
wget --no-check-certificate http://curl.haxx.se/ca/cacert.pem
After running the update-ca-trust command you can restart the web server service httpd restart for apache or service nginx restart for nginx.
I have Very Simple Solution of this problem. You can do this without any certificate file.
Note that this solution is valid for local system not client server and Production server.
Go on Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src
open Client.php
find $defaults Array . that look like this way ..
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
Now main Job is to change value of verify key ..
'verify' => false,
So After this it will not check SSL Certificate for CURL Request... This Solution is work for me. I find this solution after many research ...
I had the same issue during building my app in AppVeyor.
Download https://curl.haxx.se/ca/cacert.pem to c:\php
Enable openssl echo extension=php_openssl.dll >> c:\php\php.ini
Locate certificateecho curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini
I have a proper solution of this problem, lets try and understand the root cause of this issue. This issue comes when remote servers ssl cannot be verified using root certificates in your system's certificate store or remote ssl is not installed along with chain certificates. If you have a linux system with root ssh access, then in this case you can try updating your certificate store with below command:
update-ca-certificates
If still, it doesn't work then you need to add root and interim certificate of remote server in your cert store. You can download root and intermediate certs and add them in /usr/local/share/ca-certificates directory and then run command update-ca-certificates. This should do the trick. Similarly for windows you can search how to add root and intermediate cert.
The other way you can solve this problem is by asking remote server team to add ssl certificate as a bundle of domain root cert, intermediate cert and root cert.
Another reason this error can occur is if a CA bundle has been removed from your system (and is no longer available in ca-certificates).
This is currently the situation with the GeoTrust Global CA which (among other things) is used to sign Apple's certificate for APNS used for Push Notifications.
Additional details can be found on the bug report here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596
You can manually add the GeoTrust Global CA certificate on your machine as suggested by Carlos Alberto Lopez Perez:
wget --no-check-certificate -c https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem \
&& mkdir /usr/local/share/ca-certificates/extra \
&& mv GeoTrust_Global_CA.pem /usr/local/share/ca-certificates/extra/GeoTrust_Global_CA.crt \
&& update-ca-certificates
If none of the solutions above are working for you try updating your XAMPP installation to a newer version.
I was running XAMPP with php 5.5.11, the same exact code didn't work, I upgraded to XAMPP with php 5.6.28 and the solutions above worked.
Additionally only updating PHP didn't work either seems like a combination of apache and php settings on that version of XAMPP.
Hope it helps someone.
I got the error like :
failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`
I am using windows machine. So I followed the below steps.
1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "
2. Then I kept the downloaded file inside "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".
3. I restarted XAMPP and cleared the cache.
4. It's done.
Hope it may help someone
simply put two more line on local to solve the issue and this worked for me fine.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
for guzzle you can try this :
$client = new Client(env('API_HOST'));
$client->setSslVerification(false);
tested on guzzle/guzzle 3.*

PHP - SSL certificate error: unable to get local issuer certificate

I'm running PHP Version 5.6.3 as part of XAMPP on Windows 7.
When I try to use the Mandrill API, I'm getting the following error:
Uncaught exception 'Mandrill_HttpError' with message 'API call to messages/send-template failed: SSL certificate problem: unable to get local issuer certificate'
I already tried everything I read on StackOverflow, including adding the following to the php.ini file:
curl.cainfo = "C:\xampp\php\cacert.pem"
And ofcourse downloaded to that location the cacert.pem file from http://curl.haxx.se/docs/caextract.html
but after all that, restarted XAMPP and Apache server but still getting the same error.
I really don't know what else to try.
Can anyone advise on what else can I try?
Finally got this to work!
Download the certificate bundle.
Put it somewhere. In my case, that was c:\wamp\ directory (if you are using Wamp 64 bit then it's c:\wamp64\).
Enable mod_ssl in Apache and php_openssl.dll in php.ini (uncomment them by removing ; at the beginning). But be careful, my problem was that I had two php.ini files and I need to do this in both of them. One is the one you get from your WAMP taskbar icon, and another one is, in my case, in C:\wamp\bin\php\php5.5.12\
Add these lines to your cert in both php.ini files:
curl.cainfo="C:/wamp/cacert.pem"
openssl.cafile="C:/wamp/cacert.pem"
Restart Wamp services.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I had the same problem in Mandrill.php file after line number 65 where it says $this->ch = curl_init();
Add following two lines:
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
This solved my problem and also sent email using localhost but I suggest to NOT use it on live version live. On your live server the code should work without this code.
Thanks #Mladen Janjetovic,
Your suggestion worked for me in mac with ampps installed.
Copied: http://curl.haxx.se/ca/cacert.pem
To: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem
And updated php.ini with that path and restarted Apache:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
And applied same setting in windows AMPPS installation and it worked perfectly in it too.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"
:
Same for wamp.
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
If you are looking for generating new SSL certificate using SAN for localhost, steps on this post worked for me on Centos 7 / Vagrant / Chrome Browser.
When you view the http://curl.haxx.se/docs/caextract.html page, you will notice in big letters a section called:
RSA-1024 removed
Read it, then download the version of the certificates that includes the 'RSA-1024' certificates.
https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt
Those will work with Mandrill.
Disabling SSL is a bad idea.
The above steps, though helpful, didnt work for me on Windows 8. I don't know the co-relation, but the below steps worked. Basically a change in the cacert.pem file. Hope this helps someone.
Download cacert.pem file from here:
http://curl.haxx.se/docs/caextract.html
Save the file in your PHP installation folder. (eg: If using xampp – save it in c:\Installation_Dir\xampp\php\cacert.pem).
Open your php.ini file and add these lines:
curl.cainfo=”C:\Installation_Dir\xampp\php\cacert.pem”
openssl.cafile=”C:\Installation_Dir\xampp\php\cacert.pem”
Restart your Apache server and that should fix it (Simply stop and start the
services as needed).
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I found new Solution without any required certification to call curl only add two line code.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
If you don't have access to php.ini, adding this code (after your $ch = curl_init(); line) works for me:
$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);
Then, you will just need to download ca-bundle.crt and save it to location you specified in $certificate_location.
Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
I tried this it works
open
vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php
and change this
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
$conf[CURLOPT_SSL_VERIFYPEER] = true;
to this
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;
Note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.
Be sure you fully understand the security issues before using this as a solution.
elaborating on the above answers for server deployment.
$hostname = gethostname();
if($hostname=="mydevpc")
{
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
should do the trick for development environment without compromising the server when deployed.
I was facing a problem like this in my local system but not in the live server. I also mentioned another solution on this page its before, but that was not working in localhost.so find a new solution of this, that is working in the localhost-WAMP Server.
cURL Error #:SSL certificate problem: unable to get local issuer
certificate
sometimes system could not find your cacert.pem in your drive. so you can define this in your code where you are going to use CURL
Note that i am fulfilling all conditions for this like OPEN-SSL library active and other things.
check this code of CURL.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL =>$url,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER=> true,
));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);
but this solution may not work in live server. because of absolute path of cacert.pem
On Amazon Linux (CentOS / Red Hat etc) I did the following to fix this issue. First copy the cacert.pem downloaded from http://curl.haxx.se/ca/cacert.pem and put it in the /etc/pki/ca-trust/source/anchors/ directory. Then run the update-ca-trust command.
Here is a one liner taken from https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat
curl https://curl.se/ca/cacert.pem -o /etc/pki/ca-trust/source/anchors/curl-cacert-updated.pem && update-ca-trust
However since curl was broken I actually used this command to download the cacert.pem file.
wget --no-check-certificate http://curl.haxx.se/ca/cacert.pem
After running the update-ca-trust command you can restart the web server service httpd restart for apache or service nginx restart for nginx.
I have Very Simple Solution of this problem. You can do this without any certificate file.
Note that this solution is valid for local system not client server and Production server.
Go on Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src
open Client.php
find $defaults Array . that look like this way ..
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
Now main Job is to change value of verify key ..
'verify' => false,
So After this it will not check SSL Certificate for CURL Request... This Solution is work for me. I find this solution after many research ...
I had the same issue during building my app in AppVeyor.
Download https://curl.haxx.se/ca/cacert.pem to c:\php
Enable openssl echo extension=php_openssl.dll >> c:\php\php.ini
Locate certificateecho curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini
I have a proper solution of this problem, lets try and understand the root cause of this issue. This issue comes when remote servers ssl cannot be verified using root certificates in your system's certificate store or remote ssl is not installed along with chain certificates. If you have a linux system with root ssh access, then in this case you can try updating your certificate store with below command:
update-ca-certificates
If still, it doesn't work then you need to add root and interim certificate of remote server in your cert store. You can download root and intermediate certs and add them in /usr/local/share/ca-certificates directory and then run command update-ca-certificates. This should do the trick. Similarly for windows you can search how to add root and intermediate cert.
The other way you can solve this problem is by asking remote server team to add ssl certificate as a bundle of domain root cert, intermediate cert and root cert.
Another reason this error can occur is if a CA bundle has been removed from your system (and is no longer available in ca-certificates).
This is currently the situation with the GeoTrust Global CA which (among other things) is used to sign Apple's certificate for APNS used for Push Notifications.
Additional details can be found on the bug report here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596
You can manually add the GeoTrust Global CA certificate on your machine as suggested by Carlos Alberto Lopez Perez:
wget --no-check-certificate -c https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem \
&& mkdir /usr/local/share/ca-certificates/extra \
&& mv GeoTrust_Global_CA.pem /usr/local/share/ca-certificates/extra/GeoTrust_Global_CA.crt \
&& update-ca-certificates
If none of the solutions above are working for you try updating your XAMPP installation to a newer version.
I was running XAMPP with php 5.5.11, the same exact code didn't work, I upgraded to XAMPP with php 5.6.28 and the solutions above worked.
Additionally only updating PHP didn't work either seems like a combination of apache and php settings on that version of XAMPP.
Hope it helps someone.
I got the error like :
failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`
I am using windows machine. So I followed the below steps.
1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "
2. Then I kept the downloaded file inside "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".
3. I restarted XAMPP and cleared the cache.
4. It's done.
Hope it may help someone
simply put two more line on local to solve the issue and this worked for me fine.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
for guzzle you can try this :
$client = new Client(env('API_HOST'));
$client->setSslVerification(false);
tested on guzzle/guzzle 3.*

curl SSL certificate error

I'm trying to install Vaprobash via CURL but I get this message everytime I try to download something through CURL. I'm using a Mac.
curl -L http://bit.ly/vaprobash > Vagrantfile
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
Append option in curl call:
-k/--insecure
The curl will be not trying to verify SSL cert.
The link is redirecting to a secure HTTP (SSL) server, and curl doesn't have access to the proper chain of trusted certificates to confirm that the site says it is who it is.
If you're sure the site is legitimate, and this is a once-off effort, you can use the --insecure option (it will ignore any certificate errors). Opening the link in a browser directs to GitHub with no issues, and curl fetches it fine on my Ubuntu 12.04 box.
It's likely a missing certificate in your SSL installation. Run with the -v option to get a detailed output if you need to confirm this.

Source of PEM files for web service access

I should have paid more attention to my classes that covered security. I'm quite confused about something. To start, here's the background of what I'm trying to accomplish.
I have a web service that I need to access. The web service is set up as HTTPS. The traffic between client and server is encrypted (this doesn't have to do with authentication).
I'm interacting with the web service via cURL and PHP. I've gotten an example to work locally over HTTP and I'm fairly confident I'm on the right track with regards to cURL/PHP side of things.
When using the HTTP version of the code to access a web service over HTTPS, I am getting an error code 60 "SSL certificate problem, verify that the CA cert is OK" (error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed)
From my reading, it seems that I need a PEM file and I need to set additional cURL options such as the following:
CURLOPT_CAINFO
CURLOPT_SSLCERT
CURLOPT_SSLKEYPASSWD
My question is how do I know where to get the PEM file or whether I can simply make it? This is probably going to be an obvious answer as I'm sure I'm missing something but I figure I just need to ask and get the background I'm missing.
Amendment: The web service is using a certificate signed by VeriSign. So it's not a self signed certificate. Also, the web service is owned and operated by an external organization.
Thanks.
Despite googling around prior to asking this, it seems I've stumbled upon the answer after a bit of back-n-fourth with 'thatidiotguy' (his user name, not my name for him. ;-) ).
cURL, out of the box, does not trust any CA (VeriSign or otherwise). This needs to be setup on your server. To "solve" the problem, you have two options. You can bypass the verification with the following command:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Note that this is not optimal with regards to security. Any certificate, signed by a CA or not, will be accepted as trusted.
The proper fix involves getting the original certificate (in my case this means the web service) and "exporting" the certificate as a X.509 Certificate (PEM). The certificate then needs to appropriately moved to the server and the following configurations set:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //Check that the common name exists and that it matches the host name of the server
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/path/to/cert/my-exported.crt"); //PEM file
Source: http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
The answer is very simple. You need to download a certificate bundle, one that also ships with regular browsers.
Luckily that work is already done for you here:
http://curl.haxx.se/docs/caextract.html
Once downloaded you specify the path to this file with CURLOPT_CAINFO.

Categories