<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-jones-dkim-key-wrapper-00" submissionType="IETF" category="exp" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" consensus="true">

<front>
<title abbrev="dkimkeywrapper">DKIM Key Wrapper Format</title><seriesInfo value="draft-jones-dkim-key-wrapper-00" stream="IETF" status="experimental" name="Internet-Draft"></seriesInfo>
<author initials="S." surname="Jones, Ed." fullname="Steven M Jones"><organization>DMARC.org</organization><address><postal><street></street>
</postal><email>smj@dmarc.org</email>
</address></author><author initials="N." surname="Selenu" fullname="Nicola Selenu"><organization>ActiveCampaign</organization><address><postal><street></street>
</postal></address></author><date/>
<area>Internet</area>
<workgroup></workgroup>
<keyword>DKIM</keyword>
<keyword>public key</keyword>
<keyword>provisioning</keyword>

<abstract>
<t>This experimental RFC seeks to document a DKIM key interchange
format intended to avoid provisioning errors where different parties
are generating keys and publishing DNS records for a given domain.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>DomainKeys Internet Mail (DKIM) requires that an email sending domain
publish DKIM public keys in the Domain Name System (DNS) with very
specific formatting.  But when DKIM keys are published in the DNS with
incorrect formatting, all signature validation will fail and the
entire deployment may be abandoned.</t>
<t>A common reason for this failure mode is that an Email Service
Provider (ESP) or other party will generate the DKIM keys for the
domain owner, who may not be familiar with DNS management. They then may
have to determine how to enter the key data into a user interface
provided by a web hosting company. Often they will include formatting
characters that should be omitted, or include metadata like the TTL in
the payload or RDATA.</t>
<t>This Independent Submission proposes a wrapper format for DKIM
key information. This format provides a simple block of printable
ASCII text, which is much more easily shared without being
inadvertently corrupted. And because the format is well-documented, a
DNS operator can easily extract the key material and provision the
necessary records.</t>

<section anchor="goals"><name>Goals</name>
<t>The goal of this submission is to solicit partners for a
proof-of-concept implementation using this format, to complete testing
by mid-2023 at the latest. Experience in the field will show whether
this concept warrants further development.</t>
</section>

<section anchor="document-conventions"><name>Document Conventions</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,
&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this
document are to be interpreted as described in <xref target="RFC2119"></xref>.  As each
of these terms was intentionally and carefully chosen to improve
interoperability, each use of these terms is to be treated as a
conformance requirement.</t>
</section>
</section>

<section anchor="terminology-and-definitions"><name>Terminology and Definitions</name>
<t>Because this proposal discusses the handling of DKIM key material, the
terminology will be as close to <xref target="RFC6376"></xref> as possible. However as
some aspects of this proposal may concern actors not fully identified
in previous documents, some new elements may be identified.</t>

<section anchor="roles"><name>Roles</name>
<t>There are so many different &quot;real world&quot; scenarios where different
parties are responsible for different functions, that it is easy to
cause ambiguity by using common terms. This document will try to use
the following role definitions when describing actions.</t>

<section anchor="domain-owner"><name>Domain Owner</name>
<t>The Domain Owner is the party who controls or owns a given domain, and
presumably is seeking to benefit from deploying DKIM.</t>
</section>

<section anchor="key-generator"><name>Key Generator</name>
<t>This is the party that has generated the public keypair that will be
used for DKIM signing messages. In all likelihood they will also
fulfill one of the other roles, like the DNS Operator or an Email
Service Provider (ESP).</t>
</section>

<section anchor="dns-operator"><name>DNS Operator</name>
<t>A DNS Operator in this context is the party operating nameservers that
are authoritative for the domain where DKIM is being deployed. The DNS
Operator may be a website hosting company, or a MailBox Provider
(MBP), for example.</t>
</section>

<section anchor="email-sender"><name>Email Sender</name>
<t>The Email Sender in this context is a third party sending email on
behalf of the Domain Owner. This could be an Email Service Provider,
whose primary service is to send email messages; or a vendor primarily
providing some other service who happens to also send email.</t>
</section>
</section>
</section>

<section anchor="wrapper-format"><name>Wrapper Format</name>
<t>The information inside the wrapper is a series of key/value pairs
using the JavaScript Object Notation (JSON) format, as described in
<xref target="RFC8259"></xref>. The set of fields used depends on whether a public or
private key is being represented.</t>
<t>This data is then encoded as described below.</t>

