<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!-- <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> --> 
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="info"
  docName="draft-miller-ssh-agent-09"
  ipr="trust200902"
  obsoletes=""
  updates=""
  submissionType="IETF"
  xml:lang="en"
  version="3">
<!-- 
    * docName should be the name of your draft
    * category should be one of std, bcp, info, exp, historic
    * ipr should be one of trust200902, noModificationTrust200902, noDerivativesTrust200902, pre5378Trust200902
    * updates can be an RFC number as NNNN.
    * obsoletes can be an RFC number as NNNN 
-->

<front>
	<title>SSH Agent Protocol</title>
	<seriesInfo name="Internet-Draft" value="draft-miller-ssh-agent"/>
	<author fullname="Damien Miller" initials="D." surname="Miller">
		<organization>OpenSSH</organization>
		<address>
			<email>djm@openssh.com</email>  
			<uri>https://www.openssh.com/</uri>
		</address>
	</author>
	<date year="2023" month="8" day="23" />
	<area>General</area>
	<workgroup>Internet Engineering Task Force</workgroup>
	<keyword>ssh</keyword>
	<keyword>agent</keyword>
	<keyword>ssh-agent</keyword>
	<abstract>
		<t>
		This document describes a key agent protocol for use in
		the Secure Shell (SSH) protocol.
		</t>
	</abstract>
</front>

<middle>
<section><name>Introduction</name>
	<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 anchor="requirements"><name>Requirements Language</name>
		<t>
		The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
	        "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
	        RECOMMENDED", "MAY", and "OPTIONAL" 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>
    
<section><name>Protocol Overview</name>
	<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>
	Agents MAY implement support for only a subset of operations
	or available key types, and MAY additionally refuse abitrary
	operations in particular contexts. For example, an agent may
	allow only local clients of an agent to add or remove keys, or
	make particular subsets of keys available to a given client.
	For this reason, clients of the agent SHOULD be prepared to
	fail gracefully if any operation is refused.
	</t>
	<t>
	Note that this protocol is separate to and incompatible with
	the one described in the similarly-named
	<xref target="draft-ietf-secsh-agent-02" />.
	</t>
</section>
    
