Skip to content

Commit 2757a06

Browse files
committed
Custom TLS config support in the driver
This is pretty rudimentary, but good enough to start a PR and review/discussion for how it should end up. - There is just a single custom config called `custom` - A program using the driver can only have one custom config. That "works for me", but for people using the driver in a single program to communicate with different endpoints that probably isn't going to work - Adds a basic "wrapper" function `SetCustomTLSConfig` which passes through to `NewClientTLSConfig`. This means just the driver can be imported. To use this you'd do: ``` import ( "database/sql" "net/url" "github.com/go-mysql-org/go-mysql/driver" // full import required ) [...] var ( CaPem = []byte(`-----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE-----`) ) [...] // CA and domain, no Cert and Key driver.SetCustomTLSConfig(CaPem, make([]byte, 0), make([]byte, 0), false, "my.domain.com") [...] ```
1 parent 1aca068 commit 2757a06

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

client/tls.go

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ func NewClientTLSConfig(caPem, certPem, keyPem []byte, insecureSkipVerify bool,
1515

1616
var config *tls.Config
1717

18+
// Allow cert and key to be optional
19+
// Send through `make([]byte, 0)` for "nil"
1820
if string(certPem) != "" && string(keyPem) != "" {
1921
cert, err := tls.X509KeyPair(certPem, keyPem)
2022
if err != nil {
@@ -36,3 +38,4 @@ func NewClientTLSConfig(caPem, certPem, keyPem []byte, insecureSkipVerify bool,
3638

3739
return config
3840
}
41+

driver/driver.go

+23-19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package driver
44

55
import (
6+
"crypto/tls"
67
"database/sql"
78
sqldriver "database/sql/driver"
89
"fmt"
@@ -15,14 +16,11 @@ import (
1516
"github.com/siddontang/go/hack"
1617
)
1718

19+
var customTLSConfig *tls.Config
20+
1821
type driver struct {
1922
}
2023

21-
// Testing custom tls by hard-coding something in
22-
var CaPem = []byte(`-----BEGIN CERTIFICATE-----
23-
MYCACERT
24-
-----END CERTIFICATE-----`)
25-
2624
// Open: DSN user:password@addr[?db]
2725
func (d driver) Open(dsn string) (sqldriver.Conn, error) {
2826
lastIndex := strings.LastIndex(dsn, "@")
@@ -75,22 +73,22 @@ func (d driver) Open(dsn string) (sqldriver.Conn, error) {
7573
return nil, errors.Errorf("invalid dsn, must user:password@addr[[?db[&param=X]]")
7674
}
7775

78-
custom := client.NewClientTLSConfig(CaPem, make([]byte, 0), make([]byte, 0), false, "custom.host.name")
79-
8076
tlsConfigName, tls := params["ssl"]
8177
if tls {
82-
if tlsConfigName == "true" {
83-
// This actually does insecureSkipVerify
84-
// But not even sure if it makes sense to handle false? According to
85-
// client_test.go it doesn't - it'd result in an error
86-
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) { c.UseSSL(true) })
87-
} else {
88-
// TODO: This is going to be trickier. Need a way of taking the
89-
// `tlsConfigName` which is a string type and using that to point at the actual
90-
// `tlsConfig` which is a `NewClientTLSConfig` type. Can probably draw
91-
// inspiration from go-sql-driver/mysql
92-
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) {c.SetTLSConfig(custom)})
93-
//return nil, errors.Errorf("Custom TLS configuration support not implemented yet")
78+
switch tlsConfigName {
79+
case "true":
80+
// This actually does insecureSkipVerify
81+
// But not even sure if it makes sense to handle false? According to
82+
// client_test.go it doesn't - it'd result in an error
83+
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) { c.UseSSL(true) })
84+
case "custom":
85+
// I was too concerned about mimicking what go-sql-driver/mysql does which will
86+
// allow any name for a custom tls profile and maps the query parameter value to
87+
// that TLSConfig variable... there is no need to be that clever. We can just
88+
// insist `"custom"` (string) == `custom` (TLSConfig)
89+
c, err = client.Connect(addr, user, password, db, func(c *client.Conn) {c.SetTLSConfig(customTLSConfig)})
90+
default:
91+
return nil, errors.Errorf("Supported options are ssl=true or ssl=custom")
9492
}
9593
} else {
9694
c, err = client.Connect(addr, user, password, db)
@@ -276,3 +274,9 @@ func (r *rows) Next(dest []sqldriver.Value) error {
276274
func init() {
277275
sql.Register("mysql", driver{})
278276
}
277+
278+
func SetCustomTLSConfig(caPem []byte, certPem []byte, keyPem []byte, insecureSkipVerify bool, serverName string) {
279+
// Basic pass-through function so we can just import the driver
280+
// For now there is a single shared "custom" config. I.e. any program can only have one "custom" config
281+
customTLSConfig = client.NewClientTLSConfig(caPem, certPem, keyPem, insecureSkipVerify, serverName)
282+
}

0 commit comments

Comments
 (0)