mysql icon indicating copy to clipboard operation
mysql copied to clipboard

Feature: connect using TLS

Open EtienneBruines opened this issue 4 years ago • 5 comments

It would be nice if this mysql-driver supported connecting through TLS. This issue (to keep it simple) talks about one-way TLS, not including client-certificates.

Unfortunately, this does not mean it simply works by replacing tcp:// by tls://, as MySQL has its own protocol for that.

Basically, instead of the client immediately replying to the handshake with a HandshakeResponse, it first sends a SSLRequest to the server, then the server calls SSL_connect() which does the TLS handshake, and once a TLS session is up, the client resumes normally with a HandshakeResponse over that upgraded TLS connection.

Useful resources:


This would require some new fields in the ClientConfig:

// Pseudo-code, didn't check the syntax. 

/**
 * Client Config
 */
export interface ClientConfig {
    tls?: {
        // Path to a single file containing the CA certificate chain
        ca?: string;

        // Path to a directory containing the CAs to use, e.g. /etc/ssl/certs/
        caPath?: string;

        // The ssl-mode, one of DISABLED, PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY
        // See https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode
        mode: string = 'PREFERRED';
    }
    // ... and the existing fields
}

EtienneBruines avatar Aug 25 '21 07:08 EtienneBruines

This should be possible using only stable APIs in Deno 1.16.0, due to the stabilization of Deno.startTls.

lucacasonato avatar Nov 11 '21 00:11 lucacasonato

It's now possible to use stable Deno.startTls. Is anyone working on this yet? If not, I'll take a crack at it. I'm hoping to use Planetscale's mysql api with Deno Deploy.

dangdennis avatar Nov 29 '21 16:11 dangdennis

@dangdennis i hacked together a quick spike that works against Planetscale and local mysql with a custom CA. I can share my fork here in a bit!

codeflows avatar Nov 29 '21 17:11 codeflows

Here's my branch with the basic mechanics for getting TLS working.

Examples:

const client = await new Client().connect({
  hostname: "xyz.psdb.cloud",
  tls: {
    enabled: true,
  }
});

// Custom CA for self-signed cert
const client = await new Client().connect({
  hostname: "localhost",
  tls: {
    enabled: true,
    caCertificates: [
      await Deno.readTextFile("./certs/ca.crt")
    ]
  }
});

Things missing:

  • Proper API design?
  • Tests
  • Backwards-compatibility with older versions of deno that don't have startTls

I currently don't have time to work on this any further for at least a couple of weeks, but feel free to use my branch as the basis for a proper implementation.

codeflows avatar Nov 29 '21 20:11 codeflows

Just testing @codeflows TLS branch to connect to PlanetScale Mysql DB to a great success! Thanks @codeflows I hope you can create a PR on this.

nascode avatar Jul 10 '22 08:07 nascode

@codeflows I test the TLS branch to connect to TiDB Cloud. But fail with

error: Uncaught (in promise) Error: Currently cannot support auth method mismatch!
          throw new Error("Currently cannot support auth method mismatch!");

I am not familiar with MySQL protocol and can't find what is going wrong. Could you give me some suggestions?

shiyuhang0 avatar Nov 23 '22 09:11 shiyuhang0

@codeflows I test the TLS branch to connect to TiDB Cloud. But fail with

error: Uncaught (in promise) Error: Currently cannot support auth method mismatch!
          throw new Error("Currently cannot support auth method mismatch!");

I am not familiar with MySQL protocol and can't find what is going wrong. Could you give me some suggestions?

just a guess. this error appears because of deno driver does not handle the switch method case

shiyuhang0 avatar Nov 23 '22 13:11 shiyuhang0

any update on this?

GitHub30 avatar Apr 23 '23 02:04 GitHub30