Cannot identify local issuer - php

I'm getting this error:
SSL problem: can't identify local issuer
once I call the function to save an image or retrieve user's Facebook image:
file_get_contents()
What I've done is:
I have my website running on Azure *.azurewebsites.com
I added my custom domain and ssl certificate which were both bought from GoDaddy
I created Certificate Signing Request (CSR) (which GoDaddy asked for) using OpenSSL on my Mac
Signed it with it and downloaded it to get .p7b file and .crt file
I added the .crt file to Azure and everything works fine, my custom domain now has the lock beside it
So after those steps, logging in with Facebook got that error also so I did a temporary fix:
curl_setopt($rest, CURLOPT_SSL_VERIFYPEER, false);
This is not recommended of course, but it allows me to test the rest of the site. The error still occurred but only when invoking file_get_contents(). I've tried these fixes from what I've seen scouring around:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/cacert/cacert.pem");
But no dice. Can someone explain exactly what the error means and also to combat it? That'd be great. And also, this might be due to creating my Certificate Signing Request with OpenSSL... not sure. Please confirm.

curl_setopt flags works only with handler you're passing to those calls. file_get_contents has no idea about any of CURLOPT_SSL_VERIFYPEER or CURLOPT_SSL_VERIFYHOST flags.
Change file_get_contents to curl calls.

Related

Pulled down site with "BackupBuddy" to local machine, trying to use SendGrid to send email, getting "CURL Error 60: self signed certificate" [duplicate]

I try to send curl request with my correct APP_ID, APP_SECRET etc. to the
https://oauth.vk.com/access_token?client_id=APP_ID&client_secret=APP_SECRET&code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a&redirect_uri=REDIRECT_URI
I need to get access_token from it, but get a FALSE and curl_error() print next message otherwise:
60: SSL certificate problem: self signed certificate in certificate chain
My code is:
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
if ( ! $output) {
print curl_errno($ch) .': '. curl_error($ch);
}
// close curl resource to free up system resources
curl_close($ch);
return $output;
When I move manually to the link above, I get access_token well. Why it doesn't work with curl? Help, please.
Answers suggesting to disable CURLOPT_SSL_VERIFYPEER should not be accepted. The question is "Why doesn't it work with cURL", and as correctly pointed out by Martijn Hols, it is dangerous.
The error is probably caused by not having an up-to-date bundle of CA root certificates. This is typically a text file with a bunch of cryptographic signatures that curl uses to verify a host’s SSL certificate.
You need to make sure that your installation of PHP has one of these files, and that it’s up to date (otherwise download one here: http://curl.haxx.se/docs/caextract.html).
Then set in php.ini:
curl.cainfo = <absolute_path_to> cacert.pem
If you are setting it at runtime, use (where $ch = curl_init();):
curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
This workaround is dangerous and not recommended:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
It's not a good idea to disable SSL peer verification. Doing so might expose your requests to MITM attackers.
In fact, you just need an up-to-date CA root certificate bundle. Installing an updated one is as easy as:
Downloading up-to-date cacert.pem file from cURL website and
Setting a path to it in your php.ini file, e.g. on Windows:
curl.cainfo=c:\php\cacert.pem
That's it!
Stay safe and secure.
If the SSL certificates are not properly installed in your system, you may get this error:
cURL error 60: SSL certificate problem: unable to get local issuer
certificate.
You can solve this issue as follows:
Download a file with the updated list of certificates from https://curl.haxx.se/ca/cacert.pem
Move the downloaded cacert.pem file to some safe location in your system
Update your php.ini file and configure the path to that file:
Important: This issue drove me crazy for a couple days and I couldn't figure out what was going on with my curl & openssl installations. I finally figured out that it was my intermediate certificate (in my case, GoDaddy) which was out of date. I went back to my godaddy SSL admin panel, downloaded the new intermediate certificate, and the issue disappeared.
I'm sure this is the issue for some of you.
Apparently, GoDaddy had changed their intermediate certificate at some point, due to scurity issues, as they now display this warning:
"Please be sure to use the new SHA-2 intermediate certificates included in your downloaded bundle."
Hope this helps some of you, because I was going nuts and this cleaned up the issue on ALL my servers.
To add a more specific answer, I ran into this when using Guzzle v7, the PHP HTTP request package. Guzzle allows you to bypass this like so:
use GuzzleHttp\Client;
$this->client = new Client([
'verify' => false,
]);
Original source comment: https://github.com/guzzle/guzzle/issues/1490#issuecomment-375667460
Error: SSL certificate problem: self signed certificate in certificate
chain
Solution:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

Text magic sms API getting error on Godaddy shared hosting

I am tryng to send SMS using Textmagic from godaddy using php. I have used the official git-hub page to get API https://github.com/textmagic/textmagic-rest-php
The above setups works fine from my local Ubuntu PC and able to send SMS,
Where as when I host the API to Godaddy Windows shared hosting, and executed the same php code, I got following error.
[ERROR- ] error setting certificate verify locations: CAfile: c:\cgi\php56\curl-ca-bundle.crt CApath: none
What could be the reason.
Php version:5.6
I'm not sure if there is something GoDaddy configures that would not make this possible, but the best/most secure way to tackle this is to NOT use CURLOPT_SSL_VERIFYPEER = FALSE, but instead export the certificate chain to X.509. Then use CURLOPT_CAINFO to point to that certificate.
IE
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, "/path/to/the/certificate-you-exported.crt");
If GoDaddy does not let you do this, my suggestion would be to find another provider.
you can use :
curl_setopt($link, CURLOPT_SSL_VERIFYPEER, FALSE);
but please be sure : you will lose the benefit of certification verification.
bypassing verification is not a good idea , ( may any one with you on the server get the URL and your api key )
if you have a root access on the server please enable permission for the user on the server verification folder :
chmod 755 /usr/share/ssl/certs
this link can help for goddady : https://blog.hqcodeshop.fi/archives/304-Fixing-curl-with-Go-Daddy-Secure-Certificate-Authority-G2-CA-root.html

