6. Protocole de paquets binaires (Binary Packet Protocol)
6. Protocole de paquets binaires (Binary Packet Protocol)
Chaque paquet a le format suivant :
uint32 packet_length
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
byte[m] mac (Message Authentication Code - MAC); m = mac_length
packet_length
The length of the packet in bytes, not including 'mac' or the
'packet_length' field itself.
padding_length
Length of 'random padding' (bytes).
payload
The useful contents of the packet. If compression has been
negotiated, this field is compressed. Initially, compression
MUST be "none".
random padding
Arbitrary-length padding, such that the total length of
(packet_length || padding_length || payload || random padding)
is a multiple of the cipher block size or 8, whichever is
larger. There MUST be at least four bytes of padding. The
padding SHOULD consist of random bytes. The maximum amount of
padding is 255 bytes.
mac
Message Authentication Code. If message authentication has
been negotiated, this field contains the MAC bytes. Initially,
the MAC algorithm MUST be "none".
Notez que la longueur de la concaténation de 'packet_length', 'padding_length', 'payload' et 'random padding' DOIT (MUST) être un multiple de la taille de bloc du chiffrement ou 8, selon la plus grande des deux. Cette contrainte DOIT (MUST) être respectée, même lors de l'emploi de chiffrements par flux (stream ciphers). Notez que le champ 'packet_length' est également chiffre, et son traitement exige des précautions particulières à l'envoi ou à la réception des paquets. Notez aussi que l'insertion de quantités variables de 'random padding' peut contribuer à contrer l'analyse du trafic (traffic analysis).
La taille minimale d'un paquet est de 16 octets (ou la taille de bloc du chiffrement, si elle est plus grande) (plus 'mac'). Les implémentations DEVRAIENT (SHOULD) déchiffrer la longueur après réception des 8 premiers octets (ou de la taille de bloc du chiffrement, selon la plus grande) d'un paquet.
6.1. Longueur maximale de paquet (Maximum Packet Length)
Toutes les implémentations DOIVENT (MUST) être capables de traiter des paquets dont la charge utile non compressée (uncompressed payload) est d'au plus 32 768 octets et dont la taille totale du paquet est d'au plus 35 000 octets (y compris 'packet_length', 'padding_length', 'payload', 'random padding' et 'mac'). Le maximum de 35 000 octets est une valeur choisie arbitrairement, supérieure à la longueur non compressée indiquée ci-dessus. Les implémentations DEVRAIENT (SHOULD) prendre en charge des paquets plus longs lorsque cela peut être nécessaire. Par exemple, si une implémentation souhaite envoyer un très grand nombre de certificats, des paquets plus longs PEUVENT (MAY) être envoyés si la chaîne d'identification indique que l'autre partie est capable de les traiter. Cependant, les implémentations DEVRAIENT (SHOULD) vérifier que la longueur du paquet est raisonnable afin d'éviter les attaques par déni de service (denial of service) et/ou par dépassement de tampon (buffer overflow).
6.2. Compression (Compression)
Si une compression a été négociée, le champ 'payload' (et lui seul) sera compressé au moyen de l'algorithme négocié. Les champs 'packet_length' et 'mac' seront calculés à partir de la charge utile compressée. Le chiffrement sera effectué après la compression.
La compression PEUT (MAY) être avec état (stateful), selon la méthode. La compression DOIT (MUST) être indépendante pour chaque direction, et les implémentations DOIVENT (MUST) permettre de choisir indépendamment l'algorithme pour chaque direction. En pratique toutefois, il est RECOMMANDÉ (RECOMMENDED) que la méthode de compression soit la même dans les deux sens.
Les méthodes de compression actuellement définies sont :
none REQUIRED no compression
zlib OPTIONAL ZLIB (LZ77) compression
La compression « zlib » est décrite dans [RFC1950] et [RFC1951]. Le contexte de compression est initialisé après chaque échange de clés, et est transmis d'un paquet au suivant, seule une purge partielle (partial flush) étant effectuée à la fin de chaque paquet. Une purge partielle signifie que le bloc compressé courant est terminé et que toutes les données sont produites en sortie. Si le bloc courant n'est pas un bloc stocké (stored block), un ou plusieurs blocs vides sont ajoutés après le bloc courant pour garantir qu'il y ait au moins 8 bits, en comptant depuis le début du code de fin de bloc du bloc courant jusqu'à la fin de la charge utile du paquet.
D'autres méthodes peuvent être définies comme précisé dans [SSH-ARCH] et [SSH-NUMBERS].
6.3. Chiffrement (Encryption)
Un algorithme de chiffrement et une clé seront négociés pendant l'échange de clés. Lorsque le chiffrement est actif, les champs longueur de paquet, longueur de bourrage, charge utile et bourrage de chaque paquet DOIVENT (MUST) être chiffrés avec l'algorithme indiqué.
Les données chiffrées de tous les paquets envoyés dans une direction DEVRAIENT (SHOULD) être considérées comme un unique flux de données. Par exemple, les vecteurs d'initialisation (initialization vectors) DEVRAIENT (SHOULD) être passés de la fin d'un paquet au début du suivant. Tous les chiffrements DEVRAIENT (SHOULD) utiliser des clés d'une longueur effective d'au moins 128 bits.
Les chiffrements dans chaque direction DOIVENT (MUST) fonctionner indépendamment l'un de l'autre. Les implémentations DOIVENT (MUST) permettre de sélectionner indépendamment l'algorithme pour chaque direction si plusieurs algorithmes sont autorisés par la politique locale. En pratique toutefois, il est RECOMMANDÉ (RECOMMENDED) d'employer le même algorithme dans les deux sens.
Les chiffrements actuellement définis sont :
3des-cbc REQUIRED three-key 3DES in CBC mode
blowfish-cbc OPTIONAL Blowfish in CBC mode
twofish256-cbc OPTIONAL Twofish in CBC mode,
with a 256-bit key
twofish-cbc OPTIONAL alias for "twofish256-cbc"
(this is being retained
for historical reasons)
twofish192-cbc OPTIONAL Twofish with a 192-bit key
twofish128-cbc OPTIONAL Twofish with a 128-bit key
aes256-cbc OPTIONAL AES in CBC mode,
with a 256-bit key
aes192-cbc OPTIONAL AES with a 192-bit key
aes128-cbc RECOMMENDED AES with a 128-bit key
serpent256-cbc OPTIONAL Serpent in CBC mode, with
a 256-bit key
serpent192-cbc OPTIONAL Serpent with a 192-bit key
serpent128-cbc OPTIONAL Serpent with a 128-bit key
arcfour OPTIONAL the ARCFOUR stream cipher
with a 128-bit key
idea-cbc OPTIONAL IDEA in CBC mode
cast128-cbc OPTIONAL CAST-128 in CBC mode
none OPTIONAL no encryption; NOT RECOMMENDED
Le chiffrement « 3des-cbc » est le triple DES à trois clés (chiffrement-déchiffrement-chiffrement), où les 8 premiers octets de la clé servent au premier chiffrement, les 8 suivants au déchiffrement, et les 8 suivants au chiffrement final. Cela exige 24 octets de données de clé (dont 168 bits sont réellement utilisés). Pour mettre en œuvre le mode CBC, un chaînage externe (outer chaining) DOIT (MUST) être utilisé (c'est-à-dire qu'il n'y a qu'un seul vecteur d'initialisation). Il s'agit d'un chiffrement par blocs de 8 octets. Cet algorithme est défini dans [FIPS-46-3]. Notez que, comme cet algorithme n'a qu'une longueur de clé effective de 112 bits ([SCHNEIER]), il ne satisfait pas aux spécifications voulant que les algorithmes de chiffrement SSH utilisent des clés de 128 bits ou plus. Cependant, cet algorithme reste REQUIS (REQUIRED) pour des raisons historiques ; en substance, toutes les implémentations connues au moment de la rédaction le prennent en charge, et il est couramment utilisé car c'est l'algorithme interopérable fondamental. On s'attend à ce qu'à un moment futur, un autre algorithme, de meilleure solidité, devienne suffisamment répandu pour que l'usage de « 3des-cbc » soit déprécié par une autre action de normalisation (STANDARDS ACTION).
Le chiffrement « blowfish-cbc » est Blowfish en mode CBC, avec des clés de 128 bits [SCHNEIER]. C'est un chiffrement par blocs de 8 octets.
Le chiffrement « twofish-cbc » ou « twofish256-cbc » est Twofish en mode CBC, avec des clés de 256 bits comme décrit dans [TWOFISH]. C'est un chiffrement par blocs de 16 octets.
Le chiffrement « twofish192-cbc » est le même que ci-dessus, mais avec une clé de 192 bits.
Le chiffrement « twofish128-cbc » est le même que ci-dessus, mais avec une clé de 128 bits.
Le chiffrement « aes256-cbc » est l'AES (Advanced Encryption Standard) [FIPS-197], en mode CBC. Cette version utilise une clé de 256 bits.
Le chiffrement « aes192-cbc » est le même que ci-dessus, mais avec une clé de 192 bits.
Le chiffrement « aes128-cbc » est le même que ci-dessus, mais avec une clé de 128 bits.
Le chiffrement « serpent256-cbc » est Serpent en mode CBC, avec une clé de 256 bits comme décrit dans la soumission Serpent à l'AES.
Le chiffrement « serpent192-cbc » est le même que ci-dessus, mais avec une clé de 192 bits.
Le chiffrement « serpent128-cbc » est le même que ci-dessus, mais avec une clé de 128 bits.
Le chiffrement « arcfour » est le chiffrement par flux Arcfour avec des clés de 128 bits. On estime que le chiffrement Arcfour est compatible avec le chiffrement RC4 [SCHNEIER]. Arcfour (et RC4) présente des problèmes de clés faibles (weak keys), et doit être utilisé avec prudence.
Le chiffrement « idea-cbc » est le chiffrement IDEA en mode CBC [SCHNEIER].
Le chiffrement « cast128-cbc » est le chiffrement CAST-128 en mode CBC avec une clé de 128 bits [RFC2144].
L'algorithme « none » indique qu'aucun chiffrement n'est appliqué. Notez que cette méthode n'apporte aucune confidentialité, et il n'est PAS RECOMMANDÉ (NOT RECOMMENDED) de l'utiliser. Certaines fonctionnalités (par ex. l'authentification par mot de passe) peuvent être désactivées pour des raisons de sécurité si ce chiffrement est choisi.
D'autres méthodes peuvent être définies comme précisé dans [SSH-ARCH] et [SSH-NUMBERS].
6.4. Intégrité des données (Data Integrity)
L'intégrité des données est protégée en incluant dans chaque paquet un MAC calculé à partir d'un secret partagé, du numéro de séquence du paquet et du contenu du paquet.
L'algorithme d'authentification des messages et la clé sont négociés pendant l'échange de clés. Initialement, aucun MAC n'est en vigueur, et sa longueur DOIT (MUST) être zéro. Après l'échange de clés, le 'mac' pour l'algorithme MAC choisi sera calculé avant le chiffrement à partir de la concaténation des données de paquet :
mac = MAC(key, sequence_number || unencrypted_packet)
où unencrypted_packet est l'intégralité du paquet sans 'mac' (les champs de longueur, 'payload' et 'random padding'), et sequence_number est un numéro de séquence de paquet implicite représenté en uint32. Le sequence_number est initialisé à zéro pour le premier paquet, et est incrémenté après chaque paquet (que le chiffrement ou le MAC soient utilisés ou non). Il n'est jamais réinitialisé, même si les clés ou algorithmes sont renégociés ultérieurement. Il repasse à zéro après chaque 2^32 paquets. Le numéro de séquence du paquet lui-même n'est pas inclus dans le paquet transmis sur le fil.
Les algorithmes MAC pour chaque direction DOIVENT (MUST) fonctionner indépendamment, et les implémentations DOIVENT (MUST) permettre de choisir l'algorithme indépendamment pour les deux directions. En pratique toutefois, il est RECOMMANDÉ (RECOMMENDED) d'utiliser le même algorithme dans les deux sens.
La valeur de 'mac' résultant de l'algorithme MAC DOIT (MUST) être transmise sans chiffrement comme dernière partie du paquet. Le nombre d'octets 'mac' dépend de l'algorithme choisi.
Les algorithmes MAC actuellement définis sont :
hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
length = 20)
hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
length = 12, key length = 20)
hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
length = 16)
hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
length = 12, key length = 16)
none OPTIONAL no MAC; NOT RECOMMENDED
Les algorithmes « hmac-* » sont décrits dans [RFC2104]. Les MAC « *-n » n'utilisent que les n premiers bits de la valeur résultante.
SHA-1 est décrit dans [FIPS-180-2] et MD5 dans [RFC1321].
D'autres méthodes peuvent être définies, comme précisé dans [SSH-ARCH] et [SSH-NUMBERS].
6.5. Méthodes d'échange de clés (Key Exchange Methods)
La méthode d'échange de clés (key exchange method) précise comment les clés de session à usage unique sont générées pour le chiffrement et pour l'authentification, et comment s'effectue l'authentification du serveur.
Deux méthodes d'échange de clés REQUISES (REQUIRED) ont été définies :
diffie-hellman-group1-sha1 REQUIRED
diffie-hellman-group14-sha1 REQUIRED
Ces méthodes sont décrites à la section 8.
D'autres méthodes peuvent être définies comme précisé dans [SSH-NUMBERS]. Le nom « diffie-hellman-group1-sha1 » désigne une méthode d'échange de clés utilisant un groupe Oakley, comme défini dans [RFC2409]. SSH maintient son propre espace d'identifiants de groupes, logiquement distinct d'Oakley [RFC2412] et d'IKE ; toutefois, pour un groupe supplémentaire, le groupe de travail a adopté le numéro attribué par [RFC3526], en utilisant diffie-hellman-group14-sha1 comme nom du second groupe défini. Les implémentations doivent traiter ces noms comme des identifiants opaques et ne pas supposer de relation entre les groupes utilisés par SSH et les groupes définis pour IKE.
6.6. Algorithmes à clé publique (Public Key Algorithms)
Ce protocole a été conçu pour fonctionner avec presque tout format de clé publique, encodage et algorithme (signature et/ou chiffrement).
Plusieurs aspects définissent un type de clé publique :
-
Format de clé (Key format) : comment la clé est encodée et comment les certificats sont représentés. Les blobs de clé dans ce protocole PEUVENT (MAY) contenir des certificats en plus des clés.
-
Algorithmes de signature et/ou de chiffrement. Certains types de clé peuvent ne pas prendre en charge à la fois la signature et le chiffrement. L'usage des clés peut aussi être restreint par des déclarations de politique (par ex. dans les certificats). Dans ce cas, différents types de clé DEVRAIENT (SHOULD) être définis pour les différentes alternatives de politique.
-
Encodage des signatures et/ou des données chiffrées. Cela inclut sans s'y limiter le bourrage, l'ordre des octets et les formats de données.
Les formats de clé publique et/ou de certificat actuellement définis sont :
ssh-dss REQUIRED sign Raw DSS Key
ssh-rsa RECOMMENDED sign Raw RSA Key
pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
D'autres types de clé peuvent être définis, comme précisé dans [SSH-ARCH] et [SSH-NUMBERS].
Le type de clé DOIT (MUST) toujours être explicitement connu (par la négociation d'algorithmes ou une autre source). Il n'est en général pas inclus dans le blob de clé.
Les certificats et les clés publiques sont encodés comme suit :
string certificate or public key format identifier
byte[n] key/certificate data
La partie certificat peut être une chaîne de longueur nulle, mais une clé publique est requise. Il s'agit de la clé publique qui sera utilisée pour l'authentification. La séquence de certificats contenue dans le blob de certificat peut servir à fournir l'autorisation.
Les formats de clé publique/certificat qui ne spécifient pas explicitement un identifiant de format de signature DOIVENT (MUST) utiliser l'identifiant de format de clé publique/certificat comme identifiant de signature.
Les signatures sont encodées comme suit :
string signature format identifier (as specified by the
public key/certificate format)
byte[n] signature blob in format specific encoding.
Le format de clé « ssh-dss » a l'encodage spécifique suivant :
string "ssh-dss"
mpint p
mpint q
mpint g
mpint y
Ici, les paramètres 'p', 'q', 'g' et 'y' forment le blob de clé de signature.
La signature et la vérification avec ce format de clé s'effectuent conformément au Digital Signature Standard [FIPS-186-2] en utilisant le hachage SHA-1 [FIPS-180-2].
La signature résultante est encodée comme suit :
string "ssh-dss"
string dss_signature_blob
La valeur de 'dss_signature_blob' est encodée comme une chaîne contenant r, suivie de s (qui sont des entiers de 160 bits, sans longueurs ni bourrage, non signés, et en ordre d'octets réseau).
Le format de clé « ssh-rsa » a l'encodage spécifique suivant :
string "ssh-rsa"
mpint e
mpint n
Ici les paramètres 'e' et 'n' forment le blob de clé de signature.
La signature et la vérification avec ce format de clé sont effectuées selon le schéma RSASSA-PKCS1-v1_5 de [RFC3447] en utilisant le hachage SHA-1.
La signature résultante est encodée comme suit :
string "ssh-rsa"
string rsa_signature_blob
La valeur de 'rsa_signature_blob' est encodée comme une chaîne contenant s (qui est un entier, sans longueurs ni bourrage, non signé, et en ordre d'octets réseau).
La méthode « pgp-sign-rsa » indique que les certificats, la clé publique et la signature sont au format binaire compatible OpenPGP ([RFC2440]). Cette méthode indique qu'il s'agit d'une clé RSA.
« pgp-sign-dss » est comme ci-dessus, mais indique qu'il s'agit d'une clé DSS.