Skip to content

Commit

Permalink
Add support for specific TLS versions.
Browse files Browse the repository at this point in the history
We should allow people to specify TLS1.1 or 1.2 if they need it.
Also work around a change in PHP >5.6.7 where TLS_CLIENT only allowed
1.0 and didn't allow clients to negotiate to higher versions of TLS.
  • Loading branch information
markstory committed Oct 18, 2017
1 parent 001504a commit 5b6b990
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
25 changes: 23 additions & 2 deletions src/Network/Socket.php
Expand Up @@ -91,10 +91,16 @@ class Socket
'sslv3_client' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
'sslv23_client' => STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
'tls_client' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
'tlsv10_client' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT,
'tlsv11_client' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT,
'tlsv12_client' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER,
'sslv3_server' => STREAM_CRYPTO_METHOD_SSLv3_SERVER,
'sslv23_server' => STREAM_CRYPTO_METHOD_SSLv23_SERVER,
'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER
'tls_server' => STREAM_CRYPTO_METHOD_TLS_SERVER,
'tlsv10_server' => STREAM_CRYPTO_METHOD_TLSv1_0_SERVER,
'tlsv11_server' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER,
'tlsv12_server' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
// @codingStandardsIgnoreEnd
];

Expand Down Expand Up @@ -431,8 +437,23 @@ public function enableCrypto($type, $clientOrServer = 'client', $enable = true)
if (!array_key_exists($type . '_' . $clientOrServer, $this->_encryptMethods)) {
throw new InvalidArgumentException('Invalid encryption scheme chosen');
}
$method = $this->_encryptMethods[$type . '_' . $clientOrServer];

// Prior to PHP 5.6.7 TLS_CLIENT was any version of TLS. This was changed in 5.6.7
// to fix backwards compatibility issues, and now only resolves to TLS1.0
//
// See https://github.com/php/php-src/commit/10bc5fd4c4c8e1dd57bd911b086e9872a56300a0
if (version_compare(PHP_VERSION, '5.6.7', '>=')) {
if ($method == STREAM_CRYPTO_METHOD_TLS_CLIENT) {
$method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
}
if ($method == STREAM_CRYPTO_METHOD_TLS_SERVER) {
$method |= STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER;
}
}

try {
$enableCryptoResult = stream_socket_enable_crypto($this->connection, $enable, $this->_encryptMethods[$type . '_' . $clientOrServer]);
$enableCryptoResult = stream_socket_enable_crypto($this->connection, $enable, $method);
} catch (Exception $e) {
$this->setLastError(null, $e->getMessage());
throw new SocketException($e->getMessage());
Expand Down
15 changes: 13 additions & 2 deletions tests/TestCase/Network/SocketTest.php
Expand Up @@ -374,19 +374,30 @@ public function testEnableCryptoExceptionEnableTwice()
*/
public function testEnableCryptoExceptionDisableTwice()
{
// testing on tls server
$this->_connectSocketToSslTls();
$this->Socket->enableCrypto('tls', 'client', false);
}

/**
* testEnableCryptoEnableStatus
*
* @return void
*/
public function testEnableCryptoEnableTls12()
{
$this->_connectSocketToSslTls();
$this->assertFalse($this->Socket->encrypted);
$this->Socket->enableCrypto('tlsv12', 'client', true);
$this->assertTrue($this->Socket->encrypted);
}

/**
* testEnableCryptoEnableStatus
*
* @return void
*/
public function testEnableCryptoEnableStatus()
{
// testing on tls server
$this->_connectSocketToSslTls();
$this->assertFalse($this->Socket->encrypted);
$this->Socket->enableCrypto('tls', 'client', true);
Expand Down

0 comments on commit 5b6b990

Please sign in to comment.