Related
My PHP Mailgun interface had been working for 2 years until yesterday 1/23/2018 at about 12 noon central time.
Now all calls to the Mailgun API are returning the SSL certificate problem
Exception 0 [curl] 60: SSL certificate problem: unable to get local issuer certificate [url] https://api.mailgun.net/v2/
Curl also returns the same problem at the command line when attempting to access the mailgun API.
We have downloaded and installed the latest cacert.pem file from
https://curl.haxx.se/docs/caextract.html and includeded the path to this file in the php.ini file parameter curl.cainfo = /path/to/cacert.pem and the openssl.cafile = /path/to/cacert.pem
We have restarted our application and rebooted our server but the problem is not fixed.
Is anyone else having the same problem with the PHP Mailgun API ?
Is there a way to disable the SSL certificate check through the Mailgun API ?
The SSL Certificate problem with the PHP Mailgun API was resolved by copying the latest cacert.pem file to the following directory :
..PHP\v5.6\vendor\guzzle\guzzle\src\Guzzle\Http\Resources\
Apparently the PHP MailGun API uses this directory for the certificates when calling the guzzle and curl interfaces.
Changing the PHP.ini file parameter curl.cainfo = "/path/to/cacert.pem" is not sufficient to resolve this problem.
Do we really need to install guzzle to fix this issue? I encounter same issue.
I just came to SO myself to post a resolution my team and I found on this issue as well. As we have a Laravel 4.2 website running Guzzle 4.x for Mailgun mail delivery, all emails ceased functioning as Steve said on 1/23 around Noon.
For us, we simply had to update the cacert.pem found in the /vendor/guzzlehttp directory that the package uses and it came back online.
I can confirm updating php / curl on my dead ass old production server resolved this problem.
Actually, this should be sufficent:
sudo apt-get update && sudo apt-get upgrade
I fixed this problem... you just need to change de "pem" file inside:
guzzle/guzzle/src/Guzzle/Http/Resources/
You need to get de cacert.pem here... the last version:
https://curl.haxx.se/docs/caextract.html
And after, just change in your folder.
Actually, it's not a bug; it's for security reasons. To make it work, change
$sslEnabled = true
to
$sslEnabled = false
You can read extra details at this github issue.
I am trying to send an API request using Stripe but get the error message:
cURL error 60: SSL certificate problem: unable to get local issuer certificate
This is the code I am running:
public function chargeStripe()
{
$stripe = new Stripe;
$stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));
$charge = $stripe->charges()->create([
'amount' => 2900,
'customer' => Input::get('stripeEmail'),
'currency' => 'EUR',
]);
return Redirect::route('step1');
}
I searched a lot on Google and lots of people are suggesting that I download this file: cacert.pem, put it somewhere and reference it in my php.ini. This is the part in my php.ini:
curl.cainfo = "C:\Windows\cacert.pem"
Yet, even after restarting my server several times and changing the path, I get the same error message.
I have the ssl_module enabled in Apache, and I have php_curl enabled in my php.ini.
I have also tried another fix which suggests that I add these lines to my cURL options:
curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);
Where do I add options to my cURL? Apparently not through the command line, since my CLI doesn't find the command "curl_setopt"
How to solve this problem:
download and extract cacert.pem following the instructions at https://curl.se/docs/caextract.html
save it on your filesystem somewhere (for example, XAMPP users might use C:\xampp\php\extras\ssl\cacert.pem)
in your php.ini, put this file location in the [curl] section (putting it in the [openssl] section is also a good idea):
[curl]
curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
[openssl]
openssl.cafile = "C:\xampp\php\extras\ssl\cacert.pem"
restart your webserver (e.g. Apache) and PHP FPM server if applicable
(Reference: https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate)
Attention Wamp/Wordpress/windows users. I had this issue for hours and not even the correct answer was doing it for me, because i was editing the wrong php.ini file because the question was answered to XAMPP and not for WAMP users, even though the question was for WAMP.
Here's what I did:
Download the certificate bundle.
Put it inside of C:\wamp64\bin\php\your php version\extras\ssl
Inside of C:\wamp64\bin\apache\apache(version)\modules, make sure the file mod_ssl.so is there
Inside of Apache directory C:\wamp64\bin\apache\apache2.4.27\conf, enable mod_ssl in httpd.conf
Enable php_openssl.dll in php.ini. Be aware my problem was that I had two php.ini files and I need to do this in both of them. First one can be located inside of your WAMP taskbar icon here.
And the other one is located in C:\wamp64\bin\php\php(Version)
Find the location for both of the php.ini files and find the line curl.cainfo = and give it a path like this curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"
Now save the files and restart your server and you should be good to go
If you are using PHP 5.6 with Guzzle, Guzzle has switched to using the PHP libraries autodetect for certificates rather than it's process (ref). PHP outlines the changes here.
Finding out Where PHP/Guzzle is Looking for Certificates
You can dump where PHP is looking using the following PHP command:
var_dump(openssl_get_cert_locations());
Getting a Certificate Bundle
For OS X testing, you can use homebrew to install openssl brew install openssl and then use openssl.cafile=/usr/local/etc/openssl/cert.pem in your php.ini or Zend Server settings (under OpenSSL).
A certificate bundle is also available from curl/Mozilla on the curl website: https://curl.haxx.se/docs/caextract.html
Telling PHP Where the Certificates Are
Once you have a bundle, either place it where PHP is already looking (which you found out above) or update openssl.cafile in php.ini. (Generally, /etc/php.ini or /etc/php/7.0/cli/php.ini or /etc/php/php.ini on Unix.)
Guzzle, which is used by cartalyst/stripe, will do the following to find a proper certificate archive to check a server certificate against:
Check if openssl.cafile is set in your php.ini file.
Check if curl.cainfo is set in your php.ini file.
Check if /etc/pki/tls/certs/ca-bundle.crt exists (Red Hat, CentOS, Fedora; provided by the ca-certificates package)
Check if /etc/ssl/certs/ca-certificates.crt exists (Ubuntu, Debian; provided by the ca-certificates package)
Check if /usr/local/share/certs/ca-root-nss.crt exists (FreeBSD; provided by the ca_root_nss package)
Check if /usr/local/etc/openssl/cert.pem (OS X; provided by homebrew)
Check if C:\windows\system32\curl-ca-bundle.crt exists (Windows)
Check if C:\windows\curl-ca-bundle.crt exists (Windows)
You will want to make sure that the values for the first two settings are properly defined by doing a simple test:
echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";
Alternatively, try to write the file into the locations indicated by #7 or #8.
If you're unable to change php.ini you could also point to the cacert.pem file from code like this:
$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
What i did was use var_dump(openssl_get_cert_locations()); die; in any php script, which gave me the information about defaults that my local php was using:
array (size=8)
'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
'ini_capath' => string '' (length=0)
As you can notice, i have set the ini_cafile or the ini option curl.cainfo. But in my case, curl would try to use the "default_cert_file" which did not exist.
I copied the file from https://curl.haxx.se/ca/cacert.pem into the location for "default_cert_file" (c:/openssl-1.0.1c/ssl/cert.pem) and i was able to get it to work.
This was the only solution for me.
I had this problem appear out-of-the-blue one day, when a Guzzle(5) script was attempting to connect to a host over SSL. Sure, I could disable the VERIFY option in Guzzle/Curl, but that's clearly not the correct way to go.
I tried everything listed here and in similar threads, then eventually went to terminal with openssl to test against the domain with which I was trying to connect:
openssl s_client -connect example.com:443
... and received first few lines indicating:
CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1
... while everything worked fine when trying other destinations (ie: google.com, etc)
This prompted me to contact the domain I had been trying to connect to, and indeed, they had a problem on THEIR END that had crept up. It was resolved and my script went back to working.
So... if you're pulling your hair out, give openssl a shot and see if there's anything up with the response from the location you are attempting to connect. Maybe the issue isn't so 'local' after all sometimes.
Have you tried..
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
If you would like to risk being hit by a man-in-the-middle attack, you can skip the verify.
Be sure that you open the php.ini file directly by your Window Explorer. (in my case: C:\DevPrograms\wamp64\bin\php\php5.6.25).
Don't use the shortcut to php.ini in the Wamp/Xamp icon's menu in the System Tray. This shortcut doesn't work in this case.
Then edit that php.ini :
curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem"
and
openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"
After saving php.ini you don't need to "Restart All Services" in Wamp icon or close/re-open CMD.
I found a solution that worked for me. I downgraded from the latest guzzle to version ~4.0 and it worked.
In composer.json add "guzzlehttp/guzzle": "~4.0"
Hope it helps someone
For WAMP, this is what finally worked for me.
While it is similar to others, the solutions mentioned on this page, and other locations on the web did not work. Some "minor" detail differed.
Either the location to save the PEM file mattered, but was not specified clearly enough.
Or WHICH php.ini file to be edited was incorrect. Or both.
I'm running a 2020 installation of WAMP 3.2.0 on a Windows 10 machine.
Link to get the pem file:
http://curl.haxx.se/ca/cacert.pem
Copy the entire page and save it as: cacert.pem, in the location mentioned below.
Save the PEM file in this location
<wamp install directory>\bin\php\php<version>\extras\ssl
eg saved file and path: "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
*(I had originally saved it elsewhere (and indicated the saved location in the php.ini file, but that did not work).
There might, or might not be, other locations also work. This was the recommended location - I do not know why.)
WHERE
<wamp install directory> = path to your WAMP installation.
eg: T:\wamp64\
<php version> of php that WAMP is running: (to find out, goto: WAMP icon tray -> PHP <version number>
if the version number shown is 7.3.12, then the directory would be: php7.3.12)
eg: php7.3.12
Which php.ini file to edit
To open the proper php.ini file for editing, goto: WAMP icon tray -> PHP -> php.ini.
eg: T:\wamp64\bin\apache\apache2.4.41\bin\php.ini
NOTE: it is NOT the file in the php directory!
Update:
While it looked like I was editing the file: T:\wamp64\bin\apache\apache2.4.41\bin\php.ini,
it was actually editing that file's symlink target: T:/wamp64/bin/php/php7.3.12/phpForApache.ini.
Note that if you follow the above directions, you are NOT editing a php.ini file directly. You are actually editing a phpForApache.ini file. (a post with info about symlinks)
If you read the comments at the top of some of the php.ini files in various WAMP directories, it specifically states to NOT EDIT that particular file.
Make sure that the file you do open for editing does not include this warning.
Installing the extension Link Shell Extension allowed me to see the target of the symlink in the file Properites window, via an added tab. here is an SO answer of mine with more info about this extension.
If you run various versions of php at various times, you may need to save the PEM file in each relevant php directory.
The edits to make in your php.ini file:
Paste the path to your PEM file in the following locations.
uncomment ;curl.cainfo = and paste in the path to your PEM file.
eg: curl.cainfo = "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
uncomment ;openssl.cafile= and paste in the path to your PEM file.
eg: openssl.cafile="T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
Credits:
While not an official resource, here is a link back to the YouTube video that got the last of the details straightened out for me: https://www.youtube.com/watch?v=Fn1V4yQNgLs.
All of the answers are correct ; but the most important thing is You have to find the right php.ini file.
check this command in cmd " php --ini " is not the right answer for finding the right php.ini file.
if you edit
curl.cainfo ="PATH/cacert.pem"
and check
var_dump(openssl_get_cert_locations());
then curl.cainfo should have a value. if not then that's not right php.ini file;
*I recommend you to search *.ini in wamp/bin or xxamp/bin or any server you use and change them one by one and check it. *
I spent too much time to figure out this problem for me.
I had PHP version 5.5 and I needed to upgrade to 5.6.
In versions < 5.6 Guzzle will use it's own cacert.pem file, but in higher versions of PHP it will use system's cacert.pem file.
I also downloaded file from here https://curl.haxx.se/docs/caextract.html and set it in php.ini.
Answer found in Guzzles StreamHandler.php file https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437
// PHP 5.6 or greater will find the system cert by default. When
// < 5.6, use the Guzzle bundled cacert.
For those of you who are trying to use Wordpress's application password functionality on your local machine. You need to update the wp-includes\certificates\ca-bundle.crt
Open this file in a text editor and append your server's certificate.
Open your self-signed certificate(.crt) file and
Copy all between and including
----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
Paste at the end of the wp-includes\certificates\ca-bundle.crt
I just experienced this same problem with the Laravel 4 php framework which uses the guzzlehttp/guzzle composer package. For some reason, the SSL certificate for mailgun stopped validating suddenly and I got that same "error 60" message.
If, like me, you are on a shared hosting without access to php.ini, the other solutions are not possible. In any case, Guzzle has this client initializing code that would most likely nullify the php.ini effects:
// vendor/guzzlehttp/guzzle/src/Client.php
$settings = [
'allow_redirects' => true,
'exceptions' => true,
'decode_content' => true,
'verify' => __DIR__ . '/cacert.pem'
];
Here Guzzle forces usage of its own internal cacert.pem file, which is probably now out of date, instead of using the one provided by cURL's environment. Changing this line (on Linux at least) configures Guzzle to use cURL's default SSL verification logic and fixed my problem:
Since the files in vendor are not meant to be tampered with, a better solution would be to configure the Guzzle client on usage, but this was just too difficult to do in Laravel 4.
Hope this saves someone else a couple hours of debugging...
This might be an edge case, but in my case the problem was not the client conf (I already had curl.cainfo configured in php.ini), but rather the remote server not being configured properly:
It did not send any intermediate certs in the chain. There was no error browsing the site using Chrome, but with PHP I got following error.
cURL error 60
After including the Intermediate Certs in the remote webserver configuration it worked.
You can use this site to check the SSL configuration of your server:
https://whatsmychaincert.com/
when I run 'var_dump(php_ini_loaded_file());'
I get this output on my page
'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'
and to get php to load my cert file I had to edit the php.ini in this path 'C:\Development\bin\apache\apache2.4.33\bin\php.ini'
and add openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem" where I had downloaded and place my cert file from https://curl.haxx.se/docs/caextract.html
am on windows 10, using drupal 8, wamp and php7.2.4
I'm using Centos 7 with the free version of virtualmin. With Virtualmin you can create a wordpress website. There is functionality that will automatically update your ssl certificate for you. I noticed that /etc/httpd/conf/httpd.conf did not contain an entry for SSLCertificateChainFile. Which should be set to something like /home/websitename/ssl.combined. Updating that file accordingly and restarting apache fix this problem for me. I discovered my issue trying to install a jetpack plugin for wordpress. A search on the internet led me to realize that I didn't have SSL Configured. I followed Redhat's instructions on how to install a certificate. I hope this was useful to someone.
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.
Guzzle Version 5
This default config is working good for mine. It will disable https required.
$options = [
'defaults' => ['verify' => false],
];
new GuzzleClient($options);
In other case, you want to set path of ca, change to:
['verify' => '/path/to/cacert.pem']
As you are using Windows, I think your path separator is '\' (and '/' on Linux).
Try using the constant DIRECTORY_SEPARATOR. Your code will be more portable.
Try:
curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');
EDIT: and write the full path. I had some issues with relative paths (perhaps curl is executed from another base directory?)
if you use WAMP you should also add the certificate line in php.ini for Apache (besides the default php.ini file):
[curl]
curl.cainfo = C:\your_location\cacert.pem
works for php5.3+
I am using socialite in Laravel 5 to setup facebook login. I followed the instructions carefully until I got stuck with the following error
cURL error 60: SSL certificate problem: unable to get local issuer certificate
so I found the this answer to fix it which indeed passed but then I got this error
cURL error 77: error setting certificate verify locations:
CAfile: /Applications/XAMPP/xamppfiles/cacert.pem
CApath: none
Any ideas what's the cause of this error?! and how to fix it?!
I got stuck on this problem as well. It turned out that I had the path to my certificate set incorrectly in my php.ini file. Forgot the .txt extension.
What I had:
curl.cainfo = "C:\xampp\php\cacert.pem"
What I changed it to:
curl.cainfo = "C:\xampp\php\cacert.pem.txt"
Hope this helps.
Add cacert.pem file from https://curl.haxx.se/ca/cacert.pem in
c:\xampp\php\cacert.pem
Change setting in php.ini file:
curl.cainfo = "C:\xampp\php\cacert.pem
My error is:
cURL error 77: error setting certificate verify locations: CAfile:
C:\xampp\apache\bin\curl-ca-bundle.crt CApath: none (see
http://curl.haxx.se/libcurl/c/libcurl-errors.html)
This works well for me:
Download the certificate from: https://curl.haxx.se/ca/cacert.pem
Rename the cacert.pem file into curl-ca-bundle.crt
Copy the file into path/to/xampp/apache/bin
Restart apache
I experienced some issues following instructions in regards to error 77.
On Windows 7, depending on your security settings - the file downloaded may be blocked. See screenshot:
Once I unblocked the file and ensured proper user access rights, I also had to put the file in the following location:
C:\xampp\apache\bin\cacert.pem.txt
In addition to changing php.ini per the other posts on this issue.
curl.cainfo="C:\xampp\php\cacert.pem.txt"
After completing the above steps, restarting Apache via the XAMPP Control Panel, the error was resolved.
Save this certificate (https://curl.haxx.se/ca/cacert.pem) as cacert.pem.txt in C:\xampp\php
Add to php.ini:
curl.cainfo = "C:\xampp\php\cacert.pem.txt"
Don't forget to restart XAMPP (it won't work until it restarts)
Then it works fine!
Download from (https://curl.haxx.se/ca/cacert.pem)
Change the name 'cacert.pem' to 'curl-ca-bundle.crt' (after that, move it to the path 'C:\xampp\apache\bin')
In 'php.ini', remove ';' in the following line:
curl.cainfo="C:\xampp\apache\bin\curl-ca-bundle.crt"
That works for me.
Checkout double quote on php.ini file:
if you copied and past from the Web maybe you got wrong double quote:
”C:\xampp\php\cacert.pem.txt”
instead of
"C:\xampp\php\cacert.pem.txt"
In your php.ini file, you should also update your
;openssl.cafile
with the same cacert.pem link you used in updating your
;curl.cainfo
Have a look at mine before and after
;curl.cainfo =
;openssl.cafile=
to
curl.cainfo ="C:\php-7.4.11\extras\ssl\cacert.pem"
openssl.cafile="C:\php-7.4.11\extras\ssl\cacert.pem"
this fixes the cURL 60 error
curl.cainfo ="C:\php-7.4.11\extras\ssl\cacert.pem"
while
openssl.cafile="C:\php-7.4.11\extras\ssl\cacert.pem"
fixes the cURL 77 error.
Have fun!
NB: Do not forget to restart your server before trying it out.
For those who wish to find their php.ini file, use this command after you cd into your application
php -i | grep 'Configuration File'
You need to replace the existing certificate with the other one here. After that:
Extract and add it to xampp\php\ext
Open xampp\php\php.ini
Add this line curl.cainfo='location from the first step' to the end of the file.
Restart and it should be working now.
This is the source link.
For windows
I had same problem after i updated php on window 2008. Suddenly all my php codes stopped working. What i did, i opned php.ini then i found a line
;curl.cainfo =
and i changed to
curl.cainfo = "C:\Program Files (x86)\PHP\v7.0\cacert.pem" (remember to remove ; before curl.cainfo)
and everything went to normal. What you need is to download a cert file cert.pem and place it anywhere on your server and change the line as i did in php.ini
This same problem with me in php version 8.0.3 on windows :
Solution was I had to uncomment and set openssl.capath=path of certs in php.ini file.
I already set openssl.cafile so it was not throwing error for that but oepnssl.capath was not set sot error was there.
openssl.cafile="C:\Users\Akta\Softwares\php-8.0.3-nts-Win32-vs16-x64\extras\ssl\demoCA\cacert.pem"
openssl.capath="C:\Users\Akta\Softwares\php-8.0.3-nts-Win32-vs16-x64\extras\ssl\demoCA\certs"
I read every thread I could find and this one provided the missing piece.
Background: I encountered this issue will trying to get Drupal 8 to check for available updates on a fresh development environment (wamp based).
Get a copy of the Certificate data from Mozilla, it can be found here:
https://curl.haxx.se/ca/cacert.pem
If you want to know more about what this is read this: https://serverfault.com/questions/241046/what-is-the-cacert-pem-and-for-what-to-use-that
Save the file as "cacert.pem.txt" not as "cacert.pem" This was the missing piece, thanks LyleK!. I have no clue why but you must have the .txt extension on the end or it does not work.
Explicitly add the path to the location of the "cacert.pem.txt" file to your php.ini
Example:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "C:\wamp\custom\cacert.pem.txt"
If you are using a wamp stack restart it. You should be good to go.
First, you need to download your "curl.cainfo" file then you need to locate it to C:\xampp\php\cacert.pem.txt.
Second, you need to open your php.ini file in Xampp and copy this
=>
curl.cainfo = C:\xampp\php\cacert.pem.txt anywhere you want.
Third please restart your Apache Server refresh your localhost page and that should work fine.
If anyone is running Windows with Plesk and they get this error.
You must ensure that the curl.cainfo path is inside the Plesk PHP directory otherwise you will get the error above even with the fix.
curl.cainfo = "C:\Program Files (x86)\Parallels\Plesk\Additional\PleskPHP55\extras\ssl\cacert.pem.txt"
Fixed for me. Hope this helps someone, someday, somewhere.
I've tried #mahesh-singh-chouhan, #omarsafwany, #LyleK solutions. but get same error repeatedly.
After that, I update php.ini file without double quotes & with .pem extension & I'm succeed to get desired result with below code.
curl.cainfo=E:\Xampp-5.6.3\php\ext\cacert.pem
I've also attached Screenshot.
Please first try above users suggestions, If failed also use this.
Thanks for solutions It creates way for me
#mahesh-singh-chouhan, #omarsafwany, #LyleK
I had the same issue and i tried every solution mentioned here and on other posts but none of them worked. I tried
1) Setting proper file rights ( didn't work )
2) Changing file extension ( didn't work)
then i moved the cacert.pem file inside php/ directory in xampp and restarted it, it worked. Hope it helps someone.
this worked for me
curl.cainfo = "C:\xampp\php\cacert.pem.txt"
hope it helps some one :)
It seems you forgot to add quote for the file path. I was got the same error (77), that was because i forgot to add quotes. I solved the problem by adding that. ex: "C:\AppServ\php\cacert.pem"
you did not read the error carefully, now read it carefully
cURL error 77: error setting certificate verify locations: CAfile: D:\XAMPP\apache\bin\curl-ca-bundle.crt CApath: none (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
it means you are missing a file called curl-ca-bundle.crt to verify certificate locations,
so you just need to put this(curl-ca-bundle.crt) file into your XAMPP\apache\bin\ folder
and everything is fine error 77 has gone.
curl-ca-bundle.crt, to download the file you can use this link https://github.com/nirmalkumar98/nk
i had this problem in windows 2012
i had a virtual dedicated server that host for laravel
then i had this error and
download that file from here
put in my extras folder in php 7.2
in my php.ini file find this line
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = extras/ssl/cacert.pem
i paste my download file into php file sth like this:
curl.cainfo = "C:\Program Files (x86)\PHP\v7.2\extras\ssl\cacert.pem"
then save php.ini
then restart my iis or just website
in my case i just restart my website
For solve this error use this code :
$client = new Client(['verify' => false ]);
And use this $client like this in your code:
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
RequestOptions::BODY => ' any code for your body ',
];
$response = $client->request('POST', 'bar', [
'headers' => $headers
]);
$response = $response->getBody()->getContents();
return $response;
ULTIMATE SOLUTION THAT WORKS 2022, 2023, 2024
Download from [(https://curl.haxx.se/ca/cacert.pem)][1]
Download the 'cacert.pem' twice
Change the name of the second downloaded 'cacert.pem' to 'cacert.crt'
Place both files in C:/wamp64/bin/php/php7.4.26/extras/ssl/
In your php.ini file from the wamp sever,
Uncomment ;curl.cainfo & ;openssl.cafile, be removing the semicolon before it.
Make changes as shown below:
curl.cainfo ="C:/wamp64/bin/php/php7.4.26/extras/ssl/cacert.perm"
openssl.cafile="C:/wamp64/bin/php/php7.4.26/extras/ssl/cacert.crt"
Restart wamp
It works like merlin magic (-_-)
i had the same problem. you have to open the file .pem or pem.txt with a simple editor (bloc-note) and past the (https://curl.haxx.se/ca/cacert.pem) in your file. you have to reload apache.
If it is related to git:
git config --global http.sslverify "false"
will solve the problem.
I am trying to send an API request using Stripe but get the error message:
cURL error 60: SSL certificate problem: unable to get local issuer certificate
This is the code I am running:
public function chargeStripe()
{
$stripe = new Stripe;
$stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));
$charge = $stripe->charges()->create([
'amount' => 2900,
'customer' => Input::get('stripeEmail'),
'currency' => 'EUR',
]);
return Redirect::route('step1');
}
I searched a lot on Google and lots of people are suggesting that I download this file: cacert.pem, put it somewhere and reference it in my php.ini. This is the part in my php.ini:
curl.cainfo = "C:\Windows\cacert.pem"
Yet, even after restarting my server several times and changing the path, I get the same error message.
I have the ssl_module enabled in Apache, and I have php_curl enabled in my php.ini.
I have also tried another fix which suggests that I add these lines to my cURL options:
curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);
Where do I add options to my cURL? Apparently not through the command line, since my CLI doesn't find the command "curl_setopt"
How to solve this problem:
download and extract cacert.pem following the instructions at https://curl.se/docs/caextract.html
save it on your filesystem somewhere (for example, XAMPP users might use C:\xampp\php\extras\ssl\cacert.pem)
in your php.ini, put this file location in the [curl] section (putting it in the [openssl] section is also a good idea):
[curl]
curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
[openssl]
openssl.cafile = "C:\xampp\php\extras\ssl\cacert.pem"
restart your webserver (e.g. Apache) and PHP FPM server if applicable
(Reference: https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate)
Attention Wamp/Wordpress/windows users. I had this issue for hours and not even the correct answer was doing it for me, because i was editing the wrong php.ini file because the question was answered to XAMPP and not for WAMP users, even though the question was for WAMP.
Here's what I did:
Download the certificate bundle.
Put it inside of C:\wamp64\bin\php\your php version\extras\ssl
Inside of C:\wamp64\bin\apache\apache(version)\modules, make sure the file mod_ssl.so is there
Inside of Apache directory C:\wamp64\bin\apache\apache2.4.27\conf, enable mod_ssl in httpd.conf
Enable php_openssl.dll in php.ini. Be aware my problem was that I had two php.ini files and I need to do this in both of them. First one can be located inside of your WAMP taskbar icon here.
And the other one is located in C:\wamp64\bin\php\php(Version)
Find the location for both of the php.ini files and find the line curl.cainfo = and give it a path like this curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"
Now save the files and restart your server and you should be good to go
If you are using PHP 5.6 with Guzzle, Guzzle has switched to using the PHP libraries autodetect for certificates rather than it's process (ref). PHP outlines the changes here.
Finding out Where PHP/Guzzle is Looking for Certificates
You can dump where PHP is looking using the following PHP command:
var_dump(openssl_get_cert_locations());
Getting a Certificate Bundle
For OS X testing, you can use homebrew to install openssl brew install openssl and then use openssl.cafile=/usr/local/etc/openssl/cert.pem in your php.ini or Zend Server settings (under OpenSSL).
A certificate bundle is also available from curl/Mozilla on the curl website: https://curl.haxx.se/docs/caextract.html
Telling PHP Where the Certificates Are
Once you have a bundle, either place it where PHP is already looking (which you found out above) or update openssl.cafile in php.ini. (Generally, /etc/php.ini or /etc/php/7.0/cli/php.ini or /etc/php/php.ini on Unix.)
Guzzle, which is used by cartalyst/stripe, will do the following to find a proper certificate archive to check a server certificate against:
Check if openssl.cafile is set in your php.ini file.
Check if curl.cainfo is set in your php.ini file.
Check if /etc/pki/tls/certs/ca-bundle.crt exists (Red Hat, CentOS, Fedora; provided by the ca-certificates package)
Check if /etc/ssl/certs/ca-certificates.crt exists (Ubuntu, Debian; provided by the ca-certificates package)
Check if /usr/local/share/certs/ca-root-nss.crt exists (FreeBSD; provided by the ca_root_nss package)
Check if /usr/local/etc/openssl/cert.pem (OS X; provided by homebrew)
Check if C:\windows\system32\curl-ca-bundle.crt exists (Windows)
Check if C:\windows\curl-ca-bundle.crt exists (Windows)
You will want to make sure that the values for the first two settings are properly defined by doing a simple test:
echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";
Alternatively, try to write the file into the locations indicated by #7 or #8.
If you're unable to change php.ini you could also point to the cacert.pem file from code like this:
$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
What i did was use var_dump(openssl_get_cert_locations()); die; in any php script, which gave me the information about defaults that my local php was using:
array (size=8)
'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
'ini_capath' => string '' (length=0)
As you can notice, i have set the ini_cafile or the ini option curl.cainfo. But in my case, curl would try to use the "default_cert_file" which did not exist.
I copied the file from https://curl.haxx.se/ca/cacert.pem into the location for "default_cert_file" (c:/openssl-1.0.1c/ssl/cert.pem) and i was able to get it to work.
This was the only solution for me.
I had this problem appear out-of-the-blue one day, when a Guzzle(5) script was attempting to connect to a host over SSL. Sure, I could disable the VERIFY option in Guzzle/Curl, but that's clearly not the correct way to go.
I tried everything listed here and in similar threads, then eventually went to terminal with openssl to test against the domain with which I was trying to connect:
openssl s_client -connect example.com:443
... and received first few lines indicating:
CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1
... while everything worked fine when trying other destinations (ie: google.com, etc)
This prompted me to contact the domain I had been trying to connect to, and indeed, they had a problem on THEIR END that had crept up. It was resolved and my script went back to working.
So... if you're pulling your hair out, give openssl a shot and see if there's anything up with the response from the location you are attempting to connect. Maybe the issue isn't so 'local' after all sometimes.
Have you tried..
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
If you would like to risk being hit by a man-in-the-middle attack, you can skip the verify.
Be sure that you open the php.ini file directly by your Window Explorer. (in my case: C:\DevPrograms\wamp64\bin\php\php5.6.25).
Don't use the shortcut to php.ini in the Wamp/Xamp icon's menu in the System Tray. This shortcut doesn't work in this case.
Then edit that php.ini :
curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem"
and
openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"
After saving php.ini you don't need to "Restart All Services" in Wamp icon or close/re-open CMD.
I found a solution that worked for me. I downgraded from the latest guzzle to version ~4.0 and it worked.
In composer.json add "guzzlehttp/guzzle": "~4.0"
Hope it helps someone
For WAMP, this is what finally worked for me.
While it is similar to others, the solutions mentioned on this page, and other locations on the web did not work. Some "minor" detail differed.
Either the location to save the PEM file mattered, but was not specified clearly enough.
Or WHICH php.ini file to be edited was incorrect. Or both.
I'm running a 2020 installation of WAMP 3.2.0 on a Windows 10 machine.
Link to get the pem file:
http://curl.haxx.se/ca/cacert.pem
Copy the entire page and save it as: cacert.pem, in the location mentioned below.
Save the PEM file in this location
<wamp install directory>\bin\php\php<version>\extras\ssl
eg saved file and path: "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
*(I had originally saved it elsewhere (and indicated the saved location in the php.ini file, but that did not work).
There might, or might not be, other locations also work. This was the recommended location - I do not know why.)
WHERE
<wamp install directory> = path to your WAMP installation.
eg: T:\wamp64\
<php version> of php that WAMP is running: (to find out, goto: WAMP icon tray -> PHP <version number>
if the version number shown is 7.3.12, then the directory would be: php7.3.12)
eg: php7.3.12
Which php.ini file to edit
To open the proper php.ini file for editing, goto: WAMP icon tray -> PHP -> php.ini.
eg: T:\wamp64\bin\apache\apache2.4.41\bin\php.ini
NOTE: it is NOT the file in the php directory!
Update:
While it looked like I was editing the file: T:\wamp64\bin\apache\apache2.4.41\bin\php.ini,
it was actually editing that file's symlink target: T:/wamp64/bin/php/php7.3.12/phpForApache.ini.
Note that if you follow the above directions, you are NOT editing a php.ini file directly. You are actually editing a phpForApache.ini file. (a post with info about symlinks)
If you read the comments at the top of some of the php.ini files in various WAMP directories, it specifically states to NOT EDIT that particular file.
Make sure that the file you do open for editing does not include this warning.
Installing the extension Link Shell Extension allowed me to see the target of the symlink in the file Properites window, via an added tab. here is an SO answer of mine with more info about this extension.
If you run various versions of php at various times, you may need to save the PEM file in each relevant php directory.
The edits to make in your php.ini file:
Paste the path to your PEM file in the following locations.
uncomment ;curl.cainfo = and paste in the path to your PEM file.
eg: curl.cainfo = "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
uncomment ;openssl.cafile= and paste in the path to your PEM file.
eg: openssl.cafile="T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"
Credits:
While not an official resource, here is a link back to the YouTube video that got the last of the details straightened out for me: https://www.youtube.com/watch?v=Fn1V4yQNgLs.
All of the answers are correct ; but the most important thing is You have to find the right php.ini file.
check this command in cmd " php --ini " is not the right answer for finding the right php.ini file.
if you edit
curl.cainfo ="PATH/cacert.pem"
and check
var_dump(openssl_get_cert_locations());
then curl.cainfo should have a value. if not then that's not right php.ini file;
*I recommend you to search *.ini in wamp/bin or xxamp/bin or any server you use and change them one by one and check it. *
I spent too much time to figure out this problem for me.
I had PHP version 5.5 and I needed to upgrade to 5.6.
In versions < 5.6 Guzzle will use it's own cacert.pem file, but in higher versions of PHP it will use system's cacert.pem file.
I also downloaded file from here https://curl.haxx.se/docs/caextract.html and set it in php.ini.
Answer found in Guzzles StreamHandler.php file https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437
// PHP 5.6 or greater will find the system cert by default. When
// < 5.6, use the Guzzle bundled cacert.
For those of you who are trying to use Wordpress's application password functionality on your local machine. You need to update the wp-includes\certificates\ca-bundle.crt
Open this file in a text editor and append your server's certificate.
Open your self-signed certificate(.crt) file and
Copy all between and including
----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
Paste at the end of the wp-includes\certificates\ca-bundle.crt
I just experienced this same problem with the Laravel 4 php framework which uses the guzzlehttp/guzzle composer package. For some reason, the SSL certificate for mailgun stopped validating suddenly and I got that same "error 60" message.
If, like me, you are on a shared hosting without access to php.ini, the other solutions are not possible. In any case, Guzzle has this client initializing code that would most likely nullify the php.ini effects:
// vendor/guzzlehttp/guzzle/src/Client.php
$settings = [
'allow_redirects' => true,
'exceptions' => true,
'decode_content' => true,
'verify' => __DIR__ . '/cacert.pem'
];
Here Guzzle forces usage of its own internal cacert.pem file, which is probably now out of date, instead of using the one provided by cURL's environment. Changing this line (on Linux at least) configures Guzzle to use cURL's default SSL verification logic and fixed my problem:
Since the files in vendor are not meant to be tampered with, a better solution would be to configure the Guzzle client on usage, but this was just too difficult to do in Laravel 4.
Hope this saves someone else a couple hours of debugging...
This might be an edge case, but in my case the problem was not the client conf (I already had curl.cainfo configured in php.ini), but rather the remote server not being configured properly:
It did not send any intermediate certs in the chain. There was no error browsing the site using Chrome, but with PHP I got following error.
cURL error 60
After including the Intermediate Certs in the remote webserver configuration it worked.
You can use this site to check the SSL configuration of your server:
https://whatsmychaincert.com/
when I run 'var_dump(php_ini_loaded_file());'
I get this output on my page
'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'
and to get php to load my cert file I had to edit the php.ini in this path 'C:\Development\bin\apache\apache2.4.33\bin\php.ini'
and add openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem" where I had downloaded and place my cert file from https://curl.haxx.se/docs/caextract.html
am on windows 10, using drupal 8, wamp and php7.2.4
I'm using Centos 7 with the free version of virtualmin. With Virtualmin you can create a wordpress website. There is functionality that will automatically update your ssl certificate for you. I noticed that /etc/httpd/conf/httpd.conf did not contain an entry for SSLCertificateChainFile. Which should be set to something like /home/websitename/ssl.combined. Updating that file accordingly and restarting apache fix this problem for me. I discovered my issue trying to install a jetpack plugin for wordpress. A search on the internet led me to realize that I didn't have SSL Configured. I followed Redhat's instructions on how to install a certificate. I hope this was useful to someone.
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.
Guzzle Version 5
This default config is working good for mine. It will disable https required.
$options = [
'defaults' => ['verify' => false],
];
new GuzzleClient($options);
In other case, you want to set path of ca, change to:
['verify' => '/path/to/cacert.pem']
As you are using Windows, I think your path separator is '\' (and '/' on Linux).
Try using the constant DIRECTORY_SEPARATOR. Your code will be more portable.
Try:
curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');
EDIT: and write the full path. I had some issues with relative paths (perhaps curl is executed from another base directory?)
if you use WAMP you should also add the certificate line in php.ini for Apache (besides the default php.ini file):
[curl]
curl.cainfo = C:\your_location\cacert.pem
works for php5.3+
I'm trying to fix a php_curl call on a Windows server (running IIS) that is returning the familiar error "SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed".
As detailed in many related questions here, I downloaded http://curl.haxx.se/ca/cacert.pem, moved it to my server's hard drive, and added the curl.cainfo setting to my php.ini:
curl.cainfo = "C:\path\to\cacert.pem"
Nothing, still getting the same error. However, specifying the path in the PHP code results in a successful response!
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CAINFO, "C:\path\to\cacert.pem");
$response = curl_exec($ch);
This does give me a workaround I can use for now, but I'm maintaining a large application with php_curl calls in many places, so it would be more logical to specify this setting once in php.ini so it applies to all php_curl calls in the application.
Potential dumb mistake checking:
I'm restarting IIS between php.ini edits
I know I'm editing the right php.ini, because "echo ini_get('smtp_port');" reflects changes I make to that setting (changing a non-critical setting just for testing)
I know IIS can read the file, because it works when setting it using curl_setopt() (above)
Trying to look at the ini setting directly shows that PHP doesn't seem to know anything about it (am I doing this right?):
var_dump(ini_get('curl.cainfo'));
==> bool(false)
Any ideas why PHP wouldn't read the curl.cainfo setting?
A coworker informed me that this curl php.ini setting was not added until PHP 5.3.7: http://www.php.net/manual/en/curl.configuration.php#ini.curl.cainfo
The particular test server I was working with was running an older version than that, so PHP wasn't reading that setting from php.ini.
You might not be updating the correct php.ini file. To see which file is being used as php.ini file in your cmd window type the following
php -i
and look for the Loaded configuration file value and open that file and then set the curl_cainfo and openssl_cafile absolute path to the cacert.pem file.