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


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

]>


<rfc ipr="trust200902" docName="draft-gallagher-openpgp-hkp-04" category="info" 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>

    <date year="2024" month="March" day="04"/>

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

    <abstract>


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


<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 key server - a server that stores public keys and can be searched for a given key.
The HTTP Keyserver Protocol is a OpenPGP keyserver implemented using HTTP.</t>

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

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

</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>By convention and history, HKP uses HTTP on TCP port 11371, and HTTPS on TCP port 443.
These are often distinguished from generic use of HTTP(S) by using the URI schemes "hkp" and "hkps".
For reasons of maximum compatibility with firewalls and filtering HTTP proxies, HKP is also often served over the standard HTTP port (TCP port 80).</t>

<t>(( andrewg : We may wish to officially recommend HKPS.
See issue #7.
))</t>

<t>See <xref target="locating-keyserver"/> for an automated way for clients to discover the correct port.</t>

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

<t>HKP defines two paths, namely "/pks/lookup" for lookups (see <xref target="key-lookups"/>) and "/pks/add" for submission (see <xref target="submitting-keys"/>).
A keyserver <bcp14>MAY</bcp14> support requests to other paths, but these are implementation dependent.
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>

<t>(( andrewg : SKS uses "/pks/hashquery" for bulk updates, and hockeypuck also implements "/pks/delete" and "/pks/replace".
See issue #15.
))</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 key 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>202 Accepted</c>
      <c>Submitted key was altered to match keyserver policy</c>
      <c>403 Forbidden</c>
      <c>The requested 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>Key has been permanently deleted, e.g. due to blacklisting</c>
      <c>413 Content too large</c>
      <c>The search returned too many responses</c>
      <c>422 Unprocessable content</c>
      <c>Submitted key was rejected as per keyserver policy</c>
      <c>501 Not implemented</c>
      <c>The requested operation is not supported</c>
</texttable>

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

<t>(( andrewg : In draft-shaw-00 it was suggested that a novel header be used for statuses that could not be represented by the HTTP response codes of the time.
This was only partially specified, and it is unclear if any implementations of this header existed.
In the meantime many new HTTP response codes have been defined, so I am using them instead - even if their semantics does not exactly match that of <xref target="RFC9110"></xref>.
NB therefore that codes 202, 410, 413, 422 may not have been implemented anywhere yet.
See issue #5.
))</t>

</section>
</section>
<section anchor="key-lookups"><name>Looking up Data from a Keyserver</name>

<t>Key lookups are done via an HTTP GET request.
Specifically, the abs_path (see <xref target="RFC1945"></xref>, section 3.2) is built up of the base path "/pks/lookup", followed by any variables.
Variables are passed using HTTP query strings as specified in <xref target="RFC1866"></xref>, section 8.2.2.</t>

<t>Most HKP lookups contain both the "op" (operation) and "search" variables.
The "op" variable determines what operation the keyserver will take, and the "search" variable determines which keys are operated on.
There may also be modifier variables, as specified in <xref target="modifier-variables"/> below.
The variables may be given in any order.
Keyservers <bcp14>MUST</bcp14> ignore any unknown variables.</t>

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

<t>The op variable specifies the operation to be performed on the keyserver.
The op variable is generally used with the "search" variable to specify the keys that should be operated on.</t>

<t>If a particular operation is not supported, the keyserver should return an appropriate HTTP error code such as 501 ("Not Implemented").</t>

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

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

<t>The "get" operation requests keys from the keyserver by specifying its key ID, fingerprint, or one of its user IDs.
A string that specifies which key(s) to return is provided in the "search" variable.</t>

<t>The response to a successful "get" request is a HTTP document containing an ASCII-armored keyring as specified in <xref target="keyring-format"/>.</t>

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

<t>If no keys 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 keys on the keyserver that match the text or key ID in the "search" variable.
Historically, the "index" operation returned a human readable HTML document containing links for each found key, but this is not required.</t>

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

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

<t>The "vindex" operation is similar to "index" in that it provides a list of keys on the keyserver that match the text of key ID in the "search" variable.
Historically, a "vindex" response was the same as "index" with the addition of showing the signatures on each key, but this is not required.</t>

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

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

<t>The output of the "stats" operation is implementation-dependent, but may include diagnostic output, configuration state, or other metadata.
The "search" variable is ignored when supplied with "stats".</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 key from a keyserver by specifying its <xref target="SKS"></xref> digest.
The digest is provided in the "search" variable.</t>

</section>
<section anchor="other-operations"><name>Other operations</name>

<t>Other site-specific or nonstandard operations can be indicated by prefixing the operation name with the string "x-".</t>

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

<t>The search variable contains arbitrary text encoded as usual for a HTTP URL.
This text may represent the key ID, or fingerprint, or some text from a user ID on the key being sought.</t>

<t>If any particular type of searching is not supported, the keyserver should return an appropriate HTTP error code such as 501 ("Not Implemented").
The server <bcp14>MUST NOT</bcp14> return an error code (such as 404 ("Not Found")) that could be mistaken by the client for a valid response.</t>

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

<t>To search for a key by its key ID or fingerprint, a client <bcp14>SHOULD</bcp14> use "op=get" and prefix the "search" string with an "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.
The hexadecimal digits are not case sensitive.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> accept fingerprints and <bcp14>MAY</bcp14> accept 64-bit key IDs in the search string.
A keyserver <bcp14>MUST NOT</bcp14> return results for 32-bit "short key ID" searches, as these do not provide sufficient collision resistance.</t>

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

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

<t>To search for a key by the text of a user ID, a client <bcp14>SHOULD</bcp14> use "op=get" and <bcp14>SHOULD NOT</bcp14> prefix the "search" string with "0x".
Otherwise, how a keyserver handles textual search is implementation defined.
See also the definition of the "exact" variable (<xref target="exact-variable"/>) for a method to give additional instructions to the server on how the search is to be executed.</t>

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

<t>Search for all keys containing the string "dshaw":</t>

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

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

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

</section>
</section>
<section anchor="submitting-keys"><name>Submitting Keys To A Keyserver</name>

<t>A keyserver <bcp14>MAY</bcp14> accept submissions via an HTTP POST request.
Specifically, the abs_path (see <xref target="RFC1945"></xref>, section 3.2) is set to "/pks/add", and the key data is provided via HTTP POST as specified in <xref target="RFC1945"></xref>, section 8.3, and <xref target="RFC1866"></xref>, section 8.2.3.</t>

<t>The body of the POST message contains a "keytext" variable which contains an ASCII-armored keyring as specified in <xref target="keyring-format"/>.
The ASCII armored keyring should also be urlencoded as specified in <xref target="RFC1866"></xref>, section 8.2.1.
Note that more than one key may be submitted in a single transaction.</t>

<t>There may also be modifier variables, as specified in <xref target="modifier-variables"/> below.</t>

<t>If a keyserver does not support adding keys via HTTP, then requests to do so should return an appropriate HTTP error code, such as 403 ("Forbidden") if key submission has been disallowed, or 501 ("Not Implemented") if the server does not support HTTP key submission.
The keyserver <bcp14>MUST NOT</bcp14> return an error code (such as 404 ("Not Found")) that could be mistaken by the client for a valid response.</t>

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

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

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

<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 the request, so the output <bcp14>SHOULD</bcp14> be in machine-readable format.
See <xref target="output-formats"/> for the specific details of machine readable output.</t>

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

