From 349c5c89454ff344e4cf693492e7cb62ff549886 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 16 Mar 2016 16:54:05 +0100 Subject: methods/gpgv: Rewrite error handling and message This should be easy to extend in the future and allow us to simplify the error handling cases somewhat. Thanks: Ron Lee for wording suggestions --- methods/gpgv.cc | 69 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 3bd502c26..f355aaac3 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -39,15 +39,43 @@ using std::vector; #define GNUPGREVKEYSIG "[GNUPG:] REVKEYSIG" #define GNUPGNODATA "[GNUPG:] NODATA" -static const std::vector WeakDigests { - "1", // MD5 -// "2", // SHA1 -// "3", // RIPEMD-160 +struct Digest { + enum class State { + Untrusted, + Weak, + Trusted, + } state; + char name[32]; }; -static const std::vector DeprecatedDigests { - "2", // SHA1 - "3", // RIPEMD-160 +static constexpr Digest Digests[] = { + {Digest::State::Untrusted, "Invalid digest"}, + {Digest::State::Untrusted, "MD5"}, + {Digest::State::Weak, "SHA1"}, + {Digest::State::Weak, "RIPE-MD/160"}, + {Digest::State::Trusted, "Reserved digest"}, + {Digest::State::Trusted, "Reserved digest"}, + {Digest::State::Trusted, "Reserved digest"}, + {Digest::State::Trusted, "Reserved digest"}, + {Digest::State::Trusted, "SHA256"}, + {Digest::State::Trusted, "SHA384"}, + {Digest::State::Trusted, "SHA512"}, + {Digest::State::Trusted, "SHA224"}, +}; + +static Digest FindDigest(std::string const & Digest) +{ + int id = atoi(Digest.c_str()); + if (id >= 0 && static_cast(id) < _count(Digests)) { + return Digests[id]; + } else { + return Digests[0]; + } +} + +struct Signer { + std::string key; + std::string note; }; class GPGVMethod : public aptMethod @@ -58,7 +86,7 @@ class GPGVMethod : public aptMethod vector &GoodSigners, vector &BadSigners, vector &WorthlessSigners, - vector &SoonWorthlessSigners, + vector &SoonWorthlessSigners, vector &NoPubKeySigners); protected: virtual bool URIAcquire(std::string const &Message, FetchItem *Itm) APT_OVERRIDE; @@ -72,7 +100,7 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, vector &GoodSigners, vector &BadSigners, vector &WorthlessSigners, - vector &SoonWorthlessSigners, + vector &SoonWorthlessSigners, vector &NoPubKeySigners) { bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); @@ -164,18 +192,21 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (Debug == true) std::clog << "Got VALIDSIG, key ID: " << sig << std::endl; // Reject weak digest algorithms - if (std::find(DeprecatedDigests.begin(), DeprecatedDigests.end(), tokens[7]) != DeprecatedDigests.end()) - { + Digest digest = FindDigest(tokens[7]); + switch (digest.state) { + case Digest::State::Weak: // Treat them like an expired key: For that a message about expiry // is emitted, a VALIDSIG, but no GOODSIG. - SoonWorthlessSigners.push_back(string(sig)); - } - if (std::find(WeakDigests.begin(), WeakDigests.end(), tokens[7]) != WeakDigests.end()) - { + SoonWorthlessSigners.push_back({string(sig), digest.name}); + break; + case Digest::State::Untrusted: // Treat them like an expired key: For that a message about expiry // is emitted, a VALIDSIG, but no GOODSIG. - WorthlessSigners.push_back("WEAKDIGEST " + string(sig)); + WorthlessSigners.push_back(string(sig)); GoodSigners.erase(std::remove(GoodSigners.begin(), GoodSigners.end(), string(sig))); + break; + case Digest::State::Trusted: + break; } ValidSigners.push_back(string(sig)); @@ -259,7 +290,7 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm) vector BadSigners; // a worthless signature is a expired or revoked one vector WorthlessSigners; - vector SoonWorthlessSigners; + vector SoonWorthlessSigners; vector NoPubKeySigners; FetchResult Res; @@ -275,12 +306,12 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm) // Check if there are any good signers that are not soon worthless std::vector NotWarnAboutSigners(GoodSigners); for (auto const & Signer : SoonWorthlessSigners) - NotWarnAboutSigners.erase(std::remove(NotWarnAboutSigners.begin(), NotWarnAboutSigners.end(), "GOODSIG " + Signer)); + NotWarnAboutSigners.erase(std::remove(NotWarnAboutSigners.begin(), NotWarnAboutSigners.end(), "GOODSIG " + Signer.key)); // If all signers are soon worthless, report them. if (NotWarnAboutSigners.empty()) { for (auto const & Signer : SoonWorthlessSigners) // TRANSLATORS: The second %s is the reason and is untranslated for repository owners. - Warning(_("The repository is insufficiently signed by key %s (%s)"), (string(Signer)).c_str(), "weak digest"); + Warning(_("Weak signature from %s (%s)"), Signer.key.c_str(), Signer.note.c_str()); } if (GoodSigners.empty() || !BadSigners.empty() || !NoPubKeySigners.empty()) -- cgit v1.2.3