From 004dded0a87d713b57d8421495a5f0df17137816 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 31 Jul 2024 09:35:52 -0700 Subject: [PATCH] net/tlsdial: relax self-signed cert health warning It seems some security software or macOS itself might be MITMing TLS (for ScreenTime?), so don't warn unless it fails x509 validation against system roots. Updates #3198 Change-Id: I6ea381b5bb6385b3d51da4a1468c0d803236b7bf Signed-off-by: Brad Fitzpatrick --- net/tlsdial/tlsdial.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/net/tlsdial/tlsdial.go b/net/tlsdial/tlsdial.go index 087d2fbce..2bf88bd0e 100644 --- a/net/tlsdial/tlsdial.go +++ b/net/tlsdial/tlsdial.go @@ -76,17 +76,30 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { // own cert verification, as do the same work that it'd do // (with the baked-in fallback root) in the VerifyConnection hook. conf.InsecureSkipVerify = true - conf.VerifyConnection = func(cs tls.ConnectionState) error { + conf.VerifyConnection = func(cs tls.ConnectionState) (retErr error) { // Perform some health checks on this certificate before we do // any verification. + var selfSignedIssuer string + if certs := cs.PeerCertificates; len(certs) > 0 && certIsSelfSigned(certs[0]) { + selfSignedIssuer = certs[0].Issuer.String() + } if ht != nil { - if certIsSelfSigned(cs.PeerCertificates[0]) { - // Self-signed certs are never valid. - ht.SetTLSConnectionError(cs.ServerName, fmt.Errorf("certificate is self-signed")) - } else { - // Ensure we clear any error state for this ServerName. - ht.SetTLSConnectionError(cs.ServerName, nil) - } + defer func() { + if retErr != nil && selfSignedIssuer != "" { + // Self-signed certs are never valid. + // + // TODO(bradfitz): plumb down the selfSignedIssuer as a + // structured health warning argument. + ht.SetTLSConnectionError(cs.ServerName, fmt.Errorf("likely intercepted connection; certificate is self-signed by %v", selfSignedIssuer)) + } else { + // Ensure we clear any error state for this ServerName. + ht.SetTLSConnectionError(cs.ServerName, nil) + if selfSignedIssuer != "" { + // Log the self-signed issuer, but don't treat it as an error. + log.Printf("tlsdial: warning: server cert for %q passed x509 validation but is self-signed by %q", host, selfSignedIssuer) + } + } + }() } // First try doing x509 verification with the system's