<section anchor="encoding"><name>Encoding</name>
<t>A Key Wrapper consists of Base64 encoded text as described in
<xref target="RFC4648"></xref>, and SHOULD have no more than 65 characters per line,
appearing between delimiters that identify it as wrapped DKIM key
material. The result is very similar in appearance to the PEM format
used by OpenSSL and similar software.</t>
<t>An encoded key wrapper might look like the following example:</t>

<artwork>-----BEGIN WRAPPED PUBLIC DKIM KEY-----
eyJ0eXBlIjoiREtJTS1QVUItS0VZIiwibmFtZSI6ImtleTIwMjIwNTE1IiwidiI6Ik
RLSU0xIiwicCI6Ik1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdR
RGVKRE5hYzZnRlR3akx6eWxERWd3dk9sYk5TREcwN3FZR1h5K3hTY3F5aC9jZWIzek
R0eHZUZGpTbmFkU09adjJtWFRqZGI3N2U1eWlJaWZLbVJBZ2ZhaHF6c0dKUXEyUmRv
c2NZNkdYMThMWmxjNnNYSGJwREU0QzNaTFJoRlFHQzF0T29xU0Z5aEZya0VBeFltV2
Q2cElNajVnNWd2V3lJUm40U3p6Z3hzd0lEQVFBQiIsImsiOiJyc2EifQo=
-----END WRAPPED PUBLIC DKIM KEY-----
</artwork>

<section anchor="public-versus-private-keys"><name>Public versus Private Keys</name>
<t>In order to help users avoid inadvertant disclosure of private keys,
the tags surrounding encoded keys should indicate which type of key it
contains.</t>
<t>Public keys should use the string &quot;WRAPPED PUBLIC DKIM KEY&quot;, preceded
by the strings &quot;BEGIN&quot; or &quot;END&quot; depending on their position relative
to the encoded data.</t>
<t>Private keys should use the string &quot;WRAPPED PRIVATE DKIM KEY&quot;,
preceded by the strings &quot;BEGIN&quot; or &quot;END&quot; depending on their position
relative to the encoded data.</t>
</section>
</section>

<section anchor="data-fields"><name>Data Fields</name>
<t>The JSON formatted data consists of key/value pairs. Which keys appear
in a given wrapper will depend on what type of key material is being
represented.</t>
<t>This following sections document the names of the fields that appear
in the JSON formatted data. Some fields correspond to the &quot;tags&quot;
defined for the DNS TXT RR binding in <xref target="RFC6376"></xref> Section 3.6.</t>

<section anchor="contact"><name>contact</name>
<t>This field may include contact information for the Key Generator or
the Domain Owner. It is intended to be brief, and might typically
include an organization name, email address, telephone number, or URI.</t>
<t>Example:</t>

<artwork>&quot;contact&quot;: &quot;Hosting Company Key Services, keys@example.com, +1-123-555-1212&quot;
</artwork>
</section>

<section anchor="domain"><name>domain</name>
<t>This is the Internet domain or sub-domain that the key was generated for.</t>
<t>Example:</t>

<artwork>&quot;domain&quot;: &quot;example.com&quot;
</artwork>
</section>

<section anchor="k"><name>k</name>
<t>The key type. Historically this has almost always been &quot;rsa&quot;, but new
key types are being used more often on the Internet.</t>
<t>Example:</t>

<artwork>&quot;k&quot;: &quot;edd25519&quot;
</artwork>
</section>

<section anchor="name"><name>name</name>
<t>The common name of the key. For a DKIM public key where the full DNS
label is &quot;selector._domainkey.example.com&quot;, the value of the name field
would be &quot;selector&quot;.</t>
<t>Example:</t>

<artwork>&quot;name&quot;: &quot;selector&quot;
</artwork>
</section>

<section anchor="p"><name>p</name>
<t>The <strong>p</strong>ublic key data, the actual key material. This is formatted as
described in <tt>[@RFC6376, see section 3.6.1]</tt>.</t>
<t>Example:</t>

<artwork>&quot;p&quot;: &quot;MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeJDNac6gFTwjLzylDEgwvOlbNSDG07qYGXy+xScqyh/ceb3zDtxvTdjSnadSOZv2mXTjdb77e5yiIifKmRAgfahqzsGJQq2RdoscY6GX18LZlc6sXHbpDE4C3ZLRhFQGC1tOoqSFyhFrkEAxYmWd6pIMj5g5gvWyIRn4SzzgxswIDAQAB&quot;
</artwork>
</section>

