Résumé

  • Dans le profil RPKI, la RFC 6487 interdit les champs authorityCertIssuer et authorityCertSerialNumber dans l’extension Authority Key Identifier, alors que la RFC 5280 les prévoit dans la syntaxe X.509 générale.
  • Le commit Barry 994a598 relie authorityCertIssuer à un parseur de GeneralNames qui exige un tableau. Le lendemain, le commit Rapport b1a59a remplace l’ancienne chaîne scalaire par un tableau d’un rfc822Name et corrige le message attendu pour FORT.
  • Le script enchaîne Barry, le relying party, la vérification du journal puis celle des VRP. Ces quatre étapes expriment une intention ; aucun artefact public capturé ne prouve que ce commit a effectivement exécuté toute la chaîne.
  • Rapport annonce quatre sélecteurs de validateurs, mais le diagnostic précis de ce scénario n’est contrôlé que pour fort2. Pour les autres, un ensemble de VRP vide constate une conséquence sans identifier nécessairement sa cause.

L’objet invalide doit d’abord exister

Le scénario porte sur une règle nette. L’Authority Key Identifier d’un certificat de ressources doit permettre de retrouver la clé de l’émetteur. La RFC 6487 impose cette extension, sauf cas particulier du certificat auto-signé, exige qu’elle soit non critique et interdit la présence de authorityCertIssuer comme de authorityCertSerialNumber. Le profil X.509 plus général est moins restrictif : la RFC 5280 définit ces deux membres facultatifs et demande qu’ils soient utilisés ensemble. Le profil RPKI ferme donc volontairement une possibilité offerte par la syntaxe de base.

Sur le papier, le test paraît trivial : ajouter le membre interdit à un certificat d’autorité, placer un ROA sous cette autorité, puis vérifier qu’aucune charge utile de routage n’est acceptée. En pratique, le premier verbe est décisif. Si le générateur refuse le fichier de description, omet le champ ou s’arrête avant d’émettre le certificat, le validateur n’a jamais vu la faute recherchée. Un résultat vide peut alors sembler rassurant tout en répondant à une autre question.

Barry est précisément le générateur de cette expérience. LACNIC l’a présenté comme un outil capable de produire des dépôts RPKI valides ou volontairement invalides à partir d’une description clé-valeur. Rapport orchestre ensuite ces dépôts face à un relying party et examine ses sorties. Cette division du travail crée deux systèmes sous observation : le validateur, bien sûr, mais aussi la machine qui fabrique son entrée.

Le type de données change le sens du test

Le 1er septembre 2026, le commit Barry 994a598321336baf1767f0fbfb460ed96c29fe4f ajoute la prise en charge de authorityCertIssuer. Dans ext.c, le champ est associé au type interne ft_gnames. Dans field.c, la fonction parse_gnames exige une valeur de type ensemble ou tableau, compte ses membres, alloue les objets ASN.1 correspondants puis analyse chacun comme un GeneralName. Si la valeur n’est pas un tableau, elle emprunte le chemin d’erreur « ensemble/tableau attendu ».

Le nouveau test fonctionnel de Barry rend ce contrat concret. Son tableau contient successivement une adresse de courrier sous forme rfc822Name, une adresse IP et un identifiant enregistré. Il ne s’agit pas d’un exemple de certificat RPKI conforme ; c’est une démonstration de ce que le générateur sait encoder dans un GeneralNames.

À la révision parente du scénario Rapport, la donnée n’avait pas cette forme. Le fichier affectait à authorityCertIssuer la simple chaîne CN=Fake Issuer. La comparaison du code permet une conclusion prudente : cette valeur scalaire ne satisfait pas le contrat actuel du parseur de Barry. Elle ne permet pas de raconter ce qui s’est passé lors d’une exécution ancienne, avec un binaire ancien ou une configuration particulière. Aucun journal de cette exécution n’est disponible dans le paquet public observé.

Le 2 septembre, Rapport corrige le scénario dans b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c. La chaîne devient un tableau comportant un seul objet : type rfc822Name, avec une adresse d’exemple comme valeur. L’identité choisie importe peu ; le profil RPKI interdit le membre tout entier. L’essentiel est que la valeur est désormais exprimée dans la grammaire que Barry attend et peut donc, en principe, parvenir au certificat encodé.

Le journal attendait aussi le mauvais motif

L’ancien run.sh cherchait dans le journal de FORT un message relatif à authorityCertSerialNumber. Or le scénario tentait d’introduire authorityCertIssuer. Le commit de correction aligne le diagnostic attendu sur le champ testé. Ce second changement empêche une confusion symétrique : fabriquer le bon défaut, mais attribuer le rejet à un autre défaut.

Le déroulement du script est instructif. run_barry vient avant run_rp; ensuite seulement arrive check_logfile, puis check_vrps. On peut en tirer un modèle de preuve en quatre reçus distincts : succès du générateur, certificat décodé montrant le membre interdit, cycle du validateur identifié, enfin diagnostic et résultat de VRP correspondant. Le code montre l’ordre voulu, pas les reçus eux-mêmes.

