From e64e657944573f6341900570099be9992d5849e5 Mon Sep 17 00:00:00 2001 From: "Mark S. Lewis" Date: Sun, 8 Mar 2026 14:22:27 +0000 Subject: [PATCH] Add SecureOptions.VerifyConnection Linting flagged a gap in TLS certificate verification using the SecureOptions.VerifyCertificate function, since this is not invoked when connections are resumed. This change introduces a new SecureOptions.VerifyConnection verification function that uses more recent Go standard library features to perform verification on both connection and resume. It also provides access to additional information for more thorough verification. The VerifyConnection function replaces the older VerififyCertificate method of certification verification. The old method is retained for compatibility. Signed-off-by: Mark S. Lewis --- .golangci.yml | 5 ----- pkg/network/network.go | 31 +++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f5c647c..559f652 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -33,11 +33,6 @@ linters: presets: - common-false-positives - std-error-handling - rules: - - path: "_test.go$" - text: "^G703:" - linters: - - gosec formatters: enable: - gofmt diff --git a/pkg/network/network.go b/pkg/network/network.go index d9007e1..b2df521 100644 --- a/pkg/network/network.go +++ b/pkg/network/network.go @@ -178,25 +178,51 @@ func NewGRPCClient(config ClientConfig) (*GRPCClient, error) { // GRPCServer or GRPCClient instance type SecureOptions struct { // VerifyCertificate, if not nil, is called after normal - // certificate verification by either a TLS client or server. - // If it returns a non-nil error, the handshake is aborted and that error results. + // certificate verification by either a TLS client or server. It + // receives the raw ASN.1 certificates provided by the peer and also + // any verified chains that normal processing found. If it returns a + // non-nil error, the handshake is aborted and that error results. + // + // This callback is not invoked on resumed connections. It is recommended + // to use [SecureOptions.VerifyConnection] instead. VerifyCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error + + // VerifyConnection, if not nil, is called after normal certificate + // verification and after VerifyPeerCertificate by either a TLS client + // or server. If it returns a non-nil error, the handshake is aborted + // and that error results. + // + // If normal verification fails then the handshake will abort before + // considering this callback. This callback will run for all connections, + // including resumptions, regardless of InsecureSkipVerify or ClientAuth + // settings. + // + // For a usage example, see: https://pkg.go.dev/crypto/tls#example-Config-VerifyConnection + VerifyConnection func(tls.ConnectionState) error + // PEM-encoded X509 public key to be used for TLS communication Certificate []byte + // PEM-encoded private key to be used for TLS communication Key []byte + // Set of PEM-encoded X509 certificate authorities used by clients to // verify server certificates ServerRootCAs [][]byte + // Set of PEM-encoded X509 certificate authorities used by servers to // verify client certificates ClientRootCAs [][]byte + // Whether or not to use TLS for communication UseTLS bool + // Whether or not TLS client must present certificates for authentication RequireClientCert bool + // CipherSuites is a list of supported cipher suites for TLS CipherSuites []uint16 + // TimeShift makes TLS handshakes time sampling shift to the past by a given duration TimeShift time.Duration } @@ -209,6 +235,7 @@ func (client *GRPCClient) parseSecureOptions(opts SecureOptions) error { client.tlsConfig = &tls.Config{ VerifyPeerCertificate: opts.VerifyCertificate, + VerifyConnection: opts.VerifyConnection, MinVersion: tls.VersionTLS12} // TLS 1.2 only if serverRootCAs, err := newRootCACertPool(opts); err == nil {