Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A problem occurred somewhere in the SSL/TLS handshake

Tags:

I've been having problems on my development server where cURL, while working perfectly with anything HTTP, does not function properly with anything HTTPS—even the exact same resource with different protocols (for testing I've been requesting google.com using both HTTP and HTTPS).

The cURL error returned is 35:

A problem occurred somewhere in the SSL/TLS handshake.

I have combed the web and SO for solutions, and all of them have been to either set CURLOPT_SSL_VERIFYPEER to false, which changes nothing, or to download the certificate file and set CURLOPT_CAINFO to its path, which also changes nothing.

When setting a certificate, I followed the instructions of this tutorial and this tutorial, trying to both download the certificate for the resource I'm requesting, and downloading a cert bundle.

I've also tried explicitly setting CURLOP_PORT to 443. For thoroughness of my question, other options I set are CURLOPT_VERBOSE=true, CURLOPT_RETURNTRANSFER=true, and CURLOPT_SSL_VERIFYHOST=2 (I've tried every combination of 1, and 2 with VERIFYPEER both true and false). I also have made sure in phpinfo() that I have OpenSSL and it is enabled.

I'm using a lot of old code that worked perfectly on my last production server, so this code has worked before. But that hosting was shared hosting and I don't know most of the configuration there.

like image 387
spezied Avatar asked Mar 19 '12 16:03

spezied


People also ask

What causes TLS handshake to fail?

A TLS/SSL handshake failure occurs when a client and server cannot establish communication using the TLS/SSL protocol. When this error occurs in Apigee Edge, the client application receives an HTTP status 503 with the message Service Unavailable.


2 Answers

Curl doesn't have built-in root certificates (like most modern browser do). You need to explicitly point it to a cacert.pem file:

  curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cert/file/cacert.pem'); 

Without this, curl cannot verify the certificate sent back via ssl. This same root certificate file can be used every time you use SSL in curl.

You can get the cacert.pem file here: http://curl.haxx.se/docs/caextract.html

like image 114
Ray Avatar answered Sep 21 '22 07:09

Ray


How about this. It fetches what might be the HTTPS Google homepage. (Since I've disabled certificate verification, I have no way to actually know that it's the real Google homepage.) It should do the trick for you.

<?PHP  // connect via SSL, but don't check cert $handle=curl_init('https://www.google.com'); curl_setopt($handle, CURLOPT_VERBOSE, true); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); $content = curl_exec($handle);  echo $content; // show target page ?> 
like image 41
Joseph Lust Avatar answered Sep 21 '22 07:09

Joseph Lust