4. Objets de Signature
- Objets de Signature
COSE prend en charge deux structures de signature différentes. COSE_Sign permet d'appliquer une ou plusieurs signatures au même contenu. COSE_Sign1 est limité à un seul signataire. Les structures ne peuvent pas être converties l'une en l'autre ; comme le calcul de la signature inclut un paramètre identifiant la structure utilisée, la structure convertie échouera à la validation de la signature.
4.1. Signature avec un ou plusieurs signataires
La structure COSE_Sign permet d'appliquer une ou plusieurs signatures à une charge utile de message. Les paramètres d'en-tête relatifs au contenu et les paramètres d'en-tête relatifs à la signature sont transportés avec la signature elle-même. Ces paramètres d'en-tête peuvent être authentifiés par la signature, ou simplement être présents. Un exemple de paramètre d'en-tête concernant le contenu est le paramètre d'en-tête de type de contenu. Un exemple de paramètre d'en-tête concernant la signature serait l'algorithme et la clé utilisés pour créer la signature.
La [RFC5652] indique que :
| Lorsque plusieurs signatures sont présentes, la validation réussie d'une signature associée à un signataire donné est généralement traitée comme une signature réussie par ce signataire. Cependant, il existe certains environnements d'application où d'autres règles sont nécessaires. Une application qui emploie une règle autre qu'une signature valide pour chaque signataire doit spécifier ces règles. De plus, lorsque la simple correspondance de l'identifiant du signataire n'est pas suffisante pour déterminer si les signatures ont été générées par le même signataire, la spécification de l'application doit décrire comment déterminer quelles signatures ont été générées par le même signataire. Le support de différentes communautés de destinataires est la raison principale pour laquelle les signataires choisissent d'inclure plus d'une signature.
Par exemple, la structure COSE_Sign peut inclure des signatures générées avec l'algorithme de signature numérique à courbe d'Edwards (EdDSA) [RFC8032] et l'algorithme de signature numérique à courbe elliptique (ECDSA) [DSS]. Cela permet aux destinataires de vérifier la signature associée à un algorithme ou à l'autre. Des informations plus détaillées sur les évaluations de signatures multiples peuvent être trouvées dans la [RFC5752].
La structure de signature peut être encodée comme marquée (tagged) ou non marquée (untagged), selon le contexte dans lequel elle sera utilisée. Une structure COSE_Sign marquée est identifiée par l'étiquette CBOR 98. Le fragment CDDL qui représente ceci est :
COSE_Sign_Tagged = #6.98(COSE_Sign)
Un message signé COSE est défini en deux parties. L'objet CBOR qui transporte le corps et les informations sur le message est appelé la structure COSE_Sign. L'objet CBOR qui transporte la signature et les informations sur la signature est appelé la structure COSE_Signature. Des exemples de messages signés COSE peuvent être trouvés dans l'annexe C.1.
La structure COSE_Sign est un tableau CBOR. Les champs du tableau, dans l'ordre, sont :
protected (protégé) : Ceci est tel que décrit dans la section 3.
unprotected (non protégé) : Ceci est tel que décrit dans la section 3.
payload (charge utile) : Ce champ contient le contenu sérialisé à signer. Si la charge utile n'est pas présente dans le message, l'application est tenue de fournir la charge utile séparément. La charge utile est enveloppée dans une bstr pour s'assurer qu'elle est transportée sans modifications. Si la charge utile est transportée séparément ("contenu détaché"), alors un objet CBOR nil est placé à cet endroit, et il est de la responsabilité de l'application de s'assurer qu'elle sera transportée sans modifications.
Note : Lorsqu'une signature avec un algorithme de récupération de message est utilisée (Section 8.1), le nombre maximum d'octets qui peuvent être récupérés est la longueur de la charge utile originale. La taille de la charge utile encodée est réduite du nombre d'octets qui seront récupérés. Si tous les octets de la charge utile originale sont consommés, alors la charge utile transmise est encodée comme une chaîne d'octets de longueur nulle plutôt que comme étant absente.
signatures (signatures) : Ce champ est un tableau de signatures. Chaque signature est représentée comme une structure COSE_Signature.
Le fragment CDDL qui représente le texte ci-dessus pour COSE_Sign suit.
COSE_Sign = [ Headers, payload : bstr / nil, signatures : [+ COSE_Signature] ]
La structure COSE_Signature est un tableau CBOR. Les champs du tableau, dans l'ordre, sont :
protected (protégé) : Ceci est tel que décrit dans la section 3.
unprotected (non protégé) : Ceci est tel que décrit dans la section 3.
signature (signature) : Ce champ contient la valeur de signature calculée. Le type du champ est une bstr. Les algorithmes DOIVENT spécifier un remplissage si la valeur de la signature n'est pas un multiple de 8 bits.
Le fragment CDDL qui représente le texte ci-dessus pour COSE_Signature suit.
COSE_Signature = [ Headers, signature : bstr ]
4.2. Signature avec un seul signataire
La structure de signature COSE_Sign1 est utilisée lorsqu'une seule signature va être placée sur un message. Les paramètres d'en-tête traitant du contenu et de la signature sont placés dans la même paire de seaux, plutôt que d'avoir la séparation de COSE_Sign.
La structure peut être encodée comme marquée ou non marquée selon le contexte dans lequel elle sera utilisée. Une structure COSE_Sign1 marquée est identifiée par l'étiquette CBOR 18. Le fragment CDDL qui représente ceci est :
COSE_Sign1_Tagged = #6.18(COSE_Sign1)
L'objet CBOR qui transporte le corps, la signature et les informations sur le corps et la signature est appelé la structure COSE_Sign1. Des exemples de messages COSE_Sign1 peuvent être trouvés dans l'annexe C.2.
La structure COSE_Sign1 est un tableau CBOR. Les champs du tableau, dans l'ordre, sont :
protected (protégé) : Ceci est tel que décrit dans la section 3.
unprotected (non protégé) : Ceci est tel que décrit dans la section 3.
payload (charge utile) : Ceci est tel que décrit dans la section 4.1.
signature (signature) : Ce champ contient la valeur de signature calculée. Le type du champ est une bstr.
Le fragment CDDL qui représente le texte ci-dessus pour COSE_Sign1 suit.
COSE_Sign1 = [ Headers, payload : bstr / nil, signature : bstr ]
4.3. Données fournies de manière externe
L'une des fonctionnalités offertes dans COSE est la capacité pour les applications de fournir des données supplémentaires qui doivent être authentifiées mais qui ne sont pas transportées dans le cadre de l'objet COSE. La raison principale de supporter cela peut être vue en regardant la structure du message CoAP [RFC7252], où la possibilité existe pour que des options soient transportées avant la charge utile. Des exemples de données qui peuvent être placées à cet endroit seraient le code CoAP ou les options CoAP. Si les données sont dans les en-têtes du message CoAP, alors elles sont disponibles pour les proxys pour aider à effectuer des opérations de proxy. Par exemple, l'option Accept peut être utilisée par un proxy pour déterminer si une valeur appropriée est dans le cache du proxy. L'expéditeur peut utiliser la fonctionnalité de données supplémentaires pour permettre la détection de tout changement à l'ensemble des valeurs Accept effectué par un proxy ou un attaquant. En incluant le champ dans les données fournies de manière externe, toute modification ultérieure entraînera l'échec du traitement du message par le serveur.
Ce document décrit le processus d'utilisation d'un tableau d'octets de données authentifiées fournies de manière externe ; la méthode de construction du tableau d'octets est une fonction de l'application. Les applications qui utilisent cette fonctionnalité doivent définir comment les données authentifiées fournies de manière externe doivent être construites. Une telle construction doit prendre en compte les problèmes suivants :
-
Si plusieurs éléments sont inclus, les applications doivent s'assurer que la même chaîne d'octets ne peut pas être produite s'il y a des entrées différentes. Un exemple de la façon dont le scénario problématique pourrait survenir serait en concaténant les chaînes de texte "AB" et "CDE" ou en concaténant les chaînes de texte "ABC" et "DE". Cela est généralement résolu en rendant les champs d'une largeur fixe et/ou en encodant la longueur du champ dans le cadre de la sortie. En utilisant les options de CoAP [RFC7252] comme exemple, ces champs utilisent une structure TLV afin qu'ils puissent être concaténés sans aucun problème.
-
Si plusieurs éléments sont inclus, un ordre pour les éléments doit être défini. En utilisant les options de CoAP comme exemple, une application pourrait stipuler que les champs doivent être ordonnés par le numéro d'option.
-
Les applications doivent s'assurer que la chaîne d'octets va être la même des deux côtés. L'utilisation d'options de CoAP pourrait poser un problème si la même numérotation relative est conservée. Un nœud intermédiaire pourrait insérer ou supprimer une option, changeant la façon dont la numérotation relative est effectuée. Une application devrait spécifier que le numéro relatif doit être ré-encodé pour être relatif uniquement aux options qui sont dans les données externes.
4.4. Processus de signature et de vérification
Afin de créer une signature, une chaîne d'octets bien définie est nécessaire. La Sig_structure est utilisée pour créer la forme canonique. Ce processus de signature et de vérification prend en entrée les informations du corps (COSE_Sign ou COSE_Sign1), les informations du signataire (COSE_Signature) et les données de l'application (source externe). Une Sig_structure est un tableau CBOR. Les champs de la Sig_structure, dans l'ordre, sont :
-
Une chaîne de texte de contexte identifiant le contexte de la signature. La chaîne de texte de contexte est :
"Signature" pour les signatures utilisant la structure COSE_Signature.
"Signature1" pour les signatures utilisant la structure COSE_Sign1.
-
Les attributs protégés de la structure du corps, encodés dans un type bstr. S'il n'y a pas d'attributs protégés, une chaîne d'octets de longueur nulle est utilisée.
-
Les attributs protégés de la structure du signataire, encodés dans un type bstr. S'il n'y a pas d'attributs protégés, une chaîne d'octets de longueur nulle est utilisée. Ce champ est omis pour la structure de signature COSE_Sign1.
-
Les données fournies de manière externe par l'application, encodées dans un type bstr. Si ce champ n'est pas fourni, il prend par défaut une chaîne d'octets de longueur nulle. (Voir la section 4.3 pour les conseils d'application sur la construction de ce champ.)
-
La charge utile à signer, encodée dans un type bstr. La charge utile complète est utilisée ici, indépendamment de la manière dont elle est transportée.
Le fragment CDDL qui décrit le texte ci-dessus est :
Sig_structure = [ context : "Signature" / "Signature1", body_protected : empty_or_serialized_map, ? sign_protected : empty_or_serialized_map, external_aad : bstr, payload : bstr ]
Comment calculer une signature :
-
Créer une Sig_structure et la remplir avec les champs appropriés.
-
Créer la valeur ToBeSigned en encodant la Sig_structure en une chaîne d'octets, en utilisant l'encodage décrit dans la section 9.
-
Appeler l'algorithme de création de signature, en passant K (la clé avec laquelle signer), alg (l'algorithme avec lequel signer) et ToBeSigned (la valeur à signer).
-
Placer la valeur de signature résultante à l'endroit correct. C'est le champ "signature" de la structure COSE_Signature ou COSE_Sign1.
Les étapes pour vérifier une signature sont :
-
Créer une Sig_structure et la remplir avec les champs appropriés.
-
Créer la valeur ToBeSigned en encodant la Sig_structure en une chaîne d'octets, en utilisant l'encodage décrit dans la section 9.
-
Appeler l'algorithme de vérification de signature, en passant K (la clé avec laquelle vérifier), alg (l'algorithme utilisé pour signer), ToBeSigned (la valeur à signer) et sig (la signature à vérifier).
En plus d'effectuer la vérification de la signature, l'application effectue les vérifications appropriées pour s'assurer que la clé est correctement appariée avec l'identité de signature et que l'identité de signature est autorisée avant d'effectuer des actions.