Aller au contenu principal

RFC 6347 - 3. Aperçu de DTLS

3. Overview of DTLS

La philosophie de conception de DTLS est de construire « TLS au-dessus d'un transport à datagrammes ». TLS ne peut pas être utilisé directement car les paquets peuvent être perdus ou réordonnés. TLS n'a pas de mécanismes internes pour cette non-fiabilité ; les implémentations TLS échouent lorsqu'on les place sur un transport à datagrammes. DTLS vise les changements minimaux nécessaires à TLS pour corriger ce problème. Dans la mesure du possible, DTLS est identique à TLS ; les nouveaux mécanismes cherchent à préserver le style de TLS.

La non-fiabilité pose problème à TLS à deux niveaux :

  1. TLS ne permet pas le déchiffrement indépendant d'enregistrements individuels. Comme le contrôle d'intégrité dépend du numéro de séquence, si l'enregistrement N n'est pas reçu, le contrôle sur N+1 utilisera un mauvais numéro et échouera. (Avant TLS 1.1, il n'y avait pas d'IV explicite et le déchiffrement échouait aussi.)

  2. La couche de poignée de main TLS suppose une livraison fiable des messages et échoue si des messages sont perdus.

Le reste de cette section décrit l'approche de DTLS.

3.1. Loss-Insensitive Messaging

Dans la couche d'enregistrement TLS, les enregistrements ne sont pas indépendants. Deux types de dépendance :

  1. Le contexte cryptographique (flux de clé de chiffrement par flux) est conservé entre enregistrements.

  2. La protection anti-rejeu et contre le réordonnancement repose sur un MAC incluant un numéro de séquence implicite dans les enregistrements.

DTLS interdit les chiffres par flux pour le premier problème et ajoute des numéros de séquence explicites pour le second.

3.2. Providing Reliability for Handshake

La poignée de main TLS est une séquence cryptographique strictement ordonnée. Tout autre ordre est une erreur ; cela est incompatible avec la perte et le réordonnancement. De plus, les messages peuvent dépasser un datagramme, ce qui pose le problème de fragmentation IP. DTLS doit corriger ces deux points.

3.2.1. Packet Loss

DTLS utilise un temporisateur de retransmission simple. La figure ci-dessous illustre la première phase :

        Client                                   Server
------ ------
ClientHello ------>

X<-- HelloVerifyRequest
(lost)

[Timer Expires]

ClientHello ------>
(retransmit)

Après avoir envoyé ClientHello, le client attend HelloVerifyRequest. Si le message du serveur est perdu, le client suppose que ClientHello ou HelloVerifyRequest a été perdu et retransmet. À la réception, le serveur retransmet à son tour.

Le serveur maintient aussi un temporisateur de retransmission.

Le temporisateur ne s'applique pas à HelloVerifyRequest, car cela imposerait de créer de l'état côté serveur. HelloVerifyRequest est conçu pour rester assez petit pour éviter la fragmentation et l'entrelacement de plusieurs HelloVerifyRequest.

3.2.2. Reordering

Chaque message de poignée de main reçoit un numéro de séquence. Le pair peut vérifier s'il s'agit du prochain message attendu ; sinon il le met en file jusqu'à réception des messages précédents.

3.2.3. Message Size

Les messages TLS/DTLS peuvent être très grands (théoriquement jusqu'à 2^24-1 octets, en pratique plusieurs kilo-octets). Les datagrammes UDP sont souvent limités à moins de 1500 octets sans fragmentation IP. Chaque message DTLS peut être fragmenté sur plusieurs enregistrements DTLS, chacun devant tenir dans un datagramme IP. Chaque message contient un décalage et une longueur de fragment ; le destinataire peut réassembler le message.

3.3. Replay Detection

DTLS peut détecter le rejeu d'enregistrements, comme IPsec AH/ESP, via une fenêtre bitmap des enregistrements reçus. Les enregistrements trop anciens ou déjà reçus sont ignorés silencieusement. La fonction est optionnelle car la duplication peut être due à des erreurs de routage. Les applications peuvent détecter les doublons et adapter leur stratégie d'envoi.