Scripting with gpg
I have a build script that may, as a matter of convenience, download and build a third-party software package. Before the build script goes into any release, I want to tighten up its security to ensure it verifies the PGP signature on the package.
OK, I can do that in a Makefile using two separate targets: the tarball, and the verified tarball. I thought I could make the latter a link to the former, using something like:
gpg –verify $(TARBALL).asc $(TARBALL) \
&& ln $(TARBALL) $(TARBALL-VERIFIED) \
|| (echo “### Please verify $(TARBALL) ###” && exit 1)
However, this is failing me, because gpg is too trusting:
$ gpg –verify nginx-1.7.3.tar.gz.asc nginx-1.7.3.tar.gz
gpg: Signature made Tue 8 Jul 14:22:56 2014 BST using RSA key ID A1C052F8
gpg: Good signature from “Maxim Dounin <email.suppressed>”
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: B0F4 2533 73F8 F6F5 10D4 2178 520A 9993 A1C0 52F8$ echo $?
0
(OK, now you know the identity of $(TARBALL))
It has not verified that the signature is trusted, but it still thinks all’s well. Ouch! I can verify the signature manually (if rather weakly) but I’d rather not try to script that. Nor do I want to concern myself with issues that might change with each new nginx release, or with changes of pgp keys.
A bit of googling finds this message, from which it appears this was a known bug but fixed in GnuPG version 1.4.2.1 back in 2006 (and yes, my gpg version is more recent than that)! Was that a non-fix that only tells you if it’s a BAD signature or no PGP data at all? That would be no more useful than an MD5 or SHA checksum!
OK folks, what am I missing? What do you use to script the verification of a package?
Posted on August 1, 2014, in pgp, security. Bookmark the permalink. 2 Comments.
http://serverfault.com/questions/293101/validating-signature-trust-with-gpg suggests using status-fd and gives example, but the whole approach looks horrible
Thanks Simon.
On the basis of least-bad-solution, I’ve adapted something from that. With the extra proviso that in this case we’re dealing with a third-party signature, so there’s an additional attack vector to worry about where gpg verifies a good and trusted signature not from the nginx devs but from Evil Hacker.
I now have a separate script to invoke from my Makefile:
#!/bin/sh
# gpg alone isn’t good enough: see
# https://bahumbug.wordpress.com/2014/08/01/scripting-with-gpg/
# Workaround snarfed from
# http://serverfault.com/questions/293101/validating-signature-trust-with-gpg
# in the absence of a better solution
tmpfile=$(mktemp gpgverifyXXXXXX)
trap “rm -f $tmpfile” EXIT
# Automatically verify as much as we can
gpg –status-file $tmpfile –verify “$@” || exit 1
egrep -q ‘^\[GNUPG:] TRUST_(ULTIMATE|FULLY)’ $tmpfile || exit 1
# If it’s signed by “Evil Hacker <evil.hacker@nsa.gov>”
# give the user a chance to check.
echo
echo “======= SECURITY ========”
echo
echo “We have just downloaded nginx and verified its PGP signature.”
echo “Please confirm that you trust the signatory as shown above”
/bin/echo -n “Signature trusted [Yn]? ==> ”
read yn
[ “x$yn” = “xY” ] || [ “x$yn” = “xy” ] || [ “x$yn” = “x” ] || exit 1
exit 0