PROTOCOL.agent 18.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
This describes the protocol used by OpenSSH's ssh-agent.

OpenSSH's agent supports managing keys for the standard SSH protocol
2 as well as the legacy SSH protocol 1. Support for these key types
is almost completely disjoint - in all but a few cases, operations on
protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.

Protocol 1 and protocol 2 keys are separated because of the differing
cryptographic usage: protocol 1 private RSA keys are used to decrypt
challenges that were encrypted with the corresponding public key,
whereas protocol 2 RSA private keys are used to sign challenges with
a private key for verification with the corresponding public key. It
is considered unsound practice to use the same key for signing and
encryption.

With a couple of exceptions, the protocol message names used in this
document indicate which type of key the message relates to. SSH_*
messages refer to protocol 1 keys only. SSH2_* messages refer to
19 20 21 22
protocol 2 keys. Furthermore, the names also indicate whether the
message is a request to the agent (*_AGENTC_*) or a reply from the
agent (*_AGENT_*). Section 3 below contains the mapping of the
protocol message names to their integer values.
23 24 25

1. Data types

26
Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
protocol makes use of some data types not defined in RFC 4251.

1.1 uint16

The "uint16" data type is a simple MSB-first 16 bit unsigned integer
encoded in two bytes.

1.2 mpint1

The "mpint1" type represents an arbitrary precision integer (bignum).
Its format is as follows:

	uint16			bits
	byte[(bits + 7) / 8]	bignum

"bignum" contains an unsigned arbitrary precision integer encoded as
eight bits per byte in big-endian (MSB first) format.

45
Note the difference between the "mpint1" encoding and the "mpint"
46
encoding defined in RFC 4251. Also note that the length of the encoded
47
integer is specified in bits, not bytes and that the byte length of
48 49 50 51 52 53 54 55 56 57 58
the integer must be calculated by rounding up the number of bits to the
nearest eight.

2. Protocol Messages

All protocol messages are prefixed with their length in bytes, encoded
as a 32 bit unsigned integer. Specifically:

	uint32			message_length
	byte[message_length]	message

59
The following message descriptions refer only to the content the
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
"message" field.

2.1 Generic server responses

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:

	byte			SSH_AGENT_SUCCESS

or a request-specific success message.

On failure, the agent may reply with:

	byte			SSH_AGENT_FAILURE

SSH_AGENT_FAILURE messages are also sent in reply to unknown request
types.

2.2 Adding keys to the agent

Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
respectively.

Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
"constraints" on their usage.

OpenSSH may be built with support for keys hosted on a smartcard
89
or other hardware security module. These keys may be added
90
to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
91
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

2.2.1 Key constraints

The OpenSSH agent supports some basic optional constraints on key usage.
At present there are two constraints defined.

The first constraint limits the validity duration of a key. It is
encoded as:

	byte			SSH_AGENT_CONSTRAIN_LIFETIME
	uint32			seconds

Where "seconds" contains the number of seconds that the key shall remain
valid measured from the moment that the agent receives it. After the
validity period has expired, OpenSSH's agent will erase these keys from
memory.

The second constraint requires the agent to seek explicit user
confirmation before performing private key operations with the loaded
key. This constraint is encoded as:

	byte			SSH_AGENT_CONSTRAIN_CONFIRM

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:

	byte			constraint1_type
120
	....			constraint1_data
121
	byte			constraint2_type
122
	....			constraint2_data
123 124
	....
	byte			constraintN_type
125
	....			constraintN_data
126 127 128

Such a sequence of zero or more constraints will be referred to below
as "constraint[]". Agents may determine whether there are constraints
129
by checking whether additional data exists in the "add key" request
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
after the key data itself. OpenSSH will refuse to add a key if it
contains unknown constraints.

2.2.2 Add protocol 1 key

A client may add a protocol 1 key to an agent with the following
request:

	byte			SSH_AGENTC_ADD_RSA_IDENTITY or
				SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
	uint32			ignored
	mpint1			rsa_n
	mpint1			rsa_e
	mpint1			rsa_d
	mpint1			rsa_iqmp
	mpint1			rsa_q
	mpint1			rsa_p
	string			key_comment
	constraint[]		key_constraints

Note that there is some redundancy in the key parameters; a key could be
fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
computation.

"key_constraints" may only be present if the request type is
155
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED.
156 157 158 159 160 161

