denodrivers/mysql

Feature: connect using TLS

EtienneBruines opened this issue · 8 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
}

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

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 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!

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.

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.

@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?

@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

any update on this?