署名されたgitコミットを確認していますか?


95

新しいバージョンでgitは、PGPキーを使用して(タグに加えて)個々のコミットに署名できます。

git commit -m "some message" -S

またgit log--show-signatureオプションを使用して、これらの署名をの出力に表示できます。

$ git log --show-signature
commit 93bd0a7529ef347f8dbca7efde43f7e99ab89515
gpg: Signature made Fri 28 Jun 2013 02:28:41 PM EDT using RSA key ID AC1964A8
gpg: Good signature from "Lars Kellogg-Stedman <lars@seas.harvard.edu>"
Author: Lars Kellogg-Stedman <lars@seas.harvard.edu>
Date:   Fri Jun 28 14:28:41 2013 -0400

    this is a test

しかし、の出力をgrepする以外に、特定のコミットのプログラムで署名を検証する方法はありgit logますか?私は同等のコミットを探していますgit tag -v-特定のコミットに有効な署名があったかどうかを示す終了コードを提供するもの。


1
私はそれがあるべきだと思うgit commit ...git log ...。私の知る限り、透過的gpgに渡されるサブコマンドを追加していgitません...テストするレポはありませんが、git show --show-signature <commitish>機能しますか?
twalberg 2013年

show_signature出力に追加するだけです(github.com/git/git/blob/master/log-tree.c#L370を参照)。
Emil Sit 2013年

注:あなたはすぐに持っています--rawのためにgit verify-tag/ git verify-commit以下の私の回答を
VonC '16

1
注:GIT 2.11(Q4 2016)では、git log追加のステータス・コードを紹介しEXYRのためにERRSIGEXPSIGEXPKEYSIG、およびREVKEYSIG程度のユーザーがいることを、%G?より多くの情報を取得します。以下の編集済みの回答を
VonC '28

1
Git 2.26(2020年第1四半期)では、/のgpg.minTrustLevel使用時に新しい構成が役立ちます。以下の私の編集した回答を参照しください。git verify-tagverify -commit
VonC

回答:


114

私が行ったよう念の誰かが、検索エンジンを介してこのページに来る:質問が投稿されましたので、新しいツールが2年間で利用可能になっていますがあり、この作業のためのgitコマンドは、現在、次のとおりです。git verify-commitgit verify-tagコミットを確認するために使用することができ、それぞれタグ。


34

注:最高のgit 2.5へ、git verify-commitそしてgit verify-tag唯一の人間が読めるメッセージを表示します。
チェックを自動化したい場合は、git 2.6+(2015年第3四半期)が別の出力を追加します。

参照e18443eコミットaeff29dコミットca194d5コミット434060eをコミット8e98e5fコミットa4cc18fコミットd66aeffコミットにより(2015年6月21日)をブライアンM。カールソン(bk2204
(による合併Junio C浜野- gitster-ba12cb2をコミットし、2015年8月3日)

verify-tag/ verify-commit:生のgpgステータス情報を出力するオプションを追加します

verify-tag/ verify-commitデフォルトでは、標準エラーに人間が読める出力を表示します。
ただし、機械可読であり、署名ポリシーの自動実装を可能にする生のgpgステータス情報にアクセスすることも有用です

人間が読める形式ではなく、標準エラーに関するgpgステータス情報を生成する--rawオプションを追加しますverify-tag

プラス:

verify-tag署名は正しいが、キーが信頼できない場合は、正常に終了します。verify-commit失敗して終了します。
この行動の相違は予想外であり、望ましくありません。以前に存在していた
ためverify-tag、失敗したテストを追加して、verify-commitshare verify-tagの動作を確認します。


git 2.9(2016年6月)git merge docを更新:

Keller Fuchs( ``)によるコミット05a5869(2016年5月13日)を参照してください。 協力者:ジュニオC浜野((による合併Junio C浜野- -be6ec17をコミット 2016年5月17日)
gitster
gitster

--verify-signatures:
--no-verify-signatures:

マージされるサイドブランチのチップコミットが有効なキー、つまり有効なuidを持つキーで署名されていることを確認します。デフォルトの信頼モデルでは、これは署名キーが信頼できるキーによって署名されていることを意味します。
サイドブランチのチップコミットが有効なキーで署名されていない場合、マージは中止され
ます。


Git 2.10を更新(2016年第3四半期)

Linus Torvalds()によるcommit b624a3e(2016年8月16日)を参照してください。(合併によりJunio C浜野- -83d9eb0コミットし、2016年8月19日)をtorvalds
gitster

gpg-interface:pgp署名を検証するときに「長い」キー形式の出力を優先する

git log --show-signature」およびPGP署名の検証ステータスを表示するその他のコマンドは、32ビットのキーIDが前世紀に相当するため、より長いキーIDを表示するようになりました。

Linusのオリジナルは、過去に行き詰まっているバイナリディストリビューターが古いコードベースにそれを持ちたい場合に備えて、メンテナンストラックに適用するようにリベースされました。


Git 2.11+(2016年第4四半期)はさらに正確になります。

Michael J Gruber(によるコミット661a180(2016年10月12日)を参照してください。(合併によりJunio C浜野- -56d268bコミットし、2016年10月26日)mjg
gitster

%G?」プリティフォーマット指定子に示されているGPG検証ステータスは、有効期限が切れたキーによって作成された署名、失効したキーによって作成された署名などを区別するのに十分なほど豊富ではありませんでし
それらを表すために新しい出力文字が割り当てられました

gpg2にdoc/DETAILSよると:

各シグネチャコードの一方のみのためGOODSIGBADSIGEXPSIGEXPKEYSIGREVKEYSIG又はERRSIG放射されます。

git pretty-formatドキュメントは今、次のとおりです。

  • ' %G?':表示
    • " G"は、有効な(有効な)署名です。
    • B」は署名が悪い場合
    • " U"有効性が不明な適切な署名の場合、
    • X」は、有効期限が切れた適切な署名の場合、
    • " Y"は、期限切れの鍵によって作成された適切な署名の場合、
    • " R"失効した鍵によって作成された適切な署名の場合、
    • " E"署名を確認できない場合(例:鍵がない場合)、 "N"の場合は署名なし

Git 2.12(2017年第1四半期)「git tag」と「git verify-tagは、GPG検証ステータスを「--format=<placeholders>」の出力形式にする方法を学びました

Santiago Torres()によるcommit 4fea72fcommit 02c5433commit ff3c8c8(2017年1月17日)を参照してください。Lukas Puehringer( ``)によるcommit 07d347ccommit 2111aa7commit 94240b9(2017年1月17日)を 参照してください。(合併によりJunio C浜野- -237bdd9コミットし、2017年1月31日)をSantiagoTorres

gitster

を追加--formatするgit tag -vと、GPG検証のデフォルト出力がミュートされ、代わりにフォーマット済みタグオブジェクトが出力されます。
これにより、呼び出し元はGPG検証時に参照/タグのタグ名とタグオブジェクトヘッダーのタグ名をクロスチェックできます。


Git 2.16(2018年第1四半期)では、merge.verifySignatures構成変数を使用して、コミット署名の検証をさらに自動化できます。

コミット7f8ca20コミットca779e8(2017年12月10日)、Hans Jerry Illikainen( ``)を参照してください。
(合併によりJunio C浜野- gitster-0433d53コミットし、2017年12月28日)を

merge:設定オプションを追加 verifySignatures

git merge --verify-signatures マージされるブランチのティップコミットが適切に署名されていることを確認するために使用できますが、毎回それを指定するのは面倒です。

この動作をデフォルトで有効にする構成オプションを追加します--no-verify-signatures。これはによってオーバーライドできます。

git merge設定のmanページには、今読み取ります。

merge.verifySignatures:

trueの場合、これは--verify-signaturesコマンドラインオプションと同じです。


Git 2.19(2018年第3四半期)はさらに役立ちます。これは、「git verify-tag」と「git verify-commit」が、基になる「gpg --verify」の終了ステータスを使用して、見つかった不良または信頼できない署名を通知するように教えられているためです。

注:Git 2.19では、gpg.formatopenpgp」または「x509」に設定できます。gpg.<format>.programこれは、フォーマットを処理するために使用するプログラムを指定するために使用されます)、CMSを使用したx.509証明書を「gpgsmopenpgp経由での代わりに使用できるようにします「gnupg

Junio C Hamano()によるcommit 4e5dc9c(2018年8月9日)を参照してください。 支援者:Vojtech Myslivec(ブライアンm。カールソン(ジェフキング((合併によりJunio C浜野- -4d34122コミットし、2018年8月20日)をgitster
VojtechMyslivecbk2204peff
gitster

gpg-interface:終了ステータスをgpg呼び出し元に戻す

2015年半ばにv2.6.0-rc0〜114頃にgpg-interface APIが署名付きタグの署名検証コードパスと署名済みコミットのサポートを統合したときに、誤ってGPG署名検証を緩めました。

この変更の前は、署名されたコミットはGgpg --verify」プロセスの終了ステータスを無視しながら「」というGPGからのフード署名を探すことで検証され、署名付きタグは単に"gpg --verify「」の終了ステータスを渡すことで検証されていました。

現在使用している統合コードは、「gpg --verify」の終了ステータスを無視し、キーに設定された信頼に関係なく、署名が有効期限が切れていないキーと一致すると、検証に成功します(つまり、「G」に加えて「」、「」、「」、「U」を信頼します)。

基になる " gpg --verify"(または " gpg.program"構成変数で指定されたカスタムコマンド)が失敗した場合、これらのコマンドは終了ステータスで失敗を通知します。
これは基本的に、下位互換性のない方法で動作を変更し、信頼されていないキーで作成された署名を正しく検証した場合でも、それが「gpg --verify」の動作であるため拒否します。

ユーザーが私たちに与える可能性のある「」の周りの不適切に記述されたラッパーをキャッチするために、「gpg」から得られたゼロの終了ステータスをコードが引き続きオーバーライドすることに注意してください。 。gpg.programgpg

Uこのフォールバックコードから" " ntrustedサポートを除外することもできますが、1つのコミットで2つの下位互換性のない変更が行われるため、ここではそれを避けましょう。
必要に応じて、フォローアップ変更を行うことができます。


暗号化を行う前に、キーを信頼/署名する必要があります

信頼側では、進歩があります。Git2.26
(2020年第1四半期)では、gpg.minTrustLevel構成変数が導入され、さまざまな署名検証コードパスに必要な最小の信頼レベルを伝えています。

Hans Jerry Illikainen(によるコミット54887b4(2019年12月27日)を参照してください。Junio C Hamanoによって統合--illikainen
gitster11ad30bコミット 2020年1月30日)

gpg-interface:構成オプションとしてminTrustLevelを追加します

サインオフ:Hans Jerry Illikainen

以前は、マージ操作とプル操作の署名検証で、キーの信頼レベルが次のいずれかであるかどうかが確認されていました TRUST_NEVERかが確認さTRUST_UNDEFINEDれていましたverify_merge_signature()

その場合、プロセスはdie()'d。

署名検証を行った他のコードパスは、完全にからの戻りコードに依存していましたcheck_commit_signature()

また、信頼レベルに関係なく、適切なキーで作成された署名は、 check_commit_signature()

この動作の違いはあります間、例えば(でもそれはない操作のために、誤って自分のキーリングにあるキーの信頼レベルは常にGitリポジトリによって検討されていることを前提とするユーザーを誘導verify-commitまたはverify-tag

それが機能した方法gpg-interface.cは、キー/署名ステータス最低2つの信頼レベルからの結果を構造体のresultメンバーに格納することでしたsignature_check(遭遇したこれらのステータス行の最後はに書き込まれましたresult)。

これらは、それぞれGPGのサブセクションGeneral status codesKey relatedに記載されています。

GPGのドキュメントでは、TRUST_ statusコードについて次のように述べています


これらはいくつかの同様のステータスコードです。

- TRUST_UNDEFINED <error_token>
- TRUST_NEVER     <error_token>
- TRUST_MARGINAL  [0  [<validation_model>]]
- TRUST_FULLY     [0  [<validation_model>]]
- TRUST_ULTIMATE  [0  [<validation_model>]]

適切な署名の場合、これらのステータス行の1つが発行され、署名の作成に使用されたキーの有効性を示します。
エラートークンの値は現在gpgsmによってのみ出力されます。


私の解釈では、信頼レベルは概念的にはキーや署名の有効性とは異なります。

それはまた、古いコードの前提となっているようだcheck_signature()「のところ結果G」(のようにGOODSIG)と「Uのように(」TRUST_NEVERまたはTRUST_UNDEFINED)両方とも成功と見なされたです。

' U'の結果が特別な意味を持つ2つのケースはverify_merge_signature()(これが原因gitとなった場合die())とformat_commit_one()%G?フォーマット指定子の出力に影響した場合)でした。

TRUST_ statusラインの処理をリファクタリングすることは、ユーザーが個々の部分を持つのではなく、グローバルに適用される最小の信頼レベルを構成できるようにするのが理にかなっていると思いますgit(例えば、マージなど)のそれ自体を行わせる(下位互換性のある猶予期間を除く)のでは。

また、キー/署名ステータスと同じ構造体メンバーに信頼レベルを保存しないことも理にかなっていると思います。

TRUST_ statusコードの存在は署名が適切であることを意味しますが(上記のスニペットの最初の段落を参照)、GPGからのステータス行の順序は明確に定義されていません。したがって、signature_check構造の同じメンバーに格納されている場合、信頼レベルがキー/署名のステータスで上書きされる可能性があると考えられます。

このパッチでは、新しい構成オプションが導入されていますgpg.minTrustLevel

信頼レベルの検証を統合しgpg-interface.c、新しいtrust_levelメンバーをsignature_check構造に追加します。

下位互換性はverify_merge_signature()、ユーザー設定可能な変数gpg.minTrustLevelが設定されていない場合に拒否するという以前の動作TRUST_UNDEFINEDと、TRUST_NEVER適用されます。

一方、gpg.minTrustLevel設定されている場合、その値は古い動作を上書きします。

同様に、%G?フォーマット指定子は「ショーを続けますU」の信頼レベルを持つキーで作られた署名のTRUST_UNDEFINEDTRUST_NEVER,にもかかわらず、「U」文字は、もはやには存在しないresultのメンバーsignature_check構成。

新しいフォーマット指定子、 %GT署名のすべての可能な信頼レベルを表示したいユーザーのために、も導入されました。

別のアプローチは、信頼レベルの要件を単に verify_merge_signature()でした。

これにより、署名の検証を実行するgitの他の部分と動作が一致するようになります。

ただし、鍵の署名に最低限の信頼レベルを要求することは、実際の使用例のようです。

たとえば、Qubes OSプロジェクトで使用されているビルドシステムは現在、gitタグの署名に使用されるキーの最小信頼レベルをアサートするために、verify-tagからの生の出力を解析しています

git config gpgmanページには今含まれています:

gpg.minTrustLevel:

署名検証の最小信頼レベルを指定します。
このオプションが設定されていない場合、マージ操作の署名検証には、少なくともmarginal信頼できるキーが必要です。
署名検証を実行する他の操作には、少なくともundefined信頼できる鍵が必要です。
このオプションを設定すると、すべての操作に必要な信頼レベルが上書きされます。サポートされている値、重要度の高い順に:

  • undefined
  • never
  • marginal
  • fully
  • ultimate

Gitの2.26(Q1 2020年)、「git show」などが六角にそれを与えるように修正されたそのエラー出力、中生の形式でオブジェクトの名前を与えました。

show_one_mergetag:親でないものを16進形式で出力します。

マージタグが親以外の名前を付けると、浅いクローンの後に発生する可能性があり、そのハッシュは以前に生データとして出力されていました。
代わりに16進形式で印刷してください。

git -C shallow log --graph --show-signature -n1 plain-shallow後にテスト済みgit clone --depth 1 --no-local . shallow


Git 2.27(2020年第2四半期)では、GnuPGとインターフェースするコードがリファクタリングされました。

コミット6794898コミットf1e3df3(04 Mar 2020)by Hans Jerry Illikainen(illikainen)を参照してください。
(合併によりJunio C浜野- gitster-fa82be9コミット 2020年3月27日)

gpg-interfacecheck_signature()GPG検証を優先

サインオフ:Hans Jerry Illikainen

このコミットは、verify_signed_buffer()outsideの使用をリファクタリングして、代わりgpg-interface.cに使用しcheck_signature()ます。

またverify_signed_buffer()、によって内部的にのみ呼び出されるため、ファイルローカル関数にもなりますcheck_signature()

以前は、GPG署名検証を実行するためにGitの異なる部分で使用される2つのグローバルスコープ関数がverify_signed_buffer()ありましたcheck_signature()

現在check_signature()は使用されています。

このverify_signed_buffer()関数は、MichałGórnyによって説明されているように、署名の重複を防ぎません。

代わりに、GPGからのGOODSIGエラーのない終了コードと少なくとも1つのステータスフィールドの存在のみを保証します。

これは、check_signature()複数の署名が検出された場合にエラーを返すのとは対照的です。

検証のレベルが低いverify_signed_buffer()と、呼び出し側がGPGステータスメッセージのさまざまな部分を解析および検証しない場合、その使用が問題になります。

そして、これらのメッセージの処理gpg-interface.cは、関数で予約する必要があるタスクのようcheck_signature()です。

さらに、を使用verify_signed_buffer()すると、GPGステータスラインの内容に依存する新しい機能を導入することが難しくなります。

これで、署名検証を行うすべての操作で、への単一のエントリポイントが共有されgpg-interface.cます。

これにより、同じ程度の検証を実行しない奇妙なエッジケースがなくても、GPG署名検証の変更された機能や追加機能をGitのすべての部分に簡単に伝達できます


4

コードをざっと見ると、そのような直接的な方法はないことがわかります。

gitソースのすべてのテストは、grep出力のpingに依存していますgit show(テストについては、t / t7510-signed-commit.shを参照してください)。

--pretty "%H %G?%"簡単に解析できるように、出力をカスタマイズできます。

git merge署名の検証を要求できるように見えますが、繰り返しになりますが、テストはこれに依存していますgrept / t7612-merge-verify-signatures.shを参照)。無効なシグネチャは不正なシグネチャでgit merge終了するように見えるので、今日どこかでテストマージを実行し、そのマージを破棄することでこれを回避できる可能性がありますが、grepを呼び出すよりも悪いようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.