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

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

このコミットは、Go言語のcrypto/x509パッケージにおけるWindowsビルドの不具合を修正するものです。具体的には、Goの証明書チェーン構築動作とWindows Cryptographic API (CAPI) の動作が異なるために失敗していたテストを、一時的にスキップするよう変更しています。

コミット

Goのcrypto/x509パッケージがWindows環境で証明書チェーンを構築する際の動作が、WindowsのネイティブAPIであるCAPIと異なるために発生していたテストの失敗を回避するためのコミットです。この変更は、問題のあるテストケースにsystemSkip: trueを設定することで、Windows上でのテスト実行時にそのテストをスキップするようにします。これは一時的な回避策であり、GoのコードをCAPIの動作に合わせるという根本的な修正は、Go 1.3リリース前の大規模な変更となるため、このコミットでは見送られています。

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

https://github.com/golang/go/commit/ea3353b64c04a12a284fba10f6927e970849a33a

元コミット内容

commit ea3353b64c04a12a284fba10f6927e970849a33a
Author: Adam Langley <agl@golang.org>
Date:   Fri Mar 28 10:36:52 2014 -0400

    crypto/x509: unbreak Windows build.
    
    This change sets systemSkip on a test where Go and CAPI have different
    chain building behaviour. CAPI is correct, but aligning the Go code is
    probably too large a change prior to 1.3.
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/81620043

変更の背景

このコミットの背景には、Go言語のcrypto/x509パッケージが証明書チェーンを構築する際の内部ロジックと、Windowsオペレーティングシステムが提供する暗号化サービスであるCAPI(Cryptographic API)が証明書チェーンを構築する際のロジックとの間に、互換性の問題が存在したことがあります。

具体的には、ある特定のテストケースにおいて、Goのcrypto/x509が構築する証明書チェーンとCAPIが構築する証明書チェーンが異なる結果となり、その結果としてテストが失敗していました。コミットメッセージによると、「CAPIが正しい」とされており、GoのコードがCAPIの動作に合わせるべきであるという認識がありました。しかし、この修正はGo 1.3リリース前に行うにはあまりにも大規模な変更であると判断されました。

そのため、ビルドプロセスがWindows上で中断されるのを防ぐため、一時的な回避策として、問題を引き起こしているテストをWindows環境でスキップする決定がなされました。これにより、開発者はGoのWindowsビルドが継続して動作することを保証しつつ、根本的な問題の解決を将来のリリースに持ち越すことができました。

前提知識の解説

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

  • X.509証明書: X.509は、公開鍵証明書の形式を定義するITU-T(国際電気通信連合電気通信標準化部門)の標準です。インターネット上での身元確認やデータの暗号化、デジタル署名などに広く利用されています。ウェブサイトのSSL/TLS通信、電子メールの署名、コード署名など、様々なセキュリティプロトコルの基盤となっています。X.509証明書には、公開鍵、所有者の識別情報、発行者の識別情報、有効期間、発行者のデジタル署名などが含まれます。

  • 証明書チェーン (Certificate Chain): デジタル証明書は、その信頼性を証明するために、通常、別の信頼された証明書によって署名されています。この署名の連鎖を「証明書チェーン」と呼びます。チェーンの最上位には、自己署名された「ルート証明書」があり、これはオペレーティングシステムやブラウザに事前に組み込まれて信頼されています。ルート証明書の下には「中間証明書」が続き、最終的にウェブサイトやサーバーなどの「エンドエンティティ証明書」に到達します。証明書チェーンの検証とは、エンドエンティティ証明書からルート証明書まで、各証明書が正しく署名され、有効期限内であり、失効していないことを確認するプロセスです。

  • Windows Cryptographic API (CAPI): CAPIは、Microsoft Windowsオペレーティングシステムが提供する一連の暗号化サービスです。アプリケーションはCAPIを利用して、データの暗号化・復号化、デジタル署名の生成・検証、ハッシュ計算、乱数生成、そして証明書の管理や検証など、様々な暗号化操作を実行できます。CAPIは、Windowsの証明書ストアと密接に連携しており、システムにインストールされている信頼されたルート証明書や中間証明書を利用して、証明書チェーンの構築と検証を行います。

  • Goのcrypto/x509パッケージ: Go言語の標準ライブラリの一部であり、X.509証明書の解析、検証、生成などの機能を提供します。このパッケージは、TLS(Transport Layer Security)通信やその他のセキュリティ関連アプリケーションで、証明書を扱う際に中心的な役割を果たします。crypto/x509は、証明書チェーンの構築と検証も独自に実装しており、この部分がCAPIとの間で動作の差異を生じさせることがあります。

  • systemSkip (Goテストフレームワークの機能): Goのテストフレームワークには、特定の条件(例: 特定のオペレーティングシステム、特定のアーキテクチャなど)下でテストをスキップするメカニズムがあります。systemSkipは、テストケースの定義内で使用されるフィールドで、これがtrueに設定されると、そのテストケースは現在のシステム環境では実行されずにスキップされます。これは、環境固有のバグや未対応の機能がある場合に、CI/CDパイプラインが中断されるのを防ぐための一時的な解決策として利用されます。

技術的詳細

