Go言語のTLSのHTTP実装:オレオレ証明書をコード中で登録する
Real World HTTPで GO言語でTLSの簡易HTTPサーバ、クライアントを実装しよう、というトピックがありました。
説明の通り、OpenSSLコマンドでルートCA、サーバ、クライアントの鍵と証明書を作りました。(コマンドの意味は理解できておらず…この辺りも学んでおかないと…)
本来、無条件に信頼するルートCAはOSに登録されていたり、ツールや言語によってはn内部に含まれていたりするそうです。今回のオレオレ証明書、curlで叩くならコマンドラインで渡すなどの方法もとれるそうですが、、GO言語のデフォルトではOSのを参照してしまうそう。
それも面倒なので、プログラムコード内で登録します。
サーバ認証の場合、検証するのはクライアント側になるので、クライアントコードにルートCA追加処理を記述します。これは上記書籍にサンプルソースがありました。
*tls.Config
のRootCAs
を使うそうです。
抜粋ですが。
cert, err := ioutil.ReadFile("ca.crt") if err != nil { log.Println(err) } certPool := x509.NewCertPool() certPool.AppendCertsFromPEM(cert) tlsConfig := &tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, MinVersion: tls.VersionTLS12, ClientCAs: certPool, } tlsConfig.BuildNameToCertificate() server := &http.Server{ TLSConfig: tlsConfig, Addr: ":18443", }
じゃあクライアント認証も…ってことで、写経してみましたが動かない。
018/01/27 14:57:59 http: TLS handshake error from [::1]:57397: tls: failed to verify client's certificate: x509: certificate signed by unknown authority
むむ、CAが信頼できない、と。
じゃあどうやるんだろうってことで、crypto/tls
のドキュメントを読んだところ解決。ClientCAs
を使用します。
cert, err := ioutil.ReadFile("ca.crt") if err != nil { log.Println(err) } certPool := x509.NewCertPool() certPool.AppendCertsFromPEM(cert) tlsConfig := &tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, MinVersion: tls.VersionTLS12, ClientCAs: certPool, } tlsConfig.BuildNameToCertificate() server := &http.Server{ TLSConfig: tlsConfig, Addr: ":18443", }