Bug #68344 [Com]: MySQLi does not provide way to disable peer certificate validation

From: Date: Wed, 12 Nov 2014 16:58:59 +0000
Subject: Bug #68344 [Com]: MySQLi does not provide way to disable peer certificate validation
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-188569@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68344&edit=1

 ID:                 68344
 Comment by:         james at jamesreno dot com
 Reported by:        james at jamesreno dot com
 Summary:            MySQLi does not provide way to disable peer
                     certificate validation
 Status:             Assigned
 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:

That would work as well, just so long as we could pass in the options.

MySQL exposes a ssl-verify-server-cert option in /etc/my.cnf. Is there a way to make the mysqli
driver read that option from the config and then pass that down through to the streams api layer in
mysqlnd? That would also potentially solve this problem in a more uniform fashion?

Regards,
~james


Previous Comments:
------------------------------------------------------------------------
[2014-11-12 16:42:23] johannes@php.net

Adding the option that way works only for specially crafted applications, not off the shelf apps. On
the other hand I know no generic application (wordpress etc.) offering SSL so maybe that's no
issue. Second issue is whether allowing any stream option will cause issues if users are "too
smart" ... if that is safe my favorite would be a mysqlnd_set_default_stream_context() function
or similar which works for all APIs.

------------------------------------------------------------------------
[2014-11-12 15:16:31] james at jamesreno dot com

Even adding the cert, the problem is the 'peer-name' validity.

We have a cert installed for say "db1.example.com" on our cluster. So long as we connect
to db1.example.com we're golden and everything works. The second we try to connect to a single
node ie: "db1a.wdc01.example.com" the certname validation fails and mysqli is unable to
connect.

What about the ability to pass in a context into mysqli_init($ctx) or new mysqli($ctx) that would
allow you to specify the stream context? Would that option be a good path forward for now?

Regards,
~James

------------------------------------------------------------------------
[2014-11-12 10:49:38] johannes@php.net

I agree we have to export that option from stream layer somehow, this needs a good interface. As a
work-around you should be able to add your own key to your system's key storage.

------------------------------------------------------------------------
[2014-11-04 19:42:01] james at jamesreno dot com

Description:
------------
When the MySQLi extension is compiled against mysqlnd there is no method to disable peer_name
validation. Since MySQL 5.6 now enables peer_name validation by DEFAULT those of us connecting to
servers with self-signed certs via SSL are no longer able too.

I have tried to signal the default ssl stream context to disable peer_name validation but mysqli
extension will NOT honor it.

If the remote-server's name does not match the name you are connecting to (as in, for example,
a mysql cluster and connecting to a single node directly) you will not be able to connect at all in
any way shape or form with mysqli.  -- The old mysql extension is not effected by this change as it
honors the my.cnf mysql client's validation settings.

Test script:
---------------
<?php

stream_context_set_default(array(
        'ssl'   => array(
                'peer_name' => 'generic-server',
                'verify_peer' => FALSE,
                'verify_peer_name' => FALSE,
                'allow_self_signed' => TRUE,
        ),
));

 $mysqli = mysqli_init();
 mysqli_ssl_set($mysqli,"/etc/pki/mysql/client.key","/etc/pki/mysql/client.crt","/etc/pki/mysql/ca-cert.pem",NULL,NULL);
 $conn =
mysqli_real_connect($mysqli,'dbserver.local','test','test1234','',NULL,'',MYSQLI_CLIENT_SSL);
 var_dump($conn);

?>


Expected result:
----------------
I expect to be able to disable peer_name validation for those situations were the certificate name
cant possibly be verified (ie: self-signed certs) and be able to connect to the mysql server.

Actual result:
--------------
MySQLi will NOT connect to mysql server and throws 4 warnings:

Warning: mysqli_real_connect(): Peer certificate CN=generic-server' did not match
expected CN=dbserver.local'
Warning: mysqli_real_connect(): Cannot connect to MySQL by using SSL
Warning: mysqli_real_connect(): [2002]  (trying to connect via tcp://dbserver.local:3306)
Warning: mysqli_real_connect(): (HY000/2002):


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=68344&edit=1


Thread (57 messages)

« previous php.bugs (#188569) next »