2.5. Création de la base de signature (Creating the Signature Base)
2.5. Création de la base de signature
La base de signature est une chaîne ASCII [ASCII] contenant les composants de message HTTP canonisés couverts par la signature. L'entrée de l'algorithme de création de la base de signature est l'ensemble ordonné des identifiants de composants couverts et leurs valeurs associées, ainsi que les paramètres de signature supplémentaires de la Section 2.3.
Les identifiants de composants sont sérialisés selon les règles de sérialisation stricte définies par [STRUCTURED-FIELDS], Section 4. L'identifiant de composant a un nom de composant, qui est une valeur String Item sérialisée selon la règle ABNF sf-string. L'identifiant de composant PEUT aussi inclure des paramètres définis sérialisés selon la règle ABNF parameters. La ligne des paramètres de signature définie à la Section 2.3 suit le même schéma, mais l'identifiant de composant est un String Item à valeur fixe sans paramètres, et la valeur de composant est toujours une Inner List avec paramètres facultatifs.
Cela signifie que la sérialisation du nom de composant lui-même est entourée de guillemets doubles, les paramètres suivant comme liste séparée par des points-virgules, par ex. "cache-control", "@authority", "@signature-params", ou "example-dictionary";key="foo".
La sortie est l'ensemble ordonné d'octets formant la base de signature, qui satisfait l'ABNF suivante:
signature-base = *( signature-base-line LF ) signature-params-line signature-base-line = component-identifier ":" SP ( derived-component-value / *field-content ) ; no obs-fold nor obs-text component-identifier = component-name parameters component-name = sf-string derived-component-value = *( VCHAR / SP ) signature-params-line = DQUOTE "@signature-params" DQUOTE ":" SP inner-list
Pour créer la base de signature, le signataire ou le vérificateur concatène les entrées pour chaque identifiant de composant dans les composants couverts de la signature (y compris leurs paramètres) selon l'algorithme suivant. Toute erreur décrite ci-dessous DOIT faire échouer l'algorithme immédiatement, sans produire de base de signature.
-
Soit la sortie une chaîne vide.
-
Pour chaque élément de composant de message dans l'ensemble des composants couverts (dans l'ordre):
2.1. Si l'identifiant de composant (y compris ses paramètres) a déjà été ajouté à la base de signature, produire une erreur.
2.2. Ajouter l'identifiant de composant pour le composant couvert sérialisé selon la règle ABNF component-identifier. Cette sérialisation place le nom de composant entre guillemets doubles et ajoute les paramètres éventuels hors des guillemets.
2.3. Ajouter un seul deux-points (:).
2.4. Ajouter un seul espace (" ").
2.5. Déterminer la valeur de composant pour l'identifiant de composant.
* Si l'identifiant de composant a un paramètre non compris, produire une erreur.
* Si l'identifiant de composant a des paramètres mutuellement incompatibles, tels que bs et sf, produire une erreur.
* Si l'identifiant de composant contient le paramètre `req` et que le message cible est une requête, produire une erreur.
* Si l'identifiant de composant contient le paramètre `req` et que le message cible est une réponse, le contexte pour la valeur de composant est le message de requête associé au message de réponse cible. Sinon, le contexte pour la valeur de composant est le message cible.
* Si le nom de composant commence par le caractère arobase (@), dériver la valeur du composant du message selon les règles spécifiques définies pour le composant dérivé, comme à la Section 2.2, y compris le traitement de tout paramètre valide connu. Si le nom de composant dérivé est inconnu ou si la valeur ne peut être dérivée, produire une erreur.
* Si le nom de composant ne commence pas par un arobase (@), canoniser la valeur du champ HTTP comme à la Section 2.1, y compris le traitement de tout paramètre valide connu. Si le champ est introuvable dans le message ou si la valeur ne peut être obtenue dans le contexte, produire une erreur.2.6. Ajouter la valeur de composant canonisée du composant couvert.
2.7. Ajouter un seul saut de ligne (\n).
-
Ajouter le composant des paramètres de signature (Section 2.3) selon la règle signature-params-line comme suit:
3.1. Ajouter l'identifiant de composant pour les paramètres de signature sérialisé selon la règle component-identifier, c'est-à-dire la valeur exacte
"@signature-params"(guillemets doubles inclus).3.2. Ajouter un seul deux-points (:).
3.3. Ajouter un seul espace (" ").
3.4. Ajouter les valeurs de composant canonisées des paramètres de signature telles que définies à la Section 2.3, c'est-à-dire des valeurs Structured Field de type Inner List avec paramètres.
-
Produire une erreur si la chaîne de sortie contient des caractères non ASCII [ASCII].
-
Renvoyer la chaîne de sortie.
Si des composants couverts référencent un identifiant de composant qui ne peut être résolu en valeur de composant dans le message, l'implémentation DOIT produire une erreur et ne pas créer de base de signature. De telles situations incluent, sans s'y limiter:
-
Le signataire ou le vérificateur ne comprend pas le nom de composant dérivé.
-
Le nom de composant désigne un champ absent du message ou dont la valeur est mal formée.
-
L'identifiant de composant inclut un paramètre inconnu ou inapplicable à l'identifiant de composant auquel il est rattaché.
-
L'identifiant de composant indique qu'une sérialisation Structured Field est utilisée (via le paramètre
sf), mais le champ concerné n'est pas un Structured Field connu ou le type de Structured Field n'est pas connu de l'implémentation. -
L'identifiant de composant est un identifiant de membre Dictionary qui référence un champ absent du message, qui n'est pas un Dictionary Structured Field, ou dont la valeur est mal formée.
-
L'identifiant de composant est un identifiant de membre Dictionary ou un identifiant de paramètre de requête nommé qui référence un membre absent de la valeur de composant ou dont la valeur est mal formée. Par exemple, l'identifiant est
"example-dict";key="c", et la valeur du champ d'en-tête Example-Dict est a=1, b=2, sans valeur c.
Dans l'exemple non normatif suivant, le message HTTP signé est la requête suivante:
NOTE: retour à la ligne '' selon la RFC 8792
POST /foo?param=Value&Pet=dog HTTP/1.1
Host: example.com
Date: Tue, 20 Apr 2021 02:07:55 GMT
Content-Type: application/json
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
Content-Length: 18
{"hello": "world"}
Les composants couverts sont les composants dérivés @method, @authority et @path, suivis des champs d'en-tête HTTP Content-Digest, Content-Length et Content-Type, dans cet ordre. Les paramètres de signature comprennent un horodatage de création 1618884473 et un identifiant de clé test-key-rsa-pss. Aucun paramètre alg explicite n'est donné ici, car l'application sait que le vérificateur emploie l'algorithme RSA-PSS d'après la clé identifiée. La base de signature pour ce message avec ces paramètres est:
NOTE: retour à la ligne '' selon la RFC 8792
"@method": POST
"@authority": example.com
"@path": /foo
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
"content-length": 18
"content-type": application/json
"@signature-params": ("@method" "@authority" "@path"
"content-digest" "content-length" "content-type")
;created=1618884473;keyid="test-key-rsa-pss"
Figure 1: Exemple non normatif de base de signature
Notez que l'exemple de base de signature ci-dessus n'inclut pas le saut de ligne final qui termine l'exemple affiché, pas plus que d'autres exemples de bases de signature ailleurs dans cette spécification.