diff --git a/NEWS b/NEWS index a1626202..08d40116 100644 --- a/NEWS +++ b/NEWS @@ -4,10 +4,14 @@ Noteworthy changes in version 1.14.1 (unreleased) * New function gpgme_op_setexpire to make changing the expiration easier (requires GnuPG 2.1.22). [#4999] + * cpp: Support for set expire operations in the C++ bindings. [#5003] + * Interface changes relative to the 1.14.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_op_setexpire_start NEW. gpgme_op_setexpire NEW. + cpp: Context::setExpire NEW. + cpp: Context::startSetExpire NEW. Noteworthy changes in version 1.14.0 (2020-07-16) diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 2560a338..6b657f60 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -51,6 +51,7 @@ #include #include +#include #ifndef NDEBUG #include using std::cerr; @@ -1526,6 +1527,62 @@ Error Context::startCreateSubkey(const Key &k, const char *algo, k.impl(), algo, reserved, expires, flags)); } +std::string Context::getLFSeparatedListOfFingerprintsFromSubkeys(const std::vector &subkeys) +{ + if (subkeys.empty()) { + return std::string(); + } + + std::vector fprs; + fprs.reserve(subkeys.size()); + for (auto &it : subkeys) { + if (it.fingerprint()) { + fprs.push_back(std::string(it.fingerprint())); + } + } + + if (fprs.empty()) { + return std::string(); + } + + return std::accumulate( + std::next(fprs.begin()), + fprs.end(), + fprs[0], + [](const std::string &a, const std::string &b) { + return a + '\n' + b; + } + ); +} + +Error Context::setExpire(const Key &k, unsigned long expires, + const std::vector &subkeys, + const Context::SetExpireFlags flags) +{ + std::string subfprs; + if (flags & Context::SetExpireAllSubkeys) { + subfprs = "*"; + } else { + subfprs = getLFSeparatedListOfFingerprintsFromSubkeys(subkeys); + } + return Error(d->lasterr = gpgme_op_setexpire(d->ctx, + k.impl(), expires, subfprs.c_str(), 0)); +} + +Error Context::startSetExpire(const Key &k, unsigned long expires, + const std::vector &subkeys, + const Context::SetExpireFlags flags) +{ + std::string subfprs; + if (flags & Context::SetExpireAllSubkeys) { + subfprs = "*"; + } else { + subfprs = getLFSeparatedListOfFingerprintsFromSubkeys(subkeys); + } + return Error(d->lasterr = gpgme_op_setexpire_start(d->ctx, + k.impl(), expires, subfprs.c_str(), 0)); +} + Error Context::setFlag(const char *name, const char *value) { return Error(d->lasterr = gpgme_set_ctx_flag(d->ctx, name, value)); diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 70f1c429..ebf5adb2 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -27,6 +27,7 @@ #include "global.h" #include "error.h" +#include "key.h" #include "verificationresult.h" // for Signature::Notation #include @@ -37,7 +38,6 @@ namespace GpgME { -class Key; class Data; class TrustItem; class ProgressProvider; @@ -273,6 +273,18 @@ public: unsigned long expires = 0, unsigned int flags = 0); + enum SetExpireFlags { + SetExpireDefault = 0, + SetExpireAllSubkeys = 1 + }; + + Error setExpire(const Key &k, unsigned long expires, + const std::vector &subkeys = std::vector(), + const SetExpireFlags flags = SetExpireDefault); + Error startSetExpire(const Key &k, unsigned long expires, + const std::vector &subkeys = std::vector(), + const SetExpireFlags flags = SetExpireDefault); + // using TofuInfo::Policy Error setTofuPolicy(const Key &k, unsigned int policy); Error setTofuPolicyStart(const Key &k, unsigned int policy); @@ -488,6 +500,8 @@ private: // on the "Friendlyness" of context to access the gpgme types. gpgme_key_t *getKeysFromRecipients(const std::vector &recipients); + std::string getLFSeparatedListOfFingerprintsFromSubkeys(const std::vector &subkeys); + private: Private *const d;