[MDEV-28908] Wrong (or at least confusing) documentation and help output for --ssl-verify-server-cert Created: 2022-06-20  Updated: 2022-06-20

Status: Open
Project: MariaDB Server
Component/s: Scripts & Clients, SSL
Affects Version/s: 10.3.35, 10.4.25, 10.5.16, 10.6.8, 10.7.4, 10.8.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Hartmut Holzgraefe Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

mysql --help claims

       •   --ssl-verify-server-cert
 
           Verify server's "Common Name" in its cert against hostname used when
           connecting. This option is disabled by default.

and https://mariadb.com/kb/en/secure-connections-overview/#server-certificate-verification provides similar information.

It turns out though that this option also has an influence on whether certificate expiry date is checked.

I tested with two server instances, both having two host entries, one for names "db1" / "db2" which is a name included in their respective certificates SAN list, and one for names "foo1" / "foo2" which is not listed as a subject alternative name (SAN).

Also the certificate for server db2 has expired.

The following all work:

mysql -u ssl -p... --ssl -h db1 
mysql -u ssl -p... --ssl -h db2 
mysql -u ssl -p... --ssl -h foo1 
mysql -u ssl -p... --ssl -h foo2 

so no certificate validation seems to have happened for either server host name or expiry date.

When adding ssl-ca connections to db1/foo1 work:

mysql -u ssl -p... --ssl --ssl-ca=... -h db1 
mysql -u ssl -p... --ssl --ssl-ca=... -h foo1 

but connections to the db2/foo2 host

mysql -u ssl -p... --ssl --ssl-ca=... -h db2
mysql -u ssl -p... --ssl --ssl-ca=... -h foo2

now fail with
ERROR 2026 (HY000): SSL connection error: certificate has expired

Now trying without ssl-ca but with ssl-verify-server-cert all four fail with
ERROR 2026 (HY000): SSL connection error: self-signed certificate in certificate chain:

mysql -u ssl -pSecret23! --ssl --ssl-verify-server-cert -h db1
mysql -u ssl -pSecret23! --ssl --ssl-verify-server-cert -h db2
mysql -u ssl -pSecret23! --ssl --ssl-verify-server-cert -h foo1
mysql -u ssl -pSecret23! --ssl --ssl-verify-server-cert -h foo2

So ssl-ca is now mandatory, and with that combination both server name and expiry checks are happening. Only this now works:

mysql -u ssl -pSecret23! --ssl --ssl-ca=... --ssl-verify-server-cert -h db1

While this complains about wrong hostname:

mysql -u ssl -pSecret23! --ssl --ssl-ca=... --ssl-verify-server-cert -h foo1

and these two about expired server certificate:

mysql -u ssl -pSecret23! --ssl --ssl-ca=... --ssl-verify-server-cert -h db2
mysql -u ssl -pSecret23! --ssl --ssl-ca=... --ssl-verify-server-cert -h foo2

So aside from just checking for valid server certificate host name ssl-verify-server-cert at least also enables CA chain validation, which is contradicting the documented behavior / purpose of the option.

And explicitly giving ssl-ca does not only enable CA chain validation, but also server certificate expiry checks.



 Comments   
Comment by Hartmut Holzgraefe [ 2022-06-20 ]

Looks as if on the MySQL side this has been refactored quite a bit in MySQL 8.0 with ssl and ssl-verify-server-cert having been replaced with ssl-mode=... which allows more fine grained control about what checks to enforce, e.g. REQUIRED (like --ssl), VERIFY_CA and VERIFY_IDENTITY

https://dev.mysql.com/doc/refman/8.0/en/connection-options.html#option_general_ssl-mode

Generated at Thu Feb 08 10:04:23 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.