Skip to content

PSC connections fail with Go 1.25.2 due to trailing dot in DNS names #1017

@Strainy

Description

@Strainy

Bug Description

After upgrading go to 1.25.2, I've started to see database connection errors wrapping x509: SAN dNSName is malformed. I think this may be related to the following patch golang/go#75715. PSC DNS names have a trailing dot, which seems to not be compliant.

Refer to the example code provided. You can see the issue pretty clearly:

GOTOOLCHAIN=go1.25.2 go run main.go
Cloud SQL PSC DNS name: 42cfcd3545f4.2imj07zrx20yw.us-west1.sql.goog.
Error creating cert: x509: SAN dNSName is malformed

GOTOOLCHAIN=go1.25.1 go run main.go
Cloud SQL PSC DNS name: 42cfcd3545f4.2imj07zrx20yw.us-west1.sql.goog.
Cert created successfully

Example code (or command)

# main.go

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"fmt"
	"math/big"
	"net"
	"time"
)

func main() {
	// This is the DNS name Cloud SQL API returns for PSC instances
	dnsNameWithTrailingDot := "42cfcd3545f4.2imj07zrx20yw.us-west1.sql.goog."
	fmt.Printf("Cloud SQL PSC DNS name: %s\n", dnsNameWithTrailingDot)

	// Create a self-signed certificate with trailing dot in SAN DNS name
	// This simulates what Cloud SQL's certificate has
	_, err := createCertWithDNSName(dnsNameWithTrailingDot)
	if err != nil {
		fmt.Printf("Error creating cert: %v\n", err)
		return
	}

	fmt.Println("Cert created successfully")
}

// createCertWithDNSName creates a self-signed certificate with the given DNS name in SAN
func createCertWithDNSName(dnsName string) (tls.Certificate, error) {
	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return tls.Certificate{}, err
	}

	serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
	if err != nil {
		return tls.Certificate{}, err
	}

	template := &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			CommonName: "Cloud SQL Test",
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().Add(24 * time.Hour),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
		DNSNames:              []string{dnsName}, // Include the trailing dot
		IPAddresses:           []net.IP{net.ParseIP("127.0.0.1")},
	}

	certDER, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
	if err != nil {
		return tls.Certificate{}, err
	}

	// Parse the certificate to get the *x509.Certificate for the Leaf field
	cert, err := x509.ParseCertificate(certDER)
	if err != nil {
		return tls.Certificate{}, err
	}

	return tls.Certificate{
		Certificate: [][]byte{certDER},
		PrivateKey:  priv,
		Leaf:        cert,
	}, nil
}

Stacktrace

Steps to reproduce?

Basically upgrade to go1.25.2 and attempt to connect to a cloudsql instance via PSC.

Environment

  • Go version: 1.25.2
  • cloud-sql-go-connector version: v1.18.1
  • Cloud SQL instance type: PostgreSQL with Private Service Connect (PSC)
  • Operating System: linux/amd64

Additional Details

No response

Metadata

Metadata

Assignees

Labels

type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions