Browse Source

Merge pull request #11338 from cakephp/stream-ssl-versions

Add & Deprecated Stream SSL versions
Mark Story 8 years ago
parent
commit
499fa5a815
2 changed files with 48 additions and 12 deletions
  1. 34 2
      src/Network/Socket.php
  2. 14 10
      tests/TestCase/Network/SocketTest.php

+ 34 - 2
src/Network/Socket.php

@@ -83,18 +83,31 @@ class Socket
     /**
      * Contains all the encryption methods available
      *
+     * SSLv2 and SSLv3 are deprecated, and should not be used as they
+     * have several published vulnerablilities.
+     *
      * @var array
      */
     protected $_encryptMethods = [
         // @codingStandardsIgnoreStart
+        // @deprecated Will be removed in 4.0.0
         'sslv2_client' => STREAM_CRYPTO_METHOD_SSLv2_CLIENT,
+        // @deprecated Will be removed in 4.0.0
         '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,
+        // @deprecated Will be removed in 4.0.0
         'sslv2_server' => STREAM_CRYPTO_METHOD_SSLv2_SERVER,
+        // @deprecated Will be removed in 4.0.0
         '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 +444,27 @@ class Socket
         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) {
+                // @codingStandardsIgnoreStart
+                $method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+                // @codingStandardsIgnoreEnd
+            }
+            if ($method == STREAM_CRYPTO_METHOD_TLS_SERVER) {
+                // @codingStandardsIgnoreStart
+                $method |= STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER;
+                // @codingStandardsIgnoreEnd
+            }
+        }
+
         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());

+ 14 - 10
tests/TestCase/Network/SocketTest.php

@@ -347,7 +347,6 @@ class SocketTest extends TestCase
      */
     public function testEnableCrypto()
     {
-        $this->skipIf(!function_exists('stream_socket_enable_crypto'), 'Broken on HHVM');
         $this->_connectSocketToSslTls();
         $this->assertTrue($this->Socket->enableCrypto('tls', 'client'));
         $this->Socket->disconnect();
@@ -361,7 +360,6 @@ class SocketTest extends TestCase
      */
     public function testEnableCryptoExceptionEnableTwice()
     {
-        $this->skipIf(!function_exists('stream_socket_enable_crypto'), 'Broken on HHVM');
         // testing on tls server
         $this->_connectSocketToSslTls();
         $this->Socket->enableCrypto('tls', 'client');
@@ -376,8 +374,6 @@ class SocketTest extends TestCase
      */
     public function testEnableCryptoExceptionDisableTwice()
     {
-        $this->skipIf(!function_exists('stream_socket_enable_crypto'), 'Broken on HHVM');
-        // testing on tls server
         $this->_connectSocketToSslTls();
         $this->Socket->enableCrypto('tls', 'client', false);
     }
@@ -387,10 +383,21 @@ class SocketTest extends TestCase
      *
      * @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()
     {
-        $this->skipIf(!function_exists('stream_socket_enable_crypto'), 'Broken on HHVM');
-        // testing on tls server
         $this->_connectSocketToSslTls();
         $this->assertFalse($this->Socket->encrypted);
         $this->Socket->enableCrypto('tls', 'client', true);
@@ -404,10 +411,7 @@ class SocketTest extends TestCase
      */
     public function testGetContext()
     {
-        $this->skipIf(
-            !extension_loaded('openssl') || defined('HHVM_VERSION'),
-            'OpenSSL is not enabled cannot test SSL.'
-        );
+        $this->skipIf(!extension_loaded('openssl'), 'OpenSSL is not enabled cannot test SSL.');
         $config = [
             'host' => 'smtp.gmail.com',
             'port' => 465,