summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-02-28 14:49:48 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2024-02-28 18:21:01 +0100
commit60d653634f889abe09c0f4d88f2559eab9202635 (patch)
tree9afe7739be332d24bd948274fc7565bb6f1c57ec
parent066121ac4de3f1e07e203583a2c5d00a0289f84a (diff)
gpgv: Add a reason to worthless signers
-rw-r--r--methods/gpgv.cc32
-rwxr-xr-xtest/integration/test-method-gpgv9
2 files changed, 31 insertions, 10 deletions
diff --git a/methods/gpgv.cc b/methods/gpgv.cc
index cb46703b3..b2e73c9fe 100644
--- a/methods/gpgv.cc
+++ b/methods/gpgv.cc
@@ -108,7 +108,7 @@ static bool IsTheSameKey(std::string const &validsig, std::string const &goodsig
struct APT_HIDDEN SignersStorage {
std::vector<std::string> Good;
std::vector<std::string> Bad;
- std::vector<std::string> Worthless;
+ std::vector<Signer> Worthless;
// a worthless signature is a expired or revoked one
std::vector<Signer> SoonWorthless;
std::vector<std::string> NoPubKey;
@@ -160,6 +160,16 @@ static void PushEntryWithUID(std::vector<std::string> &Signers, char * const buf
std::clog << "Got " << msg << " !" << std::endl;
Signers.push_back(msg);
}
+static void PushEntryWithUID(std::vector<Signer> &Signers, char * const buffer, bool const Debug)
+{
+ std::string msg = buffer + sizeof(GNUPGPREFIX);
+ auto const nuke = msg.find_last_not_of("\n\t\r");
+ if (nuke != std::string::npos)
+ msg.erase(nuke + 1);
+ if (Debug == true)
+ std::clog << "Got " << msg << " !" << std::endl;
+ Signers.push_back({msg, ""});
+}
static void implodeVector(std::vector<std::string> const &vec, std::ostream &out, char const * const sep)
{
if (vec.empty())
@@ -253,7 +263,11 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
case Digest::State::Untrusted:
// Treat them like an expired key: For that a message about expiry
// is emitted, a VALIDSIG, but no GOODSIG.
- Signers.Worthless.push_back(sig);
+ {
+ std::string note;
+ strprintf(note, "untrusted digest algorithm: %s", digest.name);
+ Signers.Worthless.push_back({sig, note});
+ }
Signers.Good.erase(std::remove_if(Signers.Good.begin(), Signers.Good.end(), [&](std::string const &goodsig) {
return IsTheSameKey(sig, goodsig); }), Signers.Good.end());
if (Debug == true)
@@ -285,7 +299,9 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
}
fclose(pipein);
free(buffer);
- std::move(ErrSigners.begin(), ErrSigners.end(), std::back_inserter(Signers.Worthless));
+
+ for (auto errSigner : ErrSigners)
+ Signers.Worthless.push_back({errSigner, ""});
// apt-key has a --keyid parameter, but this requires gpg, so we call it without it
// and instead check after the fact which keyids where used for verification
@@ -381,7 +397,7 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
std::cerr << "\n Bad: ";
implodeVector(Signers.Bad, std::cerr, ", ");
std::cerr << "\n Worthless: ";
- implodeVector(Signers.Worthless, std::cerr, ", ");
+ std::for_each(Signers.Worthless.begin(), Signers.Worthless.end(), [](Signer const &sig) { std::cerr << sig.key << ", "; });
std::cerr << "\n SoonWorthless: ";
std::for_each(Signers.SoonWorthless.begin(), Signers.SoonWorthless.end(), [](Signer const &sig) { std::cerr << sig.key << ", "; });
std::cerr << "\n NoPubKey: ";
@@ -549,8 +565,12 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm)
if (!Signers.Worthless.empty())
{
errmsg += _("The following signatures were invalid:\n");
- for (auto const &I : Signers.Worthless)
- errmsg.append(I).append("\n");
+ for (auto const &[key, reason] : Signers.Worthless) {
+ errmsg.append(key);
+ if (not reason.empty())
+ errmsg.append(" (").append(reason).append(")");
+ errmsg.append("\n");
+ }
}
if (!Signers.NoPubKey.empty())
{
diff --git a/test/integration/test-method-gpgv b/test/integration/test-method-gpgv
index bfa5af4c2..99bffd6ab 100755
--- a/test/integration/test-method-gpgv
+++ b/test/integration/test-method-gpgv
@@ -46,10 +46,11 @@ testrun() {
testgpgv 'Good subkey signed with fingerprint' 'Good: GOODSIG 4281DEDBD466EAE8C1F4157E5B6896415D44C43E' '34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE, 4281DEDBD466EAE8C1F4157E5B6896415D44C43E!' '[GNUPG:] GOODSIG 4281DEDBD466EAE8C1F4157E5B6896415D44C43E Sebastian Subkey <subkey@example.org>
[GNUPG:] VALIDSIG 4281DEDBD466EAE8C1F4157E5B6896415D44C43E 2018-08-16 1534459673 0 4 0 1 11 00 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE'
- testgpgv 'Untrusted signed with long keyid' 'Worthless: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE' '' '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
+ testgpgv 'Untrusted signed with long keyid' 'Worthless: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE, ' '' '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2016-09-01 1472742625 0 4 0 1 1 00 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE'
+ exit
testsuccess grep '^\s\+Good:\s\+$' method.output
- testgpgv 'Untrusted signed with fingerprint' 'Worthless: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE' '' '[GNUPG:] GOODSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
+ testgpgv 'Untrusted signed with fingerprint' 'Worthless: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE, ' '' '[GNUPG:] GOODSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) <joe@example.org>
[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2016-09-01 1472742625 0 4 0 1 1 00 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE'
testsuccess grep '^\s\+Good:\s\+$' method.output
@@ -65,9 +66,9 @@ testrun() {
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 <rex@example.org>' '' '[GNUPG:] EXPKEYSIG 4BC0A39C27CE74F9 Rex Expired <rex@example.org>
+ testgpgv 'Expired key with long keyid' 'Worthless: EXPKEYSIG 4BC0A39C27CE74F9 Rex Expired <rex@example.org>, ' '' '[GNUPG:] EXPKEYSIG 4BC0A39C27CE74F9 Rex Expired <rex@example.org>
[GNUPG:] VALIDSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 2016-09-01 1472742629 0 4 0 1 11 00 891CC50E605796A0C6E733F74BC0A39C27CE74F9'
- testgpgv 'Expired key with fingerprint' 'Worthless: EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired <rex@example.org>' '' '[GNUPG:] EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired <rex@example.org>
+ testgpgv 'Expired key with fingerprint' 'Worthless: EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired <rex@example.org>, ' '' '[GNUPG:] EXPKEYSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 Rex Expired <rex@example.org>
[GNUPG:] VALIDSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 2016-09-01 1472742629 0 4 0 1 11 00 891CC50E605796A0C6E733F74BC0A39C27CE74F9'
}