Bug #86856 MySQL can return wrong OpenSSL error messages
Submitted: 28 Jun 2017 20:42 Modified: 29 Jun 2017 5:31
Reporter: David Gow (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S3 (Non-critical)
Version:5.7.18, 5.6.36 OS:Any (Compiled w/ OpenSSL)
Assigned to: CPU Architecture:Any
Tags: errormessage, openssl

[28 Jun 2017 20:42] David Gow
Description:
In some cases, the error message returned when an SSL operation fails can be incorrect, giving a message such as the following:
SSL connection error: error:00000001:lib(0):func(0):reason(1)
rather than an actual description of the error.

This is a result of confusion between the error code returned from the SSL_get_error() and ERR_get_error() OpenSSL functions. These functions return different types of errors, and have different namespaces.

ssl_should_retry() in vio/viossl.c can set *ssl_errno_holder to an SSL error, rather than an ERR error like other functions. Other places in the code (for example, the client when printing an error message), will call ERR_error_string_n() or similar to produce a string describing the error. As it will receive an SSL error, rather than the expected ERR error, the message will be incorrect (usually a fallback message like the one above).

How to repeat:
This can be shown by trying to connect to a server whose certificate has the wrong CA.

For example, after starting the server with these flags:
--ssl-ca=$MYSQL_TEST_DIR/std_data/crl-ca-cert.pem
--ssl-key=$MYSQL_TEST_DIR/std_data/crl-server-key.pem
--ssl-cert=$MYSQL_TEST_DIR/std_data/crl-server-cert.pem

One can connect to the server with:
$MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem test -e "SELECT 1"

The connection will fail with the message:
ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)

The connection should fail with the message:
ERROR 2026 (HY000): SSL connection error: error:14090086:SSL 
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

These steps can be automated using the mtr test below (the -master.opt file should contain the aforementioned flags; note also that it'll fail for YaSSL):

--source include/have_ssl.inc
--source include/not_embedded.inc

--echo #
--echo # SSL error messages are incorrect
--echo #

--echo # try to connect with correct CA : should connect
--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/crl-ca-cert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/crl-client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/crl-client-cert.pem test -e "SELECT 1" 2>&1
--source include/have_ssl_communication.inc

--echo # try to connect with the wrong CA : should fail with a useful error message
--error 1
--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem  test -e "SELECT 1" 2>&1

Suggested fix:
Fix ssl_should_retry() to set *ssl_errno_holder to a correct ERR error, by calling ERR_get_error().

Note that the default case of the switch() over ssl_error does clear ERR with ERR_clear_error(), so ERR_get_error() should be called beforehand.
[29 Jun 2017 5:31] MySQL Verification Team
Hello David Gow,

Thank you for the report, test case and feedback!

Thanks,
Umesh
[29 Jun 2017 5:32] MySQL Verification Team
##### 5.7.18
## Community build

ERROR 2026 (HY000): SSL connection error: ASN: bad other signature confirmation

## Commercial build

ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)