Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Curl (with NSS) is probably using SSLv3 instead of TLS when connecting to https

Tags:

php

curl

https

ssl

nss

I'm using curl library (with NSS) in PHP to connect to my other server. Everything was fine until last week, when the destination server stoped supporting SSLv3 due to poodle vulnerability (CloudFlare by the way). Now, I'm trying to make connection using TLS, but I'm still getting "SSL connect error".

There is sample code, I'm using:

$ch = curl_init();
curl_setopt_array( $ch, array(
    CURLOPT_URL => 'https://www.lumiart.cz',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSLVERSION => 1,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_VERBOSE => true
) );
$output = curl_exec( $ch );
echo $output;

print_r( curl_getinfo( $ch ) );

echo 'error:' . curl_error( $ch );

curl_close($ch);

From my understanding, setting CURLOPT_SSLVERSION to 1 should force connection via TLS.

Note: I have CURLOPT_SSL_VERIFYPEER => false just for debuging and I'm not meaning to leave it there, once I figure this problem out.

This is output:

Array
(
    [url] => https://www.lumiart.cz
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0
    [namelookup_time] => 2.3E-5
    [connect_time] => 0.005777
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 2400:cb00:2048:1::681c:86f
    [redirect_url] => 
)
error:SSL connect error

I have all of this at shared hosting provider, so I can't change any php.ini configuration or update any components. All I have is phpinfo(). I've checked for TLS support on these components version and it should be fine. Here is excerpt of phpinfo:

PHP Version 5.4.32
System  Linux wl42-f262 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64

curl:
cURL support    enabled
cURL Information    7.19.7
Age 3
Features
AsynchDNS   No
Debug   No
GSS-Negotiate   Yes
IDN Yes
IPv6    Yes
Largefile   Yes
NTLM    Yes
SPNEGO  No
SSL Yes
SSPI    No
krb4    No
libz    Yes
CharConv    No
Protocols   tftp, ftp, telnet, dict, ldap, ldaps, http, file, https, ftps, scp, sftp
Host    x86_64-redhat-linux-gnu
SSL Version NSS/3.15.3
ZLib Version    1.2.3
libSSH Version  libssh2/1.4.2

I think, that problem is usage of SSLv3 instead of TLS, but I'm not 100% sure. All I'm getting is "SSL connect error" and I don't know, how to find out, which SSL version was used to connect.

Is there a way, how to check, which SSL version is used for connection? Or am I missing something?

like image 962
Lapak Avatar asked Oct 19 '14 16:10

Lapak


4 Answers

That's an interesting problem.

If you query SSLLabs for this site you will see, that it only supports various ECDHE-ECDSA-* ciphers and no other ciphers. But, in the version history of curl you will find a bug with ECC ciphers and the NSS library (which you use) which is only fixed in curl version 7.36 "nss: allow to use ECC ciphers if NSS implements them".

Since you are using curl 7.19.7 your curl is too old to use the necessary ciphers together with the NSS library. This means you need to upgrade your curl library.

like image 171
Steffen Ullrich Avatar answered Nov 09 '22 07:11

Steffen Ullrich


I have Curl 7.21.7 and PHP 5.4.34, and this seemed to do the trick for me:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

More info here, although it doesn't say when CURL_SSLVERSION_TLSv1 was introduced.

like image 13
Derrick Miller Avatar answered Nov 09 '22 07:11

Derrick Miller


The answer for me was to use an integer value instead of a string.. i.e.: Change:

curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);

To:

curl_setopt($ch, CURLOPT_SSLVERSION, 6);

Or for tlsv1_1:

curl_setopt($ch, CURLOPT_SSLVERSION, 5);

Here's the full list:

CURL_SSLVERSION_DEFAULT (0)
CURL_SSLVERSION_TLSv1 (1)
CURL_SSLVERSION_SSLv2 (2)
CURL_SSLVERSION_SSLv3 (3)
CURL_SSLVERSION_TLSv1_0 (4)
CURL_SSLVERSION_TLSv1_1 (5)
CURL_SSLVERSION_TLSv1_2 (6)

I'm running the following by the way:

curl-7.19.7-46.el6.x86_64
nss-3.21.0-0.3.el6_7.x86_64
like image 5
David Breise Avatar answered Nov 09 '22 06:11

David Breise


Duplicate answer SSL error can not change to TLS proposed :

Try adding CURLOPT_SSL_CIPHER_LIST => 'TLSv1' to your PPHttpConfig.php.

( and discussed here Update PHP cURL request from SSLv3 to TLS..? too ).

As usefully commented, this apply to openssl curl library, not to nss.

like image 3
philippe lhardy Avatar answered Nov 09 '22 06:11

philippe lhardy