diff --git a/NEWS b/NEWS index d7a96af5..87c19b09 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ Noteworthy changes in version 1.14.1 (unreleased) * cpp: Support for set expire operations in the C++ bindings. [#5003] + * cpp: Support for revoking key signatures in the C++ bindings. [#5094] + * qt: Extended ChangeExpiryJob to support changing the expiry of subkeys. [#4717] @@ -29,6 +31,8 @@ Noteworthy changes in version 1.14.1 (unreleased) cpp: StatusConsumer NEW. cpp: StatusConsumerAssuanTransaction NEW. cpp: Context::cancelPendingOperationImmediately NEW. + cpp: Context::revokeSignature NEW. + cpp: Context::startRevokeSignature NEW. qt: operator<<(QDebug debug, const GpgME::Error &err) NEW. diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index e868d387..44587a5f 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1532,6 +1532,22 @@ Error Context::startCreateSubkey(const Key &k, const char *algo, k.impl(), algo, reserved, expires, flags)); } +static std::string getLFSeparatedListOfStrings(const std::vector &strings) +{ + if (strings.empty()) { + return std::string(); + } + + return std::accumulate( + std::next(strings.begin()), + strings.end(), + strings[0], + [](const std::string &a, const std::string &b) { + return a + '\n' + b; + } + ); +} + static std::string getLFSeparatedListOfFingerprintsFromSubkeys(const std::vector &subkeys) { if (subkeys.empty()) { @@ -1546,18 +1562,7 @@ static std::string getLFSeparatedListOfFingerprintsFromSubkeys(const std::vector } } - 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; - } - ); + return getLFSeparatedListOfStrings(fprs); } Error Context::setExpire(const Key &k, unsigned long expires, @@ -1588,6 +1593,41 @@ Error Context::startSetExpire(const Key &k, unsigned long expires, k.impl(), expires, subfprs.c_str(), 0)); } +static std::string getLFSeparatedListOfUserIds(const std::vector &userIds) +{ + if (userIds.empty()) { + return std::string(); + } + + std::vector uids; + uids.reserve(userIds.size()); + for (auto &userId : userIds) { + if (userId.id()) { + uids.push_back(std::string(userId.id())); + } + } + + return getLFSeparatedListOfStrings(uids); +} + +Error Context::revokeSignature(const Key &key, const Key &signingKey, + const std::vector &userIds) +{ + const unsigned int flags = userIds.size() > 1 ? GPGME_REVSIG_LFSEP : 0; + const std::string uids = getLFSeparatedListOfUserIds(userIds); + return Error(d->lasterr = gpgme_op_revsig(d->ctx, + key.impl(), signingKey.impl(), uids.c_str(), flags)); +} + +Error Context::startRevokeSignature(const Key &key, const Key &signingKey, + const std::vector &userIds) +{ + const unsigned int flags = userIds.size() > 1 ? GPGME_REVSIG_LFSEP : 0; + const std::string uids = getLFSeparatedListOfUserIds(userIds); + return Error(d->lasterr = gpgme_op_revsig_start(d->ctx, + key.impl(), signingKey.impl(), uids.c_str(), flags)); +} + 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 4021aa97..bcb2017a 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -285,6 +285,11 @@ public: const std::vector &subkeys = std::vector(), const SetExpireFlags flags = SetExpireDefault); + Error revokeSignature(const Key &key, const Key &signingKey, + const std::vector &userIds = std::vector()); + Error startRevokeSignature(const Key &key, const Key &signingKey, + const std::vector &userIds = std::vector()); + // using TofuInfo::Policy Error setTofuPolicy(const Key &k, unsigned int policy); Error setTofuPolicyStart(const Key &k, unsigned int policy);