<section><name>Protocol Messages</name>
	<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>
	<sourcecode>
   uint32            length
   byte              type
   byte[length - 1]  contents
	</sourcecode>
	<section><name>Generic server responses</name>
		<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>
		<sourcecode>
   byte              SSH_AGENT_SUCCESS
		</sourcecode>
		<t>
		or a request-specific success message.
		On failure, the agent may reply with:
		</t>
		<sourcecode>
   byte              SSH_AGENT_FAILURE
		</sourcecode>
		<t>
		SSH_AGENT_FAILURE messages are also sent in reply to
		requests with unknown types.
		</t>
	</section>
	<section><name>Adding keys to the agent</name>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_ADD_IDENTITY
    string           key type
    byte[]           key contents
    string           key comment
		</sourcecode>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_ADD_ID_CONSTRAINED
    string           type
    byte[]           contents
    string           comment
    constraint[]     constraints
		</sourcecode>
		<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><name>DSA keys</name>
			<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>
			<sourcecode>
    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
			</sourcecode>
			<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><name>ECDSA keys</name>
			<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>
			<sourcecode>
    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
			</sourcecode>
			<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><name>EDDSA keys</name>
			<t>
			<xref target="RFC8709" /> defines Ed25519 and
			Ed448 with key type names "ssh-ed25519" and
			"ssh-ed448" respectively.
			These 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>
			<sourcecode>
    byte             SSH_AGENTC_ADD_IDENTITY or
                     SSH_AGENTC_ADD_ID_CONSTRAINED
    string           "ssh-ed25519" or "ssh-e448"
    string           ENC(A)
    string           k || ENC(A)
    string           comment
    constraint[]     constraints
			</sourcecode>
			<t>
			The first value is the EDDSA public key
			ENC(A).
			The second value is a concatenation of
			the private key k
			and the public
			ENC(A) key.
			The contents and interpretation of the
			ENC(A)
			and k values are
			defined by <xref target="RFC8032" />.
			</t>
		</section>
		<section><name>RSA keys</name>
			<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>
			<sourcecode>
    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
			</sourcecode>
			<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><name>Adding keys from a token</name>
			<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>
			<sourcecode>
    byte             SSH_AGENTC_ADD_SMARTCARD_KEY or
                     SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
    string           id
    string           PIN
    constraint[]     constraints
			</sourcecode>
			<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>
			<sourcecode>
    byte             constraint1_type
    byte[]           constraint1_data
    byte             constraint2_type
    byte[]           constraint2_data
    ....
    byte             constraintN_type
    byte[]           constraintN_data
			</sourcecode>
			<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><name>Key lifetime constraint</name>
				<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>
				<sourcecode>
    byte             SSH_AGENT_CONSTRAIN_LIFETIME
    uint32           seconds
				</sourcecode>
			</section>
			<section><name>Key confirmation constraint</name>
				<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>
				<sourcecode>
    byte             SSH_AGENT_CONSTRAIN_CONFIRM
				</sourcecode>
			</section>
			<section><name>Constraint extensions</name>
				<t>
				Agents may implement experimental
				or private-use constraints through
				a extension constraint that supports
				named constraints.
				</t>
				<sourcecode>
    byte             SSH_AGENT_CONSTRAIN_EXTENSION
    string           extension name
    byte[]           extension-specific details
				</sourcecode>
				<t>
				The extension name MUST consist of
				a UTF-8 string suffixed by the
				implementation domain following
				the naming scheme defined in
				<xref target="RFC4251" section="4.2" />,
				e.g.  "foo@example.com".
				</t>
			</section>
		</section>
	</section>
		<section><name>Removing keys from the agent</name>
		<t>
		A client may request that an agent remove
		all keys that it stores:
		</t>
		<sourcecode>
    byte             SSH_AGENTC_REMOVE_ALL_IDENTITIES
		</sourcecode>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_REMOVE_IDENTITY
    string           key blob
		</sourcecode>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_REMOVE_SMARTCARD_KEY
    string           reader id
    string           PIN
		</sourcecode>
		<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><name>Requesting a list of keys</name>
		<t>
		A client may request a list of keys from an
		agent using the following message:
		</t>
		<sourcecode>
    byte             SSH_AGENTC_REQUEST_IDENTITIES
		</sourcecode>
		<t>
		The agent shall reply with a message with
		the following preamble.
		</t>
		<sourcecode>
    byte             SSH_AGENT_IDENTITIES_ANSWER
    uint32           nkeys
		</sourcecode>
		<t>
		Where "nkeys" indicates the number of keys
		to follow.  Following the preamble are zero
		or more keys, each encoded as:
		</t>
		<sourcecode>
    string           key blob
    string           comment
		</sourcecode>
		<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><name>Private key operations</name>
		<t>
		A client may request the agent perform a
		private key signature operation using the
		following message:
		</t>
		<sourcecode>
    byte             SSH_AGENTC_SIGN_REQUEST
    string           key blob
    string           data
    uint32           flags
		</sourcecode>
		<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>
		<sourcecode>
    byte             SSH_AGENT_SIGN_RESPONSE
    string           signature
		</sourcecode>
		<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><name>Signature flags</name>
		<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><name>Locking and unlocking an agent</name>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_LOCK
    string           passphrase
		</sourcecode>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_UNLOCK
    string           passphrase
		</sourcecode>
		<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><name>Extension mechanism</name>
		<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>
		<sourcecode>
    byte             SSH_AGENTC_EXTENSION
    string           extension type
    byte[]           extension contents
		</sourcecode>
		<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
		<xref target="RFC4251" section="4.2" />,
		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 anchor="queryext"><name>Query extension</name>
			<t>
			A single, optional extension request "query"
			is defined to allow a client to query
			which, if any, extensions are supported
			by an agent.
			</t>
		<sourcecode>
    byte             SSH_AGENTC_EXTENSION
    string           "query"
		</sourcecode>
			<t>
			If an agent supports the query extension is
			should reply with a list of supported extension names.
			</t>
			<sourcecode>
    byte             SSH_AGENT_SUCCESS
    string[]         extension type
			</sourcecode>
		</section>
	</section>
