github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/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/shogo82148/std/crypto/tls"
     9  	"github.com/shogo82148/std/crypto/x509"
    10  	"github.com/shogo82148/std/log"
    11  	"github.com/shogo82148/std/net/http"
    12  	"github.com/shogo82148/std/net/http/httptest"
    13  	"github.com/shogo82148/std/os"
    14  	"github.com/shogo82148/std/time"
    15  )
    16  
    17  func ExampleDial() {
    18  	// カスタムルート証明書セットで接続する。
    19  
    20  	const rootPEM = `
    21  -- GlobalSign Root R2, valid until Dec 15, 2021
    22  -----BEGIN CERTIFICATE-----
    23  MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
    24  A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
    25  Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
    26  MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
    27  A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
    28  hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
    29  v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
    30  eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
    31  tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
    32  C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
    33  zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
    34  mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
    35  V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
    36  bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
    37  3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
    38  J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
    39  291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
    40  ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
    41  AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
    42  TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
    43  -----END CERTIFICATE-----`
    44  
    45  	// まず、ルート証明書のセットを作成します。この例では、1つしかありません。
    46  	// もしくは、現在のオペレーティングシステムのデフォルトのルートセットを使用するために、これを省略することも可能です。
    47  	roots := x509.NewCertPool()
    48  	ok := roots.AppendCertsFromPEM([]byte(rootPEM))
    49  	if !ok {
    50  		panic("failed to parse root certificate")
    51  	}
    52  
    53  	conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{
    54  		RootCAs: roots,
    55  	})
    56  	if err != nil {
    57  		panic("failed to connect: " + err.Error())
    58  	}
    59  	conn.Close()
    60  }
    61  
    62  func ExampleConfig_keyLogWriter() {
    63  	// ネットワークトラフィックキャプチャを復号化してTLSアプリケーションをデバッグする。
    64  
    65  	// 警告: KeyLogWriterの使用はセキュリティを損なう可能性があり、
    66  	// デバッグ目的でのみ使用すべきです。
    67  
    68  	// 再現性があるように、ダミーテストのためのHTTPサーバーです。セキュリティのないランダムを使用しているので、出力も同じになります。
    69  	server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
    70  	server.TLS = &tls.Config{
    71  		Rand: zeroSource{}, // この例はただのサンプルです。これは実際には行わないでください。
    72  	}
    73  	server.StartTLS()
    74  	defer server.Close()
    75  
    76  	// 通常、ログは開かれたファイルに保存されます:
    77  	// w、err:= os.OpenFile("tls-secrets.txt"、os.O_WRONLY | os.O_CREATE | os.O_TRUNC、0600)
    78  	w := os.Stdout
    79  
    80  	client := &http.Client{
    81  		Transport: &http.Transport{
    82  			TLSClientConfig: &tls.Config{
    83  				KeyLogWriter: w,
    84  
    85  				Rand:               zeroSource{}, // 再現可能な出力のために、これを行わないでください。
    86  				InsecureSkipVerify: true,         // テストサーバー証明書は信頼されていません。
    87  			},
    88  		},
    89  	}
    90  	resp, err := client.Get(server.URL)
    91  	if err != nil {
    92  		log.Fatalf("Failed to get URL: %v", err)
    93  	}
    94  	resp.Body.Close()
    95  
    96  	// 生成されたファイルは、Wiresharkで使用することができ、SSLプロトコルの設定で(Pre)-Master-Secretログファイル名を指定することで、TLS接続を復号化できます。
    97  }
    98  
    99  func ExampleLoadX509KeyPair() {
   100  	cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem")
   101  	if err != nil {
   102  		log.Fatal(err)
   103  	}
   104  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   105  	listener, err := tls.Listen("tcp", ":2000", cfg)
   106  	if err != nil {
   107  		log.Fatal(err)
   108  	}
   109  	_ = listener
   110  }
   111  
   112  func ExampleX509KeyPair() {
   113  	certPem := []byte(`-----BEGIN CERTIFICATE-----
   114  MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
   115  DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
   116  EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
   117  7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
   118  5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
   119  BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
   120  NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
   121  Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
   122  6MF9+Yw1Yy0t
   123  -----END CERTIFICATE-----`)
   124  	keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
   125  MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
   126  AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
   127  EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
   128  -----END EC PRIVATE KEY-----`)
   129  	cert, err := tls.X509KeyPair(certPem, keyPem)
   130  	if err != nil {
   131  		log.Fatal(err)
   132  	}
   133  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   134  	listener, err := tls.Listen("tcp", ":2000", cfg)
   135  	if err != nil {
   136  		log.Fatal(err)
   137  	}
   138  	_ = listener
   139  }
   140  
   141  func ExampleX509KeyPair_httpServer() {
   142  	certPem := []byte(`-----BEGIN CERTIFICATE-----
   143  MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
   144  DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
   145  EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
   146  7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
   147  5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
   148  BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
   149  NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
   150  Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
   151  6MF9+Yw1Yy0t
   152  -----END CERTIFICATE-----`)
   153  	keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
   154  MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
   155  AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
   156  EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
   157  -----END EC PRIVATE KEY-----`)
   158  	cert, err := tls.X509KeyPair(certPem, keyPem)
   159  	if err != nil {
   160  		log.Fatal(err)
   161  	}
   162  	cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
   163  	srv := &http.Server{
   164  		TLSConfig:    cfg,
   165  		ReadTimeout:  time.Minute,
   166  		WriteTimeout: time.Minute,
   167  	}
   168  	log.Fatal(srv.ListenAndServeTLS("", ""))
   169  }
   170  
   171  func ExampleConfig_verifyConnection() {
   172  
   173  	// VerifyConnection は、接続の検証を置き換え、カスタマイズするために使用できます。
   174  	// この例では、VerifyConnection の実装方法を示しており、通常 crypto/tls で行われるピアの証明書の検証とほぼ同等です。
   175  
   176  	// クライアント側の設定。
   177  	_ = &tls.Config{
   178  
   179  		// InsecureSkipVerifyを設定して、デフォルトの検証をスキップします。
   180  		// これによってVerifyConnectionは無効になりません。
   181  		InsecureSkipVerify: true,
   182  		VerifyConnection: func(cs tls.ConnectionState) error {
   183  			opts := x509.VerifyOptions{
   184  				DNSName:       cs.ServerName,
   185  				Intermediates: x509.NewCertPool(),
   186  			}
   187  			for _, cert := range cs.PeerCertificates[1:] {
   188  				opts.Intermediates.AddCert(cert)
   189  			}
   190  			_, err := cs.PeerCertificates[0].Verify(opts)
   191  			return err
   192  		},
   193  	}
   194  
   195  	// サーバーサイドの設定。
   196  	_ = &tls.Config{
   197  
   198  		// クライアント証明書を要求する(VerifyConnection は引き続き実行され、cs.PeerCertificates[0] にアクセスできなくなるとパニックする)が、デフォルトの検証子で検証しない。これにより VerifyConnection は無効になりません。
   199  		ClientAuth: tls.RequireAnyClientCert,
   200  		VerifyConnection: func(cs tls.ConnectionState) error {
   201  			opts := x509.VerifyOptions{
   202  				DNSName:       cs.ServerName,
   203  				Intermediates: x509.NewCertPool(),
   204  				KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
   205  			}
   206  			for _, cert := range cs.PeerCertificates[1:] {
   207  				opts.Intermediates.AddCert(cert)
   208  			}
   209  			_, err := cs.PeerCertificates[0].Verify(opts)
   210  			return err
   211  		},
   212  	}
   213  
   214  	// デフォルトの検証器で証明書が処理されていない場合、ConnectionState.VerifiedChains は nil になります。
   215  }