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:
- OpenSSL --starttls mysql implementation
- MySQL Protocol TLS overview
- MySQL SSLRequest by the client after handshake from server
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?