Aller au contenu principal

15. STUN Attributes (Attributs STUN)

Après l'en-tête STUN se trouvent zéro ou plusieurs attributs. Chaque attribut DOIT être encodé en TLV, avec un type de 16 bits, une longueur de 16 bits et une valeur. Chaque attribut STUN DOIT se terminer sur une limite de 32 bits. Comme mentionné ci-dessus, tous les champs d'un attribut sont transmis avec le bit le plus significatif en premier.

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Value (variable) ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 4: Format des attributs STUN

La valeur dans le champ de longueur DOIT contenir la longueur de la partie Value de l'attribut, avant le remplissage, mesurée en octets. Étant donné que STUN aligne les attributs sur des limites de 32 bits, les attributs dont le contenu n'est pas un multiple de 4 octets sont remplis avec 1, 2 ou 3 octets de remplissage afin que leur valeur contienne un multiple de 4 octets. Les bits de remplissage sont ignorés et peuvent avoir n'importe quelle valeur.

Tout type d'attribut PEUT apparaître plus d'une fois dans un message STUN. Sauf indication contraire, l'ordre d'apparition est significatif : seule la première occurrence doit être traitée par un récepteur, et tout duplicata PEUT être ignoré par un récepteur.

Pour permettre aux révisions futures de cette spécification d'ajouter de nouveaux attributs si nécessaire, l'espace d'attributs est divisé en deux plages. Les types d'attributs avec des valeurs entre 0x0000 et 0x7FFF sont des attributs à compréhension obligatoire, ce qui signifie que l'agent STUN ne peut pas traiter avec succès le message à moins qu'il ne comprenne l'attribut. Les types d'attributs avec des valeurs entre 0x8000 et 0xFFFF sont des attributs à compréhension optionnelle, ce qui signifie que ces attributs peuvent être ignorés par l'agent STUN s'il ne les comprend pas.

L'ensemble des types d'attributs STUN est maintenu par l'IANA. L'ensemble initial défini par cette spécification se trouve dans la Section 18.2.

Le reste de cette section décrit le format des différents attributs définis dans cette spécification.

15.1. MAPPED-ADDRESS

L'attribut MAPPED-ADDRESS indique une adresse de transport réflexive du client. Il se compose d'une famille d'adresses de 8 bits et d'un port de 16 bits, suivis d'une valeur de longueur fixe représentant l'adresse IP. Si la famille d'adresses est IPv4, l'adresse DOIT être de 32 bits. Si la famille d'adresses est IPv6, l'adresse DOIT être de 128 bits. Tous les champs doivent être dans l'ordre des octets du réseau.

