]>
Commit | Line | Data |
---|---|---|
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 | |
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. | |
23 | ||
24 | 1. Data types | |
25 | ||
26 | Because of support for legacy SSH protocol 1 keys, OpenSSH's agent | |
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 | ||
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 | 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 | ||
59 | The following message descriptions refer only to the content the | |
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 | |
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 | 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 | |
120 | .... constraint1_data | |
121 | byte constraint2_type | |
122 | .... constraint2_data | |
123 | .... | |
124 | byte constraintN_type | |
125 | .... constraintN_data | |
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 | |
129 | by checking whether additional data exists in the "add key" request | |
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 | |
155 | SSH_AGENTC_ADD_RSA_IDENTITY. | |
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 | ||
162 | The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may | |
163 | be added using the following request | |
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 | ||
176 | RSA keys may be added with this request: | |
177 | ||
178 | byte SSH2_AGENTC_ADD_IDENTITY or | |
179 | SSH2_AGENTC_ADD_ID_CONSTRAINED | |
180 | string "ssh-rsa" | |
181 | mpint rsa_n | |
182 | mpint rsa_e | |
183 | mpint rsa_d | |
184 | mpint rsa_iqmp | |
185 | mpint rsa_p | |
186 | mpint rsa_q | |
187 | string key_comment | |
188 | constraint[] key_constraints | |
189 | ||
190 | Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse | |
191 | order to the protocol 1 add keys message. As with the corresponding | |
192 | protocol 1 "add key" request, the private key is overspecified to avoid | |
193 | redundant processing. | |
194 | ||
195 | For both DSA and RSA key add requests, "key_constraints" may only be | |
196 | present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. | |
197 | ||
198 | The agent will reply with a SSH_AGENT_SUCCESS if the key has been | |
199 | successfully added or a SSH_AGENT_FAILURE if an error occurred. | |
200 | ||
201 | 2.2.4 Loading keys from a smartcard | |
202 | ||
203 | The OpenSSH agent may have optional smartcard support built in to it. If | |
204 | so, it supports an operation to load keys from a smartcard. Technically, | |
205 | only the public components of the keys are loaded into the agent so | |
206 | this operation really arranges for future private key operations to be | |
207 | delegated to the smartcard. | |
208 | ||
209 | byte SSH_AGENTC_ADD_SMARTCARD_KEY or | |
210 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED | |
211 | string reader_id | |
212 | string pin | |
213 | constraint[] key_constraints | |
214 | ||
215 | "reader_id" is an identifier to a smartcard reader and "pin" | |
216 | is a PIN or passphrase used to unlock the private key(s) on the | |
217 | device. "key_constraints" may only be present if the request type is | |
218 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED. | |
219 | ||
220 | This operation may load all SSH keys that are unlocked using the | |
221 | "pin" on the specified reader. The type of key loaded (protocol 1 | |
222 | or protocol 2) will be specified by the smartcard itself, it is not | |
223 | client-specified. | |
224 | ||
225 | The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have | |
226 | been successfully loaded or a SSH_AGENT_FAILURE if an error occurred. | |
227 | The agent will also return SSH_AGENT_FAILURE if it does not support | |
228 | smartcards. | |
229 | ||
230 | 2.3 Removing multiple keys | |
231 | ||
232 | A client may request that an agent delete all protocol 1 keys using the | |
233 | following request: | |
234 | ||
235 | byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES | |
236 | ||
237 | This message requests the deletion of all protocol 2 keys: | |
238 | ||
239 | byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES | |
240 | ||
241 | On success, the agent will delete all keys of the requested type and | |
242 | reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent | |
243 | will reply with SSH_AGENT_FAILURE. | |
244 | ||
245 | Note that, to delete all keys (both protocol 1 and 2), a client | |
246 | must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a | |
247 | SSH2_AGENTC_REMOVE_ALL_IDENTITIES request. | |
248 | ||
249 | 2.4 Removing specific keys | |
250 | ||
251 | 2.4.1 Removing a protocol 1 key | |
252 | ||
253 | Removal of a protocol 1 key may be requested with the following message: | |
254 | ||
255 | byte SSH_AGENTC_REMOVE_RSA_IDENTITY | |
256 | uint32 key_bits | |
257 | mpint1 rsa_e | |
258 | mpint1 rsa_n | |
259 | ||
260 | Note that key_bits is strictly redundant, as it may be inferred by the | |
261 | length of rsa_n. | |
262 | ||
263 | The agent will delete any private key matching the specified public key | |
264 | and return SSH_AGENT_SUCCESS. If no such key was found, the agent will | |
265 | return SSH_AGENT_FAILURE. | |
266 | ||
267 | 2.4.2 Removing a protocol 2 key | |
268 | ||
269 | Protocol 2 keys may be removed with the following request: | |
270 | ||
271 | byte SSH2_AGENTC_REMOVE_IDENTITY | |
272 | string key_blob | |
273 | ||
274 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | |
275 | Algorithms" for either of the supported key types: "ssh-dss" or | |
276 | "ssh-rsa". | |
277 | ||
278 | The agent will delete any private key matching the specified public key | |
279 | and return SSH_AGENT_SUCCESS. If no such key was found, the agent will | |
280 | return SSH_AGENT_FAILURE. | |
281 | ||
282 | 2.4.3 Removing keys loaded from a smartcard | |
283 | ||
284 | A client may request that a server remove one or more smartcard-hosted | |
285 | keys using this message: | |
286 | ||
287 | byte SSH_AGENTC_REMOVE_SMARTCARD_KEY | |
288 | string reader_id | |
289 | string pin | |
290 | ||
291 | "reader_id" the an identifier to a smartcard reader and "pin" is a PIN | |
292 | or passphrase used to unlock the private key(s) on the device. | |
293 | ||
294 | When this message is received, and if the agent supports | |
295 | smartcard-hosted keys, it will delete all keys that are hosted on the | |
296 | specified smartcard that may be accessed with the given "pin". | |
297 | ||
298 | The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have | |
299 | been successfully removed or a SSH_AGENT_FAILURE if an error occurred. | |
300 | The agent will also return SSH_AGENT_FAILURE if it does not support | |
301 | smartcards. | |
302 | ||
303 | 2.5 Requesting a list of known keys | |
304 | ||
305 | An agent may be requested to list which keys it holds. Different | |
306 | requests exist for protocol 1 and protocol 2 keys. | |
307 | ||
308 | 2.5.1 Requesting a list of protocol 1 keys | |
309 | ||
310 | To request a list of protocol 1 keys that are held in the agent, a | |
311 | client may send the following message: | |
312 | ||
313 | byte SSH_AGENTC_REQUEST_RSA_IDENTITIES | |
314 | ||
315 | The agent will reply with the following message: | |
316 | ||
317 | byte SSH_AGENT_RSA_IDENTITIES_ANSWER | |
318 | uint32 num_keys | |
319 | ||
320 | Followed by zero or more consecutive keys, encoded as: | |
321 | ||
322 | uint32 bits | |
323 | mpint1 rsa_e | |
324 | mpint1 rsa_n | |
325 | string key_comment | |
326 | ||
327 | 2.5.2 Requesting a list of protocol 2 keys | |
328 | ||
329 | A client may send the following message to request a list of | |
330 | protocol 2 keys that are stored in the agent: | |
331 | ||
332 | byte SSH2_AGENTC_REQUEST_IDENTITIES | |
333 | ||
334 | The agent will reply with the following message header: | |
335 | ||
336 | byte SSH2_AGENT_IDENTITIES_ANSWER | |
337 | uint32 num_keys | |
338 | ||
339 | Followed by zero or more consecutive keys, encoded as: | |
340 | ||
341 | string key_blob | |
342 | string key_comment | |
343 | ||
344 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | |
345 | Algorithms" for either of the supported key types: "ssh-dss" or | |
346 | "ssh-rsa". | |
347 | ||
348 | 2.6 Private key operations | |
349 | ||
350 | The purpose of the agent is to perform private key operations, such as | |
351 | signing and encryption without requiring a passphrase to unlock the | |
352 | key and without allowing the private key itself to be exposed. There | |
353 | are separate requests for the protocol 1 and protocol 2 private key | |
354 | operations. | |
355 | ||
356 | 2.6.1 Protocol 1 private key challenge | |
357 | ||
358 | The private key operation used in version 1 of the SSH protocol is | |
359 | decrypting a challenge that has been encrypted with a public key. | |
360 | It may be requested using this message: | |
361 | ||
362 | byte SSH_AGENTC_RSA_CHALLENGE | |
363 | uint32 ignored | |
364 | mpint1 rsa_e | |
365 | mpint1 rsa_n | |
366 | mpint1 encrypted_challenge | |
367 | byte[16] session_id | |
368 | uint32 response_type /* must be 1 */ | |
369 | ||
370 | "rsa_e" and "rsa_n" are used to identify which private key to use. | |
371 | "encrypted_challenge" is a challenge blob that has (presumably) | |
372 | been encrypted with the public key and must be in the range | |
373 | 1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 | |
374 | session ID (computed from the server host key, the server semi-ephemeral | |
375 | key and the session cookie). | |
376 | ||
377 | "ignored" and "response_type" exist for compatibility with legacy | |
378 | implementations. "response_type" must be equal to 1; other response | |
379 | types are not supported. | |
380 | ||
381 | On receiving this request, the server decrypts the "encrypted_challenge" | |
382 | using the private key matching the supplied (rsa_e, rsa_n) values. For | |
383 | the response derivation, the decrypted challenge is represented as an | |
384 | unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values | |
385 | smaller than 2^248 will have leading 0 bytes). | |
386 | ||
387 | The response value is then calculated as: | |
388 | ||
389 | response = MD5(decrypted_challenge || session_id) | |
390 | ||
391 | and returned in the following message | |
392 | ||
393 | byte SSH_AGENT_RSA_RESPONSE | |
394 | byte[16] response | |
395 | ||
396 | If the agent cannot find the key specified by the supplied (rsa_e, | |
397 | rsa_n) then it will return SSH_AGENT_FAILURE. | |
398 | ||
399 | 2.6.2 Protocol 2 private key signature request | |
400 | ||
401 | A client may use the following message to request signing of data using | |
402 | a protocol 2 key: | |
403 | ||
404 | byte SSH2_AGENTC_SIGN_REQUEST | |
405 | string key_blob | |
406 | string data | |
407 | uint32 flags | |
408 | ||
409 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | |
410 | Algorithms" for either of the supported key types: "ssh-dss" or | |
411 | "ssh-rsa". "flags" is a bit-mask, but at present only one possible value | |
412 | is defined (see below for its meaning): | |
413 | ||
414 | SSH_AGENT_OLD_SIGNATURE 1 | |
415 | ||
416 | Upon receiving this request, the agent will look up the private key that | |
417 | corresponds to the public key contained in key_blob. It will use this | |
418 | private key to sign the "data" and produce a signature blob using the | |
419 | key type-specific method described in RFC 4253 section 6.6 "Public Key | |
420 | Algorithms". | |
421 | ||
422 | An exception to this is for "ssh-dss" keys where the "flags" word | |
423 | contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy | |
424 | signature encoding is used in lieu of the standard one. In this case, | |
425 | the DSA signature blob is encoded as: | |
426 | ||
427 | byte[40] signature | |
428 | ||
429 | The signature will be returned in the response message: | |
430 | ||
431 | byte SSH2_AGENT_SIGN_RESPONSE | |
432 | string signature_blob | |
433 | ||
434 | If the agent cannot find the key specified by the supplied key_blob then | |
435 | it will return SSH_AGENT_FAILURE. | |
436 | ||
437 | 2.7 Locking or unlocking an agent | |
438 | ||
439 | The agent supports temporary locking with a passphrase to suspend | |
440 | processing of sensitive operations until it has been unlocked with the | |
441 | same passphrase. To lock an agent, a client send the following request: | |
442 | ||
443 | byte SSH_AGENTC_LOCK | |
444 | string passphrase | |
445 | ||
446 | Upon receipt of this message and if the agent is not already locked, | |
447 | it will suspend processing requests and return a SSH_AGENT_SUCCESS | |
448 | reply. If the agent is already locked, it will return SSH_AGENT_FAILURE. | |
449 | ||
450 | While locked, the agent will refuse all requests except | |
451 | SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and | |
452 | SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are | |
453 | treated specially by a locked agent: it will always return an empty list | |
454 | of keys. | |
455 | ||
456 | To unlock an agent, a client may request: | |
457 | ||
458 | byte SSH_AGENTC_UNLOCK | |
459 | string passphrase | |
460 | ||
461 | If the passphrase matches and the agent is locked, then it will resume | |
462 | processing all requests and return SSH_AGENT_SUCCESS. If the agent | |
463 | is not locked or the passphrase does not match then it will return | |
464 | SSH_AGENT_FAILURE. | |
465 | ||
466 | Locking and unlocking affects both protocol 1 and protocol 2 keys. | |
467 | ||
468 | 3. Protocol message numbers | |
469 | ||
470 | 3.1 Requests from client to agent for protocol 1 key operations | |
471 | ||
472 | SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 | |
473 | SSH_AGENTC_RSA_CHALLENGE 3 | |
474 | SSH_AGENTC_ADD_RSA_IDENTITY 7 | |
475 | SSH_AGENTC_REMOVE_RSA_IDENTITY 8 | |
476 | SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 | |
477 | SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 | |
478 | ||
479 | 3.2 Requests from client to agent for protocol 2 key operations | |
480 | ||
481 | SSH2_AGENTC_REQUEST_IDENTITIES 11 | |
482 | SSH2_AGENTC_SIGN_REQUEST 13 | |
483 | SSH2_AGENTC_ADD_IDENTITY 17 | |
484 | SSH2_AGENTC_REMOVE_IDENTITY 18 | |
485 | SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 | |
486 | SSH2_AGENTC_ADD_ID_CONSTRAINED 25 | |
487 | ||
488 | 3.3 Key-type independent requests from client to agent | |
489 | ||
490 | SSH_AGENTC_ADD_SMARTCARD_KEY 20 | |
491 | SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 | |
492 | SSH_AGENTC_LOCK 22 | |
493 | SSH_AGENTC_UNLOCK 23 | |
494 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 | |
495 | ||
496 | 3.4 Generic replies from agent to client | |
497 | ||
498 | SSH_AGENT_FAILURE 5 | |
499 | SSH_AGENT_SUCCESS 6 | |
500 | ||
501 | 3.5 Replies from agent to client for protocol 1 key operations | |
502 | ||
503 | SSH_AGENT_RSA_IDENTITIES_ANSWER 2 | |
504 | SSH_AGENT_RSA_RESPONSE 4 | |
505 | ||
506 | 3.6 Replies from agent to client for protocol 2 key operations | |
507 | ||
508 | SSH2_AGENT_IDENTITIES_ANSWER 12 | |
509 | SSH2_AGENT_SIGN_RESPONSE 14 | |
510 | ||
511 | 3.7 Key constraint identifiers | |
512 | ||
513 | SSH_AGENT_CONSTRAIN_LIFETIME 1 | |
514 | SSH_AGENT_CONSTRAIN_CONFIRM 2 | |
515 | ||
516 | $OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $ |