diff --git a/src/Network/Socket.php b/src/Network/Socket.php index ca954d668eb..17b8cea4a03 100644 --- a/src/Network/Socket.php +++ b/src/Network/Socket.php @@ -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 ]; @@ -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()); diff --git a/tests/TestCase/Network/SocketTest.php b/tests/TestCase/Network/SocketTest.php index 84d3751bedf..e937ab53fe2 100644 --- a/tests/TestCase/Network/SocketTest.php +++ b/tests/TestCase/Network/SocketTest.php @@ -374,11 +374,23 @@ 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 * @@ -386,7 +398,6 @@ public function testEnableCryptoExceptionDisableTwice() */ public function testEnableCryptoEnableStatus() { - // testing on tls server $this->_connectSocketToSslTls(); $this->assertFalse($this->Socket->encrypted); $this->Socket->enableCrypto('tls', 'client', true);