Subject: Re: bug#78448: 30.1; mml: Produce Unobtrusive Signatures

From: Daniel Kahn Gillmor <[email-masked]>
Date: Fri, 06 Jun 2025 16:32:18 -0400

Hi Robert--

Thank you for the review!

On Tue 2025-06-03 11:32:36 +0200, Robert Pluim wrote:
>     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.

Yes, unobtrusive signatures are defined with header protection
mandatory.

Please see
https://datatracker.ietf.org/doc/draft-gallagher-email-unobtrusive-signatures/

> We donʼt use Signed-off-by (and I think a change of this size probably
> requires copyright assignment).

OK, feel fre to strip Signed-off-by when applying, that doesn't matter
to me at all.  I'm already in communication with [email-masked] about
copyright assignment.

>     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.

with-output-to-string seems to transform stdout (standard output) to a
string.  But i don't see what i'm doing above as using stdout.  I thnk
they're all manipulatig a buffer, which is why i've wrapped them in the
various staging functions (save-excursion, save-restriction,
with-temp-buffer).  Which part should be replaced with
with-output-to-string?

> pgg is marked obsolete, and I think mailcrypt is external, so thatʼs
> ok.

Thanks!  That status was unclear to me.

>     Daniel> +  (re-search-forward "^")
>
> I think thatʼs better expressed as:
>
>     (forward-line 1)

Got it, thanks.

> Also, what is the chance that this will end up inserting certain
> headers twice?

For a signed-only e-mail with header-protection, all of the headers that
the generating MUA knows about will appear twice in the message: Once in
the outer message header section (outside of the cryptographic
envelope), and once in the cryptographic payload (so that they're
covered by the signature).

It's certainly possible to trim down the message size in the future by
dropping header fields that we expect to be ignored in transit by MTAs.
But i wouldn't try to do that until we're confident that most receiving
MUAs will handle the signed header fields in the Cryptographic Payload.

In practice, the cost of all duplicated header fields in aggregate is
small compared to, say, a single attached jpg, a boilerplate disclaimer,
or (depending on the algorithm) even the signature itself.  So I'm not
particularly concerned about size.

Regards,

        --dkg