RFC 5672

RFC 4871 DomainKeys Identified Mail (DKIM) Signatures -- Update

πŸ“… published August 2009, from ietf

RFC 5672 πŸ’–

Okay bestie, this one is an Update to RFC 4871, the DomainKeys Identified Mail (DKIM) Signatures spec, so the title is RFC 4871 DomainKeys Identified Mail (DKIM) Signatures -- Update πŸ“¬. It's a Standards Track doc, dated August 2009, and it was written by D. Crocker, Ed. from Brandenburg InternetWorking πŸŽ€. It's part of the Network Working Group, and it updates RFC 4871. It doesn't list anything it obsoletes ✨.

Abstract

This doc updates RFC 4871 (the DKIM Signatures one) πŸ¦‹. It clarifies the nature, roles, and relationship of the two DKIM identifier tag values that could get handed off to a receiving processing module. The Update is written like an Errata entry, just a really long one 😭.

Status of This Memo

This document describes an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements 🌸. For the current standardization state and status of this protocol, check the current edition of "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited 🫢.

Copyright (c) 2009 IETF Trust and the persons identified as the document authors. All rights reserved πŸ’œ.

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, as they stand on the publication date of this document. The legal provisions live at http://trustee.ietf.org/license-info. Read them carefully, because they spell out your rights and restrictions for this doc πŸ“œ.

This doc may include material from IETF Documents or IETF Contributions that were published or made publicly available before November 10, 2008. The people who control the copyright in some of that material might not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So, unless you get an adequate license from whoever controls that copyright, this doc can't be modified outside the IETF Standards Process, and derivative works of it can't be created outside it either. The exceptions are formatting it for publication as an RFC, or translating it into languages other than English 🌈.

Table of Contents

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
2.  RFC 4871, Abstract . . . . . . . . . . . . . . . . . . . . . .  4
3.  RFC 4871, Section 1, Introduction  . . . . . . . . . . . . . .  4
4.  RFC 4871, Section 2.7, Identity  . . . . . . . . . . . . . . .  4
5.  RFC 4871, Section 2.8, Identifier  . . . . . . . . . . . . . .  5
6.  RFC 4871, Section 2.9, Signing Domain Identifier (SDID)  . . .  5
7.  RFC 4871, Section 2.10, Agent or User Identifier (AUID)  . . .  5
8.  RFC 4871, Section 2.11, Identity Assessor  . . . . . . . . . .  6
9.  RFC 4871, Section 3.5, The DKIM-Signature Header Field . . . .  6
10. RFC 4871, Section 3.5, The DKIM-Signature Header Field . . . .  7
11. RFC 4871, Section 3.8, Signing by Parent Domains  . . . . . . . 9
12. RFC 4871, Section 3.9, Relationship between SDID and AUID  . . 10
13. RFC 4871, Section 6.3, Interpret Results/Apply Local Policy  . 11
14. RFC 4871, Section 6.3, Interpret Results/Apply Local Policy  . 11
15. RFC 4871, Appendix D, MUA Considerations . . . . . . . . . . . 12
16. Security Considerations  . . . . . . . . . . . . . . . . . . . 12
17. Normative References . . . . . . . . . . . . . . . . . . . . . 12
Appendix A.  ABNF Fragments  . . . . . . . . . . . . . . . . . . . 13
Appendix B.  Acknowledgements  . . . . . . . . . . . . . . . . . . 14

1. Introduction ✨

Okay so, about why DKIM exists in the first place, RFC 4871 says this 🧚:

The ultimate goal of this framework is to permit a signing domain to assert responsibility for a message, thus protecting message signer identity...

So DKIM has a signer that makes a signed message, a verifier that confirms the signature, and an assessor that consumes the validated signing domain πŸ’…. The simple purpose of DKIM is to pass an identifier along to a receive-side assessor module. That identifier is a domain name that points to a responsible identity. For DKIM to be interoperable and useful, the signer and the assessor need to share the same understanding of the details about the identifier πŸŽ€.

Here's the issue though 😬. RFC 4871 defines two identifiers that can be different from each other, and both live in the DKIM-Signature: header field: d= and i=. Either one might get delivered to a receiving processing module that consumes the validated payload. The DKIM spec doesn't clearly say which one is the "payload" that gets delivered to the consuming module, and which one is just internal stuff that supports getting the payload delivered πŸ™ˆ.

That leaves signers and assessors open to reading the two identifiers differently, which can cause interoperability problems. A signer might mean for one of them to be used for assessment, and mean something else by the value in the other tag. Then the verifier might pick the wrong value to hand to the assessor, and you get an unintended (and inaccurate) assessment πŸ’€.

This Update fixes that confusion πŸ¦‹. It defines extra semantic labels for the two values, clarifies what each one is, and specifies how they relate. To be specific, it says the identifier meant for delivery to the assessor (the one that, for example, consults a whitelist) is the value of the d= tag. This does not stop message filtering engines from using the i= tag, or any other information in the message's header, for filtering decisions πŸ’–.

If your signers and verifiers have been using the i= tag as the main value delivered to the assessor, the plan is a software change over to using the d= tag πŸ“.

So this Update clarifies the formal interface to DKIM after signature verification has been done. It separates DKIM's internal signing and verification activity from its standardized delivery of data to that interface πŸ‘‘.

The focus here is the part of DKIM that works a lot like an API definition. If DKIM is implemented as a software library that other people use, it needs to define what outputs it provides. In other words, it needs to say what data an application developer using the library can expect to get back from invoking DKIM on a message 🌈.

This Update says the output of that library includes the yes/no result of the verification and the d= value. Put another way, it says which one identifier was formally specified for use by the signer, and whether using that identifier has been validated ✨. A particular library can provide other information at the discretion of the library developer, because assessor developers (the ones who consume the DKIM library) might want more info than the two standardized pieces. Still, that standardized set is the minimum that is required to be provided to a consuming module, in order for the library to claim it's DKIM compliant πŸ’œ.

This doesn't say what the implicit value of i= is, relative to d=. In this context, that fact is irrelevant πŸ™ƒ.

Another example is the difference between the socket interface to TCP and the TCP protocol itself. There's the activity inside the protocol stack, and then there's the activity inside the software libraries that actually get used 🧦.

NOTE: The text provided here updates [RFC4871]. Text appearing in the "Corrected Text:" replaces text in RFC 4871. So references that appear in the "Original Text:" can be found in RFC 4871, and aren't duplicated in this document πŸ“š.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] 🫢.

2. RFC 4871, Abstract πŸ’…

Original Text:

The ultimate goal of this framework is to permit a signing domain
to assert responsibility for a message,

Corrected Text:

The ultimate goal of this framework is to permit a person, role or
organization that owns the signing domain to assert responsibility
for a message,

3. RFC 4871, Section 1, Introduction 🌸

Original Text:

...permitting a signing domain to claim responsibility

Corrected Text:

permitting a person, role, or organization that owns the signing
domain to claim responsibility

4. RFC 4871, Section 2.7, Identity πŸŽ€

Original Text:

(None.  New section.  Additional text.)

Corrected Text:

A person, role, or organization.  In the context of DKIM, examples
include author, author's organization, an ISP along the handling
path, an independent trust assessment service, and a mailing list
operator.

5. RFC 4871, Section 2.8, Identifier πŸ¦‹

Original Text:

(None.  New section.  Additional text.)

Corrected Text:

A label that refers to an identity.

6. RFC 4871, Section 2.9, Signing Domain Identifier (SDID) πŸ‘‘

Original Text:

(None.  New section.  Additional text.)

Corrected Text:

A single domain name that is the mandatory payload output of DKIM
and that refers to the identity claiming responsibility for
introduction of a message into the mail stream.  For DKIM
processing, the name has only basic domain name semantics; any
possible owner-specific semantics are outside the scope of DKIM.
It is specified in Section 3.5.

7. RFC 4871, Section 2.10, Agent or User Identifier (AUID) 🌈

Original Text:

(None.  New section.  Additional text.)

Corrected Text:

A single identifier that refers to the agent or user on behalf of
whom the Signing Domain Identifier (SDID) has taken
responsibility.  The AUID comprises a domain name and an optional
<Local-part>.  The domain name is the same as that used for the
SDID or is a sub-domain of it.  For DKIM processing, the domain
name portion of the AUID has only basic domain name semantics; any
possible owner-specific semantics are outside the scope of DKIM.
It is specified in Section 3.5.

8. RFC 4871, Section 2.11, Identity Assessor 🫧

Original Text:

(None.  New section.  Additional text.)

Corrected Text:

A module that consumes DKIM's mandatory payload, which is the
responsible Signing Domain Identifier (SDID).  The module is
dedicated to the assessment of the delivered identifier.  Other
DKIM (and non-DKIM) values can also be delivered to this module as
well as to a more general message evaluation filtering engine.
However, this additional activity is outside the scope of the DKIM
signature specification.

9. RFC 4871, Section 3.5, The DKIM-Signature Header Field ✨

Original Text:

Okay so the d= tag is the domain of the signing entity (plain-text; REQUIRED) πŸŽ€. It's the domain that gets queried for the public key. This domain MUST be the same as or a parent domain of the i= tag (the signing identity, which we'll get to), or it MUST meet the requirements for parent domain signing described in Section 3.8. When a verifier gets a signature that doesn't meet these requirements, it MUST consider the signature invalid. πŸ’€

Internationalized domain names MUST be encoded as described in [RFC3490].

ABNF:

   sig-d-tag       = %x64 [FWS] "=" [FWS] domain-name
   domain-name     = sub-domain 1*("." sub-domain)
                    ; from RFC 2821 Domain,
                      but excluding address-literal

Corrected Text:

Here's the glow-up πŸ’–. The d= tag specifies the SDID claiming responsibility for an introduction of a message into the mail stream (plain-text; REQUIRED). So the SDID value is what gets used to form the query for the public key. The SDID MUST correspond to a valid DNS name under which the DKIM key record is published. How a signer comes up with and uses a specific SDID, plus any use of those conventions and semantics, is totally outside the scope of the DKIM Signing specification πŸ™ˆ. When a verifier is presented with a signature that doesn't meet these requirements, it MUST consider the signature invalid.

Internationalized domain names MUST be encoded as described in [RFC3490].

ABNF:

   sig-d-tag   = %x64 [FWS] "=" [FWS] domain-name
   domain-name = sub-domain 1*("." sub-domain)
                 ; from RFC 5321 Domain,
                   but excluding address-literal

10. RFC 4871, Section 3.5, The DKIM-Signature Header Field ✨

Original Text:

The i= tag is the identity of the user or agent (e.g., a mailing list manager) on whose behalf this message is signed (dkim-quoted-printable; OPTIONAL). If it's left out, the default is an empty Local-part, followed by an "@", followed by the domain from the d= tag πŸ“. The syntax is a standard email address where the Local-part MAY be omitted. The domain part of the address MUST be the same as or a subdomain of the value of the d= tag.

Internationalized domain names MUST be converted using the steps listed in Section 4 of [RFC3490] using the "ToASCII" function.

ABNF:

   sig-i-tag =  %x69 [FWS] "=" [FWS]
                [ Local-part ] "@" domain-name

INFORMATIVE NOTE: The Local-part of the i= tag is optional because, in some cases, a signer may not be able to establish a verified individual identity. In those cases, the signer may wish to say that although it's willing to go as far as signing for the domain, it's unable or unwilling to commit to an individual user name within its domain. It can do that by including the domain part but not the Local-part of the identity.

INFORMATIVE DISCUSSION: This document does not require the value of the i= tag to match the identity in any message header fields. That's considered a verifier policy issue 🧚. Constraints between the value of the i= tag and other identities in other header fields try to bring basic authentication into the semantics of trust tied to a role, like content author. Trust is a broad and complex topic, and trust mechanisms are subject to highly creative attacks 😭. The real-world efficacy of bindings between the i= value and other identities isn't well established, and neither is its vulnerability to subversion by an attacker. Hence, reliance on the use of these options should be strictly limited. In particular, it's not at all clear to what extent a typical end-user recipient can rely on any assurances that might be made by successful use of the i= options.

Corrected Text:

Okay this one's the main character πŸ‘‘. The i= tag is the Agent or User Identifier (AUID) on whose behalf the SDID is taking responsibility (dkim-quoted-printable; OPTIONAL). If it's not there, the default is an empty Local-part, followed by an "@", followed by the domain from the d= tag.

The syntax is a standard email address where the Local-part MAY be omitted. The domain part of the address MUST be the same as, or a subdomain of, the value of the d= tag.

Internationalized domain names MUST be converted using the steps listed in Section 4 of [RFC3490] using the "ToASCII" function.

ABNF:

   sig-i-tag =  %x69 [FWS] "=" [FWS]
               [ Local-part ] "@" domain-name

The AUID is written with the same syntax as an email address, but it doesn't have to carry the same semantics πŸ¦‹. Notably, the domain name doesn't have to be registered in the DNS, so it might not resolve in a query. The Local-part MAY come from a namespace that doesn't contain the user's mailbox. The Signer decides the structure and semantics of that namespace. Any knowledge or use of those details by verifiers or assessors is outside the scope of the DKIM Signing specification. The Signer MAY choose to use the same namespace for its AUIDs as its users' email addresses, or MAY choose other ways of representing its users. However, the Signer SHOULD use the same AUID for each message intended to be evaluated as being within the same sphere of responsibility, if it wants to give receivers the option of using the AUID as a stable identifier that's finer grained than the SDID πŸ’œ.

INFORMATIVE NOTE: The Local-part of the i= tag is optional because, in some cases, a signer may not be able to establish a verified individual identity. In those cases, the signer might wish to say that although it's willing to go as far as signing for the domain, it's unable or unwilling to commit to an individual user name within its domain. It can do that by including the domain part but not the Local-part of the identity.


11. RFC 4871, Section 3.8, Signing by Parent Domains ✨

Original Text:

For example, a key record for the domain example.com can be used to verify messages where the signing identity (the i= tag of the signature) is sub.example.com, or even sub1.sub2.example.com. To limit what such keys can do when that isn't intended, the s flag may be set in the t= tag of the key record. That constrains the validity of the record to exactly the domain of the signing identity πŸ”₯. If the referenced key record contains the s flag as part of the t= tag, the domain of the signing identity (i= flag) MUST be the same as that of the d= domain. If that flag is absent, the domain of the signing identity MUST be the same as, or a subdomain of, the d= domain.

Corrected Text:

...for example, a key record for the domain example.com can be used to verify messages where the AUID (i= tag of the signature) is sub.example.com, or even sub1.sub2.example.com. In order to limit the capability of such keys when that isn't intended, the s flag MAY be set in the t= tag of the key record, to constrain the validity of the domain of the AUID 🌈. If the referenced key record contains the s flag as part of the t= tag, the domain of the AUID (i= flag) MUST be the same as that of the SDID (d=) domain. If this flag is absent, the domain of the AUID MUST be the same as, or a subdomain of, the SDID.


12. RFC 4871, Section 3.9, Relationship between SDID and AUID ✨

Original Text:

(None. New section. Additional text.)

Corrected Text:

DKIM's primary task is to communicate from the Signer to a recipient-side Identity Assessor a single Signing Domain Identifier (SDID) that refers to a responsible identity πŸ‘‘. DKIM MAY optionally provide a single responsible Agent or User Identifier (AUID).

So DKIM's mandatory output to a receive-side Identity Assessor is a single domain name. Inside its use as DKIM output, the name only has basic domain name semantics. Any possible owner-specific semantics are outside the scope of DKIM πŸŽ€. That means that, as a DKIM identifier, an Identity Assessor can't assume any additional semantics.

A receive-side DKIM verifier MUST communicate the Signing Domain Identifier (d=) to a consuming Identity Assessor module, and MAY communicate the Agent or User Identifier (i=) if it's present.

If a receiver tries to intuit any structured semantics for either identifier, that's a heuristic function outside the scope of DKIM's specification and semantics 🧠. So it gets handed off to a higher-level service, like a delivery handling filter that pulls in a variety of inputs and does heuristic analysis on them.

INFORMATIVE DISCUSSION: This document does not require the value of the SDID or AUID to match the identifier in any other message header field. That's an assessor policy issue instead. The point of that kind of linkage would be to authenticate the value in that other header field, which is the basis for applying a trust assessment based on the identifier value. Trust is a broad and complex topic, and trust mechanisms are subject to highly creative attacks 😭. The real-world efficacy of any but the most basic bindings between the SDID or AUID and other identities isn't well established, and neither is its vulnerability to subversion by an attacker. Hence, reliance on the use of such bindings should be strictly limited. In particular, it's not at all clear to what extent a typical end-user recipient can rely on any assurances that might be made by successful use of the SDID or AUID.


13. RFC 4871, Section 6.3, Interpret Results/Apply Local Policy ✨

Original Text:

It's beyond the scope of this specification to describe what actions a verifier system should take πŸ™ˆ. But an authenticated email gives a receiving system an opportunity that unauthenticated email doesn't. Specifically, an authenticated email creates a predictable identifier that other decisions can reliably be managed by, such as trust and reputation. On the flip side, unauthenticated email lacks a reliable identifier that can be used to assign trust and reputation.

Corrected Text:

It's beyond the scope of this specification to describe what actions an Identity Assessor can take πŸ’…. But mail carrying a validated SDID gives an Identity Assessor an opportunity that unauthenticated email doesn't. Specifically, an authenticated email creates a predictable identifier that other decisions can reliably be managed by, such as trust and reputation.

14. RFC 4871, Section 6.3, Interpret Results/Apply Local Policy ✨

Original Text: πŸ•°οΈ

Okay so the old version said that once the signature is verified, that info MUST get passed up to higher-level systems (like explicit allow/whitelists and reputation systems) and/or to the end user. And if the message was signed on behalf of any address other than the one in the From: header field, the mail system SHOULD take pains to make sure the actual signing identity is clear to the reader. πŸ€”

Corrected Text: πŸ’–

Here's the glow-up! πŸ¦‹ Once the signature is verified, that info MUST get conveyed to the Identity Assessor (think an explicit allow/whitelist and reputation system) and/or to the end user. Then, if the SDID is not the same as the address in the From: header field, the mail system SHOULD take pains to make sure the actual SDID is clear to the reader. Sooo the big change is that the vague "signing identity" becomes the specific SDID, and the receiving systems get a proper name, the Identity Assessor, instead of just "higher-level systems." Iconic. πŸ‘‘βœ¨


15. RFC 4871, Appendix D, MUA Considerations πŸ“¬

Original Text: πŸ“œ

The tendency was for the MUA to highlight the address tied to this signing identity somehow, so the user could see the address the mail came from. πŸ™ˆ

Corrected Text: πŸŽ€

Now the MUA tends to highlight the SDID instead, so the user can see the identity that's claiming responsibility for the message. πŸ’… Same vibe, but now it's the SDID doing the talking, which is way more accurate. 🧚


16. Security Considerations πŸ”

This Update clarifies the core details of DKIM's payload, so it affects interoperability, semantic characterization, and the expectations for the identifiers that ride along with a DKIM signature. 🫢 Getting these details crystal clear is likely to limit misinterpretation of DKIM's semantics.

🚨 DKIM is fundamentally a security protocol, so tightening up these definitions should improve its security characteristics. Please take this seriously, bestie. Misreading who is actually signing a message is exactly how people get fooled, so clarity here is a real security win. πŸ’€πŸ”₯

17. Normative References πŸ“š

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3490]  Faltstrom, P., Hoffman, P., and A. Costello,
           "Internationalizing Domain Names in Applications (IDNA)",
           RFC 3490, March 2003.

[RFC4871]  Allman, E., Callas, J., Delany, M., Libbey, M., Fenton,
           J., and M. Thomas, "DomainKeys Identified Mail (DKIM)
           Signatures", RFC 4871, May 2007.

Appendix A. ABNF Fragments 🧩

This appendix is the full set of corrected ABNF fragments from this document. Here's the whole legal stuff too, so nobody can say we didn't include it. πŸ™ƒ

Copyright (c) 2009 IETF Trust and the persons identified as authors
of the code.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

- Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the
  distribution.

- Neither the name of Internet Society, IETF or IETF Trust, nor the
  names of specific contributors, may be used to endorse or promote
  products derived from this software without specific prior written
  permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This version of this MIB module is part of RFC 5672; see the RFC
itself for full legal notices.

And here are the fragments themselves, bestie. πŸ’œ

           sig-d-tag   = %x64 [FWS] "=" [FWS] domain-name
          domain-name = sub-domain 1*("." sub-domain)
                        ; from RFC 5321 Domain,
                          but excluding address-literal

           sig-i-tag =  %x69 [FWS] "=" [FWS]
                       [ Local-part ] "@" domain-name

Appendix B. Acknowledgements 🌸

This document was first put together by an ad hoc design team: Jon Callas, D. Crocker, J. D. Falk, Michael Hammer, Tony Hansen, Murray Kucherawy, John Levine, Jeff Macdonald, Ellen Siegel, and Wietse Venema. 🫢 The final version came out of some seriously vigorous discussion in the IETF DKIM working group. Honestly, the group chat must have been unhinged. 😭✨


Author's Address πŸ’Œ

D. Crocker (editor)
Brandenburg InternetWorking

Phone: +1.408.246.8253
EMail: dcrocker@bbiw.net

That's the whole RFC, bestie! πŸŒˆπŸŽ‰ πŸ¦‹

πŸ“¦ where this page comes from