Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-042 — Pile TLS : rustls + aws-lc-rs (exception C nommée, étroite), TLS 1.3, air-tls maison en contingence

Statut : Accepté (2026-06-25, validé par le BDFL). Companion de la note docs/notes/reseau-architecture-crates-fr.md (architecture des crates réseau) ; déroge ponctuellement à la politique « zéro surface C » (audit 082, check-c-surface, deny.toml) via une exception nommée au sens ADR-024/ADR-034 ; impacte ADR-025 (toolchain C au build). Cohérent avec le choix RustCrypto d’air-crypto.

Catégorie : Architecture (couche 2 — air-tls/réseau) / Sécurité.

Contexte

La pile TLS conditionne toute la connectivité sécurisée d’Air (HTTPS, QUIC/HTTP-3, demain les services AirCom distants). C’est aussi la surface de sécurité la plus critique d’un système. Deux dogmes Air s’y opposaient en apparence : « on ne réécrit pas de crypto » et « zéro surface C ». Une analyse a été menée explicitement (cette session) ; cet ADR en consigne le résultat et le raisonnement.

Démarche d’analyse (consignée pour transparence)

  1. Frontière primitives / protocole. « Pile TLS maison » ne signifierait jamais réécrire des primitives crypto (AES, ChaCha20, SHA, X25519, Ed25519…) — celles-ci restent RustCrypto/équivalent. Seul le protocole (record layer, handshake, key schedule, machine à états, X.509) serait « à nous ». C’est exactement ce que fait rustls : le protocole, au-dessus d’un provider crypto enfichable.
  2. Classes de vulnérabilités TLS : (a) sûreté mémoire (Heartbleed-class — empiriquement dominante, vit dans le C) ; (b) machine à états / protocole (goto fail, downgrade) ; (c) side-channel / primitives (Lucky13, Bleichenbacher). « Sécurité maximale » veut neutraliser les trois.
  3. Comparaison des piles (focus sécurité) : la plus sûre n’est pas une pile tout-C (même la meilleure, s2n-tls d’AWS — petite, machine à états formellement vérifiée — ne peut éliminer la classe (a) par construction). La combinaison la plus sûre disponible = protocole memory-safe + primitives formellement vérifiées.
  4. Providers rustls : ring (C+asm, maintenance irrégulière), aws-lc-rs (AWS-LC : C+asm, équipe AWS financée, asm formellement vérifié, FIPS 140-3, devenu défaut de rustls), rustls-rustcrypto (pur Rust, non-défaut, moins éprouvé).

Décision

La pile TLS d’Air est rustls (protocole, pur Rust, memory-safe) + aws-lc-rs (provider crypto, AWS-LC) + rustls-webpki (validation X.509, pur Rust). TLS 1.3 ciblé. Le C est admis par EXCEPTION NOMMÉE, ÉTROITE : il ne concerne QUE les primitives crypto (aws-lc-sys), jamais le protocole ni le parseur X.509, qui restent memory-safe Rust.

Justification (sécurité + fiabilité) :

  • La partie bug-prone reste memory-safe. Record layer, handshake, machine à états et parsing X.509/ASN.1 (la surface hostile, là où vivent les CVE catastrophiques) sont en Rust (rustls + rustls-webpki) → la classe (a) est éliminée par construction là où elle compte.
  • Le C est confiné là où il a une valeur prouvée : les primitives d’aws-lc-rs, asm formellement vérifié, FIPS 140-3, constant-time, équipe AWS financée (réponse sécurité rapide — fiabilité sur 10-20 ans). C’est une petite surface auditée, pas le protocole tentaculaire.
  • rustls : protocole moderne TLS 1.2/1.3 only (zéro legacy), financé ISRG (Let’s Encrypt), testé contre BoGo, largement déployé. C’est le défaut qu’AWS/ISRG recommandent.

→ C’est la combinaison la plus secure objectivement disponible aujourd’hui : memory-safety + vérification formelle + TLS 1.3 + maintenance financée — qu’aucune pile seule (ni full-C, ni full-pur-Rust) n’égale.

Périmètre

  • TLS 1.3 ciblé ; rustls est configuré 1.3-first (1.2 admis seulement si un besoin d’interop réel l’impose, configurable — par défaut on minimise la surface legacy).
  • X.509 : rustls-webpki (pur Rust). Pas de parseur ASN.1 maison.
  • Exception C : limitée à aws-lc-sys/aws-lc-rs (+ ses outils de build cc/cmake). Aucune autre surface C n’est ouverte par cet ADR.

Contingence — air-tls maison reste une porte de sortie

Un air-tls maison (protocole TLS implémenté par Air, sur le patron sans-IO 9-composants de la note réseau, primitives RustCrypto, régime d’homologation IETF — RFC 8448, tlsfuzzer, interop, fuzzing) pourra voir le jour SI le choix rustls devient un passif : faille de sécurité non corrigée en temps voulu, abandon/maintenance dégradée, ou complexité d’intégration rédhibitoire. Cette option est explicitement gardée ouverte (souveraineté + valeur de démonstration), mais n’est pas le choix présent : on ne porte pas le pari le plus risqué tant que rustls fait le travail.

Conséquences

  • Exception nommée à appliquer à l’implémentation (pas maintenant — aucun code réseau encore). Quand la dépendance rustls entrera (crate air-tls/air-network) :
    • deny.toml : lever le ban de aws-lc-sys (et cc/cmake sur ce sous-arbre) par une entrée nominative justifiée ; ring reste banni (on prend aws-lc-rs, pas ring).
    • docs/EXCEPTIONS.md : entrée nommée (motif = sécurité par crypto formellement vérifiée/FIPS + memory-safety du protocole ; plan de sortie = air-tls maison en contingence).
    • check-c-surface : ajuster pour autoriser uniquement aws-lc-sys (le ban générique *-sys reste pour tout le reste).
  • Builds reproductibles (ADR-025) : aws-lc-rs tire un build C (cmake)pinner la toolchain C ou utiliser les bindings pré-générés ; à traiter dans la spec air-tls (sinon la repro cargo-only ne tient plus pour ce crate).
  • Homologation : même sans pile maison, on impose et publie un régime de test/ interop sur notre intégration (matrice d’interop OpenSSL/rustls, RFC 8448 rejouées via rustls, fuzzing de notre couche d’intégration) — la rigueur reste, l’effort est moindre.
  • air-tls maison : tracé comme option de contingence dans la note réseau.

Alternatives écartées

  • air-tls maison d’emblée : le pari maison le plus risqué (historique TLS brutal) ; tout à prouver ; reporté en contingence plutôt qu’écarté.
  • rustls + provider RustCrypto (zéro-C total) : séduisant (pas d’exception C), mais provider non-défaut, moins éprouvé, sans vérification formelle ni FIPS → moins sûr que aws-lc-rs sur la classe (c). Recevable comme repli si l’exception C devait être refermée.
  • Pile tout-C (OpenSSL/BoringSSL/s2n) : protocole+parsing en C → expose la classe (a) (mémoire), la plus dommageable. Rejeté.

Adoption

Documentaire immédiat (ADR-042 + registre/INDEX/SUMMARY + correction de la ligne air-tls de la note réseau). Les changements deny.toml/EXCEPTIONS.md/check-c-surface et le pinning toolchain C (ADR-025) sont appliqués à l’implémentation d’air-tls/air-network (spec à venir), pas avant.