<?xml version="1.0"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<rfc ipr="trust200902" docName="draft-mccain-keylist-02" category="exp">
	<!-- TODO: We should verify that 'trust200902' is the intellectual property
	designation we want. ~MM -->
	<!-- TODO: figure out which category this goes in. ~MM -->
	<front>
		<!-- Working title. We'll want something that more accurately frames the
		system before we submit. It never also hurts to have a more catchy
		title... -->
		<title abbrev="OpenPGP Keylist Subscriptions">
			Distributing OpenPGP Keys with Signed Keylist Subscriptions
		</title>
		<author initials="M.M." surname="McCain" fullname="R. Miles McCain">
			<organization abbrev="FLM">
				First Look Media
			</organization>
			<address>
				<email>
					ietf@sendmiles.email
				</email>
				<uri>
					https://rmrm.io
				</uri>
			</address>
		</author>
		<author initials="M.L." surname="Lee" fullname="Micah Lee">
			<organization abbrev="TI">
				The Intercept
			</organization>
			<address>
				<email>
					micah.lee@theintercept.com
				</email>
				<uri>
					https://micahflee.com/
				</uri>
			</address>
		</author>
		<author initials="N.D.W." surname="Welch" fullname="Nat Welch">
			<organization abbrev="FLM">
				First Look Media
			</organization>
			<address>
				<email>
					nat.welch@firstlook.media
				</email>
				<uri>
					https://natwelch.com
				</uri>
			</address>
		</author>
		<date month="October" year="2018" day="13" />
		<area>
			Security
		</area>
		<keyword>
			OpenPGP
		</keyword>
		<keyword>
			GPGSync
		</keyword>
		<keyword>
			GPG
		</keyword>
		<keyword>
			Keylist
		</keyword>
		<abstract>
			<t>
				This document specifies a system by which an OpenPGP client may
				subscribe to an organization's keylist to keep its internal
				keystore up-to-date. Ensuring that all members of an
				organization have their colleagues' most recent PGP public keys
				is critical to maintaining operational security. Without the
				most recent keys and a source of trust for those keys (as this
				document specifies), users must manually update and sign each
				others keys -- a system that is untenable in larger
				organizations. This document proposes a experimental format for
				the keylist file as well as requirements for clients who wish to
				implement this experimental keylist subscription functionality.
			</t>
			<!-- We'll want to tighten this abstract up a bit... ~MM -->
			<!-- ^ I did what I could. ~MM -->
		</abstract>
	</front>
	<middle>
		<section anchor="intro" title="Introduction">
			<t>
				This document specifies a system by which clients may subscribe
				to cryptographically signed keylists. This system allows for
				seamless key rotation across entire organizations and enhances
				operational security. To enable cross-client compatibility, this
				document provides a experimental format for the keylist, its
				cryptographic verification, and the method by which it is
				retreived by the client. The user interface by which a client
				provides this functionality to the user is out of scope, as is
				the process by which the client retrieves public keys. Other
				non-security-related implementation details are also out of
				scope.
			</t>
			<section anchor="notation" title="Requirements Notation">
				<t>
					The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
					"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
					and "OPTIONAL" in this document are to be interpreted as
					described in
					<xref target="RFC2119" />
					.
				</t>
			</section>
			<section anchor="terminology" title="Terminology">
				<t>
					This document uses the terms "OpenPGP", "public key",
					"private key", "signature", and "fingerprint" as defined by
					OpenPGP Message Format
					<xref target="RFC4880" />
					.
				</t>
				<!-- TODO: add unicode definitions. ~MM -->
				<!-- TODO: verify that all the previous terms are actually
				defined in RFC4880. ~MM -->
				<!-- TODO: does 'URI' and 'Internet' need a citation? Probably
				not, but we should check. ~MM -->
				<t>
					The term "keylist" is defined as a list of OpenPGP public
					key fingerprints and accessible via a URI. The exact format
					of this data is specified in
					<xref target="formats" />
					.
				</t>
				<!-- TODO: I avoid using the word 'file' here as it has a
				nuanced meaning and really we're just talking about data
				accessible via a URI. Is there a term other than 'data' that is
				appropriate here? ~MM -->
				<!-- I think this is fine. ~NDW -->
				<t>
					An "authority key" is defined as the OpenPGP secret key used
					to sign a particular keylist. Every keylist has a
					corresponding authority key, and every authority key has at
					least one corresponding keylist. A single authority key
					SHOULD NOT be used to sign multiple keylists.
				</t>
				<!-- I'm not opposed to it, but why shouldn't the same authority
				key be used to sign multiple keylists? I think it'd be confusing
				in the UI in GPG Sync if you do this, because they keylist is
				displayed by the authority key's UID. But from a security
				standpoint, it should be probably be just as secure. ~ML -->
				<!-- I removed the reference to security. One potential
				consideration, though, is that this sentence is less about the
				spec and more about the end user. Perhaps we should just remove
				the reference all together because it doesn't fit into the
				implementation but rather the end user's habits? Could be a
				point of criticism. ~MM -->
				<t>
					To be "subscribed" to a keylist means that a program will
					retreive that keylist on a regular interval. After
					retrieval, that program will perform an update to an
					internal OpenPGP keystore.
				</t>
				<!-- TODO: This needs to be cleaned/tightened. ~MM -->
				<t>
					A "client" is a program that allows the user to subscribe to
					keylists. A client may be an OpenPGP client itself or a
					separate program that interfaces with an OpenPGP client to
					update its keystore.
				</t>
			</section>
			<section anchor="note-to-readers" title="Note to Readers">
				<t>RFC Editor: please remove this section prior to
				publication.</t>
				<t>Development of this Internet draft takes place on GitHub at
				<eref
				target="https://github.com/firstlookmedia/keylist-rfc">Keylist-RFC</eref>.
				</t>
				<t>A mailing list is available for discussion at <eref
				target="https://www.freelists.org/list/keylists">Keylists
				mailing list</eref>.</t>
			</section>
		</section>
		<section anchor="functions" title="Functions and Procedures">
			<t>
				As new keys are created and other keys are revoked, it is
				critical that all members of an organization have the most
				recent set of keys available on their computers. Keylists enable
				organizations to publish a directory of OpenPGP keys that
				clients can use to keep their internal keystores up-to-date.
			</t>
			<section anchor="keylist-subscribe" title="Subscribing to Keylists">
				<t>
					A single client may subscribe to any number of keylists.
					When a client first subscribes to a keylist, it SHOULD
					update or import every key present in the keylist into its
					local keystore. Keylist subscriptions SHOULD be persistent
					--that is, they should be permanently stored by the client
					to enable future automatic updates.
				</t>
				<t>
					To subscribe to a keylist, the client must be aware of the
					keylist URI (see <xref target="RFC3986" />), and the 
					fingerprint of the authority key used to sign the
					keylist. The protocol used to retrieve the keylist and its
					signature SHOULD be HTTPS (see <xref target="RFC2818" />),
					however other implementation MAY be supported. A client
					implementing keylist functionality MUST support the
					retrieval of keylists and signatures over HTTPS. All other
					protocols are OPTIONAL.
				</t>
				<t>
					A client MUST NOT employ a trust-on-first-use model for
					determining the fingerprint of the authority key; it must be
					explicitly provided by the user.
				</t>
				<t>
					The process by which the client stores its keylist
					subscriptions is out of scope, as is the means by which
					subscription functionality is exposed to the end-user.
				</t>
			</section>
			<section anchor="keylist-update" title="Periodic Updates">
				<t>
					The primary purpose of keylists is to enable periodic
					updates of OpenPGP clients' internal keystores. We RECOMMEND
					that clients provide a default refresh interval of less than
					one day, however we also RECOMMEND that clients allow the
					user to select this interval. The exact time at which
					updates are performed is not critical.
				</t>
				<t>
					To perform an update, the client MUST perform the following
					steps on each keylist to which it is subscribed. The steps
					SHOULD be performed in the given order.
				</t>
				<t>
					<list style="numbers">
						<t>
							Obtain a current copy of the keylist from its URI.
						</t>
						<t>
							Obtain a current copy of the keylist's signature
							data from its URI, which is included in the keylist data
							format specified in <xref target="formats" />.
						</t>
						<!-- I say 'obtain' rather than retrieve because I want
						to leave open the possibility of a client checking to
						see if the hash of the file, for example, has changed,
						and only re-requesting if it has. 'Obtain' is also very
						ambiguous, though, so it may be to our advantage to use
						something more specific or explain this rationale
						outright. ~MM -->
						<!-- we should be verifying a checksum, and be explicit
						about it in this description. ~NDW -->
						<t>
							Using the keylist and the keylist's signature,
							cryptographically verify that the keylist was signed
							using the authority key. If the signature does not
							verify, the client MUST abort the update of this
							keylist and SHOULD alert the user. The client SHOULD
							NOT abort the update of other keylists to which it
							is subscribed, unless they too fail signature
							verification.
						</t>
						<t>
							Validate the format of the keylist according to
							<xref target="formats" />
							. If the keylist is in an invalid format, the client
							MUST abort the update this keylist and SHOULD alert
							the user.
						</t>
						<t>
							For each fingerprint listed in the keyfile, if a
							copy of the associated public key is not present in
							the client's local keystore, retrieve it from the
							keyserver specified by the keylist (see 
							<xref target="formats" />) or, if the keylist specifies
							no keyserver, from any keyserver.
							If the key is already present and not revoked,
							refresh it from a keyserver. If it is present and
							revoked, do nothing.
						</t>
						<!-- TODO: Is it overkill to establish some concept of a
						'linked keystore' as the keystore that the client
						interacts with and keeps updated? This is a potential
						ambiguity for machines with multiple keystores. ~MM -->
						<!-- That could be useful, but I'd leave that up to the
						client. Maybe add a recommendation that says something
						around letting users specify which keystore they want to
						sync to? It seems slightly out of scope as you are
						saying retrival and update is out of scope. ~NDW -->
						<!-- TODO: Should anything else be in this list? ~MM -->
					</list>
				</t>
			</section>
			<section anchor="keylist-crypto" title="Cryptographic Verification of Keylists">
				<t>
					To ensure authenticity of a keylist during an update, the
					client MUST verify that the keylist's data matches its
					cryptographic signature, and that the public key used to
					verify the signature matches the authority key fingerprint
					given by the user.
				</t>
				<t>
					For enhanced security, it is RECOMMENDED that keylist
					operators sign each public key listed in their keylist with
					the authority private key. This way, an organization can
					have an internal trust relationship without requiring
					members of the organization to certify each other's public
					keys.
				</t>
			</section>
		</section>
		<section anchor="formats" title="Data Element Formats">
			<t>
				The following are format specifications for the keylist file and
				its signature file.
			</t>
			<section anchor="keylist-format" title="Keylist">
				<t>
					The keylist MUST be a valid JavaScript Object Notation
					(JSON) Data Interchange Format
					<xref target="RFC8259" /> object with specific keys
					and values, as defined below. Note that unless otherwise specified,
					'key' in this section refers to JSON keys--not OpenPGP keys.
				</t>
				<t>
					To encode metadata, the keylist MUST have a "metadata" root key
					with an object as the value ("metadata object").
					The metadata object MUST contain a "signature_uri" key whose value
					is the URI string of the keylist's signature file. All metadata keys 
					apart from "signature_uri" are OPTIONAL.
				</t>
				<t>
					The metadata object MAY contain a "keyserver" key with the value of the
					URI string of the keyserver from which the OpenPGP keys in the keylist
					should be retrieved.
				</t>
				<t>
					The metadata object MAY contain a "comment" key with the
					value of any string. The metadata object MAY also contain other arbitrary
					key-value pairs.
				</t>
				<!-- TODO: Should we specify in more detail what a keyserver URI
				is, or even what a keyserver is? More details here:
				https://github.com/firstlookmedia/keylist-rfc/issues/8#issuecomment-427133308
				~ML -->
				<t>
					The keylist MUST have a "keys" key with an array as the value.
					This array contains a list of OpenPGP key fingerprints and
					metadata about them. Each item in the array MUST be an object.
					Each of these objects MUST have a "fingerprint" key with the
					value of a string that contains the full 40-character
					hexadecimal public key fingerprint, as defined in OpenPGP
					Message Format
					<xref target="RFC4880" />
					. Any number of space characters (' ', U+0020) MAY be included
					at any location in the fingerprint string. These objects MAY 
					contain "name", "email", and "comment" key-value pairs, as well
					as any other key-value pairs relevant.
					<!-- Maybe the edit here was a bit _too_ reductive. Let me know if you
					think I cut too much. The thinking is really that "name", "email", and
					"comment" keys are really just optional, so it makes sense to merge them
					into a single sentence, but I'm also completely open to reverting this
					change if you prefer the old phrasing! -->
				</t>
				<t>
					The following is an example of a valid keylist.
				</t>
				<figure>
					<artwork>
{
  "metadata": {
    "signature_uri": "https://www.example.com/keylist.json.asc"
    "comment": "This is an example of a keylist file"
  },
  "keys": [
    {
      "fingerprint": "927F419D7EC82C2F149C1BD1403C2657CD994F73",
      "name": "Micah Lee",
      "email": "micah.lee@theintercept.com",
      "comment": "Each key can have a comment"
    },
    {
      "fingerprint": "1326CB162C6921BF085F8459F3C78280DDBF52A1",
      "name": "R. Miles McCain",
      "email": "0@rmrm.io"
    },
    {
      "fingerprint": "E0BE0804CF04A65C1FC64CC4CAD802E066046C02",
      "name": "Nat Welch",
      "email": "nat.welch@firstlook.org"
    }
  ]
}
					</artwork>
				</figure>
			</section>
			<section anchor="sigfile" title="Signature">
				<t>
					The signature file MUST be an ASCII-armored 'detached
					signature' of the keylist file, as defined in OpenPGP
					Message Format
					<xref target="RFC4880" />
					.
				</t>
			</section>
		</section>
		<section anchor="inpractice" title="In Practice">
			<t>
				GPG Sync, an open source program created by one of the authors,
				implements this experimental standard. GPG Sync is used by First
				Look Media and the Freedom of the Press Foundation to keep
				OpenPGP keys in sync across their organizations, as well as to
				publish their employee's OpenPGP keys to the world. These
				organizations collectively employ more than 200 people and have
				used the system described in this document successfully for
				multiple years.
			</t>
			<t>
				GPG Sync's existing code can be found at
				&lt;https://github.com/firstlookmedia/gpgsync&gt;
			</t>
			<t>
				First Look Media's keylist file can be found at
				&lt;https://github.com/firstlookmedia/gpgsync-firstlook-fingerprints&gt;
			</t>
			<!-- TODO: clunky. We could clean this. ~MM -->
		</section>
		<section anchor="securityconsiderations" title="Security Considerations">
			<section anchor="securitybenefits" title="Security Benefits">
				<t>
					The keylist subscription functionality defined in this
					document provide a number of security benefits, including:
				</t>
				<t>
					<list style="symbols">
						<t>
							The ability for new keys to be quickly distributed
							across an organization.
						</t>
						<t>
							It removes the complexity of key distribution from
							end users, allowing them to focus on the content of
							their communications rather than on key management.
						</t>
						<t>
							The ability for an organization to prevent the
							spread of falsely attributed keys by centralizing
							the public key discovery process within their
							organization.
						</t>
						<!-- TODO: others? ~MM -->
					</list>
				</t>
			</section>
			<section anchor="securitydrawbacks" title="Security Drawbacks">
				<t>
					There is a situation in which keylist subscriptions could
					pose a potential security threat. If the both the authority
					key and the keylist distribution system were to be
					compromised, it would be possible for an attacker to
					distribute false keys. We believe, however, that the
					security benefits of this system strongly outweigh the
					drawbacks.
				</t>
			</section>
			<!-- TODO, see https://tools.ietf.org/html/bcp72 ~MM -->
		</section>
		<section anchor="ianaconsiderations" title="IANA Considerations">
			<t>
				This document has no actions for IANA.
			</t>
		</section>
	</middle>
	<back>
		<references title="Normative References">
			<?rfc include="reference.RFC.4880.xml"?>
			<?rfc include="reference.RFC.3986.xml"?>
			<?rfc include="reference.RFC.2119.xml"?>
			<?rfc include="reference.RFC.8259.xml"?>
			<?rfc include="reference.RFC.2818.xml"?>
		</references>
		<!--
		<references title="Informative References"> </references>
		-->
	</back>
</rfc>
