[gmime: 5/23] GPGME: report highest-validity User ID
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 5/23] GPGME: report highest-validity User ID
- Date: Sun, 29 Oct 2017 14:16:04 +0000 (UTC)
commit d6701744522167728e074c44800e1714a39ea562
Author: Daniel Kahn Gillmor <dkg fifthhorseman net>
Date: Mon Oct 16 00:12:25 2017 -0400
GPGME: report highest-validity User ID
An OpenPGP certificate can have multiple User IDs in it. Some of
those User IDs can have a different calculated validity level than
others, depending on which ones have been certified by which third
parties, and which third parties are trusted. For example:
pub rsa4096 2010-08-03 [SC] [expires: 2018-03-02]
A405E58AB3725B396ED1B85C1318EFAC5FBBDBCE
uid [marginal] Ximin Luo <infinity0 freenetproject org>
uid [ unknown] Satoshi Nakamoto (www.bitcoin.org) <satoshin gmx com>
uid [ full ] Ximin Luo <infinity0 pwned gg>
When selecting a single User ID (and name, and e-mail) to report out
of GMime, we should choose the first UID of the highest-known
validity, not just the first User ID.
A more complete fix would probably include reporting all the User IDs
of a given certificate.
Or, an approach geared toward building a sensible MUA could provide a
way to report the highest-validity User ID which happens to match the
From: address of the e-mail message being evaluated. But for now
we'll just improve the behavior within the existing API.
gmime/gmime-gpgme-utils.c | 77 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 64 insertions(+), 13 deletions(-)
---
diff --git a/gmime/gmime-gpgme-utils.c b/gmime/gmime-gpgme-utils.c
index 15ceabc..28b2b28 100644
--- a/gmime/gmime-gpgme-utils.c
+++ b/gmime/gmime-gpgme-utils.c
@@ -260,6 +260,44 @@ g_mime_gpgme_sign (gpgme_ctx_t ctx, gpgme_sig_mode_t mode, const char *userid,
return (GMimeDigestAlgo) result->signatures->hash_algo;
}
+
+/* return TRUE iff a < b */
+static gboolean
+_gpgv_lt(gpgme_validity_t a, gpgme_validity_t b) {
+ switch (a) {
+ case GPGME_VALIDITY_NEVER:
+ return b != GPGME_VALIDITY_NEVER;
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
+ switch (b) {
+ case GPGME_VALIDITY_NEVER:
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+ case GPGME_VALIDITY_MARGINAL:
+ switch (b) {
+ case GPGME_VALIDITY_NEVER:
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
+ case GPGME_VALIDITY_MARGINAL:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+ case GPGME_VALIDITY_FULL:
+ return b == GPGME_VALIDITY_ULTIMATE;
+ case GPGME_VALIDITY_ULTIMATE:
+ return FALSE;
+ default:
+ g_assert_not_reached();
+ return FALSE;
+ }
+}
+
+
static GMimeSignatureList *
g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify)
{
@@ -298,21 +336,34 @@ g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify)
g_mime_certificate_set_issuer_serial (signature->cert, key->issuer_serial);
g_mime_certificate_set_issuer_name (signature->cert, key->issuer_name);
- /* get the name, email address, and full user id */
+ gpgme_validity_t validity = GPGME_VALIDITY_NEVER;
+ gboolean founduid = FALSE;
+
+ /* get the most valid name, email address, and full user id */
uid = key->uids;
while (uid) {
- if (uid->name && *uid->name)
- g_mime_certificate_set_name (signature->cert, uid->name);
-
- if (uid->email && *uid->email)
- g_mime_certificate_set_email (signature->cert, uid->email);
-
- if (uid->uid && *uid->uid)
- g_mime_certificate_set_user_id (signature->cert, uid->uid);
-
- if (signature->cert->name && signature->cert->email &&
signature->cert->user_id)
- break;
-
+ if (!founduid || !_gpgv_lt (uid->validity, validity)) {
+ /* this is as good as the best UID we've found so far */
+ founduid = TRUE;
+ if (_gpgv_lt (validity, uid->validity)) {
+ /* this is actually better than the last best,
+ so clear all the previously-found uids */
+ g_mime_certificate_set_name (signature->cert, NULL);
+ g_mime_certificate_set_email (signature->cert, NULL);
+ g_mime_certificate_set_user_id (signature->cert, NULL);
+ }
+ validity = uid->validity;
+
+ if (uid->name && *uid->name && !g_mime_certificate_get_name
(signature->cert))
+ g_mime_certificate_set_name (signature->cert, uid->name);
+
+ if (uid->email && *uid->email && !g_mime_certificate_get_email
(signature->cert))
+ g_mime_certificate_set_email (signature->cert, uid->email);
+
+ if (uid->uid && *uid->uid && !g_mime_certificate_get_user_id
(signature->cert))
+ g_mime_certificate_set_user_id (signature->cert, uid->uid);
+
+ }
uid = uid->next;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]