このコミットの技術的な核心は、Goのcrypto/x509パッケージが証明書チェーンを構築する際のロジックと、WindowsのCAPIが同じ目的で用いるロジックとの間の不一致にあります。コミットメッセージとコードの変更点から、この不一致は特に「重複したGeoTrustエントリ」を含む証明書チェーンの構築に関連していることが示唆されています。

Goのcrypto/x509パッケージは、証明書チェーンを検証する際に、信頼されたルート証明書から始まり、中間証明書を介して最終的なエンドエンティティ証明書に至るパスを構築しようとします。このプロセスでは、利用可能な証明書ストア(システムストアやアプリケーション固有のストア)から適切な証明書を見つけ出し、それらを連結していきます。

一方、WindowsのCAPIも同様に証明書チェーンを構築しますが、その内部アルゴリズムやヒューリスティックはGoのそれとは異なる場合があります。このコミットで問題となったのは、CAPIが特定の状況下で「重複したGeoTrustエントリ」を含むチェーンをGoとは異なる方法で処理し、結果としてGoのテストが期待するチェーンとは異なるチェーンを構築した、あるいは全く構築できなかった点です。コミットメッセージでは「CAPI is correct」と明記されており、CAPIの動作が標準的または望ましい動作であると認識されています。

この問題に対する即時の解決策として、開発者はsrc/pkg/crypto/x509/verify_test.go内の問題のあるテストケースにsystemSkip: trueというフラグを追加しました。このフラグは、Goのテストランナーに対して、そのテストケースを現在のシステム(この場合はWindows)では実行しないように指示します。これにより、Windows上でのビルドが失敗するのを防ぎ、開発の継続性を確保しました。

しかし、これはあくまで一時的な回避策であり、根本的な解決ではありません。根本的な解決策としては、Goのcrypto/x509パッケージの証明書チェーン構築ロジックをCAPIの動作に合わせる必要があります。コミットメッセージでは、この根本的な修正が「probably too large a change prior to 1.3」(Go 1.3リリース前には大きすぎる変更である可能性が高い)と述べられており、より詳細な検討と実装が将来のリリースに持ち越されることを示唆しています。これは、証明書チェーン構築ロジックの変更が、広範な影響を持つ可能性があり、慎重な設計とテストが必要であることを意味します。

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

変更は単一のファイルsrc/pkg/crypto/x509/verify_test.goに対して行われています。

--- a/src/pkg/crypto/x509/verify_test.go
+++ b/src/pkg/crypto/x509/verify_test.go
@@ -105,6 +105,10 @@ var verifyTests = []verifyTest{\n 			//            twice.\n 			{\"Google\", \"Google Internet Authority\", \"GeoTrust\", \"GeoTrust\"},\n 		},\n+		// CAPI doesn't build the chain with the duplicated GeoTrust\n+		// entry so the results don't match. Thus we skip this test\n+		// until that's fixed.\n+		systemSkip: true,\n 	},\n 	{\n 		leaf:          dnssecExpLeaf,\

この差分は、verifyTestsというテストケースの配列内の特定の要素に、4行の追加が行われたことを示しています。追加されたのはコメントとsystemSkip: true,という行です。

コアとなるコードの解説

変更されたコードは、src/pkg/crypto/x509/verify_test.goファイル内のverifyTestsという変数の一部です。このverifyTestsは、様々な証明書検証シナリオを定義した構造体のスライス(配列)です。

追加された行は、特定のテストケースの定義内に挿入されています。

		// CAPI doesn't build the chain with the duplicated GeoTrust
		// entry so the results don't match. Thus we skip this test
		// until that's fixed.
		systemSkip: true,
  • コメント: 追加されたコメントは、この変更の理由を明確に説明しています。「CAPI doesn't build the chain with the duplicated GeoTrust entry so the results don't match.」(CAPIは重複したGeoTrustエントリを含むチェーンを構築しないため、結果が一致しない。)とあり、Goのcrypto/x509とCAPIの間で、特に「重複したGeoTrustエントリ」を含む証明書チェーンの構築方法に差異があることを示しています。 「Thus we skip this test until that's fixed.」(したがって、修正されるまでこのテストをスキップする。)と続き、このsystemSkip: trueが一時的な回避策であることを明示しています。

  • systemSkip: true,: これがこのコミットの機能的な変更点です。systemSkipは、Goのテストフレームワークが提供するフィールドで、このフィールドがtrueに設定されているテストケースは、テスト実行時にスキップされます。この場合、Windows環境でこのテストが実行されると、Goのビルドプロセスが中断されるのを防ぐために、この特定のテストケースが無視されるようになります。

この変更は、Goのcrypto/x509パッケージの証明書チェーン構築ロジック自体を変更するものではなく、そのロジックとWindows CAPIの間の不一致によって引き起こされるテストの失敗を一時的に抑制するためのものです。これにより、開発者はWindows上での継続的な開発とテストを妨げられることなく進めることができ、根本的な問題の解決は将来のGoのバージョンに委ねられることになります。

関連リンク

参考にした情報源リンク

  • Google Web Search: "Go crypto/x509 CAPI chain building CL 81620043"
  • Go言語の公式ドキュメントおよびソースコード(crypto/x509パッケージ、テストフレームワークのsystemSkipに関する一般的な知識)I have generated the detailed explanation in Markdown format, following all the user's instructions and the specified chapter structure. I have used the commit data and the web search results to provide a comprehensive technical analysis.