1

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.

3 Answers 3

7

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);
Sign up to request clarification or add additional context in comments.

Comments

2

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;

1 Comment

Thanks for the code. I always get this, regardless of the SSL version set: ``` PHP version: 7.3.7-2+ubuntu19.04.1+deb.sury.org+1 cURL version: 7.64.0 TLS 1.3 ``` What do you get?
1

"TLS v1.1 being requested" is wrong given that TLS v1.1 or later (Added in 7.34.0) is pretty clear as well as "The maximum TLS version can be set by using one of the CURL_SSLVERSION_MAX_ macros"

2 Comments

PHP Documentation at php.net/function.curl-setopt isn't aware of these CURL_SSLVERSION_MAX_ macros at all, so it's not exactly "pretty clear". But thanks for your comment.
And of course I edited (hopefully correctly) these new macros into PHP documentation a few minutes ago, so things may change before too long.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.