web-dev-qa-db-fra.com

PHP Curl (avec NSS) utilise probablement SSLv3 au lieu de TLS lors de la connexion à https

J'utilise la bibliothèque curl (avec NSS) dans PHP pour me connecter à mon autre serveur. Tout allait bien jusqu'à la semaine dernière, lorsque le serveur de destination a cessé de prendre en charge SSLv3 en raison de la vulnérabilité du caniche (CloudFlare par le Maintenant, j'essaie d'établir une connexion en utilisant TLS, mais je reçois toujours une "erreur de connexion SSL".

Il y a un exemple de code, j'utilise:

$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);

D'après ma compréhension, la configuration CURLOPT_SSLVERSION à 1 devrait forcer la connexion via TLS.

Remarque: j'ai CURLOPT_SSL_VERIFYPEER => false juste pour le débogage et je ne veux pas le laisser là, une fois que j'ai compris ce problème.

C'est la sortie:

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

J'ai tout cela chez un fournisseur d'hébergement partagé, donc je ne peux pas changer la configuration de php.ini ni mettre à jour les composants. Tout ce que j'ai, c'est phpinfo (). J'ai vérifié la prise en charge TLS sur ces versions de composants et ça devrait aller. Voici un extrait de 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

Je pense que ce problème est l'utilisation de SSLv3 au lieu de TLS, mais je ne suis pas sûr à 100%. Tout ce que je reçois, c'est "Erreur de connexion SSL" et je ne sais pas comment savoir quelle version SSL a été utilisée pour se connecter.

Existe-t-il un moyen, comment vérifier, quelle version SSL est utilisée pour la connexion? Ou est-ce que je manque quelque chose?

11
Lapak

Voilà un problème intéressant.

Si vous interrogez SSLLabs pour ce site, vous verrez qu'il ne prend en charge que divers chiffrements ECDHE-ECDSA- * et aucun autre chiffrement. Mais, dans le historique des versions de curl vous trouverez un bug avec les chiffrements ECC et la bibliothèque NSS (que vous utilisez) qui n'est corrigé que dans la version curl 7.36 "nss: permet d'utiliser Chiffres ECC si NSS les implémente " .

Étant donné que vous utilisez curl 7.19.7, votre boucle est trop ancienne pour utiliser les chiffrements nécessaires avec la bibliothèque NSS. Cela signifie que vous devez mettre à jour votre bibliothèque curl.

20
Steffen Ullrich

J'ai Curl 7.21.7 et PHP 5.4.34, et cela semblait faire l'affaire pour moi:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

Plus d'informations ici , même si cela ne dit pas quand CURL_SSLVERSION_TLSv1 a été introduit.

12
Derrick Miller

La réponse pour moi a été d'utiliser une valeur entière au lieu d'une chaîne. C'est-à-dire: Changement:

curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);

À:

curl_setopt($ch, CURLOPT_SSLVERSION, 6);

Ou pour tlsv1_1:

curl_setopt($ch, CURLOPT_SSLVERSION, 5);

Voici la liste complète:

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)

Je lance d'ailleurs ce qui suit:

curl-7.19.7-46.el6.x86_64
nss-3.21.0-0.3.el6_7.x86_64
3
David Breise

Réponse en double l'erreur SSL ne peut pas changer en TLS proposé:

Essayez d'ajouter CURLOPT_SSL_CIPHER_LIST => 'TLSv1' à votre PPHttpConfig.php.

(et discuté ici Mettre à jour PHP demande cURL de SSLv3 à TLS ..? aussi)).

Comme utile, cela s'applique à bibliothèque openssl curl, pas à nss .

2
philippe lhardy