Edit report at https://bugs.php.net/bug.php?id=47030&edit=1
ID: 47030
Updated by: rdlowrey@php.net
Reported by: avb@php.net
Summary: SSL context option 'CN_match' useless without
'verify_peer'
-Status: Assigned
+Status: Closed
Type: Bug
Package: OpenSSL related
Operating System: Windows Vista
PHP Version: 5.2.8
Assigned To: pajoye
Block user comment: N
Private report: N
New Comment:
This has been addressed in the 5.6 development branch and master via the linked pull request.
As of 5.6 all client streams verify peers and host names by default. Peer certificate verification
(via CAs) and host name verification (via CN and SAN) are now independent of one another. As these
changes rely heavily on other features introduced in 5.6 you probably shouldn't hold your
breath waiting for them to be back-ported to older versions.
<?php
$uri = '';
$flags = STREAM_CLIENT_CONNECT;
$ctx = stream_context_create(['ssl' => [
'verify_peer' => false, // defaults to true for clients (as of 5.6)
'verify_host' => true, // defaults to true for clients (new in 5.6)
'CN_match' => 'somename.com' // <-- override the URI host name
]]);
$client = stream_socket_client($uri, $errno, $errstr, $timeout, $flags, $ctx);
Previous Comments:
------------------------------------------------------------------------
[2009-09-20 09:14:28] avb@php.net
It may also be a good idea to use name explicitly given in CN_match for peer verification instead of
host name stream_socket_client() was called upon. Consider a proxy scenario:
<php
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => true,
'CN_match' => 'sourceforge.net'
)
));
// connecting to proxy
$stream = stream_socket_client(
'tcp://proxy.example.com:3128', $errno, $errstr, 10,
STREAM_CLIENT_CONNECT, $context
);
// establishing the tunnel
fwrite($stream, 'CONNECT sourceforge.net ...');
// ... read proxy response
// establish crypto
stream_socket_enable_crypto(
$stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT
);
?>
This script will fail now since proxy.example.com obviously doesn't match the certificate for
sourceforge.net
------------------------------------------------------------------------
[2009-01-07 18:17:54] pajoye@php.net
I will take a look at that asap.
------------------------------------------------------------------------
[2009-01-07 17:33:15] avb@php.net
Description:
------------
It is currently impossible to only perform a check that the host name matches Common Name in SSL
certificate. If 'verify_peer' is off, then the check is not performed, while documentation
does not mention that these context options are dependent.
Note that cURL extension behaves as expected, the script
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_URL, 'https://sf.net/');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
if (!curl_exec($ch)) {
echo "Error #" . curl_errno($ch) . ": " . curl_error($ch);
}
?>
outputs the following:
Error #51: SSL: certificate subject name 'sourceforge.net' does not match target host name
'sf.net'
Reproduce code:
---------------
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'CN_match' => 'sf.net'
)
));
$stream = stream_socket_client('ssl://sf.net:443', $errno, $errstr, 10,
STREAM_CLIENT_CONNECT, $context);
if ($stream) {
echo "Stream connected OK\r\n";
}
Expected result:
----------------
Some error message that certificate name 'sourceforge.net' does not match expected
'sf.net'
Actual result:
--------------
Stream connected OK
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=47030&edit=1