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


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

]>


<rfc ipr="trust200902" docName="draft-gallagher-openpgp-hkp-09" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="HKP">OpenPGP HTTP Keyserver Protocol</title>

    <author fullname="Daphne Shaw">
      <organization>Jabberwocky Tech</organization>
      <address>
        <email>dshaw@jabberwocky.com</email>
      </address>
    </author>
    <author fullname="Andrew Gallagher" role="editor">
      <organization>PGPKeys.EU</organization>
      <address>
        <email>andrewg@andrewg.com</email>
      </address>
    </author>
    <author fullname="Daniel Huigens">
      <organization>Proton AG</organization>
      <address>
        <email>d.huigens@protonmail.com</email>
      </address>
    </author>

    <date year="2025" month="November" day="03"/>

    <area>sec</area>
    <workgroup>openpgp</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 68?>

<t>This document specifies a series of conventions to implement an OpenPGP keyserver using the Hypertext Transfer Protocol (HTTP).
As this document is a codification and extension of a protocol that is already in wide use, strict attention is paid to backward compatibility with these existing implementations.</t>



    </abstract>

    <note title="About This Document" removeInRFC="true">
      <t>
        The latest revision of this draft can be found at <eref target="https://andrewgdotcom.gitlab.io/draft-gallagher-openpgp-hkp"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-gallagher-openpgp-hkp/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        OpenPGP Working Group mailing list (<eref target="mailto:openpgp@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/openpgp/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/openpgp/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://gitlab.com/andrewgdotcom/draft-gallagher-openpgp-hkp"/>.</t>
    </note>


  </front>

  <middle>


<?line 73?>

<section anchor="introduction"><name>Introduction</name>

<t>For ease of use, public key cryptography requires a key distribution system.
For many years, the most commonly used system has been a keyserver - a server that stores public keys and/or certificates, with a searchable interface.
The HTTP Keyserver Protocol is a OpenPGP keyserver implemented using HTTP.</t>

</section>
<section anchor="conventions-definitions"><name>Conventions and Definitions</name>

<t>The term "OpenPGP Certificate" is used in this document interchangeably with "OpenPGP Transferable Public Key", as defined in <xref section="10.1" sectionFormat="of" target="RFC9580"/>.</t>

<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?>

</section>
<section anchor="keyserver-use-cases"><name>Keyserver Use Cases</name>

<t>A keyserver is typically used for the following (non-exhaustive) use cases:</t>

<section anchor="certificate-discovery"><name>Certificate Discovery</name>

<t>When initiating secure communication with a new correspondent, a client will typically attempt to discover the encryption key(s) that it should use.
This is a subtle issue with many security considerations, however many discovery methods involve looking up a certificate on a server using a human-readable identifier such as an email address.</t>

</section>
<section anchor="certificate-refresh"><name>Certificate Refresh</name>

<t>Certificates in OpenPGP are dynamic objects, therefore it is important to refresh known certificates in order to pick up the latest changes.
These changes can include new subkeys and User IDs, updated self-signatures and third-party certifications, and revocations.
In some cases it may no longer be possible to search by User ID, therefore it is <bcp14>RECOMMENDED</bcp14> that clients refresh known certificates by primary key fingerprint search.</t>

</section>
<section anchor="reference-resolution"><name>Reference Resolution</name>

<t>The OpenPGP wire format includes fields that reference primary keys or subkeys by either Key ID or fingerprint.
A client may therefore wish to search for previously unknown certificates based on such a reference.</t>

</section>
</section>
<section anchor="hkp-and-http"><name>HKP and HTTP</name>

<t>As HKP is implemented over HTTP, everything in <xref target="RFC1945"></xref> applies to HKP as well, and HKP error codes are the same as the ones used in HTTP.</t>

<t>Due the very large deployment of HKP clients based on HTTP version 1.0, HKP keyservers <bcp14>MUST</bcp14> support HTTP 1.0.
HKP keyservers <bcp14>MAY</bcp14> additionally support other HTTP versions.</t>

<t>(( dshaw : I expect this to be controversial, but we've got tons of deployed code that only works with 1.0.
I'd be willing to discuss removing this <bcp14>MUST</bcp14> or make it a <bcp14>SHOULD</bcp14> and add a "implementation notes" section pointing out the problem instead.
See issue #5.
))</t>

<t>When used over HTTPS, HKP is commonly referred to as "HKPS".</t>

<t>HKP(S) are distinguished from generic use of HTTP(S) by using the URI schemes "hkp" and "hkps" <xref target="RFC7595"></xref>.
HKP is assigned port number 11371 and HKPS is assigned 11372 (although this is rarely used in practice).
For reasons of maximum compatibility with firewalls and filtering HTTP proxies, HKP(S) are often served over the standard HTTP(S) port(s) (TCP ports 80 and 443).</t>

<t>By convention and history, HKP defaults to HTTP on TCP port 11371, and HKPS defaults to HTTPS on TCP port 443.</t>

<t>(( andrewg : if we assign hkps, we appear to be required to specify a dedicated port, even though nobody uses it.
See issue #14.
))</t>

<t>A keyserver <bcp14>SHOULD</bcp14> support both HKP and HKPS.
A client <bcp14>SHOULD</bcp14> use HKPS, or a transport method with equivalent security properties, such as Tor hidden services <xref target="TOR"></xref>.</t>

<section anchor="request-paths"><name>Request Paths</name>

<t>HKP defines three paths, namely "/pks/v2" for the v2 API (<xref target="v2-api"/>), "/pks/lookup" for legacy lookups (<xref target="legacy-lookups"/>), and "/pks/add" for legacy submission (<xref target="legacy-submission"/>).
Paths beginning with "/pks/v&lt;?&gt;" are reserved for future versions of HKP.</t>

<t>A keyserver <bcp14>MAY</bcp14> support requests to other paths under "/pks", but these are outside the scope of this document.
These alternative paths have historically been used to provide human-readable interfaces such as HTML forms, and functionality extensions such as <xref target="SKS"></xref>.</t>

</section>
<section anchor="http-status"><name>HTTP Status Codes</name>

<t>When a status or error code needs to be returned by a keyserver, the most appropriate HTTP code from <xref target="RFC9110"></xref> should be used.
It is good practice to return the most specific error code possible: for example, returning 404 ("Not Found") rather than 400 ("Bad Request") when a certificate is not found.</t>

<t>This document gives suggested HTTP error codes for several common situations.
Note that these are only suggestions, and implementations may have good reasons (such as not revealing the reason why a request failed) for using other error codes.</t>

<t>Clients <bcp14>SHOULD</bcp14> understand the following codes:</t>

<texttable title="Status Codes" anchor="status-codes">
      <ttcol align='left'>Status Code</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>200 OK</c>
      <c>Request succeeded</c>
      <c>403 Forbidden</c>
      <c>The requested category/operation is not permitted</c>
      <c>404 Not found</c>
      <c>The search returned no results, or path not found</c>
      <c>410 Gone</c>
      <c>Requested data has been permanently deleted, e.g. due to RTBF</c>
      <c>422 Unprocessable content</c>
      <c>Submission was not well formed</c>
      <c>501 Not implemented</c>
      <c>The requested category/operation is not supported</c>
</texttable>

<t>In addition, a client <bcp14>SHOULD</bcp14> understand 3xx redirect codes.</t>

</section>
</section>
<section anchor="v2-api"><name>The v2 API</name>

<t>The v2 API is a RESTful interface that uses the GET, PUT, POST, DELETE, HEAD, and OPTIONS methods.
Specifically, the abs_path (<xref section="3.2" sectionFormat="of" target="RFC1945"/>) is built up of the base path "/pks/v2", followed by request-specific URL path components.</t>

<section anchor="v2-lookup-format"><name>v2 Lookup Format</name>

<t>Certificate lookups are done via an HTTP GET request.</t>

<t>v2 lookups normally include both "category" and "identifier" URL path components.
They are appended to "/pks/v2" as follows:</t>

<figure><artwork><![CDATA[
GET /pks/v2/<category>/<identifier>
]]></artwork></figure>

<t>The "category" and "identifier" components <bcp14>MUST</bcp14> be supplied.</t>

<t>When the v2 lookup format is being used, v2 output format (<xref target="v2-output-format"/>) <bcp14>MUST</bcp14> be returned.</t>

<t>The v2 lookup format is designed so that a basic HKP service can be implemented using static files.</t>

<texttable title="v2 Lookup Categories" anchor="v2-lookup-categories">
      <ttcol align='left'>Category</ttcol>
      <ttcol align='left'>Identifier format</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">certs/by-identity</spanx></c>
      <c>identity</c>
      <c>Certificate bundle</c>
      <c><xref target="identity-category"/></c>
      <c><spanx style="verb">certs/by-vfingerprint</spanx></c>
      <c>versioned fingerprint</c>
      <c>Certificate bundle</c>
      <c><xref target="vfingerprint-category"/></c>
      <c><spanx style="verb">certs/by-keyid</spanx></c>
      <c>key ID</c>
      <c>Certificate bundle</c>
      <c><xref target="keyid-category"/></c>
      <c><spanx style="verb">canonical</spanx></c>
      <c>identity</c>
      <c>Canonical bundle</c>
      <c><xref target="canonical-lookup-category"/></c>
      <c><spanx style="verb">index</spanx></c>
      <c>identity</c>
      <c>Index of certificates</c>
      <c><xref target="index-category"/></c>
      <c><spanx style="verb">prefixlog</spanx></c>
      <c>date</c>
      <c>List of prefixes</c>
      <c><xref target="prefixlog-category"/></c>
</texttable>

<section anchor="identity-category"><name>The "certs/by-identity" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-identity" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-identity/<identifier>
]]></artwork></figure>

<t>The "certs/by-identity" category identifies each certificate by matching the contents of its User ID packet(s) (<xref target="identity-lookups"/>).
The response to a successful "certs/by-identity" request is a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned certificate bundle to a reasonable length.
Results <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in the identity link (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for exceeds a minimum confidence value, and <bcp14>MAY</bcp14> treat "certs/by-identity" as a synonym for "canonical".
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="vfingerprint-category"><name>The "certs/by-vfingerprint" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-vfingerprint" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-vfingerprint/<identifier>
]]></artwork></figure>

