A method for describing changes made to an email
Bron Gondwana
Fastmail Pty Ltd
Level 2, 114 William Street
3000
Australia
+61 457 416 436
brong@fastmailteam.com
03 November 2024
Internet-Draft
This memo describes a method for describing the changes made to an email during common email modifications, for example those caused by mailing lists and forwarders.
While this is general enough to be used for any changes, it is anticipated that this method will normally be used for removing added data rather than large complex changes.
Background and motivations
Currently, when an email is sent with a DKIM signature, the message can go through multiple forwarders and still be authenticated, however if a single change is made to a header which is covered by the signature, or to the body, then the signature no longer validates - and it's impossible for the receiver to know what was changed, or even if the entire messages content was replaced by an attacker.
By producing a way to describe changes, the recipient can examine the sections which were changed and determine whether the change was malicious. Because each step signs its own changes in DKIM2, this also allows the recipient to identify exactly which intermediary introduced the malicious change, and adjust their reputation accordingly.
Difference format - headers
For headers, the format is to completely replace all headers with a particular name. For example if you replace the subject and from address in an email, then you need to include the complete old headers for each of those:
Header: "DKIM2-Diff-Header:"
Command | Input
i | DKIM2 matching header number
b | replace headers with base64 octet value
t | replace headers with raw text characters value
Example for a message which has had Subject and From replaced, and Reply-To added.

From: brong@fastmailteam.com.dmarc.fail
To: dkim2@lists.ietf.org
Reply-To: dkim2@lists.ietf.org
DKIM2-Diff-Header: i=3;
                   t=Subject,A replacement for DKIM;
                   b=From,YnJvbmdAZmFzdG1haWx0ZWFtLmNvbQo=;
                   t=Reply-To

Difference format - body
This difference format for the body is inspired by [RFC3284] (The VCDIFF Generic Differencing and Compression Data Format).
Since the transport for the differences is a 7-bit mime header, this format has been made simple and human readable. It is a simple program describing ranges of data to copy from the output to recreate the input.
Header: "DKIM2-Diff-Body:"
Command | Input
i | DKIM2 matching header number
c | copy offset-length from new-message body
b | insert octets from base64 encoded value
t | insert raw text of value
Example:

DKIM2-Diff-Body: i=2;
                 c=0-19452;
                 c=20312-150

Example - appended to some base64 content; so we need to add back the last few characters (and the mime trailer)

DKIM2-Diff-Body: i=2;
                 c=0-19452;
                 t=aX==;
                 c=20312-150

Example - a URL was substituted in the content of the body (complex, but still easily doable!)

DKIM2-Diff-Body: i=3;
                 c=0-3542;
                 b=PGEgaHJlZj0iaHR0cHM6Ly93d3cuZXhhb
                   XBsZS5jb20iPkV4YW1wbGU8L2E+Cg==;
                 c=3623-84743

The decision whether to use 'b' or 't' is up to the system creating the diff, however 't' has a limited set of characters that are safe to use in headers.
Signature coverage.
Each DKIM2 signature implicitly covers all DKIM2-Diff-Body and DKIM2-Diff-Header headers with an i=N value for the same and lower N values as the i= on the DKIM2 header.
Iterative application
To get back to the original message and confirm that it was unchanged, it is necessary to apply this algorith iteratively.
For example if you receive a message at i=7 for which there is a modification to the headers at i=5 and a modification to both headers and body at i=3, to recreate the original message you would first apply the header changes from i=5, then apply the header and body changes for i=3. If this doesn't create a message which validates with the initial i=1 signature, then some hop has corrupted the message, and you can check every single DKIM signature in reverse to find the first one where the message no longer validates.
Security
TBA
IANA Considerations
TBA

Informative References
[RFC3284]

The VCDIFF Generic Differencing and Compression Data Format
D. Korn
J. MacDonald
J. Mogul
K. Vo
June 2002
RFC 3284
DOI 10.17487/RFC3284
Changes from Earlier Versions
[[This section to be removed by RFC Editor]]