0
votes

Just figured this out and wanted to share.

I am able to connect to MySQL using SSL with the PHP PDO from my local machine. The same code fails when run from a Google Compute Engine instance. I know the certs and IP address are setup correctly because connecting via the MySQL command line client using SSL on the instance works perfectly.

MySQL command line works on Compute:

mysql --ssl-ca=server-ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem \ --host=111.111.111.111 --user=someuser --password

PHP PDO does not work on Compute:

<?php
new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase', 
          'someuser', 
          'somepassword,
          array(
             PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
             PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem',
             PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem'
            )
        );

PDO gives this error on Compute:

PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2026] SSL connection error: ASN: bad other signature confirmation'

2

2 Answers

0
votes

Remove the CA cert from the PDO connection. Remove this key/value from the array:

PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem'

Like so:

<?php
new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase', 
          'someuser', 
          'somepassword,
          array(
             PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
             PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem'
            )
        );

PDO with SSL will silently fail back to an insecure connection under certain conditions. To test that SSL is working run this query on the connection:

SHOW STATUS LIKE 'Ssl_cipher';

It should return something like:

 Ssl_cipher => DHE-RSA-AES256-SHA

Otherwise the it will return an empty value.

0
votes

Just add one more PDO attribute (as per comments by Desislav Kamenov in http://php.net/manual/en/ref.pdo-mysql.php) into your array so that your PDO becomes ...

new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase',
      'someuser',
      'somepassword',
      array(
         PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
         PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem',
         PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem',
         PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
      )
    );