<t>The "certs/by-vfingerprint" category identifies each certificate by the versioned fingerprint of its primary key or a subkey.
The versioned fingerprint is provided in the "identifier" path component in hexadecimal encoding, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>A versioned fingerprint consists of one octet of fingerprint version number and N octets of fingerprint.
This is the same octet sequence used in the Issuer Fingerprint and Intended Recipient Fingerprint subpackets (<xref section="5.2.3" sectionFormat="of" target="RFC9580"/>).</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey fingerprints.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
</list></t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="keyid-category"><name>The "certs/by-keyid" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-keyid" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-keyid/<identifier>
]]></artwork></figure>

<t>The "certs/by-keyid" category identifies each certificate by the Key ID of its primary key or a subkey (<xref section="5.5.4" sectionFormat="of" target="RFC9580"/>).
The Key ID is provided in the "identifier" path component as 16 hexadecimal digits, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey Key IDs.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
</list></t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

<t>"certs/by-keyid" is only required for locating a signing key that made either a V3 signature, or a V4 signature with an Issuer Key ID subpacket and no Issuer Fingerprint subpacket.
Issuer Key ID subpackets are not specified for use in later signature versions (<xref section="5.2.3.12" sectionFormat="of" target="RFC9580"/>), and so certificates with versions greater than 4 <bcp14>MUST NOT</bcp14> be returned in response to a "certs/by-keyid" request.</t>

</section>
<section anchor="canonical-lookup-category"><name>The "canonical" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "canonical" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/canonical/<identifier>
]]></artwork></figure>

<t>The "canonical" category is similar to the "certs/by-identity" category, but is intended specifically for certificate discovery (<xref target="certificate-discovery"/>).
A keyserver <bcp14>MUST</bcp14> return either the canonical bundle of the identity being searched for (<xref target="canonical-bundles"/>), or a 404 Not Found error.</t>

</section>
<section anchor="index-category"><name>The "index" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "index" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/index/<identifier>
]]></artwork></figure>

<t>This requests a list of certificates on the keyserver whose User IDs match the identity given in the "identifier" path component (<xref target="identity-lookups"/>).
This list is returned in JSON format as specified in <xref target="v2-indexes"/>.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned index to a reasonable length.
Results <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for exceeds a minimum confidence value.
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="prefixlog-category"><name>The "prefixlog" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "prefixlog" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/prefixlog/<identifier>
]]></artwork></figure>

<t>"prefixlog" requests a list of fingerprint prefixes that indicate which certificates have been modified since 00:00:00 UTC on a specific date.
The date is provided in the "identifier" path component using the "full-date" format as per <xref section="5.6" sectionFormat="of" target="RFC3339"/>, i.e. "2025-12-31".</t>

<t>The returned data is a list of CRLF-separated, hexadecimal-encoded, primary key fingerprint prefixes, and each prefix is truncated at a hex-digit (nybble) boundary.
Fingerprint prefixes do not include the version number.
The keyserver <bcp14>SHOULD</bcp14> calibrate the prefix length so that it is long enough to provide collision resistance, but short enough to maintain a useful anonymity cohort.
For example, if the prefix length was too short, clients could be induced to make excessive numbers of network requests.
A client <bcp14>MUST NOT</bcp14> make any assumptions about the length of the prefixes returned.</t>

<t>A client that wishes to update its local keystore from a keyserver <bcp14>MAY</bcp14> first make a "prefixlog" request with the date of the last successful refresh.
It can then compare the returned list of prefixes to see if any of them are present in its local keystore, and make subsequent "certs/by-vfingerprint" requests as appropriate (<xref target="vfingerprint-category"/>).
In this way, it can avoid making unnecessary requests that will return no updates, but will still leak information to the keyserver.</t>

<t>Note that the <spanx style="verb">prefixlog</spanx> endpoint always returns fingerprint prefixes, regardless of fingerprint version.
This contrasts with v4 Key IDs, which are constructed from fingerprint suffixes.</t>

<t>A keyserver <bcp14>MUST NOT</bcp14> support indexing or downloading certificates by prefix.</t>

</section>
<section anchor="options-lookup-method"><name>OPTIONS Lookup Method</name>

<t>A client <bcp14>MAY</bcp14> attempt to detect which lookup categories a keyserver supports by making an OPTIONS request (<xref section="9.3.7" sectionFormat="of" target="RFC9110"/>) to a lookup path with the "category" path component present but the "identifier" component absent.</t>

<t>A keyserver that supports the lookup category <bcp14>MAY</bcp14> respond with:</t>

<t><list style="symbols">
  <t>a 200 "OK" code,</t>
  <t>an "Allow:" response header that includes the value "GET" (<xref section="10.2.1" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<t>Otherwise, it <bcp14>SHOULD</bcp14> respond with an error code such as 501 "Not Implemented".
Note however that a keyserver that does not support OPTIONS (for example, if it is implemented using static files) <bcp14>MAY</bcp14> return another error code such as 404 "Not Found" or 405 "Method Not Allowed".</t>

<t>A client <bcp14>SHOULD NOT</bcp14> attempt to make a GET request to a lookup path without both the "category" and "identifier" path components present.
A keyserver <bcp14>SHOULD</bcp14> return an error code such as 403 "Forbidden" to such a request.</t>

</section>
<section anchor="head-lookup-method"><name>HEAD Lookup Method</name>

<t>A client <bcp14>MAY</bcp14> attempt to retrieve the metadata of a certificate or certificate bundle by making a HEAD request (<xref section="9.3.2" sectionFormat="of" target="RFC9110"/>) to a full lookup path, with the "category" and "identifier" components present.
A keyserver <bcp14>SHOULD</bcp14> respond with the same header fields that it would have responded with if a GET request had been made.</t>

</section>
<section anchor="identity-lookups"><name>v2 Identity Lookups</name>

<t>The format of User IDs in OpenPGP has historically been vaguely specified and loosely interpreted (see <xref target="I-D.dkg-openpgp-userid-conventions"/>).
A particular identity may therefore be represented by an arbitrary number of different User ID packets.
Implementers should bear in mind that end users will typically search for identities, and not specific representations of that identity.</t>

<t>For example, the User ID strings <spanx style="verb">Andrew Gallagher &lt;andrew@example.com&gt;</spanx> and <spanx style="verb">Andrew B. Gallagher (work email) &lt;andrew@example.com&gt;</spanx> are both representations of the underlying identity <spanx style="verb">andrew@example.com</spanx>.</t>

<t>v2 "certs/by-identity", "canonical" and "index" lookup requests <bcp14>MUST</bcp14> only return results if the "identifier" path component exactly matches one of the following:</t>

<t><list style="symbols">
  <t>The portion between angle brackets (<spanx style="verb">&lt;...&gt;</spanx>) in an email-address style User ID.</t>
  <t>The full text string in a non-email-address User ID.</t>
</list></t>

<t>A keyserver <bcp14>SHOULD</bcp14> parse an email-address style User ID defensively.
In particular, if there is more than one substring of a User ID that could reasonably be interpreted as an email address, then a keyserver <bcp14>SHOULD NOT</bcp14> return an identity match on either substring.</t>

<t>Text lookups <bcp14>SHOULD NOT</bcp14> be case sensitive.
DNS names are not case sensitive, therefore any identity that contains a DNS name (including email addresses) cannot be reliably located using case sensitive matching.
Since the interpretation of User IDs is application-specific, a client <bcp14>MUST</bcp14> check that any User IDs returned from a keyserver are correctly case matched for the intended application.</t>

</section>
<section anchor="lookup-examples"><name>Lookup Examples</name>

<t>Get all certificates containing the email address "dshaw@example.com":</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-identity/dshaw@example.com
]]></artwork></figure>

<t>Get certificate 0xCAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADA (v6 fingerprint):</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-vfingerprint/06cafedadacafedadacafedadacafedadacafedadacafedadacafedadacafedada
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBAD (64-bit Key ID):</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-keyid/DEADBEEFDECAFBAD
]]></artwork></figure>

</section>
</section>
<section anchor="v2-submission-format"><name>v2 Submission Format</name>

<t>A keyserver <bcp14>MAY</bcp14> accept submissions via an HTTP POST or PUT request, as specified in <xref section="8.3" sectionFormat="of" target="RFC1945"/>, and <xref section="8.2.3" sectionFormat="of" target="RFC1866"/>.</t>

<t>v2 submission requests include a "category" URL path component, and optionally an "identifier" path component.
These are appended to "/pks/v2" as follows:</t>

<figure><artwork><![CDATA[
POST /pks/v2/<category>
PUT /pks/v2/<category>/<identifier>
]]></artwork></figure>

<t>The "category" path component <bcp14>MUST</bcp14> be supplied.
In PUT submission requests, the "identifier" path component is required.
In POST submission requests, the "identifier" path component is omitted.</t>

<texttable title="v2 Submission Request Categories" anchor="v2-submission-request-categories">
      <ttcol align='left'>Category</ttcol>
      <ttcol align='left'>Method</ttcol>
      <ttcol align='left'>Input data</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">certs</spanx></c>
      <c>POST</c>
      <c>certificate bundle</c>
      <c>submission response</c>
      <c><xref target="certs-category"/></c>
      <c><spanx style="verb">sendtoken</spanx></c>
      <c>POST</c>
      <c>email address</c>
      <c>(none)</c>
      <c><xref target="sendtoken-category"/></c>
      <c><spanx style="verb">canonical</spanx></c>
      <c>PUT</c>
      <c>canonical bundle</c>
      <c>submission response</c>
      <c><xref target="canonical-submission-category"/></c>
</texttable>

<t>Unless otherwise specified, a keyserver <bcp14>SHOULD</bcp14> respond to v2 submissions with a JSON document as described in <xref target="submission-responses"/>.</t>

<t>If a keyserver does not support submission via HTTP, then requests to do so should return an appropriate HTTP error code, such as 403 ("Forbidden") if certificate submission has been disallowed, or 404 ("Not Found") if the server does not support the requested submission category.</t>

<section anchor="certs-category"><name>The v2 "certs" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs" submission category.</t>

<figure><artwork><![CDATA[
POST /pks/v2/certs
]]></artwork></figure>

<t>A keyserver that implements it <bcp14>SHOULD</bcp14> support the basic submission workflow described in <xref target="basic-submission"/>.
It <bcp14>MAY</bcp14> support other workflows; if so it <bcp14>SHOULD</bcp14> advertise them as described in <xref target="feature-detection"/>.</t>

<t>A keyserver <bcp14>MAY</bcp14> verify the request and reject any submissions that cannot be verified.
This verification <bcp14>SHOULD</bcp14> use a reliable means of authentication, such as login credentials or a Bearer token (<xref target="token-authentication"/>).</t>

