github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/crypto/tls/example_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls_test
     6  
     7  import (
     8  	"github.com/x04/go/src/crypto/tls"
     9  	"github.com/x04/go/src/crypto/x509"
    10  	"github.com/x04/go/src/errors"
    11  	"github.com/x04/go/src/log"
    12  	"github.com/x04/go/src/net/http"
    13  	"github.com/x04/go/src/net/http/httptest"
    14  	"github.com/x04/go/src/os"
    15  	"github.com/x04/go/src/time"
    16  )
    17  
    18  // zeroSource is an io.Reader that returns an unlimited number of zero bytes.
    19  type zeroSource struct{}
    20  
    21  func (zeroSource) Read(b []byte) (n int, err error) {
    22  	for i := range b {
    23  		b[i] = 0
    24  	}
    25  
    26  	return len(b), nil
    27  }
    28  
    29  func ExampleDial() {
    30  	// Connecting with a custom root-certificate set.
    31  
    32  	const rootPEM = `
    33  -----BEGIN CERTIFICATE-----
    34  MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
    35  MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
    36  YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
    37  EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
    38  bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
    39  AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
    40  VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
    41  h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
    42  ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
    43  EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
    44  DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
    45  qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
    46  VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
    47  K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
    48  KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
    49  ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
    50  BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
    51  /iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
    52  zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
    53  HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
    54  WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
    55  yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
    56  -----END CERTIFICATE-----`
    57  
    58  	// First, create the set of root certificates. For this example we only
    59  	// have one. It's also possible to omit this in order to use the
    60  	// default root set of the current operating system.
    61  	roots := x509.NewCertPool()
    62  	ok := roots.AppendCertsFromPEM([]byte(rootPEM))
    63  	if !ok {
    64  		panic("failed to parse root certificate")
    65  	}
    66  
    67  	conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{
    68  		RootCAs: roots,
    69  	})
    70  	if err != nil {
    71  		panic("failed to connect: " + err.Error())
    72  	}
    73  	conn.Close()
    74  }
    75  
    76  func ExampleConfig_keyLogWriter() {
    77  	// Debugging TLS applications by decrypting a network traffic capture.
    78  
    79  	// WARNING: Use of KeyLogWriter compromises security and should only be
    80  	// used for debugging.
    81  
    82  	// Dummy test HTTP server for the example with insecure random so output is
    83  	// reproducible.
    84  	server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
    85  	server.TLS = &tls.Config{
    86  		Rand: zeroSource{},	// for example only; don't do this.
    87  	}
    88  	server.StartTLS()
    89  	defer server.Close()
    90  
    91  	// Typically the log would go to an open file:
    92  	// w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    93  	w := os.Stdout
    94  
    95  	client := &http.Client{
    96  		Transport: &http.Transport{
    97  			TLSClientConfig: &tls.Config{
    98  				KeyLogWriter:	w,
    99  
   100  				Rand:			zeroSource{},	// for reproducible output; don't do this.
   101  				InsecureSkipVerify:	true,		// test server certificate is not trusted.
   102  			},
   103  		},
   104  	}
   105  	resp, err := client.Get(server.URL)
   106  	if err != nil {
   107  		log.Fatalf("Failed to get URL: %v", err)
   108  	}
   109  	resp.Body.Close()
   110  
   111  	// The resulting file can be used with Wireshark to decrypt the TLS
   112  	// connection by setting (Pre)-Master-Secret log filename in SSL Protocol
   113  	// preferences.
   114  }
   115  
   116  func ExampleLoadX509KeyPair() {
   117  	cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem")
   118  	if err != nil {
   119  		log.Fatal(err)
   120  	}
   121  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   122  	listener, err := tls.Listen("tcp", ":2000", cfg)
   123  	if err != nil {
   124  		log.Fatal(err)
   125  	}
   126  	_ = listener
   127  }
   128  
   129  func ExampleX509KeyPair() {
   130  	certPem := []byte(`-----BEGIN CERTIFICATE-----
   131  MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
   132  DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
   133  EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
   134  7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
   135  5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
   136  BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
   137  NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
   138  Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
   139  6MF9+Yw1Yy0t
   140  -----END CERTIFICATE-----`)
   141  	keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
   142  MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
   143  AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
   144  EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
   145  -----END EC PRIVATE KEY-----`)
   146  	cert, err := tls.X509KeyPair(certPem, keyPem)
   147  	if err != nil {
   148  		log.Fatal(err)
   149  	}
   150  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   151  	listener, err := tls.Listen("tcp", ":2000", cfg)
   152  	if err != nil {
   153  		log.Fatal(err)
   154  	}
   155  	_ = listener
   156  }
   157  
   158  func ExampleX509KeyPair_httpServer() {
   159  	certPem := []byte(`-----BEGIN CERTIFICATE-----
   160  MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
   161  DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
   162  EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
   163  7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
   164  5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
   165  BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
   166  NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
   167  Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
   168  6MF9+Yw1Yy0t
   169  -----END CERTIFICATE-----`)
   170  	keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
   171  MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
   172  AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
   173  EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
   174  -----END EC PRIVATE KEY-----`)
   175  	cert, err := tls.X509KeyPair(certPem, keyPem)
   176  	if err != nil {
   177  		log.Fatal(err)
   178  	}
   179  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   180  	srv := &http.Server{
   181  		TLSConfig:	cfg,
   182  		ReadTimeout:	time.Minute,
   183  		WriteTimeout:	time.Minute,
   184  	}
   185  	log.Fatal(srv.ListenAndServeTLS("", ""))
   186  }
   187  
   188  func ExampleConfig_verifyPeerCertificate() {
   189  	// VerifyPeerCertificate can be used to replace and customize certificate
   190  	// verification. This example shows a VerifyPeerCertificate implementation
   191  	// that will be approximately equivalent to what crypto/tls does normally.
   192  
   193  	config := &tls.Config{
   194  		// Set InsecureSkipVerify to skip the default validation we are
   195  		// replacing. This will not disable VerifyPeerCertificate.
   196  		InsecureSkipVerify:	true,
   197  
   198  		// While packages like net/http will implicitly set ServerName, the
   199  		// VerifyPeerCertificate callback can't access that value, so it has to be set
   200  		// explicitly here or in VerifyPeerCertificate on the client side. If in
   201  		// an http.Transport DialTLS callback, this can be obtained by passing
   202  		// the addr argument to net.SplitHostPort.
   203  		ServerName:	"example.com",
   204  
   205  		// On the server side, set ClientAuth to require client certificates (or
   206  		// VerifyPeerCertificate will run anyway and panic accessing certs[0])
   207  		// but not verify them with the default verifier.
   208  		// ClientAuth: tls.RequireAnyClientCert,
   209  	}
   210  
   211  	config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error {
   212  		certs := make([]*x509.Certificate, len(certificates))
   213  		for i, asn1Data := range certificates {
   214  			cert, err := x509.ParseCertificate(asn1Data)
   215  			if err != nil {
   216  				return errors.New("tls: failed to parse certificate from server: " + err.Error())
   217  			}
   218  			certs[i] = cert
   219  		}
   220  
   221  		opts := x509.VerifyOptions{
   222  			Roots:		config.RootCAs,	// On the server side, use config.ClientCAs.
   223  			DNSName:	config.ServerName,
   224  			Intermediates:	x509.NewCertPool(),
   225  			// On the server side, set KeyUsages to ExtKeyUsageClientAuth. The
   226  			// default value is appropriate for clients side verification.
   227  			// KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
   228  		}
   229  		for _, cert := range certs[1:] {
   230  			opts.Intermediates.AddCert(cert)
   231  		}
   232  		_, err := certs[0].Verify(opts)
   233  		return err
   234  	}
   235  
   236  	// Note that when InsecureSkipVerify and VerifyPeerCertificate are in use,
   237  	// ConnectionState.VerifiedChains will be nil.
   238  }