Résumé

  • Le même objet CMS peut nommer son condensat dans SignedData, dans SignerInfo et dans un attribut signé. Le condensat du signataire doit correspondre au préhachage fixé par l’OID composite, tandis que les paramètres de l’algorithme de signature doivent être absents.
  • La réussite des deux composants ne suffit pas : le destinataire doit reconstruire les octets DER exacts, recalculer le condensat du contenu, comparer les identifiants et appliquer séparément la politique de certificat, de statut et d’autorisation.

Le moteur cryptographique avait rendu deux succès. ML-DSA était valide. La composante classique l’était aussi. Pourtant, l’enveloppe CMS déclarait un condensat différent de celui que l’algorithme composite imposait.

Le problème n’était plus de casser une signature, mais de savoir quelle déclaration contradictoire le logiciel avait effectivement utilisée.

La révision 05 de Composite Module-Lattice-Based Digital Signature Algorithm (ML-DSA) for use in Cryptographic Message Syntax (CMS) encadre précisément ce choix. C’est un Internet-Draft actif du groupe LAMPS, dans le flux IETF, destiné au statut Proposed Standard. La révision est datée du 22 mai 2026 et expire le 23 novembre. Datatracker a enregistré un changement de processus le 1er octobre et place désormais le texte dans la file du RFC Editor, en attente d’un second éditeur. Il ne s’agit pas encore d’un RFC, ni d’une preuve de support logiciel, d’émission de certificat, d’activation ou de migration réussie.

Le document accompagne la spécification de la primitive Composite ML-DSA. Celle-ci combine ML-DSA avec RSA, ECDSA, Ed25519 ou Ed448 et ne valide l’ensemble que si toutes les signatures composantes réussissent. Le profil CMS détermine les octets et les déclarations externes soumis à cette primitive.

L’OID unique ne supprime pas les autres champs

La révision reproduit 18 OID composites. Le même AlgorithmIdentifier désigne la clé publique et l’algorithme de signature ; son champ de paramètres doit être absent. Cette interface unique évite à chaque application d’inventer son propre conteneur à deux signatures.

CMS conserve néanmoins plusieurs surfaces de décision. SignedData.digestAlgorithms contient un ensemble de condensats. Chaque SignerInfo porte digestAlgorithm et signatureAlgorithm. Les attributs signés peuvent contenir CMSAlgorithmProtection. Le certificat déclare encore l’algorithme de clé.

Un appel cryptographique ne peut pas arbitrer silencieusement un désaccord entre ces champs. Le reçu doit donc garder l’OID composite, l’algorithme de clé du certificat, les identifiants du signataire, la présence des paramètres, les valeurs protégées et le résultat de chaque composante. Le raccourci « signature PQ valide » efface la décision d’interprétation.

Le nom composite fixe le préhachage CMS

Dans ce profil, Composite ML-DSA ne fonctionne qu’en mode préhaché. Chaque nom d’algorithme fixe SHA-256, SHA-512 ou SHAKE256 pour la couche CMS. SignerInfo.digestAlgorithm doit être exactement ce condensat.

Les paramètres de SHA-256 et SHA-512 sont absents. Ceux de SHAKE256 le sont aussi, avec une sortie de 64 octets. Une composante ECDSA peut employer un autre condensat en interne ; cette opération interne ne modifie pas le préhachage externe. Les journaux doivent donc nommer la couche pour ne pas confondre différence légitime et incohérence dangereuse.

L’ensemble SignedData.digestAlgorithms devrait inclure le condensat correspondant afin qu’un vérificateur en un passage puisse préparer son calcul. Une omission peut l’empêcher de réussir. Mais cet ensemble reste un indice de traitement au niveau du conteneur ; il ne remplace pas l’obligation d’égalité dans le SignerInfo concerné.

Les attributs changent les octets signés

Sans attributs signés, la signature couvre la valeur de l’OCTET STRING eContent, sans ses octets de tag et de longueur. Avec des attributs, elle couvre l’encodage DER complet de SignedAttrs, tag et longueur compris. L’entrée utilise un tag EXPLICIT SET OF, non le tag IMPLICIT [0] visible dans le message final.

Les attributs comprennent au minimum content-type et message-digest. Le destinataire doit recalculer le condensat du contenu et le comparer. Une primitive composite exécutée sur une reconstruction différente, ou sur des attributs dont le digest n’a pas été contrôlé, ne constitue pas une validation CMS complète.

Le système de preuve doit conserver le hash de l’objet brut, celui du contenu, celui du DER exact des attributs, le message-digest reçu et recalculé, ainsi que la plage d’octets passée à la primitive. Une vue ASN.1 normalisée ne remplace pas la capture originale.

La primitive possède une chaîne de contexte, mais le profil CMS la fixe à la chaîne vide. Une application ne peut donc pas attribuer ici la séparation de domaines à un contexte non vide. Elle doit la démontrer par le type de contenu, les attributs signés, la politique de certificat ou une règle d’application vérifiée.

Signer aussi le récit algorithmique

RFC 6211 définit CMSAlgorithmProtection, qui place le condensat et l’algorithme de signature ou de MAC parmi les attributs signés. RFC 8933 renforce les règles de cohérence. La révision 05 recommande cet attribut contre les substitutions d’algorithmes.

Une déclaration externe non signée peut être modifiée sans changer l’entrée cryptographique. Une fois l’algorithme placé dans SignedAttrs, la déclaration du signataire appartient aux octets protégés. Le vérificateur peut la comparer au SignerInfo, à l’OID composite et à la clé au lieu de choisir le premier champ compris par sa bibliothèque.

La présence de l’attribut n’est pas un laissez-passer. Sa forme, son emplacement, ses OID, ses paramètres et sa cohérence doivent être contrôlés. Comme le texte emploie SHOULD, l’absence doit devenir une coordonnée de politique visible, non être absorbée par un succès générique.

Le registre et le texte peuvent avancer à des rythmes différents

Le draft demande un identifiant de module ASN.1 dans le registre SMI Security for S/MIME. Le texte figé de la révision 05 contient encore un emplacement à remplacer. La capture du registre public IANA du 2 octobre montre déjà la valeur décimale 88 pour id-mod-composite-mldsa-cms-2026, avec une référence au draft.

Ces états ne s’annulent pas. Le registre publie une allocation, la source conserve une marque éditoriale, le document est dans la file RFC Editor et aucun numéro RFC n’est encore publié. L’allocation est une preuve de registre à cet instant ; elle n’est ni un RFC ni un reçu de déploiement.

Deux composantes valides ne donnent pas le pouvoir d’agir

La primitive exige la réussite de toutes les composantes et interdit de réutiliser leurs clés dans d’autres contextes. Elle répond ainsi à une question cryptographique importante.

Elle ne valide pas automatiquement la chaîne de certificats, la fraîcheur du statut, le key usage, l’autorité du signataire, le sens du document, sa destination ou l’effet qui suit. Un objet d’approbation correctement signé ne prouve pas que l’action approuvée a été réalisée.

Il faut donc séparer les reçus : parse et encodage ; accord des algorithmes ; condensat du contenu ; deux verdicts composantes ; chemin et statut du certificat ; identité et autorisation ; décision applicative ; livraison ; conservation ; résultat externe.