<?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-01" 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="August" year="2018" day="21" />
		<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
					keys identified by their 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 (defined in
					<xref target="RFC3986" />
					), the keylist's signature URI, and the fingerprint of the
					authority key used to sign the keylist. The protocol used to
					retrieve thbe keylist and its signature SHOULD be HTTPS (see
					<xref target="RFC2818" />
					), however other implementation are possible. 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.
						</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 a
							keyserver. If it is already present and not revoked,
							refresh it from a keyserver. If it is present and
							revoked, ignore it. The method by which keys are
							retrieved and updated is out of scope.
						</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 definitions of the data types we will be
				creating to support this new feature set.
			</t>
			<section anchor="terms" title="Keylist">
				<t>
					The keylist MUST be encoded in UTF-8
					<xref target="RFC3629" />
					. Each line MUST begin either with a comment, a public key
					fingerprint, or whitespace. A comment is defined as a string
					of characters between a hash symbol (#, U+0023) and a
					newline or an end of file (EOF). The keylist SHOULD end with
					a newline. The fingerprint MUST be the full 40-character
					hexadecimal public key fingerprint, as defined in OpenPGP
					Message Format
					<xref target="RFC4880" />
					. Space characters (' ', U+0020) MAY be included anywhere in
					the fingerprint. Lines SHOULD NOT exceed 128 characters in
					length.
				</t>
				<t>
					It is RECOMMENDED that keylist maintainers describe each key
					using a comment, for example:
				</t>
				<figure>
					<artwork>1326 CB16 ... DDBF 52A1 # Miles' Key</artwork>
				</figure>
				<!-- TODO: there must be better notation for this... ~MM -->
				<!-- In v3, there is <sourcecode> ~NDW -->
				<!-- TODO: I'm actually ambivalent about this recommendation. I
				think fingerprints without spaces are just as good - in the end,
				the point of the keylist is to be machine readable more than
				human readable anyway. ~ML -->
				<!-- ^ I was mostly referring to my use of the `<t>` tag for
				example notation. :) ~MM -->
				<t>
					To extract the public key fingerprints from a keylist, a
					client SHOULD perform the following steps, in order:
				</t>
				<t>
					<list style="numbers">
						<t>
							Strip the keylist of all comments, as defined above,
							including the preceding hash symbol but excluding
							the trailing newline.
						</t>
						<t>
							Strip the keylist of all non-breaking whitespace.
						</t>
					</list>
				</t>
				<t>
					Performing these steps will result in one public key
					fingerprint per line.
				</t>
				<!-- TODO: find the way to properly define unicode ~MM -->
				<!-- TODO: call it a file? Don't call it a file? What is the
				best path? It's an internet resource. ~MM -->
				<!-- I say let's keep the wording you have and show it to
				others, and see their thoughts on calling it a "file". ~ML -->
				<!-- TODO: adopt 'nonbreaking whitespace'/a citation from the
				Unicode RFC. ~MM -->
				<!-- TODO: ^ ask if the above is necessary, and if so, figure
				out how to do it. ~MM -->
			</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>
				<!-- TODO: Should we specify ASCII armored or not? At the
				moment, GPG Sync doesn't ASCII-armor the signature file, and
				it's a .sig, however I see no probably with using an
				ASCII-armored .asc file instead (and of course, I don't think
				there's any reason to require specific file extensions. It's
				just a URI after all, and this way you can choose to host the
				keylist and sig in, for example, github gists.) ~ML -->
				<!-- RESOLVED; I added language that specified ascii-armored.
				For all the reasons you specify, I think this is the best
				option. ~MM -->
			</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.3629.xml"?>
			<?rfc include="reference.RFC.2818.xml"?>
		</references>
		<!--
		<references title="Informative References"> </references>
		-->
	</back>
</rfc>
