Bug #91969 client certificate is being validated even if client authentication is disabled
Submitted: 10 Aug 2018 16:20 Modified: 19 Jun 2021 0:32
Reporter: kriti suwalka Email Updates:
Status: No Feedback Impact on me:
None 
Category:MySQL Server: Security: Encryption Severity:S4 (Feature request)
Version:5.7.17 OS:Any
Assigned to: CPU Architecture:Any
Tags: Client Cert, MySQL, SSL

[10 Aug 2018 16:20] kriti suwalka
Description:
We are trying to connect to SSL enabled MySQL DB('5.7.17-enterprise-commercial-advanced'). Client authentication is not enabled on server side. We are using MySQL JDBC driver version 8.0.12 to connect to mentioned DB. We are providing all the required SSL related connection properties as mentioned in https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-propertie... documentation.

When we don't provide clientCertificateKeyStoreUrl, connection goes through fine. But when we provide clientCertificateKeyStoreUrl, connection fails and reason being the provided certificate is not signed by a CA which is trusted by server.Connection fails with below error

The last packet successfully received from the server was 128 milliseconds ago. The last packet sent successfully to the server was 120 milliseconds ago.

Looking at the stack trace reveals that reason is unknown CA

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:188)

Now the question is if client authentication is not enabled on server, why the client certificate is being validated ? It shouldn't matter whether I provide a client certificate or not, server shouldn't validate it since it wasn't instructed to do so. We have checked with Oracle DB as well and there client certificate is not validated when client authentication is disabled even if certificate is provided and that is the expected behavior. Unfortunately MySQL doesn't behave in the same way.

We have enabled end to end SSL at our application level and we have set JVM level SSL related SSL paramaters(useSSL, verifyserverCertificate, TrustStore, Keystore) to achieve that. For one of the project under that application, we are trying to connect to SSL DB which has client authentication disabled and we are setting all the required JDBC connection parameters in JDBC connection string. since keystore is not required, we are not setting clientCertificateKeyStoreUrl in the connection string so the keystore property set at the JVM level is taking effect and that certificate is passed to driver. But connection fails with unknown_ca error as described above. It is causing a serious issue for us. hope it clarifies the issue and why it is critical.

How to repeat:
Attaching a standalone code to reproduce the issue.
[14 Aug 2018 6:42] Alexander Soklakov
Hi Kriti,

The problem can be on a client side. When you provide a client certificate via keyStore you also need to provide it's CA via trustStore because JVM also tries to validate it.

So, did you put this CA to your app-truststore.jks?
[14 Aug 2018 6:45] Alexander Soklakov
Please check https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html describing truststore and keystore preparation.
[14 Aug 2018 7:04] Alexander Soklakov
OTOH it could really happen on server side. Please clarify what does the "client authentication is not enabled on server side" mean, what is the server SSL configuration?
[20 Aug 2018 16:31] kriti suwalka
I have not created a user using "Require x509" so as per below article
https://dev.mysql.com/doc/refman/8.0/en/create-user.html#create-user-tls
client authentication is not enabled meaning client certificate won't be authenticated.

My question is if DB user is not created using "Require x509", why server is trying to validate client certificate ? Ideally it should skip it.
[23 Aug 2018 15:12] MySQL Verification Team
Hi,

In order to diagnose the problem, we need full server's configuration, including a full SSL configuration.
[24 Aug 2018 3:59] kriti suwalka
Could you be more specific in terms of what all details you need from server configuration ?
[24 Aug 2018 12:09] MySQL Verification Team
Hi,

First of all, see if the problem persists with 5.7.22, as there are many bugs fixed interim.

Second, please upload your server's my.cnf to this bug report, by using "Files" tab. That way your configuration will be viewable only by Oracle employees.
[28 Aug 2018 4:51] kriti suwalka
Hi,

We currently don't have any SSL enabled instance with 5.7.22 version. I am attaching my.cnf file as requested for the current server we faced issue with. Meanwhile we will try to setup a 5.7.22 server with SSL.
[28 Aug 2018 12:30] MySQL Verification Team
Hi,

Please try 5.7.22 and also reply to all other question that are asked in this page by our Alexander Soklakov.

Thanks in advance.
[29 Aug 2018 11:51] MySQL Verification Team
Hi,

We managed to reproduce your test case even with the latest 5.7 release of our server and client. That is, client cert not signed by server's CA does not work.

Note that the opposite direction (server's cert not signed by the client CA) works just fine.

We think that the server always verifies the certificates provided by users. And there's no way to tell it not to (as we have on the client via --ssl-mode).

Note that this is a safe assumption to make too.

Based on this  evidence, we concluded that this report is a feature request. 

Verified as a feature request.
[19 May 2021 0:32] Filipe Silva
As explained before, as long as there is a client key/certificate configured in Java system wide or through Connector/J `clientCertificateKeyStoreUrl` option, the client certificate is sent automatically while negotiating the secure socket with the server. The server, for its part, must be able to validate such certificate.

The client certificate validation you are talking about happens in a latter phase, when the secure socket is already established, so not enabling it has no effect on this process.

Currently there is a solution for this but it won't be implemented in Connector/J 5.1 since it is EOL now. Connector/J 8.0.22 introduced two new connection options that should do what you are requesting - `fallbackToSystemTrustStore` and `fallbackToSystemKeyStore`. Namely, setting `fallbackToSystemKeyStore=false` should do what you need. See details in https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-security.html

Please give it a try and let us know if it works for you.
[19 Jun 2021 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".