From 6dc85f53d92b9763a1509a6472227c54bc70b01d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 1 Sep 2016 18:55:20 +0200 Subject: [PATCH] support long keyid and fingerprint in gpgv's GOODSIG In gpgv1 GOODSIG (and the other messages of status-fd) are documented as sending the long keyid. In gpgv2 it is documented to be either long keyid or the fingerprint. At the moment it is still the long keyid, but the documentation hints at the possibility of changing this. We care about this for Signed-By support as we detect this way if the right fingerprint has signed this file (or not). The check itself is done via VALIDSIG which always is a fingerprint, but there must also be a GOODSIG (as expired sigs are valid, too) found to be accepted which wouldn't be found in the fingerprint-case and the signature hence refused. --- methods/gpgv.cc | 24 ++++++++-- test/integration/test-method-gpgv | 77 +++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100755 test/integration/test-method-gpgv diff --git a/methods/gpgv.cc b/methods/gpgv.cc index f2ef6b76e..d073c733e 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -258,16 +258,32 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (std::find(ValidSigners.begin(), ValidSigners.end(), k) == ValidSigners.end()) continue; // we look for GOODSIG here as well as an expired sig is a valid sig as well (but not a good one) + std::string const goodfingerprint = "GOODSIG " + k; std::string const goodlongkeyid = "GOODSIG " + k.substr(24, 16); - foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end(); + foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodfingerprint) != GoodSigners.end(); if (Debug == true) - std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl; + std::clog << "Key " << k << " is valid sig, is " << goodfingerprint << " also a good one? " << (foundGood ? "yes" : "no") << std::endl; + std::string goodsig; + if (foundGood == false) + { + foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end(); + if (Debug == true) + std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl; + goodsig = goodlongkeyid; + } + else + goodsig = goodfingerprint; if (foundGood == false) continue; std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator >(NoPubKeySigners)); GoodSigners.clear(); - GoodSigners.push_back(goodlongkeyid); - NoPubKeySigners.erase(std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodlongkeyid), NoPubKeySigners.end()); + GoodSigners.push_back(goodsig); + NoPubKeySigners.erase( + std::remove(NoPubKeySigners.begin(), + std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodfingerprint), + goodlongkeyid), + NoPubKeySigners.end() + ); break; } if (foundGood == false) diff --git a/test/integration/test-method-gpgv b/test/integration/test-method-gpgv new file mode 100755 index 000000000..86559b7cb --- /dev/null +++ b/test/integration/test-method-gpgv @@ -0,0 +1,77 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" + +setupenvironment +configarchitecture 'i386' + +cat > faked-apt-key <&\${GPGSTATUSFD} gpgv.output +cat gpgv.output +EOF +chmod +x faked-apt-key + +testgpgv() { + echo "$3" > gpgv.output + msgtest "$1" "$2" + gpgvmethod >method.output 2>&1 || true + testsuccess --nomsg grep "$2" method.output +} + +testrun() { + testgpgv 'Good signed with long keyid' 'Good: GOODSIG 5A90D141DBAC8DAE,' '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) +[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2016-09-01 1472742625 0 4 0 1 11 00 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE' + testgpgv 'Good signed with fingerprint' 'Good: GOODSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE,' '[GNUPG:] GOODSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) +[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2016-09-01 1472742625 0 4 0 1 11 00 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE' + + testgpgv 'No Pubkey with long keyid' 'NoPubKey: NO_PUBKEY E8525D47528144E2,' '[GNUPG:] ERRSIG E8525D47528144E2 1 11 00 1472744666 9 +[GNUPG:] NO_PUBKEY E8525D47528144E2' + testgpgv 'No Pubkey with fingerprint' 'NoPubKey: NO_PUBKEY DE66AECA9151AFA1877EC31DE8525D47528144E2,' '[GNUPG:] ERRSIG DE66AECA9151AFA1877EC31DE8525D47528144E2 1 11 00 1472744666 9 +[GNUPG:] NO_PUBKEY DE66AECA9151AFA1877EC31DE8525D47528144E2' + + testgpgv 'Expired key with long keyid' 'Worthless: EXPKEYSIG 4BC0A39C27CE74F9 Rex Expired ,' '[GNUPG:] EXPKEYSIG 4BC0A39C27CE74F9 Rex Expired +[GNUPG:] VALIDSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 2016-09-01 1472742629 0 4 0 1 11 00 891CC50E605796A0C6E733F74BC0A39C27CE74F9' + testgpgv 'Expired key with fingerprint' 'Worthless: EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired ,' '[GNUPG:] EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired +[GNUPG:] VALIDSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 2016-09-01 1472742629 0 4 0 1 11 00 891CC50E605796A0C6E733F74BC0A39C27CE74F9' +} + +gpgvmethod() { + echo '601 Configuration +Config-Item: Debug::Acquire::gpgv=1 +Config-Item: Dir::Bin::apt-key=./faked-apt-key + +600 URI Acquire +URI: file:///dev/null +Filename: /dev/zero +' | runapt "${METHODSDIR}/gpgv" +} +testrun + +gpgvmethod() { + echo '601 Configuration +Config-Item: Debug::Acquire::gpgv=1 +Config-Item: Dir::Bin::apt-key=./faked-apt-key + +600 URI Acquire +URI: file:///dev/null +Filename: /dev/zero +Signed-By: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE +' | runapt "${METHODSDIR}/gpgv" +} +testrun -- 2.45.2