<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.23 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-darling-key-directory-over-http-00" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.26.0 -->
  <front>
    <title abbrev="Key Directory over HTTP">Recommendations for Key Directories over HTTP</title>
    <seriesInfo name="Internet-Draft" value="draft-darling-key-directory-over-http-00"/>
    <author fullname="Fisher Darling">
      <organization>Cloudflare Inc.</organization>
      <address>
        <email>fisher@darling.dev</email>
      </address>
    </author>
    <author fullname="Thibault Meunier">
      <organization>Cloudflare Inc.</organization>
      <address>
        <email>ot-ietf@thibault.uk</email>
      </address>
    </author>
    <author fullname="Simon Newton">
      <organization>Cloudflare Inc.</organization>
      <address>
        <email>rfc@simonnewton.com</email>
      </address>
    </author>
    <date year="2025" month="February" day="13"/>
    <area/>
    <workgroup>???</workgroup>
    <keyword>Internet Draft</keyword>
    <keyword>Publickey</keyword>
    <keyword>Key directory</keyword>
    <keyword>Key rotation</keyword>
    <keyword>Key cache</keyword>
    <keyword>Key ID</keyword>
    <abstract>
      <?line 58?>

<t>This document defines recommendations for protocols that expose public keys over
HTTP.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://thibmeu.github.io/draft-darling-key-directory-over-http/draft-darling-key-directory-over-http.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-darling-key-directory-over-http/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        ???  mailing list (<eref target="mailto:httpapi@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/httpapi/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/httpapi/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/thibmeu/draft-darling-key-directory-over-http"/>.</t>
    </note>
  </front>
  <middle>
    <?line 64?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Multiple Internet protocols rely on public key cryptography. They require keys
to be distributed by Origins to Clients. This can be done via certificates,
software releases, or HTTP. This document focuses on this last mechanism. It
aims to set recommendations on how to design a key directory that is served
over HTTP.</t>
      <t>Distribution via HTTP allows for a more dynamic use of public keys, for
rotation, or caching on intermediate mirrors or clients.
This document specifies which cache directives origin should set, how clients
and mirrors should consume cache directive set by origins, how origins should
expose their key directory, and rotate them. This complements reccomendations
provided by <xref target="HTTP-BEST-PRACTICES"/>, narrowing them for key directories
protocols.</t>
      <t>The document does not cover a specific directory format, as these needs vary
from one protocol to the next.</t>
    </section>
    <section anchor="motivation">
      <name>Motivation</name>
      <t><xref section="5" sectionFormat="of" target="JOSE"/> and
<xref section="7" sectionFormat="of" target="COSE"/> both define ways to structure key sets, but no way to serve them.
This creates issues when serving these keys over HTTP because caching is not
taken into account, and there is no standard way to derive an ID from a key.
<xref section="4" sectionFormat="of" target="PRIVACYPASS"/>, <xref section="3" sectionFormat="of" target="OHTTP"/>, and
<xref section="4.7.1" sectionFormat="of" target="DAP"/> are also defining their own public key
directory, and are faced with similar issues. While Privacy Pass seems to have
been the most thorough, even considering <xref target="CONSISTENCY"/> for instance, these seem to
be duplicated efforts that would benefit from being consolidated into one
specification.</t>
    </section>
    <section anchor="presentation-language">
      <name>Presentation Language</name>
      <t>This document uses the TLS presentation language <xref target="RFC8446"/> to describe the
structure of protocol messages.  In addition to the base syntax, it uses two
additional features: the ability for fields to be optional and the ability for
vectors to have variable-size length headers.</t>
      <section anchor="variable-size-vector-length-headers">
        <name>Variable-Size Vector Length Headers</name>
        <t>In the TLS presentation language, vectors are encoded as a sequence of encoded
elements prefixed with a length.  The length field has a fixed size set by
specifying the minimum and maximum lengths of the encoded sequence of elements.</t>
        <t>In this document, there are several vectors whose sizes vary over significant
ranges.  So instead of using a fixed-size length field, it uses a variable-size
length using a variable-length integer encoding based on the one described in
<xref section="16" sectionFormat="of" target="RFC9000"/>. They differ only in that the one here requires a
minimum-size encoding. Instead of presenting min and max values, the vector
description simply includes a <tt>V</tt>. For example:</t>
        <sourcecode type="tls-presentation"><![CDATA[
struct {
    uint32 fixed<0..255>;
    opaque variable<V>;
} StructWithVectors;
]]></sourcecode>
      </section>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

<t>The following terms are used throughout this document:</t>
      <dl>
        <dt><strong>Client:</strong></dt>
        <dd>
          <t>An entity using public key material.</t>
        </dd>
        <dt><strong>Origin:</strong></dt>
        <dd>
          <t>An entity exposing public key material via HTTP.</t>
        </dd>
        <dt><strong>Mirror:</strong></dt>
        <dd>
          <t>An intermediary entity between client and origin. May cache data, and act as a
privacy proxy.</t>
        </dd>
        <dt><strong>Key metadata:</strong></dt>
        <dd>
          <t>Public data associated to a public key.</t>
        </dd>
        <dt><strong>Key Directory:</strong></dt>
        <dd>
          <t>Set of public keys.</t>
        </dd>
        <dt><strong>Directory Metadata:</strong></dt>
        <dd>
          <t>Public data associated to a key directory. This is protocol specific.</t>
        </dd>
      </dl>
    </section>
    <section anchor="architecture">
      <name>Architecture</name>
      <t>An Origin is exposing a key directory for Clients to fetch. Clients may fetch the
directory from a Mirror, either to protect its privacy, or because the Origin
wants to leverage a content delivery network. The endpoint and request pattern
should be the same as if the fetch was to an Origin.</t>
      <t>This document focuses on the below interaction, which is triggered when the
Client does not have valid key for the Origin. This can be because the Client is
new, its cache is expired, or the Origin refuses requests with the current key set.</t>
      <artset>
        <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="288" width="560" viewBox="0 0 560 288" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
            <path d="M 8,32 L 8,64" fill="none" stroke="black"/>
            <path d="M 40,64 L 40,272" fill="none" stroke="black"/>
            <path d="M 80,32 L 80,64" fill="none" stroke="black"/>
            <path d="M 216,32 L 216,64" fill="none" stroke="black"/>
            <path d="M 248,64 L 248,272" fill="none" stroke="black"/>
            <path d="M 288,32 L 288,64" fill="none" stroke="black"/>
            <path d="M 416,32 L 416,64" fill="none" stroke="black"/>
            <path d="M 456,64 L 456,272" fill="none" stroke="black"/>
            <path d="M 488,32 L 488,64" fill="none" stroke="black"/>
            <path d="M 8,32 L 80,32" fill="none" stroke="black"/>
            <path d="M 216,32 L 288,32" fill="none" stroke="black"/>
            <path d="M 416,32 L 488,32" fill="none" stroke="black"/>
            <path d="M 8,64 L 80,64" fill="none" stroke="black"/>
            <path d="M 216,64 L 288,64" fill="none" stroke="black"/>
            <path d="M 416,64 L 488,64" fill="none" stroke="black"/>
            <path d="M 40,96 L 64,96" fill="none" stroke="black"/>
            <path d="M 224,96 L 240,96" fill="none" stroke="black"/>
            <path d="M 248,112 L 272,112" fill="none" stroke="black"/>
            <path d="M 432,112 L 448,112" fill="none" stroke="black"/>
            <path d="M 256,128 L 288,128" fill="none" stroke="black"/>
            <path d="M 416,128 L 456,128" fill="none" stroke="black"/>
            <path d="M 248,144 L 272,144" fill="none" stroke="black"/>
            <path d="M 256,176 L 272,176" fill="none" stroke="black"/>
            <path d="M 48,192 L 80,192" fill="none" stroke="black"/>
            <path d="M 208,192 L 248,192" fill="none" stroke="black"/>
            <path d="M 40,208 L 64,208" fill="none" stroke="black"/>
            <path d="M 456,224 L 480,224" fill="none" stroke="black"/>
            <path d="M 48,240 L 64,240" fill="none" stroke="black"/>
            <path d="M 464,256 L 480,256" fill="none" stroke="black"/>
            <path d="M 272,144 C 280.83064,144 288,151.16936 288,160" fill="none" stroke="black"/>
            <path d="M 272,176 C 280.83064,176 288,168.83064 288,160" fill="none" stroke="black"/>
            <path d="M 64,208 C 72.83064,208 80,215.16936 80,224" fill="none" stroke="black"/>
            <path d="M 480,224 C 488.83064,224 496,231.16936 496,240" fill="none" stroke="black"/>
            <path d="M 64,240 C 72.83064,240 80,232.83064 80,224" fill="none" stroke="black"/>
            <path d="M 480,256 C 488.83064,256 496,248.83064 496,240" fill="none" stroke="black"/>
            <polygon class="arrowhead" points="472,256 460,250.4 460,261.6" fill="black" transform="rotate(180,464,256)"/>
            <polygon class="arrowhead" points="456,112 444,106.4 444,117.6" fill="black" transform="rotate(0,448,112)"/>
            <polygon class="arrowhead" points="264,176 252,170.4 252,181.6" fill="black" transform="rotate(180,256,176)"/>
            <polygon class="arrowhead" points="264,128 252,122.4 252,133.6" fill="black" transform="rotate(180,256,128)"/>
            <polygon class="arrowhead" points="248,96 236,90.4 236,101.6" fill="black" transform="rotate(0,240,96)"/>
            <polygon class="arrowhead" points="56,240 44,234.4 44,245.6" fill="black" transform="rotate(180,48,240)"/>
            <polygon class="arrowhead" points="56,192 44,186.4 44,197.6" fill="black" transform="rotate(180,48,192)"/>
            <g class="text">
              <text x="44" y="52">Client</text>
              <text x="252" y="52">Mirror</text>
              <text x="452" y="52">Origin</text>
              <text x="88" y="100">GET</text>
              <text x="120" y="100">Key</text>
              <text x="176" y="100">Directory</text>
              <text x="296" y="116">GET</text>
              <text x="328" y="116">Key</text>
              <text x="384" y="116">Directory</text>
              <text x="312" y="132">Key</text>
              <text x="368" y="132">Directory</text>
              <text x="320" y="164">cache</text>
              <text x="104" y="196">Key</text>
              <text x="160" y="196">Directory</text>
              <text x="112" y="228">cache</text>
              <text x="532" y="244">rotate</text>
            </g>
          </svg>
        </artwork>
        <artwork type="ascii-art"><![CDATA[
+--------+                +--------+               +--------+
| Client |                | Mirror |               | Origin |
+---+----+                +---+----+               +----+---+
    |                         |                         |
    +--- GET Key Directory -->|                         |
    |                         +--- GET Key Directory -->|
    |                         |<---- Key Directory -----+
    |                         +---.                     |
    |                         |    | cache              |
    |                         |<--'                     |
    |<---- Key Directory -----+                         |
    +---.                     |                         |
    |    | cache              |                         +---.
    |<--'                     |                         |    | rotate
    |                         |                         |<--'
    |                         |                         |
]]></artwork>
      </artset>
      <section anchor="key-id">
        <name>Key ID</name>
        <t>Each key in the directory is associated with a unique Key ID.</t>
        <t>Key ID has to be derived from key material that is shared publicly.
