Skip to main content

Fixed: "The certificate is invalid" with MySql.Data

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

The certificate is invalid was about my client certificate, the one VerifyFull needs in SslCert. I'd made it with the usual openssl req -x509, which marks a certificate as a certificate authority on a normal setup, and the driver doesn't accept a CA in that spot.

What I Was Doing​

I was creating a throwaway client pair for SslMode=VerifyFull on MySql.Data 26.10.0, as you need on a server that doesn't issue client certificates, using OpenSSL 4.1 with its default settings:

Terminal
openssl req -x509 -newkey rsa:2048 -nodes -days 3650 -keyout client-key.pem -out client-cert.pem -subj "/CN=not-checked"
openssl rsa -in client-key.pem -traditional -out client-key.pem

Then:

Terminal
dotnet run test-connection.cs

What I Expected​

A connection. An earlier pair, made with an empty OpenSSL configuration, had worked.

What I Got​

Output
Unhandled exception. MySql.Data.MySqlClient.MySqlException (0x80004005): SSL Connection error
---> System.Exception: The certificate is invalid

The test program stopping with SSL Connection error and The certificate is invalid.

What I Checked​

What the certificate says about itself:

Terminal
openssl x509 -in client-cert.pem -noout -ext basicConstraints
Output
X509v3 Basic Constraints: critical
CA:TRUE

CA:TRUE means "this certificate can sign others". openssl req -x509 adds it, from the defaults in openssl.cnf. My earlier pair had no such line, because I'd run it with an empty configuration.

The driver's source, tag 26.10.0. In the PEM validator, the CA file must be a CA, and the client certificate must not be.

Why It Happens​

A client certificate shouldn't be able to sign other certificates, so the driver checks that. On a normal machine, req -x509 produces a CA, because that's what it's mostly used for.

The Fix​

Create the certificate in two steps: a request, then a signature. openssl x509 -req adds no extensions unless you ask for them:

Terminal
openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client.csr -subj "/CN=not-checked"
openssl x509 -req -in client.csr -signkey client-key.pem -days 3650 -out client-cert.pem
openssl rsa -in client-key.pem -traditional -out client-key.pem

Check it:

Terminal
openssl x509 -in client-cert.pem -noout -ext basicConstraints
Output
No extensions in certificate

If your server gave you a client certificate, use that instead. Certificates from MySQL's own client-cert.pem are fine.

After the Fix​

Terminal
dotnet run test-connection.cs
Output
Connected as inventory_app@% to MySQL 9.7.4
TLS: TLSv1.2

The test program printing Connected as inventory_app@% with TLS: TLSv1.2 under SslMode=VerifyFull, with a client certificate made in two steps.

Common Mistakes​

MistakeWhat happensDo this instead
Using ca.pem as SslCertIt's a CA, so it's refusedUse a client certificate
Looking at the keyThis error is about the certificateCheck basicConstraints
Copying a guide that uses req -x509 for clientsIt depends on that machine's openssl.cnfUse the two steps

Troubleshooting​

SymptomLikely causeFix
The specified file cannot be converted to a keyThe third command was skippedThe fix
The specified file cannot be converted to a certificateSslCert points at something elseCheck the file starts with BEGIN CERTIFICATE
certificate expired onThe pair's own dates count tooThe fix

Conclusion​

The certificate is invalid means SslCert holds a certificate marked as a CA. Create it in two steps, without -x509, and it passes.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.