web-dev-qa-db-fra.com

Quelle est la signification du champ de version dans un message TLS 1.1+ ClientHello?

J'essaie d'ajouter la prise en charge TLS 1.1 et 1.2 à un produit de capture de paquets qui prend déjà en charge TLS 1.0.

J'ai utilisé Wireshark pour capturer le trafic entre mon navigateur et un serveur openssl pour générer des cas de test. J'ai vu une version TLS inattendue couler dans toutes les traces que j'ai créées.

Secure Sockets Layer
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 105
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 101
            Version: TLS 1.2 (0x0303)

Ce qui précède est un extrait d'une des traces TLS 1.2 tel que rapporté par Wireshark. La version donnée est TLS 1.0 dans ClientHello et 1.2 dans tous les messages suivants. Cela s'est produit dans les traces TLS 1.1 et 1.2.

Annexe E.1. (Compatibilité avec TLS 1.0/1.1 et SSL 3.0) du RFC TLS 1.2 dit:

Earlier versions of the TLS specification were not fully clear on
what the record layer version number (TLSPlaintext.version) should
contain when sending ClientHello (i.e., before it is known which
version of the protocol will be employed).  Thus, TLS servers
compliant with this specification MUST accept any value {03,XX} as
the record layer version number for ClientHello.

Cela en soi est aussi un peu ambigu pour moi.

Mes questions sont donc:

  • Ce champ peut-il avoir une valeur complètement arbitraire (tant qu'il est SSLv3 ou supérieur)?
  • Le comportement changera-t-il en fonction de la version indiquée dans ce champ?
  • Y a-t-il une importance pour le navigateur à choisir TLS 1.0 plutôt que SSLv3?

En relation:

  • https://security.stackexchange.com/a/26059/7866 Cette réponse suggère que SSLv3 devrait être utilisé dans ClientHello pour une interopérabilité maximale. La mention d'interopérabilité implique que le serveur se soucie de la valeur donnée.
13
Burhan Ali

Les champs de version se produisent à trois endroits:

  • dans le cadre de l'en-tête de chaque enregistrement envoyé par le client et le serveur;
  • dans le cadre du message ClientHello du client;
  • dans le cadre du message ServerHello du serveur.

Négociation de la version du protocole

Le champ version dans ClientHello est la version maximale prise en charge par l'implémentation client. Par exemple, lorsque le client met 0x0302 dans ce champ (c'est la valeur conventionnelle signifiant "TLS 1.1"), le client dit au serveur: "Je suis prêt à gérer toutes les versions de protocole jusqu'à TLS 1.1". Le champ de version dans le message ServerHello du serveur spécifie la version de protocole qui sera utilisée pour cette connexion. Le serveur doit utiliser la version de protocole la plus élevée prise en charge par le client et le serveur.

Le client ne doit pas annoncer la prise en charge d'une version de protocole qu'il ne prend pas réellement en charge, de peur qu'un serveur ne choisisse une telle version, croyant à tort que le client la prend en charge.

À propos des enregistrements

Le ClientHello du client est envoyé enveloppé dans un ou plusieurs enregistrements , et chaque enregistrement contient également la version du protocole. Les enregistrements sont comme les enveloppes autour des lettres. Il est sûr d'utiliser la version 0x0300 (SSLv3) pour ces enregistrements, quelle que soit la version maximale prise en charge indiquée dans le ClientHello; c'est comme envoyer une lettre dans une enveloppe SSLv3, mais la lettre dit "en passant, je supporte également TLS 1.0 et TLS 1.1". L'utilisation d'enregistrements SSLv3 maximise l'interopérabilité avec les implémentations anciennes et bogues qui ne connaissent que SSLv3 et rejetteraient les enregistrements avec une version supérieure.

La réponse du serveur indique la version du protocole qui sera utilisée et devrait provenir d'enregistrements portant cette version. Par exemple. si le serveur dit "TLS 1.1" dans son ServerHello alors que ServerHello devrait être enveloppé dans un enregistrement également étiqueté "TLS 1.1"; et tous les enregistrements ultérieurs du client et du serveur doivent utiliser cette version.

Interopérabilité

Théoriquement , un serveur doit accepter toute valeur supérieure ou égale à 0x0300 dans un champ de version, et ne doit pas se plaindre s'il contient, par ex. 0xA7C0 (signifiant "TLS 165.193", une version fictive qui ne sera probablement jamais définie). Cela vaut pour le message ClientHello et les en-têtes d'enregistrement. La version du protocole a un impact sur l'encodage des enregistrements, mais les premiers enregistrements sont en texte clair (pas de cryptographie), et pour eux, la version peut être ignorée car le texte clair est en texte clair (SSL 3.0, TLS 1.0, TLS 1.1 et TLS 1.2 les enregistrements en texte clair ne diffèrent que par la version spécifiée dans l'en-tête, mais sont par ailleurs identiques).

En pratique , il existe des rapports d'implémentations largement déployées qui ne tolèrent pas les champs "version" où le premier octet n'est pas 0x03. Il existe même des implémentations qui ne prennent pas en charge un ClientHello qui spécifie une version supérieure à 0x0301 (alias TLS 1.0).

Pour minimiser les problèmes, un client:

  • doit utiliser SSL 3.0 dans les enregistrements pour le ClientHello;
  • devrait spécifier sa version prise en charge la plus élevée dans le ClientHello;
  • peut échouer, en cas d'échec, à essayer à nouveau le ClientHello, cette fois en revendiquant une version prise en charge maximale inférieure (pour accueillir les anciens serveurs qui obtiennent un coup quand ils voient "TLS 1.1" ou "TLS 1.2").
21
Tom Leek