Protocols <bcp14>SHOULD</bcp14> provide the following blob of data:</t>
        <sourcecode type="tls"><![CDATA[
struct {
  opaque ProtocolBlob<V>;
} PublicKeyMaterial;
]]></sourcecode>
        <t>PublicKeyMaterial may be composed of both cryptographic material and metadata.</t>
        <t>Key ID is defined has follow:</t>
        <artwork><![CDATA[
key_id = encode(H(PublicKeyMaterial))
]]></artwork>
        <t>where</t>
        <ul spacing="normal">
          <li>
            <t><tt>PublicKeyMaterial</tt> is a length-prefix-encoded blob of data</t>
          </li>
          <li>
            <t><tt>H</tt> is a hash function</t>
          </li>
          <li>
            <t><tt>encode</tt> is some encoding function</t>
          </li>
        </ul>
        <t><strong>TODO Open questions about H</strong></t>
        <ul spacing="normal">
          <li>
            <t>Should the draft provide specific H?</t>
          </li>
          <li>
            <t>Should the draft define an IANA registry and require protocols to register
their H?</t>
          </li>
        </ul>
      </section>
      <section anchor="key-selection">
        <name>Key Selection</name>
        <t>The following is a deterministic algorithm for determining which Key a Client
uses to fulfill their cryptographic needs. By using a deterministic
algorithm, Origins can more easily predict the effects of a Key rotation and
implement grace periods, soak times, etc. Protocols may place additional
restrictions, or push these decision details to deployments.</t>
        <section anchor="algorithm">
          <name>Algorithm</name>
          <ol spacing="normal" type="1"><li>
              <t><strong>Filter invalid keys</strong>: Exclude keys that:
              </t>
              <ul spacing="normal">
                <li>
                  <t>Have a <tt>not-after</tt> field in the past.</t>
                </li>
                <li>
                  <t>Have a <xref target="not-before"/> field in the future.</t>
                </li>
                <li>
                  <t>Do not meet required cryptographic properties.</t>
                </li>
              </ul>
            </li>
            <li>
              <t><strong>Set missing activation times</strong>: If a key does not have a <xref target="not-before"/> field, set it to either:
              </t>
              <ul spacing="normal">
                <li>
                  <t>The <tt>Last-Modified</tt> header from the request as defined in <xref section="8.8.2" sectionFormat="of" target="HTTP"/>, if available.</t>
                </li>
                <li>
                  <t>The Date header from the request as defined in <xref section="6.6.1" sectionFormat="of" target="HTTP"/>, if available.</t>
                </li>
                <li>
                  <t>The client’s local time.</t>
                </li>
              </ul>
            </li>
            <li>
              <t><strong>Sort by activation time</strong>: If a <xref target="not-before"/> field exists, sort the
remaining keys in <strong>descending</strong> order based on <xref target="not-before"/>.</t>
            </li>
            <li>
              <t><strong>Select the first key</strong>: Choose the first key from the Key Directory, as
ordered in the Key Directory format.</t>
            </li>
          </ol>
          <t>Clients should implement the Key Selection Algorithm. Origins should present
the newest Keys first.</t>
          <t>For protocols which define a <xref target="not-before"/> field, the above algorithm minimizes the
chance that the Client uses a key that has expired between fetching the directory
from the origin and its usage as part of the protocol.</t>
          <t>For protocols without a <xref target="not-before"/> field, using the first key allows Origin
to present their key directory so that the newest is always first, and
the soon-to-be-removed key is last. This minimizes the chance of a client using
an expired key.</t>
          <t>Expired key may be presented for completion, only if the protocol defines a
<tt>not-after</tt> field.</t>
        </section>
      </section>
      <section anchor="rotation">
        <name>Rotation</name>
        <t>Key directories are not permanent: they change over time. Origins <bcp14>SHOULD</bcp14>
rotate keys on a schedule. Clients are going to fetch keys upon an immediate
rotation for security reasons. This section goes over how an Origin rotates
its keys, and how that interacts with scheduled and immediate rotations.</t>
        <section anchor="algorithm-1">
          <name>Algorithm</name>
          <t>We approach a public key generation by the following function</t>
          <artwork><![CDATA[
Generate(params, RAND) -> (publickey, privatekey, metadata)
]]></artwork>
          <t>At any point in time, all keys in the directory have a unique key id as defined in <xref target="key-id"/>.
