Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19137] ファイルの概要

このコミットは、Go言語の標準ライブラリ crypto/x509 パッケージにおけるWindowsビルドの問題を修正するものです。具体的には、証明書チェーンの検証テストがWindows環境で失敗する問題を解決するために、テストケース内のルート証明書と中間証明書の設定が調整されました。

コミット

commit 3f32a51242c2567d79681b2d4e002684f21d4a5c
Author: Adam Langley <agl@golang.org>
Date:   Mon Apr 14 13:23:58 2014 -0700

    crypto/x509: fix Windows build.
    
    Windows is building a chain to the AddTrust root which is different
    from the native Go code and causing a build failure.
    
    This change alters the test so that both should build to the AddTrust
    root.
    
    R=bradfitz
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/87570044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3f32a51242c2567d79681b2d4e002684f21d4a5c

元コミット内容

このコミットは、crypto/x509 パッケージのWindowsビルドにおける問題を修正します。問題は、Windows環境がGoのネイティブコードとは異なる方法で AddTrust ルート証明書への証明書チェーンを構築し、それがビルドエラーを引き起こしていたことにありました。この変更は、テストケースを修正し、WindowsとGoのネイティブコードの両方が AddTrust ルート証明書にチェーンを構築するように調整することで、この問題を解決します。

変更の背景

この変更の背景には、Go言語のクロスプラットフォームな性質と、各オペレーティングシステム(OS)が持つ独自の証明書ストアおよび証明書チェーン構築ロジックの違いがあります。

crypto/x509 パッケージは、X.509証明書の解析、検証、および管理を行うためのGoの標準ライブラリです。TLS/SSL通信など、セキュアな通信においてサーバー証明書の正当性を検証する際に不可欠な役割を果たします。証明書の検証プロセスでは、提示された証明書(リーフ証明書)から始まり、その発行元(中間CA証明書)をたどり、最終的に信頼されたルート証明書に到達する「証明書チェーン」を構築し、そのチェーン全体が有効であることを確認します。

問題は、Windows環境とGoのネイティブな証明書チェーン構築ロジックの間で、特定のルート証明書(この場合は AddTrust ルート)へのチェーン構築方法に差異が生じていたことです。これは、Windowsが独自の証明書ストアと検証APIを使用するのに対し、Goは独自のロジックで証明書を処理するため、同じ証明書セットを与えられても異なるチェーンを構築する可能性があったためです。

この差異が、crypto/x509 パッケージ内のテスト(特に verify_test.go)においてビルドエラーとして顕在化しました。テストは特定の証明書チェーンの構築と検証を期待していましたが、Windows環境ではその期待通りのチェーンが構築されず、テストが失敗し、結果としてビルドが完了しないという状況が発生していました。

このコミットの目的は、テストケースを調整することで、Windows環境とGoのネイティブコードの両方が AddTrust ルート証明書に正しくチェーンを構築できるようにし、テストの信頼性を確保し、Windows上でのビルドを成功させることにありました。

前提知識の解説

このコミットの理解を深めるためには、以下の技術的な概念を理解しておく必要があります。

1. X.509 証明書と公開鍵基盤 (PKI)

  • X.509 証明書: 公開鍵とそれに対応するエンティティ(個人、サーバー、組織など)の身元情報を結びつけるデジタル文書です。認証局(CA)によって署名され、その正当性が保証されます。
  • 公開鍵基盤 (PKI): デジタル証明書の発行、管理、失効、および利用を可能にするためのフレームワークです。PKIは、公開鍵暗号方式を用いて、通信の機密性、完全性、認証、否認防止を実現します。

2. 証明書チェーン (Certificate Chain)

  • リーフ証明書 (Leaf Certificate): エンドエンティティ(例: ウェブサーバー)に直接発行される証明書です。
  • 中間CA証明書 (Intermediate CA Certificate): ルートCA証明書とリーフ証明書の間にある証明書です。ルートCAが直接すべてのリーフ証明書に署名するのではなく、中間CAに署名権限を委譲することで、セキュリティと管理の柔軟性を高めます。
  • ルートCA証明書 (Root CA Certificate): 証明書チェーンの最上位に位置する自己署名証明書です。オペレーティングシステムやブラウザに事前に組み込まれており、信頼の基点となります。
  • チェーンの構築: 証明書の検証プロセスでは、リーフ証明書から始まり、その発行元の中間CA証明書をたどり、最終的に信頼されたルートCA証明書に到達するパス(チェーン)を構築します。このチェーンが完全に信頼できる場合にのみ、リーフ証明書は有効と判断されます。

3. crypto/x509 パッケージ (Go言語)

