When I try to connect MySQL server (hosted by GCP) with SSL on Mac OS, I get the following error. Same code works when I use docker or Windows machine but on Mac OS I get this error.
With the same credentials I am able to connect using MySQL Workbench.
Exception message:
System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call.
---> MySql.Data.MySqlClient.MySqlException (0x80004005): SSL Authentication Error
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+AppleCrypto+SslException: Internal error
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1312
at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1338
Connection string:
server=12.123.123.123;userid=root;password=confidential;database=news;CACertificateFile=Assets/MySqlServer/server-ca.pem;SslCert=Assets/MySqlServer/client-cert.pem;SslKey=Assets/MySqlServer/client-key.pem;SslMode=VerifyCA;
MySQL version: 5.7.14
Operating system: Mac Os
Pomelo.EntityFrameworkCore.MySql version: 3.2.4
Microsoft.AspNetCore.App version: Both 3.1 and 5.0
Other details about my project setup:
C#
services.AddDbContext<RepositoryContext>(options =>
{
options.UseMySql(connectionString, mySqlOptions =>
{
mySqlOptions.ServerVersion(new ServerVersion(new Version(5, 7, 14), ServerType.MySql));
mySqlOptions.CommandTimeout(360);
});
options.EnableSensitiveDataLogging(true);
});
Take a look at issue MacOS Big Sur: Interop+AppleCrypto+SslException in the underlying MySqlConnector repo.
Thank you for the direction. It seems problems are the same. I also updated to Big Sur but unfortunately generating new certificates didn't worked for me. I tried generating CA, Client and Key.
Also I tried to add "TlsCipherSuites" to Connection string fromw the values I got from DB. But I got an error saying "Option 'tlsciphersuites' not supported."
SHOW GLOBAL VARIABLES where variable_name = 'ssl_cipher'
Added values to Connection string
TlsCipherSuites=ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,AES128-GCM-SHA256,AES128-SHA,AES256-SHA,DES-CBC3-SHA
I tried generating CA, Client and Key.
@kocburak If you generated a new CA certificate, you will also need to create a new server certificate using the new CA.
After that, if connecting with using the client certificate and key does not work, try connecting without them by only specifying the CA (which still verifies that the server is authentic, by using the CA).
I did some tests on Big Sur and ran into .NET related issues when it came to client certificates (but I had the same issues on Catalina, which is a PlatformNotSupportedException because MySqlConnector uses the RSACryptoServiceProvider(CspParameters) constructor in its ServerSession.InitSslAsync() method, which is only supported on Windows; /cc @bgrainger), but none when just using the CA. I should mention that I did try to regenerate any certificates yet. These are older certificates from a server that is about 2 years-old.
I used the following code for testing (with MySqlConnector 0.69.10 and EF Core 3.1.10 on .NET 5.0.0):
```c#
using System;
using System.Data;
using System.Diagnostics;
using MySql.Data.MySqlClient;
namespace Issue1272_01
{
internal static class Program
{
private static void Main(string[] args)
{
var csb = new MySqlConnectionStringBuilder
{
Server = "
Port = 3306,
UserID = "
Password = "
Database = "
SslMode = MySqlSslMode.VerifyCA,
SslCa = "ca.pem",
//SslCert = "client-cert.pem",
//SslKey = "client-key.pem",
};
using var connection = new MySqlConnection(csb.ConnectionString);
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = "SHOW SESSION STATUS LIKE 'Ssl_cipher'";
string sslCipherUsed = null;
var reader = command.ExecuteReader();
if (reader.HasRows)
{
if (reader.Read())
{
sslCipherUsed = reader.GetString("Value");
}
}
Trace.Assert(connection.State == ConnectionState.Open);
Trace.Assert(!string.IsNullOrEmpty(sslCipherUsed));
Console.WriteLine(sslCipherUsed);
}
}
}
```
I tried generating CA and after Client Cert and Key but no luck. Also tried VerifyCA and the error stayed same. After that, I tried on EF 5.0.0-alpha2.
@kocburak If you generated a new CA certificate, you will also need to create a new server certificate using the new CA
I tried generating CA and after Client Cert and Key but no luck.
If you create a new CA certificate, you will also need to generate a new server certificate, not just a new _client_ certificate.
After that, if connecting with using the client certificate and key does not work, try connecting without them by only specifying the CA (which still verifies that the server is authentic, by using the CA).
Have you tried this suggestion I made? (Meaning to not specify any client certificate or key at all, as can be seen in my sample code.)
Yes for both of them. After generating new CA, I downloaded the server-ca.pem and create a new client certificate. than also download the client-ket.pem and client-cert.pem . That didn't work either so I tried switching to VerifyCA mode while removing client cert and key from ConnectionString and the error persisted. Also tried VerifyCA with adding Client cer and key.
Edit: I would expected when I generate a new CA and Client, Clients are generated from new CA. But it seems not. Until I rotate the CA (in favor of breaking live server) new client certs does not seems to be affected from new CA.
Yes for both of them. After generating new CA, I downloaded the server-ca.pem
Sorry if I am still on that part, but you again did not write, that you generated a new server-cert.pem & server-key.pem. You only wrote, that you generated a new ca.pem & ca-key.pem (kind of: you wrote that you generated and downloaded the new server-ca.pem, so it is not really clear, whether you meant the server certificate or the CA certificate). If you generate a new ca.pem & ca-key.pem, then you will also need to create a new server-cert.pem & server-key.pem, using the newly created ca.pem.
Feel free to dump the commands you used and run the following commands to ensure, that your certificates are as expected:
openssl verify -CAfile ca.pem server-cert.pem
openssl verify -CAfile ca.pem client-cert.pem
In addition to that, have you tried the TLS connection without the VerifyCA option and without a client certificate?
I am using Google Cloud MySql. I didn't run any console command. When I generate a new CA Certificate, Google does not share the CA-key. It only shares the. CA Certificate. And when I tried to generate new client certificate and key, I assumed Google generates these new Client certificates based on the most recent generated CA. But it seems not. In order to generate new clients certificates from the most recent CA, The previous CA should be revoked. That was the confusion on my side.
@kocburak I added some sample code (you can run on Big Sur) to try to diagnose the underlying issue here: https://github.com/mysql-net/MySqlConnector/issues/908#issuecomment-744653331
The resolution can be found in https://github.com/mysql-net/MySqlConnector/issues/908#issuecomment-744653331 ff.
Most helpful comment
Sorry if I am still on that part, but you again did not write, that you generated a new
server-cert.pem&server-key.pem. You only wrote, that you generated a newca.pem&ca-key.pem(kind of: you wrote that you generated and downloaded the newserver-ca.pem, so it is not really clear, whether you meant the server certificate or the CA certificate). If you generate a newca.pem&ca-key.pem, then you will also need to create a newserver-cert.pem&server-key.pem, using the newly createdca.pem.Feel free to dump the commands you used and run the following commands to ensure, that your certificates are as expected:
In addition to that, have you tried the TLS connection without the
VerifyCAoption and without a client certificate?