Annotation of src/usr.bin/ssh/PROTOCOL.agent, Revision 1.11
1.1 djm 1: This describes the protocol used by OpenSSH's ssh-agent.
2:
3: OpenSSH's agent supports managing keys for the standard SSH protocol
4: 2 as well as the legacy SSH protocol 1. Support for these key types
5: is almost completely disjoint - in all but a few cases, operations on
6: protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.
7:
8: Protocol 1 and protocol 2 keys are separated because of the differing
9: cryptographic usage: protocol 1 private RSA keys are used to decrypt
10: challenges that were encrypted with the corresponding public key,
11: whereas protocol 2 RSA private keys are used to sign challenges with
12: a private key for verification with the corresponding public key. It
13: is considered unsound practice to use the same key for signing and
14: encryption.
15:
16: With a couple of exceptions, the protocol message names used in this
17: document indicate which type of key the message relates to. SSH_*
18: messages refer to protocol 1 keys only. SSH2_* messages refer to
1.4 stevesk 19: protocol 2 keys. Furthermore, the names also indicate whether the
20: message is a request to the agent (*_AGENTC_*) or a reply from the
21: agent (*_AGENT_*). Section 3 below contains the mapping of the
22: protocol message names to their integer values.
1.1 djm 23:
24: 1. Data types
25:
1.4 stevesk 26: Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
1.1 djm 27: protocol makes use of some data types not defined in RFC 4251.
28:
29: 1.1 uint16
30:
31: The "uint16" data type is a simple MSB-first 16 bit unsigned integer
32: encoded in two bytes.
33:
34: 1.2 mpint1
35:
36: The "mpint1" type represents an arbitrary precision integer (bignum).
37: Its format is as follows:
38:
39: uint16 bits
40: byte[(bits + 7) / 8] bignum
41:
42: "bignum" contains an unsigned arbitrary precision integer encoded as
43: eight bits per byte in big-endian (MSB first) format.
44:
1.4 stevesk 45: Note the difference between the "mpint1" encoding and the "mpint"
1.1 djm 46: encoding defined in RFC 4251. Also note that the length of the encoded
1.4 stevesk 47: integer is specified in bits, not bytes and that the byte length of
1.1 djm 48: the integer must be calculated by rounding up the number of bits to the
49: nearest eight.
50:
51: 2. Protocol Messages
52:
53: All protocol messages are prefixed with their length in bytes, encoded
54: as a 32 bit unsigned integer. Specifically:
55:
56: uint32 message_length
57: byte[message_length] message
58:
1.4 stevesk 59: The following message descriptions refer only to the content the
1.1 djm 60: "message" field.
61:
62: 2.1 Generic server responses
63:
64: The following generic messages may be sent by the server in response to
65: requests from the client. On success the agent may reply either with:
66:
67: byte SSH_AGENT_SUCCESS
68:
69: or a request-specific success message.
70:
71: On failure, the agent may reply with:
72:
73: byte SSH_AGENT_FAILURE
74:
75: SSH_AGENT_FAILURE messages are also sent in reply to unknown request
76: types.
77:
78: 2.2 Adding keys to the agent
79:
80: Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
81: SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
82: respectively.
83:
84: Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
85: and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
86: "constraints" on their usage.
87:
88: OpenSSH may be built with support for keys hosted on a smartcard
1.4 stevesk 89: or other hardware security module. These keys may be added
1.1 djm 90: to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
1.4 stevesk 91: SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
1.1 djm 92:
93: 2.2.1 Key constraints
94:
95: The OpenSSH agent supports some basic optional constraints on key usage.
96: At present there are two constraints defined.
97:
98: The first constraint limits the validity duration of a key. It is
99: encoded as:
100:
101: byte SSH_AGENT_CONSTRAIN_LIFETIME
102: uint32 seconds
103:
104: Where "seconds" contains the number of seconds that the key shall remain
105: valid measured from the moment that the agent receives it. After the
106: validity period has expired, OpenSSH's agent will erase these keys from
107: memory.
108:
109: The second constraint requires the agent to seek explicit user
110: confirmation before performing private key operations with the loaded
111: key. This constraint is encoded as:
112:
113: byte SSH_AGENT_CONSTRAIN_CONFIRM
114:
115: Zero or more constraints may be specified when adding a key with one
116: of the *_CONSTRAINED requests. Multiple constraints are appended
117: consecutively to the end of the request:
118:
119: byte constraint1_type
1.3 djm 120: .... constraint1_data
1.1 djm 121: byte constraint2_type
1.3 djm 122: .... constraint2_data
1.1 djm 123: ....
124: byte constraintN_type
1.3 djm 125: .... constraintN_data
1.1 djm 126:
127: Such a sequence of zero or more constraints will be referred to below
128: as "constraint[]". Agents may determine whether there are constraints
1.4 stevesk 129: by checking whether additional data exists in the "add key" request
1.1 djm 130: after the key data itself. OpenSSH will refuse to add a key if it
131: contains unknown constraints.
132:
133: 2.2.2 Add protocol 1 key
134:
135: A client may add a protocol 1 key to an agent with the following
136: request:
137:
138: byte SSH_AGENTC_ADD_RSA_IDENTITY or
139: SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
140: uint32 ignored
141: mpint1 rsa_n
142: mpint1 rsa_e
143: mpint1 rsa_d
144: mpint1 rsa_iqmp
145: mpint1 rsa_q
146: mpint1 rsa_p
147: string key_comment
148: constraint[] key_constraints
149:
150: Note that there is some redundancy in the key parameters; a key could be
151: fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
152: computation.
153:
154: "key_constraints" may only be present if the request type is
1.7 djm 155: SSH_AGENTC_ADD_RSA_ID_CONSTRAINED.
1.1 djm 156:
157: The agent will reply with a SSH_AGENT_SUCCESS if the key has been
158: successfully added or a SSH_AGENT_FAILURE if an error occurred.
159:
160: 2.2.3 Add protocol 2 key
161:
1.6 djm 162: The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
163: keys may be added using the following request
1.1 djm 164:
165: byte SSH2_AGENTC_ADD_IDENTITY or
166: SSH2_AGENTC_ADD_ID_CONSTRAINED
167: string "ssh-dss"
168: mpint dsa_p
169: mpint dsa_q
170: mpint dsa_g
171: mpint dsa_public_key
172: mpint dsa_private_key
173: string key_comment
174: constraint[] key_constraints
175:
1.5 djm 176: DSA certificates may be added with:
177: byte SSH2_AGENTC_ADD_IDENTITY or
178: SSH2_AGENTC_ADD_ID_CONSTRAINED
179: string "ssh-dss-cert-v00@openssh.com"
180: string certificate
181: mpint dsa_private_key
182: string key_comment
183: constraint[] key_constraints
184:
1.6 djm 185: ECDSA keys may be added using the following request
186:
187: byte SSH2_AGENTC_ADD_IDENTITY or
188: SSH2_AGENTC_ADD_ID_CONSTRAINED
189: string "ecdsa-sha2-nistp256" |
190: "ecdsa-sha2-nistp384" |
191: "ecdsa-sha2-nistp521"
192: string ecdsa_curve_name
193: string ecdsa_public_key
194: mpint ecdsa_private
195: string key_comment
196: constraint[] key_constraints
197:
198: ECDSA certificates may be added with:
199: byte SSH2_AGENTC_ADD_IDENTITY or
200: SSH2_AGENTC_ADD_ID_CONSTRAINED
201: string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
202: "ecdsa-sha2-nistp384-cert-v01@openssh.com" |
203: "ecdsa-sha2-nistp521-cert-v01@openssh.com"
204: string certificate
205: mpint ecdsa_private_key
206: string key_comment
207: constraint[] key_constraints
208:
1.9 djm 209: ED25519 keys may be added using the following request
210: byte SSH2_AGENTC_ADD_IDENTITY or
211: SSH2_AGENTC_ADD_ID_CONSTRAINED
1.10 djm 212: string "ssh-ed25519"
1.11 ! djm 213: string ed25519_public_key
! 214: string ed25519_private_key || ed25519_public_key
1.9 djm 215: string key_comment
216: constraint[] key_constraints
217:
218: ED25519 certificates may be added with:
219: byte SSH2_AGENTC_ADD_IDENTITY or
220: SSH2_AGENTC_ADD_ID_CONSTRAINED
1.10 djm 221: string "ssh-ed25519-cert-v01@openssh.com"
1.9 djm 222: string certificate
1.11 ! djm 223: string ed25519_public_key
! 224: string ed25519_private_key || ed25519_public_key
1.9 djm 225: string key_comment
226: constraint[] key_constraints
227:
1.11 ! djm 228: For both ssh-ed25519 and ssh-ed25519-cert-v01@openssh.com keys, the private
! 229: key has the public key appended (for historical reasons).
! 230:
1.1 djm 231: RSA keys may be added with this request:
232:
233: byte SSH2_AGENTC_ADD_IDENTITY or
234: SSH2_AGENTC_ADD_ID_CONSTRAINED
235: string "ssh-rsa"
236: mpint rsa_n
237: mpint rsa_e
238: mpint rsa_d
239: mpint rsa_iqmp
240: mpint rsa_p
241: mpint rsa_q
242: string key_comment
243: constraint[] key_constraints
244:
1.5 djm 245: RSA certificates may be added with this request:
246:
247: byte SSH2_AGENTC_ADD_IDENTITY or
248: SSH2_AGENTC_ADD_ID_CONSTRAINED
249: string "ssh-rsa-cert-v00@openssh.com"
250: string certificate
251: mpint rsa_d
252: mpint rsa_iqmp
253: mpint rsa_p
254: mpint rsa_q
255: string key_comment
256: constraint[] key_constraints
257:
1.4 stevesk 258: Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
1.1 djm 259: order to the protocol 1 add keys message. As with the corresponding
260: protocol 1 "add key" request, the private key is overspecified to avoid
261: redundant processing.
262:
1.6 djm 263: For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
1.1 djm 264: present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
265:
266: The agent will reply with a SSH_AGENT_SUCCESS if the key has been
267: successfully added or a SSH_AGENT_FAILURE if an error occurred.
268:
269: 2.2.4 Loading keys from a smartcard
270:
271: The OpenSSH agent may have optional smartcard support built in to it. If
272: so, it supports an operation to load keys from a smartcard. Technically,
273: only the public components of the keys are loaded into the agent so
274: this operation really arranges for future private key operations to be
275: delegated to the smartcard.
276:
277: byte SSH_AGENTC_ADD_SMARTCARD_KEY or
278: SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
279: string reader_id
280: string pin
281: constraint[] key_constraints
282:
1.4 stevesk 283: "reader_id" is an identifier to a smartcard reader and "pin"
1.1 djm 284: is a PIN or passphrase used to unlock the private key(s) on the
285: device. "key_constraints" may only be present if the request type is
286: SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.
287:
288: This operation may load all SSH keys that are unlocked using the
289: "pin" on the specified reader. The type of key loaded (protocol 1
290: or protocol 2) will be specified by the smartcard itself, it is not
291: client-specified.
292:
293: The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
294: been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
295: The agent will also return SSH_AGENT_FAILURE if it does not support
296: smartcards.
297:
298: 2.3 Removing multiple keys
299:
300: A client may request that an agent delete all protocol 1 keys using the
301: following request:
302:
303: byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES
304:
305: This message requests the deletion of all protocol 2 keys:
306:
307: byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES
308:
309: On success, the agent will delete all keys of the requested type and
310: reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
311: will reply with SSH_AGENT_FAILURE.
312:
313: Note that, to delete all keys (both protocol 1 and 2), a client
314: must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
315: SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.
316:
317: 2.4 Removing specific keys
318:
319: 2.4.1 Removing a protocol 1 key
320:
321: Removal of a protocol 1 key may be requested with the following message:
322:
323: byte SSH_AGENTC_REMOVE_RSA_IDENTITY
324: uint32 key_bits
325: mpint1 rsa_e
326: mpint1 rsa_n
327:
328: Note that key_bits is strictly redundant, as it may be inferred by the
329: length of rsa_n.
330:
331: The agent will delete any private key matching the specified public key
332: and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
333: return SSH_AGENT_FAILURE.
334:
335: 2.4.2 Removing a protocol 2 key
336:
337: Protocol 2 keys may be removed with the following request:
338:
339: byte SSH2_AGENTC_REMOVE_IDENTITY
1.2 djm 340: string key_blob
1.1 djm 341:
342: Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
1.6 djm 343: Algorithms" for any of the supported protocol 2 key types.
1.1 djm 344:
345: The agent will delete any private key matching the specified public key
346: and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
347: return SSH_AGENT_FAILURE.
348:
349: 2.4.3 Removing keys loaded from a smartcard
350:
351: A client may request that a server remove one or more smartcard-hosted
352: keys using this message:
353:
354: byte SSH_AGENTC_REMOVE_SMARTCARD_KEY
355: string reader_id
356: string pin
357:
358: "reader_id" the an identifier to a smartcard reader and "pin" is a PIN
359: or passphrase used to unlock the private key(s) on the device.
360:
361: When this message is received, and if the agent supports
362: smartcard-hosted keys, it will delete all keys that are hosted on the
363: specified smartcard that may be accessed with the given "pin".
364:
365: The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
366: been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
367: The agent will also return SSH_AGENT_FAILURE if it does not support
368: smartcards.
369:
370: 2.5 Requesting a list of known keys
371:
372: An agent may be requested to list which keys it holds. Different
373: requests exist for protocol 1 and protocol 2 keys.
374:
375: 2.5.1 Requesting a list of protocol 1 keys
376:
377: To request a list of protocol 1 keys that are held in the agent, a
378: client may send the following message:
379:
380: byte SSH_AGENTC_REQUEST_RSA_IDENTITIES
381:
382: The agent will reply with the following message:
383:
384: byte SSH_AGENT_RSA_IDENTITIES_ANSWER
385: uint32 num_keys
386:
387: Followed by zero or more consecutive keys, encoded as:
388:
389: uint32 bits
390: mpint1 rsa_e
391: mpint1 rsa_n
392: string key_comment
393:
394: 2.5.2 Requesting a list of protocol 2 keys
395:
1.4 stevesk 396: A client may send the following message to request a list of
1.1 djm 397: protocol 2 keys that are stored in the agent:
398:
399: byte SSH2_AGENTC_REQUEST_IDENTITIES
400:
401: The agent will reply with the following message header:
402:
403: byte SSH2_AGENT_IDENTITIES_ANSWER
404: uint32 num_keys
405:
406: Followed by zero or more consecutive keys, encoded as:
407:
1.2 djm 408: string key_blob
1.1 djm 409: string key_comment
410:
411: Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
1.6 djm 412: Algorithms" for any of the supported protocol 2 key types.
1.1 djm 413:
414: 2.6 Private key operations
415:
416: The purpose of the agent is to perform private key operations, such as
417: signing and encryption without requiring a passphrase to unlock the
418: key and without allowing the private key itself to be exposed. There
419: are separate requests for the protocol 1 and protocol 2 private key
420: operations.
421:
422: 2.6.1 Protocol 1 private key challenge
423:
424: The private key operation used in version 1 of the SSH protocol is
425: decrypting a challenge that has been encrypted with a public key.
426: It may be requested using this message:
427:
428: byte SSH_AGENTC_RSA_CHALLENGE
429: uint32 ignored
430: mpint1 rsa_e
431: mpint1 rsa_n
432: mpint1 encrypted_challenge
433: byte[16] session_id
434: uint32 response_type /* must be 1 */
435:
436: "rsa_e" and "rsa_n" are used to identify which private key to use.
437: "encrypted_challenge" is a challenge blob that has (presumably)
1.8 djm 438: been encrypted with the public key and must be in the range
1.1 djm 439: 1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
440: session ID (computed from the server host key, the server semi-ephemeral
1.4 stevesk 441: key and the session cookie).
1.1 djm 442:
443: "ignored" and "response_type" exist for compatibility with legacy
444: implementations. "response_type" must be equal to 1; other response
445: types are not supported.
446:
447: On receiving this request, the server decrypts the "encrypted_challenge"
1.4 stevesk 448: using the private key matching the supplied (rsa_e, rsa_n) values. For
1.1 djm 449: the response derivation, the decrypted challenge is represented as an
450: unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
451: smaller than 2^248 will have leading 0 bytes).
452:
453: The response value is then calculated as:
454:
455: response = MD5(decrypted_challenge || session_id)
456:
457: and returned in the following message
458:
459: byte SSH_AGENT_RSA_RESPONSE
460: byte[16] response
461:
462: If the agent cannot find the key specified by the supplied (rsa_e,
463: rsa_n) then it will return SSH_AGENT_FAILURE.
464:
465: 2.6.2 Protocol 2 private key signature request
466:
467: A client may use the following message to request signing of data using
468: a protocol 2 key:
469:
470: byte SSH2_AGENTC_SIGN_REQUEST
471: string key_blob
472: string data
473: uint32 flags
474:
475: Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
1.6 djm 476: Algorithms" for any of the supported protocol 2 key types. "flags" is
477: a bit-mask, but at present only one possible value is defined (see below
478: for its meaning):
1.1 djm 479:
480: SSH_AGENT_OLD_SIGNATURE 1
481:
482: Upon receiving this request, the agent will look up the private key that
483: corresponds to the public key contained in key_blob. It will use this
484: private key to sign the "data" and produce a signature blob using the
485: key type-specific method described in RFC 4253 section 6.6 "Public Key
486: Algorithms".
487:
488: An exception to this is for "ssh-dss" keys where the "flags" word
489: contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
490: signature encoding is used in lieu of the standard one. In this case,
491: the DSA signature blob is encoded as:
492:
493: byte[40] signature
494:
495: The signature will be returned in the response message:
496:
497: byte SSH2_AGENT_SIGN_RESPONSE
498: string signature_blob
499:
500: If the agent cannot find the key specified by the supplied key_blob then
501: it will return SSH_AGENT_FAILURE.
502:
503: 2.7 Locking or unlocking an agent
504:
505: The agent supports temporary locking with a passphrase to suspend
506: processing of sensitive operations until it has been unlocked with the
507: same passphrase. To lock an agent, a client send the following request:
508:
509: byte SSH_AGENTC_LOCK
510: string passphrase
511:
512: Upon receipt of this message and if the agent is not already locked,
513: it will suspend processing requests and return a SSH_AGENT_SUCCESS
514: reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.
515:
516: While locked, the agent will refuse all requests except
517: SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
518: SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
519: treated specially by a locked agent: it will always return an empty list
520: of keys.
521:
522: To unlock an agent, a client may request:
523:
524: byte SSH_AGENTC_UNLOCK
525: string passphrase
526:
527: If the passphrase matches and the agent is locked, then it will resume
528: processing all requests and return SSH_AGENT_SUCCESS. If the agent
529: is not locked or the passphrase does not match then it will return
530: SSH_AGENT_FAILURE.
531:
532: Locking and unlocking affects both protocol 1 and protocol 2 keys.
533:
534: 3. Protocol message numbers
535:
536: 3.1 Requests from client to agent for protocol 1 key operations
537:
538: SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
539: SSH_AGENTC_RSA_CHALLENGE 3
540: SSH_AGENTC_ADD_RSA_IDENTITY 7
541: SSH_AGENTC_REMOVE_RSA_IDENTITY 8
542: SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
543: SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
544:
545: 3.2 Requests from client to agent for protocol 2 key operations
546:
547: SSH2_AGENTC_REQUEST_IDENTITIES 11
548: SSH2_AGENTC_SIGN_REQUEST 13
549: SSH2_AGENTC_ADD_IDENTITY 17
550: SSH2_AGENTC_REMOVE_IDENTITY 18
551: SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
552: SSH2_AGENTC_ADD_ID_CONSTRAINED 25
553:
554: 3.3 Key-type independent requests from client to agent
555:
556: SSH_AGENTC_ADD_SMARTCARD_KEY 20
557: SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
558: SSH_AGENTC_LOCK 22
559: SSH_AGENTC_UNLOCK 23
560: SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
561:
562: 3.4 Generic replies from agent to client
563:
564: SSH_AGENT_FAILURE 5
565: SSH_AGENT_SUCCESS 6
566:
567: 3.5 Replies from agent to client for protocol 1 key operations
568:
569: SSH_AGENT_RSA_IDENTITIES_ANSWER 2
570: SSH_AGENT_RSA_RESPONSE 4
571:
572: 3.6 Replies from agent to client for protocol 2 key operations
573:
574: SSH2_AGENT_IDENTITIES_ANSWER 12
575: SSH2_AGENT_SIGN_RESPONSE 14
576:
577: 3.7 Key constraint identifiers
578:
579: SSH_AGENT_CONSTRAIN_LIFETIME 1
580: SSH_AGENT_CONSTRAIN_CONFIRM 2
581:
1.11 ! djm 582: $OpenBSD: PROTOCOL.agent,v 1.10 2016/05/04 12:16:39 djm Exp $