diff options
Diffstat (limited to 'src/crypto/tls/example_test.go')
-rw-r--r-- | src/crypto/tls/example_test.go | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/crypto/tls/example_test.go b/src/crypto/tls/example_test.go new file mode 100644 index 0000000..6389fd7 --- /dev/null +++ b/src/crypto/tls/example_test.go @@ -0,0 +1,232 @@ +// 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. +} |