In an offline conversation with Bron and Tobias, they described a likely improvement to the header signing method described 26 March 2025. The following is my description of that proposal. The change is that all headers fields of a given name are signed, instead of worrying about the DKIM1 style of order sensitive "h=" header field name list. This also solves the problem of worrying singletons vs trace headers and how to protect against newly added header fields i.e. "oversigning".
As noted on 26 March, the recommended header field list is: * From * Reply-To * Subject * Date * To, Cc * Resent-Date, Resent-From, Resent-To, Resent-Cc * In-Reply-To, References * List-Id, List-Help, List-Unsubscribe, List-Subscribe, List-Post, List-Owner, List-Archive Hashing procedures 1) Find in the message which of the recommended header fields are present. Read the header fields in the order found in the recommended header field list, and canonicalize using the Relaxed algorithm found in RFC6376 section 3.4.2 <https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.2>. Then successively hash them. While not expected, if multiple header fields of a given name are found, read them from the header field in a bottom to top order as described in RFC6376 section 5.4.2 <https://datatracker.ietf.org/doc/html/rfc6376#section-5.4.2> and hash in that order. 2) Take the list of extra header field names given in the colon separated "h=" header field name list, and read the header field in the order found. Canonicalize using the Relaxed algorithm found in RFC6376 section 3.4.2 <https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.2> then successively hash them. If multiple header fields of a given name are found in "h=", read them in a bottom to top order as described in RFC6376 section 5.4.2 <https://datatracker.ietf.org/doc/html/rfc6376#section-5.4.2>. If not found, treat the value as empty. Unlike section 5.4.2, for each name in "h=", if multiple header fields with the same name are present, all instances will be hashed. 3) Hash the body and DKIM2-Signature header fields (out of scope for this description) The hashing for validation and signing algorithm is analogous. There is also an extra header field name "h=" list tag validation procedure. The names in the "h=" list at some later instance number "i=" must be a superset of earlier ones. A simple but restrictive check would require that any earlier instance number "h=" names must be a prefix of a given "h=" name list. EXAMPLE The following example simulates a message that went through a mailing list that rewrites the From header. Not included in this description is the header algebra to support this scenario. ORIGINATION MESSAGE: with List-Unsubscribe-Post as the extra header DKIM2-Signature: i=1; h=list-unsubscribe-post To: list@mailinglist.example From: user@origination.example List-Unsubscribe-Post: Order of header fields hashed: from:to:list-unsubscribe-post FORWARDED MESSAGE: From header rewritten and Delivered-to added DKIM2-Signature: i=2; h=list-unsubscribe-post:x-foo X-foo: ghi X-foo: def X-foo: abc From: list@mailinglist.example DKIM2-Signature: i=1; h=list-unsubscribe-post:x-foo To: list@mailinglist.example List-Unsubscribe-Post: Order of header fields hashed: from:to:list-unsubscribe-post:x-foo:x-foo:x-foo -Wei On Wed, Mar 26, 2025 at 1:23 AM Wei Chuang <wei...@google.com> wrote: > This is a strawman description for the DKIM2 header signing. I know that > Richard is writing a draft for this, but as draft writing is heavyweight > and before going too deep down a particular path, I think there is benefit > to put some sort of concept out early for community feedback. In the > IETF-122 discussion we heard from Bron that there is an implicit list of > headers that always will be signed, and that the headers will be > oversigned. There is also a DKIM2-Signature "h=" to specify extra headers > to be signed not covered by the implicit list as mentioned in > draft-gondwana-dkim2-header. Bron also mentioned that subsequent > DKIM2-Signatures extra headers "h=" cover prior DKIM2-Signatures "h=" > headers i.e. must be a superset. > > RFC6376 has a list of recommended headers to sign for in section 5.4.1 > <https://datatracker.ietf.org/doc/html/rfc6376#section-5.4.1>. This can > be the start of that implicit always signed headers. These are: > > * From > > * Reply-To > > * Subject > > * Date > > * To, Cc > > * Resent-Date, Resent-From, Resent-To, Resent-Cc > > * In-Reply-To, References > > * List-Id, List-Help, List-Unsubscribe, List-Subscribe, List-Post, > List-Owner, List-Archive > > At a high level, the signing algorithm would be: > > 1) Find in the message which of the recommended headers are present. > Obtain the values in the order found in the recommended headers list, and > canonicalize using the Relaxed algorithm found in RFC6376 section 3.4.2 > <https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.2>. Then > successively hash them. If multiple headers of a given name are found, > obtain these in a bottom to top order as described in RFC6376 section > 5.4.2 <https://datatracker.ietf.org/doc/html/rfc6376#section-5.4.2>. > > 2) Take the headers in the extra "h=" headers list, and obtain the value > in the order found. If multiple headers of a given name are found in "h=", > obtain them in a bottom to top order as described in RFC6376 section 5.4.2 > <https://datatracker.ietf.org/doc/html/rfc6376#section-5.4.2>. > Canonicalize using the Relaxed algorithm found in RFC6376 section 3.4.2 > <https://datatracker.ietf.org/doc/html/rfc6376#section-3.4.2> then > successively hash them. If not found, treat the value as empty. > > 3) Oversign the entire list of recommended headers as described in RFC6376 > section 3.5 <https://datatracker.ietf.org/doc/html/rfc6376#section-3.5> > thereby preventing those from being added to the message. This hashes an > empty value for each header. > > 4) Oversign the extra "h=" headers, preventing them from being added to > the message. This hashes an empty value for each header > > 5) Hash the body and DKIM2-Signature headers (out of scope for this > description) > > 6) Sign the hash. > > The validation algorithm is analogous. Hash as above, then perform the > signature validation with the hash. > > The giant <implicit oversigning list> is: > > > from:reply-to:subject:date:to:cc:resent-date:resent-from:resent-to:resent-cc:in-reply-to: > > > references:list-id:list-help:list-unsubscribe:list-subscribe:list-post:list-owner:list-archive > > EXAMPLE > > ORIGINATION MESSAGE: with List-Unsubscribe-Post as the extra header > > DKIM2-Signature: i=1; h=list-unsubscribe-post > > To: list@mailinglist.example > > From: user@origination.example > > List-Unsubscribe-Post: > > Effective h=from:to:list-unsubscribe-post:<implicit oversigning > list>:list-unsubscribe-post i.e. is order the headers are hashed. > > FORWARDED MESSAGE: From header rewritten and Delivered-to added > > DKIM2-Signature: i=2; h=list-unsubscribe-post:delivered-to > > From: list@mailinglist.example > > Delivered-to: list@mailinglist.example > > DKIM2-Signature: i=1; h=list-unsubscribe-post > > To: list@mailinglist.example > > List-Unsubscribe-Post: > > Effective h=from:to:list-unsubscribe-post:delivered-to:<implicit > oversigning list>: > > list-unsubscribe-post:delivered-to i.e. is order the headers are hashed. > > > So I think this implicit header signing could work and does save some > unnecessary legacy h= overhead in the message header. > > -Wei >
_______________________________________________ Ietf-dkim mailing list -- ietf-dkim@ietf.org To unsubscribe send an email to ietf-dkim-le...@ietf.org