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

From: Date: Wed, 14 Mar 2018 23:45:43 +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-214364@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:         spam2 at rhsoft dot net
 Reported by:        james at jamesreno dot com
 Summary:            MySQLi does not provide way to disable peer
                     certificate validation
 Status:             Closed
 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 code is only using the CA

i used from day one client AND server certificates with the same ca-cert

1) ca.crt
2) server.pem (cert+key)
3) client.epm (cert+key)

when you roll out a new CA and new certificates they need to match in such a setup meaning until you
restart mysqld with the new ca/crt/key you can't connect with the new client-pairs - and in
such a setup any verification on the php side is pointless (no idea about PDO anyways - i wrote my
own database layer long before it existed at all)


Previous Comments:
------------------------------------------------------------------------
[2018-03-14 23:30:35] mp at webfactory dot de

Here's a script I tried on PHP 7.1.11-0ubuntu0.17.10.1.

<?php
$pdo = new PDO('mysql:host=...;dbname=...', 'user', 'pass', array(
    PDO::MYSQL_ATTR_SSL_CA => '/path/to/my/ca.pem',
    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true
    )
);
$statement = $pdo->query("SHOW SESSION STATUS LIKE 'ssl_cipher';");
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) print_r($row);
?>

When PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true, then

- I will get "PHP Fatal error:  Uncaught PDOException: PDO::__construct(): Peer certificate
CN=development-vm' did not match expected CN=127.0.0.1'" when the ca.pem
is the one that signed the server's cert, but the hostname does not match

- I will get "PHP Fatal error:  Uncaught PDOException: PDO::__construct(): SSL operation failed
with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed" when I use a
different ca.pem

- I will get "PHP Fatal error:  Uncaught PDOException: failed loading cafile stream: ..."
when I provide an invalid ca.pem path.

When PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false, in all three cases (sic!) it will
successfully establish a connection and show "DHE-RSA-AES256-SHA" as the cipher in use.

The only explanation I have for this is that with PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT set to
"false", the client will use SSL *but* accept *any* certificate the server provides.

------------------------------------------------------------------------
[2018-03-14 22:55:16] spam2 at rhsoft dot net

no it does not, when i deploy new ca/cert/keys pairs and mysqld did not get started no connection is
possible at all until both sides have a certificate from the new self signed CA

------------------------------------------------------------------------
[2018-03-14 22:40:59] mp at webfactory dot de

I understand that this request was initially about disabling the check that the host name
you're connecting matches the CN provided in the server's X509 cert. 

In other words, what is desired is to make sure that the server is providing a cert signed by the
given CA, but ignore whatever CN it has.

We now have MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT in mysqli and the (undocumented?)
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT. 

I am under the impression that they actually do what has been documented, namely "disables
validation of the provided SSL certificate".

So, this does NOT disable only name verification, but COMPLETELY DISABLES certificate checking.

------------------------------------------------------------------------
[2016-12-14 23:24:50] mjmetz at ualberta dot ca

I feel the PHP documentation should be clearer on what this actually does.

http://php.net/manual/en/mysqli.real-connect.php#refsect1-mysqli.real-connect-parameters

MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT 

It currently says:
    Like MYSQLI_CLIENT_SSL, but disables validation of the provided SSL certificate. This is only
for installations using MySQL Native Driver and MySQL 5.6 or later.

But it should highlight that it just disables Common Name (CN) verification but still verifies the
certificate with the CA (if a CA was given in mysqli::set_ssl()).

A better description would be:
    Like MYSQLI_CLIENT_SSL, but disables Common Name (CN) validation of the provided SSL
certificate. CA validation will still occur if a CA was specified with mysqli::set_ssl(). This is
only for installations using MySQL Native Driver and MySQL 5.6 or later.

------------------------------------------------------------------------
[2016-10-13 08:37:32] jimmmaaay at hotmail dot com

MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT is missing from PHP 7

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


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


Thread (57 messages)

« previous php.bugs (#214364) next »