Résumé

  • Dans RFC 5280, les mappages de politiques peuvent dupliquer les mêmes états à chaque niveau de certificat et faire croître valid_policy_tree de manière exponentielle.
  • RFC 9618 partage ces états dans un graphe acyclique orienté, borné linéairement par le nombre de politiques et de mappages, sans changer la validité du chemin ni l’ensemble final des politiques.
  • Une homologation sérieuse doit produire deux preuves : l’équivalence sémantique sur les cas difficiles et une enveloppe de ressources mesurée face aux entrées hostiles.

Le procès-verbal de recette semblait complet. L’ancien moteur et le nouveau acceptaient les mêmes certificats ; ils rejetaient les mêmes chaînes expirées ou incompatibles. Le fournisseur pouvait donc écrire « compatible » dans la dernière case.

Le document ne disait pas combien de mémoire chaque réponse avait coûté. Il ne disait pas non plus qu’une courte chaîne construite avec des mappages de politiques denses pouvait immobiliser un processus de validation. L’égalité des verdicts masquait une inégalité essentielle : l’un des moteurs pouvait fabriquer un objet interne exponentiellement plus grand que l’entrée reçue.

C’est le problème précis traité par RFC 9618. La sécurité d’un validateur ne réside pas seulement dans sa réponse. Elle dépend aussi de la quantité de travail qu’un interlocuteur non encore autorisé peut lui imposer avant cette réponse.

Ce que calcule la politique de certificat

L’extension certificatePolicies associe un certificat à des identifiants de politique, exprimés par des OID. Des certificats d’autorité peuvent limiter l’ensemble acceptable et relier une politique du domaine émetteur à une politique du domaine sujet. L’application part de ses politiques admissibles, puis le traitement du chemin conserve ce qui traverse les certificats, les contraintes et les mappages.

RFC 5280 décrivait ce traitement au moyen de valid_policy_tree. Il faut le distinguer de la construction du chemin : RFC 4158 explique comment trouver une chaîne candidate entre un certificat cible et une ancre de confiance. RFC 9618 intervient une fois cette chaîne connue, pendant sa validation.

Dans l’arbre, chaque itinéraire logique obtient ses propres nœuds. Si deux politiques émettrices conduisent à la même politique suivante, ce même état est copié deux fois. Les descendants de chaque copie sont à leur tour recopiés. Avec deux OID à chaque niveau et un produit cartésien complet des mappages, la taille double à chaque profondeur. Quelques certificats suffisent alors à provoquer beaucoup plus de calcul que leur taille sur le réseau ne le laisse prévoir.

Cette asymétrie constitue le déni de service. Un serveur TLS qui vérifie les certificats clients peut épuiser mémoire et processeur avant d’accepter ou de rejeter la chaîne. L’attaquant n’a pas besoin de falsifier une signature ni d’obtenir une identité : il lui suffit de faire payer au serveur l’expansion prescrite.

Les références à CVE-2023-0464 et CVE-2023-23524 relient l’algorithme à l’exploitation réelle. Le journal de correction OpenSSL décrit l’usage exponentiel des ressources et la limitation des nœuds de l’arbre. L’avis d’Apple indique qu’un certificat malveillant pouvait causer un déni de service. Le journal de versions OpenSSL conserve la trace de cette mitigation.

Partager l’état plutôt que recopier les chemins

RFC 9618 remplace l’arbre par valid_policy_graph, un graphe acyclique orienté organisé par profondeur de certificat. Pour un OID donné, il existe au plus un nœud à une profondeur donnée. Plusieurs parents peuvent pointer vers ce nœud partagé. Ses enfants n’ont donc pas à être répliqués pour chaque route qui y arrive.

Le graphe ne change pas le sens. L’ancien arbre correspond à l’énumération de tous les chemins entre la racine et les feuilles du graphe. On peut connaître les politiques atteignables sans matérialiser toutes les routes qui prouvent cette atteignabilité. La validité du chemin et les politiques finales demeurent les mêmes.

La différence porte sur la borne : la taille du graphe évolue linéairement avec le total des politiques et des mappages encodés. Une grande entrée reste coûteuse, mais une petite structure combinatoire ne crée plus silencieusement une représentation exponentielle.

Cette séparation illustre une bonne norme minimale. Le protocole commun fixe les invariants sémantiques — traitement de anyPolicy, compteurs, mappages, élagage et résultat — sans imposer une disposition mémoire particulière. L’implémentation locale garde sa liberté, à condition de conserver le sens et de rendre son coût contrôlable.

La sortie historique peut rouvrir la faille

Le point le plus délicat vient du contrat de sortie. RFC 5280 présentait l’arbre complet comme un résultat de validation. Un consommateur ancien peut donc demander cet objet, même si le validateur moderne travaille efficacement sur un graphe.

Déplier le graphe pour recréer chaque chemin reproduit précisément l’objet exponentiel. RFC 9618 déconseille et déprécie cette sortie. Il recommande de retourner les ensembles de politiques contraints par les autorités et par l’utilisateur. Pour beaucoup d’applications, ce résultat répond à la question métier sans exposer la structure complète.

Une reconstruction à la demande reste possible pour compatibilité, mais « à la demande » ne veut pas dire « sûre ». Le coût exponentiel est simplement reporté au moment où le client appelle l’ancienne interface. Cette reconstruction doit donc être isolée, limitée et attribuée à un propriétaire qui en accepte le risque.

Le choix est institutionnel autant que technique. Une API de diagnostic ne doit pas, par inertie, dicter la disponibilité de toutes les authentifications. L’organisation doit identifier les consommateurs qui utilisent réellement l’arbre, distinguer leur besoin de la simple habitude et supprimer leur pouvoir implicite sur le chemin critique.

Une limite n’est pas une preuve d’équivalence

Limiter la profondeur de chaîne ou le nombre de nœuds peut protéger les versions qui ne disposent pas encore du graphe. Ces mesures ont toutefois leur propre sémantique. Une profondeur trop faible rejette des chaînes légitimes ; une profondeur plus élevée peut encore autoriser de nombreux mappages. RFC 9618 explique que l’augmentation des politiques par certificat permet de conserver une croissance proche de O(N^(profondeur/2)).

Une limite de nœuds introduit aussi une nouvelle cause de rejet. Il faut savoir si elle intervient avant l’épuisement des ressources, quel message est renvoyé et quelles infrastructures légitimes elle exclut. Le nombre configuré ne constitue pas à lui seul un reçu opérationnel.

Désactiver le traitement des politiques n’autorise pas à ignorer leur sens. Si les extensions concernées sont critiques, un moteur incapable de les traiter doit les considérer comme non reconnues et rejeter le certificat. Cette règle protège le contrat signé de criticité ; elle ne doit pas être confondue avec le remplacement arbre-graphe.

Deux reçus pour une seule migration

Le reçu sémantique couvre les politiques ordinaires, les mappages multiples, anyPolicy, l’exigence de politique explicite, l’inhibition des mappages, l’inhibition de anyPolicy, l’élagage et l’ensemble final vide. Pour chaque cas, il compare succès ou échec et politiques finales. Un moteur rapide parce qu’il ignore une branche valable n’est pas conforme.

Le reçu de complexité fait varier séparément profondeur, politiques par certificat et multiplicité des parents. Il conserve la taille encodée, les nœuds et arêtes créés, la mémoire maximale, les allocations, le temps CPU et mural, le motif de rejet et l’effet sur les requêtes concurrentes. Un test isolé qui termine avant un délai global ne montre pas si dix requêtes épuisent la file.

Enfin, le reçu de déploiement identifie le binaire réellement chargé, ses options, la configuration active du traitement de politiques et les appels à l’ancienne sortie. Une publication ou un paquet disponible ne prouve pas que le processus en service l’utilise.

La conclusion est volontairement étroite. RFC 9618 ne résout pas toutes les attaques X.509. La construction du chemin, la révocation, les signatures, l’analyse ASN.1 et l’autorisation applicative gardent leurs propres risques. Il retire une amplification précise tout en conservant le résultat attendu. C’est justement ce qui permet de demander une preuve précise.

Sources