Description
What version of Go are you using (go version
)?
$ go version go version go1.15 darwin/amd64
Does this issue reproduce with the latest release?
Only the latest release.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/kristiandrucker/Library/Caches/go-build" GOENV="/Users/kristiandrucker/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/kristiandrucker/go/pkg/mod" GOOS="darwin" GOPATH="/Users/kristiandrucker/go" GOPROXY="https://proxy.golang.org,direct" GOROOT="/Users/kristiandrucker/sdk/go1.15" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/Users/kristiandrucker/sdk/go1.15/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/k2/q0d7ylmn3xvb1znmhd__5yvw0000gn/T/go-build717576566=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I've tried to connect to a Google Cloud MySQL instance using TLS. This worked flawlessly on previous releases, however with Go 1.15+ I'm getting the following error x509: certificate is not valid for any names, but wanted to match project-name:db-name
. Am using the same code as before as well as the same certificates. While debugging and stepping through the TLS verification I found that commonNameAsHostname function fails on validHostnamePattern
which calls validHostname with the hostname string and isPattern
set to true.
Since the Google Cloud SQL ServerName is expected to be in format of project-name:db-name
, the validHostname
function would return false because it does not consider :
to be valid. This change has been done in the following commit where the :
character has been removed which causes the issue.
My code to connect to the Google Cloud SQL:
package main
import (
"crypto/tls"
"crypto/x509"
"database/sql"
"github.com/go-sql-driver/mysql"
"io/ioutil"
)
func main() {
rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile("/path/server-ca.pem")
if err != nil {
log.Fatal(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
log.Fatal("Failed to append PEM.")
}
clientCert := make([]tls.Certificate, 0, 1)
certs, err := tls.LoadX509KeyPair("/path/client-cert.pem",
"/path/client-key.pem")
if err != nil {
log.Fatal(err)
}
clientCert = append(clientCert, certs)
mysql.RegisterTLSConfig("custom", &tls.Config{
RootCAs: rootCertPool,
Certificates: clientCert,
ServerName: "<gcp-project-id>:<cloud-sql-instance>", // hostname
})
db, err := sql.Open("mysql",
"<user>:<password>@tcp(<cloud sql ip>:3306)/<db_name>?tls=custom")
// Code to execute commands against the DB. We use [EntGo](https://entgo.io/) but it uses the sql.DB interface for command execution.
}
What did you expect to see?
A successful database connection and command execution.
What did you see instead?
x509: certificate is not valid for any names, but wanted to match project-name:db-name
while trying to connect to the database with TLS on Google Cloud SQL.