Mandrill CA SSL errors with cURL

I'm trying out Mandrill. It looks nice. I signed up with an account and got an api key. Downloaded the Mandrill PHP wrapper from
https://bitbucket.org/mailchimp/mandrill-api-php
This post seemed to have a pretty good hello-world Mandrill email example, so I tried it out:
Simple php function to send an email with Mandrill
Kept getting this error:
API call to templates/add failed: Problem with the SSL CA cert (path? access rights?)
I followed the instructions from these S.O. posts:
error in send email using Mandrill (php)
HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK
Grabbed the .pem file from http://curl.haxx.se/docs/caextract.html
and made sure the the curl api pointed to that file inside the Mandrill api
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");
The .pem file is readable. No crazy permissions situations.
No help. Same deal:
API call to templates/add failed: Problem with the SSL CA cert (path? access rights?)
Googling around I followed the CentOS 6.0 steps here:
http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html
As well as the steps here:
http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
Same error. As a last try, I set curl to ignore the ssl-step entirely. This of course is not advised, but I just wanted to feel solid ground under my feet. I went back into Mandrill.php and gave this a shot.
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
Again, same error. I was wondering if someone else can shed some light on this for me. I've exhausted google. (It gave me a recaptcha because I was using it too much). Thanks for your time!
(System: CentOS 6.5, PHP 5.3)
Odd that you're having this issue on Linux (known problem in Windows though).
The only thing I kan think of is that you try to load the the .pem as a default via your php.ini-file, check curl.cainfo and supply an absolute path to the cacert.pem-file. That should make so that you don't have to use CURLOPT_CAINFO – and perhaps gives a better result?
Half off-topic; if you don't need all the features that the API gives you, you can also use an SMTP-connection (always easier to work with).

Are SSL Certificates personal or global?

I'm wondering i export the certificate of a website will it get exported with some of my personal info?
Basically I'm working on a cURL script and other people are gonna use it too so the following would not be the best option:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
So i came across a guide on how to verify the certificate and it says i need to export it and attach those lines to my code:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
Now the problem is i don't really know how this thing works, is it safe to export a certificate and let others use the cURL with it or the certificate has some of my own info (Users/Password/Activity etc..) when exported thru my browser?
SOLVED: This is the guide i was using for those who will find this topic later: LINK and the Certificate i was talking about is from Facebook.
:)
That depends. Server HTTPS certificates are global, and so are CA certificates (which is what you seem to be after). These are used by the client to verify that it's talking to the correct server securely.
On the other hand, it is possible for the server to verify a client-side certificate, to verify "who is the user" (that does not seem to be the case here).

PHP curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false) too slow

I use this method to get facebook api data. just a search query. but I find use curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); cost more time during a curl time (over 10+ seconds).
Is there other curl method can run faster?
NOTE: I am now testing in localhost
$url = "https://graph.facebook.com/search?access_token=".$token."&q=dallas&type=post&scope=publish_stream,offline_access,user_status,read_stream";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 2);
//curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__). '/file.crt'); the way as Lumbendil recommend, download a crt file via firefox. still slowly.
$body= curl_exec($ch);
curl_close ($ch);
PS:I do not want to use a SDK, becuase I failed set SDK in localhost test. Although I have read many articles of how to set in localhost. I have set http://127.0.0.1/facebook as my callback url. But just failed. So I still want to get an easy curl way.
Thanks.
You could use a .crt file and verify against that instead of ignoring SSL verification, as explained here.
To keep all the information in one place: In your code, you should write the following:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/crt/file.crt');
To obtain the certificate, you should go with the browser to the page, and then with "view certificate" you have to export it. Remember that you must export it as X.509 Certificate (PEM) for this to work. For a more detailed guide on how to export the certificate, visit the link provided.
If ignoring to check a certificate takes 10 seconds, the problem is not with the certificate or with the checking and quite frankly, it probably isn't with SSL at all.
Ignoring to check the certificate should be very fast and not be measurable compared to how long the rest of the SSL handshake procedure takes.
To properly track down the problem, I would recommend you use the curl command line tool and its --trace-ascii and --trace-time options to see what seems to take time. You may need to snoop on the network with wireshark or similar to get an even better picture of what's going on.
I can't see how the other suggestions of adding a certificate check to the mix will make anything faster.
Just a side note, but if you do wish to use the SDK you can work around the local issue by editing your hosts file and adding localhost.local for 127.0.0.1. /etc/hosts on a linux machine and C:\WINDOWS\system32\drivers\etc\hosts on a windows machine.
Then in the Facebook app settings, simply set localhost.local as your domain and set your site url accordingly.
You should be ready to go then.

Categories