When adding a key in the directory, that key has a unique key id.</t>
          <t>Generation looks as follows</t>
          <artwork><![CDATA[
do
  (publickey, privatekey, metadata) <- Generate(params, RAND)
  public_key_material <- (publickey | metadata)
  key_id <- encode(H(public_key_material))
while (key_id is not unique)
]]></artwork>
        </section>
        <section anchor="scheduled-rotation">
          <name>Scheduled rotation</name>
          <t>Scheduled rotation happens at a time known to Origins, Clients, and Mirrors.
This may be a regular interval (monthly, weekly, daily), or an ad-hoc schedule
agreed between all parties.</t>
          <t>Scheduled rotations are communicated in one of the two mode below</t>
          <dl>
            <dt><strong>Passive:</strong></dt>
            <dd>
              <t>Origins rely on cache headers to inform Clients about key expiry. They stop
advertising the key at time <tt>t</tt>, and delete it at time <tt>t_expiry=t+maxage</tt>.
Origins may have to take intermediate mirrors into considerations, if they
are aware these mirrors don't respect their cache headers.</t>
            </dd>
            <dt><strong>Active:</strong></dt>
            <dd>
              <t>Origins keep serving the key and add a <tt>not-after</tt> field. This field should be
at least <tt>t+maxage</tt>.</t>
            </dd>
          </dl>
          <t>With both modes, an Origin has to signal a key is not supported by sending a
response with status code 400. For instance, the error can include a key ID as
defined in <xref target="key-id"/>.</t>
        </section>
        <section anchor="immediate">
          <name>Immediate</name>
          <t>Origins might have to rotate keys immediately. Existing keys may have to be
invalidated and/or new keys be provisioned. Immediate key rotation can happen in
the event of a key compromise, loss, or other imperious reason.</t>
          <t>Immediate key rotation will cause some client requests to the server to fail
until the client and mirrors retrieve a new version of the directory. The key
directory endpoint is going to be placed under a higher load.</t>
          <ol spacing="normal" type="1"><li>
              <t>Origins should consider introducing a random backoff to spread the load of
key distribution over time. See <xref target="cache-behaviour"/></t>
            </li>
            <li>
              <t>Clients on a scheduled rotation should be configured to distrust rotation outside
a fixed window. Such policies should be defined by protocols.</t>
            </li>
          </ol>
        </section>
      </section>
      <section anchor="cache-behaviour">
        <name>Cache behaviour</name>
        <t>Caching the Key Directory lowers latency and reduces resource usage on
Mirrors and the Origin. An optimal caching strategy should minimize resource
usage for both the Client and Origin while preventing the client from using an
invalid key.</t>
        <t>These two requirements, minimizing resource usage and never using an invalid
key, are at odds with each other. In the event of an <xref target="immediate"/> key rotation, a
Client might use an invalid key. However, if a Client fetches an Origin key
directory for every request, it would waste time and network resources.</t>
        <t>This section provides interaction with some cache directive. Deployments should
also consider the recommendations laid out in <xref section="4.9" sectionFormat="of" target="HTTP-BEST-PRACTICES"/>.</t>
        <section anchor="not-before">
          <name><tt>not-before</tt> fields</name>
          <t>Protocols should define a <tt>not-before</tt> field. This field can be attached by Origins
to each Key in the Directory. The <tt>not-before</tt> field allows
Origins to signal to Clients when a Key is ready to use and reduces the
chance a Client uses a key which is not yet available. not-before fields <bcp14>SHOULD</bcp14>
be a Unix epoch timestamp in seconds.</t>
        </section>
        <section anchor="cache-directives">
          <name>Cache directives</name>
          <t>Origins responds with cache directives <xref target="HTTP-CACHE"/>. These
control when the Key Directory should be refreshed. For instance, Origins
provides a
<tt>Cache-Control: max-age</tt> header, or <tt>Expires</tt> header which is slightly less than
the grace period given for a key about to rotate. Clients should respect the
<tt>max-age</tt> cache directive or other directives. If an Origin
provides a <tt>max-age</tt> header and a Mirror is used, an Origin should provide a
<tt>s-maxage</tt> header that is equivalent to <tt>max-age</tt>.</t>
          <t>To prevent Clients refreshing their Key Directories at the same time
(synchronization), Mirrors should provide to its clients a <tt>max-age</tt> cache
directive with duration in the range <tt>[0, Origin s-maxage]</tt>.</t>
          <t>Origins should consider using <tt>Date</tt> (<xref section="6.6.1" sectionFormat="of" target="HTTP"/>) and
<tt>Last-modified</tt> (<xref section="8.8.2" sectionFormat="of" target="HTTP"/>) headers to ease <xref target="rotation"/>.</t>
        </section>
        <section anchor="client-cache-refresh">
          <name>Client cache refresh</name>
          <t>The primary method a Client should use to determine when it refreshes its view
of the Key Directory is through the delta seconds described in the <tt>max-age</tt>
cache directive. The higher the delta, the less frequent a Client will update
its cache. The lower the delta, the quicker clients will respond to unplanned
key rotations.</t>
          <t><tt>min-fresh</tt> could also be sent by Origins as defined in <xref target="HTTP-CACHE"/>.</t>
        </section>
      </section>
      <section anchor="well-known-url">
        <name>Well known URL</name>
        <t>It is recommended protocols register a <xref target="WELL-KNOWN"/> URL and associated
content-type.</t>
        <t>A key directory server should consider supporting both GET and HEAD request on