<t>As keyservers may modify submitted keys to suit a particular policy, this option is used to inform the keyserver that the submitter would rather have the submission fail completely then have the submitted key(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 key was submitted, the keyserver <bcp14>MAY</bcp14> trim any noncompliant user IDs before accepting the key.
If this option was set, then such a key 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="other-options"><name>Other Options</name>

<t>Other site-specific or nonstandard options can be indicated by prefixing the option name with the string "x-".
Non-standard options <bcp14>MUST</bcp14> represent boolean values with a default value of "false".</t>

</section>
</section>
<section anchor="v-variable"><name>The "v" (Version) Variable</name>

<t>This variable identifies the version of machine readable output that the client supports.
Currently, only "v=1" is defined.</t>

<t>"v" is meaningful for machine readable output only.</t>

</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 key fingerprint for each key in an "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.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable or set the default behaviour to "on".</t>

<t>"fingerprint" is meaningful for 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 key in an "index" or "vindex" operation in the default human-readable form.
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.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable or set the default behaviour to "on".</t>

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

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

<t>This variable takes one argument: "on" or "off".
If present and on, it instructs the server to search for an exact match for the contents of the "search" variable.
The exact meaning of "exact match" is implementation defined.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable or set the default behaviour to "on".</t>

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

</section>
<section anchor="other-variables"><name>Other Variables</name>

<t>Other site-specific or nonstandard variables can be indicated by prefixing the variable name with the string "x-".</t>

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

<t>HKP is intended for both human and programmatic use.
In general, the default "human readable" output is implementation specific.
The "machine readable" option is used to tailor the output for automated use.
For interoperability, the "machine readable" output <bcp14>MUST</bcp14> carefully follow the guidelines given here.</t>

<t>A client implementation <bcp14>SHOULD</bcp14> request machine readable output and <bcp14>SHOULD NOT</bcp14> attempt to parse human-readable output.</t>

<section anchor="mr-output"><name>Machine Readable Output</name>

<t>Clients requesting machine readable output:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> supply "v=1" (<xref target="v-variable"/>) and "option=mr" (<xref target="mr-option"/>) in the request.</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 keys with unknown versions or algorithms.</t>
</list></t>

<t>Keyservers returning 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> set "Content-Type: application/pgp-keys" when returning keys ("op=get"), as specified in <xref target="RFC3156"></xref>, section 7.</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="mr-indexes"/> when returning indexes ("op=index").</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>

</section>
<section anchor="mr-indexes"><name>Machine Readable Indexes</name>

<t>The machine readable index format is a list of newline-separated records.
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="Information Record Fields" anchor="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 keys 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 keys, and not the number of lines returned.
That is, it <bcp14>SHOULD</bcp14> match the number of "pub:" lines returned.</t>

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

<figure><artwork><![CDATA[
pub:<keyid>:<algorithm>:<keylen>:<creationdate>:<expirationdate>:<flags>:<version>
]]></artwork></figure>

<texttable title="Public Key Record Fields" anchor="public-key-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>keyid</c>
      <c>the fingerprint or the key ID</c>
      <c>algorithm</c>
      <c>the algorithm ID</c>
      <c>keylen</c>
      <c>the key length in bits</c>
      <c>creationdate</c>
      <c>creation date of the key</c>
      <c>expirationdate</c>
      <c>expiration date of the key</c>
      <c>flags</c>
      <c>letter codes to indicate details of the key</c>
      <c>version</c>
      <c>the version of the key</c>
</texttable>

<t>A keyserver <bcp14>MAY</bcp14> return a 16-digit key ID, but <bcp14>SHOULD</bcp14> return a fingerprint if available.
Since it is not possible to calculate the key ID from a V3 key fingerprint, for V3 keys this <bcp14>SHOULD</bcp14> be the 16-digit key ID only.</t>

<t>The algorithm ID is as specified in <xref target="crypto-refresh"></xref>, section 9.1 i.e.
1==RSA, 17==DSA, etc.</t>

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

<figure><artwork><![CDATA[
uid:<uidstring>:<creationdate>:<expirationdate>:<flags>
]]></artwork></figure>

<texttable title="User ID Record Fields" anchor="user-id-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>uidstring</c>
      <c>the user ID string</c>
      <c>creationdate</c>
      <c>creation date of the User ID</c>
      <c>expirationdate</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 HTTP % encoding for anything that isn't 7-bit safe as well as for the ":" character.
Any other characters <bcp14>MAY</bcp14> be HTTP encoded, as desired.</t>

<t>The information for the "creationdate", "expirationdate", and "flags" fields is taken from the User ID self-signature, if any, and applies to the user ID in question, not to the key 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.
Client implementations <bcp14>MUST</bcp14> ignore unknown flags.</t>

<texttable title="Record Flags" anchor="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 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.
Client implementations <bcp14>MUST</bcp14> ignore unknown trailing fields.
All dates are given in the number of seconds since midnight 1/1/1970 UTC.</t>

</section>
</section>
<section anchor="keyring-format"><name>Keyring Format</name>

<t>HKP uses an ASCII-armored keyring as its primary data representation for both input and output.</t>

<t>A keyring is a sequence of one or more OpenPGP Transferable Public Keys, concatenated directly, as specified in <xref target="crypto-refresh"></xref> sections 10.1 and 3.6.
An ASCII-armored keyring is a keyring that has been encoded as a single armored block, as specified in <xref target="crypto-refresh"></xref> section 6.2.</t>

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

<t>Traditionally, OpenPGP key revocation signatures have sometimes been distributed as a detached "revocation certificate", as per <xref target="crypto-refresh"></xref> section 10.1.3.
An HKP implementation <bcp14>MAY</bcp14> accept an ASCII-armored detached revocation as input, in place of an ASCII-armored keyring.</t>

<t>(( andrewg : We may wish to specify multiple detached revocations, and/or a mixture of detached revocations and TPKs.
We may also wish to specify them for both input and output.
See issue #18.
))</t>

</section>
</section>
<section anchor="locating-keyserver"><name>Locating a HKP Keyserver</name>

<t>Clients are usually manually configured with the address of a HKP keyserver.
Client implementations should be aware that it is reasonably common practice to use a single name in DNS that resolves to multiple address records.
When receiving a DNS response with multiple addresses, clients <bcp14>SHOULD</bcp14> try each address until a server is reached.
The order to try these addresses in is implementation defined.</t>

<t>A far more flexible scheme for listing multiple HKP keyservers in DNS is the use of DNS SRV records as specified in <xref target="RFC2782"></xref>.
DNS SRV allows for different priorities and weights to be applied to each HKP keyserver in the list, which allows an administrator much more control over how clients will contact the servers.
The SRV symbolic service name for HKP keyservers is "hkp" when used over plaintext HTTP, or "hkps" when using HTTPS.
For example, the SRV record for HKP keyservers in domain "example.com" would be "_hkp._tcp.example.com".</t>

<t>SRV records contain the port that the target server runs on, so SRV can also be used to automatically discover the proper port for contacting a HKP keyserver.
HKP clients <bcp14>SHOULD</bcp14> support SRV records.</t>

<section anchor="key-discovery"><name>Key discovery</name>

<t>An additional use of SRV records is when a client needs to locate a specified key by email address.
For example, a client trying to locate a key for isabella@silvie.example.com could consult "_hkp._tcp.silvie.example.com".</t>

<t>(( andrewg : key discovery is the subject of ongoing debate, and may need to be left for another document.
See issue #1.
))</t>

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

<t>As described here, a keyserver is a searchable database of public keys accessed over the network.
While there may be security considerations arising from distributing keys 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 search results cannot be trusted by the client until the OpenPGP client actually retrieves and checks the key for itself.
This is important and must be stressed: without a specific reason to treat information otherwise, all search results must be regarded as untrustworthy and informational only.</t>

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

<t>This document assigns the DNS SRV symbolic names "hkp" and "hkps", the URI schemes "hkp" and "hkps", and the HKP port 11371.</t>

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

</section>


  </middle>

  <back>


    <references title='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='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="crypto-refresh" target="https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-13">
  <front>
    <title>OpenPGP</title>
    <author initials="P." surname="Wouters" fullname="Paul Wouters">
      <organization></organization>
    </author>
    <author initials="D." surname="Huigens" fullname="Daniel Huigens">
      <organization></organization>
    </author>
    <author initials="J." surname="Winter" fullname="Justus Winter">
      <organization></organization>
    </author>
    <author initials="N." surname="Yutaka" fullname="Niibe Yutaka">
      <organization></organization>
    </author>
    <date year="2023" month="October"/>
  </front>
</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='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'>



<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="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>


    </references>


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

<t>This document is a formalization and extension of the HKP originally implemented in the PKS keyserver by Marc Horowitz, which in turn was based on earlier work by Brian LaMacchia and Michael Graff.
Without their grounding, this document would not exist.</t>

<t>The authors would also 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.</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-03-and-04"><name>Changes Between -03 and -04</name>

<t><list style="symbols">
  <t>Reworded <xref target="key-lookups"/> 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-02-and-03"><name>Changes Between -02 and -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-01-and-02"><name>Changes Between -01 and -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-00-and-01"><name>Changes Between -00 and -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:
H4sIAAAAAAAAA+196XIbSZLmfzxFLGQ7TZYB4FkqFa1U2xSpg62LI1ItKyuT
tRLIAJDNRCYmD1IYtt5lnmWfbP1z94iMTIAsamZ2+8+qzCQgERnh4fcVUcPh
sFclVWqPTP/90mbnL8/Nq8vLc/ParkpbXNvCnBd5lU/ytN+LxuPCXtPIV6/P
+71JVNlZXqyOTJJN816cT7JoQfPERTSthrMoTaPZ3BbDnKZdzpbD+dVyuHvY
S5bFkamKuqz2d3d/3t3vRYWNMEfVu8mLq1mR18sjoy/1ruyKnsZH5iyrbJHZ
aniK6XtlPV4kZZnk2eVqSYuePb980bu2WW2PesboJG5HfXpU8bD+J1oiyWbm
JUbg+SJKUnqu6/05sdV0lBcz/BQVkzn9NK+qZXm0s4OReJRc25EbtoMHO+Mi
vyntjs6xg3cLu8yDd2eE4mg8muSLnSiLC3szi/MK3+5BFqZJCcdlFUzUenuk
0yb5/fOUFb32tyjNM0LBypa9ZXJkfieiDkyZF1VhpyV9Wi3w4XMvqqt5XhAa
hwSAMdM6TYWwp9FynllzMY9u+Bfaf5Ql/x5VRIUj8xfiDlvc5JOrlbm0kzkP
sYLeuKR3/vz3ZgQwsb7AMW/OvHS72LAKUROcOXr+MZxfsfJn/Vdmpz9FDsa2
cVLlRS/LiwXNcs0c8uHFyd7Phz+6j08eP9aP+z892dePB3s/uqc/7+3t4uOk
WC2rfEiIKmw5P+JFqqiYWaKRI1EcVVFVRJMrWzR8QtKxM68WqRIKzz2N2pMO
9w5k2rZU9vmhpw3/Geq/xgj+zqM6NZ/ymiSlvGPIKeHSpuZVncxsdtegv5Bw
1qX5lEDm7hjzLknG1vxWV9FVxD/Rtunx+0mVE5HN/u4+tnHy/sPFZixNbTWZ
j8qlnYxu5lFFRAOaHk3yohwuVeOEeDgp8rI074tklmTmgy3zupgwLxYkzj1o
oDZ1n+z/+DM+Xry+AwCSnXktIllelcMrp+86326SqySE42KVTeZFniUl1Ajx
orkQNfkJA3vD4dBE4xL0r3q9y3lSGiJ9vbBZZbDZZJrY0kSGZseHfGomeUZ6
C9xdmio3yWKZWh4eZcZpZA+OqXnZam7NK1JoRWW/VuayiLJyGmhqswUVvj3q
HdOULRASrD3JYwJjwhIF0TE0CTEDvhE8kXHop3cjeSUlFR2vSEebmyS2BIQl
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
D5tOGVWCYy8AbeeV7CFhDM394LJFEmfJbF6ZvR367+efds3HyxPOb73WjhdJ
cMnhy7BNRvJbfNr2vl4btEI6p5V7iHw5q1FxnBRLMpe/8UmZYz9RUnY0QmiO
3WVY7iY0Dusax7XkLnfYh4zjTTmCzEcK/sB5cL5DafZ2yXvgU8yjx5wc3bzf
RJvOmxNdvlElaBPy/Tzudc6+PBwc85gPflKMfkrKgW8Q+0AiOfGN57E+HhbN
Y0TqRdTcRTQI7xAzzcDwaATLGnqxcTK5abjxzZq8F7eY6QeTTGxRScXfSo4G
SvrO/QC7aP8ivHLOdD3xrJXwNUbziwdrg+kyPtxAOOR7QPR42Eaa/cH1Nu6U
5KJOq2Qph1i7K0p4uSONlslX4E6uYlofyTx0ef6ahPVT0LvVXQ1x432SEd5q
8qQ5Py3X6qAB//V5q8tww407TSZTWnFqPje6iDL54M6FhMdIfcPBVJcITqPe
obaa46TRTeROkEsMITdwkKyu3FUg4U0n8My8nHAinoh5+u5CZiAwco6q0T3k
KOPA8/mkT5JYm9jkWtCC95uzQ9hW92WUqSbt+z0qUlysu938dVah+8LVa2Qr
ILSeyYWrwe5RsdIuaj85NnFP0YUU3jRSpTZN7VcOr+SuKCmP6GlHD3XnvjFF
kaZA9BIqPLn48FfvgG3KY+La08+jnhvK1lkMWpxMuQMbCeUEkRdfYEmseGNh
Nlw/cKTnfugb46oFmLNBAH+giUhdAmWQeEEuH+7MrKDQkd9jBMh1Z6lcVIU+
ZEcXPmvOruKkCgpnmkAE/OVqMUZHEP8ChmIGwna6CHNXcN20LxzjhCE3jEt/
Iwp5fEGXG+iO7V90PJhKIdDAcdOSmfbmcC3OdRf3m3ag/t9opdHfqskybD9G
zSmkonOhOSckZ6K0+0JuOnXcWdTc9cI+Kd5H+cs3r2r1R+s8ejdU65KtJRd7
ZAW+jEvQ3miZQAWEN+l1zlsHkIvhem2bhVZ6sYP/jm6wLOxRV04O948GKrmV
SMtF/lIm1nWsPDyX6ymAVtvUmuup85DU6oV4fiJOX6D4RX4uOXzRn8skvU5s
SB7t78Q5By7WNTRcH9vvmpyrFjJUest6/Hcu2MPXmeWAKbZjPp4H8ePLNqzP
mLIvKZGrhJ0uj962Fc5UXOAQBu7sOtGDGd51KPWX4aT1izToNVdqoljXdq/V
Q0MVWi57IF9vrHeztu4/5YJOeAFdZivcTgh9naTs22tbM1+RqoC2wSGbJTfw
cmjbXOfq6jbullAyZ5mc6E6CS09I/TaqQ+cnKJ0/JCe9iUifyELg0kI+jVby
vY1Tubuc2DAVSObJkuCsbuAaBb1PIJG7CaxdQdDi29qpxCRrbgCSgzokqnp3
Da/Z3Fuja4gdwgMHuVucz8nzhXyEF3utGpvsyOSqbNqSwNG61Us98kqYoW1G
uoEFdjrmyjeT7IhtJjASNQ2hepEW2zvLIXKzW19qGvCZj87+3PSFnUWFO0WY
8V6JH6q55A+C+UgTuMYAc3b87nide5Moi9Y5t31JWVTCwxU8OIPnDQYMxfq1
jKLX77u4sTkrAS3YXCjZFXWK9G6sgmDw5gDfldndYePQE4R/7ToVMO1A7vQB
GWaIkvmwBAdhSUfWD0XYKW7nC5mBtOMJAkcK1Wd8fV4XMyzCjO1Ub1xfvx/a
bTHnEixzWXjLj1qk89cX7QO3b4ny5lVe5MRB/+58AAxG1hnNov7qVeKRNOFe
3OIKbz4riKjmTfSWFMecz73E5i29HdnUvCyiKXGvk9OKbznC7f8ZMnle7HV7
N/46KL58ySWU+U51147LplGam5DDibIrc45ba8zLuoIycefTBDwN8E8o2OGb
nv3d2QPRGb7synehSdWZW7JEeyrHLCxCc5+0dBVpxh0F2+kV/18K5D4Bkpib
eS6+kQZhaPvUTtiF3IrIyqe5MY/l5dRhQQ7Vr1x2Jsdt6eY535F/JAhzUVnj
u/OVsNA/0v4r6tyduiZrfkKIotXMM1WEw90DBgL/w4feDxSc4gZper9zh6Ze
7xlBAY9o3IWWhD0EU7m7odC0LDeq0zAVjU3xFX7/yJdHxs3ZwfIuKPcVygNA
ebLuukiHt/ly/XTvC9EvGWq9BfA0jVY/uFJ5t63EVUjl9Kyr1XCyZhQsuLHj
IqWpXEXb53kmRT1FT7X77hN+nP8RjuokAf9gmYc3dfxgkF3SawGGhVb4oaZK
s4Wei0Gr8s5FlW09BnrDi2OOM60ZC17RmPel6bdim3jx+uIucu0pufZBrkuE
HxamtF7ieu/h3qFJ6Y06mtnWSl/y5VNcDPAlmP8H3/cN4OQue1yLqv3VjBDX
eMXN1IOggyxFECjvMPGBR8nSmmgMPcQJfr05lNvX65KB2ryrXd3VHnZ1tkCn
KPCD4EO6A+uCN3Qcxy2m5muyEYLs4LZdvSr1anm0A7NyhOP3zlrhbRynQvVZ
TvyiQoXxMXJxYly0HLeGOr7DoY27t3KzMg0A3UUAYh9vyh1feZrPVj6QwwFh
dkahDDglQ+4I2XmaM8CTcmL7QuLw91Hv/wDkyfEGsWYAAA==

-->

</rfc>

