]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: replace VerifyPeerCertificate example with VerifyConnection
authorFilippo Valsorda <filippo@golang.org>
Tue, 23 Jun 2020 21:19:01 +0000 (17:19 -0400)
committerFilippo Valsorda <filippo@golang.org>
Wed, 24 Jun 2020 20:48:12 +0000 (20:48 +0000)
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>
src/crypto/tls/example_test.go

index cf58a58a8a2a5da11df7f0e77822c743b50a8f23..6389fd7fedc2d5c4a55206315f6301f124f3a30a 100644 (file)
@@ -7,7 +7,6 @@ package tls_test
 import (
        "crypto/tls"
        "crypto/x509"
-       "errors"
        "log"
        "net/http"
        "net/http/httptest"
@@ -184,54 +183,50 @@ EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
        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,
+               VerifyConnection: func(cs tls.ConnectionState) error {
+                       opts := x509.VerifyOptions{
+                               DNSName:       cs.ServerName,
+                               Intermediates: x509.NewCertPool(),
+                       }
+                       for _, cert := range cs.PeerCertificates[1:] {
+                               opts.Intermediates.AddCert(cert)
+                       }
+                       _, err := cs.PeerCertificates[0].Verify(opts)
+                       return err
+               },
        }
 
-       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())
+       // 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)
                        }
-                       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
+                       _, err := cs.PeerCertificates[0].Verify(opts)
+                       return err
+               },
        }
 
-       // Note that when InsecureSkipVerify and VerifyPeerCertificate are in use,
+       // Note that when certificates are not handled by the default verifier
        // ConnectionState.VerifiedChains will be nil.
 }