unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] crypto: signature verification reports valid User IDs
@ 2017-11-30  4:20 Daniel Kahn Gillmor
  2017-12-08  6:38 ` Daniel Kahn Gillmor
  2017-12-08 18:36 ` David Bremner
  0 siblings, 2 replies; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-11-30  4:20 UTC (permalink / raw)
  To: Notmuch Mail

When i'm trying to understand a message signature, i care that i know
who it came from (the "validity" of the identity associated with the
key), *not* whether i'm willing to accept the keyholder's other
identity assertions (the "trust" associated with the certificate).

We've been reporting User ID information based on the "trust"
associated with the certificate, because GMime didn't clearly expose
the validity of the User IDs.

This change relies on fixes made in GMime 3.0.3 and later which
include https://github.com/jstedfast/gmime/pull/18.
---
 configure          |  3 ++-
 notmuch-show.c     | 36 +++++++++++++++++++++++++++++-------
 test/T355-smime.sh |  8 +++++++-
 util/gmime-extra.h | 11 -----------
 4 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index d3e30b53..cfbf827c 100755
--- a/configure
+++ b/configure
@@ -478,9 +478,10 @@ fi
 # we need to have a version >= 2.6.5 to avoid a crypto bug. We need
 # 2.6.7 for permissive "From " header handling.
 GMIME_MINVER=2.6.7
+GMIME3_MINVER=3.0.3
 
 printf "Checking for GMime development files... "
-if pkg-config --exists "gmime-3.0"; then
+if pkg-config --exists "gmime-3.0 > $GMIME3_MINVER"; then
     printf "Yes (3.0).\n"
     have_gmime=1
     gmime_cflags=$(pkg-config --cflags gmime-3.0)
diff --git a/notmuch-show.c b/notmuch-show.c
index 7afd3947..4b89be0a 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -401,6 +401,32 @@ format_signature_errors (sprinter_t *sp, GMimeSignature *signature)
 }
 #endif
 
+
+static const char*
+_get_certificate_valid_userid (GMimeCertificate *cert)
+{
+    /* output user id only if validity is FULL or ULTIMATE. */
+#if (GMIME_MAJOR_VERSION < 3)
+    /* note that gmime 2.6 is using the term "trust" here, which
+     * is WRONG.  It's actually user id "validity". */
+    const char *name = g_mime_certificate_get_name (cert);
+    if (name == NULL)
+	return name;
+    GMimeCertificateTrust trust = g_mime_certificate_get_trust (cert);
+    if (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)
+	return name;
+    return NULL;
+#else
+    const char *uid = g_mime_certificate_get_user_id (cert);
+    if (uid == NULL)
+	return uid;
+    GMimeValidity validity = g_mime_certificate_get_id_validity (cert);
+    if (validity == GMIME_VALIDITY_FULL || validity == GMIME_VALIDITY_ULTIMATE)
+	return uid;
+    return NULL;
+#endif
+}
+
 /* Signature status sprinter (GMime 2.6) */
 static void
 format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
@@ -446,15 +472,11 @@ format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
 		sp->map_key (sp, "expires");
 		sp->integer (sp, expires);
 	    }