</section>

<section><name>Forwarding access to an agent</name>
	<t>
	The agent protocol may be forwarded over a SSH connection,
	using the <xref target="RFC4254" /> connection protocol,
	allowing agent forwarding to be requested for any session
	channel, using a model that is similar to the connection
	protocol's support for X11 Forwarding
	(<xref target="RFC4254" section="6.3"/>)
	</t>
	<section anchor="fwdext" title="Advertising agent forwarding support">
		<t>
		Support for agent forwarding may be advertised by a
		SSH protocol server using the
		<xref target="RFC8308" /> extension
		mechanism using the name "agent-forward" in the
		SSH_MSG_EXT_INFO message.
		</t>
		<sourcecode>
    string           "agent-forward"
    string           "0" (version)
		</sourcecode>
		<t>
		Note that this protocol substantially predates the
		existence of the
		<xref target="RFC8308" /> extension mechanism and
		several widely-deployed SSH implementations that
		support agent forwarding do not advertise their ability
		to do so. Clients MAY opportunitically attempt to
		request agent forwarding in the absence of an
		<xref target="RFC8308" />
		advertisment using the vendor-specific names mentioned
		below.
		</t>
	</section>
	<section anchor="fwdreq"><name>Requesting agent forwarding</name>
		<t>
		A client may request agent forwarding for a
		previously-opened session using the following
		channel request.
		</t>
		<sourcecode>
    byte             SSH_MSG_CHANNEL_REQUEST
    string           channel_id
    string           "auth-agent-req@openssh.com" | "agent-forward"
    boolean          want_reply
		</sourcecode>
		<t>
		Where channel_id is
		the identifier for an established session channel
		(as returned from a previous SSH_MSG_CHANNEL_OPEN
		request, and the
		want_reply flag indicates
		whether the server should respond with a confirmation
		of whether the request was successful (as specified
		in <xref target="RFC4254" section="5.4"/>)
		</t>
		<t>
		As mentioned previously,
		many deployed implementations only support the former,
		pre-standardisation "auth-agent-req@openssh.com" request
		name. The latter "agent-req" name SHOULD only be used if
		support was explicitly advertised as per
		<xref target="fwdext" />.
		</t>
	</section>
	<section anchor="fwdtype"><name>Agent connection requests</name>
		<t>
		After a client has requested that a session have agent
		forwarding enabled, the server later may request a
		connection to the forwarded agent. The server does this
		by requesting a dedicated channel to communicate with
		the client's agent.
		</t>
		<sourcecode>
    byte             SSH_MSG_CHANNEL_OPEN
    string           "auth-agent@openssh.com" | "agent-connect"
    uint32           channel_id
    uint32           local_window
    uint32           local_maxpacket
		</sourcecode>
		<t>
		The channel_id,
		local_window and
		local_maxpacket fields
		should be interpreted as specified by
		<xref target="RFC4254" section="5.1"/>.
		</t>
		<t>
		As above, the latter "agent-connect" open type name
		SHOULD only be used if support was explicitly
		advertised as per <xref target="fwdext" />.
		</t>
		<t>
		A client SHOULD be prepared to handle multiple
		concurrent active agent connections.
		</t>
	</section>
</section>

<section><name>Protocol numbers</name>
	<section anchor="messagenum" title="Message numbers">
		<t>
		The following numbers are used for requests from the
		client to the agent.
		</t>
		<sourcecode>
    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
		</sourcecode>
		<t>
		The following numbers are used for replies from the
		agent to the client.
		</t>
		<sourcecode>
    SSH_AGENT_FAILURE                               5
    SSH_AGENT_SUCCESS                               6
    SSH_AGENT_EXTENSION_FAILURE                     28
    SSH_AGENT_IDENTITIES_ANSWER                     12
    SSH_AGENT_SIGN_RESPONSE                         14
		</sourcecode>
		<section anchor="reservednum"><name>Reserved message numbers</name>
			<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>
		<sourcecode>
    SSH_AGENT_CONSTRAIN_LIFETIME                    1
    SSH_AGENT_CONSTRAIN_CONFIRM                     2
    SSH_AGENT_CONSTRAIN_EXTENSION                   255
		</sourcecode>
	</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>
		<sourcecode>
    SSH_AGENT_RSA_SHA2_256                          2
    SSH_AGENT_RSA_SHA2_512                          4
		</sourcecode>
		<t>
		The flag value 1 is reserved for historical
		implementations.
		</t>
	</section>
</section>

<section anchor="IANA"><name>IANA Considerations</name>
	<t>
	This protocol requires three registries be established, one for
	message numbers, one for constraints and one for
	signature request flags.
	</t>
	<section><name>New registry: SSH agent protocol numbers</name>
		<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>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>2</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>3</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>4</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>5</td><td>SSH_AGENT_FAILURE</td><td><xref target="messagenum" /></td></tr>
<tr><td>6</td><td>SSH_AGENT_SUCCESS</td><td><xref target="messagenum" /></td></tr>
<tr><td>7</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>8</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>9</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>10</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>11</td><td>SSH_AGENTC_REQUEST_IDENTITIES</td><td><xref target="messagenum" /></td></tr>
<tr><td>12</td><td>SSH_AGENT_IDENTITIES_ANSWER</td><td><xref target="messagenum" /></td></tr>
<tr><td>13</td><td>SSH_AGENTC_SIGN_REQUEST</td><td><xref target="messagenum" /></td></tr>
<tr><td>14</td><td>SSH_AGENT_SIGN_RESPONSE</td><td><xref target="messagenum" /></td></tr>
<tr><td>15</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>16</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>17</td><td>SSH_AGENTC_ADD_IDENTITY</td><td><xref target="messagenum" /></td></tr>
<tr><td>18</td><td>SSH_AGENTC_REMOVE_IDENTITY</td><td><xref target="messagenum" /></td></tr>
<tr><td>19</td><td>SSH_AGENTC_REMOVE_ALL_IDENTITIES</td><td><xref target="messagenum" /></td></tr>
<tr><td>20</td><td>SSH_AGENTC_ADD_SMARTCARD_KEY</td><td><xref target="messagenum" /></td></tr>
<tr><td>21</td><td>SSH_AGENTC_REMOVE_SMARTCARD_KEY</td><td><xref target="messagenum" /></td></tr>
<tr><td>22</td><td>SSH_AGENTC_LOCK</td><td><xref target="messagenum" /></td></tr>
<tr><td>23</td><td>SSH_AGENTC_UNLOCK</td><td><xref target="messagenum" /></td></tr>
<tr><td>24</td><td>reserved</td><td><xref target="reservednum" /></td></tr>
<tr><td>25</td><td>SSH_AGENTC_ADD_ID_CONSTRAINED</td><td><xref target="messagenum" /></td></tr>
<tr><td>26</td><td>SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED</td><td><xref target="messagenum" /></td></tr>
<tr><td>27</td><td>SSH_AGENTC_EXTENSION</td><td><xref target="messagenum" /></td></tr>
<tr><td>28</td><td>SSH_AGENT_EXTENSION_FAILURE</td><td><xref target="messagenum" /></td></tr>
</tbody>
</table>
	</section>
	<section><name>New registry: SSH agent key constraint numbers</name>
		<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>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>SSH_AGENT_CONSTRAIN_LIFETIME</td><td><xref target="constraintnum" /></td></tr>
<tr><td>2</td><td>SSH_AGENT_CONSTRAIN_CONFIRM</td><td><xref target="constraintnum" /></td></tr>
<tr><td>255</td><td>SSH_AGENT_CONSTRAIN_EXTENSION</td><td><xref target="constraintnum" /></td></tr>
</tbody>
</table>
	</section>
	<section><name>New registry: SSH agent signature flags</name>
		<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>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>0x01</td><td>reserved</td><td><xref target="sigflagnum" /></td></tr>
<tr><td>0x02</td><td>SSH_AGENT_RSA_SHA2_256</td><td><xref target="sigflagnum" /></td></tr>
<tr><td>0x04</td><td>SSH_AGENT_RSA_SHA2_512</td><td><xref target="sigflagnum" /></td></tr>
</tbody>
</table>
	</section>
	<section><name>New registry: SSH agent extension request names</name>
		<t>
		This registry, titled "SSH agent extension request names"
		records the names used in the generic extension request
		message (SSH_AGENTC_EXTENSION).
		Its initial state should consist of the
		following names.
		</t>
		<t>
		Future constraint number allocations shall require
		specification in the form of an RFC
		(RFC REQUIRED as per <xref target="RFC5226" />).
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>query</td><td><xref target="queryext" /></td></tr>
</tbody>
</table>
	</section>
	<section title="Additions to SSH Extension Names">
		<t>
		IANA is requested to insert the following entries into the
		table Extension Names <xref target="IANA-SSH-EXT" /> under
		Secure Shell (SSH) Protocol Parameters
		<xref target="RFC4250" />.
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-forward</td><td><xref target="fwdext" /></td></tr>
</tbody>
</table>
	</section>
	<section title="Additions to SSH Connection Protocol Channel Request Names">
		<t>
		IANA is requested to insert the following entries into the
		table Connection Protocol Channel Request Names <xref target="IANA-SSH-CHANREQ" /> under
		Secure Shell (SSH) Protocol Parameters
		<xref target="RFC4250" />.
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-forward</td><td><xref target="fwdreq" /></td></tr>
</tbody>
</table>
	</section>
	<section title="Additions to SSH Connection Protocol Channel Types">
		<t>
		IANA is requested to insert the following entries into the
		table Connection Protocol Channel Types <xref target="IANA-SSH-CHANTYPE" /> under
		Secure Shell (SSH) Protocol Parameters
		<xref target="RFC4250" />.
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-connect</td><td><xref target="fwdtype" /></td></tr>
</tbody>
</table>
	</section>
</section>

<section anchor="Security"><name>Security Considerations</name>
	<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 and
	their authorised delegates.
	</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
	into 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
	and MAY take additional measures to hide the actual time
	spent processing private key operations.
	</t>
</section>
</middle>

<back>
<references>
	<name>References</name>
	<references><name>Normative References</name>
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4250.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4251.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4253.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4254.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5226.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5656.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8308.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8332.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8709.xml" />
		<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><name>Informative References</name>
			<reference anchor="IANA-SSH-CHANREQ" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Connection Protocol Channel Types</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>       
			<reference anchor="IANA-SSH-CHANTYPE" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Extension Names</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>       
			<reference anchor="IANA-SSH-EXT" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Connection Protocol Channel Request Names</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>       

		<!-- XXX bibtex gives me xml2rfc errors -->
		<!-- <xi:include href="https://datatracker.ietf.org/doc/bibxml3/draft-ietf-secsh-agent-02.xml" /> -->
		<reference anchor="draft-ietf-secsh-agent-02" target="https://datatracker.ietf.org/doc/html/draft-ietf-secsh-agent-02"><front>
			<title>Secure Shell Authentication Agent Protocol</title>
			<author surname="Ylonen" fullname="Tatu Ylonen" />
			<author surname="Rinne" fullname="Timo J. Rinne" />
			<author surname="Lehtinen" fullname="Sami Lehtinen" />
			<date year="2004" month="January"/>
			<abstract>
				<t>
				This document describes the Secure Shell
				authentication agent protocol (i.e., the
				protocol used between a client requesting
				authentication and the authentication agent).
				This protocol usually runs in a machine-spe-
				cific local channel or over a forwarded
				authentication channel.  It is assumed that
				the channel is trusted, so no protection for
				the communica- tions channel is provided by
				this protocol.
				</t>
			</abstract>
		</front></reference>
	</references>
</references>

<!--   
<section><name>Appendix 1</name>
	<t>
	This becomes an Appendix
	</t>
</section>
-->

<section anchor="Acknowledgements" numbered="false"><name>Acknowledgements</name>
	<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 Niels Möller who reviewed and helped
	improve this document.
	</t>
</section>


<!--
<section anchor="Contributors" numbered="false"><name>Contributors</name>
	<t>Thanks to all of the contributors.</t>
	<contact fullname="Jane Doe" initials="J" surname="Doe">
	<organization>Acme</organization>
	<address>
	<email>jdoe@example.com</email>
	</address>
	</contact>
</section>
-->

</back>
</rfc>