that endpoint.</t>
        <artwork><![CDATA[
GET /.well-known/<your-protocol>

HTTP/1.1 200 OK
Cache-Control: max-age=<Client Cache TTL>, s-maxage=<Shared Cache TTL>
Content-Type: <your-protocol>
Last-Modified: <datestamp>
]]></artwork>
        <t>HEAD requests can be used by Clients to cheaply determine if the directory has
changed. The Origin server <bcp14>SHOULD</bcp14> issue a <tt>Last-Modified</tt> header with the date
stamp of when the key directory resource was last modified.</t>
        <t>If issuing a <tt>Last-Modified</tt> header, the Origin server <bcp14>SHOULD</bcp14> support the correct
response to a <tt>If-Modified-Since</tt> HTTP GET or HEAD request, returning the
appropriate HTTP status codes <xref target="HTTP-CACHE"/>.</t>
        <t>It is recommended that Mirrors support <tt>Last-Modified</tt> and <tt>If-Modified-Since</tt>
          <xref target="HTTP-CACHE"/>.</t>
      </section>
      <section anchor="future-considerations">
        <name>Future considerations</name>
        <t>These considerations should be addressed in future drafts. Defining them now
appears to be premature as the core of the draft does not have consensus.</t>
        <section anchor="consistency">
          <name>Consistency</name>
          <t>Consistency allows client to prevent themselves from split view attack. A
proposal that has been made for Privacy Pass is to use multiple mirrors
<xref target="CONSISTENCY"/>. With a sufficiently high quorum, clients get more confident
that they are not singled out.
It presents scalability issues as you need multiple mirrors, and have one more
requests from client per mirror in the quorum.</t>
        </section>
        <section anchor="key-transparency">
          <name>Key Transparency</name>
          <t>Key Directory over HTTP <bcp14>SHOULD</bcp14> integrate with transparency, once the protocol has
been defined in <xref target="KEYTRANS"/>.
There are specific consideration as to what goes in the log: the full
directory, keys individually, privacy considerations.</t>
        </section>
      </section>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy Considerations</name>
      <t>Clients fetching keys mean they reveal their IP, time, and other informations.
When the key directory is provided by an Origin distinct from the Origin
providing service, Clients <bcp14>SHOULD</bcp14> consider proxying their traffic through a
Mirror server provided by the service they use. This may happen if the Origin
service delegates key management to a third party for instance.
Mirrors <bcp14>SHOULD NOT</bcp14> collide with the key server in an attempt to break Client
privacy.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TODO Security</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="HTTP">
          <front>
            <title>HTTP Semantics</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
              <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="97"/>
          <seriesInfo name="RFC" value="9110"/>
          <seriesInfo name="DOI" value="10.17487/RFC9110"/>
        </reference>
        <reference anchor="HTTP-CACHE">
          <front>
            <title>HTTP Caching</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document defines HTTP caches and the associated header fields that control cache behavior or indicate cacheable response messages.</t>
              <t>This document obsoletes RFC 7234.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="98"/>
          <seriesInfo name="RFC" value="9111"/>
          <seriesInfo name="DOI" value="10.17487/RFC9111"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="WELL-KNOWN">
          <front>
            <title>Well-Known Uniform Resource Identifiers (URIs)</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <date month="May" year="2019"/>
            <abstract>
              <t>This memo defines a path prefix for "well-known locations", "/.well-known/", in selected Uniform Resource Identifier (URI) schemes.</t>
              <t>In doing so, it obsoletes RFC 5785 and updates the URI schemes defined in RFC 7230 to reserve that space. It also updates RFC 7595 to track URI schemes that support well-known URIs in their registry.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8615"/>
          <seriesInfo name="DOI" value="10.17487/RFC8615"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="CONSISTENCY">
          <front>
            <title>Checking Resource Consistency with HTTP Mirrors</title>
            <author fullname="Benjamin Beurdouche" initials="B." surname="Beurdouche">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Matthew Finkel" initials="M." surname="Finkel">
              <organization>Apple Inc.</organization>
            </author>
            <author fullname="Steven Valdez" initials="S." surname="Valdez">
              <organization>Google LLC</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <author fullname="Tommy Pauly" initials="T." surname="Pauly">
              <organization>Apple Inc.</organization>
            </author>
            <date day="30" month="January" year="2024"/>
            <abstract>
              <t>   This document describes the mirror protocol, an HTTP-based protocol
   for fetching mirrored HTTP resources.  The primary use case for the
   mirror protocol is to support HTTP resource consistency checks in
   protocols that require clients have a consistent view of some
   protocol-specific resource (typically, a public key) for security or
   privacy reasons, including Privacy Pass and Oblivious HTTP.  To that
   end, this document also describes how to use the mirror protocol to
   implement these consistency checks.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-privacypass-consistency-mirror-00"/>
        </reference>
        <reference anchor="COSE">
          <front>
            <title>CBOR Object Signing and Encryption (COSE)</title>
            <author fullname="J. Schaad" initials="J." surname="Schaad"/>
            <date month="July" year="2017"/>
            <abstract>
              <t>Concise Binary Object Representation (CBOR) is a data format designed for small code size and small message size. There is a need for the ability to have basic security services defined for this data format. This document defines the CBOR Object Signing and Encryption (COSE) protocol. This specification describes how to create and process signatures, message authentication codes, and encryption using CBOR for serialization. This specification additionally describes how to represent cryptographic keys using CBOR.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8152"/>
          <seriesInfo name="DOI" value="10.17487/RFC8152"/>
        </reference>
        <reference anchor="COSE-HPKE">
          <front>
            <title>Use of Hybrid Public-Key Encryption (HPKE) with CBOR Object Signing and Encryption (COSE)</title>
            <author fullname="Hannes Tschofenig" initials="H." surname="Tschofenig">
              <organization>University of Applied Sciences Bonn-Rhein-Sieg</organization>
            </author>
            <author fullname="Orie Steele" initials="O." surname="Steele">
              <organization>Transmute</organization>
            </author>
            <author fullname="Ajitomi, Daisuke" initials="A." surname="Daisuke">
              <organization>bibital</organization>
            </author>
            <author fullname="Laurence Lundblade" initials="L." surname="Lundblade">
              <organization>Security Theory LLC</organization>
            </author>
            <date day="18" month="January" year="2025"/>
            <abstract>
              <t>   This specification defines hybrid public-key encryption (HPKE) for
   use with CBOR Object Signing and Encryption (COSE).  HPKE offers a
   variant of public-key encryption of arbitrary-sized plaintexts for a
   recipient public key.

   HPKE works for any combination of an asymmetric key encapsulation
   mechanism (KEM), key derivation function (KDF), and authenticated
   encryption with additional data (AEAD) function.  Authentication for
   HPKE in COSE is provided by COSE-native security mechanisms or by one
   of the authenticated variants of HPKE.

   This document defines the use of the HPKE with COSE.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-cose-hpke-10"/>
        </reference>
        <reference anchor="DAP">
          <front>
            <title>Distributed Aggregation Protocol for Privacy Preserving Measurement</title>
            <author fullname="Tim Geoghegan" initials="T." surname="Geoghegan">
              <organization>ISRG</organization>
            </author>
            <author fullname="Christopher Patton" initials="C." surname="Patton">
              <organization>Cloudflare</organization>
            </author>
            <author fullname="Brandon Pitman" initials="B." surname="Pitman">
              <organization>ISRG</organization>
            </author>
            <author fullname="Eric Rescorla" initials="E." surname="Rescorla">
              <organization>Independent</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="3" month="February" year="2025"/>
            <abstract>
              <t>   There are many situations in which it is desirable to take
   measurements of data which people consider sensitive.  In these
   cases, the entity taking the measurement is usually not interested in
   people's individual responses but rather in aggregated data.
   Conventional methods require collecting individual responses and then
   aggregating them, thus representing a threat to user privacy and
   rendering many such measurements difficult and impractical.  This
   document describes a multi-party distributed aggregation protocol
   (DAP) for privacy preserving measurement (PPM) which can be used to
   collect aggregate data without revealing any individual user's data.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-ppm-dap-14"/>
        </reference>
        <reference anchor="HTTP-BEST-PRACTICES">
          <front>
            <title>Building Protocols with HTTP</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>Applications often use HTTP as a substrate to create HTTP-based APIs. This document specifies best practices for writing specifications that use HTTP to define new application protocols. It is written primarily to guide IETF efforts to define application protocols using HTTP for deployment on the Internet but might be applicable in other situations.</t>
              <t>This document obsoletes RFC 3205.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="56"/>
          <seriesInfo name="RFC" value="9205"/>
          <seriesInfo name="DOI" value="10.17487/RFC9205"/>
        </reference>
        <reference anchor="JOSE">
          <front>
            <title>JSON Web Key (JWK)</title>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <date month="May" year="2015"/>
            <abstract>
              <t>A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data structure that represents a cryptographic key. This specification also defines a JWK Set JSON data structure that represents a set of JWKs. Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and IANA registries established by that specification.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7517"/>
          <seriesInfo name="DOI" value="10.17487/RFC7517"/>
        </reference>
        <reference anchor="JOSE-HPKE">
          <front>
            <title>Use of Hybrid Public Key Encryption (HPKE) with JSON Object Signing and Encryption (JOSE)</title>
            <author fullname="Tirumaleswar Reddy.K" initials="T." surname="Reddy.K">
              <organization>Nokia</organization>
            </author>
            <author fullname="Hannes Tschofenig" initials="H." surname="Tschofenig">
         </author>
            <author fullname="Aritra Banerjee" initials="A." surname="Banerjee">
              <organization>Nokia</organization>
            </author>
            <author fullname="Orie Steele" initials="O." surname="Steele">
              <organization>Transmute</organization>
            </author>
            <author fullname="Michael B. Jones" initials="M. B." surname="Jones">
              <organization>Self-Issued Consulting</organization>
            </author>
            <date day="31" month="March" year="2024"/>
            <abstract>
              <t>   This specification defines Hybrid Public Key Encryption (HPKE) for
   use with JSON Object Signing and Encryption (JOSE).  HPKE offers a
   variant of public key encryption of arbitrary-sized plaintexts for a
   recipient public key.

   HPKE works for any combination of an asymmetric key encapsulation
   mechanism (KEM), key derivation function (KDF), and authenticated
   encryption with additional data (AEAD) function.  Authentication for
   HPKE in JOSE is provided by JOSE-native security mechanisms or by one
   of the authenticated variants of HPKE.

   This document defines the use of the HPKE with JOSE.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-rha-jose-hpke-encrypt-07"/>
        </reference>
        <reference anchor="KEYTRANS">
          <front>
            <title>Key Transparency Protocol</title>
            <author fullname="Brendan McMillion" initials="B." surname="McMillion">
         </author>
            <author fullname="Felix Linker" initials="F." surname="Linker">
         </author>
            <date day="10" month="December" year="2024"/>
            <abstract>
              <t>   While there are several established protocols for end-to-end
   encryption, relatively little attention has been given to securely
   distributing the end-user public keys for such encryption.  As a
   result, these protocols are often still vulnerable to eavesdropping
   by active attackers.  Key Transparency is a protocol for distributing
   sensitive cryptographic information, such as public keys, in a way
   that reliably either prevents interference or detects that it
   occurred in a timely manner.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-keytrans-protocol-00"/>
        </reference>
        <reference anchor="OHTTP">
          <front>
            <title>Oblivious HTTP</title>
            <author fullname="M. Thomson" initials="M." surname="Thomson"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="January" year="2024"/>
            <abstract>
              <t>This document describes Oblivious HTTP, a protocol for forwarding encrypted HTTP messages. Oblivious HTTP allows a client to make multiple requests to an origin server without that server being able to link those requests to the client or to identify the requests as having come from the same client, while placing only limited trust in the nodes used to forward the messages.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9458"/>
          <seriesInfo name="DOI" value="10.17487/RFC9458"/>
        </reference>
        <reference anchor="PRIVACYPASS">
          <front>
            <title>Privacy Pass Issuance Protocols</title>
            <author fullname="S. Celi" initials="S." surname="Celi"/>
            <author fullname="A. Davidson" initials="A." surname="Davidson"/>
            <author fullname="S. Valdez" initials="S." surname="Valdez"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="June" year="2024"/>
            <abstract>
              <t>This document specifies two variants of the two-message issuance protocol for Privacy Pass tokens: one that produces tokens that are privately verifiable using the Issuer Private Key and one that produces tokens that are publicly verifiable using the Issuer Public Key. Instances of "issuance protocol" and "issuance protocols" in the text of this document are used interchangeably to refer to the two variants of the Privacy Pass issuance protocol.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9578"/>
          <seriesInfo name="DOI" value="10.17487/RFC9578"/>
        </reference>
        <reference anchor="RFC9000">
          <front>
            <title>QUIC: A UDP-Based Multiplexed and Secure Transport</title>
            <author fullname="J. Iyengar" initials="J." role="editor" surname="Iyengar"/>
            <author fullname="M. Thomson" initials="M." role="editor" surname="Thomson"/>
            <date month="May" year="2021"/>
            <abstract>
              <t>This document defines the core of the QUIC transport protocol. QUIC provides applications with flow-controlled streams for structured communication, low-latency connection establishment, and network path migration. QUIC includes security measures that ensure confidentiality, integrity, and availability in a range of deployment circumstances. Accompanying documents describe the integration of TLS for key negotiation, loss detection, and an exemplary congestion control algorithm.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9000"/>
          <seriesInfo name="DOI" value="10.17487/RFC9000"/>
        </reference>
      </references>
    </references>
    <?line 458?>

