简体   繁体   中英

PHP cURL: enforce low TLS version

Goal is to write PHP code testing for TLS v1.2 connectivity. Getting a successful answer isn't a problem, but I can't produce a failure by using an older TLS version in PHP. Testing failures is obviously needed to prove correctness of code (to some reasonable degree).

On the command line I could come up with this, giving a clear distinction:

$ curl -X POST https://api.paypal.com/v1/oauth2/token 
{"name":"AUTHENTICATION_FAILURE", [...]

$ curl --tls-max 1.1 -X POST https://api.paypal.com/v1/oauth2/token 
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

In PHP I tried this ...

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// $response: '{"name":"AUTHENTICATION_FAILURE", [...]

... which means a succcessful TLS v1.2 connection, as one can see in the CLI example above, despite TLS v1.1 being requested. It's the same result as when requesting CURL_SSLVERSION_TLSv1_2.

This is PHP 7.3.7 with cURL 7.64.0 and I hope I can get away without recompiling PHP just for disabling TLS v1.2 support.

Little PHP/CURL test script:

<?php

echo 'PHP version: ' . phpversion() . PHP_EOL;
echo 'cURL version: ' . curl_version()['version'] . PHP_EOL;

$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0); // TLS 1.0
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1); // TLS 1.1
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // TLS 1.2 or 1.3

$data = curl_exec($ch);
curl_close($ch);

$json = json_decode($data);

echo ($data ? $json->tls_version : 'curl request failed') . PHP_EOL;

鉴于TLS v1.1或更高版本(在7.34.0中添加)非常清楚,以及“可以使用CURL_SSLVERSION_MAX_宏之一来设置最大TLS版本”,因此“请求TLS v1.1”是错误的

To answer my own question, documentation at https://www.php.net/function.curl-setopt is/was outdated. cURL 7.54 changed behavior of CURL_SSLVERSION_ macros, these set now the minimum acceptable TLS version for the connection. It also introduced CURL_SSLVERSION_MAX_ macros, which set the maximum TLS version tried. Until PHP documentation is updated, see https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html .

Accordingly, limiting the connection to TLS v1.1 works like this:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM