<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.19 (Ruby 3.0.2) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-gondwana-dkim2-modification-alegbra-02" category="std" consensus="true" submissionType="IETF" obsoletes="4686" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="Email Modification Algebra">A method for describing changes made to an email</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail Pty Ltd</organization>
      <address>
        <postal>
          <street>Level 2, 114 William Street</street>
          <code>3000</code>
          <country>Australia</country>
        </postal>
        <phone>+61 457 416 436</phone>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>

    <date year="2025" month="June" day="18"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 31?>

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

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



    </abstract>



  </front>

  <middle>


<?line 41?>

<section anchor="background-and-motivations"><name>Background and motivations</name>

<t>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 message was replaced.</t>

<t>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 each change, and adjust their
reputation accordingly.</t>

</section>
<section anchor="delta-format-headers"><name>Delta format - headers</name>

<t>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:</t>

<t>Header: "DKIM2-Delta-Header:"</t>

<texttable>
      <ttcol align='left'>Command</ttcol>
      <ttcol align='left'>Input</ttcol>
      <c>i</c>
      <c>DKIM2 matching header number</c>
      <c>b</c>
      <c>replace headers with base64 octet value</c>
      <c>t</c>
      <c>replace headers with raw text characters value</c>
</texttable>

<t>Example for a message which has had Subject and From replaced,
and Reply-To added.</t>

<figure><artwork><![CDATA[
From: brong@fastmailteam.com.dmarc.fail
To: dkim2@lists.ietf.org
Reply-To: dkim2@lists.ietf.org
DKIM2-Delta-Header: i=3;
 t=Subject:A replacement for DKIM;
 b=From:YnJvbmdAZmFzdG1haWx0ZWFtLmNvbQo=;
 t=Reply-To
]]></artwork></figure>

<t>Notice that "Reply-To" has no colon, and hence is an instruction to
remove any "Reply-To" headers.  All headers are case insignificant
for removal, and SHOULD be inserted with the case given in the header
when being added back.</t>

</section>
<section anchor="delta-format-body"><name>Delta format - body</name>

<t>This difference format for the body was originally going to be
an octet-based change format, however this is incompatible with
"relaxed" signature checks as line ending normalisation could
change the octet lengths, so this format was changed to be line
based.</t>

<t>Since the transport for the delta 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.</t>

<t>Header: "DKIM2-Delta-Body:"</t>

<texttable>
      <ttcol align='left'>Command</ttcol>
      <ttcol align='left'>Input</ttcol>
      <c>i=n</c>
      <c>DKIM2 matching header number</c>
      <c>b=b64val</c>
      <c>decode the value as base64 an insert the resulting octets as a line</c>
      <c>c=a-b</c>
      <c>insert the numbered lines from a to b inclusive (starting at 1)</c>
      <c>t=value</c>
      <c>insert the text of the value as a line</c>
      <c>z=y</c>
      <c>MUST be the only source; changes are not reversible via this mechanism</c>
</texttable>

<t>Example:</t>

<figure><artwork><![CDATA[
DKIM2-Delta-Body: i=2; c=1-500; c=520-520
]]></artwork></figure>

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

<figure><artwork><![CDATA[
DKIM2-Delta-Body: i=3;
 c=1-500;
 b=PGEgaHJlZj0iaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iPkV4YW1wbGU8L2E+Cg==;
 c=501-702
]]></artwork></figure>

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

<t>Likewise, it is expected that 'c' will normally be used to copy lines directly from
the new message, however in cases where a message needs to transit 7 bits systems
cleanly, the email modifier may need to re-encode the octets of the original message,
and this allows for doing so.</t>

</section>
<section anchor="signature-coverage"><name>Signature coverage.</name>

<t>Each DKIM2 signature implicitly covers all DKIM2-Delta-Body and DKIM2-Delta-Header headers
with an <spanx style="verb">i=N</spanx> value for the same and lower N values as the <spanx style="verb">i=</spanx> on the DKIM2 header.</t>

</section>
<section anchor="iterative-application"><name>Iterative application</name>

<t>To get back to the original message and confirm that it was unchanged, it is necessary
to apply this algorith iteratively.</t>

<t>For example if you receive a message at <spanx style="verb">i=7</spanx> for which there is a modification to the
headers at <spanx style="verb">i=5</spanx> and a modification to both headers and body at <spanx style="verb">i=3</spanx>, to recreate the
original message you would first apply the header changes from <spanx style="verb">i=5</spanx>, then apply the
header and body changes for <spanx style="verb">i=3</spanx>.  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.</t>

</section>
<section anchor="security"><name>Security</name>

<t>TBA</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>TBA</t>

</section>


  </middle>

  <back>




    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="RFC3284">
  <front>
    <title>The VCDIFF Generic Differencing and Compression Data Format</title>
    <author fullname="D. Korn" initials="D." surname="Korn"/>
    <author fullname="J. MacDonald" initials="J." surname="MacDonald"/>
    <author fullname="J. Mogul" initials="J." surname="Mogul"/>
    <author fullname="K. Vo" initials="K." surname="Vo"/>
    <date month="June" year="2002"/>
    <abstract>
      <t>This memo describes VCDIFF, a general, efficient and portable data format suitable for encoding compressed and/or differencing data so that they can be easily transported among computers. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3284"/>
  <seriesInfo name="DOI" value="10.17487/RFC3284"/>
</reference>

<reference anchor="RFC2046">
  <front>
    <title>Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types</title>
    <author fullname="N. Freed" initials="N." surname="Freed"/>
    <author fullname="N. Borenstein" initials="N." surname="Borenstein"/>
    <date month="November" year="1996"/>
    <abstract>
      <t>This second document defines the general structure of the MIME media typing system and defines an initial set of media types. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="2046"/>
  <seriesInfo name="DOI" value="10.17487/RFC2046"/>
</reference>




    </references>



<?line 163?>

<section anchor="changes-from-earlier-versions"><name>Changes from Earlier Versions</name>

<section anchor="draft-gondwana-dkim2-modification-algebra-02"><name>draft-gondwana-dkim2-modification-algebra-02</name>

<t><list style="symbols">
  <t>change to using line numbers rather than octet offsets</t>
  <t>remove d= base64 decoding capability</t>
  <t>for multiple lines; require a separate b= or t= for each line</t>
</list></t>

</section>
<section anchor="draft-gondwana-dkim2-modification-algebra-01"><name>draft-gondwana-dkim2-modification-algebra-01</name>

<t><list style="symbols">
  <t>rename 'DKIM2-Diff' headers to 'DKIM2-Delta'</t>
  <t>add 'z=y' option to DKIM2-Delta-Body for "complete replacement"</t>
  <t>add d= base64 decoding option to DKIM2-Delta-Body</t>
</list></t>

</section>
<section anchor="draft-gondwana-dkim2-modification-algebra-00"><name>draft-gondwana-dkim2-modification-algebra-00</name>

<t><list style="symbols">
  <t>original version</t>
</list></t>

<t>[[This section to be removed by RFC Editor]]</t>

</section>
</section>


  </back>

<!-- ##markdown-source:
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

-->

</rfc>

