4

I have 2 php scripts , to send an xml file and catch it. I am using cURL and everything was ok. Now i am trying to do the same but using HTTP over SSL (HTTPS). I have installed a local server with XAMPP and i have set up SSL by following this post : Setting up SSL on a local xampp/apache server .

I am trying to send the xml file like this :

<?php
  /*
   * XML Sender/Client.
   */
  // Get our XML. You can declare it here or even load a file.



  $xml = file_get_contents("data.xml");


  // We send XML via CURL using POST with a http header of text/xml.
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

  //i use this line only for debugging through fiddler. Must delete after done with debugging.
  curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');

  // set URL and other appropriate options
  curl_setopt($ch, CURLOPT_URL, "https://ipv4.fiddler/iPM/receiver.php");
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  curl_setopt($ch, CURLOPT_REFERER, 'https://ipv4.fiddler/iPM/receiver.php');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $ch_result = curl_exec($ch);
  echo "Result = ".$ch_result;
  curl_close($ch);
  // Print CURL result.
?>

I downloaded the new certificate for cURL from here :

http://curl.haxx.se/ca/cacert.pem

I am not sure where i should put the certificate but i put it in my workspace directory of this project.

The problem now is that the XML file is never sent to the receiver. Any ideas?

Community
  • 1
  • 1
donparalias
  • 1,834
  • 16
  • 37
  • 60
  • The self signed cert you've used should be passed to cURL instead as part of your test configuration. – Ja͢ck Jan 21 '13 at 23:11
  • Can you explain a bit more what you mean because i am confused? – donparalias Jan 21 '13 at 23:14
  • The cacert.pem is used to validate ca signed certificates, but your test server is using a self signed certificate. Perhaps this will help: http://stackoverflow.com/questions/10901189/curl-php-proper-ssl-between-private-servers-with-self-signed-certificate – Ja͢ck Jan 21 '13 at 23:23
  • so what can i do about that? i am sorry i am very new to php.. – donparalias Jan 21 '13 at 23:25
  • I am sorry but now i am more confused. The guy is asking what i need but i cant understand the answer to the problem. – donparalias Jan 21 '13 at 23:33
  • The answer is more in the question itself; if you have self signed your certificate you should have a `.crt` file lying around; you can pass that to cURL to verify the cert. – Ja͢ck Jan 21 '13 at 23:41
  • So what i should look for is how to make a self signed certificate and i am set? i mean just for the developing period to my localhost. – donparalias Jan 21 '13 at 23:41
  • Yeah, that should do it. I'm surprised that step wasn't explained in the related article you've read. – Ja͢ck Jan 21 '13 at 23:47
  • Yes you are completely right. I just didnt understand it when i read it. Now that you called it "self signed certificate" i understood what it was all about. If you like you can post a full answer and i will accept it. – donparalias Jan 21 '13 at 23:50
  • I'll ponder on this for a while and formulate my answer :) – Ja͢ck Jan 22 '13 at 00:05

2 Answers2

7

The cacert.pem that you're passing to cURL via the CURLOPT_CAINFO is used to verify certificate authorities, but development servers typically have self signed certificates which are not included in that bundle.

The first step is to generate your own self signed certificate. This article describes the process step-by-step. Make sure that during the CSR generation you're using the intended server name under the Common Name (CN), e.g. ipv4.fiddler.

Once you have configured your web server using the self signed certificate (e.g. server.crt) and key (e.g. server.key), you need to copy the former to a location that your script can access it.

The following bare essentials can be used to verify the whole thing:

$ch = curl_init('https://ipv4.fidler');
curl_setopt_array($ch, array(
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_VERBOSE => true,
    CURLOPT_CAINFO => '/path/to/server.crt',
));

if (false === curl_exec($ch)) {
    echo "Error while loading page: ", curl_error($ch), "\n";
}
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Dear @Jack i get this error :SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed . I think i need to configure the CURLOPT_SSLCERT too. However when i use both i always get this error : Curl error: unable to use client certificate (no key found or wrong pass phrase?) Please if you are kind enough check this question that i describe the problem more in depth : http://stackoverflow.com/questions/14450530/how-to-use-a-self-signed-certificate-with-xampp-for-https-requests-using-curl – donparalias Jan 23 '13 at 01:37
  • @donparalias I've tried the code in my answer almost verbatim and it works without any errors; maybe the wrong file was used to verify the certificate. I would suggest you only try this script before trying to make changes to existing code. – Ja͢ck Jan 23 '13 at 02:03
  • Dear @Jack , i just run your script. i get Error while loading page: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed . – donparalias Jan 23 '13 at 02:25
  • @donparalias well, that's just baffling, especially if you have followed all the steps in my answer. – Ja͢ck Jan 23 '13 at 02:39
  • What does the error mean? Where can the mistake be? If you see the other post i directed you to , you ll see exactly what i did to make my certificate and how i configured apache. – donparalias Jan 23 '13 at 02:48
  • @donparalias The other post is way more complicated than this; basically it can't verify the certificate based on what you have given ... but if you ran my code (note that it doesn't use proxies), it seems that even that doesn't work, but it really should. – Ja͢ck Jan 23 '13 at 02:53
  • Dear @Jack . I tried not to use the proxy and made a certificate with the common name : localhost and it worked!!!! However when i trie to make a certificate for ipv4.fiddler it doesnt work. Maybe because is a proxy and i have no authority on that? fillder is just a web debugger that i use. – donparalias Jan 23 '13 at 03:06
  • @donparalias I'm glad to know that the basics work; so then we've narrowed the problem down to the proxy server itself, which can be discussed in the related question. – Ja͢ck Jan 23 '13 at 03:10
  • Yes you are right. I am really glad it works i was working on this almost 24h without any luck. I cant thank you enough. I ll contact the support service of the debugger for more information. – donparalias Jan 23 '13 at 03:13
2

If I you want to send a ssl post request using Curl, without verify the certificate, you can use the following code:

$data = array(
    'name' => $name,
    'ip' => $ip,
    'text'=> "text"
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,'https://myserver.com/index.php/');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
          http_build_query($data));

// receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
Khushal Chouhan
  • 581
  • 5
  • 15