[インデックス 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 Root
と COMODO 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の挙動に合わせることで、両方の環境でテストが成功するようにすることです。具体的には、以下の変更が行われました。
- 中間証明書の追加:
intermediates
リストにcomodoRSAAuthority
が追加されました。これは、comodoRSARoot
が実際には中間CAとして機能し、その上位にAddTrust
ルートが存在するという現実の証明書階層を反映するためと考えられます。 - ルート証明書の変更:
roots
リストがcomodoRSARoot
からaddTrustRoot
に変更されました。これにより、テストは明示的にAddTrust
ルートを信頼の基点として期待するようになります。 - 期待されるチェーンの更新:
expectedChain
リストに"AddTrust External CA Root"
が追加されました。これは、検証が成功した場合に期待される最終的なチェーンにAddTrust
ルートが含まれることを示します。 - 定数名の変更:
comodoRSARoot
定数がcomodoRSAAuthority
にリネームされました。これは、その証明書がルートではなく中間CAとして機能するという役割をより正確に反映するためです。 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
配列における特定のテストケースの修正です。
-
intermediates
とroots
の変更:- 元のコードでは、
intermediates
にcomodoIntermediateSHA384
のみが指定され、roots
にはcomodoRSARoot
が指定されていました。 - 変更後、
intermediates
にはcomodoIntermediateSHA384
に加えてcomodoRSAAuthority
が追加されました。これは、comodoRSAAuthority
が実際にはAddTrust External CA Root
の下位に位置する中間CAであることを示唆しています。 roots
はcomodoRSARoot
からaddTrustRoot
に変更されました。これにより、テストは明示的にAddTrust External CA Root
を信頼されたルートとして使用するようになります。
- 元のコードでは、
-
expectedChain
の更新:- 元の
expectedChain
には"AddTrust External CA Root"
が含まれていませんでした。 - 変更後、
expectedChain
に"AddTrust External CA Root"
が追加されました。これは、証明書検証が成功した場合に、最終的なチェーンにこのルート証明書が含まれることをテストが期待するようになったことを意味します。
- 元の
-
定数名の変更と追加:
const comodoRSARoot
がconst comodoRSAAuthority
にリネームされました。これは、この証明書がルートではなく、より正確には中間認証局であることを明確にするための変更です。- 新たに
const addTrustRoot
が追加され、AddTrust External CA Root
のPEMエンコードされた証明書データが格納されました。これにより、テストケース内でこのルート証明書を直接参照できるようになります。
これらの変更は、Windows環境における証明書チェーン構築の挙動とGoのネイティブな検証ロジックとの間の不一致を解消するために行われました。Windowsは、Goのテストが当初期待していた comodoRSARoot
ではなく、AddTrust External CA Root
を最終的な信頼の基点としてチェーンを構築していました。このコミットは、テストケースの期待値をWindowsの実際の挙動に合わせることで、テストが両方の環境で一貫してパスするように調整しました。
これにより、Goの crypto/x509
パッケージが異なるOS環境下でも、標準的な証明書チェーンの検証ロジックに従って正しく機能することが保証され、クロスプラットフォームな互換性が向上しました。
関連リンク
- Go Code Review: https://golang.org/cl/87570044
参考にした情報源リンク
- 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公式ドキュメントなど)