php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81213 Stream crypto methods SSLv2 and v3 switch to TLS1.0
Submitted: 2021-07-01 12:01 UTC Modified: 2021-07-01 13:33 UTC
From: camille at affinez dot nl Assigned:
Status: Verified Package: OpenSSL related
PHP Version: 8.0.7 OS: Windows, Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: camille at affinez dot nl
New email:
PHP Version: OS:

 

 [2021-07-01 12:01 UTC] camille at affinez dot nl
Description:
------------
Forcing an SMTP encryption channel to either SSLv2 or SSLv3 doesn't work as expected. When creating a network trace with Wireshark, it appears the stream is utilizing TLS1.0 instead.

Google's SMTP servers return a false positive result when forcing SSLv2 and SSLv3, as Google supports TLS1.0 and up.

When testing with Microsoft's 365 SMTP servers, a correct result is given as Microsoft only supports TLS1.2.


Verified with OpenSSL 1.1.1h and the following command:
openssl s_client -connect aspmx.l.google.com:25 -starttls smtp -servername mail.domain.com -no_tls1 -no_tls1_1 -no_tls1_2 -no_tls1_3

OpenSSL fails as expected.

Test script:
---------------
$SMTPconn = fsockopen("aspmx.l.google.com", 25, $error_int, $error_string, 10);
fwrite($SMTPconn, "EHLO " . "tls.php.net" . "\r\n");
while (!feof($SMTPconn)) {
	$line = fgets($SMTPconn);
	$read = array($SMTPconn); $write = null; $except = null; $timeout = 0; $utimeout = 200000;
	if (!stream_select($read, $write, $except, $timeout, $utimeout)) break;
}
fwrite($SMTPconn, "STARTTLS" . "\r\n");
while (!feof($SMTPconn)) {
	$line = fgets($SMTPconn);
	$read = array($SMTPconn); $write = null; $except = null; $timeout = 0; $utimeout = 200000;
	if (!stream_select($read, $write, $except, $timeout, $utimeout)) break;
}
stream_context_set_option($SMTPconn, 'ssl', 'verify_peer', false);
stream_context_set_option($SMTPconn, 'ssl', 'verify_peer_name', false);
stream_context_set_option($SMTPconn, 'ssl', 'allow_self_signed', true);
stream_context_set_option($SMTPconn, 'ssl', 'capture_peer_cert', true);
stream_context_set_option($SMTPconn, 'ssl', 'capture_peer_cert_chain', true);
$res = @stream_socket_enable_crypto($SMTPconn, true, STREAM_CRYPTO_METHOD_SSLv2_CLIENT);
var_dump($res);

Expected result:
----------------
int(0) or bool(false)

The connection should fail, as SSLv2 or SSLv3 are not supported.


Actual result:
--------------
bool(true)

The connection (falsely) succeeds by utilizing TLS1.0 instead of SSLv2 or SSLv3.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-01 12:15 UTC] daverandom@php.net
-Status: Open +Status: Verified
 [2021-07-01 12:28 UTC] daverandom@php.net
I don't have a build environment set up to test this theory, but I suspect this is related to the openssl build that PHP is using having SSL3 disabled: https://github.com/php/php-src/blob/master/ext/openssl/xp_ssl.c#L87-L92
 [2021-07-01 13:33 UTC] cmb@php.net
Right.  This looks more like a docuumentation issue to me.  As of
PHP 7.3.0, the min_proto_version and max_proto_version ssl stream
options have been introduced[1], but are not documented in the
manual proper.

Or would it be preferable to let stream_socket_enable_crypto()
fail if an unsupported version is given, instead of using the
minimal supported version?
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Fri Oct 22 07:03:33 2021 UTC