<section anchor="r"><name>r</name>
<t>The p<strong>r</strong>ivate key data. This is formatted in the manner for public key data (&quot;p=&quot; tag) described in <tt>[@RFC6376, see section 3.6.1]</tt>.</t>
<t>Example:</t>

<artwork>&quot;r&quot;: &quot;MIIBOwIBAAJBAODmxiUEZdxP34cYT1g2p7NvZkOKwdkOcjQljOFikQgZXSAwTWdgnsedt1V7V37Bc9iO3cUQSESKRGZCCz1CbD0CAwEAAQJBAKZe8Vt26mdVCvVkLWYDYIGjuhHi9s28Gw2qbZJZmRJUVgSG7mJItIN7FMTdjBRU9GoYgbtdnyE36nOiRZUlzEECIQDxoVuwBvwo8xIMBuLdhFrBHjPBBzY+M9y6mgiyi54ksQIhAO5Gu0utP5qg5mKs1WWfbLVnpNKS0djF9a+2ql9ojFNNAiEApOMJoFuD46XLoO1qDuPs0m/7vTNgrp3ReHz4hm6EImECIFucLDSLVpHv3MQBaUZaBiS0xYUEV9P9QFmfZF+sRY9dAiBIdJ7uoXHG8l3zaFX1v0qxUI9KTRB92mDK6nxG+OPzGQ==&quot;
</artwork>
</section>

<section anchor="size"><name>size</name>
<t>This field reflects the size of the key in bits, and is intended for
informational purposes. It is much easier to glance at this field,
than extract the key material and determine the key size
programmatically.</t>
<t>Example:</t>

<artwork>&quot;size&quot;: &quot;1024&quot;
</artwork>
</section>

<section anchor="type"><name>type</name>
<t>This field indicates the type of key material encoded in this
file. Examples are &quot;DKIM-PUB-KEY&quot; and &quot;DKIM-PRIV-KEY&quot;. The value of
this field determines what other fields must be present.</t>
<t>Valid values are currently &quot;DKIM-PUB-KEY&quot; and &quot;DKIM-PRIV-KEY&quot;. The use
of any other value means that the entire record MUST be ignored.</t>
<t>Example:</t>

<artwork>&quot;type&quot;: &quot;DKIM-PUB-KEY&quot;
</artwork>
</section>

<section anchor="v"><name>v</name>
<t>The version of the DKIM key. This is the same value as specified for
the &quot;v=&quot; tag in <tt>[@RFC6376, see section 3.6.1]</tt>, with all the
corresponding normative constraints.</t>
<t>Example:</t>

<artwork>&quot;v&quot;: &quot;DKIM1&quot;
</artwork>
</section>
</section>

<section anchor="record-types"><name>Record Types</name>
<t>There are two record types defined, which correspond to public and
private keys. Each type requires a specific set of data fields. Any
fields not included for a given record type below MUST be ignored.</t>

<section anchor="dkim-pub-key"><name>DKIM-PUB-KEY</name>
<t>This record type presents DKIM public key data. It is the type of
record that would be given to a DNS Operator for publication as a DNS
TXT RR.</t>
<t>Required fields:</t>

<ul spacing="compact">
<li>k</li>
<li>name</li>
<li>p</li>
<li>type</li>
<li>v</li>
</ul>
<t>Optional fields:</t>

<ul spacing="compact">
<li>contact</li>
<li>domain</li>
<li>size</li>
</ul>
<t>Example:</t>

<artwork>{
  &quot;contact&quot;: &quot;Hosting Company Key Services, keys@example.com, +1-123-555-1212&quot;,
  &quot;domain&quot;: &quot;example.com&quot;,
  &quot;k&quot;: &quot;rsa&quot;,
  &quot;name&quot;: &quot;selector&quot;,
  &quot;p&quot;: &quot;MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeJDNac6gFTwjLzylDEgwvOlbNSDG07qYGXy+xScqyh/ceb3zDtxvTdjSnadSOZv2mXTjdb77e5yiIifKmRAgfahqzsGJQq2RdoscY6GX18LZlc6sXHbpDE4C3ZLRhFQGC1tOoqSFyhFrkEAxYmWd6pIMj5g5gvWyIRn4SzzgxswIDAQAB&quot;,
  &quot;size&quot;: &quot;2048&quot;,
  &quot;type&quot;: &quot;DKIM-PUB-KEY&quot;,
  &quot;v&quot;: &quot;DKIM1&quot;
}
</artwork>
</section>

<section anchor="dkim-priv-key"><name>DKIM-PRIV-KEY</name>
<t>This record type presents the DKIM private key data. It is the type of
record that would be given to an Email Sender, who needs the private
key to produce DKIM signatures for email messages being sent.</t>
<t>Required fields:</t>

<ul spacing="compact">
<li>k</li>
<li>name</li>
<li>r</li>
<li>type</li>
<li>v</li>
</ul>
<t>Optional fields:</t>

<ul spacing="compact">
<li>contact</li>
<li>domain</li>
<li>size</li>
</ul>
<t>Example:</t>

<artwork>{
  &quot;contact&quot;: &quot;Hosting Company Key Services, keys@example.com, +1-123-555-1212&quot;,
  &quot;domain&quot;: &quot;example.com&quot;,
  &quot;k&quot;: &quot;rsa&quot;,
  &quot;name&quot;: &quot;selector&quot;,
  &quot;r&quot;: &quot;MIIBOwIBAAJBAODmxiUEZdxP34cYT1g2p7NvZkOKwdkOcjQljOFikQgZXSAwTWdgnsedt1V7V37Bc9iO3cUQSESKRGZCCz1CbD0CAwEAAQJBAKZe8Vt26mdVCvVkLWYDYIGjuhHi9s28Gw2qbZJZmRJUVgSG7mJItIN7FMTdjBRU9GoYgbtdnyE36nOiRZUlzEECIQDxoVuwBvwo8xIMBuLdhFrBHjPBBzY+M9y6mgiyi54ksQIhAO5Gu0utP5qg5mKs1WWfbLVnpNKS0djF9a+2ql9ojFNNAiEApOMJoFuD46XLoO1qDuPs0m/7vTNgrp3ReHz4hm6EImECIFucLDSLVpHv3MQBaUZaBiS0xYUEV9P9QFmfZF+sRY9dAiBIdJ7uoXHG8l3zaFX1v0qxUI9KTRB92mDK6nxG+OPzGQ==&quot;
  &quot;size&quot;: &quot;2048&quot;,
  &quot;type&quot;: &quot;DKIM-PRIV-KEY&quot;,
  &quot;v&quot;: &quot;DKIM1&quot;
}
</artwork>
</section>
</section>

<section anchor="filenames"><name>Filenames</name>
<t>This proposal does not attempt to mandate a specific file naming
convention. Filenames SHOULD use a standard filename extension,
described below. The main file name may be whatever is sensible to the
party creating or using the file.</t>
<t>Example:</t>

<ul spacing="compact">
<li>example.com-public-20220921.wdkim</li>
<li>EnterpriseName-keyname.wdkim</li>
<li>pubkey-example.net-20220831.wdkim</li>
</ul>

<section anchor="filename-extensions"><name>Filename Extensions</name>
<t>There is a well-established practice of using so-called filename
extensions to indicate what the contents of a file are. For example,
&quot;.txt&quot; indicating a file containing some kind of text, or &quot;.pem&quot;
indicating that a file contains PEM encoded certificate data.</t>
<t>Users of this proposal SHOULD use the filename extension &quot;.wdkim&quot; to
indicate the contents are a wrapped DKIM key.</t>
</section>
</section>

<section anchor="file-contents"><name>File Contents</name>
<t>Each file SHOULD contain a single wrapped DKIM key block.</t>

<section anchor="combined-files"><name>Combined Files</name>
<t>Users that wish to store more than one wrapped key per file are
strongly urged to only combine the public and private key of the same
keypair in a single file.</t>
<t>Combined files that contain private keys pose a significant risk if
they are disclosed unintentionally. Users are advised to treat any
combined files containing private keys as they would treat the private
key alone.</t>
</section>
</section>
</section>

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

<section anchor="security-considerations"><name>Security Considerations</name>

<section anchor="why-support-private-keys"><name>Why Support Private Keys?</name>
<t>How sensitive information is handled is not dictated by a file
format.</t>
<t>DKIM uses keypairs, with both a public and private key. Any
standardized representation of one can very easily support the
other. From the perspective of a standard that represents DKIM keys,
why wouldn't it make sense to represent private keys?</t>
<t>Parties handling large numbers of DKIM keys may benefit from using a
standardized format. Indeed, they may have a need to archive the
public and private keys for a given client or instance together.</t>
</section>

<section anchor="private-key-disclosure"><name>Private Key Disclosure</name>
<t>Possession of private DKIM keys allows an actor to send email posing
as the associated domain that successfully passes DKIM checks. As a
result they need to be treated as very sensitive credentials, and
protected accordingly.</t>
<t>While combined files containing both the public and private DKIM keys
may be attractive from, for example, an archival perspective, there is
always a risk that a party intending to share only the public key will
send the combined file. Users are again strongly encouraged to keep
private keys separate.</t>
</section>
</section>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.4648.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6376.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
</references>

<section anchor="examples"><name>Examples</name>

<section anchor="an-rsa-key"><name>An RSA Key</name>
<t>TODO rsa key</t>
</section>

<section anchor="an-elliptic-curve-key"><name>An Elliptic Curve Key</name>
<t>TODO ec key</t>
</section>

<section anchor="manually-decoding-a-wrapped-key"><name>Manually Decoding A Wrapped Key</name>
<t>The following sequence shows a user on a UNIX-like system manually
decoding a Wrapped DKIM Key using common command-line tools.</t>

<artwork>212 host$ cat sample-public-key.wdkim
-----BEGIN WRAPPED PUBLIC DKIM KEY-----
eyJ0eXBlIjoiREtJTS1QVUItS0VZIiwibmFtZSI6ImtleTIwMjIwNTE1IiwidiI6Ik
RLSU0xIiwicCI6Ik1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdR
RGVKRE5hYzZnRlR3akx6eWxERWd3dk9sYk5TREcwN3FZR1h5K3hTY3F5aC9jZWIzek
R0eHZUZGpTbmFkU09adjJtWFRqZGI3N2U1eWlJaWZLbVJBZ2ZhaHF6c0dKUXEyUmRv
c2NZNkdYMThMWmxjNnNYSGJwREU0QzNaTFJoRlFHQzF0T29xU0Z5aEZya0VBeFltV2
Q2cElNajVnNWd2V3lJUm40U3p6Z3hzd0lEQVFBQiIsImsiOiJyc2EifQo=
-----END WRAPPED PUBLIC DKIM KEY-----
213 host%
</artwork>
<t>In the following example, &quot;base64&quot; is a command line utility that
performs base64 encoding and decoding. &quot;awk&quot; is a common text
processing utility, used here to extract the delimiter lines. &quot;jq&quot; is
a common command line JSON processor.</t>

<artwork>TODO: Which decoding example?
$ egrep -v '^-----' sample-public-key.wdkim | base64 -d - | jq .
{
  &quot;contact&quot;: &quot;Hosting Company Key Services, keys@example.com, +1-123-555-1212&quot;,
  &quot;domain&quot;: &quot;example.com&quot;,
  &quot;k&quot;: &quot;rsa&quot;,
  &quot;name&quot;: &quot;selector&quot;,
  &quot;p&quot;: &quot;MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeJDNac6gFTwjLzylDEgwvOlbNSDG07qYGXy+xScqyh/ceb3zDtxvTdjSnadSOZv2mXTjdb77e5yiIifKmRAgfahqzsGJQq2RdoscY6GX18LZlc6sXHbpDE4C3ZLRhFQGC1tOoqSFyhFrkEAxYmWd6pIMj5g5gvWyIRn4SzzgxswIDAQAB&quot;,
  &quot;size&quot;: &quot;2048&quot;,
  &quot;type&quot;: &quot;DKIM-PUB-KEY&quot;,
  &quot;v&quot;: &quot;DKIM1&quot;
}
214 host$ 
</artwork>
</section>
</section>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>M3AAWG (www.m3aawg.org) supports a DKIM Enablement initiative, and
on-going discussion by participants around DKIM provisioning. The
authors are grateful for the support of this organization.</t>
<t><contact initials="T." surname="Herr" fullname="Todd Herr"><organization>ValiMail</organization><address><postal><street></street>
</postal></address></contact></t>
<t>Todd Herr solicited interested parties to shepherd the DKIM Enablement
topic at the M3AAWG meeting in February 2022, and the authors put
their names forward. This proposal came out of a suggestion made in a
M3AAWG Slack channel, and subsequent discussions between these
gentlemen.</t>
</section>

<section anchor="change-log"><name>Change Log</name>
<t>[RFC Editor: Please remove this section prior to publicaion.]</t>
<t>TODO Change Log</t>
</section>

</back>

</rfc>
