summaryrefslogtreecommitdiff
path: root/methods/gpgv.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2018-08-17 11:59:45 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2018-09-11 13:16:11 +0200
commitff8fa4ab4b80384a9240f0df63181f71077a8d83 (patch)
tree9e01aae054c99f8467dc5c2feb196378a33772ea /methods/gpgv.cc
parenta5953d914488c80c28fba6b59d2f0be461cd9f03 (diff)
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/gpgv.cc')
-rw-r--r--methods/gpgv.cc44
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";