Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Feature] Passing Certificate in X509Certificate/X509Certificate2 format rather than physical paths #976

Closed
kisalay19 opened this issue Apr 23, 2021 · 11 comments · Fixed by #1061
Milestone

Comments

@kisalay19
Copy link

Currently the MySqlConnectionStringBuilder has the ability to add SSL Certificates which accepts physical paths only.

It would be good if there is a feature added to pass the certificate directly in X509Certificate/X509Certificate2 format as against physical path.

Example :

AS IS

var buiderObject = new MySQLConnectionStringBuilder
{
      ...
      CertificateFile = <PFX file Path>,
      ...
}

TO BE

var buiderObject = new MySQLConnectionStringBuilder
{
      ...
      CertificateFile = new X509Certificate2(...), OR new X509Certificate(...),
      ...
}
@kisalay19 kisalay19 changed the title Passing Certificate in X509Certificate/X509Certificate2 format rather than physical paths [New Feature] Passing Certificate in X509Certificate/X509Certificate2 format rather than physical paths Apr 23, 2021
@bgrainger
Copy link
Member

Properties set on the MySqlConnectionStringBuilder generally have to support being serialised into a string via the ConnectionString property. (Ultimately, MySqlConnection.ConnectionString is the only way to pass these properties through to the code that actually makes the connection.) This serialisation is handled by the DbConnectionStringBuilder base class.

This makes me suspect that it won't actually be possible to pass settings using complex .NET objects. I'm not sure if there's precedent for something similar on another ADO.NET provider.

@loonwong
Copy link

Some ADO.NET providers allow us to perform custom validation of the server certificate, using the RemoteCertificateValidationCallback delegate. This is a very flexible validation method and it would be great to see it in your project.

@bgrainger
Copy link
Member

Do you have links to documentation (for other ADO.NET libraries) of the public API through which this is exposed?

@loonwong
Copy link

@bgrainger
Copy link
Member

Accessing a property on each MySqlConnection object feels inconvenient (you really only want to have to set it once per "connection pool", not on each connection; it may be difficult to access when using Pomelo or some other higher-level library).

#800 (comment) suggests a static callback (for a similar problem); that might also work in this scenario.

@loonwong
Copy link

But this is convenient when each connection is independent of each other and is validated by its own CA. For example, in my data logging software, a user can create an arbitrary number of connections for each destination, whether it is a cloud, a local network, or a dedicated server.

@dotfede
Copy link

dotfede commented Sep 9, 2021

@bgrainger we need this for an azure functions scenario, where filesystem cannot be accessed. I need to be able to pass in a Stream with the certificate data, or otherwise be able to provide a certificate that does not require filesystem access.

@bgrainger
Copy link
Member

@fberasategui Which certificate(s) do you need to supply? Client, server, CA, all of the above?

@michaeljon
Copy link

I'll chime in from our side. When we start our containers, in AWS, we pull the current CA cert chain for the RDS instance dynamically, but we're doing this in code, not in the container's bootstrap. One of our services talks to arbitrary RDS instances and arbitrary database systems (Postgres and MySql typically, but also Aurora-backed stuff) and we wrap the db connection creation in a single place. We're handling this in the PG case using the above. terribly named, UserCertificateValidationCallback in NpgSql. It would be great to have a symmetrical way to handle this for MySql.

@dotfede
Copy link

dotfede commented Oct 7, 2021

@bgrainger sorry for the late reply. For some reason I missed the notification of your message.

So, this is the code I'm currently using:

        private async Task<MySqlConnection> GetConnection()
        {
            var b = new MySqlConnectionStringBuilder
            {
                Server = this.Server,
                UserID = this.UserName,
                Password = this.Password,
                Database = this.Database,
                Port = (uint)this.Port,

                CertificateFile = await GetPfxPath(),
                CertificatePassword = this.PfxPassword
            };

            var connection = new MySqlConnection(b.ConnectionString);

            await connection.OpenAsync();

            return connection;
        }

I resolved the PFX path-based requirement by:

  • Having the PFX file stored in Azure Blob
  • Downloading the file on demand and storing to Path.GetTempPath() with a random filename
  • mapping the connection string to said filename

@bgrainger
Copy link
Member

I've written up an API design for this here: #1056

Please upvote/downvote/comment with any feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

5 participants