diff options
author | David Kalnischkies <david@kalnischkies.de> | 2018-08-17 11:59:45 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2018-09-11 13:16:11 +0200 |
commit | ff8fa4ab4b80384a9240f0df63181f71077a8d83 (patch) | |
tree | 9e01aae054c99f8467dc5c2feb196378a33772ea /methods | |
parent | a5953d914488c80c28fba6b59d2f0be461cd9f03 (diff) | |
download | apt-ff8fa4ab4b80384a9240f0df63181f71077a8d83.tar.gz |
Support subkeys properly in Signed-By options
If we limit a file to be signed by a certain key it should usually
accept also being signed by any of this keys subkeys instead of
requiring each subkey to be listed explicitly. If the later is really
wanted we support now also the same syntax as gpg does with appending an
exclamation mark at the end of the fingerprint to force no mapping.
Diffstat (limited to 'methods')
-rw-r--r-- | methods/gpgv.cc | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 84b8c3e59..e2a20722b 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -20,6 +20,7 @@ #include <array> #include <iostream> #include <iterator> +#include <map> #include <sstream> #include <string> #include <vector> @@ -175,6 +176,7 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, // Loop over the output of apt-key (which really is gnupg), and check the signatures. std::vector<std::string> ValidSigners; std::vector<std::string> ErrSigners; + std::map<std::string, std::vector<std::string>> SubKeyMapping; size_t buffersize = 0; char *buffer = NULL; bool gotNODATA = false; @@ -242,6 +244,9 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, } ValidSigners.push_back(sig); + + if (tokens.size() > 9 && sig != tokens[9]) + SubKeyMapping[tokens[9]].emplace_back(sig); } else if (strncmp(buffer, APTKEYWARNING, sizeof(APTKEYWARNING)-1) == 0) Warning("%s", buffer + sizeof(APTKEYWARNING)); @@ -265,15 +270,38 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (Debug == true) std::clog << "Key " << good << " is good sig, is it also a valid and allowed one? "; bool found = false; - for (auto const &l : limitedTo) + for (auto l : limitedTo) { - if (IsTheSameKey(l, good) == false) - continue; - // GOODSIG might be "just" a longid, so we check VALIDSIG which is always a fingerprint - if (std::find(ValidSigners.begin(), ValidSigners.end(), l) == ValidSigners.end()) - continue; - found = true; - break; + bool exactKey = false; + if (APT::String::Endswith(l, "!")) + { + exactKey = true; + l.erase(l.length() - 1); + } + if (IsTheSameKey(l, good)) + { + // GOODSIG might be "just" a longid, so we check VALIDSIG which is always a fingerprint + if (std::find(ValidSigners.cbegin(), ValidSigners.cend(), l) == ValidSigners.cend()) + continue; + found = true; + break; + } + else if (exactKey == false) + { + auto const master = SubKeyMapping.find(l); + if (master == SubKeyMapping.end()) + continue; + for (auto const &sub : master->second) + if (IsTheSameKey(sub, good)) + { + if (std::find(ValidSigners.cbegin(), ValidSigners.cend(), sub) == ValidSigners.cend()) + continue; + found = true; + break; + } + if (found) + break; + } } if (Debug) std::clog << (found ? "yes" : "no") << "\n"; |