Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 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. |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 23 | |
| 24 | 1. Data types |
| 25 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 26 | Because of support for legacy SSH protocol 1 keys, OpenSSH's agent |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 45 | Note the difference between the "mpint1" encoding and the "mpint" |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 46 | encoding defined in RFC 4251. Also note that the length of the encoded |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 47 | integer is specified in bits, not bytes and that the byte length of |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 59 | The following message descriptions refer only to the content the |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 89 | or other hardware security module. These keys may be added |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 90 | to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 91 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests. |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Darren Tucker | 00f00f0 | 2008-07-02 22:31:31 +1000 | [diff] [blame] | 120 | .... constraint1_data |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 121 | byte constraint2_type |
Darren Tucker | 00f00f0 | 2008-07-02 22:31:31 +1000 | [diff] [blame] | 122 | .... constraint2_data |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 123 | .... |
| 124 | byte constraintN_type |
Darren Tucker | 00f00f0 | 2008-07-02 22:31:31 +1000 | [diff] [blame] | 125 | .... constraintN_data |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 129 | by checking whether additional data exists in the "add key" request |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Damien Miller | 697485d | 2013-01-09 15:56:13 +1100 | [diff] [blame] | 155 | SSH_AGENTC_ADD_RSA_ID_CONSTRAINED. |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 162 | The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA |
| 163 | keys may be added using the following request |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Damien Miller | 0a80ca1 | 2010-02-27 07:55:05 +1100 | [diff] [blame] | 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 | |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 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 | |
djm@openbsd.org | b466f95 | 2016-05-03 10:24:27 +0000 | [diff] [blame] | 209 | ED25519 keys may be added using the following request |
| 210 | byte SSH2_AGENTC_ADD_IDENTITY or |
| 211 | SSH2_AGENTC_ADD_ID_CONSTRAINED |
djm@openbsd.org | 910e59b | 2016-05-04 12:16:39 +0000 | [diff] [blame] | 212 | string "ssh-ed25519" |
djm@openbsd.org | 531c135 | 2016-05-19 07:45:32 +0000 | [diff] [blame] | 213 | string ed25519_public_key |
| 214 | string ed25519_private_key || ed25519_public_key |
djm@openbsd.org | b466f95 | 2016-05-03 10:24:27 +0000 | [diff] [blame] | 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 |
djm@openbsd.org | 910e59b | 2016-05-04 12:16:39 +0000 | [diff] [blame] | 221 | string "ssh-ed25519-cert-v01@openssh.com" |
djm@openbsd.org | b466f95 | 2016-05-03 10:24:27 +0000 | [diff] [blame] | 222 | string certificate |
djm@openbsd.org | 531c135 | 2016-05-19 07:45:32 +0000 | [diff] [blame] | 223 | string ed25519_public_key |
| 224 | string ed25519_private_key || ed25519_public_key |
djm@openbsd.org | b466f95 | 2016-05-03 10:24:27 +0000 | [diff] [blame] | 225 | string key_comment |
| 226 | constraint[] key_constraints |
| 227 | |
djm@openbsd.org | 531c135 | 2016-05-19 07:45:32 +0000 | [diff] [blame] | 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 | |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Damien Miller | 0a80ca1 | 2010-02-27 07:55:05 +1100 | [diff] [blame] | 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 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 258 | Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 263 | For DSA, ECDSA and RSA key add requests, "key_constraints" may only be |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 283 | "reader_id" is an identifier to a smartcard reader and "pin" |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
| 340 | string key_blob |
| 341 | |
| 342 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 343 | Algorithms" for any of the supported protocol 2 key types. |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 396 | A client may send the following message to request a list of |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
| 408 | string key_blob |
| 409 | string key_comment |
| 410 | |
| 411 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 412 | Algorithms" for any of the supported protocol 2 key types. |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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) |
djm@openbsd.org | 4e636cf | 2015-05-08 03:56:51 +0000 | [diff] [blame] | 438 | been encrypted with the public key and must be in the range |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 441 | key and the session cookie). |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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" |
Darren Tucker | f2e21de | 2008-07-02 22:35:00 +1000 | [diff] [blame] | 448 | using the private key matching the supplied (rsa_e, rsa_n) values. For |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 |
Damien Miller | eb8b60e | 2010-08-31 22:41:14 +1000 | [diff] [blame] | 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): |
Damien Miller | 1e18beb | 2008-06-30 00:07:00 +1000 | [diff] [blame] | 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 | |
djm@openbsd.org | 531c135 | 2016-05-19 07:45:32 +0000 | [diff] [blame] | 582 | $OpenBSD: PROTOCOL.agent,v 1.11 2016/05/19 07:45:32 djm Exp $ |