<section anchor="test-vectors">
      <name>Test vectors</name>
      <t>Implementation may test the following scenarios
1. One key is provided on a normal basis, the key rotates:
  1. does the directory has two entries or one?
  2. what are the cache headers?
  3. what are the keys as seen by a client?
  4. does the new key has a unique key id?</t>
      <ol spacing="normal" type="1"><li>
          <t>Key has to be rotated immediately</t>
        </li>
        <li>
          <t>How long does it take for client to notice</t>
        </li>
        <li>
          <t>What is the backoff to avoid a thundering herd issue</t>
        </li>
      </ol>
    </section>
    <section anchor="non-normative-proposals">
      <name>Non normative proposals</name>
      <section anchor="for-jose">
        <name>For JOSE</name>
        <t>JOSE has a key directory in the form of JWK Set as defined in <xref section="5" sectionFormat="of" target="JOSE"/>.
However, it does not addhere to the best practices laid down here, despite being
Web keys. This would be valuable as the group aims to integrates with all sort
of cryptographic keys, as can be seen with the new HPKE proposal <xref target="JOSE-HPKE"/>.</t>
        <t>Following these recommendations, JOSE may define:</t>
        <ul spacing="normal">
          <li>
            <t>A well-known URI</t>
          </li>
          <li>
            <t>A deterministic Key ID</t>
          </li>
          <li>
            <t>Recommendations for caching and rotation, or leave it to implementations.</t>
          </li>
        </ul>
      </section>
      <section anchor="for-cose">
        <name>For COSE</name>
        <t>Same as the above, for COSE Key Set.</t>
      </section>
    </section>
    <section anchor="use-cases">
      <name>Use cases</name>
      <t>See existing key directory on https://key-directory-over-http.research.cloudflare.com/</t>
      <section anchor="dap">
        <name>DAP</name>
        <t>Defined in <xref section="4.5.1" sectionFormat="of" target="DAP"/>.</t>
        <sourcecode type="tls"><![CDATA[
HpkeConfig HpkeConfigList<0..2^16-1>;

struct {
  HpkeConfigId id;
  HpkeKemId kem_id;
  HpkeKdfId kdf_id;
  HpkeAeadId aead_id;
  HpkePublicKey public_key;
} HpkeConfig;

opaque HpkePublicKey<0..2^16-1>;
uint16 HpkeAeadId; /* Defined in [HPKE] */
uint16 HpkeKemId;  /* Defined in [HPKE] */
uint16 HpkeKdfId;  /* Defined in [HPKE] */
]]></sourcecode>
        <t>Partially informed comments:</t>
        <ul spacing="normal">
          <li>
            <t>HpkeConfigId could be removed</t>
          </li>
          <li>
            <t>Need not-before to handle early capture</t>
          </li>
        </ul>
      </section>
      <section anchor="ohttp">
        <name>OHTTP</name>
        <t>Defined in <xref section="3" sectionFormat="of" target="OHTTP"/>.</t>
        <sourcecode type="tls"><![CDATA[
HPKE Symmetric Algorithms {
  HPKE KDF ID (16),
  HPKE AEAD ID (16),
}

Key Config {
  Key Identifier (8),
  HPKE KEM ID (16),
  HPKE Public Key (Npk * 8),
  HPKE Symmetric Algorithms Length (16) = 4..65532,
  HPKE Symmetric Algorithms (32) ...,
}
]]></sourcecode>
        <t>Partially informed comments:</t>
        <ul spacing="normal">
          <li>
            <t>Key Identifier could be removed/be deterministic</t>
          </li>
          <li>
            <t>No mention of not-before</t>
          </li>
          <li>
            <t>No mention of HTTP Caching for rotation</t>
          </li>
        </ul>
      </section>
      <section anchor="privacy-pass">
        <name>Privacy Pass</name>
        <t>Defined in <xref section="4" sectionFormat="of" target="PRIVACYPASS"/></t>
        <sourcecode type="tls"><![CDATA[
 {
    "issuer-request-uri": "https://issuer.example.net/request",
    "token-keys": [
      {
        "token-type": 2,
        "token-key": "MI...AB",
        "not-before": 1686913811,
      },
      {
        "token-type": 2,
        "token-key": "MI...AQ",
      }
    ]
 }
]]></sourcecode>
        <t>Partially informed comments:
* Not as flexible as HPKE
* Has some protocol metadata (token-type, issuer-request-uri, rate-limit)</t>
      </section>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors would like to thank Ethan Heilman, Michael Rosenberg, and Chris Wood
for their knowledge of existing practices on key directories, and Mark
Nottingham for helpful discussion on HTTP best practices.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA6Vc3XbbRpK+76fokS/GVkjK8l8cxbGjSHKktWVrLCU+OTnZ
qEk0SaxAgAuAkjmK5uxr7N0+yz7KPsnWV1XdAEgpcWZ8YZFA/1RXV1d99dPs
9/umTuvM79iND35UzGY+T1ydFnllx0Vp3/il3U9LP6qLMvWVLS59aQ/Pzk42
jBsOS3+502mybBqYkav9hB7t2DQfF8YkxSh3M5ooKd247ieuzNJ80r/wy34S
uvfRvT+t63n/4UNTLYaztKqImHo5p45HB2evzYhI83m1qHZsXS68IQoeG1d6
RyvYMFdFeTEpi8Wcvr169WrD0PD0LNkxtm+P8tqXua/tPijAk5PFMEtH1AZf
sJBISXhQFjWzI3wfudHUhy9H++bS5wtPo9vOrNYKxRv4OHNpRh+xKjdPv019
PR4U5QSvXDma6qtqZ2sLLfEovfSD0GwLD7aGZXFV+S0dYwt9J2k9XQypdz1N
hzO/2PosvqJnRjtT1a15dYSBDDlIi88b6/NaDab1LNswxi3qaVFiI4gEa8eL
LBN5eJ1WUxKafRmGX9K6XZ7+nTm/Y/eyYpGMiTOetnA04BZeuDrmvt8qCYPE
X66Pf0arc4ustsd+kae+/HMzFHUfW/FtraMMFhfrU5ymsyK37/xVDUn5M8OX
49G3FXrn3HlAR9CYvChn1PWSBQuHacd+eL331fb2Q/3e39vdOzwIT7eNwRFr
9dl7/+706PTs4N3eT3Rs+vssTf15mV660XLuqqqPY5RWtc9Hy/4sLcuixIlD
z1MZ9/n200f6vX948uZAxpEd59FGReX70/mF7zNZ+7sna03m8xlJx7y//STQ
/d3B6Vn/5MPu3tnR3sGpLODRw6f0+t/CxF8+3f5Sv69NXE5d/z/ivER8uZzX
/Ydo/+bgp7MPu+9OW+slgaxLl1e08KIuRkUmS3zfcPTJ0+f04OTD0Y+7ez+d
7J4qRU+/fG6M6ff71g0rGmJUG0NSVFnSYQvSkLVN/DjNSR+Wt+jMMFtl66mr
rf80J4rtnFWNJZpEixpQMdBpZmmSZN6Ye9BRZZEsRqxzzDEJXDrPfKO6msFL
n5G6zVsDW2ZHMSndfLockNxDf/n/XNCZ5HlNXdihJx1Ha0qHi9ondri078t0
khLp9HIvS2lxFbrSYkcu5+ZF7u1l6uzIl3U6TqHXq56pinF9BYkmOryr6BEJ
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

-->

</rfc>
