Résumé

  • Dans l’échange ordinaire défini par la RFC 9811, un 200 OK confirme la réussite de la requête HTTP et transporte une réponse CMP ; il ne dit pas si l’opération PKI a été acceptée, modifiée, rejetée ou mise en attente.
  • Une preuve exploitable doit relier, sans les confondre, l’autorité visée, la session HTTP, le message CMP protégé, le transactionID, l’éventuel scrutin d’approbation, la confirmation du certificat, son installation et l’acceptation par les systèmes utilisateurs.

Le piège n’est pas un code rouge. C’est un 200 OK auquel on demande de parler au nom d’un protocole qu’il ne fait que transporter.

La RFC 9811, publiée en juillet 2025 dans la voie des normes de l’IETF, organise le transport HTTP du Certificate Management Protocol. Elle impose une forme étroite : le client place un PKIMessage encodé en DER dans le corps d’une requête POST, avec le type application/pkixcmp. Lorsque cette requête HTTP réussit dans le dialogue ordinaire, le serveur renvoie la réponse CMP dans le corps d’une réponse 200. Aucun autre code 2xx ne doit jouer ce rôle.

Cette exactitude n’élargit pas l’autorité de HTTP. Elle la borne. Le code extérieur atteste que l’échange HTTP a abouti selon le contrat. Le message intérieur conserve la décision de gestion du certificat.

Deux vocabulaires de résultat

La RFC 9810 définit les états CMP. Une réponse peut être accepted, grantedWithMods, rejection ou waiting. Elle peut aussi porter des avertissements concernant la révocation ou la mise à jour d’une clé. Une même ligne HTTP 200 peut donc recouvrir quatre conduites différentes : continuer avec le résultat demandé, examiner des modifications, arrêter l’opération refusée, ou attendre et interroger de nouveau.

Le tableau de bord qui réduit tout cela à « succès HTTP » a perdu l’information qui détermine l’action suivante. L’erreur symétrique consiste à abandonner le corps dès que le statut HTTP vaut 4xx ou 5xx. La RFC 9811 exige qu’un client sache traiter un PKIMessage de réponse présent dans le corps d’une réponse 2xx, 4xx ou 5xx. Un échec au niveau HTTP peut donc arriver avec une explication CMP authentifiable et corrélable.

La chaîne de traitement doit rester visible. On reçoit l’enveloppe. On contrôle son type et sa taille. On décode le DER. On vérifie la protection CMP et l’identité pertinente. On rattache le message à la transaction. Ensuite seulement, on interprète le corps, le statut et les informations d’échec. Chaque contrôle a sa propre vérité ; aucun ne doit falsifier la preuve du précédent.

L’absence de réponse crée une dette d’incertitude

La RFC 9811 impose une règle conservatrice : si aucune réponse HTTP ne confirme la réception, le message CMP doit être considéré comme n’ayant pas été remis avec succès. C’est une discipline de transport, pas une caméra placée dans le serveur.

Une connexion peut se rompre après la lecture ou même après le traitement de la demande. Du côté du client, la remise n’est pas confirmée ; du côté de l’autorité, un état peut déjà exister. Rejouer immédiatement la requête sous une nouvelle identité transforme alors l’incertitude en risque de duplication. Ne jamais rejouer peut laisser expirer un certificat qui devait être renouvelé.

Le remède n’est pas une règle universelle de nouvelle tentative. Il faut conserver le corps exact et son empreinte, l’autorité ciblée, le type d’opération, l’heure limite et surtout le transactionID. La reprise doit suivre l’automate CMP de l’opération, ou déclencher une réconciliation explicite si l’implémentation ne permet pas de déterminer l’état. Une métrique ne doit pas fabriquer une deuxième transaction pour effacer une première ligne ambiguë.

Une transaction avec plusieurs trajets HTTP

HTTP peut être sans état sans que l’opération PKI le soit. Certaines opérations CMP exigent plusieurs couples requête-réponse. Le transactionID relie ces messages. Une fois sa valeur établie, la RFC 9810 demande qu’elle soit conservée dans les échanges suivants. Un client ne doit pas mener simultanément, vers le même serveur, deux transactions avec le même identifiant.

La recommandation de 128 bits pseudo-aléatoires réduit le risque de collision. Selon sa capacité à distinguer les clients, le serveur peut exiger l’unicité du couple {client, transactionID} ou celle de l’identifiant seul. Une valeur déjà utilisée et incompatible avec une association correcte doit conduire à transactionIdInUse.

Cette puissance de corrélation ne doit pas devenir une identité imaginaire. Le champ ne prouve ni qui est le client, ni son autorisation, ni l’intégrité du message. Il ne garantit pas non plus l’idempotence métier d’une application qui englobe le client CMP. La protection du message, les nonces, les identifiants de demande et la politique locale portent d’autres responsabilités.

La question du transactionID est : « à quel dialogue ce message appartient-il ? » La question de l’autorisation est : « cet acteur peut-il demander ce profil à cette autorité ? » La question de l’exploitation est : « quel certificat et quelle clé sont réellement chargés ? » Les réunir dans un dossier est utile ; les remplacer par un champ unique est dangereux.

waiting : l’HTTP est terminé, la décision ne l’est pas

L’état waiting rend la séparation concrète. Il signifie que le corps de la demande n’a pas encore été traité et qu’une suite est attendue. Le client envoie pollReq. L’autorité renvoie la réponse finale si elle est prête, sinon un pollRep avec checkAfter. Le client doit attendre au moins la durée indiquée.

