11

I am writing a simple checker where you can enter a URL that would check if the URL entered is using TLS 1.0, 1.1 or 1.2. Essentially I want to show a message saying "Yoursite.com is using TLS 1.0. It is recommended to disable this."

The problem is, I am only able to figure it out if I am the server making the call. Then I can use this. That allows you to write a Curl script, connect to howsmyssl.com and it would return what connection I used to connect. This is not what I want.

I want to know how I can use PHP to connect to a URL, and see if that server supports TLS1.0, 1.1 or 1.2.

Is there a way to do this?

rockstardev
  • 13,479
  • 39
  • 164
  • 296
  • This might help https://serverfault.com/questions/638691/how-can-i-verify-if-tls-1-2-is-supported-on-a-remote-web-server-from-the-rhel-ce – Sarang PM Mar 21 '18 at 05:02

3 Answers3

24

How about this:

<?php

$url = 'https://fancyssl.hboeck.de/';

$protocols = [
    'TLS1.0' => ['protocol' => CURL_SSLVERSION_TLSv1_0, 'sec' => false],
    'TLS1.1' => ['protocol' => CURL_SSLVERSION_TLSv1_1, 'sec' => false],
    'TLS1.2' => ['protocol' => CURL_SSLVERSION_TLSv1_2, 'sec' => true],
    'TLS1.3' => ['protocol' => CURL_SSLVERSION_TLSv1_3, 'sec' => true],
];

foreach ($protocols as $name => $value) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSLVERSION, $value['protocol']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($ch) !== false;

    if ($value['sec'] && !$response) {
        echo "Secure $name not supported =( \n";
    } elseif ($value['sec'] && $response) {
        echo "Ok! Secure $name supported \n";
    } elseif (!$value['sec'] && $response) {
        echo "Insecure $name supported =( \n";
    } elseif (!$value['sec'] && !$response) {
        echo "Ok! Insecure $name not supported\n";
    }
}

Output is:

Ok! Insecure TLS1.0 not supported
Ok! Insecure TLS1.1 not supported
Ok! Secure TLS1.2 supported 
Ok! Secure TLS1.3 supported 
monstercode
  • 944
  • 6
  • 25
  • This will tell you if YOUR CONNECTION TO THE SERVER is the relevant TLS. Not if the server supports the relevant TLS version. – rockstardev Mar 16 '18 at 05:39
  • 3
    If you can connect using TLS 1.0, then the server supports it. The connection is established using the same protocol for both ways. If you want to know if the requests initiated by the server uses TLS 1.0 it's not possible without access to the server, or at least not in a non hacky way. Otherwise, it would be revealing sensitive information about installed components. – monstercode Mar 16 '18 at 14:08
6

Found the following at:Verify if curl is using TLS

<?php 
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);

$json = json_decode($data);
echo $json->tls_version;
?>

$json->tls_version is probably what you are looking for.

Mr. de Silva
  • 382
  • 2
  • 11
4

You can simply check, if there is a valid answer from server:

$site = 'google.com';
$ctx = stream_context_create(['ssl' => [
    'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
]]);

@$r = file_get_contents("https://$site/", FALSE, $ctx);

if ($r === false) {
    $answer = "$site is using TLS 1.0. It is recommended to disable this";
}
Mykola Vasilaki
  • 416
  • 6
  • 11
  • This will tell you if YOUR CONNECTION TO THE SERVER is the relevant TLS. Not if the server supports the relevant TLS version. – rockstardev Mar 16 '18 at 05:39
  • @coderama will you get correct response from server with this code if server NOT supports TLSv1.0? Or client can use TLSv1.0 and server can response with TLSv1.2? We can make some experiments with http://ssllabs.com/ – Mykola Vasilaki Mar 16 '18 at 07:00