web-dev-qa-db-ja.com

gpgで署名の信頼を検証していますか?

システム構成管理ツールのいくつかの側面を検証するためにgpg署名を使用したいと思います。さらに、個々のsysadminキーがマスター署名キーで署名される「信頼」モデルを使用したいと考えています。その後、システムはそのマスターキーを信頼します(そして、sysadminによる署名を検証するために「web of trust」を使用します)。

これにより、誰かが離れたときにキーの信頼を簡単に取り消すことができるなど、多くの柔軟性が得られますが、問題が発生しました。 gpgコマンドはtellを実行しますが、キーが信頼できない場合は、このことを示す終了コードを返しません。例えば:

# gpg -v < foo.asc
Version: GnuPG v1.4.11 (GNU/Linux)
gpg: armor header: 
gpg: original file name=''
this is a test
gpg: Signature made Fri 22 Jul 2011 11:34:02 AM EDT using RSA key ID ABCD00B0
gpg: using PGP trust model
gpg: Good signature from "Testing Key <[email protected]>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: ABCD 1234 0527 9D0C 3C4A  CAFE BABE DEAD BEEF 00B0
gpg: binary signature, digest algorithm SHA1

私たちが気にする部分はこれです:

gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

この場合にgpgによって返される終了コードは、信頼の失敗にもかかわらず0です。

# echo $?
0

信頼できない署名で何かが署名された場合、どのようにしてgpgを失敗させるのですか?

gpgvコマンドが適切な終了コードを返すという提案をいくつか見ましたが、残念ながらgpgvはキーサーバーからキーを取得する方法を知りません。 gpgからのステータス出力(--status-fdを使用)を解析できると思いますが、もっと良い方法はありますか?

13
larsks

これは、次のようになったものです。

#!/bin/sh

tmpfile=$(mktemp gpgverifyXXXXXX)
trap "rm -f $tmpfile" EXIT

gpg --status-fd 3 --verify "$@" 3> $tmpfile || exit 1
egrep -q '^\[GNUPG:] TRUST_(ULTIMATE|FULLY)' $tmpfile

これは、gpg--status-fdに出力する信頼情報を探します。信頼できない署名(または無効/署名なし)が存在する場合、スクリプトはエラーで終了します。

$ sh checksig sample.sh.bad 
gpg: Signature made Mon 24 Jun 2013 11:42:58 AM EDT using RSA key ID DCD5C569
gpg: Good signature from "Test User <[email protected]>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 6FCD 3CF0 8BBC AD50 662E  5070 E33E D53C DCD5 C569
$ echo $?
1

スクリプトは、有効で信頼できる署名があるとエラーなしで終了します。

$ sh checksig sample.sh.good
gpg: Signature made Mon 24 Jun 2013 11:38:49 AM EDT using RSA key ID 5C2864A8
gpg: Good signature from "Lars Kellogg-Stedman <...>"
$ echo $?
0
6
larsks

だから問題を分割してみましょう:

最初の問題は、あなたがテストしているキーが信頼されていないようです。

gpg -v < test.txt.asc 
gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
gpg: original file name='test.txt'
this is a test
gpg: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpg: using PGP trust model
gpg: Good signature from "John Doe <[email protected]>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 5DD8 216D ADB1 51E8 4326  3ACA 1DED BB72 FE1B 770E
gpg: binary signature, digest algorithm SHA1

これは意図的なものだと思っていました...しかし、修正する前に、gpg -vの代わりにgpgvを使用することをお勧めしますか?すぐに理由がわかります。

$ gpgv < test.txt.asc 
gpgv: keyblock resource `/user/.gnupg/trustedkeys.gpg': file open error
gpgv: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpgv: Can't check signature: public key not found

$ echo $?
2

キーなし、信頼なし...いいえ、キーをtrustedkeys.gpgにインポートします

$ gpg --no-default-keyring --keyring trustedkeys.gpg --import jdoe_pub.gpg
gpg: keyring `/user/.gnupg/trustedkeys.gpg' created
gpg: key FE1B770E: public key "John Doe <[email protected]>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
$ gpgv < test.txt.asc 
gpgv: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpgv: Good signature from "John Doe <[email protected]>"

$ echo $?
0

それが役に立てば幸い

5

2つのオプションが思い浮かびます(出力の解析以外)。

すばやく汚れた方法は、bothgpggpgvの両方を実行することです。 gpgを最初に実行すると、キーがキーサーバーから確実にフェッチされ、次にgpgvで必要な戻りコードが返されます。

よりエレガントで制御された方法(より多くの作業が必要になります)は、署名を検証するために gpgme ライブラリーを使用することです。 Perl[〜#〜] php [〜#〜]Python および-のラッパーはありますが、これはCライブラリです。 ルビー 。 (Python 1つは非常に低いレベルですが、Ruby 1つはいくつかのより高いレベルの抽象化を持っていますが、PerlまたはPHPについては不明です)。

GPGMEライブラリは、私が使用したときにキーサーバーと通信しているように見えますが、確認する必要があります。 Ruby gpgmeライブラリを使用するコードverifyverified_ok?を検索して、署名、およびsig_output_linesの場合、署名が信頼できるかどうかを判断する一部のコード)。

1
Hamish Downer