Php - Curl - SSL Handshake Failure


I have a big ssl problem with curl on certain web sites, where it returns :

curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

Open in new window

This error is documented (Google) but the provided tips and solutions found so far did not work, merely it relies on this configuration lines inside a php script :

curl_setopt ($curlId, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($curlId, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($curlId, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');

Open in new window

What I did : upgrade gnutls to 3.3.9, then upgrade from the latest curl version (7.41.0) an recompile php (5.4.38) on my system, I also  tried to recompile curl with openssl (0.9.8o) instead of gnutls but I dit get the exact same result.

From a php script the output displays :

* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
* Closing connection 0

Open in new window

Any help / solution greatly appreciated.

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Try setting CURLOPT_SSLVERSION to either 4, 5, or 6 and comment out the CURLOPT_SSL_CIPHER_LIST line.
FFTAuthor Commented:
Thanks for the reply

I did what you asked, not working :

1 => error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake
2 => Unknown SSL protocol error in connection
3 => error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
4 => error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
5 => Unsupported SSL protocol version
6 => Unsupported SSL protocol version
It sounds like the server you're connecting to might be having some SSL trouble. Can you tell us what the hostname is and the port you're connecting to?
IT Pros Agree: AI and Machine Learning Key

We’d all like to think our company’s data is well protected, but when you ask IT professionals they admit the data probably is not as safe as it could be.

FFTAuthor Commented:

you may be right :

It works fine with

Is there a way to bypass this error, as in a normal browser there is no alert, and by using an SSL certificate checker there is no problem ?
Dave BaldwinFixer of ProblemsCommented:
This is what I have been using:
		curl_setopt($ch, CURLOPT_SSLVERSION, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Open in new window

FFTAuthor Commented:
Absolutely not working with my current system... with still the same error

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Open in new window

It's working using wget though, I don't understand why curl does not bypass the handshake by using VERIFYHOST / VERIFYPEER in disabled mode...
VERIFYHOST and VERIFYPEER have nothing to do with the SSL connection handshake itself. Those options simply disable the checking and validation of the certificates that are being used after they are exchanged during the handshake. So if was using a self-signed certificate, then those options would allow cURL to make use of them, even if your system doesn't natively trust the certificates.

In general, it's a bad idea to EVER disable those options. It leaves the connection open to man-in-the-middle attacks.

The problem is that the server isn't offering up many available ciphers to use. During the SSL/TLS handshake (your server allows TLS v1.0, by the way), the client asks the server, "I have these 20 ciphers that I can understand - do you support any of them?" If the server doesn't use any of those ciphers, it'll fail the handshake. The server looks like it's limited to a very recent/narrow list of ciphers that older versions of cURL do not have, but your browsers DO have.

In this case, your server is offering up the use of this cipher:

But older versions of cURL do not have the "EC..." series (elliptical curve - ECDHE and ECDSA) of ciphers, and the server isn't willing to work with older ciphers, so it just fails the handshake.

I just downloaded a recent build of cURL (7.41) and it had those ciphers in the newer version, so it worked in the newer version.

So you have two options:

Option 1: Update cURL and OpenSSL to the most recent versions (do OpenSSL first). This will fix YOUR situation, and YOUR situation only. Anyone else using older ciphers will still have the same problem, including people on older browsers. I don't know which browser versions introduced support for the newer ciphers.

Option 2: Update the server to support some older ciphers for compatibility purposes (e.g. any non-EC ciphers with AES 256 might be a good choice). I don't really know how to do this for nginx, which seems to the web server for that site, so it'll be up to you to do the googling and research to do this.

That said, the problem truly is the cipher list.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Also, FWIW, Wireshark is a great packet sniffing tool with SSL inspection tools. It's a little cumbersome to learn how to use properly, but very powerful. That's how I was able to compare the cipher lists offered up by both the browser and by the older and newer versions of cURL.
Actually, I just noticed the server is cloudflare-nginx. I'm guessing might be making use of Universal SSL:

...which apparently intentionally limits the cipher list to only newer ciphers:

These challenges required that, for free customers, we limit Universal SSL support to modern browsers. Modern browsers include support for ECDSA, where many legacy browsers do not.
Dave BaldwinFixer of ProblemsCommented:
Did you also install a current version of 'libcurl'?
FFTAuthor Commented:
By installing openssl 1.0.2 and recompiling Apache / Php / Curl it finally work abide a small problem, as described here :
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.