La cause de l’attente peut se trouver bien après HTTP : charge du service interne, transfert hors ligne entre entités PKI, ou validation humaine par une autorité d’enregistrement. Une requête réseau terminée peut précéder une décision institutionnelle encore ouverte.

Une automatisation sérieuse donne donc à l’attente un propriétaire, une prochaine heure autorisée, une échéance, un seuil d’escalade et le contexte original. Interroger plus vite que checkAfter gaspille la capacité du serveur et nie l’état déclaré. Considérer l’attente comme un refus peut lancer une deuxième inscription. La prendre pour une acceptation clôt artificiellement un contrôle sans certificat.

L’émission n’est pas toujours la clôture

Quand une autorité renvoie un certificat, le protocole peut encore attendre la décision du demandeur. La RFC 9810 définit certConf, qui permet au client d’accepter ou de rejeter les certificats reçus, puis pkiconf pour la confirmation finale. Cette étape est essentielle lorsque l’autorité a modifié des champs demandés : grantedWithMods n’est pas l’autorisation d’installer sans examen.

Il faut alors suivre une série d’objets distincts : la réponse protégée, son statut, le certificat et son empreinte, la comparaison avec la demande, la confirmation du client, la clôture du protocole, l’écriture dans le magasin de clés, le chargement par le service et la validation par les parties qui s’y fient. Une même empreinte peut relier ces preuves. Elle ne démontre pas que toutes existent.

Un registre d’émission ne voit pas nécessairement le certificat encore servi par un répartiteur. Un outil de déploiement ne sait pas forcément si les clients acceptent la chaîne, le nom ou l’usage de clé. Un service qui fonctionne peut masquer une transaction que l’autorité considère toujours inachevée. La réalité d’exécution et la clôture protocolaire sont complémentaires.

Les annonces ont leur propre contrat

La RFC 9811 distingue les annonces poussées par une autorité : mise à jour de clé de CA, certificat, révocation ou liste de révocation. Ici, le serveur CMP devient client HTTP et le destinataire ne renvoie pas de réponse CMP. Il répond avec un corps vide.

201 Created atteste que l’information a été stockée ou était déjà présente. 202 Accepted signifie seulement qu’elle a été admise pour un traitement ultérieur. Après 202, l’émetteur peut attendre puis réessayer jusqu’à obtenir la confirmation du traitement. Ces codes ne doivent pas être importés dans le dialogue ordinaire où 200 transporte un verdict CMP. Les deux flux utilisent HTTP, mais ne délèguent pas la même signification à son statut.

Sans protection et authentification adéquates, même l’accusé de traitement d’une annonce ne peut être tenu pour fiable. La RFC avertit que l’architecture PKI ne doit alors pas dépendre de sa réception garantie. Un nombre n’est une preuve que si l’on sait qui l’a envoyé, pour quel message et sous quelle protection.

Le chemin connu ne choisit pas l’autorité

La convention /.well-known/cmp facilite l’interopérabilité. Des segments supplémentaires peuvent distinguer une opération, une CA ou un profil de certificat. Le registre IANA des URI bien connues inscrit cmp comme suffixe permanent contrôlé par l’IETF.

Cette adresse relative dit où interroger une origine ; elle ne découvre pas le nom d’hôte légitime. La RFC 8615 l’énonce et rappelle qu’un emplacement « well-known » représente un pouvoir à l’échelle de l’origine. Il faut donc conserver l’origine de la configuration, les résolutions, les redirections, l’identité TLS, l’expéditeur du message CMP protégé et la règle locale qui relie ces éléments.

Les redirections méritent leur propre journal. La RFC 9811 autorise leur prise en charge mais déconseille un suivi automatique sans examen de sécurité. Une destination 301 conservée de façon malveillante peut couper durablement le client de la bonne autorité. La commodité de HTTP ne doit pas réécrire silencieusement le point de confiance.

Un dossier de preuve au lieu d’un booléen

Le dossier minimal enregistre l’autorité prévue, l’URI et ses redirections ; le pair TLS ; la méthode, le statut, le type de média et les empreintes des corps HTTP ; les identités CMP, le type de message et le verdict de protection ; le transactionID, les nonces et l’identifiant de demande ; le statut PKI, l’échec éventuel et checkAfter ; l’empreinte du certificat, les différences de profil et la confirmation ; enfin le magasin, le service chargé et les validations indépendantes.

Il doit aussi savoir écrire « inconnu ». Pas de réponse HTTP signifie remise non confirmée, non absence certaine d’effet. 200 signifie réponse reçue, non certificat accepté. Émis ne signifie pas installé. Installé ne signifie pas accepté par toutes les parties utilisatrices.

Running-Code Primacy fournit le test final : une norme définit l’enveloppe interopérable, mais seuls le client en exécution, l’état de la CA ou de la RA, le magasin de clés et les transactions réelles prouvent le comportement. Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption justifie une couche commune stricte mais étroite, qui n’absorbe ni la politique de certificat ni la décision de déploiement. Reality Layers interdit enfin de transformer ces vérités superposées en un seul symbole de réussite.

La RFC 9811 ne diminue pas la valeur de 200 OK. Elle lui rend sa crédibilité : la requête HTTP a réussi et la réponse est arrivée. La décision sur le certificat reste à lire.

Sources