cpp: Make signatures belonging to the same user ID sortable
lang/cpp/src/key.h, lang/cpp/src/key.cpp (UserID::Signature::operator<): New. lang/cpp/src/key.cpp (signature_index): New. -- operator< defines a canonical sort order for signatures belonging to the same user ID. It is based on the sort order defined by cmp_signodes() in g10/keylist.c of gnupg. In particular, the ordering of signatures made with the same key by creation time allows to see easily whether the most recent signature is a certification or a revocation. GnuPG-bug-id: 5094 recent
This commit is contained in:
parent
f042739d3a
commit
6a6d2a2764
1
NEWS
1
NEWS
@ -35,6 +35,7 @@ Noteworthy changes in version 1.14.1 (unreleased)
|
||||
cpp: Context::cancelPendingOperationImmediately NEW.
|
||||
cpp: Context::revokeSignature NEW.
|
||||
cpp: Context::startRevokeSignature NEW.
|
||||
cpp: UserID::Signature::operator< NEW.
|
||||
qt: operator<<(QDebug debug, const GpgME::Error &err) NEW.
|
||||
qt: QuickJob::startRevokeSignature NEW.
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <cassert>
|
||||
#include <istream>
|
||||
#include <iterator>
|
||||
|
||||
@ -839,18 +840,76 @@ gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int signature_index(gpgme_user_id_t uid, gpgme_key_sig_t sig)
|
||||
{
|
||||
if (uid) {
|
||||
int i = 0;
|
||||
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, ++i) {
|
||||
if (s == sig) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
UserID::Signature::Signature() : key(), uid(nullptr), sig(nullptr) {}
|
||||
|
||||
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, unsigned int idx)
|
||||
: key(k), uid(verify_uid(k, u)), sig(find_signature(uid, idx))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, gpgme_key_sig_t s)
|
||||
: key(k), uid(verify_uid(k, u)), sig(verify_signature(uid, s))
|
||||
{
|
||||
}
|
||||
|
||||
bool UserID::Signature::operator<(const Signature &other)
|
||||
{
|
||||
// based on cmp_signodes() in g10/keylist.c
|
||||
|
||||
// both signatures must belong to the same user ID
|
||||
assert(uid == other.uid);
|
||||
|
||||
// self-signatures are ordered first
|
||||
const char *primaryKeyId = parent().parent().keyID();
|
||||
const bool thisIsSelfSignature = strcmp(signerKeyID(), primaryKeyId) == 0;
|
||||
const bool otherIsSelfSignature = strcmp(other.signerKeyID(), primaryKeyId) == 0;
|
||||
if (thisIsSelfSignature && !otherIsSelfSignature) {
|
||||
return true;
|
||||
}
|
||||
if (otherIsSelfSignature && !thisIsSelfSignature) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// then sort by signer key ID (which are or course the same for self-sigs)
|
||||
const int keyIdComparison = strcmp(signerKeyID(), other.signerKeyID());
|
||||
if (keyIdComparison < 0) {
|
||||
return true;
|
||||
}
|
||||
if (keyIdComparison > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// followed by creation time
|
||||
if (creationTime() < other.creationTime()) {
|
||||
return true;
|
||||
}
|
||||
if (creationTime() > other.creationTime()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// followed by the class in a way that a rev comes first
|
||||
if (certClass() < other.certClass()) {
|
||||
return true;
|
||||
}
|
||||
if (certClass() > other.certClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// to make the sort stable we compare the indexes of the signatures as last resort
|
||||
return signature_index(uid, sig) < signature_index(uid, other.sig);
|
||||
}
|
||||
|
||||
UserID UserID::Signature::parent() const
|
||||
|
@ -467,6 +467,9 @@ public:
|
||||
swap(this->sig, other.sig);
|
||||
}
|
||||
|
||||
/*! Defines a canonical sort order for signatures of the same user ID. */
|
||||
bool operator<(const Signature &other);
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return !sig || !uid || !key ;
|
||||
|
Loading…
Reference in New Issue
Block a user