in internal/cloudsql/tls_verify.go [65:129]
func verifyPeerCertificateFunc(
serverName string, cn instance.ConnName, roots *x509.CertPool,
) func(certs [][]byte, chain [][]*x509.Certificate) error {
return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
if len(rawCerts) == 0 {
return errtype.NewDialError(
"no certificate to verify", cn.String(), nil,
)
}
// Parse the raw certificates
certs := make([]*x509.Certificate, 0, len(rawCerts))
var err error
for _, certBytes := range rawCerts {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return errtype.NewDialError(
"failed to parse X.509 certificate", cn.String(), err,
)
}
certs = append(certs, cert)
}
serverCert := certs[0]
// Verify the validity of the certificate chain
_, err = serverCert.Verify(x509.VerifyOptions{
Roots: roots,
})
if err != nil {
err = &tls.CertificateVerificationError{
UnverifiedCertificates: certs,
Err: err,
}
return errtype.NewDialError(
"failed to verify certificate", cn.String(), err,
)
}
var serverNameErr error
if serverName == "" {
// The instance has no DNS name.
// Verify only the CN
return verifyCn(cn, serverCert)
}
// The instance has a DNS name.
// First, verify the server hostname
serverNameErr = serverCert.VerifyHostname(serverName)
if serverNameErr != nil {
// If that failed, verify the CN field.
cnErr := verifyCn(cn, serverCert)
if cnErr != nil {
// If both failed, return the server hostname error.
serverNameErr = &tls.CertificateVerificationError{
UnverifiedCertificates: certs,
Err: serverNameErr,
}
return serverNameErr
}
}
// All checks passed
return nil
}
}