Reported by: Daniel Kahn Gillmor <dkg <at> fifthhorseman.net>
Date: Fri, 16 May 2025 03:57:02 UTC
Severity: normal
Found in version 30.1
Message #29 received at 78448 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: eric <at> ericabrahamsen.net, 78448 <at> debbugs.gnu.org, rms <at> gnu.org, Daniel Kahn Gillmor <dkg <at> fifthhorseman.net> Subject: Re: bug#78448: 30.1; mml: Produce Unobtrusive Signatures Date: Tue, 03 Jun 2025 11:32:36 +0200
>>>>> On Sat, 31 May 2025 12:21:10 +0300, Eli Zaretskii <eliz <at> gnu.org> said: Eli> Ping! Eric, would you please chime in and comment on the Eli> patch? Iʼm not Eric, but I have comments and questions below Daniel> These three patches appear to do the trick for me. I'm not an elisp Daniel> guru or a gnus expert. I'm happy to hear any feedback about how they Daniel> could be improved. Daniel> Regards, Daniel> --dkg Daniel> From 81c3e7f5de0bbb24bbd2a2b43a103fb83c530f6d Mon Sep 17 00:00:00 2001 Daniel> From: Daniel Kahn Gillmor <dkg <at> fifthhorseman.net> Daniel> Date: Thu, 15 May 2025 21:49:32 -0400 Daniel> Subject: [PATCH 1/3] mml: Pass likely headers through to mml-sec functions Daniel> By pre-computing the likely headers for an outbound message, and passing Daniel> them along as a tag in mml-parse, we create an opportunity to provide Daniel> Header Protection as described in Daniel> https://datatracker.ietf.org/doc/draft-ietf-lamps-header-protection/ Is this necessary for unobtrusive signatures to work? If itʼs to enable future functionality Iʼd rather leave it out. Daniel> Signed-off-by: Daniel Kahn Gillmor <dkg <at> fifthhorseman.net> We donʼt use Signed-off-by (and I think a change of this size probably requires copyright assignment). Daniel> --- Daniel> lisp/gnus/mml.el | 17 +++++++++++++++++ Daniel> 1 file changed, 17 insertions(+) Daniel> diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el Daniel> index 51d8d2c3769..11a8de7c011 100644 Daniel> --- a/lisp/gnus/mml.el Daniel> +++ b/lisp/gnus/mml.el Daniel> @@ -265,6 +265,8 @@ part. This is for the internal use, you should never modify the value.") Daniel> (apply #'mml-insert-tag Daniel> secure-mode Daniel> `(,@tags Daniel> + ,"likely-headers" Daniel> + ,(mml-get-likely-headers) Daniel> ,(if keyfile "keyfile") Daniel> ,keyfile Daniel> ,@(apply #'append Daniel> @@ -492,6 +494,21 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." Daniel> (declare-function libxml-parse-html-region "xml.c" Daniel> (start end &optional base-url discard-comments)) Daniel> +(defun mml-get-likely-headers () Daniel> + "Get likely final headers from the existing message" Daniel> + (save-excursion Daniel> + (save-restriction Daniel> + (message-narrow-to-headers-or-head) Daniel> + (let ((x (buffer-substring (point-min) (point-max)))) Daniel> + (with-temp-buffer Daniel> + (insert x) Daniel> + (message-remove-header "Bcc") Daniel> + (message-remove-header message-ignored-mail-headers t) Daniel> + (mail-encode-encoded-word-buffer) Daniel> + (message-cleanup-headers) Daniel> + (buffer-string) Daniel> + ))))) Daniel> + `with-output-to-string' is what youʼre looking for here, I think. Daniel> (defun mml-generate-mime (&optional multipart-type content-type) Daniel> "Generate a MIME message based on the current MML document. Daniel> MULTIPART-TYPE defaults to \"mixed\", but can also Daniel> -- Daniel> 2.47.2 Daniel> From 75f8c5c936deafea1ee44edad5e0f530ec6c4dfc Mon Sep 17 00:00:00 2001 Daniel> From: Daniel Kahn Gillmor <dkg <at> fifthhorseman.net> Daniel> Date: Thu, 15 May 2025 21:54:06 -0400 Daniel> Subject: [PATCH 2/3] mml: Enable production of Unobtrusive Signatures via epg Daniel> https://datatracker.ietf.org/doc/draft-gallagher-email-invisible-signatures/ Daniel> describes a mechanism to produce cleartext signatures over MIME messages Daniel> that are less likely to cause problems than traditional PGP/MIME. Daniel> With this patch, it's possible to produce those signatures with: Daniel> (mml-secure-message "unobtrusive" 'sign) Daniel> This patch only works with epg, not with mailcrypt or pgg, because epg Daniel> is what i'm familiar with and what i can easily test. pgg is marked obsolete, and I think mailcrypt is external, so thatʼs ok. Daniel> Signed-off-by: Daniel Kahn Gillmor <dkg <at> fifthhorseman.net> Daniel> --- Daniel> lisp/gnus/mml-sec.el | 6 ++++++ Daniel> lisp/gnus/mml2015.el | 39 +++++++++++++++++++++++++++++++++++++++ Daniel> 2 files changed, 45 insertions(+) Daniel> diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el Daniel> index 8dffcf872f3..6fb82836e9a 100644 Daniel> --- a/lisp/gnus/mml-sec.el Daniel> +++ b/lisp/gnus/mml-sec.el Daniel> @@ -34,6 +34,7 @@ Daniel> (autoload 'mail-strip-quoted-names "mail-utils") Daniel> (autoload 'mml2015-sign "mml2015") Daniel> (autoload 'mml2015-encrypt "mml2015") Daniel> +(autoload 'mml-unobtrusive-sign "mml2015") Daniel> (autoload 'mml1991-sign "mml1991") Daniel> (autoload 'mml1991-encrypt "mml1991") Daniel> (autoload 'message-fetch-field "message") Daniel> @@ -56,6 +57,7 @@ Daniel> '(("smime" mml-smime-sign-buffer mml-smime-sign-query) Daniel> ("pgp" mml-pgp-sign-buffer list) Daniel> ("pgpauto" mml-pgpauto-sign-buffer list) Daniel> + ("unobtrusive" mml-unobtrusive-sign-buffer list) Daniel> ("pgpmime" mml-pgpmime-sign-buffer list)) Daniel> "Alist of MIME signer functions.") Daniel> @@ -198,6 +200,10 @@ You can also customize or set `mml-signencrypt-style-alist' instead." Daniel> (or (mml2015-sign cont) Daniel> (error "Signing failed... inspect message logs for errors"))) Daniel> +(defun mml-unobtrusive-sign-buffer (cont) Daniel> + (or (mml-unobtrusive-sign cont) Daniel> + (error "Signing failed... inspect message logs for errors"))) Daniel> + Daniel> (defun mml-pgpmime-encrypt-buffer (cont &optional sign) Daniel> (or (mml2015-encrypt cont sign) Daniel> (error "Encryption failed... inspect message logs for errors"))) Daniel> diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el Daniel> index a46aa68f56a..646fb018a31 100644 Daniel> --- a/lisp/gnus/mml2015.el Daniel> +++ b/lisp/gnus/mml2015.el Daniel> @@ -25,6 +25,9 @@ Daniel> ;; RFC 2015 is updated by RFC 3156, this file should be compatible Daniel> ;; with both. Daniel> +;; This is also capable of producing unobtrusive signatures based on Daniel> +;; draft-gallagher-email-unobtrusive-signatures Daniel> + Daniel> ;;; Code: Daniel> (eval-when-compile (require 'cl-lib)) Daniel> @@ -945,6 +948,42 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." Daniel> (insert (format "--%s--\n" boundary)) Daniel> (goto-char (point-max)))) Daniel> +;;; Unobtrusive Signatures, see: Daniel> +;;; https://datatracker.ietf.org/doc/draft-gallagher-email-unobtrusive-signatures/ Daniel> + Daniel> +; convert ASCII-armored PGP SIGNATURE block to base64-encoded with FWS Daniel> +; at the start of each line: Daniel> +(defun pgpsig-armor-to-wrapped-b64 (s) Daniel> + (string-join Daniel> + (string-split Daniel> + (string-trim-right Daniel> + (string-trim-left s "-----BEGIN PGP SIGNATURE-----\n\\(?:[^\n]+\n\\)*\n") Daniel> + "\n\\(?:=....\n\\)?-----END PGP SIGNATURE-----\n?") Daniel> + "\n") Daniel> + "\n ")) Daniel> + Daniel> +(defun mml-unobtrusive-sign (cont) Daniel> + (goto-char (point-min)) Daniel> + (insert (cdr (assq 'likely-headers cont))) Daniel> + (re-search-forward "^Content-Type: [^\n]*\\(\n[ \t][^\n]*$\\)*") Daniel> + (insert "; hp=\"clear\"") Daniel> + (re-search-forward "^") I think thatʼs better expressed as: (forward-line 1) Also, what is the chance that this will end up inserting certain headers twice? Robert --
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.