From 565bebad5e4ade8cfa6274919b8e4f647f35b129 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 26 May 2021 18:41:49 -0400 Subject: [PATCH] Prefer gpgme_user_id_t's address field over the email field GMimeCertificate's email field is typically populated from the `email` field of the highest-validity `gpgme_user_id_t` object. But gpgme offers some confusing commentary on the `gpgme_user_id_t`, [in particular](https://gnupg.org/documentation/manuals/gpgme/Key-objects.html#index-gpgme_005fuser_005fid_005ft): char *email This is the email component of uid, if available. char *address; The mail address (addr-spec from RFC-5322) of the user ID string. This is general the same as the email part of this structure but might be slightly different. If no mail address is available NULL is stored. It's hard to say exactly what this difference means. Experimenting with some certificates and gpgme 1.15.1, it looks to me like the differences between `email` and `address` are: - when an OpenPGP User ID *does* contain an e-mail address, the two fields appear to be identical: they are both the same addr-spec. - when an OpenPGP User ID does not appear to contain an e-mail address, `email` is set to the empty string, but `address` is set to NULL. - when rendering the X.509 Subject DN as a user ID, the email is the the empty string, but the address is set to NULL (this is true regardless of whether the DN contains an 1.2.840.113549.1.9.1 ("emailAddress") component, which I've [suggested might change](https://dev.gnupg.org/T5450), but I'm not convinced anything will happen). - when rendering an X.509 SubjectAltName of type rfc822Name, `address` is an addr-spec, but "email" is an angle-addr. that is, for [Alice's signing cert](https://www.ietf.org/archive/id/draft-ietf-lamps-samples-04.html#name-alices-signature-verificati), the `address` field is `alice@smime.example` but the email field is `` - when rendering an X.509 SubjectAltName of any other type, `email` is the empty string but `address` is NULL. It looks to me like `address` gives us a more stable guarantee -- it's either NULL or an addr-spec, while `email` might vary between: - the empty string - addr-spec - angle-addr (maybe the `email` field could be NULL as well, but i haven't encountered that yet). This patch prefers to populate the `email` field of GMimeCertificate from `gpgme_user_id_t`'s `address` field, when it is present but differs from the `email` field. --- gmime/gmime-gpgme-utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gmime/gmime-gpgme-utils.c b/gmime/gmime-gpgme-utils.c index 08699dbc..615ae318 100644 --- a/gmime/gmime-gpgme-utils.c +++ b/gmime/gmime-gpgme-utils.c @@ -383,6 +383,9 @@ g_mime_gpgme_get_signatures (gpgme_ctx_t ctx, gboolean verify) if (uid->name && *uid->name && !g_mime_certificate_get_name (signature->cert)) g_mime_certificate_set_name (signature->cert, uid->name); + if (uid->address && *uid->address && !g_mime_certificate_get_email (signature->cert)) + g_mime_certificate_set_email (signature->cert, uid->address); + if (uid->email && *uid->email && !g_mime_certificate_get_email (signature->cert)) g_mime_certificate_set_email (signature->cert, uid->email);