The agent will reply with a SSH_AGENT_SUCCESS if the key has been
successfully added or a SSH_AGENT_FAILURE if an error occurred.

2.2.3 Add protocol 2 key

162 163
The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
keys may be added using the following request
164 165 166 167 168 169 170 171 172 173 174 175

	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ssh-dss"
	mpint			dsa_p
	mpint			dsa_q
	mpint			dsa_g
	mpint			dsa_public_key
	mpint			dsa_private_key
	string			key_comment
	constraint[]		key_constraints

Damien Miller's avatar
Damien Miller committed
176 177 178 179 180 181 182 183 184
DSA certificates may be added with:
	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ssh-dss-cert-v00@openssh.com"
	string			certificate
	mpint			dsa_private_key
	string			key_comment
	constraint[]		key_constraints

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
ECDSA keys may be added using the following request

	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ecdsa-sha2-nistp256" |
				"ecdsa-sha2-nistp384" |
				"ecdsa-sha2-nistp521"
	string			ecdsa_curve_name
	string			ecdsa_public_key
	mpint			ecdsa_private
	string			key_comment
	constraint[]		key_constraints

ECDSA certificates may be added with:
	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ecdsa-sha2-nistp256-cert-v01@openssh.com" |
				"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
				"ecdsa-sha2-nistp521-cert-v01@openssh.com"
	string			certificate
	mpint			ecdsa_private_key
	string			key_comment
	constraint[]		key_constraints

djm@openbsd.org's avatar
djm@openbsd.org committed
209 210 211
ED25519 keys may be added using the following request
	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
djm@openbsd.org's avatar
djm@openbsd.org committed
212
	string			"ssh-ed25519"
djm@openbsd.org's avatar
djm@openbsd.org committed
213 214 215 216 217 218 219 220
	mpint			ed25519_public_key
	mpint			ed25519_private_key
	string			key_comment
	constraint[]		key_constraints

ED25519 certificates may be added with:
	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
djm@openbsd.org's avatar
djm@openbsd.org committed
221
	string			"ssh-ed25519-cert-v01@openssh.com"
djm@openbsd.org's avatar
djm@openbsd.org committed
222 223 224 225 226 227
	string			certificate
	mpint			ed25519_public_key
	mpint			ed25519_private_key
	string			key_comment
	constraint[]		key_constraints

228 229 230 231 232 233 234 235 236 237 238 239 240 241
RSA keys may be added with this request:

	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ssh-rsa"
	mpint			rsa_n
	mpint			rsa_e
	mpint			rsa_d
	mpint			rsa_iqmp
	mpint			rsa_p
	mpint			rsa_q
	string			key_comment
	constraint[]		key_constraints

Damien Miller's avatar
Damien Miller committed
242 243 244 245 246 247 248 249 250 251 252 253 254
RSA certificates may be added with this request:

	byte			SSH2_AGENTC_ADD_IDENTITY or
				SSH2_AGENTC_ADD_ID_CONSTRAINED
	string			"ssh-rsa-cert-v00@openssh.com"
	string			certificate
	mpint			rsa_d
	mpint			rsa_iqmp
	mpint			rsa_p
	mpint			rsa_q
	string			key_comment
	constraint[]		key_constraints

255
Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
256 257 258 259
order to the protocol 1 add keys message. As with the corresponding
protocol 1 "add key" request, the private key is overspecified to avoid
redundant processing.

260
For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.

The agent will reply with a SSH_AGENT_SUCCESS if the key has been
successfully added or a SSH_AGENT_FAILURE if an error occurred.

2.2.4 Loading keys from a smartcard

The OpenSSH agent may have optional smartcard support built in to it. If
so, it supports an operation to load keys from a smartcard. Technically,
only the public components of the keys are loaded into the agent so
this operation really arranges for future private key operations to be
delegated to the smartcard.

	byte			SSH_AGENTC_ADD_SMARTCARD_KEY or
				SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
	string			reader_id
	string			pin
	constraint[]		key_constraints

280
"reader_id" is an identifier to a smartcard reader and "pin"
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
is a PIN or passphrase used to unlock the private key(s) on the
device. "key_constraints" may only be present if the request type is
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.

This operation may load all SSH keys that are unlocked using the
"pin" on the specified reader. The type of key loaded (protocol 1
or protocol 2) will be specified by the smartcard itself, it is not
client-specified.

