Once again, another question concerning cURL and SSL, as I cannot find matching answers to my problem.
I have working SSL on my webserver, with trusted cert and green signs on browsers address bar a.s.o., NOT self signed. So good, so far.
Now I want communicate with cURL and use the following function (POST data not added yet):
function ssltest(){
$post_data = '';
$url = 'https://myserver/test.php';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_MUTE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/cacert.pem');
curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/false.pem');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
echo ssltest();
As the cacert.pem I use this one, which I found in my browser, which is obviously identical to what I found here http://curl.haxx.se/ca/cacert.pem
In the code shown above there is a false.pem to be seen. Now what ? If this file is empty, there's no response from Server, but I tested to paste the cert from another enterprise from the list on curl.haxx.se I get the same correct answer from the server as result, as when I use my correct .pem
What's the issue ? What I am missing ?
"there's no response from Server"
I think that's very unlikely. I suspect there is no HTTP response from the server, but that the SSL negotiation is failing - but you've got no error checking in your code. If $output===false, have a look at curl_error().
You might want to play around with VERIFYHOST and VERIFYPEER to pin down the exact cause of the problem.
Related
I am trying to fetch a data from a site using curl method. Before i can able to get data by using curl.Recently client taken ssl certificate for that site from then onwards i can't able to get the data using curl. But when i try the URL in browser i can able to see data. Can any one tell me why it is not working.did i need to try in some another way.
Below is my code
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "https://qa.myhealth.today/myhealth-portal/nirvahak/public/validateSessionttt?username=pavithra#gmail.com");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
$output=json_decode($output);
print_r($output);
There are 2 fixes:
1) SSL certified websites do not trust any non-SSL requests. So, we need to win trust of SSL enabled client.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
2) Provide him the security certificate.
Go the the respective site. Save the SSL certificate and pass the certificate path to the CURL request.
So, the final code should be:
// create curl resource
$ch = curl_init();
$url = "https://qa.myhealth.today/myhealth-portal/nirvahak/public/validateSessionttt?username=pavithra#gmail.com";
// set url
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
$output=json_decode($output);
print_r($output);
Detailed instructions on how to do it are place here:
Set CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER to false.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
CURLOPT_SSL_VERIFYHOST
1 to check the existence of a common name in the SSL peer certificate. 2 to check the existence of a common name and also verify that it matches the hostname provided. In production environments the value of this option should be kept at 2 (default value).
CURLOPT_SSL_VERIFYPEER
FALSE to stop cURL from verifying the peer's certificate. Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option.
Source: http://php.net/manual/en/function.curl-setopt.php
I'm a bit of a beginner to this. But I am trying to use cURL to perform a GET request to pull back users tweets.
I've been able to authenticate OK. But I cannot work out how to GET the data. I'm working from my localhost.
I've tried adding a basic certificate but it does not work.
Do I have to buy an SSL certificate for my site? I've seen twitter feeds on other sites that haven't purchased SSL certificates so I don't know how they do it?
I've seen this in the Twitter documentation. The file that is mentioned, is that the one I can purchase?
curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, True);
curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($connection, CURLOPT_CAINFO, "path:/ca-bundle.crt");
This is my cURL code, it worked before I put the CURLOPT_URL section in and got a positive response from the server:
$url = "https://api.twitter.com/oauth2/token";
$headers = array(
"POST /oauth2/token HTTP/1.1",
"Host: api.twitter.com",
"User-Agent: my Twitter App v.1",
"Authorization: Basic ".$encoded."",
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8"
);
$ch = curl_init();
curl_setopt ($ch, CURLOPT_CAINFO, "cacert.pem");
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/".$username.".json?count=".$num_tweets);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$header = curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
Edit: there are problems with the code above, I'm aware I'm doing something wrong but not sure what. Anyway, here is the original code I had which did work OK and got the expected result back from the server. So the next step is to request the user's tweets from their timeline.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
$header = curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
You may use curl_getinfo to know what's going on.
You may also post the url of the Twitter documentation so we can have a look.
$headers indicates a host as api.twitter.com but CURLOPT_URL uses twitter.com, is this a typo ?
Your code is schizophrenic:
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/".$username.".json?count=".$num_tweets);
You're setting the URL twice, to different URLs. Only the LAST url set will have any effect, so you're not posting to the API, you're posting to something else on the main twitter site.
And no, you don't need an SSL cert on your own machine to do any of this. The ca-cert.pem is a list of cert issuer's public certs, which will be used to validate/authenticate Twitter's own certificate. It's basically the same thing built into your browser(s) that allow them to validate any other SSL cert out there. e.g. you don't have to buy a personal SSL cert to go shopping on amazon.com, you just need the CA certs in your browsers to authenticate amazon's servers.
I am having some issues communicating to certain third party system, through CURL in PHP.
This is part of the code I have to submit come requests
$query = '<tag>some xml content with request data</tag>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://secure.certainsystem.com/function.php");
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_POST, 1);
$data = curl_exec($ch);
The request is the same for all cases, but sometimes I don't get any data from the curl_exec($ch), and instead, when I run curl_error($ch), I get:
SSL peer certificate or SSH remote key was not OK
This is not happening all the times, but it is happening, so I'm not sure what the problem could be, if the problem is in the code, or there is a problem in the third party system I'm comunicating to.
I searched for this message error in other places and here as well, and I found that if CURLOPT_SSL_VERIFYPEER is set to true, then it could be a problem with the third party system's certificate, perhaps a self-signed one. But in my case, that option is set to 0, which I assume is taken as false.
Recently I found there is an option CURLOPT_SSL_VERIFYHOST, but I'm not setting that option to any value, so I think it is taking the default, which according to PHP.net documentation, is 2, which means:
2 to check the existence of a common name and also verify that it matches the hostname provided.
Thank you very much for your help.
add options
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
more see here https://answers.launchpad.net/ubuntu/+question/171188
Although I am answering an old post, I think it will help the new viewers-
You can check the problem by adding
curl_setopt($ch, CURLOPT_VERBOSE, 1);
The reason is explained in my post here.
This is my Code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postValues);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
Now the $result is "false" and the curl_error() shows me the SSL-Error "Peer's Certificate issuer is not recognized.".
But although there is this error, the post data has been sent to the $apiUrl.
Is this correct? Bug or feature? ;)
How can I improve this to prevent sending data to an insecure service?
Thanks in advance! :)
There is two solution for this...
Solution - 1
If you want to skip check SSL certificate use....
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
Solution - 2
If you have certificate with you use....
curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Thanks.
Finally I found the reason why the data has been transfered although there has been a curl error!
There was a redirect to another location and with "followlocation" active, the error happened on the redirected site!
So the data has been sent to the $apiUrl and has been processed. After this the curl call has been redirected and the error appeared.
My trust in logic has been restored :D
This is incorrect; cURL does not send any data when there is a problem with the SSL certificate.
(I just tested with a connection to a local script - the second script did not run when the first script encountered an SSL error while connecting to it.)
I'm trying to get response using the Google Safe Browsing Lookup API like this:
$url ="https://sb-ssl.google.com/safebrowsing/api/lookup?client=myappname&apikey=mykey&appver=1.0&pver=3.0&url=".urlencode($myurl);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
$body = curl_exec($ch);
$info = curl_getinfo($ch);
I know that my URL is correct since if I dump it and then paste it to the browser I get the expected result (for example 'malware').
So I am assuming it must be something with cURL. I'm working on localhost and extension=php_curl.dll is un-commented in my php.ini, Php version 5.4.4
The html_code is always 0
Simply set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to false.
Anything wrong with my cURL code (http status of 0)?
Also check http://code.google.com/p/twitter-api/issues/detail?id=1291 , it might help. It is different APIs, but with the same problem anyway.
The problem and its solution is very nicely described here:
http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/
Basically if you are not using a standalone version of cURL the chances are that the cURL functions do not include a certificate bundle which was needed in my case since I was trying to connect to secure host.
$ch = curl_init();
// Apply various settings
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CAINFO, "C:/xampp/ca-bundle.crt"); //path to the CA-bundle
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close($ch);