Le format de l'attribut MAPPED-ADDRESS est :

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0| Family | Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Address (32 bits or 128 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 5: Format de l'attribut MAPPED-ADDRESS

La famille d'adresses peut prendre les valeurs suivantes :

  • 0x01: IPv4
  • 0x02: IPv6

Les 8 premiers bits du MAPPED-ADDRESS DOIVENT être définis sur 0 et DOIVENT être ignorés par les récepteurs. Ces bits sont présents pour aligner les paramètres sur des limites naturelles de 32 bits.

Cet attribut est utilisé uniquement par les serveurs pour assurer la rétrocompatibilité avec les clients RFC 3489 [RFC3489].

15.2. XOR-MAPPED-ADDRESS

L'attribut XOR-MAPPED-ADDRESS est identique à l'attribut MAPPED-ADDRESS, sauf que l'adresse de transport réflexive est obscurcie par la fonction XOR.

Le format du XOR-MAPPED-ADDRESS est :

   0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|x x x x x x x x| Family | X-Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| X-Address (Variable)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 6: Format de l'attribut XOR-MAPPED-ADDRESS

Family représente la famille d'adresses IP et est codée de manière identique à Family dans MAPPED-ADDRESS.

X-Port est calculé en prenant le port mappé dans l'ordre des octets de l'hôte, en effectuant un XOR avec les 16 bits les plus significatifs du magic cookie, puis en convertissant le résultat dans l'ordre des octets du réseau. Si la famille d'adresses IP est IPv4, X-Address est calculée en prenant l'adresse IP mappée dans l'ordre des octets de l'hôte, en effectuant un XOR avec le magic cookie, et en convertissant le résultat dans l'ordre des octets du réseau. Si la famille d'adresses IP est IPv6, X-Address est calculée en prenant l'adresse IP mappée dans l'ordre des octets de l'hôte, en effectuant un XOR avec la concaténation du magic cookie et de l'ID de transaction de 96 bits, et en convertissant le résultat dans l'ordre des octets du réseau.

Les règles d'encodage et de traitement des 8 premiers bits de la valeur de l'attribut, les règles de gestion des occurrences multiples de l'attribut et les règles de traitement des familles d'adresses sont les mêmes que pour MAPPED-ADDRESS.

Note : XOR-MAPPED-ADDRESS et MAPPED-ADDRESS ne diffèrent que dans leur encodage de l'adresse de transport. Le premier encode l'adresse de transport en effectuant un ou exclusif avec le magic cookie. Le second l'encode directement sous forme binaire. RFC 3489 spécifiait à l'origine uniquement MAPPED-ADDRESS. Cependant, l'expérience de déploiement a révélé que certains NAT réécrivent les charges utiles binaires de 32 bits contenant l'adresse IP publique du NAT, telles que l'attribut MAPPED-ADDRESS de STUN, dans une tentative bien intentionnée mais mal orientée de fournir une fonction ALG générique. Un tel comportement interfère avec le fonctionnement de STUN et provoque également l'échec de la vérification de l'intégrité des messages de STUN.

15.3. USERNAME

L'attribut USERNAME est utilisé pour l'intégrité des messages. Il identifie la combinaison nom d'utilisateur et mot de passe utilisée dans la vérification de l'intégrité des messages.

La valeur de USERNAME est une valeur de longueur variable. Elle DOIT contenir une séquence encodée en UTF-8 [RFC3629] de moins de 513 octets, et DOIT avoir été traitée à l'aide de SASLprep [RFC4013].

15.4. MESSAGE-INTEGRITY

L'attribut MESSAGE-INTEGRITY contient un HMAC-SHA1 [RFC2104] du message STUN. L'attribut MESSAGE-INTEGRITY peut être présent dans tout type de message STUN. Puisqu'il utilise le hachage SHA1, le HMAC sera de 20 octets. Le texte utilisé comme entrée pour HMAC est le message STUN, y compris l'en-tête, jusqu'à et y compris l'attribut précédant l'attribut MESSAGE-INTEGRITY. À l'exception de l'attribut FINGERPRINT (qui apparaît après MESSAGE-INTEGRITY), les agents DOIVENT ignorer tous les autres attributs qui suivent MESSAGE-INTEGRITY.

La clé pour le HMAC dépend de l'utilisation d'identifiants à long terme ou à court terme. Pour les identifiants à long terme, la clé est de 16 octets :

key = MD5(username ":" realm ":" SASLprep(password))

C'est-à-dire que la clé de 16 octets est formée en prenant le hachage MD5 du résultat de la concaténation des cinq champs suivants : (1) Le nom d'utilisateur, avec toutes les guillemets et les nulls de fin supprimés, de l'attribut USERNAME (s'il est présent) ; (2) Deux-points unique ; (3) Le realm, avec toutes les guillemets et les nulls de fin supprimés ; (4) Deux-points unique ; et (5) Le mot de passe, avec tous les nulls de fin supprimés et après traitement à l'aide de SASLprep. Par exemple, si le nom d'utilisateur était 'user', le realm était 'realm' et le mot de passe était 'pass', alors la clé HMAC de 16 octets serait le résultat de l'exécution d'un hachage MD5 sur la chaîne 'user:realm:pass', le hachage étant 0x8493fbc53ba582fb4c044c456bdc40eb.

Pour les identifiants à court terme :

key = SASLprep(password)

où MD5 est défini dans RFC 1321 [RFC1321] et SASLprep() est défini dans RFC 4013 [RFC4013].

La structure de la clé lorsqu'elle est utilisée avec des identifiants à long terme facilite le déploiement dans les systèmes qui utilisent également SIP. En règle générale, les systèmes SIP utilisant le mécanisme d'authentification digest de SIP ne stockent pas réellement le mot de passe dans la base de données. Au lieu de cela, ils stockent une valeur appelée H(A1), qui est égale à la clé définie ci-dessus.

