diff options
Diffstat (limited to '')
-rw-r--r-- | PROTOCOL | 499 | ||||
-rw-r--r-- | PROTOCOL.agent | 5 | ||||
-rw-r--r-- | PROTOCOL.certkeys | 306 | ||||
-rw-r--r-- | PROTOCOL.chacha20poly1305 | 107 | ||||
-rw-r--r-- | PROTOCOL.key | 68 | ||||
-rw-r--r-- | PROTOCOL.krl | 171 | ||||
-rw-r--r-- | PROTOCOL.mux | 298 |
7 files changed, 1454 insertions, 0 deletions
diff --git a/PROTOCOL b/PROTOCOL new file mode 100644 index 0000000..f75c1c0 --- /dev/null +++ b/PROTOCOL @@ -0,0 +1,499 @@ +This documents OpenSSH's deviations and extensions to the published SSH +protocol. + +Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH +filexfer protocol described in: + +https://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt + +Newer versions of the draft will not be supported, though some features +are individually implemented as extensions described below. + +The protocol used by OpenSSH's ssh-agent is described in the file +PROTOCOL.agent + +1. Transport protocol changes + +1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" + +This is a new transport-layer MAC method using the UMAC algorithm +(rfc4418). This method is identical to the "umac-64" method documented +in: + +https://www.openssh.com/txt/draft-miller-secsh-umac-01.txt + +1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com" + +This transport-layer compression method uses the zlib compression +algorithm (identical to the "zlib" method in rfc4253), but delays the +start of compression until after authentication has completed. This +avoids exposing compression code to attacks from unauthenticated users. + +The method is documented in: + +https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt + +1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com", + "ssh-dsa-cert-v01@openssh.com", + "ecdsa-sha2-nistp256-cert-v01@openssh.com", + "ecdsa-sha2-nistp384-cert-v01@openssh.com" and + "ecdsa-sha2-nistp521-cert-v01@openssh.com" + +OpenSSH introduces new public key algorithms to support certificate +authentication for users and host keys. These methods are documented +in the file PROTOCOL.certkeys + +1.4. transport: Elliptic Curve cryptography + +OpenSSH supports ECC key exchange and public key authentication as +specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 +and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic +curve points encoded using point compression are NOT accepted or +generated. + +1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms + +OpenSSH supports MAC algorithms, whose names contain "-etm", that +perform the calculations in a different order to that defined in RFC +4253. These variants use the so-called "encrypt then MAC" ordering, +calculating the MAC over the packet ciphertext rather than the +plaintext. This ordering closes a security flaw in the SSH transport +protocol, where decryption of unauthenticated ciphertext provided a +"decryption oracle" that could, in conjunction with cipher flaws, reveal +session plaintext. + +Specifically, the "-etm" MAC algorithms modify the transport protocol +to calculate the MAC over the packet ciphertext and to send the packet +length unencrypted. This is necessary for the transport to obtain the +length of the packet and location of the MAC tag so that it may be +verified without decrypting unauthenticated data. + +As such, the MAC covers: + + mac = MAC(key, sequence_number || packet_length || encrypted_packet) + +where "packet_length" is encoded as a uint32 and "encrypted_packet" +contains: + + byte padding_length + byte[n1] payload; n1 = packet_length - padding_length - 1 + byte[n2] random padding; n2 = padding_length + +1.6 transport: AES-GCM + +OpenSSH supports the AES-GCM algorithm as specified in RFC 5647. +Because of problems with the specification of the key exchange +the behaviour of OpenSSH differs from the RFC as follows: + +AES-GCM is only negotiated as the cipher algorithms +"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as +an MAC algorithm. Additionally, if AES-GCM is selected as the cipher +the exchanged MAC algorithms are ignored and there doesn't have to be +a matching MAC. + +1.7 transport: chacha20-poly1305@openssh.com authenticated encryption + +OpenSSH supports authenticated encryption using ChaCha20 and Poly1305 +as described in PROTOCOL.chacha20poly1305. + +1.8 transport: curve25519-sha256@libssh.org key exchange algorithm + +OpenSSH supports the use of ECDH in Curve25519 for key exchange as +described at: +http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519 + +2. Connection protocol changes + +2.1. connection: Channel write close extension "eow@openssh.com" + +The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF +message to allow an endpoint to signal its peer that it will send no +more data over a channel. Unfortunately, there is no symmetric way for +an endpoint to request that its peer should cease sending data to it +while still keeping the channel open for the endpoint to send data to +the peer. + +This is desirable, since it saves the transmission of data that would +otherwise need to be discarded and it allows an endpoint to signal local +processes of the condition, e.g. by closing the corresponding file +descriptor. + +OpenSSH implements a channel extension message to perform this +signalling: "eow@openssh.com" (End Of Write). This message is sent by +an endpoint when the local output of a session channel is closed or +experiences a write error. The message is formatted as follows: + + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "eow@openssh.com" + boolean FALSE + +On receiving this message, the peer SHOULD cease sending data of +the channel and MAY signal the process from which the channel data +originates (e.g. by closing its read file descriptor). + +As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does +remain open after a "eow@openssh.com" has been sent and more data may +still be sent in the other direction. This message does not consume +window space and may be sent even if no window space is available. + +NB. due to certain broken SSH implementations aborting upon receipt +of this message (in contravention of RFC4254 section 5.4), this +message is only sent to OpenSSH peers (identified by banner). +Other SSH implementations may be whitelisted to receive this message +upon request. + +2.2. connection: disallow additional sessions extension + "no-more-sessions@openssh.com" + +Most SSH connections will only ever request a single session, but a +attacker may abuse a running ssh client to surreptitiously open +additional sessions under their control. OpenSSH provides a global +request "no-more-sessions@openssh.com" to mitigate this attack. + +When an OpenSSH client expects that it will never open another session +(i.e. it has been started with connection multiplexing disabled), it +will send the following global request: + + byte SSH_MSG_GLOBAL_REQUEST + string "no-more-sessions@openssh.com" + char want-reply + +On receipt of such a message, an OpenSSH server will refuse to open +future channels of type "session" and instead immediately abort the +connection. + +Note that this is not a general defence against compromised clients +(that is impossible), but it thwarts a simple attack. + +NB. due to certain broken SSH implementations aborting upon receipt +of this message, the no-more-sessions request is only sent to OpenSSH +servers (identified by banner). Other SSH implementations may be +whitelisted to receive this message upon request. + +2.3. connection: Tunnel forward extension "tun@openssh.com" + +OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" +channel type. This channel type supports forwarding of network packets +with datagram boundaries intact between endpoints equipped with +interfaces like the BSD tun(4) device. Tunnel forwarding channels are +requested by the client with the following packet: + + byte SSH_MSG_CHANNEL_OPEN + string "tun@openssh.com" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + uint32 tunnel mode + uint32 remote unit number + +The "tunnel mode" parameter specifies whether the tunnel should forward +layer 2 frames or layer 3 packets. It may take one of the following values: + + SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */ + SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */ + +The "tunnel unit number" specifies the remote interface number, or may +be 0x7fffffff to allow the server to automatically chose an interface. A +server that is not willing to open a client-specified unit should refuse +the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful +open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS. + +Once established the client and server may exchange packet or frames +over the tunnel channel by encapsulating them in SSH protocol strings +and sending them as channel data. This ensures that packet boundaries +are kept intact. Specifically, packets are transmitted using normal +SSH_MSG_CHANNEL_DATA packets: + + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + +The contents of the "data" field for layer 3 packets is: + + uint32 packet length + uint32 address family + byte[packet length - 4] packet data + +The "address family" field identifies the type of packet in the message. +It may be one of: + + SSH_TUN_AF_INET 2 /* IPv4 */ + SSH_TUN_AF_INET6 24 /* IPv6 */ + +The "packet data" field consists of the IPv4/IPv6 datagram itself +without any link layer header. + +The contents of the "data" field for layer 2 packets is: + + uint32 packet length + byte[packet length] frame + +The "frame" field contains an IEEE 802.3 Ethernet frame, including +header. + +2.4. connection: Unix domain socket forwarding + +OpenSSH supports local and remote Unix domain socket forwarding +using the "streamlocal" extension. Forwarding is initiated as per +TCP sockets but with a single path instead of a host and port. + +Similar to direct-tcpip, direct-streamlocal is sent by the client +to request that the server make a connection to a Unix domain socket. + + byte SSH_MSG_CHANNEL_OPEN + string "direct-streamlocal@openssh.com" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + string socket path + string reserved + uint32 reserved + +Similar to forwarded-tcpip, forwarded-streamlocal is sent by the +server when the client has previously send the server a streamlocal-forward +GLOBAL_REQUEST. + + byte SSH_MSG_CHANNEL_OPEN + string "forwarded-streamlocal@openssh.com" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + string socket path + string reserved for future use + +The reserved field is not currently defined and is ignored on the +remote end. It is intended to be used in the future to pass +information about the socket file, such as ownership and mode. +The client currently sends the empty string for this field. + +Similar to tcpip-forward, streamlocal-forward is sent by the client +to request remote forwarding of a Unix domain socket. + + byte SSH2_MSG_GLOBAL_REQUEST + string "streamlocal-forward@openssh.com" + boolean TRUE + string socket path + +Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent +by the client cancel the forwarding of a Unix domain socket. + + byte SSH2_MSG_GLOBAL_REQUEST + string "cancel-streamlocal-forward@openssh.com" + boolean FALSE + string socket path + +2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com" +and "hostkeys-prove-00@openssh.com" + +OpenSSH supports a protocol extension allowing a server to inform +a client of all its protocol v.2 host keys after user-authentication +has completed. + + byte SSH_MSG_GLOBAL_REQUEST + string "hostkeys-00@openssh.com" + string[] hostkeys + +Upon receiving this message, a client should check which of the +supplied host keys are present in known_hosts. + +Note that the server may send key types that the client does not +support. The client should disgregard such keys if they are received. + +If the client identifies any keys that are not present for the host, +it should send a "hostkeys-prove@openssh.com" message to request the +server prove ownership of the private half of the key. + + byte SSH_MSG_GLOBAL_REQUEST + string "hostkeys-prove-00@openssh.com" + char 1 /* want-reply */ + string[] hostkeys + +When a server receives this message, it should generate a signature +using each requested key over the following: + + string "hostkeys-prove-00@openssh.com" + string session identifier + string hostkey + +These signatures should be included in the reply, in the order matching +the hostkeys in the request: + + byte SSH_MSG_REQUEST_SUCCESS + string[] signatures + +When the client receives this reply (and not a failure), it should +validate the signatures and may update its known_hosts file, adding keys +that it has not seen before and deleting keys for the server host that +are no longer offered. + +These extensions let a client learn key types that it had not previously +encountered, thereby allowing it to potentially upgrade from weaker +key algorithms to better ones. It also supports graceful key rotation: +a server may offer multiple keys of the same type for a period (to +give clients an opportunity to learn them using this extension) before +removing the deprecated key from those offered. + +2.6. connection: SIGINFO support for "signal" channel request + +The SSH channels protocol (RFC4254 section 6.9) supports sending a +signal to a session attached to a channel. OpenSSH supports one +extension signal "INFO@openssh.com" that allows sending SIGINFO on +BSD-derived systems. + +3. SFTP protocol changes + +3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK + +When OpenSSH's sftp-server was implemented, the order of the arguments +to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, +the reversal was not noticed until the server was widely deployed. Since +fixing this to follow the specification would cause incompatibility, the +current order was retained. For correct operation, clients should send +SSH_FXP_SYMLINK as follows: + + uint32 id + string targetpath + string linkpath + +3.2. sftp: Server extension announcement in SSH_FXP_VERSION + +OpenSSH's sftp-server lists the extensions it supports using the +standard extension announcement mechanism in the SSH_FXP_VERSION server +hello packet: + + uint32 3 /* protocol version */ + string ext1-name + string ext1-version + string ext2-name + string ext2-version + ... + string extN-name + string extN-version + +Each extension reports its integer version number as an ASCII encoded +string, e.g. "1". The version will be incremented if the extension is +ever changed in an incompatible way. The server MAY advertise the same +extension with multiple versions (though this is unlikely). Clients MUST +check the version number before attempting to use the extension. + +3.3. sftp: Extension request "posix-rename@openssh.com" + +This operation provides a rename operation with POSIX semantics, which +are different to those provided by the standard SSH_FXP_RENAME in +draft-ietf-secsh-filexfer-02.txt. This request is implemented as a +SSH_FXP_EXTENDED request with the following format: + + uint32 id + string "posix-rename@openssh.com" + string oldpath + string newpath + +On receiving this request the server will perform the POSIX operation +rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +3.4. sftp: Extension requests "statvfs@openssh.com" and + "fstatvfs@openssh.com" + +These requests correspond to the statvfs and fstatvfs POSIX system +interfaces. The "statvfs@openssh.com" request operates on an explicit +pathname, and is formatted as follows: + + uint32 id + string "statvfs@openssh.com" + string path + +The "fstatvfs@openssh.com" operates on an open file handle: + + uint32 id + string "fstatvfs@openssh.com" + string handle + +These requests return a SSH_FXP_STATUS reply on failure. On success they +return the following SSH_FXP_EXTENDED_REPLY reply: + + uint32 id + uint64 f_bsize /* file system block size */ + uint64 f_frsize /* fundamental fs block size */ + uint64 f_blocks /* number of blocks (unit f_frsize) */ + uint64 f_bfree /* free blocks in file system */ + uint64 f_bavail /* free blocks for non-root */ + uint64 f_files /* total file inodes */ + uint64 f_ffree /* free file inodes */ + uint64 f_favail /* free file inodes for to non-root */ + uint64 f_fsid /* file system id */ + uint64 f_flag /* bit mask of f_flag values */ + uint64 f_namemax /* maximum filename length */ + +The values of the f_flag bitmask are as follows: + + #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */ + #define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */ + +Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are +advertised in the SSH_FXP_VERSION hello with version "2". + +3.5. sftp: Extension request "hardlink@openssh.com" + +This request is for creating a hard link to a regular file. This +request is implemented as a SSH_FXP_EXTENDED request with the +following format: + + uint32 id + string "hardlink@openssh.com" + string oldpath + string newpath + +On receiving this request the server will perform the operation +link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +3.6. sftp: Extension request "fsync@openssh.com" + +This request asks the server to call fsync(2) on an open file handle. + + uint32 id + string "fsync@openssh.com" + string handle + +One receiving this request, a server will call fsync(handle_fd) and will +respond with a SSH_FXP_STATUS message. + +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +4. Miscellaneous changes + +4.1 Public key format + +OpenSSH public keys, as generated by ssh-keygen(1) and appearing in +authorized_keys files, are formatted as a single line of text consisting +of the public key algorithm name followed by a base64-encoded key blob. +The public key blob (before base64 encoding) is the same format used for +the encoding of public keys sent on the wire: as described in RFC4253 +section 6.6 for RSA and DSA keys, RFC5656 section 3.1 for ECDSA keys +and the "New public key formats" section of PROTOCOL.certkeys for the +OpenSSH certificate formats. + +4.2 Private key format + +OpenSSH private keys, as generated by ssh-keygen(1) use the format +described in PROTOCOL.key by default. As a legacy option, PEM format +(RFC7468) private keys are also supported for RSA, DSA and ECDSA keys +and were the default format before OpenSSH 7.8. + +4.3 KRL format + +OpenSSH supports a compact format for Key Revocation Lists (KRLs). This +format is described in the PROTOCOL.krl file. + +4.4 Connection multiplexing + +OpenSSH's connection multiplexing uses messages as described in +PROTOCOL.mux over a Unix domain socket for communications between a +master instance and later clients. + +$OpenBSD: PROTOCOL,v 1.36 2018/10/02 12:51:58 djm Exp $ diff --git a/PROTOCOL.agent b/PROTOCOL.agent new file mode 100644 index 0000000..da33819 --- /dev/null +++ b/PROTOCOL.agent @@ -0,0 +1,5 @@ +This file used to contain a description of the SSH agent protocol +implemented by OpenSSH. It has since been superseded by an Internet- +draft that is available from: + +https://tools.ietf.org/html/draft-miller-ssh-agent-02 diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys new file mode 100644 index 0000000..11363fd --- /dev/null +++ b/PROTOCOL.certkeys @@ -0,0 +1,306 @@ +This document describes a simple public-key certificate authentication +system for use by SSH. + +Background +---------- + +The SSH protocol currently supports a simple public key authentication +mechanism. Unlike other public key implementations, SSH eschews the use +of X.509 certificates and uses raw keys. This approach has some benefits +relating to simplicity of configuration and minimisation of attack +surface, but it does not support the important use-cases of centrally +managed, passwordless authentication and centrally certified host keys. + +These protocol extensions build on the simple public key authentication +system already in SSH to allow certificate-based authentication. The +certificates used are not traditional X.509 certificates, with numerous +options and complex encoding rules, but something rather more minimal: a +key, some identity information and usage options that have been signed +with some other trusted key. + +A sshd server may be configured to allow authentication via certified +keys, by extending the existing ~/.ssh/authorized_keys mechanism to +allow specification of certification authority keys in addition to +raw user keys. The ssh client will support automatic verification of +acceptance of certified host keys, by adding a similar ability to +specify CA keys in ~/.ssh/known_hosts. + +All certificate types include certification information along with the +public key that is used to sign challenges. In OpenSSH, ssh-keygen +performs the CA signing operation. + +Certified keys are represented using new key types: + + ssh-rsa-cert-v01@openssh.com + ssh-dss-cert-v01@openssh.com + ecdsa-sha2-nistp256-cert-v01@openssh.com + ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com + +Two additional types exist for RSA certificates to force use of +SHA-2 signatures (SHA-256 and SHA-512 respectively): + + rsa-sha2-256-cert-v01@openssh.com + rsa-sha2-512-cert-v01@openssh.com + +These RSA/SHA-2 types should not appear in keys at rest or transmitted +on their wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms +field or in the "public key algorithm name" field of a "publickey" +SSH_USERAUTH_REQUEST to indicate that the signature will use the +specified algorithm. + +Protocol extensions +------------------- + +The SSH wire protocol includes several extensibility mechanisms. +These modifications shall take advantage of namespaced public key +algorithm names to add support for certificate authentication without +breaking the protocol - implementations that do not support the +extensions will simply ignore them. + +Authentication using the new key formats described below proceeds +using the existing SSH "publickey" authentication method described +in RFC4252 section 7. + +New public key formats +---------------------- + +The certificate key types take a similar high-level format (note: data +types and encoding are as per RFC4251 section 5). The serialised wire +encoding of these certificates is also used for storing them on disk. + +#define SSH_CERT_TYPE_USER 1 +#define SSH_CERT_TYPE_HOST 2 + +RSA certificate + + string "ssh-rsa-cert-v01@openssh.com" + string nonce + mpint e + mpint n + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +DSA certificate + + string "ssh-dss-cert-v01@openssh.com" + string nonce + mpint p + mpint q + mpint g + mpint y + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +ECDSA certificate + + string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | + "ecdsa-sha2-nistp384-cert-v01@openssh.com" | + "ecdsa-sha2-nistp521-cert-v01@openssh.com" + string nonce + string curve + string public_key + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +ED25519 certificate + + string "ssh-ed25519-cert-v01@openssh.com" + string nonce + string pk + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +The nonce field is a CA-provided random bitstring of arbitrary length +(but typically 16 or 32 bytes) included to make attacks that depend on +inducing collisions in the signature hash infeasible. + +e and n are the RSA exponent and public modulus respectively. + +p, q, g, y are the DSA parameters as described in FIPS-186-2. + +curve and public key are respectively the ECDSA "[identifier]" and "Q" +defined in section 3.1 of RFC5656. + +pk is the encoded Ed25519 public key as defined by +draft-josefsson-eddsa-ed25519-03. + +serial is an optional certificate serial number set by the CA to +provide an abbreviated way to refer to certificates from that CA. +If a CA does not wish to number its certificates it must set this +field to zero. + +type specifies whether this certificate is for identification of a user +or a host using a SSH_CERT_TYPE_... value. + +key id is a free-form text field that is filled in by the CA at the time +of signing; the intention is that the contents of this field are used to +identify the identity principal in log messages. + +"valid principals" is a string containing zero or more principals as +strings packed inside it. These principals list the names for which this +certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and +usernames for SSH_CERT_TYPE_USER certificates. As a special case, a +zero-length "valid principals" field means the certificate is valid for +any principal of the specified type. + +"valid after" and "valid before" specify a validity period for the +certificate. Each represents a time in seconds since 1970-01-01 +00:00:00. A certificate is considered valid if: + + valid after <= current time < valid before + +critical options is a set of zero or more key options encoded as +below. All such options are "critical" in the sense that an implementation +must refuse to authorise a key that has an unrecognised option. + +extensions is a set of zero or more optional extensions. These extensions +are not critical, and an implementation that encounters one that it does +not recognise may safely ignore it. + +Generally, critical options are used to control features that restrict +access where extensions are used to enable features that grant access. +This ensures that certificates containing unknown restrictions do not +inadvertently grant access while allowing new protocol features to be +enabled via extensions without breaking certificates' backwards +compatibility. + +The reserved field is currently unused and is ignored in this version of +the protocol. + +The signature key field contains the CA key used to sign the +certificate. The valid key types for CA keys are ssh-rsa, +ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256, +ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where +the signature key type is a certificate type itself are NOT supported. +Note that it is possible for a RSA certificate key to be signed by a +Ed25519 or ECDSA CA key and vice-versa. + +signature is computed over all preceding fields from the initial string +up to, and including the signature key. Signatures are computed and +encoded according to the rules defined for the CA's public key algorithm +(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA +types), and draft-josefsson-eddsa-ed25519-03 for Ed25519. + +Critical options +---------------- + +The critical options section of the certificate specifies zero or more +options on the certificates validity. The format of this field +is a sequence of zero or more tuples: + + string name + string data + +Options must be lexically ordered by "name" if they appear in the +sequence. Each named option may only appear once in a certificate. + +The name field identifies the option and the data field encodes +option-specific information (see below). All options are +"critical", if an implementation does not recognise a option +then the validating party should refuse to accept the certificate. + +Custom options should append the originating author or organisation's +domain name to the option name, e.g. "my-option@example.com". + +No critical options are defined for host certificates at present. The +supported user certificate options and the contents and structure of +their data fields are: + +Name Format Description +----------------------------------------------------------------------------- +force-command string Specifies a command that is executed + (replacing any the user specified on the + ssh command-line) whenever this key is + used for authentication. + +source-address string Comma-separated list of source addresses + from which this certificate is accepted + for authentication. Addresses are + specified in CIDR format (nn.nn.nn.nn/nn + or hhhh::hhhh/nn). + If this option is not present then + certificates may be presented from any + source address. + +Extensions +---------- + +The extensions section of the certificate specifies zero or more +non-critical certificate extensions. The encoding and ordering of +extensions in this field is identical to that of the critical options, +as is the requirement that each name appear only once. + +If an implementation does not recognise an extension, then it should +ignore it. + +Custom options should append the originating author or organisation's +domain name to the option name, e.g. "my-option@example.com". + +No extensions are defined for host certificates at present. The +supported user certificate extensions and the contents and structure of +their data fields are: + +Name Format Description +----------------------------------------------------------------------------- +permit-X11-forwarding empty Flag indicating that X11 forwarding + should be permitted. X11 forwarding will + be refused if this option is absent. + +permit-agent-forwarding empty Flag indicating that agent forwarding + should be allowed. Agent forwarding + must not be permitted unless this + option is present. + +permit-port-forwarding empty Flag indicating that port-forwarding + should be allowed. If this option is + not present then no port forwarding will + be allowed. + +permit-pty empty Flag indicating that PTY allocation + should be permitted. In the absence of + this option PTY allocation will be + disabled. + +permit-user-rc empty Flag indicating that execution of + ~/.ssh/rc should be permitted. Execution + of this script will not be permitted if + this option is not present. + +$OpenBSD: PROTOCOL.certkeys,v 1.15 2018/07/03 11:39:54 djm Exp $ diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305 new file mode 100644 index 0000000..9ce2a1e --- /dev/null +++ b/PROTOCOL.chacha20poly1305 @@ -0,0 +1,107 @@ +This document describes the chacha20-poly1305@openssh.com authenticated +encryption cipher supported by OpenSSH. + +Background +---------- + +ChaCha20 is a stream cipher designed by Daniel Bernstein and described +in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, +a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output +is used as a keystream, with any unused bytes simply discarded. + +Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC +that computes a 128 bit integrity tag given a message and a single-use +256 bit secret key. + +The chacha20-poly1305@openssh.com combines these two primitives into an +authenticated encryption mode. The construction used is based on that +proposed for TLS by Adam Langley in [3], but differs in the layout of +data passed to the MAC and in the addition of encryption of the packet +lengths. + +Negotiation +----------- + +The chacha20-poly1305@openssh.com offers both encryption and +authentication. As such, no separate MAC is required. If the +chacha20-poly1305@openssh.com cipher is selected in key exchange, +the offered MAC algorithms are ignored and no MAC is required to be +negotiated. + +Detailed Construction +--------------------- + +The chacha20-poly1305@openssh.com cipher requires 512 bits of key +material as output from the SSH key exchange. This forms two 256 bit +keys (K_1 and K_2), used by two separate instances of chacha20. +The first 256 bits consitute K_2 and the second 256 bits become +K_1. + +The instance keyed by K_1 is a stream cipher that is used only +to encrypt the 4 byte packet length field. The second instance, +keyed by K_2, is used in conjunction with poly1305 to build an AEAD +(Authenticated Encryption with Associated Data) that is used to encrypt +and authenticate the entire packet. + +Two separate cipher instances are used here so as to keep the packet +lengths confidential but not create an oracle for the packet payload +cipher by decrypting and using the packet length prior to checking +the MAC. By using an independently-keyed cipher instance to encrypt the +length, an active attacker seeking to exploit the packet input handling +as a decryption oracle can learn nothing about the payload contents or +its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). + +The AEAD is constructed as follows: for each packet, generate a Poly1305 +key by taking the first 256 bits of ChaCha20 stream output generated +using K_2, an IV consisting of the packet sequence number encoded as an +uint64 under the SSH wire encoding rules and a ChaCha20 block counter of +zero. The K_2 ChaCha20 block counter is then set to the little-endian +encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used +for encryption of the packet payload. + +Packet Handling +--------------- + +When receiving a packet, the length must be decrypted first. When 4 +bytes of ciphertext length have been received, they may be decrypted +using the K_1 key, a nonce consisting of the packet sequence number +encoded as a uint64 under the usual SSH wire encoding and a zero block +counter to obtain the plaintext length. + +Once the entire packet has been received, the MAC MUST be checked +before decryption. A per-packet Poly1305 key is generated as described +above and the MAC tag calculated using Poly1305 with this key over the +ciphertext of the packet length and the payload together. The calculated +MAC is then compared in constant time with the one appended to the +packet and the packet decrypted using ChaCha20 as described above (with +K_2, the packet sequence number as nonce and a starting block counter of +1). + +To send a packet, first encode the 4 byte length and encrypt it using +K_1. Encrypt the packet payload (using K_2) and append it to the +encrypted length. Finally, calculate a MAC tag and append it. + +Rekeying +-------- + +ChaCha20 must never reuse a {key, nonce} for encryption nor may it be +used to encrypt more than 2^70 bytes under the same {key, nonce}. The +SSH Transport protocol (RFC4253) recommends a far more conservative +rekeying every 1GB of data sent or received. If this recommendation +is followed, then chacha20-poly1305@openssh.com requires no special +handling in this area. + +References +---------- + +[1] "ChaCha, a variant of Salsa20", Daniel Bernstein + http://cr.yp.to/chacha/chacha-20080128.pdf + +[2] "The Poly1305-AES message-authentication code", Daniel Bernstein + http://cr.yp.to/mac/poly1305-20050329.pdf + +[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley + http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + +$OpenBSD: PROTOCOL.chacha20poly1305,v 1.4 2018/04/10 00:10:49 djm Exp $ + diff --git a/PROTOCOL.key b/PROTOCOL.key new file mode 100644 index 0000000..959bd7a --- /dev/null +++ b/PROTOCOL.key @@ -0,0 +1,68 @@ +This document describes the private key format for OpenSSH. + +1. Overall format + +The key consists of a header, a list of public keys, and +an encrypted list of matching private keys. + +#define AUTH_MAGIC "openssh-key-v1" + + byte[] AUTH_MAGIC + string ciphername + string kdfname + string kdfoptions + int number of keys N + string publickey1 + string publickey2 + ... + string publickeyN + string encrypted, padded list of private keys + +2. KDF options for kdfname "bcrypt" + +The options: + + string salt + uint32 rounds + +are concatenated and represented as a string. + +3. Unencrypted list of N private keys + +The list of privatekey/comment pairs is padded with the +bytes 1, 2, 3, ... until the total length is a multiple +of the cipher block size. + + uint32 checkint + uint32 checkint + string privatekey1 + string comment1 + string privatekey2 + string comment2 + ... + string privatekeyN + string commentN + char 1 + char 2 + char 3 + ... + char padlen % 255 + +Before the key is encrypted, a random integer is assigned +to both checkint fields so successful decryption can be +quickly checked by verifying that both checkint fields +hold the same value. + +4. Encryption + +The KDF is used to derive a key, IV (and other values required by +the cipher) from the passphrase. These values are then used to +encrypt the unencrypted list of private keys. + +5. No encryption + +For unencrypted keys the cipher "none" and the KDF "none" +are used with empty passphrases. The options if the KDF "none" +are the empty string. + +$OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $ diff --git a/PROTOCOL.krl b/PROTOCOL.krl new file mode 100644 index 0000000..115f80e --- /dev/null +++ b/PROTOCOL.krl @@ -0,0 +1,171 @@ +This describes the key/certificate revocation list format for OpenSSH. + +1. Overall format + +The KRL consists of a header and zero or more sections. The header is: + +#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */ +#define KRL_FORMAT_VERSION 1 + + uint64 KRL_MAGIC + uint32 KRL_FORMAT_VERSION + uint64 krl_version + uint64 generated_date + uint64 flags + string reserved + string comment + +Where "krl_version" is a version number that increases each time the KRL +is modified, "generated_date" is the time in seconds since 1970-01-01 +00:00:00 UTC that the KRL was generated, "comment" is an optional comment +and "reserved" an extension field whose contents are currently ignored. +No "flags" are currently defined. + +Following the header are zero or more sections, each consisting of: + + byte section_type + string section_data + +Where "section_type" indicates the type of the "section_data". An exception +to this is the KRL_SECTION_SIGNATURE section, that has a slightly different +format (see below). + +The available section types are: + +#define KRL_SECTION_CERTIFICATES 1 +#define KRL_SECTION_EXPLICIT_KEY 2 +#define KRL_SECTION_FINGERPRINT_SHA1 3 +#define KRL_SECTION_SIGNATURE 4 +#define KRL_SECTION_FINGERPRINT_SHA256 5 + +2. Certificate section + +These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by +serial number or key ID. The consist of the CA key that issued the +certificates to be revoked and a reserved field whose contents is currently +ignored. + + string ca_key + string reserved + +Where "ca_key" is the standard SSH wire serialisation of the CA's +public key. Alternately, "ca_key" may be an empty string to indicate +the certificate section applies to all CAs (this is most useful when +revoking key IDs). + +Followed by one or more sections: + + byte cert_section_type + string cert_section_data + +The certificate section types are: + +#define KRL_SECTION_CERT_SERIAL_LIST 0x20 +#define KRL_SECTION_CERT_SERIAL_RANGE 0x21 +#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22 +#define KRL_SECTION_CERT_KEY_ID 0x23 + +2.1 Certificate serial list section + +This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes +certificates by listing their serial numbers. The cert_section_data in this +case contains: + + uint64 revoked_cert_serial + uint64 ... + +This section may appear multiple times. + +2.2. Certificate serial range section + +These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold +a range of serial numbers of certificates: + + uint64 serial_min + uint64 serial_max + +All certificates in the range serial_min <= serial <= serial_max are +revoked. + +This section may appear multiple times. + +2.3. Certificate serial bitmap section + +Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys +by listing their serial number in a bitmap. + + uint64 serial_offset + mpint revoked_keys_bitmap + +A bit set at index N in the bitmap corresponds to revocation of a keys with +serial number (serial_offset + N). + +This section may appear multiple times. + +2.4. Revoked key ID sections + +KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key +ID" strings. This may be useful in revoking all certificates +associated with a particular identity, e.g. a host or a user. + + string key_id[0] + ... + +This section must contain at least one "key_id". This section may appear +multiple times. + +3. Explicit key sections + +These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys +(not certificates). They are less space efficient than serial numbers, +but are able to revoke plain keys. + + string public_key_blob[0] + .... + +This section must contain at least one "public_key_blob". The blob +must be a raw key (i.e. not a certificate). + +This section may appear multiple times. + +4. SHA1/SHA256 fingerprint sections + +These sections, identified as KRL_SECTION_FINGERPRINT_SHA1 and +KRL_SECTION_FINGERPRINT_SHA256, revoke plain keys (i.e. not +certificates) by listing their hashes: + + string public_key_hash[0] + .... + +This section must contain at least one "public_key_hash". The hash blob +is obtained by taking the SHA1 or SHA256 hash of the public key blob. +Hashes in this section must appear in numeric order, treating each hash +as a big-endian integer. + +This section may appear multiple times. + +5. KRL signature sections + +The KRL_SECTION_SIGNATURE section serves a different purpose to the +preceding ones: to provide cryptographic authentication of a KRL that +is retrieved over a channel that does not provide integrity protection. +Its format is slightly different to the previously-described sections: +in order to simplify the signature generation, it includes as a "body" +two string components instead of one. + + byte KRL_SECTION_SIGNATURE + string signature_key + string signature + +The signature is calculated over the entire KRL from the KRL_MAGIC +to this subsection's "signature_key", including both and using the +signature generation rules appropriate for the type of "signature_key". + +This section must appear last in the KRL. If multiple signature sections +appear, they must appear consecutively at the end of the KRL file. + +Implementations that retrieve KRLs over untrusted channels must verify +signatures. Signature sections are optional for KRLs distributed by +trusted means. + +$OpenBSD: PROTOCOL.krl,v 1.5 2018/09/12 01:21:34 djm Exp $ diff --git a/PROTOCOL.mux b/PROTOCOL.mux new file mode 100644 index 0000000..77a0780 --- /dev/null +++ b/PROTOCOL.mux @@ -0,0 +1,298 @@ +This document describes the multiplexing protocol used by ssh(1)'s +ControlMaster connection-sharing. + +Multiplexing starts with a ssh(1) configured to act as a multiplexing +master. This will cause ssh(1) to listen on a Unix domain socket for +requests from clients. Clients communicate over this socket using a +simple packetised protocol, where each message is proceeded with +a length and message type in SSH uint32 wire format: + + uint32 packet length + uint32 packet type + ... packet body + +Most messages from the client to the server contain a "request id" +field. This field is returned in replies as "client request id" to +facilitate matching of responses to requests. + +Many muliplexing (mux) client requests yield immediate responses from +the mux process; requesting a forwarding, performing an alive check or +requesting the master terminate itself fall in to this category. + +The most common use of multiplexing however is to maintain multiple +concurrent sessions. These are supported via two separate modes: + +"Passenger" clients start by requesting a new session with a +MUX_C_NEW_SESSION message and passing stdio file descriptors over the +Unix domain control socket. The passenger client then waits until it is +signaled or the mux server closes the session. This mode is so named as +the client waits around while the mux server does all the driving. + +Stdio forwarding (requested using MUX_C_NEW_STDIO_FWD) is another +example of passenger mode; the client passes the stdio file descriptors +and passively waits for something to happen. + +"Proxy" clients, requested using MUX_C_PROXY, work quite differently. In +this mode, the mux client/server connection socket will stop speaking +the multiplexing protocol and start proxying SSH connection protocol +messages between the client and server. The client therefore must +speak a significant subset of the SSH protocol, but in return is able +to access basically the full suite of connection protocol features. +Moreover, as no file descriptor passing is required, the connection +supporting a proxy client may iteself be forwarded or relayed to another +host if necessary. + +1. Connection setup + +When a multiplexing connection is made to a ssh(1) operating as a +ControlMaster from a client ssh(1), the first action of each is send +a hello messages to its peer: + + uint32 MUX_MSG_HELLO + uint32 protocol version + string extension name [optional] + string extension value [optional] + ... + +The current version of the mux protocol is 4. A client should refuse +to connect to a master that speaks an unsupported protocol version. + +Following the version identifier are zero or more extensions represented +as a name/value pair. No extensions are currently defined. + +2. Opening a passenger mode session + +To open a new multiplexed session in passenger mode, a client sends the +following request: + + uint32 MUX_C_NEW_SESSION + uint32 request id + string reserved + bool want tty flag + bool want X11 forwarding flag + bool want agent flag + bool subsystem flag + uint32 escape char + string terminal type + string command + string environment string 0 [optional] + ... + +To disable the use of an escape character, "escape char" may be set +to 0xffffffff. "terminal type" is generally set to the value of +$TERM. zero or more environment strings may follow the command. + +The client then sends its standard input, output and error file +descriptors (in that order) using Unix domain socket control messages. + +The contents of "reserved" are currently ignored. + +If successful, the server will reply with MUX_S_SESSION_OPENED + + uint32 MUX_S_SESSION_OPENED + uint32 client request id + uint32 session id + +Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or +MUX_S_FAILURE. + +Once the server has received the fds, it will respond with MUX_S_OK +indicating that the session is up. The client now waits for the +session to end. When it does, the server will send an exit status +message: + + uint32 MUX_S_EXIT_MESSAGE + uint32 session id + uint32 exit value + +The client should exit with this value to mimic the behaviour of a +non-multiplexed ssh(1) connection. Two additional cases that the +client must cope with are it receiving a signal itself and the +server disconnecting without sending an exit message. + +A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE +if remote TTY allocation was unsuccessful. The client may use this to +return its local tty to "cooked" mode. + + uint32 MUX_S_TTY_ALLOC_FAIL + uint32 session id + +3. Requesting passenger-mode stdio forwarding + +A client may request the master to establish a stdio forwarding: + + uint32 MUX_C_NEW_STDIO_FWD + uint32 request id + string reserved + string connect host + string connect port + +The client then sends its standard input and output file descriptors +(in that order) using Unix domain socket control messages. + +The contents of "reserved" are currently ignored. + +A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED +or a MUX_S_FAILURE. + +4. Health checks + +The client may request a health check/PID report from a server: + + uint32 MUX_C_ALIVE_CHECK + uint32 request id + +The server replies with: + + uint32 MUX_S_ALIVE + uint32 client request id + uint32 server pid + +5. Remotely terminating a master + +A client may request that a master terminate immediately: + + uint32 MUX_C_TERMINATE + uint32 request id + +The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED. + +6. Requesting establishment of port forwards + +A client may request the master to establish a port forward: + + uint32 MUX_C_OPEN_FWD + uint32 request id + uint32 forwarding type + string listen host + uint32 listen port + string connect host + uint32 connect port + +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. + +If listen port is (unsigned int) -2, then the listen host is treated as +a unix socket path name. + +If connect port is (unsigned int) -2, then the connect host is treated +as a unix socket path name. + +A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a +MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. + +For dynamically allocated listen port the server replies with + + uint32 MUX_S_REMOTE_PORT + uint32 client request id + uint32 allocated remote listen port + +7. Requesting closure of port forwards + +Note: currently unimplemented (server will always reply with MUX_S_FAILURE). + +A client may request the master to close a port forward: + + uint32 MUX_C_CLOSE_FWD + uint32 request id + uint32 forwarding type + string listen host + uint32 listen port + string connect host + uint32 connect port + +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a +MUX_S_FAILURE. + +8. Requesting shutdown of mux listener + +A client may request the master to stop accepting new multiplexing requests +and remove its listener socket. + + uint32 MUX_C_STOP_LISTENING + uint32 request id + +A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a +MUX_S_FAILURE. + +9. Requesting proxy mode + +A client may request that the the control connection be placed in proxy +mode: + + uint32 MUX_C_PROXY + uint32 request id + +When a mux master receives this message, it will reply with a +confirmation: + + uint32 MUX_S_PROXY + uint32 request id + +And go into proxy mode. All subsequent data over the connection will +be formatted as unencrypted, unpadded, SSH transport messages: + + uint32 packet length + byte 0 (padding length) + byte packet type + byte[packet length - 2] ... + +The mux master will accept most connection messages and global requests, +and will translate channel identifiers to ensure that the proxy client has +globally unique channel numbers (i.e. a proxy client need not worry about +collisions with other clients). + +10. Status messages + +The MUX_S_OK message is empty: + + uint32 MUX_S_OK + uint32 client request id + +The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: + + uint32 MUX_S_PERMISSION_DENIED + uint32 client request id + string reason + + uint32 MUX_S_FAILURE + uint32 client request id + string reason + +11. Protocol numbers + +#define MUX_MSG_HELLO 0x00000001 +#define MUX_C_NEW_SESSION 0x10000002 +#define MUX_C_ALIVE_CHECK 0x10000004 +#define MUX_C_TERMINATE 0x10000005 +#define MUX_C_OPEN_FWD 0x10000006 +#define MUX_C_CLOSE_FWD 0x10000007 +#define MUX_C_NEW_STDIO_FWD 0x10000008 +#define MUX_C_STOP_LISTENING 0x10000009 +#define MUX_S_OK 0x80000001 +#define MUX_S_PERMISSION_DENIED 0x80000002 +#define MUX_S_FAILURE 0x80000003 +#define MUX_S_EXIT_MESSAGE 0x80000004 +#define MUX_S_ALIVE 0x80000005 +#define MUX_S_SESSION_OPENED 0x80000006 +#define MUX_S_REMOTE_PORT 0x80000007 +#define MUX_S_TTY_ALLOC_FAIL 0x80000008 + +#define MUX_FWD_LOCAL 1 +#define MUX_FWD_REMOTE 2 +#define MUX_FWD_DYNAMIC 3 + +XXX TODO +XXX extended status (e.g. report open channels / forwards) +XXX lock (maybe) +XXX watch in/out traffic (pre/post crypto) +XXX inject packet (what about replies) +XXX server->client error/warning notifications +XXX send signals via mux +XXX ^Z support in passengers +XXX extensions for multi-agent +XXX extensions for multi-X11 +XXX session inspection via master +XXX signals via mux request +XXX list active connections via mux + +$OpenBSD: PROTOCOL.mux,v 1.11 2018/09/26 07:30:05 djm Exp $ |