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-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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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

Pull Requests

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?
 [2021-12-14 21:54 UTC] bukka@php.net
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: Thu Dec 26 19:01:30 2024 UTC