|  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-12-14 21:54 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
Have you experienced this issue?
Rate the importance of this bug to you:

 [2021-07-01 12:01 UTC] camille at affinez dot nl
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 -starttls smtp -servername -no_tls1 -no_tls1_1 -no_tls1_2 -no_tls1_3

OpenSSL fails as expected.

Test script:
$SMTPconn = fsockopen("", 25, $error_int, $error_string, 10);
fwrite($SMTPconn, "EHLO " . "" . "\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);

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

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

Actual result:

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


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-01 12:15 UTC]
-Status: Open +Status: Verified
 [2021-07-01 12:28 UTC]
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:
 [2021-07-01 13:33 UTC]
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?
 [2021-12-14 21:54 UTC]
This is actually a bit confusing because we still support method flags. But if an unsupported flag is set, it's just silently ignored. Might be actually worth to consider notice here.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jul 21 10:01:30 2024 UTC