Validating signature trust with gpg

cryptographydigital-signaturesgpgpgp

We would like to use gpg signatures to verify some aspects of our
system configuration management tools. Additionally, we would like to
use a "trust" model where individual sysadmin keys are signed with a
master signing key, and then our systems trust that master key (and
use the "web of trust" to validate signatures by our sysadmins).

This gives us a lot of flexibility, such as the ability to easily
revoke the trust on a key when someone leaves, but we've run into a
problem. While the gpg command will tell you if a key is
untrusted, it doesn't appear to return an exit code indicating this
fact. For example:

# 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 <someone@example.com>"
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

The part we care about is this:

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

The exit code returned by gpg in this case is 0, despite the trust
failure:

# echo $?
0

How do we get gpg to fail in the event that something is signed with
an untrusted signature?

I've seen some suggestions that the gpgv command will return a proper exit code, but unfortunately gpgv doesn't know how to fetch keys from keyservers. I guess we can parse the status output (using –status-fd) from gpg, but is there a better way?

Best Answer

This is what ended up with:

#!/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

This looks for the trust information that gpg outputs on --status-fd. The script exits with an error in the presence of an untrusted signature (or invalid/no signature):

$ 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 <testuser@example.com>"
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

The script exits with no error in the presence of a valid, trusted signature:

$ 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
Related Topic