|  | // Copyright 2014 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package tls_test | 
|  |  | 
|  | import ( | 
|  | "crypto/tls" | 
|  | "crypto/x509" | 
|  | "log" | 
|  | "net/http" | 
|  | "net/http/httptest" | 
|  | "os" | 
|  | "time" | 
|  | ) | 
|  |  | 
|  | // zeroSource is an io.Reader that returns an unlimited number of zero bytes. | 
|  | type zeroSource struct{} | 
|  |  | 
|  | func (zeroSource) Read(b []byte) (n int, err error) { | 
|  | for i := range b { | 
|  | b[i] = 0 | 
|  | } | 
|  |  | 
|  | return len(b), nil | 
|  | } | 
|  |  | 
|  | func ExampleDial() { | 
|  | // Connecting with a custom root-certificate set. | 
|  |  | 
|  | const rootPEM = ` | 
|  | -- GlobalSign Root R2, valid until Dec 15, 2021 | 
|  | -----BEGIN CERTIFICATE----- | 
|  | MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G | 
|  | A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp | 
|  | Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 | 
|  | MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG | 
|  | A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI | 
|  | hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL | 
|  | v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 | 
|  | eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq | 
|  | tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd | 
|  | C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa | 
|  | zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB | 
|  | mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH | 
|  | V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n | 
|  | bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG | 
|  | 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs | 
|  | J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO | 
|  | 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS | 
|  | ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd | 
|  | AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 | 
|  | TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== | 
|  | -----END CERTIFICATE-----` | 
|  |  | 
|  | // First, create the set of root certificates. For this example we only | 
|  | // have one. It's also possible to omit this in order to use the | 
|  | // default root set of the current operating system. | 
|  | roots := x509.NewCertPool() | 
|  | ok := roots.AppendCertsFromPEM([]byte(rootPEM)) | 
|  | if !ok { | 
|  | panic("failed to parse root certificate") | 
|  | } | 
|  |  | 
|  | conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ | 
|  | RootCAs: roots, | 
|  | }) | 
|  | if err != nil { | 
|  | panic("failed to connect: " + err.Error()) | 
|  | } | 
|  | conn.Close() | 
|  | } | 
|  |  | 
|  | func ExampleConfig_keyLogWriter() { | 
|  | // Debugging TLS applications by decrypting a network traffic capture. | 
|  |  | 
|  | // WARNING: Use of KeyLogWriter compromises security and should only be | 
|  | // used for debugging. | 
|  |  | 
|  | // Dummy test HTTP server for the example with insecure random so output is | 
|  | // reproducible. | 
|  | server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) | 
|  | server.TLS = &tls.Config{ | 
|  | Rand: zeroSource{}, // for example only; don't do this. | 
|  | } | 
|  | server.StartTLS() | 
|  | defer server.Close() | 
|  |  | 
|  | // Typically the log would go to an open file: | 
|  | // w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | 
|  | w := os.Stdout | 
|  |  | 
|  | client := &http.Client{ | 
|  | Transport: &http.Transport{ | 
|  | TLSClientConfig: &tls.Config{ | 
|  | KeyLogWriter: w, | 
|  |  | 
|  | Rand:               zeroSource{}, // for reproducible output; don't do this. | 
|  | InsecureSkipVerify: true,         // test server certificate is not trusted. | 
|  | }, | 
|  | }, | 
|  | } | 
|  | resp, err := client.Get(server.URL) | 
|  | if err != nil { | 
|  | log.Fatalf("Failed to get URL: %v", err) | 
|  | } | 
|  | resp.Body.Close() | 
|  |  | 
|  | // The resulting file can be used with Wireshark to decrypt the TLS | 
|  | // connection by setting (Pre)-Master-Secret log filename in SSL Protocol | 
|  | // preferences. | 
|  | } | 
|  |  | 
|  | func ExampleLoadX509KeyPair() { | 
|  | cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem") | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | cfg := &tls.Config{Certificates: []tls.Certificate{cert}} | 
|  | listener, err := tls.Listen("tcp", ":2000", cfg) | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | _ = listener | 
|  | } | 
|  |  | 
|  | func ExampleX509KeyPair() { | 
|  | certPem := []byte(`-----BEGIN CERTIFICATE----- | 
|  | MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw | 
|  | DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow | 
|  | EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d | 
|  | 7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B | 
|  | 5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr | 
|  | BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 | 
|  | NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l | 
|  | Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc | 
|  | 6MF9+Yw1Yy0t | 
|  | -----END CERTIFICATE-----`) | 
|  | keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- | 
|  | MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 | 
|  | AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q | 
|  | EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== | 
|  | -----END EC PRIVATE KEY-----`) | 
|  | cert, err := tls.X509KeyPair(certPem, keyPem) | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | cfg := &tls.Config{Certificates: []tls.Certificate{cert}} | 
|  | listener, err := tls.Listen("tcp", ":2000", cfg) | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | _ = listener | 
|  | } | 
|  |  | 
|  | func ExampleX509KeyPair_httpServer() { | 
|  | certPem := []byte(`-----BEGIN CERTIFICATE----- | 
|  | MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw | 
|  | DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow | 
|  | EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d | 
|  | 7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B | 
|  | 5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr | 
|  | BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 | 
|  | NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l | 
|  | Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc | 
|  | 6MF9+Yw1Yy0t | 
|  | -----END CERTIFICATE-----`) | 
|  | keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- | 
|  | MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 | 
|  | AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q | 
|  | EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== | 
|  | -----END EC PRIVATE KEY-----`) | 
|  | cert, err := tls.X509KeyPair(certPem, keyPem) | 
|  | if err != nil { | 
|  | log.Fatal(err) | 
|  | } | 
|  | cfg := &tls.Config{Certificates: []tls.Certificate{cert}} | 
|  | srv := &http.Server{ | 
|  | TLSConfig:    cfg, | 
|  | ReadTimeout:  time.Minute, | 
|  | WriteTimeout: time.Minute, | 
|  | } | 
|  | log.Fatal(srv.ListenAndServeTLS("", "")) | 
|  | } | 
|  |  | 
|  | 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. | 
|  |  | 
|  | // Client side configuration. | 
|  | _ = &tls.Config{ | 
|  | // Set InsecureSkipVerify to skip the default validation we are | 
|  | // replacing. This will not disable VerifyConnection. | 
|  | InsecureSkipVerify: true, | 
|  | 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 | 
|  | }, | 
|  | } | 
|  |  | 
|  | // 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. | 
|  | } |