Le point est important parce que la surface publique du commit ne présente aucun check run. Le dépôt Rapport n’expose ni tag ni release au moment de la capture. Cela ne prouve nullement l’absence de tests locaux, d’intégration privée ou de paquetage externe. Cela interdit seulement de transformer une correction de source en résultat exécuté et versionné sans une pièce supplémentaire.

Un fichier vide ne donne pas la cause

Le helper check_vrps crée d’abord le fichier attendu à partir de ses arguments. Ici, le script l’appelle sans argument : l’attendu est donc vide. Les VRP effectivement produits sont normalisés, triés et comparés à ce vide. Si la comparaison réussit, le scénario établit qu’aucun VRP n’est sorti par ce chemin.

C’est une conséquence utile, car le dépôt contient un ROA sous le certificat fautif. Ce n’est pas encore un diagnostic. Un échec de récupération, un mauvais trust anchor, une autre anomalie du dépôt ou l’absence même du certificat peut également conduire au vide. Pour relier la conséquence à authorityCertIssuer, il faut la preuve de construction et un signal du validateur.

Ce dernier signal n’est pas uniforme. Le script appelle check_logfile fort2 .... Le helper ne contrôle le journal que si la variable RP vaut exactement le sélecteur demandé ; sinon il retourne sans erreur. Le message précis sur authorityCertIssuer est donc une assertion propre à FORT 2 dans ce scénario.

Le README de la révision épinglée répertorie pourtant quatre valeurs de RP : fort2, routinator, rpki-client et rpki-prover, une seule étant visée à chaque exécution. Cette pluralité d’adaptateurs est prometteuse, mais elle ne rend pas automatiquement les preuves équivalentes. Avec les trois autres validateurs, le scénario vérifie toujours le résultat vide ; la source ne montre pas une assertion propre à chacun qui nomme la raison du rejet.

Le reçu minimal d’un résultat portable

Une matrice de conformité honnête devrait séparer trois colonnes : construction, décision, sortie. Pour la construction, elle conserverait le commit et l’empreinte du binaire Barry, le hash du fichier de scénario, le code de sortie, le certificat généré et un décodage de son AKI. Pour la décision, elle indiquerait le validateur, sa version, sa configuration, le trust anchor et, si l’interface le permet, le code ou message de rejet. Pour la sortie, elle publierait les empreintes des ensembles VRP attendu et observé.

Tous les validateurs ne promettent pas un texte de journal stable, et il serait contre-productif d’imposer une phrase commune. Un code structuré, une classe d’erreur propre au produit ou une conclusion strictement limitée à « aucune charge utile acceptée » peuvent convenir. La comparabilité vient de la précision de la revendication, non de l’uniformité artificielle des interfaces.

Il faut également distinguer le test présent dans la branche, le test exécuté, puis le test inclus dans une version. Le premier prouve une intention contrôlable par lecture du code. Le deuxième ajoute l’environnement et les artefacts. Le troisième permet à un opérateur de relier le résultat à la version qu’il envisage de déployer. Une case verte qui efface ces trois états reporte l’incertitude sur l’acheteur.

LACNIC décrivait Barry et Rapport comme encore jeunes dans son billet de décembre 2025. À cette date, le texte mettait FORT au premier plan ; le README ultérieur annonce quatre sélecteurs. Ces deux sources racontent une évolution, pas une contradiction à résoudre. Le bon niveau de prudence consiste à dater chaque capacité et chaque preuve.

La conclusion la plus solide reste donc limitée. Barry a acquis la mécanique nécessaire pour encoder authorityCertIssuer. Rapport a ensuite adapté le type de la fixture et le message attendu pour FORT. La définition du test est devenue plus cohérente. Les sources capturées ne certifient pas que le test a réussi, ni pour FORT, ni pour les trois autres relying parties.

Sources

  1. LACNIC Blog, « Open-Source Projects at LACNIC » : https://blog.lacnic.net/en/open-source-projects-lacnic/
  2. Commit Barry 994a598 : https://github.com/LACNIC/barry/commit/994a598321336baf1767f0fbfb460ed96c29fe4f
  3. Parseur et liaison du champ dans Barry : https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/field.c et https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/ext.c
  4. Scénario fonctionnel GeneralNames de Barry : https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/test/functional/tests/gnames.rd
  5. Commit correctif Rapport b1a59a : https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c
  6. Fixture et runner corrigés : https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd et https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  7. Helpers et README de Rapport : https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tools/checks.sh et https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/README.md
  8. RFC 6487 : https://www.rfc-editor.org/rfc/rfc6487.html
  9. RFC 5280 : https://www.rfc-editor.org/rfc/rfc5280.html
  10. Fixture et runner antérieurs à la correction, au commit 69da5fe : https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd et https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  11. Fichiers modifiés par le commit correctif b1a59a : https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/checks
  12. Historique du chemin de la fixture sur main : https://github.com/LACNIC/rapport/commits/main/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd
  13. Tags et releases de Rapport : https://github.com/LACNIC/rapport/tags et https://github.com/LACNIC/rapport/releases