<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC4251 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4251.xml">
<!ENTITY RFC4253 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4253.xml">
<!ENTITY RFC5226 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226.xml">
<!ENTITY RFC5226 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226.xml">
<!ENTITY RFC5656 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5656.xml">
<!ENTITY RFC8032 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8032.xml">
<!ENTITY RFC8332 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8332.xml">
<!ENTITY RFC8709 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8709.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="4"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space 
    (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="info" docName="draft-miller-ssh-agent-06" ipr="trust200902">
 <!-- category values: std, bcp, info, exp, and historic
    ipr values: trust200902, noModificationTrust200902, noDerivativesTrust200902,
       or pre5378Trust200902
    you can add the attributes updates="NNNN" and obsoletes="NNNN" 
    they will automatically be output with "(if approved)" -->
<front>
	<title abbrev="SSH Agent">SSH Agent Protocol</title>
	<!-- add 'role="editor"' below for the editors if appropriate -->
	<!-- Another author who claims to be an editor -->
	<author fullname="Damien Miller" initials="D.J."
	        surname="Miller">
		<organization>OpenSSH</organization>
		<address>
<!--
			<postal>
				<street></street>
				<city></city>
				<region></region>
				<code></code>
				<country></country>
			</postal>
-->
			<!-- <phone></phone> -->
			<email>djm@openssh.com</email>
			<uri>http://www.openssh.com/</uri>
			<!-- uri and facsimile elements may also be added -->
		</address>
	</author>
   <date year="2023" />
   <!-- If the month and year are both specified and are the current ones, xml2rfc will fill 
	in the current day for you. If only the current year is specified, xml2rfc will fill 
	 in the current day and month for you. If the year is not the current one, it is 
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the 
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to 
	 specify just the year. -->

   <!-- Meta-data Declarations -->

   <area>General</area>

   <workgroup>Internet Engineering Task Force</workgroup>

   <!-- WG name at the upperleft corner of the doc,
	IETF is fine for individual submissions.  
	 If this element is not present, the default is "Network Working Group",
	which is used by the RFC Editor as a nod to the history of the IETF. -->

   <keyword>ssh</keyword>
   <keyword>agent</keyword>
   <keyword>ssh-agent</keyword>

   <!-- Keywords will be incorporated into HTML output
	files in a meta tag but they have no effect on text or nroff
	output. If you submit your draft to the RFC Editor, the
	keywords will be used for the search engine. -->

	<abstract>
	<t>
		This document describes a key agent protocol for use in
		the Secure Shell (SSH) protocol.
	</t>
	</abstract>
 </front>

 <middle>
	<section title="Introduction">
		<t>
		Secure Shell (SSH) is a protocol for secure remote
		connections and login over untrusted networks.
		It supports multiple authentication mechanisms,
		including public key authentication. This document
		describes the protocol for interacting with an agent
		that holds private keys. Clients (and possibly
		servers) can use invoke the agent via this protocol
		to perform operations using public and private keys
		held in the agent.
		</t>
		<t>
		Holding keys in an agent offers usability and security
		advantages to loading and unwrapping them at each use.
		Moreover, the agent implements a simple protocol and
		presents a smaller attack surface than a key loaded into
		a full SSH server or client.
		</t>
		<t>
		This agent protocol is already widely used and a de-facto
		standard, having been implemented by a number of popular
		SSH clients and servers for many years. The purpose of
		this document is to describe the protocol as it has been
		implemented.
		</t>
	</section>
	<section title="Requirements Language">
		<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 title="Protocol Overview">
		<t>
		The agent protocol is a packetised request-response protocol,
		solely driven by the client. It consists of a number of
		requests sent from the client to the server and a set of reply
		messages that are sent in response. At no time does the server
		send messages except in response to a client request. Replies
		are sent in order.
		</t>
		<t>
		All values in the agent protocol are encoded using the SSH wire
		representations specified by <xref target="RFC4251" />.
		Messages consist of a length, type and contents.
		</t>
		<figure><artwork>
   uint32                    message length
   byte                      message type
   byte[message length - 1]  message contents
		</artwork></figure>
	</section>
	<section title="Protocol Messages">
		<section title="Generic server responses">
			<t>
			The following generic messages may be sent by the server
			in response to requests from the client. On success the
			agent may reply either with:
			</t>
			<figure><artwork>
   byte                     SSH_AGENT_SUCCESS
			</artwork></figure>
			<t>
			or a request-specific success message.
			On failure, the agent may reply with:
			</t>
			<figure><artwork>
   byte                     SSH_AGENT_FAILURE
			</artwork></figure>
			<t>
			SSH_AGENT_FAILURE messages are also sent in reply to
			requests with unknown types.
			</t>
		</section>
		<section title="Adding keys to the agent">
			<t>
			Keys may be added to the agent using the
			SSH_AGENTC_ADD_IDENTITY or
			SSH_AGENTC_ADD_ID_CONSTRAINED messages.
			The latter variant allows adding keys with
			optional constraints on their usage.
			</t>
			<t>
			The generic format for the key
			SSH_AGENTC_ADD_IDENTITY message is:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_ADD_IDENTITY
    string                  key type
    byte[]                  key contents
    string                  key comment
			</artwork></figure>
			<t>
			Here "type" is the specified key type name, for example
			"ssh-rsa" for a RSA key as defined by
			<xref target="RFC4253" />. "contents"
			consists of the public and private components of the key
			and vary by key type, they are listed below for
			standard and commonly used key types. "comment" is
			an optional human-readable key name or comment
			as a UTF-8 string that may serve to identify the
			key in user-visible messages.
			</t>
			<t>
			The SSH_AGENTC_ADD_ID_CONSTRAINED is similar, but adds a
			extra field:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_ADD_ID_CONSTRAINED
    string                  type
    byte[]                  contents
    string                  comment
    constraint[]            constraints
			</artwork></figure>
			<t>
			Constraints are used to place limits on the validity
			or use of keys.
			<xref target="constraints" /> details constraint types
			and their format.
			</t>
			<t>
			An agent should reply with SSH_AGENT_SUCCESS
			if the key was successfully loaded
			as a result of one of these messages, or
			SSH_AGENT_FAILURE otherwise.
			</t>
			<section title="DSA keys">
				<t>
				DSA keys have key type "ssh-dss" and are
				defined in <xref target="RFC4253" />. They
				may be added to the agent using the following
				message. The "constraints" field is only
				present for the SSH_AGENTC_ADD_ID_CONSTRAINED
				message.
				</t>
				<figure><artwork>
    byte                    SSH_AGENTC_ADD_IDENTITY or
                            SSH_AGENTC_ADD_ID_CONSTRAINED
    string                  "ssh-dss"
    mpint                   p
    mpint                   q
    mpint                   g
    mpint                   y
    mpint                   x
    string                  comment
    constraint[]            constraints
				</artwork></figure>
				<t>
				The "p", "q", "g" values are the DSA domain
				parameters. "y" and "x" are the public and
				private keys respectively. These values are
				as defined by <xref target="FIPS.186-4" />.
				</t>
			</section>
			<section title="ECDSA keys">
				<t>
				ECDSA keys have key types starting with
				"ecdsa-sha2-" and are defined in
				<xref target="RFC5656" />. They
				may be added to the agent using the
				following message.
				The "constraints" field is only present for
				the SSH_AGENTC_ADD_ID_CONSTRAINED message.
				</t>
				<figure><artwork>
    byte                    SSH_AGENTC_ADD_IDENTITY or
                            SSH_AGENTC_ADD_ID_CONSTRAINED
    string                  key type
    string                  ecdsa_curve_name
    string                  Q
    mpint                   d
    string                  comment
    constraint[]            constraints
				</artwork></figure>
				<t>
				The values "Q" and "d" are the ECDSA public and
				private values respectively. Both are defined
				by <xref target="FIPS.186-4" />.
				</t>
			</section>
			<section title="ED25519 keys">
				<t>
				Ed25519 keys have key type "ssh-ed25519" and are
				defined in
				<xref target="RFC8709" />.
				They may be added to the agent using the
				following message. The "key constraints"
				field is only present for
				the SSH_AGENTC_ADD_ID_CONSTRAINED message.
				</t>
				<figure><artwork>
    byte                    SSH_AGENTC_ADD_IDENTITY or
                            SSH_AGENTC_ADD_ID_CONSTRAINED
    string                  "ssh-ed25519"
    string                  ENC(A)
    string                  k || ENC(A)
    string                  comment
    constraint[]            constraints
				</artwork></figure>
				<t>
				The first value is the 32 byte Ed25519
				public key
				<spanx style="verb">ENC(A)</spanx>.
				The second value is a concatenation of
				the 32 byte private key
				<spanx style="verb">k</spanx> and
				32 byte public
				<spanx style="verb">ENC(A)</spanx> key.
				The contents and interpretation of the
				<spanx style="verb">ENC(A)</spanx>
				and <spanx style="verb">k</spanx> values are
				defined by <xref target="RFC8032" />.
				</t>
			</section>
			<section title="RSA keys">
				<t>
				RSA keys have key type "ssh-rsa" and are
				defined in <xref target="RFC4253" />. They
				may be added to the agent using the following
				message. The "key constraints" field is only
				present for the
				SSH_AGENTC_ADD_ID_CONSTRAINED message.
				</t>
				<figure><artwork>
    byte                    SSH_AGENTC_ADD_IDENTITY or
                            SSH_AGENTC_ADD_ID_CONSTRAINED
    string                  "ssh-rsa"
    mpint                   n
    mpint                   e
    mpint                   d
    mpint                   iqmp
    mpint                   p
    mpint                   q
    string                  comment
    constraint[]            constraints
				</artwork></figure>
				<t>
				"n" is the public composite modulus.
				"p" and "q" are its constituent private
				prime factors. "e" is the public exponent.
				"iqmp" is the inverse of "q" modulo
				"p". All these values except "iqmp"
				(which can be calculated from the others)
				are defined by <xref target="FIPS.186-4" />.
				</t>
			</section>
			<section title="Adding keys from a token">
				<t>
				Keys hosted on smart-cards or other hardware
				tokens may be added using the
				SSH_AGENTC_ADD_SMARTCARD_KEY and
				SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
				requests. Note that "constraints" field is only
				included for the
				SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
				variant of this message.
				</t>
				<figure><artwork>
    byte                    SSH_AGENTC_ADD_SMARTCARD_KEY or
                            SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
    string                  id
    string                  PIN
    constraint[]            constraints
				</artwork></figure>
				<t>
				Here "id" is an opaque identifier for the
				hardware token and "PIN" is an optional
				password on PIN to unlock the key.
				The interpretation of "id" is not defined
				by the protocol but is left solely up to
				the agent.
				</t>
				<t>
				Typically only the public components of
				any keys supported on a hardware token
				will be loaded into an agent so, strictly
				speaking, this message really arranges
				future private key operations to be
				delegated to the hardware token in question.
				</t>
				<t>
				An agent should reply with SSH_AGENT_SUCCESS
				if one or more keys were successfully loaded
				as a result of one of these messages, or
				SSH_AGENT_FAILURE if no keys were found.
				The agent should also return SSH_AGENT_FAILURE
				if the token "id" was not recognised or if
				the agent doesn't support token-hosted keys
				at all.
				</t>
			</section>
			<section title="Key Constraints" anchor="constraints">
				<t>
				A number of constraints and may be used in the
				constrained variants of the key add messages.
				Each constraint is represented by a type byte
				followed by zero or more value bytes.
				</t>
				<t>
				Zero or more constraints may be specified when
				adding a key with one of the *_CONSTRAINED
				requests. Multiple constraints are appended
				consecutively to the end of the request:
				</t>
				<figure><artwork>
    byte                    constraint1_type
    byte[]                  constraint1_data
    byte                    constraint2_type
    byte[]                  constraint2_data
    ....
    byte                    constraintN_type
    byte[]                  constraintN_data
				</artwork></figure>
				<t>
				If an agent does not recognise or support a
				requested constraint it MUST refuse the request
				and return a SSH_AGENT_FAILURE message to the
				client.
				</t>
				<t>
				The following constraints are defined.
				</t>
				<section title="Key lifetime constraint">
					<t>
					This constraint requests that the
					agent limit the key's lifetime by
					deleting it after the specified
					duration (in seconds) has elapsed
					from the time the key was added to
					the agent.
					</t>
					<figure><artwork>
    byte                    SSH_AGENT_CONSTRAIN_LIFETIME
    uint32                  seconds
					</artwork></figure>
				</section>
				<section title="Key confirmation constraint">
					<t>
					This constraint requests that the
					agent require explicit user
					confirmation for each private key
					operation using the key. For example,
					the agent could present a confirmation
					dialog before completing a signature
					operation.
					</t>
					<figure><artwork>
    byte                    SSH_AGENT_CONSTRAIN_CONFIRM
					</artwork></figure>
				</section>
				<section title="Constraint extensions">
					<t>
					Agents may implement experimental
					or private-use constraints through
					a extension constraint that supports
					named constraints.
					</t>
					<figure><artwork>
    byte                    SSH_AGENT_CONSTRAIN_EXTENSION
    string                  extension name
    byte[]                  extension-specific details
					</artwork></figure>
					<t>
					The extension name MUST consist of
					a UTF-8 string suffixed by the
					implementation domain following
					the naming scheme defined in
					Section 4.2 of
					<xref target="RFC4251" />,
					e.g.  "foo@example.com".
					</t>
				</section>
			</section>
		</section>
			<section title="Removing keys from the agent">
			<t>
			A client may request that an agent remove
			all keys that it stores:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_REMOVE_ALL_IDENTITIES
			</artwork></figure>
			<t>
			On receipt of such a message, an agent
			shall delete all keys that it is holding
			and reply with SSH_AGENT_SUCCESS.
			</t>
			<t>
			Specific keys may also be removed:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_REMOVE_IDENTITY
    string                  key blob
			</artwork></figure>
			<t>
			Where "key blob" is the standard public
			key encoding of the key to be removed.
			SSH protocol key encodings are defined in
			<xref target="RFC4253" /> for "ssh-rsa" and
			"ssh-dss" keys, in <xref target="RFC5656" />
			for "ecdsa-sha2-*" keys and in
			<xref target="RFC8709" />
			for "ssh-ed25519" keys.
			</t>
			<t>
			An agent shall reply with SSH_AGENT_SUCCESS
			if the key was deleted or SSH_AGENT_FAILURE
			if it was not found.
			</t>
			<t>
			Smartcard keys may be removed using:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_REMOVE_SMARTCARD_KEY
    string                  reader id
    string                  PIN
			</artwork></figure>
			<t>
			Where "reader id" is an opaque identifier for
			the smartcard reader and "PIN" is an optional
			password or PIN (not typically used).
			Requesting deletion of smartcard-hosted keys
			will cause the agent to remove
			all keys loaded from that smartcard.
			</t>
			<t>
			An agent shall reply with SSH_AGENT_SUCCESS
			if the key was deleted or SSH_AGENT_FAILURE
			if it was not found.
			</t>
		</section>
		<section title="Requesting a list of keys">
			<t>
			A client may request a list of keys from an
			agent using the following message:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_REQUEST_IDENTITIES
			</artwork></figure>
			<t>
			The agent shall reply with a message with
			the following preamble.
			</t>
			<figure><artwork>
    byte                    SSH_AGENT_IDENTITIES_ANSWER
    uint32                  nkeys
			</artwork></figure>
			<t>
			Where "nkeys" indicates the number of keys
			to follow.  Following the preamble are zero
			or more keys, each encoded as:
			</t>
			<figure><artwork>
    string                  key blob
    string                  comment
			</artwork></figure>
			<t>
			Where "key blob" is the wire encoding of the
			public key and "comment" is a human-readable
			comment encoded as a UTF-8 string.
			</t>
		</section>
		<section title="Private key operations">
			<t>
				A client may request the agent perform a
				private key signature operation using the
				following message:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_SIGN_REQUEST
    string                  key blob
    string                  data
    uint32                  flags
			</artwork></figure>
			<t>
			Where "key blob" is the key requested to
			perform the signature, "data" is the data
			to be signed and "flags" is a bitfield
			containing the bitwise OR of zero or more
			signature flags (see below).
			</t>
			<t>
			If the agent does not support the requested
			flags, or is otherwise unable or unwilling to
			generate the signature (e.g. because it
			doesn't have the specified key, or the user
			refused confirmation of a constrained
			key), it must reply with a SSH_AGENT_FAILURE
			message.
			</t>
			<t>
			On success, the agent shall reply with:
			</t>
			<figure><artwork>
    byte                    SSH_AGENT_SIGN_RESPONSE
    string                  signature
			</artwork></figure>
			<t>
			The signature format is specific to the
			algorithm of the key type in use.
			SSH protocol signature formats are defined in
			<xref target="RFC4253" /> for "ssh-rsa" and
			"ssh-dss" keys, in <xref target="RFC5656" />
			for "ecdsa-sha2-*" keys and in
			<xref target="RFC8709" />
			for "ssh-ed25519" keys.
			</t>
			<section title="Signature flags">
			<t>
			Two flags are currently defined for
			signature request messages:
			SSH_AGENT_RSA_SHA2_256 and SSH_AGENT_RSA_SHA2_512.
			These two flags are only valid for
			"ssh-rsa" keys and request that the agent
			return a signature using
			the "rsa-sha2-256" or "rsa-sha2-512"
			signature methods respectively. These
			signature schemes are defined in
			<xref target="RFC8332" />.
			</t>
			</section>
		</section>
		<section title="Locking and unlocking an agent">
			<t>
			The agent protocol supports requesting that
			an agent temporarily lock itself with a
			pass-phrase. When locked an agent should
			suspend processing of sensitive operations
			(private key operations at the very least)
			until it has been unlocked with the same
			pass-phrase.
			</t>
			<t>
			The following message requests agent locking
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_LOCK
    string                  passphrase
			</artwork></figure>
			<t>
			The agent shall reply with SSH_AGENT_SUCCESS
			if locked successfully or SSH_AGENT_FAILURE
			otherwise (e.g. if the agent was already
			locked).
			</t>
			<t>
			The following message requests unlocking an
			agent:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_UNLOCK
    string                  passphrase
			</artwork></figure>
			<t>
			If the agent is already locked and the
			pass-phrase matches the one used to lock it
			then it should unlock and reply with
			SSH_AGENT_SUCCESS. If the agent is unlocked
			or if the the pass-phrase does not match
			it should reply with SSH_AGENT_FAILURE.
			An agent SHOULD take countermeasures against
			brute-force guessing attacks against the
			pass-phrase.
			</t>
		</section>
		<section title="Extension mechanism">
			<t>
			The agent protocol includes an optional extension
			mechanism that allows vendor-specific and
			experimental messages to be sent via the
			agent protocol.  Extension requests from
			the client consist of:
			</t>
			<figure><artwork>
    byte                    SSH_AGENTC_EXTENSION
    string                  extension type
    byte[]                  extension contents
			</artwork></figure>
			<t>
			The extension type indicates the type of the
			extension message as a UTF-8 string.
			Implementation-specific
			extensions should be suffixed by the
			implementation domain following the extension
			naming scheme defined in Section 4.2 of
			<xref target="RFC4251" />,
			e.g.  "foo@example.com".
			</t>
			<t>
			An agent that does not support extensions of
			the supplied type MUST reply with an empty
			SSH_AGENT_FAILURE message. This reply is also
			sent by agents that do not support the
			extension mechanism at all.
			</t>
			<t>
			The contents of successful extension reply
			messages are specific to the extension type.
			Extension requests may return
			SSH_AGENT_SUCCESS on success or some other
			extension-specific message.
			</t>
			<t>
			Extension failure should be signaled using the
			SSH_AGENT_EXTENSION_FAILURE code - extensions
			should not use the standard SSH_AGENT_FAILURE
			message. This allows failed requests to be
			distinguished from the extension not being
			supported.
			</t>
			<section title="Query extension">
				<t>
				A single, optional extension request
				<spanx style="verb">query</spanx>
				is defined to allow a client to query
				which, if any, extensions are supported
				by an agent.
				</t>
				<t>
				If an agent supports the
				<spanx style="verb">query</spanx>
				extension is should reply with
				a list of supported extension names.
				</t>
				<figure><artwork>
    byte                    SSH_AGENT_SUCCESS
    string[]                extension type
				</artwork></figure>
			</section>
		</section>
	</section>
	<section title="Protocol numbers">
		<section anchor="messagenum" title="Message numbers">
			<t>
			The following numbers are used for requests from the
			client to the agent.
			</t>
			<figure><artwork>
    SSH_AGENTC_REQUEST_IDENTITIES                  11
    SSH_AGENTC_SIGN_REQUEST                        13
    SSH_AGENTC_ADD_IDENTITY                        17
    SSH_AGENTC_REMOVE_IDENTITY                     18
    SSH_AGENTC_REMOVE_ALL_IDENTITIES               19
    SSH_AGENTC_ADD_ID_CONSTRAINED                  25
    SSH_AGENTC_ADD_SMARTCARD_KEY                   20
    SSH_AGENTC_REMOVE_SMARTCARD_KEY                21
    SSH_AGENTC_LOCK                                22
    SSH_AGENTC_UNLOCK                              23
    SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED       26
    SSH_AGENTC_EXTENSION                           27
			</artwork></figure>
			<t>
			The following numbers are used for replies from the
			agent to the client.
			</t>
			<figure><artwork>
    SSH_AGENT_FAILURE                               5
    SSH_AGENT_SUCCESS                               6
    SSH_AGENT_EXTENSION_FAILURE                     28
    SSH_AGENT_IDENTITIES_ANSWER                     12
    SSH_AGENT_SIGN_RESPONSE                         14
			</artwork></figure>
			<section title="Reserved message numbers">
				<t>
				The following message numbers are reserved
				for implementations that implement support for
				the legacy SSH protocol version 1:
				1-4, 7-9 and 24 (inclusive).
				These message numbers MAY be used by an
				implementation supporting the legacy protocol
				but MUST NOT be reused otherwise.
				</t>
			</section>
		</section>
		<section anchor="constraintnum" title="Constraint identifiers">
			<t>
			The following numbers are used to identify key
			constraints. These are only used in key constraints
			and are not sent as message numbers.
			</t>
			<figure><artwork>
    SSH_AGENT_CONSTRAIN_LIFETIME                    1
    SSH_AGENT_CONSTRAIN_CONFIRM                     2
    SSH_AGENT_CONSTRAIN_EXTENSION                   255
			</artwork></figure>
		</section>
		<section anchor="sigflagnum" title="Signature flags">
			<t>
			The following numbers may be present in signature
			request (SSH_AGENTC_SIGN_REQUEST) messages.
			These flags form a bit field by taking the logical
			OR of zero or more flags.
			</t>
			<figure><artwork>
    SSH_AGENT_RSA_SHA2_256                          2
    SSH_AGENT_RSA_SHA2_512                          4
			</artwork></figure>
			<t>
			The flag value 1 is reserved for historical
			implementations.
			</t>
		</section>
	</section>
	<section anchor="Acknowledgements" title="Acknowledgements">
		<t>
		This protocol was designed and first implemented by
		Markus Friedl, based on a similar protocol for an agent
		to support the legacy SSH version 1 by Tatu Ylonen. 
		</t>
		<t>
		Thanks to Simon Tatham <!-- and ... --> who reviewed and helped
		improve this document.
		</t>
	</section>
	<section anchor="IANA" title="IANA Considerations">
		<t>
		This protocol requires three registries be established, one for
		message numbers, one for constraints and one for
		signature request flags.
		</t>
		<section title="New registry: SSH agent protocol numbers">
			<t>
			This registry, titled "SSH agent protocol numbers"
			records the message numbers for client requests and
			agent responses.
			Its initial state should consist of the following
			numbers and reservations.
			Future message number allocations shall require
			specification in the form of an RFC
			(RFC REQUIRED as per <xref target="RFC5226" />).
			</t>
<texttable title="Initial registry state: SSH agent protocol numbers" suppress-title="true" style="headers">
<ttcol align='right'>Number</ttcol>
<ttcol align='left'>Identifier</ttcol>
<ttcol align='left'>Reference</ttcol>
<c>1</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>2</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>3</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>4</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>5</c><c>SSH_AGENT_FAILURE</c><c><xref target="messagenum" /></c>
<c>6</c><c>SSH_AGENT_SUCCESS</c><c><xref target="messagenum" /></c>
<c>7</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>8</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>9</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>10</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>11</c><c>SSH_AGENTC_REQUEST_IDENTITIES</c><c><xref target="messagenum" /></c>
<c>12</c><c>SSH_AGENT_IDENTITIES_ANSWER</c><c><xref target="messagenum" /></c>
<c>13</c><c>SSH_AGENTC_SIGN_REQUEST</c><c><xref target="messagenum" /></c>
<c>14</c><c>SSH_AGENT_SIGN_RESPONSE</c><c><xref target="messagenum" /></c>
<c>15</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>16</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>17</c><c>SSH_AGENTC_ADD_IDENTITY</c><c><xref target="messagenum" /></c>
<c>18</c><c>SSH_AGENTC_REMOVE_IDENTITY</c><c><xref target="messagenum" /></c>
<c>19</c><c>SSH_AGENTC_REMOVE_ALL_IDENTITIES</c><c><xref target="messagenum" /></c>
<c>20</c><c>SSH_AGENTC_ADD_SMARTCARD_KEY</c><c><xref target="messagenum" /></c>
<c>21</c><c>SSH_AGENTC_REMOVE_SMARTCARD_KEY</c><c><xref target="messagenum" /></c>
<c>22</c><c>SSH_AGENTC_LOCK</c><c><xref target="messagenum" /></c>
<c>23</c><c>SSH_AGENTC_UNLOCK</c><c><xref target="messagenum" /></c>
<c>24</c><c>reserved</c><c><xref target="messagenum" /></c>
<c>25</c><c>SSH_AGENTC_ADD_ID_CONSTRAINED</c><c><xref target="messagenum" /></c>
<c>26</c><c>SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED</c><c><xref target="messagenum" /></c>
<c>27</c><c>SSH_AGENTC_EXTENSION</c><c><xref target="messagenum" /></c>
<c>28</c><c>SSH_AGENT_EXTENSION_FAILURE</c><c><xref target="messagenum" /></c>
</texttable>
		</section>
		<section title="New registry: SSH agent key constraint numbers">
			<t>
			This registry, titled "SSH agent key constraint numbers"
			records the message numbers for key use constraints.
			Its initial state should consist of the
			following numbers.
			Future constraint number allocations shall require
			specification in the form of an RFC
			(RFC REQUIRED as per <xref target="RFC5226" />).
			</t>
<texttable title="Initial registry state: SSH agent key constraint numbers" suppress-title="true" style="headers">
<ttcol align='right'>Number</ttcol>
<ttcol align='left'>Identifier</ttcol>
<ttcol align='left'>Reference</ttcol>
<c>1</c><c>SSH_AGENT_CONSTRAIN_LIFETIME</c><c><xref target="constraintnum" /></c>
<c>2</c><c>SSH_AGENT_CONSTRAIN_CONFIRM</c><c><xref target="constraintnum" /></c>
<c>255</c><c>SSH_AGENT_CONSTRAIN_EXTENSION</c><c><xref target="constraintnum" /></c>
</texttable>
		</section>
		<section title="New registry: SSH agent signature flags">
			<t>
			This registry, titled "SSH agent signature flags
			records the values for signature request
			(SSH_AGENTC_SIGN_REQUEST) flag values.
			Its initial state should consist of the
			following numbers. Note that as the flags are
			combined by bitwise OR, all flag values must be
			powers of two and the maximum available
			flag value is 0x80000000.
			</t>
			<t>
			Future constraint number allocations shall require
			specification in the form of an RFC
			(RFC REQUIRED as per <xref target="RFC5226" />).
			</t>
<texttable title="Initial registry state: SSH agent signature flags" suppress-title="true" style="headers">
<ttcol align='right'>Number</ttcol>
<ttcol align='left'>Identifier</ttcol>
<ttcol align='left'>Reference</ttcol>
<c>0x01</c><c>reserved</c><c><xref target="sigflagnum" /></c>
<c>0x02</c><c>SSH_AGENT_RSA_SHA2_256</c><c><xref target="sigflagnum" /></c>
<c>0x04</c><c>SSH_AGENT_RSA_SHA2_512</c><c><xref target="sigflagnum" /></c>
</texttable>
		</section>
	</section>
	<section anchor="Security" title="Security Considerations">
		<t>
		The agent is a service that
		is tasked with retaining and providing controlled access to
		what are typically long-lived login authentication credentials.
		It is by nature a sensitive and trusted software component.
		Moreover, the agent protocol itself does not include any
		authentication or transport security; ability to communicate
		with an agent is usually sufficient to invoke it to perform
		private key operations.
		</t>
		<t>
		Since being able to access an agent is usually sufficient
		to perform private key operations, it is critically
		important that the agent only be exposed to its owner.
		</t>
		<t>
		The primary design intention of an agent is that an attacker
		with unprivileged access to their victim's agent should be
		prevented from gaining a copy of any keys that have been loaded
		in to it. This may not preclude the attacker from
		stealing use of those keys (e.g. if they have been loaded
		without a confirmation constraint).
		</t>
		<t>
		Given this, the agent
		should, as far as possible, prevent its memory being read
		by other processes to direct theft of loaded keys. 
		This typically include disabling debugging interfaces and
		preventing process memory dumps on abnormal termination.
		</t>
		<t>
		Another, more subtle, means by which keys may be stolen are
		via cryptographic side-channels. Private key operations may
		leak information about the contents of keys via differences
		in timing, power use or by side-effects in the memory
		subsystems (e.g. CPU caches) of the host running the agent. 
		For the case of a local attacker and an agent holding
		unconstrained keys, the only limit on the number of private
		key operations the attacker may be able to observe is the
		rate at which the CPU can perform signatures. This grants
		the attacker an almost ideal oracle for side-channel attacks.
		While a full treatment of side-channel attacks is beyond the
		scope of this specification, agents SHOULD use cryptographic
		implementations that are resistant to side-channel attacks.
		</t>
	</section>
 </middle>

<back>
	<references title="Normative References">
		<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
		&RFC2119;

		&RFC4251;

		&RFC4253;

		&RFC5226;

		&RFC5656;

		&RFC8032;

		&RFC8332;

		&RFC8709;

		<reference anchor="FIPS.186-4">
			<front>
				<title>Digital Signature Standard (DSS)</title>
				<author>
					<organization>
						National Institute of
						Standards and Technology
					</organization>
				</author>
				<date month="July" year="2013" />
			</front>
			<seriesInfo name="FIPS" value="PUB 186-4" />
			<format target="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf" type="PDF" />
		</reference>
	</references>

<!--
	<references title="Informative References">
	</references>

	<section anchor="app-additional" title="Additional Stuff">
		<t>This becomes an Appendix.</t>
	</section>
-->
	</back>
</rfc>
