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