diff options
| author | Ingo Klöcker <[email protected]> | 2020-11-03 07:59:54 +0000 | 
|---|---|---|
| committer | Ingo Klöcker <[email protected]> | 2020-11-03 07:59:54 +0000 | 
| commit | 6a6d2a27648490f08aaf0759a533aef08b32070d (patch) | |
| tree | e283ae9e10c81472081cc6c9d94d5674dbb0a451 /lang/cpp/src | |
| parent | qt: Add support for revoke signature quick command (diff) | |
| download | gpgme-6a6d2a27648490f08aaf0759a533aef08b32070d.tar.gz gpgme-6a6d2a27648490f08aaf0759a533aef08b32070d.zip | |
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
Diffstat (limited to 'lang/cpp/src')
| -rw-r--r-- | lang/cpp/src/key.cpp | 61 | ||||
| -rw-r--r-- | lang/cpp/src/key.h | 3 | 
2 files changed, 63 insertions, 1 deletions
| diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 4ebd3fe0..017f6624 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -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 diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index d3c6125a..a7931672 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -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 ; | 