The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
The agent will also return SSH_AGENT_FAILURE if it does not support
smartcards.

2.3 Removing multiple keys

A client may request that an agent delete all protocol 1 keys using the
following request:

	byte			SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES

This message requests the deletion of all protocol 2 keys:

	byte			SSH2_AGENTC_REMOVE_ALL_IDENTITIES

On success, the agent will delete all keys of the requested type and
reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
will reply with SSH_AGENT_FAILURE.

Note that, to delete all keys (both protocol 1 and 2), a client
must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.

2.4 Removing specific keys

2.4.1 Removing a protocol 1 key

Removal of a protocol 1 key may be requested with the following message:

	byte 			SSH_AGENTC_REMOVE_RSA_IDENTITY
	uint32			key_bits
	mpint1			rsa_e
	mpint1			rsa_n

Note that key_bits is strictly redundant, as it may be inferred by the
length of rsa_n.

The agent will delete any private key matching the specified public key
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
return SSH_AGENT_FAILURE.

2.4.2 Removing a protocol 2 key

Protocol 2 keys may be removed with the following request:

	byte			SSH2_AGENTC_REMOVE_IDENTITY
	string			key_blob

Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
340
Algorithms" for any of the supported protocol 2 key types.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392

The agent will delete any private key matching the specified public key
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
return SSH_AGENT_FAILURE.

2.4.3 Removing keys loaded from a smartcard

A client may request that a server remove one or more smartcard-hosted
keys using this message:

	byte			SSH_AGENTC_REMOVE_SMARTCARD_KEY
	string			reader_id
	string			pin

"reader_id" the an identifier to a smartcard reader and "pin" is a PIN
or passphrase used to unlock the private key(s) on the device.

When this message is received, and if the agent supports
smartcard-hosted keys, it will delete all keys that are hosted on the
specified smartcard that may be accessed with the given "pin".

The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
The agent will also return SSH_AGENT_FAILURE if it does not support
smartcards.

2.5 Requesting a list of known keys

An agent may be requested to list which keys it holds. Different
requests exist for protocol 1 and protocol 2 keys.

2.5.1 Requesting a list of protocol 1 keys

To request a list of protocol 1 keys that are held in the agent, a
client may send the following message:

	byte			SSH_AGENTC_REQUEST_RSA_IDENTITIES

The agent will reply with the following message:

	byte			SSH_AGENT_RSA_IDENTITIES_ANSWER
	uint32			num_keys

Followed by zero or more consecutive keys, encoded as:

	uint32			bits
	mpint1			rsa_e
	mpint1			rsa_n
	string			key_comment

2.5.2 Requesting a list of protocol 2 keys

393
A client may send the following message to request a list of
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
protocol 2 keys that are stored in the agent:

	byte			SSH2_AGENTC_REQUEST_IDENTITIES

The agent will reply with the following message header:

	byte			SSH2_AGENT_IDENTITIES_ANSWER
	uint32			num_keys

Followed by zero or more consecutive keys, encoded as:

	string			key_blob
	string			key_comment

Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
409
Algorithms" for any of the supported protocol 2 key types.
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

2.6 Private key operations

The purpose of the agent is to perform private key operations, such as
signing and encryption without requiring a passphrase to unlock the
key and without allowing the private key itself to be exposed. There
are separate requests for the protocol 1 and protocol 2 private key
operations.

2.6.1 Protocol 1 private key challenge

The private key operation used in version 1 of the SSH protocol is
decrypting a challenge that has been encrypted with a public key.
It may be requested using this message:

	byte			SSH_AGENTC_RSA_CHALLENGE
	uint32			ignored
	mpint1			rsa_e
	mpint1			rsa_n
	mpint1			encrypted_challenge
	byte[16]		session_id
	uint32			response_type /* must be 1 */

"rsa_e" and "rsa_n" are used to identify which private key to use.
"encrypted_challenge" is a challenge blob that has (presumably)
djm@openbsd.org's avatar
djm@openbsd.org committed
435
been encrypted with the public key and must be in the range
436 437
1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
session ID (computed from the server host key, the server semi-ephemeral
438
key and the session cookie).
439 440 441 442 443 444

"ignored" and "response_type" exist for compatibility with legacy
implementations. "response_type" must be equal to 1; other response
types are not supported.

