In PHP, it is possible to control the SSL protocol that curl uses with the CURL_SSLVERSION_* constants.
By setting:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
I can force curl to use "TLS 1.1".
By setting:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
I can force curl to use "TLS 1.0".
To test all possible SSL protocols, I created the following script, which is then executed by travis-ci:
<?php
$sslVersions = [
CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1,
CURL_SSLVERSION_TLSv1_0,
CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2,
CURL_SSLVERSION_SSLv2,
CURL_SSLVERSION_SSLv3,
];
var_dump(curl_version());
foreach ($sslVersions as $sslVersion) {
$uri = "https://api.reporting.cloud";
printf("Trying %d", $sslVersion);
echo PHP_EOL;
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_VERBOSE , true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt($ch, CURLOPT_TIMEOUT , 2);
curl_setopt($ch, CURLOPT_SSLVERSION , $sslVersion);
if (curl_exec($ch) === false) {
var_dump(curl_error($ch));
} else {
curl_close($ch);
}
echo PHP_EOL;
echo PHP_EOL;
}
exit(1);
The output of this script in my development environments is:
array(9) {
["version_number"]=>
int(468480)
["age"]=>
int(3)
["features"]=>
int(182173)
["ssl_version_number"]=>
int(0)
["version"]=>
string(6) "7.38.0"
["host"]=>
string(19) "x86_64-pc-linux-gnu"
["ssl_version"]=>
string(14) "OpenSSL/1.0.1t"
["libz_version"]=>
string(5) "1.2.8"
["protocols"]=>
array(21) {
[0]=>
string(4) "dict"
[1]=>
string(4) "file"
[2]=>
string(3) "ftp"
[3]=>
string(4) "ftps"
[4]=>
string(6) "gopher"
[5]=>
string(4) "http"
[6]=>
string(5) "https"
[7]=>
string(4) "imap"
[8]=>
string(5) "imaps"
[9]=>
string(4) "ldap"
[10]=>
string(5) "ldaps"
[11]=>
string(4) "pop3"
[12]=>
string(5) "pop3s"
[13]=>
string(4) "rtmp"
[14]=>
string(4) "rtsp"
[15]=>
string(3) "scp"
[16]=>
string(4) "sftp"
[17]=>
string(4) "smtp"
[18]=>
string(5) "smtps"
[19]=>
string(6) "telnet"
[20]=>
string(4) "tftp"
}
}
Trying 0
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was NOT found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 1
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 4
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.0 / ECDHE-RSA-AES256-SHA
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:40 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 5
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.1 / ECDHE-RSA-AES256-SHA
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:41 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 6
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
* subject: serialNumber=HRB 25927; 1.3.6.1.4.1.311.60.2.1.3=DE; businessCategory=Private Organization; C=DE; postalCode=28215; ST=Bremen; L=Bremen; street=Admiralstr. 54; O=Text Control GmbH; OU=ReportingCloud; OU=COMODO EV SSL; CN=api.reporting.cloud
* start date: 2016-06-17 00:00:00 GMT
* expire date: 2017-06-17 23:59:59 GMT
* subjectAltName: api.reporting.cloud matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Extended Validation Secure Server CA
* SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.reporting.cloud
Accept: */*
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
* Server Microsoft-IIS/8.5 is not blacklisted
< Server: Microsoft-IIS/8.5
< X-AspNetMvc-Version: 5.2
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Fri, 15 Jul 2016 14:22:41 GMT
< Content-Length: 952
<
* Connection #0 to host api.reporting.cloud left intact
Trying 2
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* OpenSSL was built without SSLv2 support
* Closing connection 0
string(39) "OpenSSL was built without SSLv2 support"
Trying 3
* Rebuilt URL to: https://api.reporting.cloud/
* Hostname was found in DNS cache
* Trying 40.76.93.116...
* Connected to api.reporting.cloud (40.76.93.116) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* Unknown SSL protocol error in connection to api.reporting.cloud:443
* Closing connection 0
string(68) "Unknown SSL protocol error in connection to api.reporting.cloud:443 "
Here, we can clearly see that 'SSL connection using TLSv1.0' is connecting correctly to the backend server.
However, running the same script on travi-ci results in the following:
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_0 - assumed 'CURL_SSLVERSION_TLSv1_0' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 7
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_0 - assumed 'CURL_SSLVERSION_TLSv1_0' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 7
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_1 - assumed 'CURL_SSLVERSION_TLSv1_1' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 8
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_1 - assumed 'CURL_SSLVERSION_TLSv1_1' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 8
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
PHP Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_2 - assumed 'CURL_SSLVERSION_TLSv1_2' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 9
PHP Stack trace:
PHP 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
Notice: Use of undefined constant CURL_SSLVERSION_TLSv1_2 - assumed 'CURL_SSLVERSION_TLSv1_2' in /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php on line 9
Call Stack:
0.0002 241400 1. {main}() /home/travis/build/TextControl/txtextcontrol-reportingcloud-php/demo/ssl-issue.php:0
array(9) {
'version_number' =>
int(464384)
'age' =>
int(3)
'features' =>
int(50749)
'ssl_version_number' =>
int(0)
'version' =>
string(6) "7.22.0"
'host' =>
string(19) "x86_64-pc-linux-gnu"
'ssl_version' =>
string(14) "GnuTLS/2.12.14"
'libz_version' =>
string(7) "1.2.3.4"
'protocols' =>
array(18) {
[0] =>
string(4) "dict"
[1] =>
string(4) "file"
[2] =>
string(3) "ftp"
[3] =>
string(4) "ftps"
[4] =>
string(6) "gopher"
[5] =>
string(4) "http"
[6] =>
string(5) "https"
[7] =>
string(4) "imap"
[8] =>
string(5) "imaps"
[9] =>
string(4) "ldap"
[10] =>
string(4) "pop3"
[11] =>
string(5) "pop3s"
[12] =>
string(4) "rtmp"
[13] =>
string(4) "rtsp"
[14] =>
string(4) "smtp"
[15] =>
string(5) "smtps"
[16] =>
string(6) "telnet"
[17] =>
string(4) "tftp"
}
}
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 1
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 0
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
Trying 2
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* GnuTLS does not support SSLv2
* Closing connection #0
string(29) "GnuTLS does not support SSLv2"
Trying 3
* About to connect() to api.reporting.cloud port 443 (#0)
* Trying 40.76.93.116... * connected
* found 164 certificates in /etc/ssl/certs/ca-certificates.crt
* gnutls_handshake() failed: A TLS packet with unexpected length was received.
* Closing connection #0
string(76) "gnutls_handshake() failed: A TLS packet with unexpected length was received."
I also noticed that the constants CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1 and CURL_SSLVERSION_TLSv1_2 are not available on travis-ci's PHP 5.6, nor PHP 7 versions.
To summarize, I have looped through all possible CURL_SSLVERSION_* constants and not one single one allows me to connect to api.reporting.cloud on travis-ci, regardless of which PHP version I use.
Does anyone have any suggestions on how I can connect to api.reporting.cloud from travis-ci?