diff options
author | Andre Heinecke <[email protected]> | 2019-10-29 15:24:01 +0000 |
---|---|---|
committer | Andre Heinecke <[email protected]> | 2019-10-29 15:24:01 +0000 |
commit | 83ecf1686a9a4e7de3a7b176cf272d9f9f640445 (patch) | |
tree | aa7491e42ae490da06b20d52b3be3833a07a8ce4 | |
parent | core: Add cert-notation support and extended-edit (diff) | |
download | gpgme-83ecf1686a9a4e7de3a7b176cf272d9f9f640445.tar.gz gpgme-83ecf1686a9a4e7de3a7b176cf272d9f9f640445.zip |
cpp: Add convenience API to obtain remarks
* lang/cpp/src/key.h, lang/cpp/src/key.cpp (UserID::remark): New.
--
A remark made by one key on another is a signature notation on
a user id certification signature with the name "[email protected]".
This helps with:
GnuPG-Bug-Id: T4734
-rw-r--r-- | lang/cpp/src/key.cpp | 50 | ||||
-rw-r--r-- | lang/cpp/src/key.h | 17 |
2 files changed, 67 insertions, 0 deletions
diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 4b370207..eb7a5030 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -723,6 +723,56 @@ TofuInfo UserID::tofuInfo() const return TofuInfo(uid->tofu); } +static gpgme_key_sig_t find_last_valid_sig_for_keyid (gpgme_user_id_t uid, + const char *keyid) +{ + if (!keyid) { + return nullptr; + } + gpgme_key_sig_t ret = NULL; + for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) { + if (s->keyid && !strcmp(keyid, s->keyid)) { + if (!s->expired && !s->revoked && !s->invalid && !s->status) { + if (!ret) { + ret = s; + } else if (ret && ret->timestamp <= s->timestamp) { + /* Equals because when the timestamps are the same we prefer + the last in the list */ + ret = s; + } + } + } + } + return ret; +} + +const char *UserID::remark(const Key &remarker, Error &err) const +{ + if (!uid || remarker.isNull()) { + err = Error::fromCode(GPG_ERR_GENERAL); + return nullptr; + } + + if (!(parent().keyListMode() & GPGME_KEYLIST_MODE_SIG_NOTATIONS) || + !(parent().keyListMode() & GPGME_KEYLIST_MODE_SIGS)) { + err = Error::fromCode(GPG_ERR_NO_DATA); + return nullptr; + } + + gpgme_key_sig_t s = find_last_valid_sig_for_keyid(uid, remarker.keyID()); + + if (!s) { + return nullptr; + } + + for (gpgme_sig_notation_t n = s->notations; n ; n = n->next) { + if (n->name && !strcmp(n->name, "[email protected]")) { + return n->value; + } + } + return nullptr; +} + // // // class Signature diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index dd855aec..cca3c7a6 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -413,6 +413,23 @@ public: * * @returns the last update time. */ time_t lastUpdate() const; + + /*! Get a remark made by the key provided. + * A remark is a signature notation on + * this user id made by the key with the + * name "[email protected]". Returns an error if the + * parent key of this user id was not listed with the + * keylist mode flags for signatures and signature notations. + * + * @param key The key for which comments should be searched. + * @param error Set to GPG_ERR_NO_DATA if the keylist did + * not include signature notations. + * + * @returns The value of the comment or NULL if none exists. + **/ + const char *remark(const Key &key, + Error &error) const; + private: shared_gpgme_key_t key; gpgme_user_id_t uid; |