From 194272dbc3e326cc32c1464bc6fda0c0d10b5559 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Fri, 13 Dec 2019 18:06:00 +0100 Subject: [PATCH] cpp, qt: Use uidhash to select uids for signing * lang/cpp/src/gpgsignkeyeditinteractor.cpp (action): Use uidhash instead of number. (GpgSignKeyEditInteractor::setKey): New. * lang/cpp/src/gpgsignkeyeditinteractor.h: Update accordingly. * lang/cpp/src/key.h, lang/cpp/src/key.cpp: Wrap uidhash. * lang/qt/src/qgpgmesignkeyjob.cpp: Set the key. -- Using the uidhash avoids problems when the user ids on --edit-key are different ones then the uids captured by gpgme when listing keys. Or if they are in a different order. This can happen with cached keys or keys with user attributes. --- lang/cpp/src/gpgsignkeyeditinteractor.cpp | 17 ++++++++++++++++- lang/cpp/src/gpgsignkeyeditinteractor.h | 1 + lang/cpp/src/key.cpp | 5 +++++ lang/cpp/src/key.h | 1 + lang/qt/src/qgpgmesignkeyjob.cpp | 1 + 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lang/cpp/src/gpgsignkeyeditinteractor.cpp b/lang/cpp/src/gpgsignkeyeditinteractor.cpp index bf21cbc1..33ffbcfc 100644 --- a/lang/cpp/src/gpgsignkeyeditinteractor.cpp +++ b/lang/cpp/src/gpgsignkeyeditinteractor.cpp @@ -65,6 +65,7 @@ public: std::vector::const_iterator currentId, nextId; unsigned int checkLevel; bool dupeOk; + Key key; const char *command() const { @@ -259,7 +260,17 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const default: if (st >= UIDS_LIST_SEPARATELY && st < UIDS_LIST_SEPARATELY_DONE) { std::stringstream ss; - ss << d->nextUserID(); + auto nextID = d->nextUserID(); + const char *hash; + assert (nextID); + if (!d->key.isNull() && (hash = d->key.userID(nextID - 1).uidhash())) { + /* Prefer uidhash if it is available as it might happen + * that uidattrs break the ordering of the uids in the + * edit-key interface */ + ss << "uid " << hash; + } else { + ss << nextID; + } d->scratch = ss.str(); return d->scratch.c_str(); } @@ -318,6 +329,10 @@ unsigned int GpgSignKeyEditInteractor::nextState(unsigned int status, const char err = GENERAL_ERROR; return ERROR; } +void GpgSignKeyEditInteractor::setKey(const Key &key) +{ + d->key = key; +} void GpgSignKeyEditInteractor::setCheckLevel(unsigned int checkLevel) { diff --git a/lang/cpp/src/gpgsignkeyeditinteractor.h b/lang/cpp/src/gpgsignkeyeditinteractor.h index bb5320a2..d4596876 100644 --- a/lang/cpp/src/gpgsignkeyeditinteractor.h +++ b/lang/cpp/src/gpgsignkeyeditinteractor.h @@ -50,6 +50,7 @@ public: void setCheckLevel(unsigned int checkLevel); void setUserIDsToSign(const std::vector &userIDsToSign); + void setKey(const Key &key); void setSigningOptions(int options); /* Set this if it is ok to overwrite an existing signature. In that diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 5108a6ee..73045fb3 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -673,6 +673,11 @@ const char *UserID::comment() const return uid ? uid->comment : nullptr ; } +const char *UserID::uidhash() const +{ + return uid ? uid->uidhash : nullptr ; +} + UserID::Validity UserID::validity() const { if (!uid) { diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index cf4e9054..fc5e67ee 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -363,6 +363,7 @@ public: const char *name() const; const char *email() const; const char *comment() const; + const char *uidhash() const; enum Validity { Unknown = 0, Undefined = 1, Never = 2, Marginal = 3, Full = 4, Ultimate = 5 diff --git a/lang/qt/src/qgpgmesignkeyjob.cpp b/lang/qt/src/qgpgmesignkeyjob.cpp index 7cd10eb5..1d36d95a 100644 --- a/lang/qt/src/qgpgmesignkeyjob.cpp +++ b/lang/qt/src/qgpgmesignkeyjob.cpp @@ -76,6 +76,7 @@ static QGpgMESignKeyJob::result_type sign_key(Context *ctx, const Key &key, cons skei->setUserIDsToSign(uids); skei->setCheckLevel(checkLevel); skei->setSigningOptions(opts); + skei->setKey(key); if (dupeOk) { ctx->setFlag("extended-edit", "1");