Comme dit précédemment, le TLS est un protocole
à mi-chemin entre le transport et l'applicatif. Cette
ambiguïté est fortement marquée quand nous regardons de plus
près les spécifications détaillées dans la RFC
5246. Le TLS communique entre le client et le serveur au travers de 4 types de
messages principaux différents (appelés aussi high-level)
:
· Handshake protocol: permet
d'échanger sur les algorithmes de chiffrements qui seront
utilisés, mais également sur les différentes valeurs pour
générer les clefs de chiffrement. L'authentification des parties
via un certificat est gérée par ce type de message, et est
considérée comme optionnelle. Néanmoins, dans le contexte
de cet article, l'authentification du serveur sera considérée
comme obligatoire.
· Alert protocol : est en charge de la
notification d'erreurs repérées lors d'un échange TLS.
· Change cipher spec protocol: notifie
une volonté de changer les algorithmes de chiffrement utilisés
pour une session TLS en cours.
· Application data protocol : contient
la charge utile du TLS, c'est-à-dire, les données appli-catives
chiffrées.
Et un dernier pour les transporter tous : le TLS Record
Protocol qui a pour rôle d'annoncer et encapsuler les
différents messages du protocole.
2.6.1 Les messages d'extension
Il existe d'autres types de message mais qui sont liés
à des extensions TLS. Ces messages permettent d'ajouter des
paramètres lors de l'établissement d'une session TLS. Pour
exemple, il existe le type de message CertificateURL qui permet, lors
de l'authentification du client, que celui-ci n'envoie pas un certificat, mais
une URL vers un certificat pour l'authentifier. Cet article ne s'attardera pas
sur ces messages annexes, mais il est important de connaître leur
existence pour comprendre certaines problématiques de l'interception TLS
qui seront abordées dans d'autres chapitres.
2.6.2 TLS Record Protocol
Le TLS Record Protocol a plusieurs rôles à son
actif qui seront tous décrits :
· La gestion des états des connexions
· La fragmentation des données
· La compression et décompression des
données
· Le chiffrement des données envoyées
La gestion des états de connexions
C'est un concept important dans le TLS. Pour rappel, le TLS
va utiliser un chiffrement asymétrique en début de session puis
par la suite utiliser un chiffrement symétrique. Or, une des attaques
les plus fréquentes contre ce genre de chiffrement est l'analyse de
fréquence et l'attaque par message connu. Pour faire simple, un
même message chiffré avec la même clef donnera fatalement le
même message chiffré. Or, le TLS chiffre des informations
provenant de diverses applications, qui elles-mêmes utilisent un
formalisme pour la présentation des données. Par
conséquent, les en-têtes des messages applicatifs sont souvent les
mêmes et font des cibles parfaites pour l'attaque par message connu. Pour
pallier cela, il est important de changer régulièrement la clef
de chiffrement afin de limiter le nombre de messages chiffrés avec la
même clef. TLS propose donc de découper une session en plusieurs
connexions à état.
C'est-à-dire que chaque connexion aura son propre
environnement les valeurs qui permettent la
création des clefs de
chiffrement symétrique changeront entre chaque connexion.
Pour cela, le client et le serveur vont générer
une structure de données, appelée SecurityParame-ters(fig.
2.5 p.18), qui établira le contexte de la connexion.
Cette structure s'instancie suite aux premiers
échanges entre le client et le serveur à travers des messages
Handshake protocol. Nous y reviendrons en détail par la
suite.
Une fois cette structure remplie, les champs
prf_algorithm, master_secret, client_random et ser-ver_random
seront utilisés pour générer six nouvelles clefs :
Edouard Petitjean M2 MIAGE SIID 18
TLS : un protocole compliqué? - TLS : le protocole en
détail
uint8 enc_
key_length ;
length;
uint8 block_
iv_length ;
uint8 fixed_
uint8 record_
iv_length ;
MACAlgorithm mac_algorithm ;
uint8 mac_
uint8 mac_
CompressionMethod compression_algorithm ;
opaque master_secret [ 4 8 ] ;
opaque client_random [ 3 2 ] ;
opaque server_random [ 3 2 ] ;
} SecurityParameters ;
key_length ;
length;
struct {
ConnectionEnd entity;
PRFAlgorithm prf_algorithm ;
BulkCipherAlgorithm bulk_cipher_algorithm ;
CipherType cipher_type ;
FIGURE 2.5 - Définition de SecurityParameters dans la
RFC5246
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment [ TLSPlaintext . length];
} TLSPlaintext ;
FIGURE 2.6 - Définition de TLSPlaintext dans la
RFC5246
-- client write MAC key
-- server write MAC key -- client write encryption key -- server
write encryption key -- client write IV
-- server write IV
Ce sont ces six clefs qui seront utilisées pour
chiffrer et signer les messages. Les clefs client write seront
utilisées par le serveur quand il recevra des messages du client, tandis
que le client utilisera les clefs server write. Une fois ces clefs
générées, l'échange de message chiffré
pourra se faire. Pour finir, chaque connexion se verra attribuer un identifiant
unique appelé sequence number
Record Layer
C'est la couche en charge du transport des données
TLS. Pour que le client et le serveur puissent comprendre les données
TLS, celles-ci doivent être formatées de façon
précise. Notamment, le TLS utilise une notion de message de base
(TLS record Protocol) et de message high-level, or ces
derniers seront eux-mêmes encapsulés dans des messages de base. Le
formatage des données va respecter la structure TLSPlaintext (fig.
2.6 p.18) définie par la RFC5246.
A ce stade, il est important de comprendre chaque attribut de
cette structure.
· type : est un champ sur 1 octet qui
permet de définir le type de message qui sera contenu dans fragment.
Ce champ peut prendre les valeurs suivantes:
-- 20 : change_cipher_spec
-- 21 : alert
-- 22 : handshake
Edouard Petitjean M2 MIAGE SIID 19
TLS : un protocole compliqué? - TLS : le protocole en
détail
-- 23 : application_data
· version : est un champ composé
de 2 octets représentant respectivement la version majeure et mineure du
protocole utilisé. Le passage de SSL à TLS rend ce champ peu
instinctif pour ceux ne connaissant pas l'historique. Ce champ peut prendre les
valeurs suivantes:
-- 2 et 0 : SSL 2.0
-- 3 et 0 : SSL 3.0 -- 3 et 1 : TLS 1.0 -- 3 et 2 : TLS 1.1 -- 3
et 3 : TLS 1.2
· length : est un champ sur 2 octets
donnant la taille du buffer stocké dans fragment. Cette valeur
ne pas excéder 214, taille maximale pour fragment
· fragment : est un buffer contenant la
charge utile. C'est-à-dire les messages high-level. La
fragmentation de fragment.
La taille maximale prévue pour le buffer fragment
est de 214 octets. Il est rare que toutes les données
d'un message puissent être stockées dans un buffer de cette
taille. Par conséquent, le TLS record Protocol va
procéder à la fragmentation des données, puis envoyer
plusieurs messages TLS. Par la suite, le correspondant récupérera
tous ces fragments puis les concaténera pour reformer le message
envoyé.
La compression des messages
Elle permet de réduire la taille de la charge utile
à travers le TLS. Même si la compression n'est pas
utilisée, la structure TLSPlaintext sera transformée en
une structure TLSCompressed. Les attributs de la structure ne changent
pas. Mais son utilisation apporte quelques changements quant à la
structure utilisée pour échanger des messages. La taille limite
du buffer fragment (qui est donc de la donnée
compressée) est de 214 + 1024. Afin de prendre en compte
l'en-tête lié à l'algorithme de compression utilisé.
Mais il existe aussi une vérification lors de la décompression.
Si la donnée décompressée dépasse les
214 octets, alors TLS générera une erreur fatale et
mettra fin à la connexion en cours.
La protection de fragment
Elle va procéder au chiffrement de fragment.
Comme précédemment, la structure va changer et devenir une
structure TLSCiphertext. Cette fois, la taille limite de fragment
passe à 214 + 2048 octets. De plus, fragment ne
contiendra plus la donnée (compressée ou non), mais la
donnée chiffrée ainsi que la signature MAC. Cette dernière
sera un hash créé à partir de la MAC write key,
ainsi que de la concaténation des éléments suivants :
sequence number de la connexion, type, version, length et
fragment. Après cette dernière étape, le message
est envoyé au correspondant.
2.6.3 Handshake Protocol
Le Handshake Protocol est constitué de
messages permettant de gérer les échanges sur les informations
liées à l'établissement d'une session TLS. La
compréhension du Handshake Protocol est capitale pour
comprendre la technique de l'interception TLS que nous verrons par la
suite. Donc, ce type de message sera détaillé afin
d'appréhender sereinement la suite. Parmi les informations
échangées par le Handshake Protocol, il y a :
· session identifier : une séquence
d'octets permettant d'identifier une session.
· peer certificate : l'échange des
certificats et leur authentification.
· compression method : l'algorithme de compression
utilisé par TLS avant le chiffrement de données
· cipher spec : les différents
algorithmes de chiffrement qui seront utilisés par TLS
(génération de clefs, chiffrement, signature). Également
certaines valeurs sur la longueur des clefs ou de la signature.
Edouard Petitjean M2 MIAGE SIID 20
TLS : un protocole compliqué? - TLS : le protocole en
détail
FIGURE 2.7 - Echange TLS Handshake Protocol
· master secret : une séquence de 48
octets qui est un secret partagé entre le client et le serveur. Ce
secret sera par la suite utilisé comme source entropique pour
générer les clefs de chiffrement vues
précédemment.
· is resumable : un indicateur permettant de
définir si la session peut être réutilisée pour une
nouvelle connexion.
Toutes ces informations vont s'échanger en un minimum
d'échange pour accélérer l'établissement des
sessions. Le schéma fig. 2.7 p.20 donne un aperçu des
échanges.
Les échanges en bleus sont obligatoires dans le
protocole TLS alors que les échanges en jaunes sont facultatifs. La
flèche verte indique l'utilisation d'un autre protocole qui sera vu par
la suite.
Client Hello est le message envoyé
par le client au serveur qui va permettre le début de communication TLS.
Ce message est composé des éléments suivants :
· client_version : la version du protocole la
plus récente que le client supporte. La version reprend la codification
indiquée au paragraphe Record Layer p.18.
· random : un nombre composé de la
concaténation d'un horodatage représentant le nombre de secondes
depuis le 1er janvier 1970 sur 4 octets. Ainsi que
d'un nombre aléatoire de 28 octets généré via un
algorithme de génération sécurisée. Cette valeur
sera utilisée pour générer les clefs décrites au
paragraphe La gestion des états de connexions p.17.
· session_id : un nombre permettant
d'identifier la session en cours. Un champ vide (égale 0)
représente la volonté du client d'ouvrir/réinitialiser la
session actuelle.
· cipher_suites : la liste des suites de
chiffrements que le client supporte. Cette liste est ordonnancée par
ordre de préférence du client. Souvent, les protocoles les plus
sécurisés sont annoncés en début de liste, mais
certains clients peuvent préférer d'annoncer les suites de
chiffrement les plus stables en fonction de leur implémentation.
· compression_methods : une liste des
méthodes de compression supportées par le client. Son
ordonnancement suit la même logique que l'élément
précédent.
· extensions : une suite
d'éléments, tous indépendants les uns des autres, que le
client voudrait utiliser avec le serveur. La structure d'un
élément extension sera composée d'un identifiant
numérique de 2 octets, ainsi que de la donnée que l'extension va
utiliser. Il n'existe pas d'ordre de préférence pour annoncer les
extensions, mais chaque extension ne peut être annoncée qu'une
seule fois.
Server Hello est le message envoyé
par le serveur au client pour notifier le choix des options qu'il aura
établi en fonction des préférences du client et de ses
capacités. Les éléments qui composent ce message sont les
mêmes que pour Client Hello :
· server_version : la version la plus faible du
client et qui correspond à la version la plus haute du serveur.
Edouard Petitjean M2 MIAGE SIID 21
TLS : un protocole compliqué? - TLS : le protocole en
détail
· random: un nombre généré
aléatoirement par le serveur en se servant de la même
méthode que le client. A l'instar de la valeur contenue dans le
Client Hello, cette valeur sera utilisée lors de la
génération des clefs vues précédemment.
· session_id : un nombre permettant
d'identifier la session en cours. Si lors du message Client Hello, la
valeur est nulle, alors le serveur va renvoyer les valeurs qu'il aura choisies
pour cette session. Dans le cas contraire, le serveur va vérifier si la
valeur est en cache ou non. Si oui, alors le serveur va reprendre les valeurs
en cache. Sinon, il renvoie un session_id nul pour notifier au client
qu'un échange complet est nécessaire.
· cipher_suites : la suite de chiffrement qui
aura été retenue par le serveur. Pour choisir, le serveur
parcourra la liste envoyée par le client et récupérera la
première valeur qu'il supporte.
· compression_methods : la méthode de
compression retenue par le serveur. Son choix est similaire au
cipher_suites.
· extensions : les extensions demandées
par le client. Seules les extensions à l'initiative du client peuvent
être présentes.
Le certificat du serveur n'est pas la seule donnée qui
transite dans ce message. Pour rappel, les clients ne connaissent
généralement que les autorités de certificats racines. Par
conséquent, c'est souvent un certificat chaîné14
qui sera utilisé dans ce message.
Si ce message est utilisé, alors il fournira au client
une clef publique permettant l'utilisation d'un algorithme de chiffrement
asymétrique pour générer (Diffie-Hellman) ou chiffrer
(RSA) la clef premaster secret.
Ce message contiendra une liste de tous les DN des
autorités de certification qui devront avoir signé le certificat
du client. Aussi, le client ne peut pas présenter un certificat
signé par une AC ne se trouvant pas dans la liste envoyée par le
serveur.
14. une succession de certificat permettant de retrouver le
certificat du serveur, mais également les certificats des
autorités de certification intermédiaires
Ce protocole est très simple car il ne comporte qu'un
message contenant un seul octet défini à 1. Ce protocole est
utilisé par le client et le serveur pendant la phase de
négociation juste avant les messages Finished. Il permet de
signaler que les échanges qui auront lieu par la suite seront
chiffrés symétriquement via les nouvelles clefs
générées.