diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp index a7b073e6..23c458e1 100644 --- a/lang/cpp/src/verificationresult.cpp +++ b/lang/cpp/src/verificationresult.cpp @@ -29,6 +29,7 @@ #include "result_p.h" #include "util.h" #include "key.h" +#include "context.h" #include @@ -121,6 +122,7 @@ public: std::vector keys; std::vector purls; std::string file_name; + Protocol proto; }; GpgME::VerificationResult::VerificationResult(gpgme_ctx_t ctx, int error) @@ -145,6 +147,10 @@ void GpgME::VerificationResult::init(gpgme_ctx_t ctx) return; } d.reset(new Private(res)); + gpgme_protocol_t proto = gpgme_get_protocol(ctx); + d->proto = proto == GPGME_PROTOCOL_OpenPGP ? OpenPGP : + proto == GPGME_PROTOCOL_CMS ? CMS : + UnknownProtocol; } make_standard_stuff(VerificationResult) @@ -386,6 +392,32 @@ GpgME::Key GpgME::Signature::key() const return d->keys[idx]; } +GpgME::Key GpgME::Signature::key(bool search, bool update) const +{ + if (isNull()) { + return Key(); + } + + GpgME::Key ret = key(); + if (ret.isNull() && search) { + auto ctx = Context::createForProtocol (d->proto); + if (ctx) { + ctx->setKeyListMode(KeyListMode::Local | + KeyListMode::Signatures | + KeyListMode::SignatureNotations | + KeyListMode::Validate | + KeyListMode::WithTofu); + Error e; + ret = d->keys[idx] = ctx->key(fingerprint(), e, false); + delete ctx; + } + } + if (update) { + ret.update(); + } + return ret; +} + class GpgME::Notation::Private { public: diff --git a/lang/cpp/src/verificationresult.h b/lang/cpp/src/verificationresult.h index 93288af2..b6d1d8ce 100644 --- a/lang/cpp/src/verificationresult.h +++ b/lang/cpp/src/verificationresult.h @@ -163,6 +163,27 @@ public: * set or the associated TOFU Information if applicable. */ GpgME::Key key() const; + /* Search / Update the key of this signature. + * + * Same as above but if search is set to true this will + * either update the key provided by the engine or search + * the key in the engine. The key is cached. + * + * As this involves an engine call it might take some time + * to finish so it should be avoided to do this in a UI + * thread. The result will be cached and no engine call + * will be done if update is set to false and a key is + * already cached. + * + * If no key was provided by the engine this will look + * up the key so this call might block while the engine + * is called to obtain the key. + * + * If both search and update are false this is the same + * as calling key() + */ + GpgME::Key key(bool search, bool update) const; + private: std::shared_ptr d; unsigned int idx;