On receiving this request, the server decrypts the "encrypted_challenge"
445
using the private key matching the supplied (rsa_e, rsa_n) values. For
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
the response derivation, the decrypted challenge is represented as an
unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
smaller than 2^248 will have leading 0 bytes).

The response value is then calculated as:

	response = MD5(decrypted_challenge || session_id)

and returned in the following message

	byte			SSH_AGENT_RSA_RESPONSE
	byte[16]		response

If the agent cannot find the key specified by the supplied (rsa_e,
rsa_n) then it will return SSH_AGENT_FAILURE.

2.6.2 Protocol 2 private key signature request

A client may use the following message to request signing of data using
a protocol 2 key:

	byte			SSH2_AGENTC_SIGN_REQUEST
	string			key_blob
	string			data
	uint32			flags

Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
473 474 475
Algorithms" for any of the supported protocol 2 key types. "flags" is
a bit-mask, but at present only one possible value is defined (see below
for its meaning):
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578

	SSH_AGENT_OLD_SIGNATURE		1

Upon receiving this request, the agent will look up the private key that
corresponds to the public key contained in key_blob. It will use this
private key to sign the "data" and produce a signature blob using the
key type-specific method described in RFC 4253 section 6.6 "Public Key
Algorithms".

An exception to this is for "ssh-dss" keys where the "flags" word
contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
signature encoding is used in lieu of the standard one. In this case,
the DSA signature blob is encoded as:

	byte[40]		signature

The signature will be returned in the response message:

	byte			SSH2_AGENT_SIGN_RESPONSE
	string			signature_blob

If the agent cannot find the key specified by the supplied key_blob then
it will return SSH_AGENT_FAILURE.

2.7 Locking or unlocking an agent

The agent supports temporary locking with a passphrase to suspend
processing of sensitive operations until it has been unlocked with the
same passphrase. To lock an agent, a client send the following request:

	byte			SSH_AGENTC_LOCK
	string			passphrase

Upon receipt of this message and if the agent is not already locked,
it will suspend processing requests and return a SSH_AGENT_SUCCESS
reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.

While locked, the agent will refuse all requests except
SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
treated specially by a locked agent: it will always return an empty list
of keys.

To unlock an agent, a client may request:

	byte			SSH_AGENTC_UNLOCK
	string			passphrase

If the passphrase matches and the agent is locked, then it will resume
processing all requests and return SSH_AGENT_SUCCESS. If the agent
is not locked or the passphrase does not match then it will return
SSH_AGENT_FAILURE.

Locking and unlocking affects both protocol 1 and protocol 2 keys.

3. Protocol message numbers

3.1 Requests from client to agent for protocol 1 key operations

	SSH_AGENTC_REQUEST_RSA_IDENTITIES		1
	SSH_AGENTC_RSA_CHALLENGE			3
	SSH_AGENTC_ADD_RSA_IDENTITY			7
	SSH_AGENTC_REMOVE_RSA_IDENTITY			8
	SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES		9
	SSH_AGENTC_ADD_RSA_ID_CONSTRAINED		24

3.2 Requests from client to agent for protocol 2 key operations

	SSH2_AGENTC_REQUEST_IDENTITIES			11
	SSH2_AGENTC_SIGN_REQUEST			13
	SSH2_AGENTC_ADD_IDENTITY			17
	SSH2_AGENTC_REMOVE_IDENTITY			18
	SSH2_AGENTC_REMOVE_ALL_IDENTITIES		19
	SSH2_AGENTC_ADD_ID_CONSTRAINED			25

3.3 Key-type independent requests from client to agent

	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

3.4 Generic replies from agent to client

	SSH_AGENT_FAILURE				5
	SSH_AGENT_SUCCESS				6

3.5 Replies from agent to client for protocol 1 key operations

	SSH_AGENT_RSA_IDENTITIES_ANSWER			2
	SSH_AGENT_RSA_RESPONSE				4

3.6 Replies from agent to client for protocol 2 key operations

	SSH2_AGENT_IDENTITIES_ANSWER			12
	SSH2_AGENT_SIGN_RESPONSE			14

3.7 Key constraint identifiers

	SSH_AGENT_CONSTRAIN_LIFETIME			1
	SSH_AGENT_CONSTRAIN_CONFIRM			2

djm@openbsd.org's avatar
djm@openbsd.org committed
579
$OpenBSD: PROTOCOL.agent,v 1.10 2016/05/04 12:16:39 djm Exp $