Bug #84507 Server starts w/ unusable SSL context if server-cert.pemis expired
Submitted: 15 Jan 2017 13:05 Modified: 9 Jul 2019 17:39
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Won't fix Impact on me:
None 
Category:MySQL Server: Security: Encryption Severity:S3 (Non-critical)
Version:5.7.17 OS:Any
Assigned to: CPU Architecture:Any
Tags: SSL, tls, yassl

[15 Jan 2017 13:05] Daniël van Eeden
Description:
If the server.pem file in the datadir has an 'Not After' date which is in the past then the server starts without returning an error or warning. However all SSL connections fail.

How to repeat:
Place a set of pem files in the datadir (ca.pem, server-key.pem, server-cert.pem) of which only the server-cert.pem is expired.

The server starts. There is no warning written to the error log.
The only SSL related messages are these:
2017-01-15T12:41:14.705391Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2017-01-15T12:41:14.705765Z 0 [Warning] CA certificate ca.pem is self signed.

Looking at have_ssl everything looks fine..

mysql> show global variables like '%ssl%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
9 rows in set (0.01 sec)

But the first weird thing is that Ssl_server_not_after remains empty.

mysql> show global status like '%ssl%';
+--------------------------------+---------+
| Variable_name                  | Value   |
+--------------------------------+---------+
| Com_show_processlist           | 0       |
| Ssl_accept_renegotiates        | 0       |
| Ssl_accepts                    | 0       |
| Ssl_callback_cache_hits        | 0       |
| Ssl_cipher                     |         |
| Ssl_cipher_list                |         |
| Ssl_client_connects            | 0       |
| Ssl_connect_renegotiates       | 0       |
| Ssl_ctx_verify_depth           | 0       |
| Ssl_ctx_verify_mode            | 0       |
| Ssl_default_timeout            | 0       |
| Ssl_finished_accepts           | 0       |
| Ssl_finished_connects          | 0       |
| Ssl_server_not_after           |         |
| Ssl_server_not_before          |         |
| Ssl_session_cache_hits         | 0       |
| Ssl_session_cache_misses       | 0       |
| Ssl_session_cache_mode         | Unknown |
| Ssl_session_cache_overflows    | 0       |
| Ssl_session_cache_size         | 0       |
| Ssl_session_cache_timeouts     | 0       |
| Ssl_sessions_reused            | 0       |
| Ssl_used_session_cache_entries | 0       |
| Ssl_verify_depth               | 0       |
| Ssl_verify_mode                | 0       |
| Ssl_version                    |         |
+--------------------------------+---------+
26 rows in set (0.01 sec)

This is a MySQL 5.7.17 build w/ WITH_SSL=bundled (YaSSL).

If I look at a handshake with wireshark I see this:
S → C: Server Greeting (ssl flag set)
C → S: Login Request (ssl flag set)
S → C: Bad handshake

Instead of the 'Bad handshake' I expected the server to start an SSL/TLS handshake with an expired SSL certificate, which the client would then reject.

Suggested fix:
Make sure the ssl context is usable.

Not enabling SSL would have been better than enabling a broken SSL context.

Option 1:
  Detect the expired certificate (or unusable SSL context)
  Log an error to the error log about that
  Disable SSL and startup

Option 2:
  Detect the expired certificate
  Somehow force loading of the certificate to make the context usable
  Log a warning to the error log
  Enable SSL and startup
  Let the client decide if it wants to trust the certificate (and connection)

Note that 2 is somewhat similar to what happens if the certificate expires while the server is running.

Related to:
Bug #84300 	Setting to disable checking of "Not After" for replication with SSL/TLS
[15 Jan 2017 13:07] Daniël van Eeden
A server compiled with OpenSSL will just load the certificate.
[17 Jan 2017 6:35] MySQL Verification Team
Hello Daniël,

Thank you for the report.
Verified as described.

Thanks,
Umesh
[9 Jul 2019 17:39] Paul DuBois
Posted by developer:
 
This is a yaSSL issue. yaSSL support is removed as of MySQL 5.6.46/5.7.28, so this bug is being closed with no action taken.