E. Rescorla (RTFM)N. Modadugu
(Stanford University)April20062009-06-16
Le protocole de cryptographieTLS, normalisé dans le , ne s'appliquait traditionnellement qu'à
TCP. Les applications utilisant
UDP, comme le fait souvent la
téléphonie sur IP ne pouvaient pas utiliser
TLS pour protéger leur trafic contre l'écoute ou la modification des
données. Mais, désormais, cette limitation disparait, DTLS permet de
protéger du trafic UDP. Ce RFC était le premier
sur DTLS, il a été remplacé depuis par le et l'ancienne version de DTLS décrite dans notre RFC est maintenant abandonnée.
TLS ne tournait que sur
TCP car il avait besoin d'un transport fiable, garantissant
que les données arrivent toutes, et dans l'ordre. Le grand succès de
TLS (notamment utilisé pour HTTP et
IMAP) vient de sa simplicité pour le
programmeur : rendre une application capable de faire du TLS ne
nécessite que très peu de code, exécuté juste avant l'envoi des
données. Par contre, cela laissait les applications
UDP comme
SIP non
protégées (section 1 de notre RFC). Les solutions existantes comme
IPsec ne sont
pas satisfaisantes, notamment parce qu'elles n'offrent pas la même
facilité de déploiement que TLS, qui tourne typiquement dans
l'application et pas dans le noyau.
DTLS a été conçu pour fournir TLS aux
applications UDP. Il offre les mêmes services que
TLS : garantie de
l'intégrité des données et
confidentialité.
La section 3 explique les principes de DTLS : protégé ou pas par
DTLS, UDP a la même sémantique, celle d'un service de datagrammes non fiable. DTLS est une
légère modification de TLS : il en garde les principales propriétés,
bonnes ou mauvaises.
Mais pourquoi ne peut-on pas faire du TLS normal sur UDP ? Parce
que TLS n'a pas été conçu pour tourner au dessus d'un protocole non
fiable. TLS organise les données en enregistrements
(records) et il ne permet pas de déchiffrer
indépendamment les enregistrements. Si l'enregistrement N est perdu,
le N+1 ne peut pas être déchiffré. De même, la procédure d'association initiale
de TLS (handshake) ne prévoit pas de perte de
messages et ne se termine pas si un message est perdu.
Le premier problème fait l'objet de la section 3.1. La dépendance
des enregistrements TLS vis-à-vis de leurs prédécesseurs vient du
chaînage cryptographique (chiffrement par
blocs) et de fonctions
anti-rejeu qui utilisent un numéro de séquence,
qui est implicitement le rang de l'enregistrement. DTLS résout le
problème en indiquant explicitement le rang dans les
enregistrements.
Et la question de l'association initiale est vue dans la section
3.2. Pour la perte de paquets lors de l'association, DTLS utilise un
système de retransmission (section 3.2.1) et pour l'éventuelle
réorganisation des paquets, DTLS introduit un numéro de séquence
(section 3.2.2). En prime, DTLS doit gérer la taille importante des
messages TLS (souvent plusieurs kilo-octets), qui peut être
supérieure à la MTU. DTLS permet donc une
fragmentation des paquets au niveau applicatif, un message pouvant
être réparti dans plusieurs enregistrements (section 3.2.3).
Enfin, l'anti-rejeu a été modifié pour tenir compte du fait que la
duplication de paquets, en UDP, n'est pas forcément malveillante
(sections 3.3 et 4.1.2.5).
La définition formelle du nouveau protocole est en section 4. DTLS
étant une légère évolution de TLS, la définition se fait uniquement en
listant les différences avec TLS, dont il faut donc garder le sous la main.
Au niveau du Record
Protocol de TLS, l'enregistrement spécifié dans la section
6.2.1 du gagne deux champs (section 4.1) :
struct {
ContentType type;
ProtocolVersion version;
uint16 epoch; // NOUVEAU
uint48 sequence_number; // NOUVEAU
uint16 length;
opaque fragment[DTLSPlaintext.length];
} DTLSPlaintext;
notamment le numéro de séquence sequence_number
(qui était implicite dans TLS, puisque TCP garantissait l'ordre des
messages). Pour éviter la fragmentation et les
ennuis associés, les mises en œuvre de DTLS doivent déterminer
la MTU du chemin et n'envoyer que des
enregistrements plus petits que cette MTU (section 4.1.1).
Contrairement à IPsec, DTLS n'a pas la notion d'identificateur
d'association. Une machine qui reçoit du TLS doit trouver
l'association toute seule, typiquement en utilisant le tuple
(adresse IP, port).
En toute rigueur, DTLS n'est pas spécifique à UDP, il peut marcher
sur n'importe quel protocole de transport ayant une sémantique
« datagrammes ». Certains de ces protocoles, comme
DCCP (cf. ), ont leur propres numéros de séquence et
ils font donc double emploi avec ceux de DTLS. Petite inefficacité pas
trop grave.
Au niveau du Hanshake protocol, les
modifications que DTLS apporte à TLS font l'objet de la section
4.2. Les trois principales sont :
L'ajout d'un gâteau pour limiter les risques de
DoS,Modification des en-têtes pour gérer les pertes ou
réordonnancements des paquets (section 4.2.2),Ajouts de minuteries pour
détecter les pertes de paquets (section 4.2.4).
Les gâteaux de DTLS sont analogues à ceux de
Photuris ou
IKE (section
4.2.1). Le message ClientHello de la section
7.4.1.2 du y gagne un champ :
opaque cookie<0..32>; // NOUVEAU
OpenSSL gère DTLS depuis la version 0.9.8
(on peut aussi consulter le site Web du
développeur). Un exemple d'utilisation se trouve dans . Il
me reste à inclure ce protocole dans echoping. GnuTLS
n'a pas de support DTLS (et aucun développement n'est en cours, les
volontaires sont les bienvenus).
Une très bonne description de la conception de Datagram
TLS et des choix qui ont été faits lors de sa mise au point,
se trouve dans l'article The Design
and Implementation of Datagram TLS, écrit par les
auteurs du RFC. C'est une lecture très recommandée.