It would be useful to have a callback in tls.Config called after the TLS handshake to allow the callee to perform additional or alternate certificate verification on the peer. This would enable custom cert checking and/or explicit certificate pinning/whitelisting (e.g. by cert hash).
I propose calling VerifyPeerCertificate (if !nil) during the respective client and server handshakes (doFullHandshake and processPeerCertsFromClient) after the peer certificates have been received.
The func is introduced to tls.Config
// VerifyPeerCertificate returns an error if the peer should not be
// trusted. It will be called after the initial handshake and before
// any other verification checks on the cert or chain are performed.
// This provides the callee an opportunity to augment the certificate
// verification.
//
// If VerifyPeerCertificate is not nil and returns an error,
// then the handshake will fail.
VerifyPeerCertificate func(peer []*x509.Certificate) error
This works with both http and http2. It appears that tls.Config is cloned from the initial transport for TLSNextProto -- is this intentional or an artifact of the current impl?
c := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 60 * time.Second,
KeepAlive: 60 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
// inject our callback to check the peer here
NextProtos: []string{"h2"},
VerifyPeerCertificate: verifyPeerCertificate,
},
TLSNextProto: map[string]func(authority string, c *tls.Conn) http.RoundTripper{
"h2": func(authority string, c *tls.Conn) http.RoundTripper {
return http.DefaultTransport
},
},
},
}
I have a changset ready if this is a reasonable approach.
Fixes #9126
Fixes #9451
It would be useful to have a callback in tls.Config called after the TLS handshake to allow the callee to perform additional or alternate certificate verification on the peer. This would enable custom cert checking and/or explicit certificate pinning/whitelisting (e.g. by cert hash).
I propose calling VerifyPeerCertificate (if !nil) during the respective client and server handshakes (doFullHandshake and processPeerCertsFromClient) after the peer certificates have been received.
The func is introduced to tls.Config
This works with both http and http2. It appears that tls.Config is cloned from the initial transport for TLSNextProto -- is this intentional or an artifact of the current impl?
I have a changset ready if this is a reasonable approach.
Fixes #9126
Fixes #9451