Résumé

  • Dans la RFC 9846, close_notify clôt proprement un seul sens d’envoi TLS et fournit une borne contre la troncature. Il n’accuse réception ni du traitement applicatif, ni d’une écriture durable, ni d’un effet métier.
  • Il faut relier le dernier enregistrement TLS et l’alerte à un reçu applicatif distinct : identifiant d’opération, état autoritatif, réponse et règle de nouvelle tentative.

Un client envoie une instruction, vide son tampon puis voit arriver close_notify. La bibliothèque TLS signale une fin de données ordonnée. Rien dans cette séquence ne révèle si le service a refusé l’instruction, l’a placée dans une file, l’a validée en mémoire ou l’a effectivement inscrite dans son registre. La propreté du canal ne comble pas cette lacune.

La RFC 9846, norme proposée de juillet 2026 pour TLS 1.3, attribue à l’alerte une portée étroite. close_notify signifie que son émetteur n’enverra plus de message sur cette connexion. À sa réception, les données ultérieures doivent être ignorées et l’implémentation TLS devrait signaler à l’application une fin de données.

Il s’agit d’un sens de la connexion. Chaque partie peut fermer son côté écriture sans fermer son côté lecture. Un client peut cesser d’émettre tout en attendant la fin d’une réponse. Un serveur peut achever sa sortie et continuer à lire. Une alerte n’est donc ni un arrêt symétrique instantané, ni le second vote d’une validation distribuée.

Sauf si elle a déjà émis une alerte d’erreur, chaque partie doit envoyer close_notify avant de fermer son côté écriture. Elle n’est pourtant pas obligée d’attendre l’alerte du pair avant de fermer son côté lecture. La RFC précise que ce choix peut introduire une troncature. Deux directions gouvernées séparément donnent deux observations de fermeture.

La valeur principale de l’alerte est négative : elle borne ce qui ne viendra plus. Si le transport se ferme avant l’alerte, le destinataire ne peut pas savoir s’il a reçu toutes les données envoyées. Une alerte authentifiée retire cette ambiguïté pour la suite TLS de l’émetteur. Elle ne décrit pas l’état interne du programme qui a consommé les octets précédents.

Le registre IANA des paramètres TLS attribue le code correspondant. La RFC 9846 rétablit aussi l’obligation d’utiliser le niveau historique warning. Ce niveau n’en fait pas une suggestion facultative, pas plus que le mot « alerte » n’en fait une fermeture par erreur. Les alertes d’erreur ont un effet abortif et interdisent tout trafic ultérieur.

TLS 1.3 a justement séparé les directions pour éviter une ancienne forme de troncature. Des versions précédentes demandaient au destinataire de jeter ses écritures en attente, de répondre immédiatement et de fermer. Le pair pouvait alors lui couper une sortie encore utile. Désormais, le profil applicatif peut décider comment achever sa propre émission.

Cette liberté exige une politique. Une application peut vider son tampon et répondre aussitôt à l’alerte reçue, mais la RFC avertit qu’un attaquant peut influencer les données reçues par le pair en retardant l’alerte ou les paquets applicatifs. Il faut donc définir, au niveau applicatif, ce qui est encore accepté après l’envoi de la fermeture et quel message constitue le résultat final.

L’hypothèse de transport reste elle-même bornée. La RFC suppose que fermer le côté écriture livre de façon fiable les données en attente avant la destruction du transport. Même si cette hypothèse tient, « livré au pair TLS » ne veut pas dire « décodé par l’application », encore moins « validé dans une base » ou « réglé auprès d’un tiers ».

La RFC 9293 fournit le modèle TCP souvent sous-jacent, avec son flux d’octets ordonné et ses fermetures directionnelles. Les RFC 9110 et 9112 définissent au-dessus les messages et la sémantique HTTP. Assembler les couches ne fusionne pas leurs preuves de complétude.

Une opération HTTP peut exiger une réponse finale et un corps complet. Une file exige souvent un acquittement après persistance. Un paiement exige une référence stable et un état réconciliable. Aucun de ces objets n’est codé dans close_notify. La proximité temporelle entre dernière écriture, dernier record et fermeture aide à enquêter, mais ne crée pas de causalité métier.

L’erreur inverse est tout aussi coûteuse. L’absence de close_notify ne prouve pas l’échec de l’opération. Le serveur peut avoir validé l’effet et perdu la réponse pendant une rupture de transport. Rejouer automatiquement une commande non idempotente parce que la fermeture TLS est incomplète peut doubler l’effet que l’on croyait absent.

user_canceled ne fournit pas un vocabulaire métier de remplacement. Dans la RFC 9846, cette alerte concerne l’annulation d’une poignée de main pour une raison qui n’est pas une faute de protocole. Elle doit être suivie de close_notify, et le destinataire devrait continuer à lire jusque-là. Elle ne signifie ni remboursement, ni annulation de commande, ni retrait de consentement.

La norme préserve aussi l’autorité du profil d’usage. Si des données peuvent continuer sur le transport sous-jacent après la fermeture TLS, l’implémentation doit avoir reçu close_notify avant d’indiquer la fin TLS à l’application. Elle ne dicte toutefois pas quand le profil ouvre ou ferme le transport.

Les variantes de transport confirment la prudence nécessaire. La RFC 9001 utilise TLS pour la poignée de main QUIC, mais remplace sa couche d’enregistrements et emploie les fermetures propres à QUIC. La RFC 9147 adapte le modèle à DTLS. Une règle de reçu construite pour le flux TLS ne doit pas être appliquée par simple ressemblance à tous les transports chiffrés.

Enfin, la fermeture ne renouvelle pas l’identité. La RFC 9525 place la vérification de l’identité de service dans l’intégration entre application et TLS. close_notify ne refait pas la poignée de main, ne prolonge pas une autorisation et n’identifie pas l’être humain ayant demandé l’action.

Sources