crypto/tls: replace VerifyPeerCertificate example with VerifyConnection
Look at how much better it is!
Updates #36736
Change-Id: I53a314a103a42dd869c05823fa50f37d70f9d283
Reviewed-on: https://go-review.googlesource.com/c/go/+/239560
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
diff --git a/src/crypto/tls/example_test.go b/src/crypto/tls/example_test.go
index cf58a58..6389fd7 100644
--- a/src/crypto/tls/example_test.go
+++ b/src/crypto/tls/example_test.go
@@ -7,7 +7,6 @@
import (
"crypto/tls"
"crypto/x509"
- "errors"
"log"
"net/http"
"net/http/httptest"
@@ -184,54 +183,50 @@
log.Fatal(srv.ListenAndServeTLS("", ""))
}
-func ExampleConfig_verifyPeerCertificate() {
- // VerifyPeerCertificate can be used to replace and customize certificate
- // verification. This example shows a VerifyPeerCertificate implementation
- // that will be approximately equivalent to what crypto/tls does normally.
+func ExampleConfig_verifyConnection() {
+ // VerifyConnection can be used to replace and customize connection
+ // verification. This example shows a VerifyConnection implementation that
+ // will be approximately equivalent to what crypto/tls does normally to
+ // verify the peer's certificate.
- config := &tls.Config{
+ // Client side configuration.
+ _ = &tls.Config{
// Set InsecureSkipVerify to skip the default validation we are
- // replacing. This will not disable VerifyPeerCertificate.
+ // replacing. This will not disable VerifyConnection.
InsecureSkipVerify: true,
-
- // While packages like net/http will implicitly set ServerName, the
- // VerifyPeerCertificate callback can't access that value, so it has to be set
- // explicitly here or in VerifyPeerCertificate on the client side. If in
- // an http.Transport DialTLS callback, this can be obtained by passing
- // the addr argument to net.SplitHostPort.
- ServerName: "example.com",
-
- // On the server side, set ClientAuth to require client certificates (or
- // VerifyPeerCertificate will run anyway and panic accessing certs[0])
- // but not verify them with the default verifier.
- // ClientAuth: tls.RequireAnyClientCert,
- }
-
- config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error {
- certs := make([]*x509.Certificate, len(certificates))
- for i, asn1Data := range certificates {
- cert, err := x509.ParseCertificate(asn1Data)
- if err != nil {
- return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ VerifyConnection: func(cs tls.ConnectionState) error {
+ opts := x509.VerifyOptions{
+ DNSName: cs.ServerName,
+ Intermediates: x509.NewCertPool(),
}
- certs[i] = cert
- }
-
- opts := x509.VerifyOptions{
- Roots: config.RootCAs, // On the server side, use config.ClientCAs.
- DNSName: config.ServerName,
- Intermediates: x509.NewCertPool(),
- // On the server side, set KeyUsages to ExtKeyUsageClientAuth. The
- // default value is appropriate for clients side verification.
- // KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
- }
- for _, cert := range certs[1:] {
- opts.Intermediates.AddCert(cert)
- }
- _, err := certs[0].Verify(opts)
- return err
+ for _, cert := range cs.PeerCertificates[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ _, err := cs.PeerCertificates[0].Verify(opts)
+ return err
+ },
}
- // Note that when InsecureSkipVerify and VerifyPeerCertificate are in use,
+ // Server side configuration.
+ _ = &tls.Config{
+ // Require client certificates (or VerifyConnection will run anyway and
+ // panic accessing cs.PeerCertificates[0]) but don't verify them with the
+ // default verifier. This will not disable VerifyConnection.
+ ClientAuth: tls.RequireAnyClientCert,
+ VerifyConnection: func(cs tls.ConnectionState) error {
+ opts := x509.VerifyOptions{
+ DNSName: cs.ServerName,
+ Intermediates: x509.NewCertPool(),
+ KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+ }
+ for _, cert := range cs.PeerCertificates[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ _, err := cs.PeerCertificates[0].Verify(opts)
+ return err
+ },
+ }
+
+ // Note that when certificates are not handled by the default verifier
// ConnectionState.VerifiedChains will be nil.
}