Go言語の標準ライブラリである crypto/x509 パッケージは、X.509証明書のエンコード/デコード、解析、および検証機能を提供します。このパッケージは、TLSクライアントやサーバーが証明書を検証する際に内部的に利用されます。特に、x509.Verify 関数は、与えられた証明書とオプションの検証オプションに基づいて、証明書チェーンの構築と検証を行います。

4. AddTrust External CA RootCOMODO RSA Certification Authority

これらは、広く信頼されているルート認証局の名称です。

  • AddTrust External CA Root: Sectigo(旧Comodo CA)が所有するルート証明書の一つで、多くのSSL/TLS証明書の信頼の基点となっています。
  • COMODO RSA Certification Authority: 現在はSectigo RSA Certification Authorityとして知られており、これもまた広く利用されている中間CA証明書またはルート証明書です。

これらのルート証明書は、多くのOSやブラウザの信頼ストアにプリインストールされており、それらによって署名された証明書は自動的に信頼されます。

5. クロスプラットフォームビルドとOS固有の挙動

Go言語はクロスプラットフォーム開発を強力にサポートしていますが、OS固有のAPIや挙動に依存する部分も存在します。証明書管理はその典型例です。Windowsは独自の証明書ストア(Windows Certificate Store)を持ち、証明書の検索やチェーン構築に独自のAPIを使用します。これに対し、Goの crypto/x509 パッケージは、可能な限りOSに依存しない形で証明書を処理しようとしますが、特定の条件下ではOSの挙動が影響を与えることがあります。今回の問題は、まさにこのOS固有の挙動の違いがテストに影響を与えたケースです。

技術的詳細

このコミットは、src/pkg/crypto/x509/verify_test.go ファイル内の verifyTests というテストケース定義に焦点を当てています。このファイルは、crypto/x509 パッケージの証明書検証ロジックが正しく機能するかどうかを検証するための単体テストを含んでいます。

verifyTests は、verifyTest 構造体のスライスであり、各要素が特定の証明書検証シナリオを定義しています。各 verifyTest には、以下のフィールドが含まれます。

  • leaf: 検証対象となるリーフ証明書。
  • intermediates: 中間CA証明書のリスト。
  • roots: 信頼されたルート証明書のリスト。
  • currentTime: 検証時の時刻(有効期限のチェック用)。
  • dnsName: 検証対象のDNS名(ホスト名のチェック用)。
  • expectedChain: 期待される証明書チェーンのSubject Common Name (CN) のリスト。

問題が発生していたのは、moipLeafCert を使用するテストケースでした。このテストケースは、SHA-384ハッシュアルゴリズムを使用する中間証明書が正しく機能するかどうかを検証することを目的としていました。

元の設定では、このテストケースは comodoIntermediateSHA384 を中間証明書として、comodoRSARoot をルート証明書として使用していました。しかし、Windows環境では、Goのネイティブな検証ロジックが comodoRSARoot ではなく AddTrust External CA Root を最終的な信頼の基点としてチェーンを構築しようとしていました。この不一致がテストの失敗、ひいてはビルドの失敗につながっていました。

このコミットの技術的な解決策は、テストケースの期待値をWindowsの挙動に合わせることで、両方の環境でテストが成功するようにすることです。具体的には、以下の変更が行われました。

  1. 中間証明書の追加: intermediates リストに comodoRSAAuthority が追加されました。これは、comodoRSARoot が実際には中間CAとして機能し、その上位に AddTrust ルートが存在するという現実の証明書階層を反映するためと考えられます。
  2. ルート証明書の変更: roots リストが comodoRSARoot から addTrustRoot に変更されました。これにより、テストは明示的に AddTrust ルートを信頼の基点として期待するようになります。
  3. 期待されるチェーンの更新: expectedChain リストに "AddTrust External CA Root" が追加されました。これは、検証が成功した場合に期待される最終的なチェーンに AddTrust ルートが含まれることを示します。
  4. 定数名の変更: comodoRSARoot 定数が comodoRSAAuthority にリネームされました。これは、その証明書がルートではなく中間CAとして機能するという役割をより正確に反映するためです。
  5. addTrustRoot 定数の追加: AddTrust External CA Root 証明書のPEMエンコードされたデータを含む新しい定数 addTrustRoot が追加されました。

これらの変更により、テストケースはWindows環境での証明書チェーン構築の現実的な挙動と一致するようになり、テストが期待通りにパスするようになりました。

コアとなるコードの変更箇所

