[インデックス 10021] ファイルの概要
コミット
- コミットハッシュ: c9bf048337c1a68d467195b3b747073f76e5f063
- 作成者: Mikkel Krautz mikkel@krautz.dk
- コミット日時: 2011年10月18日 15:31:55 +1100
- コミットメッセージ: ld: bump pe linker version to 3.0 to allow code signing
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c9bf048337c1a68d467195b3b747073f76e5f063
元コミット内容
commit c9bf048337c1a68d467195b3b747073f76e5f063
Author: Mikkel Krautz <mikkel@krautz.dk>
Date: Tue Oct 18 15:31:55 2011 +1100
ld: bump pe linker version to 3.0 to allow code signing
The Windows signtool.exe thinks our binaries are 'invalid
Win32 programs' unless the PE linker version field is 3.0
or greater.
This minor change makes it possible to successfully sign
gc-built binaries on Windows.
R=golang-dev, alex.brainman, rsc
CC=golang-dev
https://golang.org/cl/5268045
src/cmd/ld/pe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
変更の背景
このコミットは、GoのWindowsバイナリのコード署名に関する問題を解決するためのものです。2011年当時、Goコンパイラ(gc)によって生成されたWindowsバイナリは、Microsoft Windows SignTool.exeによって「無効なWin32プログラム」として判定されていました。
この問題は、GoのリンカーがPE(Portable Executable)ファイルのヘッダーに設定するリンカーバージョンが3.0未満であったことが原因でした。SignTool.exeは、適切なコード署名を行うために、PEファイルのリンカーバージョンが3.0以上である必要があるという検証を行っていました。
前提知識の解説
PE(Portable Executable)フォーマット
PE(Portable Executable)フォーマットは、Windows上で実行可能ファイル(.exe)、動的リンクライブラリ(.dll)、オブジェクトファイルなどに使用されるファイル形式です。PEフォーマットは、32ビットと64ビットの両方のWindows環境で使用され、UEFIファームウェア環境でも利用されています。
PEファイルのリンカーバージョンフィールド
PEファイルのヘッダー内のIMAGE_OPTIONAL_HEADER構造体には、以下のフィールドが含まれています:
- MajorLinkerVersion: リンカーのメジャーバージョン番号
- MinorLinkerVersion: リンカーのマイナーバージョン番号
これらのフィールドは、そのPEファイルを作成したリンカーのバージョンを示し、ツールの識別、互換性情報、フォレンジック分析などに使用されます。
Windows コード署名(Code Signing)
Windows コード署名は、実行可能ファイルやドライバーの整合性を検証し、作成者の身元を確認するためのデジタル署名技術です。コード署名により、以下の目的を達成できます:
- 整合性の保証: ファイルが改ざんされていないことを確認
- 認証: ソフトウェアの作成者を確認
- 信頼性: ユーザーに対してソフトウェアの信頼性を示す
SignTool.exe
SignTool.exeは、Windows SDK(Software Development Kit)に含まれるコマンドラインツールで、以下の機能を提供します:
- デジタル署名の作成
- 署名の検証
- 署名の削除
- タイムスタンプの追加
技術的詳細
リンカーバージョン3.0の意味
2011年当時、Microsoft SignTool.exeは、PEファイルのリンカーバージョンが3.0未満の場合、そのバイナリを「無効なWin32プログラム」として判定していました。これは、古いリンカーで作成されたファイルが、現代的なコード署名要件に適合していない可能性があることを示していました。
Goリンカーの進化
2011年のGoは、まだ初期段階にあり、Windowsサポートも発展途上でした。このコミットは、GoのWindowsサポートを改善し、エンタープライズ環境でのGoアプリケーションの採用を促進するために重要でした。
当時のGoリンカー(ld)は、C言語で実装されており、src/cmd/ld/pe.c
ファイルにPE関連の処理が含まれていました。現在のGoでは、リンカーはGo言語で実装されており、cmd/link
パッケージに移行されています。
コアとなるコードの変更箇所
変更されたファイル:src/cmd/ld/pe.c
このファイルは、GoのリンカーがPE(Windows実行可能ファイル)形式のファイルを生成する際に使用されるコードです。この変更により、生成されるPEファイルのリンカーバージョンが3.0に設定されるようになりました。
コアとなるコードの解説
この変更は非常にシンプルで、1行の変更(1つの挿入と1つの削除)のみです。具体的には、PEヘッダーのリンカーバージョンフィールドを、以前のバージョン(おそらく2.x)から3.0に変更しています。
変更の詳細:
- PEファイルのIMAGE_OPTIONAL_HEADERのMajorLinkerVersionフィールドを3に設定
- これにより、SignTool.exeがバイナリを有効なWin32プログラムとして認識するようになる
この変更により、以下のことが可能になりました:
- コード署名の成功: GoコンパイラーによってビルドされたWindowsバイナリが、SignTool.exeによって正常に署名可能になる
- エンタープライズ環境での採用: 署名されたバイナリは、企業のセキュリティポリシーに準拠しやすくなる
- 配布の容易さ: 署名されたバイナリは、ユーザーに対してより信頼性の高いソフトウェアとして認識される
関連リンク
- Go言語公式サイト
- Go言語リリース履歴
- PE Format - Microsoft Learn
- SignTool.exe - Microsoft Learn
- Windows Authenticode PE Signature Format
参考にした情報源リンク
- Stack Overflow: Is there any way to sign the windows executables generated by the Go compiler?
- GitHub Issue: GC linker produces invalid windows binaries
- Microsoft Learn: PE Format
- Microsoft Learn: Inside Windows: Win32 Portable Executable File Format in Detail
- Advanced Installer: Microsoft SignTool - Windows code signing tool