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 5package tls_test 6 7import ( 8 "crypto/tls" 9 "crypto/x509" 10 "log" 11 "net/http" 12 "net/http/httptest" 13 "os" 14 "time" 15) 16 17// zeroSource is an io.Reader that returns an unlimited number of zero bytes. 18type zeroSource struct{} 19 20func (zeroSource) Read(b []byte) (n int, err error) { 21 for i := range b { 22 b[i] = 0 23 } 24 25 return len(b), nil 26} 27 28func ExampleDial() { 29 // Connecting with a custom root-certificate set. 30 31 const rootPEM = ` 32-- GlobalSign Root R2, valid until Dec 15, 2021 33-----BEGIN CERTIFICATE----- 34MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G 35A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp 36Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 37MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG 38A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI 39hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL 40v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 41eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq 42tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd 43C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa 44zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB 45mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH 46V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n 47bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 483lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs 49J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 50291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS 51ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd 52AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 53TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== 54-----END CERTIFICATE-----` 55 56 // First, create the set of root certificates. For this example we only 57 // have one. It's also possible to omit this in order to use the 58 // default root set of the current operating system. 59 roots := x509.NewCertPool() 60 ok := roots.AppendCertsFromPEM([]byte(rootPEM)) 61 if !ok { 62 panic("failed to parse root certificate") 63 } 64 65 conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ 66 RootCAs: roots, 67 }) 68 if err != nil { 69 panic("failed to connect: " + err.Error()) 70 } 71 conn.Close() 72} 73 74func ExampleConfig_keyLogWriter() { 75 // Debugging TLS applications by decrypting a network traffic capture. 76 77 // WARNING: Use of KeyLogWriter compromises security and should only be 78 // used for debugging. 79 80 // Dummy test HTTP server for the example with insecure random so output is 81 // reproducible. 82 server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) 83 server.TLS = &tls.Config{ 84 Rand: zeroSource{}, // for example only; don't do this. 85 } 86 server.StartTLS() 87 defer server.Close() 88 89 // Typically the log would go to an open file: 90 // w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 91 w := os.Stdout 92 93 client := &http.Client{ 94 Transport: &http.Transport{ 95 TLSClientConfig: &tls.Config{ 96 KeyLogWriter: w, 97 98 Rand: zeroSource{}, // for reproducible output; don't do this. 99 InsecureSkipVerify: true, // test server certificate is not trusted. 100 }, 101 }, 102 } 103 resp, err := client.Get(server.URL) 104 if err != nil { 105 log.Fatalf("Failed to get URL: %v", err) 106 } 107 resp.Body.Close() 108 109 // The resulting file can be used with Wireshark to decrypt the TLS 110 // connection by setting (Pre)-Master-Secret log filename in SSL Protocol 111 // preferences. 112} 113 114func ExampleLoadX509KeyPair() { 115 cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem") 116 if err != nil { 117 log.Fatal(err) 118 } 119 cfg := &tls.Config{Certificates: []tls.Certificate{cert}} 120 listener, err := tls.Listen("tcp", ":2000", cfg) 121 if err != nil { 122 log.Fatal(err) 123 } 124 _ = listener 125} 126 127func ExampleX509KeyPair() { 128 certPem := []byte(`-----BEGIN CERTIFICATE----- 129MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw 130DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow 131EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d 1327VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B 1335aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr 134BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 135NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l 136Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc 1376MF9+Yw1Yy0t 138-----END CERTIFICATE-----`) 139 keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- 140MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 141AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q 142EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== 143-----END EC PRIVATE KEY-----`) 144 cert, err := tls.X509KeyPair(certPem, keyPem) 145 if err != nil { 146 log.Fatal(err) 147 } 148 cfg := &tls.Config{Certificates: []tls.Certificate{cert}} 149 listener, err := tls.Listen("tcp", ":2000", cfg) 150 if err != nil { 151 log.Fatal(err) 152 } 153 _ = listener 154} 155 156func ExampleX509KeyPair_httpServer() { 157 certPem := []byte(`-----BEGIN CERTIFICATE----- 158MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw 159DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow 160EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d 1617VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B 1625aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr 163BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 164NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l 165Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc 1666MF9+Yw1Yy0t 167-----END CERTIFICATE-----`) 168 keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- 169MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 170AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q 171EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== 172-----END EC PRIVATE KEY-----`) 173 cert, err := tls.X509KeyPair(certPem, keyPem) 174 if err != nil { 175 log.Fatal(err) 176 } 177 cfg := &tls.Config{Certificates: []tls.Certificate{cert}} 178 srv := &http.Server{ 179 TLSConfig: cfg, 180 ReadTimeout: time.Minute, 181 WriteTimeout: time.Minute, 182 } 183 log.Fatal(srv.ListenAndServeTLS("", "")) 184} 185 186func ExampleConfig_verifyConnection() { 187 // VerifyConnection can be used to replace and customize connection 188 // verification. This example shows a VerifyConnection implementation that 189 // will be approximately equivalent to what crypto/tls does normally to 190 // verify the peer's certificate. 191 192 // Client side configuration. 193 _ = &tls.Config{ 194 // Set InsecureSkipVerify to skip the default validation we are 195 // replacing. This will not disable VerifyConnection. 196 InsecureSkipVerify: true, 197 VerifyConnection: func(cs tls.ConnectionState) error { 198 opts := x509.VerifyOptions{ 199 DNSName: cs.ServerName, 200 Intermediates: x509.NewCertPool(), 201 } 202 for _, cert := range cs.PeerCertificates[1:] { 203 opts.Intermediates.AddCert(cert) 204 } 205 _, err := cs.PeerCertificates[0].Verify(opts) 206 return err 207 }, 208 } 209 210 // Server side configuration. 211 _ = &tls.Config{ 212 // Require client certificates (or VerifyConnection will run anyway and 213 // panic accessing cs.PeerCertificates[0]) but don't verify them with the 214 // default verifier. This will not disable VerifyConnection. 215 ClientAuth: tls.RequireAnyClientCert, 216 VerifyConnection: func(cs tls.ConnectionState) error { 217 opts := x509.VerifyOptions{ 218 DNSName: cs.ServerName, 219 Intermediates: x509.NewCertPool(), 220 KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 221 } 222 for _, cert := range cs.PeerCertificates[1:] { 223 opts.Intermediates.AddCert(cert) 224 } 225 _, err := cs.PeerCertificates[0].Verify(opts) 226 return err 227 }, 228 } 229 230 // Note that when certificates are not handled by the default verifier 231 // ConnectionState.VerifiedChains will be nil. 232} 233