Sur la base des règles ci-dessus, le hachage utilisé pour construire MESSAGE-INTEGRITY inclut le champ de longueur de l'en-tête du message STUN. Avant d'effectuer le hachage, l'attribut MESSAGE-INTEGRITY DOIT être inséré dans le message (avec un contenu factice). La longueur DOIT ensuite être définie pour pointer vers la longueur du message jusqu'à et y compris l'attribut MESSAGE-INTEGRITY lui-même, mais excluant tous les attributs après celui-ci. Une fois le calcul effectué, la valeur de l'attribut MESSAGE-INTEGRITY peut être remplie, et la valeur de la longueur dans l'en-tête STUN peut être définie sur sa valeur correcte -- la longueur du message entier. De même, lors de la validation du MESSAGE-INTEGRITY, le champ de longueur doit être ajusté pour pointer vers la fin de l'attribut MESSAGE-INTEGRITY avant de calculer le HMAC. Un tel ajustement est nécessaire lorsque des attributs, tels que FINGERPRINT, apparaissent après MESSAGE-INTEGRITY.

15.5. FINGERPRINT

L'attribut FINGERPRINT PEUT être présent dans tous les messages STUN. La valeur de l'attribut est calculée comme le CRC-32 du message STUN jusqu'à (mais excluant) l'attribut FINGERPRINT lui-même, effectuant un XOR avec la valeur 32 bits 0x5354554e (le XOR aide dans les cas où un paquet d'application utilise également CRC-32). Le CRC de 32 bits est celui défini dans ITU V.42 [ITU.V42.2002], qui a un polynôme générateur de x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1. Lorsqu'il est présent, l'attribut FINGERPRINT DOIT être le dernier attribut du message, et apparaîtra donc après MESSAGE-INTEGRITY.

L'attribut FINGERPRINT peut aider à distinguer les paquets STUN des paquets d'autres protocoles. Voir Section 8.

Comme avec MESSAGE-INTEGRITY, le CRC utilisé dans l'attribut FINGERPRINT couvre le champ de longueur de l'en-tête du message STUN. Par conséquent, cette valeur doit être correcte et inclure l'attribut CRC dans la longueur du message, avant le calcul du CRC. Lors de l'utilisation de l'attribut FINGERPRINT dans un message, l'attribut est d'abord placé dans le message avec une valeur factice, puis le CRC est calculé, puis la valeur de l'attribut est mise à jour. Si l'attribut MESSAGE-INTEGRITY est également présent, il doit avoir la valeur d'intégrité de message correcte avant que le CRC ne soit calculé, car le CRC est effectué sur la valeur de l'attribut MESSAGE-INTEGRITY également.

15.6. ERROR-CODE

L'attribut ERROR-CODE est utilisé dans les messages de réponse d'erreur. Il contient une valeur de code d'erreur numérique dans la plage de 300 à 699 plus une phrase de raison textuelle encodée en UTF-8 [RFC3629], et est cohérent dans ses affectations de code et sa sémantique avec SIP [RFC3261] et HTTP [RFC2616]. La phrase de raison est destinée à la consommation de l'utilisateur et peut être tout ce qui convient au code d'erreur. Les phrases de raison recommandées pour les codes d'erreur définis sont incluses dans le registre IANA pour les codes d'erreur. La phrase de raison DOIT être une séquence encodée UTF-8 [RFC3629] de moins de 128 caractères (qui peut aller jusqu'à 763 octets).

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved, should be 0 |Class| Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reason Phrase (variable) ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 7: Attribut ERROR-CODE

Pour faciliter le traitement, la classe du code d'erreur (le chiffre des centaines) est encodée séparément du reste du code, comme le montre la Figure 7.

Les bits réservés DEVRAIENT être 0 et sont pour l'alignement sur des limites de 32 bits. Les récepteurs DOIVENT ignorer ces bits. La classe représente le chiffre des centaines du code d'erreur. La valeur DOIT être entre 3 et 6. Le numéro représente le code d'erreur modulo 100, et sa valeur DOIT être entre 0 et 99.

Les codes d'erreur suivants, ainsi que leurs phrases de raison recommandées, sont définis :

300 Try Alternate : Le client devrait contacter un serveur alternatif pour cette demande. Cette réponse d'erreur NE DOIT être envoyée que si la demande incluait un attribut USERNAME et un attribut MESSAGE-INTEGRITY valide ; sinon, elle NE DOIT PAS être envoyée et le code d'erreur 400 (Bad Request) est suggéré. Cette réponse d'erreur DOIT être protégée avec l'attribut MESSAGE-INTEGRITY, et les récepteurs DOIVENT valider le MESSAGE-INTEGRITY de cette réponse avant de se rediriger vers un serveur alternatif.

