@@ -66,10 +66,46 @@ func setupTLSCommonName(config *tls.Config, pem []byte) error {
6666
6767// setupTLSCertificateOnly validates the certificate chain without checking the hostname
6868func setupTLSCertificateOnly (config * tls.Config , pem []byte ) error {
69- // Skip hostname validation by setting ServerName to empty string.
70- // When ServerName is empty, Go's TLS implementation will skip hostname verification
71- // but still verify the certificate chain against the RootCAs (configured in SetupTLS after this function returns).
72- // This is the secure way to skip hostname validation without using InsecureSkipVerify.
73- config .ServerName = ""
69+ // To skip hostname validation while still validating the certificate chain,
70+ // we must use InsecureSkipVerify=true with a VerifyPeerCertificate callback.
71+ // This is the only way to skip hostname checks in Go's TLS implementation.
72+
73+ // Create a certificate pool with the provided certificate as the root CA
74+ roots := x509 .NewCertPool ()
75+ roots .AppendCertsFromPEM (pem )
76+
77+ config .InsecureSkipVerify = true
78+ config .VerifyPeerCertificate = func (rawCerts [][]byte , verifiedChains [][]* x509.Certificate ) error {
79+ if len (rawCerts ) == 0 {
80+ return fmt .Errorf ("no peer certificates provided" )
81+ }
82+
83+ // Parse the peer certificate
84+ cert , err := x509 .ParseCertificate (rawCerts [0 ])
85+ if err != nil {
86+ return fmt .Errorf ("failed to parse certificate: %w" , err )
87+ }
88+
89+ // Build intermediates pool from the peer certificates (excluding the first one which is the server cert)
90+ intermediates := x509 .NewCertPool ()
91+ if len (rawCerts ) > 1 {
92+ for i := 1 ; i < len (rawCerts ); i ++ {
93+ intermediateCert , err := x509 .ParseCertificate (rawCerts [i ])
94+ if err != nil {
95+ return fmt .Errorf ("failed to parse intermediate certificate: %w" , err )
96+ }
97+ intermediates .AddCert (intermediateCert )
98+ }
99+ }
100+
101+ // Verify the certificate chain against the provided root CA
102+ // Note: We do NOT check the hostname here - that's intentional for this use case
103+ opts := x509.VerifyOptions {
104+ Roots : roots ,
105+ Intermediates : intermediates ,
106+ }
107+ _ , err = cert .Verify (opts )
108+ return err
109+ }
74110 return nil
75111}
0 commit comments