-	    /* output user id only if validity is FULL or ULTIMATE. */
-	    /* note that gmime is using the term "trust" here, which
-	     * is WRONG.  It's actually user id "validity". */
 	    if (certificate) {
-		const char *name = g_mime_certificate_get_uid (certificate);
-		GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate);
-		if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) {
+		const char *uid = _get_certificate_valid_userid (certificate);
+		if (uid) {
 		    sp->map_key (sp, "userid");
-		    sp->string (sp, name);
+		    sp->string (sp, uid);
 		}
 	    }
 	} else if (certificate) {
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index 1523f17b..be45e3b1 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -48,6 +48,12 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "signature verification (notmuch CLI)"
+if [ "${NOTMUCH_GMIME_MAJOR}" -lt 3 ]; then
+    # gmime 2 can't report User IDs properly for S/MIME
+    USERID=''
+else
+    USERID='"userid": "CN=Notmuch Test Suite",'
+fi
 output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | notmuch_json_show_sanitize \
     | sed -e 's|"created": [-1234567890]*|"created": 946728000|' \
@@ -65,7 +71,7 @@ expected='[[[{"id": "XXXXX",
  "Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
  "body": [{"id": 1,
  "sigstatus": [{"fingerprint": "'$FINGERPRINT'",
- "status": "good",
+ "status": "good",'$USERID'
  "expires": 424242424,
  "created": 946728000}],
  "content-type": "multipart/signed",
diff --git a/util/gmime-extra.h b/util/gmime-extra.h
index 40bf1454..ec4ca186 100644
--- a/util/gmime-extra.h
+++ b/util/gmime-extra.h
@@ -16,11 +16,9 @@ GMimeStream *g_mime_stream_stdout_new(void);
 #define g_mime_2_6_unref(obj) g_object_unref (obj)
 #define g_mime_3_unused(arg) arg
 #define g_mime_certificate_get_fpr16(cert) g_mime_certificate_get_key_id (cert)
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_name (cert);
 #else /* GMime >= 3.0 */
 
 #define GMIME_ENABLE_RFC_2047_WORKAROUNDS 0xdeadbeef
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_key_id (cert);
 #define g_mime_content_type_to_string(c) g_mime_content_type_get_mime_type (c)
 #define g_mime_filter_crlf_new(encode,dots) g_mime_filter_dos2unix_new (FALSE)
 #define g_mime_gpg_context_new(func,path) g_mime_gpg_context_new ()
@@ -45,15 +43,6 @@ typedef GMimeAddressType GMimeRecipientType;
 
 typedef GMimeSignatureStatus GMimeSignatureError;
 
-typedef GMimeTrust GMimeCertificateTrust;
-
-#define GMIME_CERTIFICATE_TRUST_UNKNOWN GMIME_TRUST_UNKNOWN
-#define GMIME_CERTIFICATE_TRUST_UNDEFINED GMIME_TRUST_UNDEFINED
-#define GMIME_CERTIFICATE_TRUST_NEVER GMIME_TRUST_NEVER
-#define GMIME_CERTIFICATE_TRUST_MARGINAL GMIME_TRUST_MARGINAL
-#define GMIME_CERTIFICATE_TRUST_FULLY GMIME_TRUST_FULL
-#define GMIME_CERTIFICATE_TRUST_ULTIMATE GMIME_TRUST_ULTIMATE
-
 #define g_mime_2_6_unref(obj) /*ignore*/
 #define g_mime_3_unused(arg) unused(arg)
 #endif
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: signature verification reports valid User IDs
  2017-11-30  4:20 [PATCH] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
@ 2017-12-08  6:38 ` Daniel Kahn Gillmor
  2017-12-08 18:36 ` David Bremner
  1 sibling, 0 replies; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-08  6:38 UTC (permalink / raw)
  To: Notmuch Mail

[-- Attachment #1: Type: text/plain, Size: 1008 bytes --]

On Wed 2017-11-29 23:20:35 -0500, Daniel Kahn Gillmor wrote:
> When i'm trying to understand a message signature, i care that i know
> who it came from (the "validity" of the identity associated with the
> key), *not* whether i'm willing to accept the keyholder's other
> identity assertions (the "trust" associated with the certificate).
>
> We've been reporting User ID information based on the "trust"
> associated with the certificate, because GMime didn't clearly expose
> the validity of the User IDs.
>
> This change relies on fixes made in GMime 3.0.3 and later which
> include https://github.com/jstedfast/gmime/pull/18.

Without this patch, the notmuch test suite currently fails when built
against gmime 3 on debian testing, because gmime 3 on debian testing
now correctly returns key IDs for _get_key_id().

This patch corrects the misbehavior of previous versions of notmuch, and
restores the ability to display correct validity of the keys in
question.

I welcome review for it!

        --dkg

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: signature verification reports valid User IDs
  2017-11-30  4:20 [PATCH] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
  2017-12-08  6:38 ` Daniel Kahn Gillmor
@ 2017-12-08 18:36 ` David Bremner
  2017-12-08 18:55   ` Daniel Kahn Gillmor
  2017-12-08 18:55   ` [PATCH v2] " Daniel Kahn Gillmor
  1 sibling, 2 replies; 8+ messages in thread
From: David Bremner @ 2017-12-08 18:36 UTC (permalink / raw)
  To: Daniel Kahn Gillmor, Notmuch Mail

Daniel Kahn Gillmor <dkg@fifthhorseman.net> writes:

> @@ -478,9 +478,10 @@ fi
>  # we need to have a version >= 2.6.5 to avoid a crypto bug. We need
>  # 2.6.7 for permissive "From " header handling.
>  GMIME_MINVER=2.6.7
> +GMIME3_MINVER=3.0.3

Does this change mean notmuch won't build at all for people with gmime-3
< 3.0.3? I understand that's not a problem in Debian, but what about in
general?

>  
> +
> +static const char*
> +_get_certificate_valid_userid (GMimeCertificate *cert)
> +{

Since we already have util/gmime-extra.c to deal with differences
between gmime-3.0 and 2.6, and since this code is purely gmime related
(not using any notmuch data or types), it makes sense to me put this
(split) there. I guess we might use a different prefix for stuff we add,
although iirc we didn't bother for zlib-extra.c

d

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: signature verification reports valid User IDs
  2017-12-08 18:36 ` David Bremner
@ 2017-12-08 18:55   ` Daniel Kahn Gillmor
  2017-12-08 18:55   ` [PATCH v2] " Daniel Kahn Gillmor
  1 sibling, 0 replies; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-08 18:55 UTC (permalink / raw)
  To: David Bremner, Notmuch Mail

[-- Attachment #1: Type: text/plain, Size: 2144 bytes --]

On Fri 2017-12-08 14:36:04 -0400, David Bremner wrote:
> Daniel Kahn Gillmor <dkg@fifthhorseman.net> writes:
>
>> @@ -478,9 +478,10 @@ fi
>>  # we need to have a version >= 2.6.5 to avoid a crypto bug. We need
>>  # 2.6.7 for permissive "From " header handling.
>>  GMIME_MINVER=2.6.7
>> +GMIME3_MINVER=3.0.3
>
> Does this change mean notmuch won't build at all for people with gmime-3
> < 3.0.3? I understand that's not a problem in Debian, but what about in
> general?

iiuc, if you've only got gmime-3 version < 3.0.3, then you will not be
able to build notmuch.  however, if you have that *and* you have a
version of gmime-2.6, configure will just use gmime 2.6.

If you only have gmime-2.4, or a version of gmime 2.6 before 2.6.7, then
you are SOL.

I think that's an acceptable situation, though.  We're not taking away
too many options from users.

Also, when built against 3.0.0, 3.0.1, or 3.0.2, the identification
information shown during signed messages is strictly *wrong* -- it shows
the assigned ownertrust of a certificate where it should show the
validity.  This is not only wrong, but it's actively dangerous, because
it encourages users to mark keys with elevated ownertrust "just to turn
them green".  This is the equivalent of encouraging users to add
arbitrary root CAs to their list of trusted X.509 anchors.  Not
something a MUA should be doing.

>> +
>> +static const char*
>> +_get_certificate_valid_userid (GMimeCertificate *cert)
>> +{
>
> Since we already have util/gmime-extra.c to deal with differences
> between gmime-3.0 and 2.6, and since this code is purely gmime related
> (not using any notmuch data or types), it makes sense to me put this
> (split) there. I guess we might use a different prefix for stuff we add,
> although iirc we didn't bother for zlib-extra.c

The (very slight) disadvantage of putting this code in
util/gmime-extra.c is that it will no longer be static, but will instead
be exposed across compilation units.  That said, i don't think that's
actually a big deal, and i understand why you want it in
util/gmime-extra.c. So i'll send a new revision of this patch shortly.

        --dkg

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] crypto: signature verification reports valid User IDs
  2017-12-08 18:36 ` David Bremner
  2017-12-08 18:55   ` Daniel Kahn Gillmor
@ 2017-12-08 18:55   ` Daniel Kahn Gillmor
  2017-12-08 20:09     ` v3 of fixing signature verification Daniel Kahn Gillmor
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-08 18:55 UTC (permalink / raw)
  To: Notmuch Mail

When i'm trying to understand a message signature, i care that i know
who it came from (the "validity" of the identity associated with the
key), *not* whether i'm willing to accept the keyholder's other
identity assertions (the "trust" associated with the certificate).

We've been reporting User ID information based on the "trust"
associated with the certificate, because GMime didn't clearly expose
the validity of the User IDs.

This change relies on fixes made in GMime 3.0.3 and later which
include https://github.com/jstedfast/gmime/pull/18.
---
 configure          |  3 ++-
 notmuch-show.c     | 10 +++-------
 test/T355-smime.sh |  8 +++++++-
 util/gmime-extra.c | 26 ++++++++++++++++++++++++++
 util/gmime-extra.h | 17 ++++++-----------
 5 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index fc70031b..b177b141 100755
--- a/configure
+++ b/configure
@@ -478,9 +478,10 @@ fi
 # we need to have a version >= 2.6.5 to avoid a crypto bug. We need
 # 2.6.7 for permissive "From " header handling.
 GMIME_MINVER=2.6.7
+GMIME3_MINVER=3.0.3
 
 printf "Checking for GMime development files... "
-if pkg-config --exists "gmime-3.0"; then
+if pkg-config --exists "gmime-3.0 > $GMIME3_MINVER"; then
     printf "Yes (3.0).\n"
     have_gmime=1
     gmime_cflags=$(pkg-config --cflags gmime-3.0)
diff --git a/notmuch-show.c b/notmuch-show.c
index 7afd3947..7d2c3813 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -446,15 +446,11 @@ format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
 		sp->map_key (sp, "expires");
 		sp->integer (sp, expires);
 	    }
-	    /* output user id only if validity is FULL or ULTIMATE. */
-	    /* note that gmime is using the term "trust" here, which
-	     * is WRONG.  It's actually user id "validity". */
 	    if (certificate) {
-		const char *name = g_mime_certificate_get_uid (certificate);
-		GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate);
-		if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) {
+		const char *uid = g_mime_get_certificate_valid_userid (certificate);
+		if (uid) {
 		    sp->map_key (sp, "userid");
-		    sp->string (sp, name);
+		    sp->string (sp, uid);
 		}
 	    }
 	} else if (certificate) {
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index 1523f17b..be45e3b1 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -48,6 +48,12 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "signature verification (notmuch CLI)"
+if [ "${NOTMUCH_GMIME_MAJOR}" -lt 3 ]; then
+    # gmime 2 can't report User IDs properly for S/MIME
+    USERID=''
+else
+    USERID='"userid": "CN=Notmuch Test Suite",'
+fi
 output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | notmuch_json_show_sanitize \
     | sed -e 's|"created": [-1234567890]*|"created": 946728000|' \
@@ -65,7 +71,7 @@ expected='[[[{"id": "XXXXX",
  "Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
  "body": [{"id": 1,
  "sigstatus": [{"fingerprint": "'$FINGERPRINT'",
- "status": "good",
+ "status": "good",'$USERID'
  "expires": 424242424,
  "created": 946728000}],
  "content-type": "multipart/signed",
diff --git a/util/gmime-extra.c b/util/gmime-extra.c
index 901d4d56..2d0f7443 100644
--- a/util/gmime-extra.c
+++ b/util/gmime-extra.c
@@ -196,4 +196,30 @@ g_mime_utils_header_decode_date_unix (const char *date) {
     return ret;
 }
 
+const char *
+g_mime_get_certificate_valid_userid (GMimeCertificate *cert)
+{
+    /* output user id only if validity is FULL or ULTIMATE. */
+#if (GMIME_MAJOR_VERSION < 3)
+    /* note that gmime 2.6 is using the term "trust" here, which
+     * is WRONG.  It's actually user id "validity". */
+    const char *name = g_mime_certificate_get_name (cert);
+    if (name == NULL)
+	return name;
+    GMimeCertificateTrust trust = g_mime_certificate_get_trust (cert);
+    if (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)
+	return name;
+    return NULL;
+#else
+    const char *uid = g_mime_certificate_get_user_id (cert);
+    if (uid == NULL)
+	return uid;
+    GMimeValidity validity = g_mime_certificate_get_id_validity (cert);
+    if (validity == GMIME_VALIDITY_FULL || validity == GMIME_VALIDITY_ULTIMATE)
+	return uid;
+    return NULL;
+#endif
+}
+
+
 #endif
diff --git a/util/gmime-extra.h b/util/gmime-extra.h
index 40bf1454..389cf38f 100644
--- a/util/gmime-extra.h
+++ b/util/gmime-extra.h
@@ -16,11 +16,9 @@ GMimeStream *g_mime_stream_stdout_new(void);
 #define g_mime_2_6_unref(obj) g_object_unref (obj)
 #define g_mime_3_unused(arg) arg
 #define g_mime_certificate_get_fpr16(cert) g_mime_certificate_get_key_id (cert)
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_name (cert);
 #else /* GMime >= 3.0 */
 
 #define GMIME_ENABLE_RFC_2047_WORKAROUNDS 0xdeadbeef
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_key_id (cert);
 #define g_mime_content_type_to_string(c) g_mime_content_type_get_mime_type (c)
 #define g_mime_filter_crlf_new(encode,dots) g_mime_filter_dos2unix_new (FALSE)
 #define g_mime_gpg_context_new(func,path) g_mime_gpg_context_new ()
@@ -45,15 +43,6 @@ typedef GMimeAddressType GMimeRecipientType;
 
 typedef GMimeSignatureStatus GMimeSignatureError;
 
-typedef GMimeTrust GMimeCertificateTrust;
-
-#define GMIME_CERTIFICATE_TRUST_UNKNOWN GMIME_TRUST_UNKNOWN
-#define GMIME_CERTIFICATE_TRUST_UNDEFINED GMIME_TRUST_UNDEFINED
-#define GMIME_CERTIFICATE_TRUST_NEVER GMIME_TRUST_NEVER
-#define GMIME_CERTIFICATE_TRUST_MARGINAL GMIME_TRUST_MARGINAL
-#define GMIME_CERTIFICATE_TRUST_FULLY GMIME_TRUST_FULL
-#define GMIME_CERTIFICATE_TRUST_ULTIMATE GMIME_TRUST_ULTIMATE
-
 #define g_mime_2_6_unref(obj) /*ignore*/
 #define g_mime_3_unused(arg) unused(arg)
 #endif
@@ -105,4 +94,10 @@ gboolean g_mime_signature_status_bad (GMimeSignatureStatus status);
 gboolean g_mime_signature_status_error (GMimeSignatureError status);
 
 gint64 g_mime_utils_header_decode_date_unix (const char *date);
+
+/**
+ * Return string for valid User ID (or NULL if no valid User ID exists)
+ */
+const char * g_mime_get_certificate_valid_userid (GMimeCertificate *cert);
+
 #endif
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* v3 of fixing signature verification
  2017-12-08 18:55   ` [PATCH v2] " Daniel Kahn Gillmor
@ 2017-12-08 20:09     ` Daniel Kahn Gillmor
  2017-12-08 20:09       ` [PATCH v3] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-08 20:09 UTC (permalink / raw)
  To: Notmuch Mail

Bremner pointed out to me that v2 of this patch doesn't work with 2.6,
and that the name of the function should be
g_mime_certificate_get_valid_userid, instead of
g_mime_get_certificate_valid_userid.

Also, he asked that it be built against the "release" branch, since
it's important there, too.

So v3 is built against the release branch, though it is also trivial
to cherry-pick or merge into master.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3] crypto: signature verification reports valid User IDs
  2017-12-08 20:09     ` v3 of fixing signature verification Daniel Kahn Gillmor
@ 2017-12-08 20:09       ` Daniel Kahn Gillmor
  2017-12-09  2:26         ` David Bremner
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-08 20:09 UTC (permalink / raw)
  To: Notmuch Mail

When i'm trying to understand a message signature, i care that i know
who it came from (the "validity" of the identity associated with the
key), *not* whether i'm willing to accept the keyholder's other
identity assertions (the "trust" associated with the certificate).

We've been reporting User ID information based on the "trust"
associated with the certificate, because GMime didn't clearly expose
the validity of the User IDs.

This change relies on fixes made in GMime 3.0.3 and later which
include https://github.com/jstedfast/gmime/pull/18.
---
 configure          |  3 ++-
 notmuch-show.c     | 10 +++-------
 test/T355-smime.sh |  8 +++++++-
 util/gmime-extra.c | 28 ++++++++++++++++++++++++++++
 util/gmime-extra.h | 17 ++++++-----------
 5 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index c5e2ffed..daee5a6e 100755
--- a/configure
+++ b/configure
@@ -482,9 +482,10 @@ fi
 # we need to have a version >= 2.6.5 to avoid a crypto bug. We need
 # 2.6.7 for permissive "From " header handling.
 GMIME_MINVER=2.6.7
+GMIME3_MINVER=3.0.3
 
 printf "Checking for GMime development files... "
-if pkg-config --exists "gmime-3.0"; then
+if pkg-config --exists "gmime-3.0 > $GMIME3_MINVER"; then
     printf "Yes (3.0).\n"
     have_gmime=1
     gmime_cflags=$(pkg-config --cflags gmime-3.0)
diff --git a/notmuch-show.c b/notmuch-show.c
index 74e77249..bb44d938 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -446,15 +446,11 @@ format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
 		sp->map_key (sp, "expires");
 		sp->integer (sp, expires);
 	    }
-	    /* output user id only if validity is FULL or ULTIMATE. */
-	    /* note that gmime is using the term "trust" here, which
-	     * is WRONG.  It's actually user id "validity". */
 	    if (certificate) {
-		const char *name = g_mime_certificate_get_uid (certificate);
-		GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate);
-		if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) {
+		const char *uid = g_mime_certificate_get_valid_userid (certificate);
+		if (uid) {
 		    sp->map_key (sp, "userid");
-		    sp->string (sp, name);
+		    sp->string (sp, uid);
 		}
 	    }
 	} else if (certificate) {
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index 03d24581..532cd84b 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -48,6 +48,12 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "signature verification (notmuch CLI)"
+if [ "${NOTMUCH_GMIME_MAJOR}" -lt 3 ]; then
+    # gmime 2 can't report User IDs properly for S/MIME
+    USERID=''
+else
+    USERID='"userid": "CN=Notmuch Test Suite",'
+fi
 output=$(notmuch show --format=json --verify subject:"test signed message 001" \
     | notmuch_json_show_sanitize \
     | sed -e 's|"created": [-1234567890]*|"created": 946728000|' \
@@ -65,7 +71,7 @@ expected='[[[{"id": "XXXXX",
  "Date": "Sat, 01 Jan 2000 12:00:00 +0000"},
  "body": [{"id": 1,
  "sigstatus": [{"fingerprint": "'$FINGERPRINT'",
- "status": "good",
+ "status": "good",'$USERID'
  "expires": 424242424,
  "created": 946728000}],
  "content-type": "multipart/signed",
diff --git a/util/gmime-extra.c b/util/gmime-extra.c
index 901d4d56..bc1e3c4d 100644
--- a/util/gmime-extra.c
+++ b/util/gmime-extra.c
@@ -33,6 +33,21 @@ g_string_talloc_strdup (void *ctx, char *g_string)
 
 #if (GMIME_MAJOR_VERSION < 3)
 
+const char *
+g_mime_certificate_get_valid_userid (GMimeCertificate *cert)
+{
+    /* output user id only if validity is FULL or ULTIMATE. */
+    /* note that gmime 2.6 is using the term "trust" here, which
+     * is WRONG.  It's actually user id "validity". */
+    const char *name = g_mime_certificate_get_name (cert);
+    if (name == NULL)
+	return name;
+    GMimeCertificateTrust trust = g_mime_certificate_get_trust (cert);
+    if (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)
+	return name;
+    return NULL;
+}
+
 char *
 g_mime_message_get_address_string (GMimeMessage *message, GMimeRecipientType type)
 {
@@ -107,6 +122,19 @@ g_mime_utils_header_decode_date_unix (const char *date) {
 
 #else /* GMime >= 3.0 */
 
+const char *
+g_mime_certificate_get_valid_userid (GMimeCertificate *cert)
+{
+    /* output user id only if validity is FULL or ULTIMATE. */
+    const char *uid = g_mime_certificate_get_user_id (cert);
+    if (uid == NULL)
+	return uid;
+    GMimeValidity validity = g_mime_certificate_get_id_validity (cert);
+    if (validity == GMIME_VALIDITY_FULL || validity == GMIME_VALIDITY_ULTIMATE)
+	return uid;
+    return NULL;
+}
+
 const char*
 g_mime_certificate_get_fpr16 (GMimeCertificate *cert) {
     const char *fpr = g_mime_certificate_get_fingerprint (cert);
diff --git a/util/gmime-extra.h b/util/gmime-extra.h
index de275bc1..18888b55 100644
--- a/util/gmime-extra.h
+++ b/util/gmime-extra.h
@@ -16,12 +16,10 @@ GMimeStream *g_mime_stream_stdout_new(void);
 #define g_mime_2_6_unref(obj) g_object_unref (obj)
 #define g_mime_3_unused(arg) arg
 #define g_mime_certificate_get_fpr16(cert) g_mime_certificate_get_key_id (cert)
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_name (cert);
 #else /* GMime >= 3.0 */
 typedef GMimeAddressType GMimeRecipientType;
 
 #define GMIME_ENABLE_RFC_2047_WORKAROUNDS 0xdeadbeef
-#define g_mime_certificate_get_uid(cert) g_mime_certificate_get_key_id (cert);
 #define g_mime_content_type_to_string(c) g_mime_content_type_get_mime_type (c)
 #define g_mime_filter_crlf_new(encode,dots) g_mime_filter_dos2unix_new (FALSE)
 #define g_mime_gpg_context_new(func,path) g_mime_gpg_context_new ()
@@ -47,15 +45,6 @@ typedef GMimeAddressType GMimeRecipientType;
 
 typedef GMimeSignatureStatus GMimeSignatureError;
 
-typedef GMimeTrust GMimeCertificateTrust;
-
-#define GMIME_CERTIFICATE_TRUST_UNKNOWN GMIME_TRUST_UNKNOWN
-#define GMIME_CERTIFICATE_TRUST_UNDEFINED GMIME_TRUST_UNDEFINED
-#define GMIME_CERTIFICATE_TRUST_NEVER GMIME_TRUST_NEVER
-#define GMIME_CERTIFICATE_TRUST_MARGINAL GMIME_TRUST_MARGINAL
-#define GMIME_CERTIFICATE_TRUST_FULLY GMIME_TRUST_FULL
-#define GMIME_CERTIFICATE_TRUST_ULTIMATE GMIME_TRUST_ULTIMATE
-
 #define g_mime_2_6_unref(obj) /*ignore*/
 #define g_mime_3_unused(arg) unused(arg)
 #endif
@@ -107,4 +96,10 @@ gboolean g_mime_signature_status_bad (GMimeSignatureStatus status);
 gboolean g_mime_signature_status_error (GMimeSignatureError status);
 
 gint64 g_mime_utils_header_decode_date_unix (const char *date);
+
+/**
+ * Return string for valid User ID (or NULL if no valid User ID exists)
+ */
+const char * g_mime_certificate_get_valid_userid (GMimeCertificate *cert);
+
 #endif
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] crypto: signature verification reports valid User IDs
  2017-12-08 20:09       ` [PATCH v3] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
@ 2017-12-09  2:26         ` David Bremner
  0 siblings, 0 replies; 8+ messages in thread
From: David Bremner @ 2017-12-09  2:26 UTC (permalink / raw)
  To: Daniel Kahn Gillmor, Notmuch Mail

Daniel Kahn Gillmor <dkg@fifthhorseman.net> writes:

> When i'm trying to understand a message signature, i care that i know
> who it came from (the "validity" of the identity associated with the
> key), *not* whether i'm willing to accept the keyholder's other
> identity assertions (the "trust" associated with the certificate).
>
pushed to release and master

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-12-09  2:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-30  4:20 [PATCH] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
2017-12-08  6:38 ` Daniel Kahn Gillmor
2017-12-08 18:36 ` David Bremner
2017-12-08 18:55   ` Daniel Kahn Gillmor
2017-12-08 18:55   ` [PATCH v2] " Daniel Kahn Gillmor
2017-12-08 20:09     ` v3 of fixing signature verification Daniel Kahn Gillmor
2017-12-08 20:09       ` [PATCH v3] crypto: signature verification reports valid User IDs Daniel Kahn Gillmor
2017-12-09  2:26         ` David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).