</section>
<section anchor="sendtoken-category"><name>The v2 "sendtoken" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "sendtoken" submission category.</t>

<figure><artwork><![CDATA[
POST /pks/v2/sendtoken
]]></artwork></figure>

<t>The body of the POST request is a single email address.
It <bcp14>SHOULD</bcp14> have a content-type of "text/plain".
The keyserver <bcp14>SHOULD</bcp14> respond with an empty document.</t>

<t>A keyserver that supports the "sendtoken" request category <bcp14>SHOULD</bcp14> attempt to verify the email address by sending a time-limited Bearer token via email.
A client that receives the verification email can then use the token in a canonical submission request (<xref target="canonical-submission-category"/>).
A keyserver <bcp14>MAY</bcp14> limit the number and frequency of verification requests.</t>

<t>The verification email <bcp14>SHOULD</bcp14> contain a multipart/alternative message with two parts:</t>

<t><list style="symbols">
  <t>A JSON-LD structured mail document <xref target="I-D.ietf-sml-structured-email"></xref>.</t>
  <t>A human-readable document containing instructions for manual submission.</t>
</list></t>

<t>The schema for the JSON-LD document is (( TBC, issue #40 )), and it contains the following fields:</t>

<texttable title="Structured Mail Fields" anchor="structured-mail-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">email</spanx></c>
      <c>string</c>
      <c>email address being verified</c>
      <c><spanx style="verb">url</spanx></c>
      <c>string</c>
      <c>URL to be used for submission</c>
      <c><spanx style="verb">token</spanx></c>
      <c>string</c>
      <c>verification token</c>
      <c><spanx style="verb">expires</spanx></c>
      <c>timestamp</c>
      <c>expiry time of the token</c>
</texttable>

<t>Timestamps are given in UTC as per <xref section="5.6" sectionFormat="of" target="RFC3339"/>.</t>

<t>(( TBC: this follows a prove-then-submit model, which is the inverse of KOO's current submit-then-prove process.
The rationale is that submit-then-prove often silently degrades to "submit-then-forget-to-prove".
Failed advance proofs are less likely to be mis-reported as a success.
In addition, prove-then-submit more easily generalises to other forms of verification.
Is this defensible?
issue #41 ))</t>

</section>
<section anchor="canonical-submission-category"><name>The v2 "canonical" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "canonical" submission category.</t>

<figure><artwork><![CDATA[
PUT /pks/v2/canonical/<identifier>
]]></artwork></figure>

<t>The request path is the same as the one used for the "canonical" lookup category (<xref target="canonical-lookup-category"/>).</t>

<t>A keyserver that implements it <bcp14>SHOULD</bcp14> support the basic submission workflow described in <xref target="basic-submission"/>.
It <bcp14>MAY</bcp14> support other workflows; if so it <bcp14>SHOULD</bcp14> advertise them as described in <xref target="feature-detection"/>.</t>

<t>This instructs the server that for the identity (<xref target="identity-lookups"/>) supplied in the request path:</t>

<t><list style="symbols">
  <t>The certificates contained in the submission that have the corresponding identity are regarded by the owner as canonical for that identity,</t>
  <t>The owner wishes for these certificates to be served in the same order and format that they appear in the submission, and:</t>
  <t>Any certificates for that identity that are not contained in the submission are not (or no longer) canonical for that identity.</t>
</list></t>

<t>A keyserver <bcp14>MUST</bcp14> verify the request and reject any submissions that cannot be verified.
This verification <bcp14>SHOULD</bcp14> use a reliable means of authentication, such as login credentials or a Bearer token (<xref target="token-authentication"/>).
Once the keyserver verifies the submission, it stores the resulting canonical bundle (<xref target="canonical-bundles"/>) and updates any internal confidence values as necessary (<xref target="confidence"/>).</t>

</section>
<section anchor="basic-submission"><name>Basic Submission</name>

<t>Basic submission uses a content-type of "application/pgp-keys;armor=no" (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>).
The body of the POST or PUT request contains a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<section anchor="token-authentication"><name>Token Authentication</name>

<t>When using token authentication with a basic submission workflow, the client adds an Authentication request header containing a Bearer token obtained via a "sendtoken" request (<xref target="sendtoken-category"/>).</t>

<figure><artwork><![CDATA[
Authentication: Bearer <token>
]]></artwork></figure>

<t>This token <bcp14>MUST</bcp14> correspond to one of the identities present in the canonical bundle being submitted.
A client <bcp14>SHOULD</bcp14> remove any User IDs not related to the token.
A keyserver <bcp14>MAY</bcp14> reject a canonical bundle that contains User IDs not related to the token.</t>

</section>
</section>
<section anchor="advanced-submission"><name>Advanced Submission</name>

<t>Advanced submission uses a content-type of "multipart/form-data".
The body of the POST or PUT request contains a multipart with one or more parts.
The required part has a content-type of "application/pgp-keys;armor=no" (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>) and <bcp14>MUST</bcp14> be named "keytext".
This part contains a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<t>Other parts <bcp14>MAY</bcp14> be included as required by an advanced submission workflow.
No advanced submission workflows are currently specified.</t>

</section>
<section anchor="feature-detection"><name>Submission Feature Detection Using OPTIONS</name>

<t>A client <bcp14>MAY</bcp14> attempt to detect which certificate submission workflows a keyserver supports by making an OPTIONS request (<xref section="9.3.7" sectionFormat="of" target="RFC9110"/>) to a submission path with the "category" path component present but the "identifier" path component absent.
A keyserver that supports v2 submission <bcp14>SHOULD</bcp14> respond with:</t>

<t><list style="symbols">
  <t>a 200 code,</t>
  <t>an "Allow:" response header that includes the value "POST" (<xref section="10.2.1" sectionFormat="of" target="RFC9110"/>),</t>
  <t>one or more "Accept:" response header(s) (<xref section="12.5.1" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<t><spanx style="verb">Accept</spanx> response media types <bcp14>MAY</bcp14> include:</t>

<t><list style="symbols">
  <t><spanx style="verb">application/pgp-keys</spanx> - basic submission without proof</t>
  <t><spanx style="verb">application/pgp-keys;proof=tokens</spanx> - basic submission with token proof</t>
  <t><spanx style="verb">multipart/form-data;proof=dkim</spanx> - advanced submission with DKIM proof (EXPERIMENTAL)</t>
</list></t>

<t>(( TODO: check the requirements for CORS preflight, issue #38 ))</t>

</section>
<section anchor="canonical-bundles"><name>Canonical Bundles</name>

<t>A certificate bundle submitted or returned via a "canonical" request is called a "canonical bundle".
A canonical bundle represents both the list of certificates that the key holder wishes to be associated with an identity, and their preferred form of those certificates.
A keyserver <bcp14>SHOULD</bcp14> serve only canonical bundles in response to a "canonical" lookup request.
A keyserver <bcp14>MAY</bcp14> serve full copies of the matching certificate(s) in response to a "certs" lookup request.
For example, a full copy may include valid certificate components obtained by non-canonical submission, but not present in the canonical bundle.</t>

<t>When submitting a canonical bundle, any new certificate components <bcp14>SHOULD</bcp14> be merged into the full copy of the corresponding certificate, if the keyserver supports it.
Any valid key or self-certification revocations known to the keyserver <bcp14>SHOULD</bcp14> be merged into the corresponding canonical bundle(s), if any.
This applies both to revocations already present in the key store, and to those submitted at any later date.
A keyserver <bcp14>SHOULD NOT</bcp14> modify a canonical bundle in any other way.</t>

<t>A keyserver that accepts submissions <bcp14>MUST</bcp14> allow a valid key revocation certificate for any key to be submitted without identity verification.
A valid key revocation signature <bcp14>SHOULD</bcp14> be applied to all copies of the key that it revokes, and <bcp14>SHOULD</bcp14> be served in response to all requests for that key.
An implementation <bcp14>MAY</bcp14> however omit some revocations for brevity - for example, if two valid revocations exist with different timestamps but otherwise identical effect, an implementation <bcp14>MAY</bcp14> serve the older revocation and omit the newer one.</t>

<t>Other methods such as <xref target="I-D.dkg-openpgp-1pa3pc"/> are more appropriate for controlling the form of certificates returned by non-canonical requests.</t>

</section>
<section anchor="submission-examples"><name>Submission Examples</name>

<t>(( TODO: issue #39 ))</t>

</section>
</section>
</section>
<section anchor="legacy-api"><name>The Legacy API</name>

<t>For backwards compatibility with the existing installed client base, a Legacy API is defined.
New implementations <bcp14>SHOULD</bcp14> use the v2 API.</t>

<section anchor="legacy-lookups"><name>Legacy Lookup Format</name>

<t>Legacy certificate lookups are done via an HTTP GET request.
Specifically, the abs_path (<xref section="3.2" sectionFormat="of" target="RFC1945"/>) is built up of the base path "/pks/lookup", followed by a request-specific query string (<xref section="8.2.2" sectionFormat="of" target="RFC1866"/>).
No URL path components under "/pks/lookup" are used.</t>

<t>Most Legacy lookups contain both the "op" (operation) and "search" variables.
These roughly correspond to the "category" and "identifier" components of the v2 API, but with subtly different semantics.
The "op" variable determines what operation the keyserver will execute, and the "search" variable determines which certificates are operated on.</t>

<t>The "op" and "search" variables are supplied as HTTP query strings, in the form "&lt;variable-name&gt;=&lt;value&gt;":</t>

<figure><artwork><![CDATA[
/pks/lookup?op=<op>&search=<search>[&...]
]]></artwork></figure>

<t>The "op" variable <bcp14>MUST</bcp14> be supplied, and the "search" variable <bcp14>MUST</bcp14> be supplied unless the "stats" operation is being requested (<xref target="stats-operation"/>).</t>

<t>There may also be modifier variables, as specified in <xref target="legacy-modifier-variables"/> below.
Keyservers <bcp14>MUST</bcp14> ignore any unknown query string parameters.</t>

<section anchor="operation-lookup-variable"><name>The "op" (Operation) Lookup Variable</name>

<t>The "op" (operation) variable specifies the lookup operation to be performed on the keyserver.
The "op" variable is generally accompanied by a "search" variable to specify the certificates that should be looked up.</t>

<t>If a particular operation is not supported, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 501 ("Not Implemented").
The server <bcp14>SHOULD NOT</bcp14> return an error code (such as 404 ("Not Found")) that could be interpreted by the client as an explicit statement of non-existence.</t>

<texttable title="Legacy Lookup Operations" anchor="legacy-lookup-operations">
      <ttcol align='left'>Operation</ttcol>
      <ttcol align='left'>Search format</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">get</spanx></c>
      <c>text</c>
      <c>Certificate bundle</c>
      <c><xref target="get-operation"/></c>
      <c><spanx style="verb">hget</spanx></c>
      <c>SKS hash</c>
      <c>Certificate bundle</c>
      <c><xref target="hget-operation"/></c>
      <c><spanx style="verb">index</spanx></c>
      <c>text</c>
      <c>Index of certificates</c>
      <c><xref target="index-operation"/></c>
      <c><spanx style="verb">vindex</spanx></c>
      <c>text</c>
      <c>Index of certificates</c>
      <c><xref target="vindex-operation"/></c>
      <c><spanx style="verb">stats</spanx></c>
      <c>(none)</c>
      <c>Implementation info</c>
      <c><xref target="stats-operation"/></c>
</texttable>

</section>
<section anchor="get-operation"><name>The "get" Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "get" operation.</t>

<t>The "get" operation requests certificates from the keyserver by textual search.
A string that specifies which certificate(s) to return is provided in the "search" variable.</t>

<t>The response to a successful "get" operation is an ASCII-armored certificate bundle as specified in <xref target="certificate-bundle-format"/>.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned certificate bundle to a reasonable length.
Results from a User ID search <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for has a nonzero confidence value.
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="hget-operation"><name>The "hget" (hash get) Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "hget" operation.</t>

<t>"hget" requests a certificate from a keyserver by specifying its <xref target="SKS"></xref> digest.
The digest is provided in the "search" variable in hexadecimal encoding, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="index-operation"><name>The "index" Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "index" operation.</t>

<t>The "index" operation requests a list of certificates on the keyserver that match the text in the "search" variable.
Historically, the "index" operation returned a human-readable HTML document containing links for each found certificate, but this is not required.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned index to a reasonable length.
Results from a User ID search <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="vindex-operation"><name>The "vindex" (verbose index) Operation (Deprecated)</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "vindex" operation.
The "vindex" operation is deprecated.
Historically, a "vindex" response was the same as "index" with the addition of showing the signatures on each certificate, but this is not required.
A server that supports "vindex" <bcp14>SHOULD</bcp14> treat it as a synonym for "index".</t>

</section>
<section anchor="stats-operation"><name>The "stats" (statistics/status) Operation (Deprecated)</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "stats" operation.
The "stats" operation is deprecated.
It is <bcp14>RECOMMENDED</bcp14> to use a URL outside the standard HKP paths (such as "/pks/stats") instead.</t>

<t>The output of the "stats" operation is implementation-dependent, but may include diagnostic output, configuration state, or other metadata.
The "search" variable <bcp14>SHOULD NOT</bcp14> be supplied, and <bcp14>SHOULD</bcp14> be ignored if received.</t>

</section>
<section anchor="search-lookup-variable"><name>The "search" Lookup Variable</name>

<t>The "search" variable contains arbitrary text encoded as usual for a HTTP URL.
This text may represent a Key ID, or fingerprint, or some text from a User ID on the certificate being sought, depending on the operation.</t>

<section anchor="legacy-searches"><name>Legacy Key ID and Fingerprint Searches</name>

<t>To search for a certificate by the Key ID or fingerprint of a primary key or subkey, a client <bcp14>SHOULD</bcp14> use a v2 lookup and either the "certs/by-keyid" (<xref target="keyid-category"/>) or "certs/by-vfingerprint" (<xref target="vfingerprint-category"/>) lookup category (as appropriate).</t>

<t>If making a Legacy lookup, a client <bcp14>SHOULD</bcp14> use the "get" operation and prefix the "search" string with "0x" to indicate a hexadecimal number.
Key ID strings are 16 hexadecimal digits (64 bits).
Fingerprint strings are either 32 (version 3), 40 (version 4), or 64 (version 6) hexadecimal digits and do not include the version number.
The hexadecimal digits are not case sensitive.</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> accept fingerprints and <bcp14>MAY</bcp14> accept 64-bit Key IDs in the Legacy lookup "search" variable.</t>
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey fingerprints and Key IDs.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
  <t><bcp14>MUST NOT</bcp14> return results for 32-bit "short Key ID" searches, as these do not provide sufficient collision resistance.</t>
  <t><bcp14>MUST NOT</bcp14> return certificates with versions later than 4 for Key ID searches.</t>
  <t><bcp14>MUST NOT</bcp14> return version 6 (or later) certificates in the results for Legacy machine-readable requests, but <bcp14>MAY</bcp14> do so for Legacy human-readable requests (<xref target="legacy-mr-output"/>).</t>
</list></t>

<t>V3 certificates are no longer considered secure, but <bcp14>MAY</bcp14> be distributed for historical reference.</t>

</section>
<section anchor="legacy-text-searches"><name>Legacy Text Searches</name>

<t>To perform a Legacy search for a certificate by the text of a User ID, a client <bcp14>SHOULD</bcp14> use the "get" or "index" operation (as appropriate) and <bcp14>MUST NOT</bcp14> prefix the "search" string with "0x".
A keyserver <bcp14>MUST NOT</bcp14> return version 6 (or later) certificates in the results for Legacy machine-readable requests, but <bcp14>MAY</bcp14> do so for Legacy human-readable requests (<xref target="legacy-mr-indexes"/>).</t>

<t>Legacy text searches <bcp14>SHOULD</bcp14> only return results if the "search" variable exactly matches one of the following:</t>

<t><list style="symbols">
  <t>The full text string of a User ID.</t>
  <t>The portion between angle brackets ("&lt;...&gt;") in an email-address style User ID.</t>
</list></t>

<t>Text searches <bcp14>SHOULD NOT</bcp14> be case sensitive.
DNS names are not case sensitive, therefore any User ID that contains a DNS name (including email addresses) cannot be reliably located using case sensitive matching.
Since the interpretation of User IDs is application-specific, a client <bcp14>MUST</bcp14> check that any User IDs returned from a keyserver are correctly case matched for the intended application.</t>

<t>A client making a Legacy text search <bcp14>SHOULD</bcp14> set the modifier variable "exact=on" (<xref target="exact-variable"/>).</t>

<t>To ensure that relevant results are returned, it is <bcp14>RECOMMENDED</bcp14> that implementations limit themselves to a subset of UTF-8 when generating both User IDs and search strings:</t>

<t><list style="symbols">
  <t>Canonicalise to Unicode Normalization Form C <xref target="UNF"></xref>.</t>
  <t>Do not use punycode <xref target="RFC3492"></xref>.</t>
  <t>Use lowercase in the domain part of email addresses.</t>
  <t>Avoid leading or trailing whitespace.</t>
  <t>Avoid control characters, including format effectors (such as tabs or newlines).</t>
</list></t>

<t>A keyserver <bcp14>MUST NOT</bcp14> return legacy text search results for a search string that begins with "0x".
Since the "0x" prefix is generally understood as indicating a fingerprint or key ID, violating this convention could enable a key substitution attack.</t>

</section>
</section>
<section anchor="legacy-lookup-examples"><name>Legacy Lookup Examples</name>

<t>Search for all certificates containing the email address "dshaw@example.com", using plaintext HTTP:</t>

<figure><artwork><![CDATA[
http://keys.example.com:11371/pks/lookup?search=dshaw@example.com&op=index
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBADDEADBEEFDECAFBADDEADBEEFDECAFBAD (v4 fingerprint), using HTTPS:</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/lookup?op=get&search=0xDEADBEEFDECAFBADDEADBEEFDECAFBADDEADBEEFDECAFBAD
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBAD (64-bit Key ID), using HTTPS:</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/lookup?op=get&search=0xDEADBEEFDECAFBAD
]]></artwork></figure>

</section>
</section>
<section anchor="legacy-submission"><name>Legacy Submission Format</name>

<t>The abs_path (<xref section="3.2" sectionFormat="of" target="RFC1945"/>) for certificate submission is always "/pks/add" in the Legacy API.</t>

<t>No URL path components under "/pks/add" are used, and there are no mandatory query strings.</t>

<t>The body of the POST message has a content-type of "application/x-www-form-urlencoded".
It contains a "keytext" field whose value is an ASCII-armored certificate bundle as specified in <xref target="certificate-bundle-format"/>.
The ASCII armored certificate bundle should also be urlencoded as specified in <xref section="8.2.1" sectionFormat="of" target="RFC1866"/>.</t>

<t>There may also be modifier variables, as specified in <xref target="legacy-modifier-variables"/> below.
Modifiers are passed using HTTP query strings as specified in <xref section="8.2.2" sectionFormat="of" target="RFC1866"/>.
HTTP query strings <bcp14>MAY</bcp14> be given in any order.
Keyservers <bcp14>MUST</bcp14> ignore any unknown query strings.</t>

<t>Note that more than one certificate may be submitted in a single transaction.</t>

<t>If a keyserver does not support adding certificates via HTTP, then requests to do so should return an appropriate HTTP error code, such as 403 ("Forbidden") if certificate submission has been disallowed, or 404 ("Not Found") if the server does not support the legacy submission API.</t>

</section>
<section anchor="legacy-modifier-variables"><name>Legacy Modifier Variables</name>

<t>These variables are used to modify basic Legacy requests.</t>

<texttable title="Legacy Variable Names" anchor="legacy-variable-names">
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Context</ttcol>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>See</ttcol>
      <c>options</c>
      <c>any</c>
      <c>list of flags</c>
      <c><xref target="options-variable"/></c>
      <c>fingerprint</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="fingerprint-variable"/></c>
      <c>hash</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="hash-variable"/></c>
      <c>exact</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="exact-variable"/></c>
</texttable>

<section anchor="options-variable"><name>The "options" Variable</name>

<t>This variable takes one or more option values, separated by commas.
These are used to modify the behavior of the keyserver on a per-request basis.
Each value indicates a boolean flag, where the presence of the value indicates "true" and the absence "false".</t>

<texttable title="Legacy Option Values" anchor="legacy-option-values">
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Context</ttcol>
      <ttcol align='left'>See</ttcol>
      <c>nm</c>
      <c>submission</c>
      <c><xref target="nm-option"/></c>
      <c>mr</c>
      <c>lookup</c>
      <c><xref target="mr-option"/></c>
</texttable>

<section anchor="nm-option"><name>The "nm" (No Modification) Option</name>

<t>As keyservers may modify submitted certificates to suit a particular policy, this option is used to inform the keyserver that the submitter would rather have the submission fail completely than have the submitted certificate(s) modified.
An example of this would be a keyserver that does not accept User IDs with an email address outside of the local domain.
If such a certificate was submitted, the keyserver <bcp14>MAY</bcp14> trim any noncompliant User IDs before accepting the certificate.
If this option was set, then such a certificate submission <bcp14>SHOULD</bcp14> fail with an appropriate error code such as 422 (Unprocessable content).</t>

<t>"nm" is meaningful for submissions only.</t>

</section>
<section anchor="mr-option"><name>The "mr" (Machine-Readable) Option</name>

<t>The machine-readable option instructs the server that a program (rather than a person) is making a Legacy request, so the output <bcp14>SHOULD</bcp14> be in Legacy machine-readable format.
If a v2 request format is being used, this option has no effect.
See <xref target="legacy-mr-output"/> for the specific details of Legacy machine-readable output.</t>

<t>An implementation that does not wish to provide a human-readable interface <bcp14>MAY</bcp14> choose to behave as if this option is always present.
Implementations <bcp14>SHOULD NOT</bcp14> provide a Legacy interface without supporting machine-readable output.</t>

<t>"mr" is meaningful for Legacy lookups only.</t>

</section>
</section>
<section anchor="fingerprint-variable"><name>The "fingerprint" Variable</name>

<t>This variable takes one argument: "on" or "off".
If present and on, it instructs the server to provide the primary key fingerprint for each certificate in a Legacy "index" or "vindex" operation.
This variable has no effect on any other operation.
The exact format of the displayed fingerprint, like the "index" and "vindex" operations themselves, is implementation defined in Legacy human-readable output.
In Legacy machine-readable indexes, a value of "on" indicates that the "keyid" field <bcp14>SHOULD</bcp14> contain the fingerprint, except for v3 certificates (<xref target="legacy-mr-indexes"/>).
An implementation <bcp14>SHOULD</bcp14> treat this variable as being "on" for all Legacy machine-readable indexes.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable and/or set the default behaviour to "on" for Legacy human-readable indexes.</t>

<t>"fingerprint" is meaningful for Legacy lookups only.</t>

</section>
<section anchor="hash-variable"><name>The "hash" Variable</name>

<t>This variable takes one argument: "on" or "off".
If present and on, it instructs the server to provide the <xref target="SKS"></xref> digest of each certificate in an "index" or "vindex" operation in the Legacy human-readable output format.
This variable has no effect on any other operation, or on Legacy machine-readable output.
The exact format of the displayed digest, like the "index" and "vindex" operations themselves, is implementation defined.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable and/or set the default behaviour to "on".</t>

<t>"hash" is meaningful for Legacy lookups only.</t>

</section>
<section anchor="exact-variable"><name>The "exact" Variable</name>

<t>This variable takes one argument: "on" or "off".
If set to "off", it instructs the server that it <bcp14>MAY</bcp14> use non-exact matching for the contents of the "search" variable in text searches (<xref target="legacy-text-searches"/>).
How a keyserver handles non-exact text searches is implementation defined.
For example, a keyserver <bcp14>MAY</bcp14> use case-insensitive or tokenized searching.</t>

<t>A keyserver implementation <bcp14>SHOULD</bcp14> set the default behaviour to "on" and <bcp14>MAY</bcp14> ignore this variable.</t>

<t>"exact" is meaningful for Legacy lookups only.</t>

</section>
</section>
</section>
<section anchor="output-formats"><name>Output Formats</name>

<t>HKP was originally intended for both human and programmatic use.
In general, the Legacy human-readable output is implementation specific.
The "machine-readable" option is used to tailor the output of Legacy requests for automated use.
For interoperability, the Legacy machine-readable output <bcp14>MUST</bcp14> carefully follow the guidelines given here.
A client implementation <bcp14>SHOULD NOT</bcp14> attempt to parse Legacy human-readable output.</t>

<t>The v2 API always returns either non-armored certificate bundles or JSON <xref target="RFC8259"></xref>, depending on the request.</t>

<section anchor="v2-output-format"><name>v2 Output Format</name>

<t>Clients making v2 requests:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> silently ignore any primary keys with unknown versions or algorithms.</t>
  <t><bcp14>MUST</bcp14> silently ignore any unknown fields in JSON responses.</t>
</list></t>

<t>In response to a v2 request, a keyserver:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> set the HTTP header "Access-Control-Allow-Origin: *", as specified in <xref target="CORS"></xref>.</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="v2-indexes"/> when responding to "index" lookups.</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="submission-responses"/> when responding to "certs" submissions.</t>
  <t><bcp14>MUST</bcp14> return non-armored (binary) certificate bundles in response to lookup requests.</t>
  <t><bcp14>MUST</bcp14> set "Content-Type: application/json" for JSON responses.</t>
  <t><bcp14>MUST</bcp14> set "Content-Type: application/pgp-keys;armor=no" when returning non-armored certificate bundles (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>).</t>
  <t><bcp14>MAY</bcp14> set "Last-Modified:" to indicate the modification date of the requested certificate or certificate bundle (<xref section="8.8.2" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<section anchor="v2-indexes"><name>v2 Indexes</name>

<t>A v2 "index" request <bcp14>SHOULD</bcp14> return a JSON list of certificates.
If the search was for an identity, it <bcp14>SHOULD</bcp14> be sorted in decreasing order of confidence (<xref target="confidence"/>).
Each certificate object contains some or all of the following fields:</t>

<texttable title="v2 Index Fields" anchor="v2-index-certificate-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>integer</c>
      <c>version of the primary key (<bcp14>REQUIRED</bcp14>)</c>
      <c>fingerprint</c>
      <c>string</c>
      <c>fingerprint of the primary key (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of the key</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the key</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>algorithm</c>
      <c>algorithm</c>
      <c>(<xref target="v2-index-algorithm-fields"/>)</c>
      <c>userIDs</c>
      <c>userID array</c>
      <c>(<xref target="v2-index-userid-fields"/>)</c>
      <c>subkeys</c>
      <c>subkey array</c>
      <c>(<xref target="v2-index-subkey-fields"/>)</c>
</texttable>

<texttable title="v2 Index Algorithm Fields" anchor="v2-index-algorithm-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>code</c>
      <c>integer</c>
      <c>algorithm ID (<bcp14>REQUIRED</bcp14>)</c>
      <c>name</c>
      <c>string</c>
      <c>a human-readable identifier for the algorithm</c>
      <c>bitLength</c>
      <c>integer</c>
      <c>key length in bits (DSA/RSA/ElGamal keys only)</c>
</texttable>

<texttable title="v2 Index UserID Fields" anchor="v2-index-userid-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>uidString</c>
      <c>string</c>
      <c>User ID string contents (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of (the first signature over) the User ID</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the User ID</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>confidence</c>
      <c>integer</c>
      <c>(<xref target="confidence"/>)</c>
</texttable>

<texttable title="v2 Index Subkey Fields" anchor="v2-index-subkey-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>integer</c>
      <c>version of the subkey (<bcp14>REQUIRED</bcp14>)</c>
      <c>fingerprint</c>
      <c>string</c>
      <c>fingerprint of the subkey (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of the subkey</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the subkey</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>algorithm</c>
      <c>algorithm</c>
      <c>(<xref target="v2-index-algorithm-fields"/>)</c>
</texttable>

<t>Fingerprints are given in hexadecimal notation, without any "0x" prefix.
Timestamps are given in UTC as per <xref section="5.6" sectionFormat="of" target="RFC3339"/>.
Algorithm IDs are as specified in <xref section="9.1" sectionFormat="of" target="RFC9580"/>.</t>

<t>The only required fields are the version and fingerprint of any key material, and the uidString of any User IDs.
Implementations <bcp14>MAY</bcp14> omit algorithms, subkeys and User IDs from indexes; however if they are present they <bcp14>MUST</bcp14> contain the required fields.</t>

</section>
</section>
<section anchor="submission-responses"><name>v2 and Legacy Submission Responses</name>

<t>A v2 or Legacy submission <bcp14>MAY</bcp14> return an empty response, or it <bcp14>MAY</bcp14> return a JSON object summarising the changes.
The JSON object <bcp14>MAY</bcp14> contain any or all of the following fields, each of which is an array of certificate objects:</t>

<texttable title="Submission Response Fields" anchor="submission-response-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>inserted</c>
      <c>certificate array</c>
      <c>newly added certificates</c>
      <c>updated</c>
      <c>certificate array</c>
      <c>updated certificates</c>
      <c>deleted</c>
      <c>certificate array</c>
      <c>deleted certificates</c>
      <c>ignored</c>
      <c>certificate array</c>
      <c>certificates with no new information</c>
      <c>invalid</c>
      <c>certificate array</c>
      <c>certificates that could not be processed</c>
</texttable>

<t>Each certificate object <bcp14>MUST</bcp14> contain "version" and "fingerprint" fields, as in <xref target="v2-index-certificate-fields"/>.</t>

<t>Certificates in the "ignored" and "invalid" arrays <bcp14>MAY</bcp14> also contain a "comment" field describing the reason for their rejection.
The comment is a human-readable string, and <bcp14>MAY</bcp14> be displayed to the user.</t>

</section>
<section anchor="legacy-mr-output"><name>Legacy machine-readable Output</name>

<t>Clients requesting machine-readable output in Legacy lookup requests:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> supply "options=mr" (<xref target="mr-option"/>).</t>
  <t><bcp14>MUST</bcp14> silently ignore any content preceding or following a returned armored key block.</t>
  <t><bcp14>MUST</bcp14> silently ignore any primary keys with unknown versions or algorithms.</t>
</list></t>

<t>Keyservers returning Legacy machine-readable output:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> set the HTTP header "Access-Control-Allow-Origin: *", as specified in <xref target="CORS"></xref>.</t>
  <t><bcp14>MUST</bcp14> return ASCII-armored certificate bundles.</t>
  <t><bcp14>MUST NOT</bcp14> return version 6 (or later) certificates.</t>
  <t><bcp14>MUST</bcp14> set "Content-Type: application/pgp-keys" when returning ASCII-armored certificate bundles (the "get" and "hget" operations), as specified in <xref section="7" sectionFormat="of" target="RFC3156"/>.</t>
  <t><bcp14>MAY</bcp14> set "Last-Modified:" to indicate the modification date of the requested certificate or certificate bundle (<xref section="8.8.2" sectionFormat="of" target="RFC9110"/>).</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="legacy-mr-indexes"/> when returning indexes (the "index" and "vindex" operations).</t>
  <t><bcp14>MAY</bcp14> return statistics in JSON format <xref target="RFC8259"></xref>, the schema of which is otherwise implementation-dependent.</t>
</list></t>

<t>ASCII-armored responses <bcp14>MAY</bcp14> be wrapped in any HTML or other text desired, except that the actual certificate data consisting of an initial line break, the "-----BEGIN PGP PUBLIC KEY BLOCK-----" header, the armored certificate data itself, the "-----END PGP PUBLIC KEY BLOCK-----" footer, and a final line break <bcp14>MUST NOT</bcp14> be modified from the form specified in <xref target="RFC9580"></xref>.</t>

<section anchor="legacy-mr-indexes"><name>Legacy machine-readable Indexes</name>

<t>The Legacy machine-readable index format is a list of newline-separated records, consisting of colon-separated fields.
The document is 7-bit clean, and as such is sent with no encoding and Content-Type: text/plain.</t>

<t>The machine-readable response <bcp14>MAY</bcp14> be prefixed by an information record:</t>

<figure><artwork><![CDATA[
info:<version>:<count>
]]></artwork></figure>

<texttable title="Legacy Information Record Fields" anchor="legacy-information-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>the version of this output format</c>
      <c>count</c>
      <c>the number of certificates returned</c>
</texttable>

<t>If this line is not included, or the version information is not supplied, the version number is assumed to be 1.
Currently, only version 1 is defined.</t>

<t>Note that "count" is the number of certificates, and not the number of lines returned.
That is, it <bcp14>SHOULD</bcp14> match the number of "pub:" lines returned.</t>

<t>The certificate listings themselves are made up of several records per certificate.
The first record specifies the primary key:</t>

<figure><artwork><![CDATA[
pub:<keyID>:<code>:<bitLength>:<creation>:<expiration>:<flags>
]]></artwork></figure>

<texttable title="Legacy Public Key Record Fields" anchor="legacy-public-key-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>keyID</c>
      <c>fingerprint or long Key ID</c>
      <c>code</c>
      <c>algorithm ID</c>
      <c>bitLength</c>
      <c>key length in bits</c>
      <c>creation</c>
      <c>creation date of the key</c>
      <c>expiration</c>
      <c>expiration date of the key</c>
      <c>flags</c>
      <c>letter codes to indicate details of the key</c>
</texttable>

<t>Since it is not possible to calculate the Key ID from a V3 fingerprint, for V3 primary keys the "keyID" field <bcp14>SHOULD</bcp14> contain the 16-digit long Key ID only.
Otherwise, a keyserver <bcp14>SHOULD</bcp14> return a fingerprint if available (<xref target="fingerprint-variable"/>).</t>

<t>Fingerprints and long Key IDs are given in hexadecimal notation, without any "0x" prefix.
Timestamps are given in seconds since midnight on 1st January 1970.
Algorithm IDs are as specified in <xref section="9.1" sectionFormat="of" target="RFC9580"/>.</t>

<t>Following the "pub" record are one or more "uid" records to indicate User IDs on the certificate:</t>

<figure><artwork><![CDATA[
uid:<uidString>:<creation>:<expiration>:<flags>
]]></artwork></figure>

<texttable title="Legacy User ID Record Fields" anchor="legacy-index-userid-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>uidString</c>
      <c>User ID string contents</c>
      <c>creation</c>
      <c>creation date of (the first self-signature over) the User ID</c>
      <c>expiration</c>
      <c>expiration date of the User ID</c>
      <c>flags</c>
      <c>letter codes to indicate details of the User ID</c>
</texttable>

<t>The User ID string <bcp14>MUST</bcp14> use urlencoding for anything that isn't 7-bit safe as well as for the ":" and "%" characters.
Any other characters <bcp14>MAY</bcp14> be urlencoded, as desired.</t>

<t>The information for the "creation", "expiration", and "flags" fields is taken from the User ID self-signature, if any, and applies to the User ID in question, not to the certificate as a whole.</t>

<t>Primary key and User ID records may contain a "flags" field containing a sequence of alphabetical characters, one per flag.
Flags <bcp14>MAY</bcp14> be given in any order.
The meaning of "disabled" is implementation-specific.
Note that individual flags may be unimplemented, so the absence of a given flag does not necessarily mean the absence of the detail.</t>

<texttable title="Legacy Record Flags" anchor="legacy-record-flags">
      <ttcol align='left'>Flag</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">r</spanx></c>
      <c>revoked</c>
      <c><spanx style="verb">d</spanx></c>
      <c>disabled</c>
      <c><spanx style="verb">e</spanx></c>
      <c>expired</c>
</texttable>

<t>Note that empty fields are allowed.
For example, a primary key with no expiration date would have the "expirationdate" field empty.
Also, a keyserver that does not track a particular piece of information may leave that field empty as well.
Colons for empty fields on the end of each line <bcp14>MAY</bcp14> be left off, if desired.
All dates are given in the number of seconds since 1970-01-01T00:00:00 UTC.</t>

<t>For backwards compatibility with the installed client base, Legacy machine-readable lookup requests <bcp14>MUST</bcp14> omit version 6 (and later) certificates from the returned indexes.</t>

</section>
</section>
</section>
<section anchor="confidence"><name>Confidence</name>

<t>Traditionally, keyservers did not perform any checks against uploaded content other than simple parseability.
This left them open to abuse such as flooding and third-party signature spam.
Most modern keyservers are now able to perform cryptographic validity tests, and automated content moderation is generally possible.</t>

<t>It is <bcp14>RECOMMENDED</bcp14> that a keyserver assigns a "confidence" value to each User ID in its database.
The exact definition of "confidence" is implementation-dependent, but <bcp14>MAY</bcp14> include checks such as email verification or third-party certifications.</t>

<t>A keyserver <bcp14>MAY</bcp14> represent confidence as a number between 0 and 255, where values of 120 or greater indicate "complete confidence", in a v2 Index User ID object (<xref target="v2-index-userid-fields"/>).
This is numerically compatible with the "trust amount" field specified in <xref section="5.2.3.21" sectionFormat="of" target="RFC9580"/>, but it is not required to calculate it in the same way or represent it internally as an integer value.
The confidence field in a v2 Index User ID object is intended as a heuristic for sorting and filtering responses to lookup requests, and is not a replacement for cryptographic verification.
A client <bcp14>SHOULD NOT</bcp14> rely on this confidence field, and <bcp14>SHOULD</bcp14> perform its own checks.
A keyserver that wishes to publish a cryptographically-verifiable statement about its internal confidence value <bcp14>MAY</bcp14> do so using a certification signature.</t>

</section>
<section anchor="certificate-bundle-format"><name>Certificate Bundle Format</name>

<t>HKP uses a "certificate bundle" as its primary data representation for both input and output.</t>

<t>A certificate bundle is a sequence of one or more OpenPGP certificates (Transferable Public Keys), concatenated directly, as specified in Sections <xref target="RFC9580" section="10.1" sectionFormat="bare"/> and <xref target="RFC9580" section="3.6" sectionFormat="bare"/> of <xref target="RFC9580"/>.
An ASCII-armored certificate bundle is a certificate bundle that has been encoded as a single armored block, as specified in <xref section="6.2" sectionFormat="of" target="RFC9580"/>.
The Legacy API uses ASCII-armored certificate bundles exclusively, whereas the v2 API uses non-armored certificate bundles exclusively.</t>

<t>Certificate bundles are often called "keyrings", however the term "keyring" is used to refer to several related but distinct concepts:</t>

<t><list style="symbols">
  <t>A sequence of one or more Transferable Public Keys ("public keyring")</t>
  <t>A sequence of one or more Transferable Secret Keys ("private/secret keyring")</t>
  <t>A sequence of packets forming a single Transferable Public Key</t>
  <t>A sequence of packets forming a single Transferable Secret Key</t>
</list></t>

<t>It is therefore <bcp14>RECOMMENDED</bcp14> that implementations avoid using the term "keyring" without qualification.</t>

<section anchor="detached-revocations"><name>Detached Revocations</name>

<t>For OpenPGP certificates prior to version 6, revocation signatures have customarily been distributed as a detached "revocation certificate", as per <xref section="10.1.3" sectionFormat="of" target="RFC9580"/>.
An HKP server <bcp14>SHOULD</bcp14> allow submission of these detached revocations.</t>

<t>An HKP implementation <bcp14>MAY</bcp14> accept or serve an ASCII-armored "mixed certificate bundle" where one or more revoked certificates have been replaced by their detached revocation certificate(s).
Such a "mixed certificate bundle" <bcp14>MUST</bcp14> be sorted so that all detached revocation certificates appear first.
This ensures that detached revocations cannot be mistaken for signatures over another primary key.</t>

<t>Mixed certificate bundles <bcp14>MUST NOT</bcp14> be served in responses to v2 lookup requests.</t>

</section>
</section>
<section anchor="certificate-discovery-using-hkps"><name>Certificate Discovery Using HKPS</name>

<t>SRV records <xref target="RFC2782"></xref> are commonly used by clients to discover the location of internet services.
We can use the "openpgpkey" service name to locate an HKPS service for certificate discovery.
HKP clients <bcp14>SHOULD</bcp14> support SRV records.</t>

<section anchor="openpgpkey-srv-record"><name>The "openpgpkey" SRV Record</name>

<t>The service name for HKPS discovery is "openpgpkey", and the protocol name is "https".
The service and protocol labels are therefore "_openpgpkey" and "_https" respectively.
These are prepended to the domain part of the email addresses for which certificates are being published:</t>

<figure><artwork><![CDATA[
_openpgpkey._https.<domain-part>
]]></artwork></figure>

<t>A domain owner wishing to publish OpenPGP certificates for their users would create one or more SRV records at this location, each referencing the address and port number of a keyserver that is authoritative for that domain.
Each unique domain part for which email addresses are supported will have its own SRV records.</t>

</section>
<section anchor="discovery-lookup-over-hkps"><name>Discovery Lookup Over HKPS</name>

<t>When making an HKPS discovery request, a client <bcp14>SHOULD</bcp14> use an HTTP GET request to an authoritative keyserver using the "canonical" lookup category, with the email address in the "identifier" component.</t>

<t>Note that discovery is performed using the "canonical" lookup category, to ensure that the discovery results have been filtered.
The domain owner <bcp14>SHOULD</bcp14> take reasonable steps to ensure that any certificates returned from this lookup request are valid certificates for the identity in the "identifier" component.
Discovery <bcp14>MAY</bcp14> be implemented at low cost by serving such requests from a static filesystem.</t>

<t>It is <bcp14>RECOMMENDED</bcp14> that certificates returned from discovery are subject to further verification on the client side wherever possible, to mitigate against compromise of the discovery server.</t>

</section>
<section anchor="certificate-discovery-example"><name>Certificate Discovery Example</name>

<t>A client trying to locate a certificate for isabella@example.com makes a DNS request for the SRV record at <spanx style="verb">_openpgpkey._https.example.com.</spanx>.
This would return:</t>

<figure><artwork><![CDATA[
_openpgpkey._https.example.com. 3600 IN SRV 1 1 443 keyserver.example.com
]]></artwork></figure>

<t>On finding this record, the client makes an HTTP GET request for the following URL:</t>

<figure><artwork><![CDATA[
hkps://keyserver.example.com:443/pks/v2/canonical/isabella@example.com
]]></artwork></figure>

<t>The keyserver returns the canonical bundle for isabella@example.com, and the client proceeds to check its validity according to the local policy.</t>

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

<t>As described here, a keyserver is a searchable database of OpenPGP Certificates accessed over the network.
While there may be security considerations arising from distributing arbitrary certificates in this manner, this does not impact the security of OpenPGP itself.</t>

<t>Without some sort of trust relationship between the client and server, information returned from a keyserver in arbitrary search results cannot be trusted by the client until the OpenPGP client actually retrieves and checks the certificate for itself.
This is important and must be stressed: without a specific reason to treat information otherwise, all search results <bcp14>SHOULD</bcp14> be regarded as untrustworthy and informational only.</t>

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

<t>This document allocates the ports 11371 and 11372, the service names "hkps" and "openpgpkey", and the URI schemes "hkp" and "hkps".</t>

<section anchor="updated-registry-entries"><name>Updated Registry Entries</name>

<t>IANA is requested to update the contact details for port 11371 in the "Service Name and Transport Protocol Port Number" registry to "Daphne Shaw".</t>

</section>
<section anchor="new-registry-entries"><name>New Registry Entries</name>

<t>IANA is requested to add the following entries to the "Service Name and Transport Protocol Port Number" registry as per <xref target="RFC6335"></xref>:</t>

<texttable title="Service Name and Transport Protocol Port Number Registry" anchor="service-name-port-registry">
      <ttcol align='left'>Service Name</ttcol>
      <ttcol align='left'>Port</ttcol>
      <ttcol align='left'>Transport Protocol</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Contact</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>hkps</c>
      <c>11372</c>
      <c>tcp and udp</c>
      <c>OpenPGP HTTP Keyserver (Secure)</c>
      <c>Daphne Shaw</c>
      <c>This document</c>
      <c>openpgpkey</c>
      <c>&#160;</c>
      <c>&#160;</c>
      <c>OpenPGP Certificate Discovery</c>
      <c>Daphne Shaw</c>
      <c>This document</c>
</texttable>

<t>IANA is requested to add the following entries to the "URI Schemes" registry as per <xref target="RFC7595"></xref>:</t>

<texttable title="Uniform Resource Identifier (URI) Schemes Registry" anchor="uri-schemes-registry">
      <ttcol align='left'>URI Scheme</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Status</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>hkp</c>
      <c>OpenPGP HTTP Keyserver</c>
      <c>Permanent</c>
      <c>This document</c>
      <c>hkps</c>
      <c>OpenPGP HTTP Keyserver (Secure)</c>
      <c>Permanent</c>
      <c>This document</c>
</texttable>

</section>
</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="RFC1945">
  <front>
    <title>Hypertext Transfer Protocol -- HTTP/1.0</title>
    <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
    <author fullname="R. Fielding" initials="R." surname="Fielding"/>
    <author fullname="H. Frystyk" initials="H." surname="Frystyk"/>
    <date month="May" year="1996"/>
    <abstract>
      <t>The Hypertext Transfer Protocol (HTTP) is an application-level protocol with the lightness and speed necessary for distributed, collaborative, hypermedia information systems. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="1945"/>
  <seriesInfo name="DOI" value="10.17487/RFC1945"/>
</reference>
<reference anchor="RFC1866">
  <front>
    <title>Hypertext Markup Language - 2.0</title>
    <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
    <author fullname="D. Connolly" initials="D." surname="Connolly"/>
    <date month="November" year="1995"/>
    <abstract>
      <t>This document defines a HTML 2.0 (to distinguish it from the previous informal specifications). [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="1866"/>
  <seriesInfo name="DOI" value="10.17487/RFC1866"/>
</reference>
<reference anchor="RFC2782">
  <front>
    <title>A DNS RR for specifying the location of services (DNS SRV)</title>
    <author fullname="A. Gulbrandsen" initials="A." surname="Gulbrandsen"/>
    <author fullname="P. Vixie" initials="P." surname="Vixie"/>
    <author fullname="L. Esibov" initials="L." surname="Esibov"/>
    <date month="February" year="2000"/>
    <abstract>
      <t>This document describes a DNS RR which specifies the location of the server(s) for a specific protocol and domain. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="2782"/>
  <seriesInfo name="DOI" value="10.17487/RFC2782"/>
</reference>
<reference anchor="RFC3156">
  <front>
    <title>MIME Security with OpenPGP</title>
    <author fullname="M. Elkins" initials="M." surname="Elkins"/>
    <author fullname="D. Del Torto" initials="D." surname="Del Torto"/>
    <author fullname="R. Levien" initials="R." surname="Levien"/>
    <author fullname="T. Roessler" initials="T." surname="Roessler"/>
    <date month="August" year="2001"/>
    <abstract>
      <t>This document describes how the OpenPGP Message Format can be used to provide privacy and authentication using the Multipurpose Internet Mail Extensions (MIME) security content types described in RFC 1847. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3156"/>
  <seriesInfo name="DOI" value="10.17487/RFC3156"/>
</reference>
<reference anchor="RFC3339">
  <front>
    <title>Date and Time on the Internet: Timestamps</title>
    <author fullname="G. Klyne" initials="G." surname="Klyne"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2002"/>
    <abstract>
      <t>This document defines a date and time format for use in Internet protocols that is a profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3339"/>
  <seriesInfo name="DOI" value="10.17487/RFC3339"/>
</reference>
<reference anchor="RFC8259">
  <front>
    <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
    <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
    <date month="December" year="2017"/>
    <abstract>
      <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
      <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="90"/>
  <seriesInfo name="RFC" value="8259"/>
  <seriesInfo name="DOI" value="10.17487/RFC8259"/>
</reference>
<reference anchor="RFC9110">
  <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="RFC9580">
  <front>
    <title>OpenPGP</title>
    <author fullname="P. Wouters" initials="P." role="editor" surname="Wouters"/>
    <author fullname="D. Huigens" initials="D." surname="Huigens"/>
    <author fullname="J. Winter" initials="J." surname="Winter"/>
    <author fullname="Y. Niibe" initials="Y." surname="Niibe"/>
    <date month="July" year="2024"/>
    <abstract>
      <t>This document specifies the message formats used in OpenPGP. OpenPGP provides encryption with public key or symmetric cryptographic algorithms, digital signatures, compression, and key management.</t>
      <t>This document is maintained in order to publish all necessary information needed to develop interoperable applications based on the OpenPGP format. It is not a step-by-step cookbook for writing an application. It describes only the format and methods needed to read, check, generate, and write conforming packets crossing any network. It does not deal with storage and implementation questions. It does, however, discuss implementation issues necessary to avoid security flaws.</t>
      <t>This document obsoletes RFCs 4880 ("OpenPGP Message Format"), 5581 ("The Camellia Cipher in OpenPGP"), and 6637 ("Elliptic Curve Cryptography (ECC) in OpenPGP").</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9580"/>
  <seriesInfo name="DOI" value="10.17487/RFC9580"/>
</reference>

<reference anchor="CORS" target="https://fetch.spec.whatwg.org/#cors-protocol">
  <front>
    <title>Cross Origin Resource Sharing</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="UNF" target="https://www.unicode.org/reports/tr15/">
  <front>
    <title>Unicode Normalization Forms</title>
    <author fullname="Ken Whistler">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>



<reference anchor="I-D.gallagher-openpgp-media-types">
   <front>
      <title>Media Types for OpenPGP</title>
      <author fullname="Andrew Gallagher" initials="A." surname="Gallagher">
         <organization>PGPKeys.EU</organization>
      </author>
      <date day="8" month="August" year="2025"/>
      <abstract>
	 <t>   This document updates the specification of existing media types, and
   specifies additional media types, for the identification of OpenPGP
   data in non-MIME contexts.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-gallagher-openpgp-media-types-00"/>
   
</reference>

<reference anchor="I-D.ietf-sml-structured-email">
   <front>
      <title>Structured Email</title>
      <author fullname="Hans-Jörg Happel" initials="H." surname="Happel">
         <organization>audriga GmbH</organization>
      </author>
      <date day="21" month="October" year="2025"/>
      <abstract>
	 <t>   This document specifies how a machine-readable version of the content
   of email messages can be added to those messages.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-sml-structured-email-05"/>
   
</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>



    </references>

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



<reference anchor="RFC3492">
  <front>
    <title>Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)</title>
    <author fullname="A. Costello" initials="A." surname="Costello"/>
    <date month="March" year="2003"/>
    <abstract>
      <t>Punycode is a simple and efficient transfer encoding syntax designed for use with Internationalized Domain Names in Applications (IDNA). It uniquely and reversibly transforms a Unicode string into an ASCII string. ASCII characters in the Unicode string are represented literally, and non-ASCII characters are represented by ASCII characters that are allowed in host name labels (letters, digits, and hyphens). This document defines a general algorithm called Bootstring that allows a string of basic code points to uniquely represent any string of code points drawn from a larger set. Punycode is an instance of Bootstring that uses particular parameter values specified by this document, appropriate for IDNA. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3492"/>
  <seriesInfo name="DOI" value="10.17487/RFC3492"/>
</reference>
<reference anchor="RFC6335">
  <front>
    <title>Internet Assigned Numbers Authority (IANA) Procedures for the Management of the Service Name and Transport Protocol Port Number Registry</title>
    <author fullname="M. Cotton" initials="M." surname="Cotton"/>
    <author fullname="L. Eggert" initials="L." surname="Eggert"/>
    <author fullname="J. Touch" initials="J." surname="Touch"/>
    <author fullname="M. Westerlund" initials="M." surname="Westerlund"/>
    <author fullname="S. Cheshire" initials="S." surname="Cheshire"/>
    <date month="August" year="2011"/>
    <abstract>
      <t>This document defines the procedures that the Internet Assigned Numbers Authority (IANA) uses when handling assignment and other requests related to the Service Name and Transport Protocol Port Number registry. It also discusses the rationale and principles behind these procedures and how they facilitate the long-term sustainability of the registry.</t>
      <t>This document updates IANA's procedures by obsoleting the previous UDP and TCP port assignment procedures defined in Sections 8 and 9.1 of the IANA Allocation Guidelines, and it updates the IANA service name and port assignment procedures for UDP-Lite, the Datagram Congestion Control Protocol (DCCP), and the Stream Control Transmission Protocol (SCTP). It also updates the DNS SRV specification to clarify what a service name is and how it is registered. This memo documents an Internet Best Current Practice.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="165"/>
  <seriesInfo name="RFC" value="6335"/>
  <seriesInfo name="DOI" value="10.17487/RFC6335"/>
</reference>
<reference anchor="RFC7595">
  <front>
    <title>Guidelines and Registration Procedures for URI Schemes</title>
    <author fullname="D. Thaler" initials="D." role="editor" surname="Thaler"/>
    <author fullname="T. Hansen" initials="T." surname="Hansen"/>
    <author fullname="T. Hardie" initials="T." surname="Hardie"/>
    <date month="June" year="2015"/>
    <abstract>
      <t>This document updates the guidelines and recommendations, as well as the IANA registration processes, for the definition of Uniform Resource Identifier (URI) schemes. It obsoletes RFC 4395.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="35"/>
  <seriesInfo name="RFC" value="7595"/>
  <seriesInfo name="DOI" value="10.17487/RFC7595"/>
</reference>

<reference anchor="SKS" target="https://github.com/sks-keyserver/sks-keyserver/wiki">
  <front>
    <title>Synchronising Key Server Wiki</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="TOR" target="https://spec.torproject.org/">
  <front>
    <title>Tor Specifications</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>



<reference anchor="I-D.dkg-openpgp-1pa3pc">
   <front>
      <title>First-Party Approved Third-Party Certifications in OpenPGP</title>
      <author fullname="Daniel Kahn Gillmor" initials="D. K." surname="Gillmor">
         <organization>ACLU</organization>
      </author>
      <date day="6" month="September" year="2024"/>
      <abstract>
	 <t>   An OpenPGP certificate can grow in size without bound when third-
   party certifications are included.  This document describes a way for
   the owner of the certificate to explicitly approve of specific third-
   party certifications, so that relying parties can safely prune the
   certificate of any unapproved certifications.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-dkg-openpgp-1pa3pc-02"/>
   
</reference>

<reference anchor="I-D.dkg-openpgp-userid-conventions">
   <front>
      <title>OpenPGP User ID Conventions</title>
      <author fullname="Daniel Kahn Gillmor" initials="D. K." surname="Gillmor">
         <organization>ACLU</organization>
      </author>
      <date day="25" month="August" year="2023"/>
      <abstract>
	 <t>   OpenPGP User IDs are UTF-8 strings.  Existing documents claim that by
   conventione, they contain &quot;an RFC 2822 name-addr object&quot;, but that&#x27;s
   not the case.  This document attempts to better describe the actual
   conventions about User IDs in the deployed OpenPGP ecosystem.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-dkg-openpgp-userid-conventions-00"/>
   
</reference>



    </references>

</references>


<?line 1116?>

<section anchor="acknowledgments"><name>Acknowledgments</name>

<t>This document is a formalization and extension of HKP, originally implemented in the PKS keyserver by Marc Horowitz, which in turn was based on earlier work by Brian LaMacchia and Michael Graff.
The "prefixlog" request category is based on an earlier proposal by Daniel Kahn Gillmor and Vincent Breitmoser.</t>

<t>The authors would like to thank Peter Gutmann for his work on the Certstore protocol, some of which was applicable here, and the members of the pgp-keyserver-folk mailing list who contributed valuable comments and suggestions.
They would also like to thank Bart Butler, Daniel Kahn Gillmor, Heiko Schäfer, Justus Winter and Vincent Breitmoser for help with the v2 request format.</t>

</section>
<section anchor="document-history"><name>Document History</name>

<t>Note to RFC Editor: this section should be removed before publication.</t>

<section anchor="changes-between-draft-gallagher-openpgp-hkp-08-and-draft-gallagher-openpgp-hkp-09"><name>Changes Between draft-gallagher-openpgp-hkp-08 and draft-gallagher-openpgp-hkp-09</name>

<t><list style="symbols">
  <t>Refactored to separate v2 and Legacy sections.</t>
  <t>v2 API is now RESTful.</t>
  <t>v2 uses "category" and "identifier" instead of "op" and "search".</t>
  <t>v2 keywords are less terse.</t>
  <t>Defined "canonical bundle".</t>
  <t>Defined "identity".</t>
  <t>Resurrected SRV-based discovery.</t>
  <t>Added basic vs advanced submission.</t>
  <t>Added structured email.</t>
  <t>Specified bearer token authentication.</t>
  <t>Specified use of OPTIONS and HEAD.</t>
  <t>Specified the Last-Modified response header.</t>
  <t>Clarify subkey lookups.</t>
  <t>Sideline inexact matching.</t>
  <t>Discourage badly-behaved User IDs.</t>
  <t>Removed some misused HTTP return codes.</t>
  <t>Added tabular summaries.</t>
  <t>Added Daniel Huigens as co-author.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-07-and-draft-gallagher-openpgp-hkp-08"><name>Changes Between draft-gallagher-openpgp-hkp-07 and draft-gallagher-openpgp-hkp-08</name>

<t><list style="symbols">
  <t>Verified uploads now use prove-then-submit workflow.</t>
  <t>Removed SRV and discovery discussion (temporarily?).</t>
  <t>Added definitions of "discovery", "refresh" and "reference resolution".</t>
  <t>Normalised "certificate" terminology and warned about unqualified use of "keyring".</t>
  <t>Renumbered HKPv1 to HKPv2 for avoidance of confusion, and reordered path components.</t>
  <t>HKPv2 is now explicitly a binary protocol, and uses simplified paths.</t>
  <t>Defined v2 submission requests and "cb" option.</t>
  <t>Explicitly forbade mixed certificate bundle responses to v2 lookups.</t>
  <t>"since" is now "prefixlog".</t>
  <t>"get" operation is now <bcp14>MAY</bcp14>.</t>
  <t>"x-*" parameters are no longer specified (as per RFC6648).</t>
  <t>Fixed several errata.</t>
  <t>Expanded commentary and guidance.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-06-and-draft-gallagher-openpgp-hkp-07"><name>Changes Between draft-gallagher-openpgp-hkp-06 and draft-gallagher-openpgp-hkp-07</name>

<t><list style="symbols">
  <t>Added "authget" and "since" operations.</t>
  <t>Defined confidence.</t>
  <t>Added more explicit guidance re sorting, filtering and error codes.</t>
  <t>Key version MR output field is now "keyversion" to distinguish from the output format version.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-05-and-draft-gallagher-openpgp-hkp-06"><name>Changes Between draft-gallagher-openpgp-hkp-05 and draft-gallagher-openpgp-hkp-06</name>

<t><list style="symbols">
  <t>Updated references.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-04-and-draft-gallagher-openpgp-hkp-05"><name>Changes Between draft-gallagher-openpgp-hkp-04 and draft-gallagher-openpgp-hkp-05</name>

<t><list style="symbols">
  <t>Allow detached revocations in keyrings.</t>
  <t>Redesigned v2 request format to use path components for required fields.</t>
  <t>Added openpgpkey discovery file.</t>
  <t>Added "vfpget" and "kidget" operations.</t>
  <t>Added meaningful "exact" semantics.</t>
  <t>HKPS is now <bcp14>SHOULD</bcp14>.</t>
  <t>Defined port 11372.</t>
  <t>IANA registry tables.</t>
  <t>Deprecated <spanx style="verb">op=stats</spanx>.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-03-and-draft-gallagher-openpgp-hkp-04"><name>Changes Between draft-gallagher-openpgp-hkp-03 and draft-gallagher-openpgp-hkp-04</name>

<t><list style="symbols">
  <t>Reworded certificate lookups section for clarity.</t>
  <t>Separate section for keyring format.</t>
  <t>Specify detached revocations.</t>
  <t>Updated references.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-02-and-draft-gallagher-openpgp-hkp-03"><name>Changes Between draft-gallagher-openpgp-hkp-02 and draft-gallagher-openpgp-hkp-03</name>

<t><list style="symbols">
  <t>Clients <bcp14>SHOULD</bcp14> supply the <spanx style="verb">v=1</spanx> api-versioning variable.</t>
  <t>machine-readable output includes key version field.</t>
  <t>Clients <bcp14>MUST</bcp14> silently ignore leading and trailing cruft, trailing unknown fields, and unknown flags.</t>
  <t>Clients <bcp14>MUST</bcp14> silently ignore keys with unknown versions or algorithms.</t>
  <t>All other m-r index specs (CORS, Content-Type etc.) are now <bcp14>MUST</bcp14>.</t>
  <t>Included the <spanx style="verb">hash</spanx> variable from SKS.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-01-and-draft-gallagher-openpgp-hkp-02"><name>Changes Between draft-gallagher-openpgp-hkp-01 and draft-gallagher-openpgp-hkp-02</name>

<t><list style="symbols">
  <t>Tightened up BCP-14 language.</t>
  <t>Included <spanx style="verb">op=hget</spanx> from SKS.</t>
  <t>Options now strictly boolean with default false, variables less strict.</t>
  <t>More detail about HTTP status code usage.</t>
</list></t>

</section>
<section anchor="changes-between-draft-shaw-openpgp-hkp-00-and-draft-gallagher-openpgp-hkp-01"><name>Changes Between draft-shaw-openpgp-hkp-00 and draft-gallagher-openpgp-hkp-01</name>

<t><list style="symbols">
  <t>Improved text structure.</t>
  <t>Added references to HTTPS/HKPS, and hkp:/hkps: URL schemes.</t>
  <t>Forbade short IDs and deprecated V3 keys.</t>
  <t>Included <spanx style="verb">op=stats</spanx> from SKS.</t>
  <t>Mentioned CORS.</t>
  <t>Made use of terminology more consistent.</t>
  <t>Replaced custom status codes with standard HTTP status codes.</t>
</list></t>

</section>
</section>


  </back>

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

-->

</rfc>