--- a/src/pkg/crypto/x509/verify_test.go
+++ b/src/pkg/crypto/x509/verify_test.go
@@ -213,8 +213,8 @@ var verifyTests = []verifyTest{\n 		// Check that SHA-384 intermediates (which are popping up)\n 		// work.\n 		leaf:          moipLeafCert,\n-		intermediates: []string{comodoIntermediateSHA384},\n-		roots:         []string{comodoRSARoot},\n+		intermediates: []string{comodoIntermediateSHA384, comodoRSAAuthority},\n+		roots:         []string{addTrustRoot},\n 		currentTime:   1397502195,\n 		dnsName:       \"api.moip.com.br\",\n 
@@ -223,6 +223,7 @@ var verifyTests = []verifyTest{\n 				"api.moip.com.br",\n 				"COMODO RSA Extended Validation Secure Server CA",\n 				"COMODO RSA Certification Authority",\n+				"AddTrust External CA Root",\n 			},\n 		},\n 	},\n@@ -1062,7 +1063,7 @@ jwLI5jqmBNFI+8NKAnb9L9K8E7bobTQk+p0pisehKxTxlgBzuRPpwLk6R1YCcYAn\n pLwltum95OmYdBbxN4SBB7SC\n -----END CERTIFICATE-----`\n \n-const comodoRSARoot = `-----BEGIN CERTIFICATE-----\n+const comodoRSAAuthority = `-----BEGIN CERTIFICATE-----\n MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv\n MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk\n ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF\n@@ -1094,3 +1095,29 @@ B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx\n PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR\n pu/xO28QOG8=\n -----END CERTIFICATE-----`\n+\n+const addTrustRoot = `-----BEGIN CERTIFICATE-----\n+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\n+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\n+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\n+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1QQGEwJTRTEU\n+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\n+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\n+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\n+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\n+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\n+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\n+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\n+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\n+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\n+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\n+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\n+cnVzdCBBQjEmMCQGAgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290ggEBMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\n+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\n+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\n+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\n+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n+-----END CERTIFICATE-----`

コアとなるコードの解説

このコミットの核心は、src/pkg/crypto/x509/verify_test.go ファイル内の verifyTests 配列における特定のテストケースの修正です。

  1. intermediatesroots の変更:

    • 元のコードでは、intermediatescomodoIntermediateSHA384 のみが指定され、roots には comodoRSARoot が指定されていました。
    • 変更後、intermediates には comodoIntermediateSHA384 に加えて comodoRSAAuthority が追加されました。これは、comodoRSAAuthority が実際には AddTrust External CA Root の下位に位置する中間CAであることを示唆しています。
    • rootscomodoRSARoot から addTrustRoot に変更されました。これにより、テストは明示的に AddTrust External CA Root を信頼されたルートとして使用するようになります。
  2. expectedChain の更新:

    • 元の expectedChain には "AddTrust External CA Root" が含まれていませんでした。
    • 変更後、expectedChain"AddTrust External CA Root" が追加されました。これは、証明書検証が成功した場合に、最終的なチェーンにこのルート証明書が含まれることをテストが期待するようになったことを意味します。
  3. 定数名の変更と追加:

    • const comodoRSARootconst comodoRSAAuthority にリネームされました。これは、この証明書がルートではなく、より正確には中間認証局であることを明確にするための変更です。
    • 新たに const addTrustRoot が追加され、AddTrust External CA Root のPEMエンコードされた証明書データが格納されました。これにより、テストケース内でこのルート証明書を直接参照できるようになります。

これらの変更は、Windows環境における証明書チェーン構築の挙動とGoのネイティブな検証ロジックとの間の不一致を解消するために行われました。Windowsは、Goのテストが当初期待していた comodoRSARoot ではなく、AddTrust External CA Root を最終的な信頼の基点としてチェーンを構築していました。このコミットは、テストケースの期待値をWindowsの実際の挙動に合わせることで、テストが両方の環境で一貫してパスするように調整しました。

これにより、Goの crypto/x509 パッケージが異なるOS環境下でも、標準的な証明書チェーンの検証ロジックに従って正しく機能することが保証され、クロスプラットフォームな互換性が向上しました。

関連リンク

参考にした情報源リンク

  • X.509 Certificate: https://en.wikipedia.org/wiki/X.509
  • Certificate chain: https://en.wikipedia.org/wiki/Chain_of_trust
  • Go crypto/x509 package documentation: https://pkg.go.dev/crypto/x509
  • AddTrust External CA Root: (一般的な情報源、例: SSLストアのドキュメントなど)
  • COMODO RSA Certification Authority: (一般的な情報源、例: SSLストアのドキュメントなど)
  • Windows Certificate Store: (Microsoft Learnなど)
  • Go言語のクロスコンパイルとOS固有の挙動に関するドキュメント (Go公式ドキュメントなど)