Edit report at https://bugs.php.net/bug.php?id=68344&edit=1
ID: 68344
Comment by: arekm at maven dot pl
Reported by: james at jamesreno dot com
Summary: MySQLi does not provide way to disable peer
certificate validation
Status: No Feedback
Type: Bug
Package: MySQLi related
Operating System: NA
PHP Version: 5.6.2
Assigned To: mysql
Block user comment: N
Private report: N
New Comment:
"nicely sets GET_VER_OPT("verify_peer") and
GET_VER_OPT("verify_peer_name")) to 0, which is fine."
or rather these are 0 by default.... so default context options are actually not being passed here
:-/
Previous Comments:
------------------------------------------------------------------------
[2015-08-10 07:51:01] arekm at maven dot pl
Ok, the problem comes from generic openssl code:
ext/openssl/xp_ssl.c, apply_peer_verification_policy() function
must_verify_peer = GET_VER_OPT("verify_peer")
? zend_is_true(*val)
: sslsock->is_client;
has_cnmatch_ctx_opt = GET_VER_OPT("CN_match");
must_verify_peer_name = (has_cnmatch_ctx_opt || GET_VER_OPT("verify_peer_name"))
? zend_is_true(*val)
: sslsock->is_client;
Now code:
$opts = array('ssl'=>array('verify_peer'=> false,
'verify_peer_name' => false));
stream_context_set_default($opts);
nicely sets GET_VER_OPT("verify_peer") and GET_VER_OPT("verify_peer_name")) to
0, which is fine.
Unfortunately above code fallback to sslsock->is_client which is 1. That means that if we are
client (is_client==1) then openssl extension ignores our verify_peer and verify_peer_name settings.
Why is that? No idea.
If I'm looking correctly then this commit changed behaviour:
commit ce8dc0ede2e8084beef1e7b03c8960e938c8399f
Author: Daniel Lowrey <rdlowrey@php.net>
Date: Fri Feb 14 15:17:30 2014 -0700
Bug #47030 (separate host and peer verification)
Previously it behaved differently for is_client == 1.
------------------------------------------------------------------------
[2015-08-09 20:03:26] arekm at maven dot pl
"Warning: mysqli_real_connect(): Peer certificate CN=.... did not match expected CN" comes
from openssl/xp_ssl.c
That code uses php stream functions like:
stream = php_stream_alloc_rel(&php_openssl_socket_ops, sslsock, persistent_id, "r+");
...
then php_openssl_socket_ops structure has php_openssl_sockop_set_option function which then call few
functions and is some cases raises above error.
apply_peer_verification_policy actually checks verify_peer:
must_verify_peer = GET_VER_OPT("verify_peer")
? zend_is_true(*val)
: sslsock->is_client;
so it should be possible to switch this check off. Unfortunately for me php 5.6.12 is ignoring
setting for this:
$opts = array('ssl'=>array('verify_peer'=> false,
'verify_peer_name' => false));
stream_context_set_default($opts);
$cb = mysqli_init();
mysqli_ssl_set($cb, null, null, null, null, null);
mysqli_real_connect($cb,$db_host, $db_user, $db_pass, $db_name, false, false, MYSQLI_CLIENT_SSL)
and yet I'm getting
"Warning: mysqli_real_connect(): Peer certificate CN=.... did not match expected CN"
So the question is - why openssl code ignores verify_peer setting from default context?
------------------------------------------------------------------------
[2015-08-07 12:08:28] t dot launer at intershop dot de
I've been watching this bug entry for some time now and actually thought this issue was too
important not to be fixed fast. A number of our systems are affected by this bug, seeing that we
maintain a set of distributed applications and a central MySQL server that hosts all the
company's MySQL database instances with which every application server (OTRS, Wikis, ...) must
communicate via X509. I simply cannot upgrade their PHP to 5.6 because that required abandoning our
security policy.
I agree with "spam2 at rhsoft dot net" in that it is a security measure to create server
and client certificates from a CA that is hidden to everyone.
Please consider fixing this bug in 5.6 soon - or at least make the 5.5 functionality available as
option again in version 7.
------------------------------------------------------------------------
[2015-08-07 07:31:24] spam2 at rhsoft dot net
and another month is gone where peole which using encryption for anything which make sit to a
ethernet cable the last years CAN NOT UPGRADE TO PHP 5.6 - holy crap mysql encryption in general
broke repeatly without even push a fixing update in a tiemly manner, now it's broken again -
that's all a joke
------------------------------------------------------------------------
[2015-07-10 10:17:29] spam2 at rhsoft dot net
stream_context_set_default(array('ssl'=>array('verify_peer'=>false,
'verify_peer_name'=>false, 'allow_self_signed'=>true))); has to work
anyways but it does not
http://php.net/manual/de/function.stream-context-set-default.php
Set the default stream context which will be used whenever file operations (fopen(),
file_get_contents(), etc...) are called without a context parameter. Uses the same syntax as
stream_context_create()
is pretty clear in the documentation and so PHP is once again not consistent, but that should
anyways be only a temporary workaround because in production environments you want the peer
verification for file_get_contents() to remote server and using stream_context_set_default() for the
sake of mysql-over-tls would disable that too
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=68344
--
Edit this bug report at https://bugs.php.net/bug.php?id=68344&edit=1