[MDEV-27405] Inconsistent error messages upon missing correct extendKeyUsage purpose in certificates Created: 2022-01-02  Updated: 2023-03-03

Status: Open
Project: MariaDB Server
Component/s: SSL
Affects Version/s: 10.6
Fix Version/s: 10.6

Type: Bug Priority: Minor
Reporter: Hartmut Holzgraefe Assignee: Georg Richter
Resolution: Unresolved Votes: 2
Labels: None

Attachments: File certs_and_conf.tar.gz     File client1.pcap     File client2.pcap    
Issue Links:
Blocks
is blocked by CONC-603 Wrong error handling in TLS read/write Open

 Description   

When configuring TLS on the server side using a x509 v3 certificate with the extendedKeyUsage present, but not including the serverAuth purpose, the server process starts up without any warning.

When trying to connect to such a server clients report

ERROR 2026 (HY000): SSL connection error: unsupported certificate purpose

so it is at least somewhat clear why connections fail.

When the server is set up correctly, but the client wants to use two way TLS and does not have clientAuth in its own certificate set the situation is more tricky though. The client will report

ERROR 2013 (HY000): Lost connection to server at 'sending authentication information', system error: 104

and the server side error log only shows:

[Warning] Aborted connection ... to db: 'unconnected' user: 'unauthenticated' host: '...' (This connection closed normally without authentication)

So in this constellation it is extremely difficult to figure out what the actual cause of the connection failure is.

Tested with 10.6.5



 Comments   
Comment by Sergei Golubchik [ 2022-01-03 ]

What SSL libraries were the server and the client build with?

Comment by Hartmut Holzgraefe [ 2022-01-03 ]

I was testing with our own 10.6 packages on Ubuntu 20.04, so both server and client were using the OpenSSL 1.1.1f system library as far as I can tell.

Older Ubuntus own distro packages that were build against yaSSL 2.4.4 do not seem to care about the extension flags at all.

Now trying with binary tarballs that have wolfSSL instead of yaSSL alredy ...

Comment by Hartmut Holzgraefe [ 2022-01-03 ]

With 10.6.5 binary tarball on Ubuntu 20.04 the server certificate having or not having the serverAuth flag set does not make a difference, but when trying to do a two way connect with a client certificate that does not have clientAuth set I'm now getting:

ERROR 2013 (HY000): Lost connection to server at 'reading authorization packet', system error: 11

from the command line client while the server still logs

[Warning] Aborted connection 9 to db: 'unconnected' user: 'unauthenticated' host: '10.0.2.15' (This connection closed normally without authentication)

So this is WolfSSL 4.8.1 on the server side, and GnuTLS on the client side (not sure how to retrieve that actual version from the statically linked client)

Comment by Vladislav Vaintroub [ 2022-02-07 ]

hholzgra could you please collect the wireshark trace? And the certificate, or instructions how to create such a certificate.

Comment by Hartmut Holzgraefe [ 2022-02-15 ]

I used the attached certs and config, the client1 cert was created with:

basicConstraints=CA:FALSE
keyUsage=digitalSignature
extendedKeyUsage=clientAuth

and the client2 one with

...
extendedKeyUsage=serverAuth

instead.

Trying two-way TLS with client1 certificate works just fine:

$ mysql -h 127.0.0.1 -u user -psecret --ssl --ssl-ca=/vagrant/ssl/ca-cert.pem --ssl-key=/vagrant/ssl/client1-key.pem --ssl-cert=/vagrant/ssl/client1-cert.pem -e "SHOW STATUS LIKE 'Ssl_version'"
+---------------+---------+
| Variable_name | Value   |
+---------------+---------+
| Ssl_version   | TLSv1.3 |
+---------------+---------+

When trying the client2 certificate on the other hand I get

$ mysql -h 127.0.0.1 -u user -psecret --ssl --ssl-ca=/vagrant/ssl/ca-cert.pem --ssl-key=/vagrant/ssl/client2-key.pem --ssl-cert=/vagrant/ssl/client2-cert.pem -e "SHOW STATUS LIKE 'Ssl_version'"
ERROR 2013 (HY000): Lost connection to server at 'reading authorization packet', system error: 0

I attached the pcap files created by "tcpdump -w ...filename... -i lo port 3306" for both the successful and the failing attempt, too.

Comment by Vladislav Vaintroub [ 2022-02-15 ]

I think there is also something that 9EOR9 could do to it too, since server might not be able to send the crystal clear message to the client. In fact, server already send "bad handshake" in clear text, which client is not able to read. At very least client could say that "SSL handshake failed (with client certificate)" instead of "Lost connection to server at 'reading authorization packet'" . The server should probably also do better, but as already mentioned, first thing user sees is the client message.

Comment by Georg Richter [ 2022-07-08 ]

This seems to be happen only using TLSv1.3 where client certificate is checked after handshake.

Server:
SSL_accept() returns -1 and SSL_get_error returns SSL_ERROR_SSL. Instead of retrieving the OpenSSL error, this error is handled as a protocol error (errno=EPROTO):

(gdb) p ssl_error
$1 = 1
(gdb) p ERR_error_string(1, NULL)
$2 = 0x7ffff7cfb1a0 <buf> "error:00000001:lib(0):func(0):reason(1)"
(gdb) p ERR_error_string(ERR_peek_error(), NULL)
$3 = 0x7ffff7cfb1a0 <buf> "error:1417C086:SSL routines:tls_process_client_certificate:certificate verify failed"

On client side SSL_connect() returns success (=1)

Comment by Georg Richter [ 2022-07-08 ]

Partial fix pushed for Connector/C - server still needs to be fixed. (reassigning to wlad)

Comment by Vladislav Vaintroub [ 2022-07-08 ]

Only client-side solution is OK I guess. If this is really fixed on the client, georg, please indicate the versions where it would be fixed, and feel free to close

Comment by Hartmut Holzgraefe [ 2022-07-08 ]

I tend to disagree, this is not the only connector in the world, and there even be client applications using Connector/C but don't forward library error messages properly.

So wearing my "I have to support all of this" hat I'd very much like to see the server report actual reasons for (This connection closed normally without authentication).

Comment by Georg Richter [ 2022-07-09 ]

wlad I didn't close it, since it needs to be fixed in server. The information":tls_process_client_certificate:certificate verify failed" is available and should be written to logs.
Since TLSv1.3 alerts can be send after initial handshake - so read/write error is not a socket error ony, but also an TLS alert. If SSL_get_error() returns SSL_ERROR_SSL server should retrieve the errormsg and write it to log.

Generated at Thu Feb 08 09:52:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.