Note : L'échec de la génération et de la validation de l'intégrité des messages pour une réponse 300 permet à un attaquant sur le chemin de falsifier une réponse 300, provoquant ainsi l'envoi de messages STUN ultérieurs à une victime.

400 Bad Request : La demande était mal formée. Le client NE DEVRAIT PAS réessayer la demande sans modification par rapport à la tentative précédente. Le serveur peut ne pas être en mesure de générer un MESSAGE-INTEGRITY valide pour cette erreur, donc le client NE DOIT PAS s'attendre à un attribut MESSAGE-INTEGRITY valide sur cette réponse.

401 Unauthorized : La demande ne contenait pas les informations d'identification correctes pour continuer. Le client devrait réessayer la demande avec les informations d'identification appropriées.

420 Unknown Attribute : Le serveur a reçu un paquet STUN contenant un attribut à compréhension obligatoire qu'il n'a pas compris. Le serveur DOIT mettre cet attribut inconnu dans l'attribut UNKNOWN-ATTRIBUTE de sa réponse d'erreur.

438 Stale Nonce : Le NONCE utilisé par le client n'était plus valide. Le client devrait réessayer en utilisant le NONCE fourni dans la réponse.

500 Server Error : Le serveur a subi une erreur temporaire. Le client devrait réessayer.

15.7. REALM

L'attribut REALM peut être présent dans les demandes et les réponses. Il contient du texte qui répond à la grammaire pour "realm-value" telle que décrite dans RFC 3261 [RFC3261] mais sans les guillemets doubles et leurs espaces environnants. C'est-à-dire qu'il s'agit d'une valeur de realm non citée (et donc d'une séquence de qdtext ou de quoted-pair). Il DOIT s'agir d'une séquence encodée UTF-8 [RFC3629] de moins de 128 caractères (qui peut aller jusqu'à 763 octets), et DOIT avoir été traitée à l'aide de SASLprep [RFC4013].

La présence de l'attribut REALM dans une demande indique que des identifiants à long terme sont utilisés pour l'authentification. La présence dans certaines réponses d'erreur indique que le serveur souhaite que le client utilise des identifiants à long terme pour l'authentification.

15.8. NONCE

L'attribut NONCE peut être présent dans les demandes et les réponses. Il contient une séquence de qdtext ou de quoted-pair, qui sont définis dans RFC 3261 [RFC3261]. Notez que cela signifie que l'attribut NONCE ne contiendra pas de caractères de citation réels. Voir RFC 2617 [RFC2617], Section 4.3, pour des conseils sur la sélection des valeurs nonce dans un serveur.

Il DOIT être inférieur à 128 caractères (qui peut aller jusqu'à 763 octets).

15.9. UNKNOWN-ATTRIBUTES

L'attribut UNKNOWN-ATTRIBUTES n'est présent que dans une réponse d'erreur lorsque le code de réponse dans l'attribut ERROR-CODE est 420.

L'attribut contient une liste de valeurs de 16 bits, chacune représentant un type d'attribut qui n'a pas été compris par le serveur.

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute 1 Type | Attribute 2 Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute 3 Type | Attribute 4 Type ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 8: Format de l'attribut UNKNOWN-ATTRIBUTES

Note : Dans [RFC3489], ce champ était rempli à 32 en dupliquant le dernier attribut. Dans cette version de la spécification, les règles de remplissage normales pour les attributs sont utilisées à la place.

15.10. SOFTWARE

L'attribut SOFTWARE contient une description textuelle du logiciel utilisé par l'agent envoyant le message. Il est utilisé par les clients et les serveurs. Sa valeur DEVRAIT inclure le fabricant et le numéro de version. L'attribut n'a aucun impact sur le fonctionnement du protocole et ne sert que d'outil à des fins de diagnostic et de débogage. La valeur de SOFTWARE est de longueur variable. Elle DOIT être une séquence encodée UTF-8 [RFC3629] de moins de 128 caractères (qui peut aller jusqu'à 763 octets).

15.11. ALTERNATE-SERVER

Le serveur alternatif représente une adresse de transport alternative identifiant un serveur STUN différent que le client STUN devrait essayer.

Il est encodé de la même manière que MAPPED-ADDRESS, et fait donc référence à un serveur unique par adresse IP. La famille d'adresses IP DOIT être identique à celle de l'adresse IP source de la demande.