From edfa3dcb5ffc498e4f9962c0dc96fd45263faf54 Mon Sep 17 00:00:00 2001 From: Kevin Borgolte Date: Fri, 8 Jul 2016 17:54:28 -0700 Subject: [PATCH] Allow GPG to fail on some keys If multiple GPG keys exist that could be used to decrypt the repository key, but GPG fails on one of them (e.g., the first one because it is stored on a SmartCard that is not plugged in), then no other keys are used to try to decrypt it, failing entirely instead of trying the additional GPG keys. Modified-by: Andrew Ayer * Make exception variable const * Make whitespace conform to project conventions Signed-off-by: Andrew Ayer Closes: #88 --- commands.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/commands.cpp b/commands.cpp index 0972823..866eb81 100644 --- a/commands.cpp +++ b/commands.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include static std::string attribute_name (const char* key_name) @@ -589,13 +590,20 @@ static void load_key (Key_file& key_file, const char* key_name, const char* key_ static bool decrypt_repo_key (Key_file& key_file, const char* key_name, uint32_t key_version, const std::vector& secret_keys, const std::string& keys_path) { + std::exception_ptr gpg_error; + for (std::vector::const_iterator seckey(secret_keys.begin()); seckey != secret_keys.end(); ++seckey) { std::ostringstream path_builder; path_builder << keys_path << '/' << (key_name ? key_name : "default") << '/' << key_version << '/' << *seckey << ".gpg"; std::string path(path_builder.str()); if (access(path.c_str(), F_OK) == 0) { std::stringstream decrypted_contents; - gpg_decrypt_from_file(path, decrypted_contents); + try { + gpg_decrypt_from_file(path, decrypted_contents); + } catch (const Gpg_error&) { + gpg_error = std::current_exception(); + continue; + } Key_file this_version_key_file; this_version_key_file.load(decrypted_contents); const Key_file::Entry* this_version_entry = this_version_key_file.get(key_version); @@ -610,6 +618,11 @@ static bool decrypt_repo_key (Key_file& key_file, const char* key_name, uint32_t return true; } } + + if (gpg_error) { + std::rethrow_exception(gpg_error); + } + return false; }