[BACK]Return to PROTOCOL.agent CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/PROTOCOL.agent, Revision 1.1

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
        !            19: protocol 2 keys. Furthermore, the names also indicate whether message
        !            20: is a request to the agent (*_AGENTC_*) or a reply from the agent
        !            21: (*_AGENT_*). Section 3 below contains the mapping of the protocol
        !            22: message names to their integer values.
        !            23:
        !            24: 1. Data types
        !            25:
        !            26: Because of it 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 an the 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 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 description 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 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_date
        !           121:        byte                    constraint2_type
        !           122:        ....                    constraint2_date
        !           123:        ....
        !           124:        byte                    constraintN_type
        !           125:        ....                    constraintN_date
        !           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 an "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 send 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" the 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:        byte[n]                 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 keys
        !           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:        byte[n]                 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 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$