summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2021-05-26 21:44:58 -0400
committerDavid Bremner <david@tethera.net>2021-06-26 13:07:47 -0300
commit8c29a5da096b0314c6cca8889b740b79a9a548ed (patch)
tree4e967955f6f29c0b74d949fc90e18f8dc4a27ab4
parent4b0c6fb2f1ba989fee554cb8fa2612046d6414a8 (diff)
cli/show: produce "email" element in sigstatus
When the certificate that signs a message is known to be valid, GMime is capable of reporting on the e-mail address embedded in the certificate. We pass this information along to the caller of "notmuch show", as often only the e-mail address of the certificate has actually been checked/verified. Furthermore, signature verification should probably at some point compare the e-mail address of the caller against the sender address of the message itself. Having to parse what gmime thinks is a "userid" to extract an e-mail address seems clunky and unnecessary if gmime already thinks it knows what the e-mail address is. See id:878s41ax6t.fsf@fifthhorseman.net for more motivation and discussion. Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-rw-r--r--devel/schemata1
-rw-r--r--notmuch-show.c5
-rwxr-xr-xtest/T350-crypto.sh6
-rwxr-xr-xtest/T355-smime.sh3
-rwxr-xr-xtest/T356-protected-headers.sh8
-rw-r--r--test/test-lib.sh1
-rw-r--r--util/gmime-extra.c15
-rw-r--r--util/gmime-extra.h4
8 files changed, 36 insertions, 7 deletions
diff --git a/devel/schemata b/devel/schemata
index 28332c6b..ae84a528 100644
--- a/devel/schemata
+++ b/devel/schemata
@@ -158,6 +158,7 @@ signature = {
created?: unix_time,
expires?: unix_time,
userid?: string
+ email?: string
# if status is not "good":
keyid?: string
errors?: sig_errors
diff --git a/notmuch-show.c b/notmuch-show.c
index bdb87321..232557d5 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -475,6 +475,11 @@ format_part_sigstatus_sprinter (sprinter_t *sp, GMimeSignatureList *siglist)
sp->map_key (sp, "userid");
sp->string (sp, uid);
}
+ const char *email = g_mime_certificate_get_valid_email (certificate);
+ if (email) {
+ sp->map_key (sp, "email");
+ sp->string (sp, email);
+ }
}
} else if (certificate) {
const char *key_id = g_mime_certificate_get_fpr16 (certificate);
diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh
index c1c1fccc..8dbf8935 100755
--- a/test/T350-crypto.sh
+++ b/test/T350-crypto.sh
@@ -35,7 +35,7 @@ expected='[[[{"id": "XXXXX",
"timestamp": 946728000,
"date_relative": "2000-01-01",
"tags": ["inbox","signed"],
- "crypto": {"signed": {"status": [{ "status": "good", "created": 946728000, "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'"}]}},
+ "crypto": {"signed": {"status": [{ "status": "good", "created": 946728000, "email": "'"$SELF_EMAIL"'", "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'"}]}},
"headers": {"Subject": "test signed message 001",
"From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
"To": "test_suite@notmuchmail.org",
@@ -44,6 +44,7 @@ expected='[[[{"id": "XXXXX",
"sigstatus": [{"status": "good",
"fingerprint": "'$FINGERPRINT'",
"created": 946728000,
+ "email": "'"$SELF_EMAIL"'",
"userid": "'"$SELF_USERID"'"}],
"content-type": "multipart/signed",
"content": [{"id": 2,
@@ -367,7 +368,7 @@ expected='[[[{"id": "XXXXX",
"timestamp": 946728000,
"date_relative": "2000-01-01",
"tags": ["encrypted","inbox"],
- "crypto": {"signed": {"status": [{ "status": "good", "created": 946728000, "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'"}],
+ "crypto": {"signed": {"status": [{ "status": "good", "created": 946728000, "fingerprint": "'$FINGERPRINT'", "email": "'"$SELF_EMAIL"'", "userid": "'"$SELF_USERID"'"}],
"encrypted": true },
"decrypted": {"status": "full"}},
"headers": {"Subject": "test encrypted message 002",
@@ -379,6 +380,7 @@ expected='[[[{"id": "XXXXX",
"sigstatus": [{"status": "good",
"fingerprint": "'$FINGERPRINT'",
"created": 946728000,
+ "email": "'"$SELF_EMAIL"'",
"userid": "'"$SELF_USERID"'"}],
"content-type": "multipart/encrypted",
"content": [{"id": 2,
diff --git a/test/T355-smime.sh b/test/T355-smime.sh
index b7269686..31fa4b4e 100755
--- a/test/T355-smime.sh
+++ b/test/T355-smime.sh
@@ -46,7 +46,7 @@ expected='[[[{"id": "XXXXX",
"timestamp": 946728000,
"date_relative": "2000-01-01",
"tags": ["inbox","signed"],
- "crypto": {"signed": {"status": [{"fingerprint": "'$FINGERPRINT'", "status": "good","userid": "CN=Notmuch Test Suite","expires": 424242424, "created": 946728000}]}},
+ "crypto": {"signed": {"status": [{"fingerprint": "'$FINGERPRINT'", "status": "good","userid": "CN=Notmuch Test Suite", "email": "<test_suite@notmuchmail.org>", "expires": 424242424, "created": 946728000}]}},
"headers": {"Subject": "test signed message 001",
"From": "Notmuch Test Suite <test_suite@notmuchmail.org>",
"To": "test_suite@notmuchmail.org",
@@ -55,6 +55,7 @@ expected='[[[{"id": "XXXXX",
"sigstatus": [{"fingerprint": "'$FINGERPRINT'",
"status": "good",
"userid": "CN=Notmuch Test Suite",
+ "email": "<test_suite@notmuchmail.org>",
"expires": 424242424,
"created": 946728000}],
"content-type": "multipart/signed",
diff --git a/test/T356-protected-headers.sh b/test/T356-protected-headers.sh
index 074a2345..f0aba14e 100755
--- a/test/T356-protected-headers.sh
+++ b/test/T356-protected-headers.sh
@@ -69,12 +69,12 @@ test_json_nodes <<<"$output" \
test_begin_subtest "show cryptographic envelope on signed mail"
output=$(notmuch show --verify --format=json id:simple-signed-mail@crypto.notmuchmail.org)
test_json_nodes <<<"$output" \
- 'crypto:[0][0][0]["crypto"]={"signed": {"status": [{"created": 1525609971, "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'", "status": "good"}]}}'
+ 'crypto:[0][0][0]["crypto"]={"signed": {"status": [{"created": 1525609971, "fingerprint": "'$FINGERPRINT'", "email": "'"$SELF_EMAIL"'", "userid": "'"$SELF_USERID"'", "status": "good"}]}}'
test_begin_subtest "verify signed protected header"
output=$(notmuch show --verify --format=json id:signed-protected-header@crypto.notmuchmail.org)
test_json_nodes <<<"$output" \
- 'crypto:[0][0][0]["crypto"]={"signed": {"status": [{"created": 1525350527, "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'", "status": "good"}], "headers": ["Subject"]}}'
+ 'crypto:[0][0][0]["crypto"]={"signed": {"status": [{"created": 1525350527, "fingerprint": "'$FINGERPRINT'", "email": "'"$SELF_EMAIL"'", "userid": "'"$SELF_USERID"'", "status": "good"}], "headers": ["Subject"]}}'
test_begin_subtest "protected subject does not leak by default in replies"
output=$(notmuch reply --decrypt=true --format=json id:protected-header@crypto.notmuchmail.org)
@@ -115,7 +115,7 @@ test_begin_subtest "verify protected header is both signed and encrypted"
output=$(notmuch show --decrypt=true --format=json id:encrypted-signed@crypto.notmuchmail.org)
test_json_nodes <<<"$output" \
'crypto:[0][0][0]["crypto"]={
- "signed":{"status": [{"status": "good", "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'", "created": 1525812676}],
+ "signed":{"status": [{"status": "good", "fingerprint": "'$FINGERPRINT'", "email": "'"$SELF_EMAIL"'", "userid": "'"$SELF_USERID"'", "created": 1525812676}],
"encrypted": true, "headers": ["Subject"]},"decrypted": {"status": "full", "header-mask": {"Subject": "Subject Unavailable"}}}' \
'subject:[0][0][0]["headers"]["Subject"]="Rhinoceros dinner"'
@@ -123,7 +123,7 @@ test_begin_subtest "verify protected header is signed even when not masked"
output=$(notmuch show --decrypt=true --format=json id:encrypted-signed-not-masked@crypto.notmuchmail.org)
test_json_nodes <<<"$output" \
'crypto:[0][0][0]["crypto"]={
- "signed":{"status": [{"status": "good", "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'", "created": 1525812676}],
+ "signed":{"status": [{"status": "good", "fingerprint": "'$FINGERPRINT'", "userid": "'"$SELF_USERID"'", "email": "'"$SELF_EMAIL"'", "created": 1525812676}],
"encrypted": true, "headers": ["Subject"]},"decrypted": {"status": "full"}}' \
'subject:[0][0][0]["headers"]["Subject"]="Rhinoceros dinner"'
diff --git a/test/test-lib.sh b/test/test-lib.sh
index f83f7c6a..67ad8853 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -131,6 +131,7 @@ add_gnupg_home () {
# Change this if we ship a new test key
FINGERPRINT="5AEAB11F5E33DCE875DDB75B6D92612D94E46381"
SELF_USERID="Notmuch Test Suite <test_suite@notmuchmail.org> (INSECURE!)"
+ SELF_EMAIL="test_suite@notmuchmail.org"
printf '%s:6:\n' "$FINGERPRINT" | gpg --quiet --batch --no-tty --import-ownertrust
}
diff --git a/util/gmime-extra.c b/util/gmime-extra.c
index 81a5b174..192cb078 100644
--- a/util/gmime-extra.c
+++ b/util/gmime-extra.c
@@ -108,6 +108,21 @@ g_mime_certificate_get_valid_userid (GMimeCertificate *cert)
}
const char *
+g_mime_certificate_get_valid_email (GMimeCertificate *cert)
+{
+ /* output e-mail address only if validity is FULL or ULTIMATE. */
+ const char *email = g_mime_certificate_get_email(cert);
+
+ if (email == NULL)
+ return email;
+ GMimeValidity validity = g_mime_certificate_get_id_validity (cert);
+
+ if (validity == GMIME_VALIDITY_FULL || validity == GMIME_VALIDITY_ULTIMATE)
+ return email;
+ 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 094309ec..889e91f3 100644
--- a/util/gmime-extra.h
+++ b/util/gmime-extra.h
@@ -69,6 +69,10 @@ 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);
+/**
+ * Return string for valid e-mail address (or NULL if no valid e-mail address exists)
+ */
+const char *g_mime_certificate_get_valid_email (GMimeCertificate *cert);
#ifdef __cplusplus
}