rfc9421.original | rfc9421.txt | |||
---|---|---|---|---|
HTTP A. Backman, Ed. | Internet Engineering Task Force (IETF) A. Backman, Ed. | |||
Internet-Draft Amazon | Request for Comments: 9421 Amazon | |||
Intended status: Standards Track J. Richer, Ed. | Category: Standards Track J. Richer, Ed. | |||
Expires: 28 January 2024 Bespoke Engineering | ISSN: 2070-1721 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
27 July 2023 | February 2024 | |||
HTTP Message Signatures | HTTP Message Signatures | |||
draft-ietf-httpbis-message-signatures-19 | ||||
Abstract | Abstract | |||
This document describes a mechanism for creating, encoding, and | This document describes a mechanism for creating, encoding, and | |||
verifying digital signatures or message authentication codes over | verifying digital signatures or message authentication codes over | |||
components of an HTTP message. This mechanism supports use cases | components of an HTTP message. This mechanism supports use cases | |||
where the full HTTP message may not be known to the signer, and where | where the full HTTP message may not be known to the signer and where | |||
the message may be transformed (e.g., by intermediaries) before | the message may be transformed (e.g., by intermediaries) before | |||
reaching the verifier. This document also describes a means for | reaching the verifier. This document also describes a means for | |||
requesting that a signature be applied to a subsequent HTTP message | requesting that a signature be applied to a subsequent HTTP message | |||
in an ongoing HTTP exchange. | in an ongoing HTTP exchange. | |||
About This Document | ||||
This note is to be removed before publishing as an RFC. | ||||
Status information for this document may be found at | ||||
https://datatracker.ietf.org/doc/draft-ietf-httpbis-message- | ||||
signatures/. | ||||
Discussion of this document takes place on the HTTP Working Group | ||||
mailing list (mailto:ietf-http-wg@w3.org), which is archived at | ||||
https://lists.w3.org/Archives/Public/ietf-http-wg/. Working Group | ||||
information can be found at https://httpwg.org/. | ||||
Source for this draft and an issue tracker can be found at | ||||
https://github.com/httpwg/http-extensions/labels/signatures. | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This is an Internet Standards Track document. | |||
provisions of BCP 78 and BCP 79. | ||||
Internet-Drafts are working documents of the Internet Engineering | ||||
Task Force (IETF). Note that other groups may also distribute | ||||
working documents as Internet-Drafts. The list of current Internet- | ||||
Drafts is at https://datatracker.ietf.org/drafts/current/. | ||||
Internet-Drafts are draft documents valid for a maximum of six months | This document is a product of the Internet Engineering Task Force | |||
and may be updated, replaced, or obsoleted by other documents at any | (IETF). It represents the consensus of the IETF community. It has | |||
time. It is inappropriate to use Internet-Drafts as reference | received public review and has been approved for publication by the | |||
material or to cite them other than as "work in progress." | Internet Engineering Steering Group (IESG). Further information on | |||
Internet Standards is available in Section 2 of RFC 7841. | ||||
This Internet-Draft will expire on 28 January 2024. | Information about the current status of this document, any errata, | |||
and how to provide feedback on it may be obtained at | ||||
https://www.rfc-editor.org/info/rfc9421. | ||||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2023 IETF Trust and the persons identified as the | Copyright (c) 2024 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents | |||
license-info) in effect on the date of publication of this document. | (https://trustee.ietf.org/license-info) in effect on the date of | |||
Please review these documents carefully, as they describe your rights | publication of this document. Please review these documents | |||
and restrictions with respect to this document. Code Components | carefully, as they describe your rights and restrictions with respect | |||
extracted from this document must include Revised BSD License text as | to this document. Code Components extracted from this document must | |||
described in Section 4.e of the Trust Legal Provisions and are | include Revised BSD License text as described in Section 4.e of the | |||
provided without warranty as described in the Revised BSD License. | Trust Legal Provisions and are provided without warranty as described | |||
in the Revised BSD License. | ||||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 | 1. Introduction | |||
1.1. Conventions and Terminology . . . . . . . . . . . . . . . 7 | 1.1. Conventions and Terminology | |||
1.2. Requirements . . . . . . . . . . . . . . . . . . . . . . 9 | 1.2. Requirements | |||
1.3. HTTP Message Transformations . . . . . . . . . . . . . . 10 | 1.3. HTTP Message Transformations | |||
1.4. Application of HTTP Message Signatures . . . . . . . . . 11 | 1.4. Application of HTTP Message Signatures | |||
2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 13 | 2. HTTP Message Components | |||
2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 15 | 2.1. HTTP Fields | |||
2.1.1. Strict Serialization of HTTP Structured Fields . . . 18 | 2.1.1. Strict Serialization of HTTP Structured Fields | |||
2.1.2. Dictionary Structured Field Members . . . . . . . . . 19 | 2.1.2. Dictionary Structured Field Members | |||
2.1.3. Binary-wrapped HTTP Fields . . . . . . . . . . . . . 20 | 2.1.3. Binary-Wrapped HTTP Fields | |||
2.1.4. Trailer Fields . . . . . . . . . . . . . . . . . . . 21 | 2.1.4. Trailer Fields | |||
2.2. Derived Components . . . . . . . . . . . . . . . . . . . 22 | 2.2. Derived Components | |||
2.2.1. Method . . . . . . . . . . . . . . . . . . . . . . . 24 | 2.2.1. Method | |||
2.2.2. Target URI . . . . . . . . . . . . . . . . . . . . . 24 | 2.2.2. Target URI | |||
2.2.3. Authority . . . . . . . . . . . . . . . . . . . . . . 25 | 2.2.3. Authority | |||
2.2.4. Scheme . . . . . . . . . . . . . . . . . . . . . . . 25 | 2.2.4. Scheme | |||
2.2.5. Request Target . . . . . . . . . . . . . . . . . . . 26 | 2.2.5. Request Target | |||
2.2.6. Path . . . . . . . . . . . . . . . . . . . . . . . . 27 | 2.2.6. Path | |||
2.2.7. Query . . . . . . . . . . . . . . . . . . . . . . . . 28 | 2.2.7. Query | |||
2.2.8. Query Parameters . . . . . . . . . . . . . . . . . . 29 | 2.2.8. Query Parameters | |||
2.2.9. Status Code . . . . . . . . . . . . . . . . . . . . . 31 | 2.2.9. Status Code | |||
2.3. Signature Parameters . . . . . . . . . . . . . . . . . . 31 | 2.3. Signature Parameters | |||
2.4. Signing Request Components in a Response Message . . . . 33 | 2.4. Signing Request Components in a Response Message | |||
2.5. Creating the Signature Base . . . . . . . . . . . . . . . 38 | 2.5. Creating the Signature Base | |||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 42 | 3. HTTP Message Signatures | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 42 | 3.1. Creating a Signature | |||
3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 44 | 3.2. Verifying a Signature | |||
3.2.1. Enforcing Application Requirements . . . . . . . . . 47 | 3.2.1. Enforcing Application Requirements | |||
3.3. Signature Algorithms . . . . . . . . . . . . . . . . . . 48 | 3.3. Signature Algorithms | |||
3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 49 | 3.3.1. RSASSA-PSS Using SHA-512 | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 50 | 3.3.2. RSASSA-PKCS1-v1_5 Using SHA-256 | |||
3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 50 | 3.3.3. HMAC Using SHA-256 | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 51 | 3.3.4. ECDSA Using Curve P-256 DSS and SHA-256 | |||
3.3.5. ECDSA using curve P-384 DSS and SHA-384 . . . . . . . 51 | 3.3.5. ECDSA Using Curve P-384 DSS and SHA-384 | |||
3.3.6. EdDSA using curve edwards25519 . . . . . . . . . . . 52 | 3.3.6. EdDSA Using Curve edwards25519 | |||
3.3.7. JSON Web Signature (JWS) algorithms . . . . . . . . . 53 | 3.3.7. JSON Web Signature (JWS) Algorithms | |||
4. Including a Message Signature in a Message . . . . . . . . . 53 | 4. Including a Message Signature in a Message | |||
4.1. The Signature-Input HTTP Field . . . . . . . . . . . . . 54 | 4.1. The Signature-Input HTTP Field | |||
4.2. The Signature HTTP Field . . . . . . . . . . . . . . . . 54 | 4.2. The Signature HTTP Field | |||
4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 55 | 4.3. Multiple Signatures | |||
5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 59 | 5. Requesting Signatures | |||
5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 59 | 5.1. The Accept-Signature Field | |||
5.2. Processing an Accept-Signature . . . . . . . . . . . . . 60 | 5.2. Processing an Accept-Signature | |||
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 61 | 6. IANA Considerations | |||
6.1. HTTP Field Name Registration . . . . . . . . . . . . . . 62 | 6.1. HTTP Field Name Registration | |||
6.2. HTTP Signature Algorithms Registry . . . . . . . . . . . 62 | 6.2. HTTP Signature Algorithms Registry | |||
6.2.1. Registration Template . . . . . . . . . . . . . . . . 63 | 6.2.1. Registration Template | |||
6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 64 | 6.2.2. Initial Contents | |||
6.3. HTTP Signature Metadata Parameters Registry . . . . . . . 65 | 6.3. HTTP Signature Metadata Parameters Registry | |||
6.3.1. Registration Template . . . . . . . . . . . . . . . . 65 | 6.3.1. Registration Template | |||
6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 66 | 6.3.2. Initial Contents | |||
6.4. HTTP Signature Derived Component Names Registry . . . . . 66 | 6.4. HTTP Signature Derived Component Names Registry | |||
6.4.1. Registration Template . . . . . . . . . . . . . . . . 67 | 6.4.1. Registration Template | |||
6.4.2. Initial Contents . . . . . . . . . . . . . . . . . . 68 | 6.4.2. Initial Contents | |||
6.5. HTTP Signature Component Parameters Registry . . . . . . 69 | 6.5. HTTP Signature Component Parameters Registry | |||
6.5.1. Registration Template . . . . . . . . . . . . . . . . 69 | 6.5.1. Registration Template | |||
6.5.2. Initial Contents . . . . . . . . . . . . . . . . . . 70 | 6.5.2. Initial Contents | |||
7. Security Considerations . . . . . . . . . . . . . . . . . . . 70 | 7. Security Considerations | |||
7.1. General Considerations . . . . . . . . . . . . . . . . . 71 | 7.1. General Considerations | |||
7.1.1. Skipping Signature Verification . . . . . . . . . . . 71 | 7.1.1. Skipping Signature Verification | |||
7.1.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . 71 | 7.1.2. Use of TLS | |||
7.2. Message Processing and Selection . . . . . . . . . . . . 72 | 7.2. Message Processing and Selection | |||
7.2.1. Insufficient Coverage . . . . . . . . . . . . . . . . 72 | 7.2.1. Insufficient Coverage | |||
7.2.2. Signature Replay . . . . . . . . . . . . . . . . . . 72 | 7.2.2. Signature Replay | |||
7.2.3. Choosing Message Components . . . . . . . . . . . . . 73 | 7.2.3. Choosing Message Components | |||
7.2.4. Choosing Signature Parameters and Derived Components | 7.2.4. Choosing Signature Parameters and Derived Components | |||
over HTTP Fields . . . . . . . . . . . . . . . . . . 73 | over HTTP Fields | |||
7.2.5. Signature Labels . . . . . . . . . . . . . . . . . . 74 | 7.2.5. Signature Labels | |||
7.2.6. Multiple Signature Confusion . . . . . . . . . . . . 74 | 7.2.6. Multiple Signature Confusion | |||
7.2.7. Collision of Application-Specific Signature Tag . . . 75 | 7.2.7. Collision of Application-Specific Signature Tag | |||
7.2.8. Message Content . . . . . . . . . . . . . . . . . . . 75 | 7.2.8. Message Content | |||
7.3. Cryptographic Considerations . . . . . . . . . . . . . . 76 | 7.3. Cryptographic Considerations | |||
7.3.1. Cryptography and Signature Collision . . . . . . . . 77 | 7.3.1. Cryptography and Signature Collision | |||
7.3.2. Key Theft . . . . . . . . . . . . . . . . . . . . . . 77 | 7.3.2. Key Theft | |||
7.3.3. Symmetric Cryptography . . . . . . . . . . . . . . . 78 | 7.3.3. Symmetric Cryptography | |||
7.3.4. Key Specification Mix-Up . . . . . . . . . . . . . . 78 | 7.3.4. Key Specification Mixup | |||
7.3.5. Non-deterministic Signature Primitives . . . . . . . 78 | 7.3.5. Non-deterministic Signature Primitives | |||
7.3.6. Key and Algorithm Specification Downgrades . . . . . 79 | 7.3.6. Key and Algorithm Specification Downgrades | |||
7.3.7. Signing Signature Values . . . . . . . . . . . . . . 79 | 7.3.7. Signing Signature Values | |||
7.4. Matching Covered Components to Message . . . . . . . . . 80 | 7.4. Matching Signature Parameters to the Target Message | |||
7.4.1. Modification of Required Message Parameters . . . . . 81 | 7.4.1. Modification of Required Message Parameters | |||
7.4.2. Mismatch of Signature Parameters from Message . . . . 81 | 7.4.2. Matching Values of Covered Components to Values in the | |||
7.4.3. Message Component Source and Context . . . . . . . . 81 | Target Message | |||
7.4.4. Multiple Message Component Contexts . . . . . . . . . 82 | 7.4.3. Message Component Source and Context | |||
7.5. HTTP Processing . . . . . . . . . . . . . . . . . . . . . 83 | 7.4.4. Multiple Message Component Contexts | |||
7.5.1. Confusing HTTP Field Names for Derived Component | 7.5. HTTP Processing | |||
Names . . . . . . . . . . . . . . . . . . . . . . . . 83 | 7.5.1. Processing Invalid HTTP Field Names as Derived | |||
7.5.2. Semantically Equivalent Field Values . . . . . . . . 84 | Component Names | |||
7.5.3. Parsing Structured Field Values . . . . . . . . . . . 84 | 7.5.2. Semantically Equivalent Field Values | |||
7.5.4. HTTP Versions and Component Ambiguity . . . . . . . . 85 | 7.5.3. Parsing Structured Field Values | |||
7.5.5. Canonicalization Attacks . . . . . . . . . . . . . . 85 | 7.5.4. HTTP Versions and Component Ambiguity | |||
7.5.6. Non-List Field Values . . . . . . . . . . . . . . . . 86 | 7.5.5. Canonicalization Attacks | |||
7.5.7. Padding Attacks with Multiple Field Values . . . . . 87 | 7.5.6. Non-List Field Values | |||
7.5.8. Ambiguous Handling of Query Elements . . . . . . . . 88 | 7.5.7. Padding Attacks with Multiple Field Values | |||
8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 88 | 7.5.8. Ambiguous Handling of Query Elements | |||
8.1. Identification through Keys . . . . . . . . . . . . . . . 88 | 8. Privacy Considerations | |||
8.2. Signatures do not provide confidentiality . . . . . . . . 89 | 8.1. Identification through Keys | |||
8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 89 | 8.2. Signatures do not provide confidentiality | |||
8.4. Required Content . . . . . . . . . . . . . . . . . . . . 89 | 8.3. Oracles | |||
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 89 | 8.4. Required Content | |||
9.1. Normative References . . . . . . . . . . . . . . . . . . 89 | 9. References | |||
9.2. Informative References . . . . . . . . . . . . . . . . . 91 | 9.1. Normative References | |||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 93 | 9.2. Informative References | |||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 93 | Appendix A. Detecting HTTP Message Signatures | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 94 | Appendix B. Examples | |||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 94 | B.1. Example Keys | |||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 96 | B.1.1. Example RSA Key | |||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 98 | B.1.2. Example RSA-PSS Key | |||
B.1.4. Example Ed25519 Test Key . . . . . . . . . . . . . . 99 | B.1.3. Example ECC P-256 Test Key | |||
B.1.5. Example Shared Secret . . . . . . . . . . . . . . . . 100 | B.1.4. Example Ed25519 Test Key | |||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 100 | B.1.5. Example Shared Secret | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 101 | B.2. Test Cases | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 102 | B.2.1. Minimal Signature Using rsa-pss-sha512 | |||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 103 | B.2.2. Selective Covered Components Using rsa-pss-sha512 | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 104 | B.2.3. Full Coverage Using rsa-pss-sha512 | |||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 104 | B.2.4. Signing a Response Using ecdsa-p256-sha256 | |||
B.2.6. Signing a Request using ed25519 . . . . . . . . . . . 105 | B.2.5. Signing a Request Using hmac-sha256 | |||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 106 | B.2.6. Signing a Request Using ed25519 | |||
B.4. HTTP Message Transformations . . . . . . . . . . . . . . 108 | B.3. TLS-Terminating Proxies | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 111 | B.4. HTTP Message Transformations | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 111 | Acknowledgements | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 117 | Authors' Addresses | |||
1. Introduction | 1. Introduction | |||
Message integrity and authenticity are security properties that are | Message integrity and authenticity are security properties that are | |||
critical to the secure operation of many HTTP applications. | critical to the secure operation of many HTTP applications. | |||
Application developers typically rely on the transport layer to | Application developers typically rely on the transport layer to | |||
provide these properties, by operating their application over [TLS]. | provide these properties, by operating their application over TLS | |||
However, TLS only guarantees these properties over a single TLS | [TLS]. However, TLS only guarantees these properties over a single | |||
connection, and the path between client and application may be | TLS connection, and the path between the client and application may | |||
composed of multiple independent TLS connections (for example, if the | be composed of multiple independent TLS connections (for example, if | |||
application is hosted behind a TLS-terminating gateway or if the | the application is hosted behind a TLS-terminating gateway or if the | |||
client is behind a TLS Inspection appliance). In such cases, TLS | client is behind a TLS Inspection appliance). In such cases, TLS | |||
cannot guarantee end-to-end message integrity or authenticity between | cannot guarantee end-to-end message integrity or authenticity between | |||
the client and application. Additionally, some operating | the client and application. Additionally, some operating | |||
environments present obstacles that make it impractical to use TLS | environments present obstacles that make it impractical to use TLS | |||
(such as presentation of client certificates from a browser), or to | (such as the presentation of client certificates from a browser) or | |||
use features necessary to provide message authenticity. Furthermore, | to use features necessary to provide message authenticity. | |||
some applications require the binding of a higher-level application- | Furthermore, some applications require the binding of a higher-level | |||
specific key to the HTTP message, separate from any TLS certificates | application-specific key to the HTTP message, separate from any TLS | |||
in use. Consequently, while TLS can meet message integrity and | certificates in use. Consequently, while TLS can meet message | |||
authenticity needs for many HTTP-based applications, it is not a | integrity and authenticity needs for many HTTP-based applications, it | |||
universal solution. | is not a universal solution. | |||
Additionally, many applications need to be able to generate and | Additionally, many applications need to be able to generate and | |||
verify signatures despite incomplete knowledge of the HTTP message as | verify signatures despite incomplete knowledge of the HTTP message as | |||
seen on the wire, due to the use of libraries, proxies, or | seen on the wire, due to the use of libraries, proxies, or | |||
application frameworks that alter or hide portions of the message | application frameworks that alter or hide portions of the message | |||
from the application at the time of signing or verification. These | from the application at the time of signing or verification. These | |||
applications need a means to protect the parts of the message that | applications need a means to protect the parts of the message that | |||
are most relevant to the application without having to violate | are most relevant to the application without having to violate | |||
layering and abstraction. | layering and abstraction. | |||
Finally, object-based signature mechanisms such as [JWS] require the | Finally, object-based signature mechanisms such as JSON Web Signature | |||
intact conveyance of the exact information that was signed. When | [JWS] require the intact conveyance of the exact information that was | |||
applying such technologies to an HTTP message, elements of the HTTP | signed. When applying such technologies to an HTTP message, elements | |||
message need to be duplicated in the object payload either directly | of the HTTP message need to be duplicated in the object payload | |||
or through inclusion of a hash. This practice introduces complexity | either directly or through the inclusion of a hash. This practice | |||
since the repeated information needs to be carefully checked for | introduces complexity, since the repeated information needs to be | |||
consistency when the signature is verified. | carefully checked for consistency when the signature is verified. | |||
This document defines a mechanism for providing end-to-end integrity | This document defines a mechanism for providing end-to-end integrity | |||
and authenticity for components of an HTTP message by use of a | and authenticity for components of an HTTP message by using a | |||
detached signature on HTTP messages. The mechanism allows | detached signature on HTTP messages. The mechanism allows | |||
applications to create digital signatures or message authentication | applications to create digital signatures or message authentication | |||
codes (MACs) over only the components of the message that are | codes (MACs) over only the components of the message that are | |||
meaningful and appropriate for the application. Strict | meaningful and appropriate for the application. Strict | |||
canonicalization rules ensure that the verifier can verify the | canonicalization rules ensure that the verifier can verify the | |||
signature even if the message has been transformed in many of the | signature even if the message has been transformed in many of the | |||
ways permitted by HTTP. | ways permitted by HTTP. | |||
The signing mechanism described in this document consists of three | The signing mechanism described in this document consists of three | |||
parts: | parts: | |||
* A common nomenclature and canonicalization rule set for the | * A common nomenclature and canonicalization rule set for the | |||
different protocol elements and other components of HTTP messages, | different protocol elements and other components of HTTP messages, | |||
used to create the signature base. (Section 2) | used to create the signature base (Section 2). | |||
* Algorithms for generating and verifying signatures over HTTP | * Algorithms for generating and verifying signatures over HTTP | |||
message components using this signature base through application | message components using this signature base through the | |||
of cryptographic primitives. (Section 3) | application of cryptographic primitives (Section 3). | |||
* A mechanism for attaching a signature and related metadata to an | * A mechanism for attaching a signature and related metadata to an | |||
HTTP message, and for parsing attached signatures and metadata | HTTP message and for parsing attached signatures and metadata from | |||
from HTTP messages. To facilitate this, this document defines the | HTTP messages. To facilitate this, this document defines the | |||
"Signature-Input" and "Signature" fields. (Section 4) | "Signature-Input" and "Signature" fields (Section 4). | |||
This document also provides a mechanism for negotiation the use of | This document also provides a mechanism for negotiating the use of | |||
signatures in one or more subsequent messages via the "Accept- | signatures in one or more subsequent messages via the "Accept- | |||
Signature" field (Section 5). This optional negotiation mechanism | Signature" field (Section 5). This optional negotiation mechanism | |||
can be used along with opportunistic or application-driven message | can be used along with opportunistic or application-driven message | |||
signatures by either party. | signatures by either party. | |||
The mechanisms defined in this document are important tools that can | The mechanisms defined in this document are important tools that can | |||
be used to an overall security mechanism for an application. This | be used to build an overall security mechanism for an application. | |||
toolkit provides some powerful capabilities, but does not sufficient | This toolkit provides some powerful capabilities but is not | |||
in creating an overall security story. In particular, the | sufficient in creating an overall security story. In particular, the | |||
requirements in Section 1.4 and the security considerations in | requirements listed in Section 1.4 and the security considerations | |||
Section 7 are of high importance to all implementors of this | discussed in Section 7 are of high importance to all implementors of | |||
specification. For example, this specification does not define a | this specification. For example, this specification does not define | |||
means to directly cover HTTP message content (defined in Section 6.4 | a means to directly cover HTTP message content (defined in | |||
of [HTTP]), but relies on the [DIGEST] specification to provide a | Section 6.4 of [HTTP]); rather, it relies on the Digest specification | |||
hash of the message content, as discussed in Section 7.2.8. | [DIGEST] to provide a hash of the message content, as discussed in | |||
Section 7.2.8. | ||||
1.1. Conventions and Terminology | 1.1. Conventions and Terminology | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in | "OPTIONAL" in this document are to be interpreted as described in | |||
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
The terms "HTTP message", "HTTP request", "HTTP response", "target | The terms "HTTP message", "HTTP request", "HTTP response", "target | |||
skipping to change at page 7, line 30 ¶ | skipping to change at line 285 ¶ | |||
cryptography) and keyed MACs (which use symmetric cryptography). | cryptography) and keyed MACs (which use symmetric cryptography). | |||
Similarly, the verb "sign" refers to the generation of either a | Similarly, the verb "sign" refers to the generation of either a | |||
digital signature or keyed MAC over a given signature base. The | digital signature or keyed MAC over a given signature base. The | |||
qualified term "digital signature" refers specifically to the output | qualified term "digital signature" refers specifically to the output | |||
of an asymmetric cryptographic signing operation. | of an asymmetric cryptographic signing operation. | |||
This document uses the following terminology from Section 3 of | This document uses the following terminology from Section 3 of | |||
[STRUCTURED-FIELDS] to specify data types: List, Inner List, | [STRUCTURED-FIELDS] to specify data types: List, Inner List, | |||
Dictionary, Item, String, Integer, Byte Sequence, and Boolean. | Dictionary, Item, String, Integer, Byte Sequence, and Boolean. | |||
This document defines several string constructions using [ABNF] and | This document defines several string constructions using ABNF [ABNF] | |||
uses the following ABNF rules: VCHAR, SP, DQUOTE, LF. This document | and uses the following ABNF rules: VCHAR, SP, DQUOTE, and LF. This | |||
uses the following ABNF rules from [STRUCTURED-FIELDS]: sf-string, | document uses the following ABNF rules from [STRUCTURED-FIELDS]: sf- | |||
inner-list, parameters. This document uses the following ABNF rules | string, inner-list, and parameters. This document uses the following | |||
from [HTTP] and [HTTP/1.1]: field-content, obs-fold, obs-text. | ABNF rules from [HTTP] and [HTTP/1.1]: field-content, obs-fold, and | |||
obs-text. | ||||
In addition to those listed above, this document uses the following | In addition to those listed above, this document uses the following | |||
terms: | terms: | |||
HTTP Message Signature: | HTTP Message Signature: | |||
A digital signature or keyed MAC that covers one or more portions | A digital signature or keyed MAC that covers one or more portions | |||
of an HTTP message. Note that a given HTTP Message can contain | of an HTTP message. Note that a given HTTP message can contain | |||
multiple HTTP Message Signatures. | multiple HTTP message signatures. | |||
Signer: | Signer: | |||
The entity that is generating or has generated an HTTP Message | The entity that is generating or has generated an HTTP message | |||
Signature. Note that multiple entities can act as signers and | signature. Note that multiple entities can act as signers and | |||
apply separate HTTP Message Signatures to a given HTTP Message. | apply separate HTTP message signatures to a given HTTP message. | |||
Verifier: | Verifier: | |||
An entity that is verifying or has verified an HTTP message | ||||
An entity that is verifying or has verified an HTTP Message | signature against an HTTP message. Note that an HTTP message | |||
Signature against an HTTP Message. Note that an HTTP Message | signature may be verified multiple times, potentially by different | |||
Signature may be verified multiple times, potentially by different | ||||
entities. | entities. | |||
HTTP Message Component: | HTTP Message Component: | |||
A portion of an HTTP message that is capable of being covered by | A portion of an HTTP message that is capable of being covered by | |||
an HTTP Message Signature. | an HTTP message signature. | |||
Derived Component: | Derived Component: | |||
An HTTP Message Component derived from the HTTP message through | An HTTP message component derived from the HTTP message through | |||
the use of a specified algorithm or process. See Section 2.2. | the use of a specified algorithm or process. See Section 2.2. | |||
HTTP Message Component Name: | HTTP Message Component Name: | |||
A string that identifies an HTTP Message Component's source, such | A String that identifies an HTTP message component's source, such | |||
as a field name or derived component name. | as a field name or derived component name. | |||
HTTP Message Component Identifier: | HTTP Message Component Identifier: | |||
The combination of an HTTP Message Component Name and any | The combination of an HTTP message component name and any | |||
parameters that uniquely identifies a specific HTTP Message | parameters. This combination uniquely identifies a specific HTTP | |||
Component in respect to a particular HTTP Message Signature and | message component with respect to a particular HTTP message | |||
the HTTP Message it applies to. | signature and the HTTP message it applies to. | |||
HTTP Message Component Value: | HTTP Message Component Value: | |||
The value associated with a given component identifier within the | The value associated with a given component identifier within the | |||
context of a particular HTTP Message. Component values are | context of a particular HTTP message. Component values are | |||
derived from the HTTP Message and are usually subject to a | derived from the HTTP message and are usually subject to a | |||
canonicalization process. | canonicalization process. | |||
Covered Components: | Covered Components: | |||
An ordered set of HTTP message component identifiers for fields | An ordered set of HTTP message component identifiers for fields | |||
(Section 2.1) and derived components (Section 2.2) that indicates | (Section 2.1) and derived components (Section 2.2) that indicates | |||
the set of message components covered by the signature, never | the set of message components covered by the signature, never | |||
including the @signature-params identifier itself. The order of | including the @signature-params identifier itself. The order of | |||
this set is preserved and communicated between the signer and | this set is preserved and communicated between the signer and | |||
verifier to facilitate reconstruction of the signature base. | verifier to facilitate reconstruction of the signature base. | |||
Signature Base: | Signature Base: | |||
The sequence of bytes generated by the signer and verifier using | The sequence of bytes generated by the signer and verifier using | |||
the covered components set and the HTTP Message. The signature | the covered components set and the HTTP message. The signature | |||
base is processed by the cryptographic algorithm to produce or | base is processed by the cryptographic algorithm to produce or | |||
verify the HTTP Message Signature. | verify the HTTP message signature. | |||
HTTP Message Signature Algorithm: | HTTP Message Signature Algorithm: | |||
A cryptographic algorithm that describes the signing and | A cryptographic algorithm that describes the signing and | |||
verification process for the signature, defined in terms of the | verification process for the signature, defined in terms of the | |||
HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | |||
Key Material: | Key Material: | |||
The key material required to create or verify the signature. The | The key material required to create or verify the signature. The | |||
key material is often identified with an explicit key identifier, | key material is often identified with an explicit key identifier, | |||
allowing the signer to indicate to the verifier which key was | allowing the signer to indicate to the verifier which key was | |||
skipping to change at page 9, line 21 ¶ | skipping to change at line 370 ¶ | |||
Creation Time: | Creation Time: | |||
A timestamp representing the point in time that the signature was | A timestamp representing the point in time that the signature was | |||
generated, as asserted by the signer. | generated, as asserted by the signer. | |||
Expiration Time: | Expiration Time: | |||
A timestamp representing the point in time after which the | A timestamp representing the point in time after which the | |||
signature should no longer be accepted by the verifier, as | signature should no longer be accepted by the verifier, as | |||
asserted by the signer. | asserted by the signer. | |||
Target Message: | Target Message: | |||
The HTTP message to which an HTTP Message Signature is applied. | The HTTP message to which an HTTP message signature is applied. | |||
Signature Context: | Signature Context: | |||
The data source from which the HTTP Message Component Values are | The data source from which the HTTP message component values are | |||
drawn. The context includes the target message and any additional | drawn. The context includes the target message and any additional | |||
information the signer or verifier might have, such as the full | information the signer or verifier might have, such as the full | |||
target URI of a request or the related request message for a | target URI of a request or the related request message for a | |||
response. | response. | |||
The term "Unix timestamp" refers to what Section 4.16 of [POSIX.1] | The term "UNIX timestamp" refers to what Section 4.16 of [POSIX.1] | |||
calls "Seconds Since the Epoch". | calls "seconds since the Epoch". | |||
This document contains non-normative examples of partial and complete | This document contains non-normative examples of partial and complete | |||
HTTP messages. Some examples use a single trailing backslash \ to | HTTP messages. Some examples use a single trailing backslash (\) to | |||
indicate line wrapping for long values, as per [RFC8792]. The \ | indicate line wrapping for long values, as per [RFC8792]. The \ | |||
character and leading spaces on wrapped lines are not part of the | character and leading spaces on wrapped lines are not part of the | |||
value. | value. | |||
1.2. Requirements | 1.2. Requirements | |||
HTTP permits and sometimes requires intermediaries to transform | HTTP permits, and sometimes requires, intermediaries to transform | |||
messages in a variety of ways. This can result in a recipient | messages in a variety of ways. This can result in a recipient | |||
receiving a message that is not bitwise-equivalent to the message | receiving a message that is not bitwise-equivalent to the message | |||
that was originally sent. In such a case, the recipient will be | that was originally sent. In such a case, the recipient will be | |||
unable to verify integrity protections over the raw bytes of the | unable to verify integrity protections over the raw bytes of the | |||
sender's HTTP message, as verifying digital signatures or MACs | sender's HTTP message, as verifying digital signatures or MACs | |||
requires both signer and verifier to have the exact same signature | requires both signer and verifier to have the exact same signature | |||
base. Since the exact raw bytes of the message cannot be relied upon | base. Since the exact raw bytes of the message cannot be relied upon | |||
as a reliable source for a signature base, the signer and verifier | as a reliable source for a signature base, the signer and verifier | |||
have to independently create the signature base from their respective | have to independently create the signature base from their respective | |||
versions of the message, via a mechanism that is resilient to safe | versions of the message, via a mechanism that is resilient to safe | |||
changes that do not alter the meaning of the message. | changes that do not alter the meaning of the message. | |||
For a variety of reasons, it is impractical to strictly define what | For a variety of reasons, it is impractical to strictly define what | |||
constitutes a safe change versus an unsafe one. Applications use | constitutes a safe change versus an unsafe one. Applications use | |||
HTTP in a wide variety of ways and may disagree on whether a | HTTP in a wide variety of ways and may disagree on whether a | |||
particular piece of information in a message (e.g., the message | particular piece of information in a message (e.g., the message | |||
content, the method, or a particular header field) is relevant. | content, the method, or a particular header field) is relevant. | |||
Thus, a general purpose solution needs to provide signers with some | Thus, a general-purpose solution needs to provide signers with some | |||
degree of control over which message components are signed. | degree of control over which message components are signed. | |||
HTTP applications may be running in environments that do not provide | HTTP applications may be running in environments that do not provide | |||
complete access to or control over HTTP messages (such as a web | complete access to or control over HTTP messages (such as a web | |||
browser's JavaScript environment), or may be using libraries that | browser's JavaScript environment) or may be using libraries that | |||
abstract away the details of the protocol (such as the Java | abstract away the details of the protocol (such as the Java HTTP | |||
HTTPClient library (https://openjdk.java.net/groups/net/httpclient/ | Client (HttpClient) library | |||
intro.html)). These applications need to be able to generate and | (https://openjdk.java.net/groups/net/httpclient/intro.html)). These | |||
verify signatures despite incomplete knowledge of the HTTP message. | applications need to be able to generate and verify signatures | |||
despite incomplete knowledge of the HTTP message. | ||||
1.3. HTTP Message Transformations | 1.3. HTTP Message Transformations | |||
As mentioned earlier, HTTP explicitly permits and in some cases | As mentioned earlier, HTTP explicitly permits, and in some cases | |||
requires implementations to transform messages in a variety of ways. | requires, implementations to transform messages in a variety of ways. | |||
Implementations are required to tolerate many of these | Implementations are required to tolerate many of these | |||
transformations. What follows is a non-normative and non-exhaustive | transformations. What follows is a non-normative and non-exhaustive | |||
list of transformations that could occur under HTTP, provided as | list of transformations that could occur under HTTP, provided as | |||
context: | context: | |||
* Re-ordering of fields with different field names (Section 5.3 of | * Reordering of fields with different field names (Section 5.3 of | |||
[HTTP]). | [HTTP]). | |||
* Combination of fields with the same field name (Section 5.2 of | * Combination of fields with the same field name (Section 5.2 of | |||
[HTTP]). | [HTTP]). | |||
* Removal of fields listed in the Connection header field | * Removal of fields listed in the Connection header field | |||
(Section 7.6.1 of [HTTP]). | (Section 7.6.1 of [HTTP]). | |||
* Addition of fields that indicate control options (Section 7.6.1 of | * Addition of fields that indicate control options (Section 7.6.1 of | |||
[HTTP]). | [HTTP]). | |||
* Addition or removal of a transfer coding (Section 7.7 of [HTTP]). | * Addition or removal of a transfer coding (Section 7.7 of [HTTP]). | |||
* Addition of fields such as Via (Section 7.6.3 of [HTTP]) and | * Addition of fields such as Via (Section 7.6.3 of [HTTP]) and | |||
Forwarded (Section 4 of [RFC7239]). | Forwarded (Section 4 of [RFC7239]). | |||
* Conversion between different versions of the HTTP protocol (e.g., | * Conversion between different versions of HTTP (e.g., HTTP/1.x to | |||
HTTP/1.x to HTTP/2, or vice-versa). | HTTP/2, or vice versa). | |||
* Changes in casing (e.g., "Origin" to "origin") of any case- | * Changes in case (e.g., "Origin" to "origin") of any case- | |||
insensitive components such as field names, request URI scheme, or | insensitive components such as field names, request URI scheme, or | |||
host. | host. | |||
* Changes to the request target and authority that when applied | * Changes to the request target and authority that, when applied | |||
together do not result in a change to the message's target URI, as | together, do not result in a change to the message's target URI, | |||
defined in Section 7.1 of [HTTP]. | as defined in Section 7.1 of [HTTP]. | |||
Additionally, there are some transformations that are either | Additionally, there are some transformations that are either | |||
deprecated or otherwise not allowed, but still could occur in the | deprecated or otherwise not allowed but that could still occur in the | |||
wild. These transformations can still be handled without breaking | wild. These transformations can still be handled without breaking | |||
the signature, and include things such as: | the signature; they include such actions as: | |||
* Use, addition, or removal of leading or trailing whitespace in a | * Use, addition, or removal of leading or trailing whitespace in a | |||
field value. | field value. | |||
* Use, addition, or removal of obs-fold in field values (Section 5.2 | * Use, addition, or removal of obs-fold in field values (Section 5.2 | |||
of [HTTP/1.1]). | of [HTTP/1.1]). | |||
We can identify these types of transformations as ones that should | We can identify these types of transformations as transformations | |||
not prevent signature verification, even when performed on message | that should not prevent signature verification, even when performed | |||
components covered by the signature. Additionally, all changes to | on message components covered by the signature. Additionally, all | |||
components not covered by the signature should not prevent signature | changes to components not covered by the signature should not prevent | |||
verification. | signature verification. | |||
Some examples of these kinds of transformations, and the effect they | Some examples of these kinds of transformations, and the effect they | |||
have on the message signature, are found in Appendix B.4. | have on the message signature, are found in Appendix B.4. | |||
Other transformations, such as parsing and re-serializing the field | Other transformations, such as parsing and reserializing the field | |||
values of a covered component or changing the value of a derived | values of a covered component or changing the value of a derived | |||
component, can cause a signature to no longer validate against a | component, can cause a signature to no longer validate against a | |||
target message. Applications of this specification need to take care | target message. Applications of this specification need to take care | |||
to ensure that the transformations expected by the application are | to ensure that the transformations expected by the application are | |||
adequately handled by the choice of covered components. | adequately handled by the choice of covered components. | |||
1.4. Application of HTTP Message Signatures | 1.4. Application of HTTP Message Signatures | |||
HTTP Message Signatures are designed to be a general-purpose tool | HTTP message signatures are designed to be a general-purpose tool | |||
applicable in a wide variety of circumstances and applications. In | applicable in a wide variety of circumstances and applications. In | |||
order to properly and safely apply HTTP Message Signatures, an | order to properly and safely apply HTTP message signatures, an | |||
application or profile of this specification MUST specify at least | application or profile of this specification MUST specify, at a | |||
all of the following items: | minimum, all of the following items: | |||
* The set of component identifiers (Section 2) and signature | * The set of component identifiers (Section 2) and signature | |||
parameters (Section 2.3) that are expected and required to be | parameters (Section 2.3) that are expected and required to be | |||
included in the covered components list. For example, an | included in the covered components list. For example, an | |||
authorization protocol could mandate that the Authorization field | authorization protocol could mandate that the Authorization field | |||
be covered to protect the authorization credentials and mandate | be covered to protect the authorization credentials and mandate | |||
the signature parameters contain a created parameter, while an API | that the signature parameters contain a created parameter | |||
expecting semantically relevant HTTP message content could require | (Section 2.3), while an API expecting semantically relevant HTTP | |||
the Content-Digest field defined in [DIGEST] to be present and | message content could require the Content-Digest field defined in | |||
covered as well as mandate a value for tag that is specific to the | [DIGEST] to be present and covered as well as mandate a value for | |||
API being protected. | the tag parameter (Section 2.3) that is specific to the API being | |||
protected. | ||||
* The expected structured field types ([STRUCTURED-FIELDS]) of any | * The expected Structured Field types [STRUCTURED-FIELDS] of any | |||
required or expected covered component fields or parameters. | required or expected covered component fields or parameters. | |||
* A means of retrieving the key material used to verify the | * A means of retrieving the key material used to verify the | |||
signature. An application will usually use the keyid parameter of | signature. An application will usually use the keyid parameter of | |||
the signature parameters (Section 2.3) and define rules for | the signature parameters (Section 2.3) and define rules for | |||
resolving a key from there, though the appropriate key could be | resolving a key from there, though the appropriate key could be | |||
known from other means such as pre-registration of a signer's key. | known from other means such as preregistration of a signer's key. | |||
* The set of allowable signature algorithms to be used by signers | * The set of allowable signature algorithms to be used by signers | |||
and accepted by verifiers. | and accepted by verifiers. | |||
* A means of determining that the signature algorithm used to verify | * A means of determining that the signature algorithm used to verify | |||
the signature is appropriate for the key material and context of | the signature is appropriate for the key material and context of | |||
the message. For example, the process could use the alg parameter | the message. For example, the process could use the alg parameter | |||
of the signature parameters (Section 2.3) to state the algorithm | of the signature parameters (Section 2.3) to state the algorithm | |||
explicitly, derive the algorithm from the key material, or use | explicitly, derive the algorithm from the key material, or use | |||
some pre-configured algorithm agreed upon by the signer and | some preconfigured algorithm agreed upon by the signer and | |||
verifier. | verifier. | |||
* A means of determining that a given key and algorithm used for a | * A means of determining that a given key and algorithm used for a | |||
signature are appropriate for the context of the message. For | signature are appropriate for the context of the message. For | |||
example, a server expecting only ECDSA signatures should know to | example, a server expecting only ECDSA signatures should know to | |||
reject any RSA signatures, or a server expecting asymmetric | reject any RSA signatures, or a server expecting asymmetric | |||
cryptography should know to reject any symmetric cryptography. | cryptography should know to reject any symmetric cryptography. | |||
* A means of determining the context for derivation of message | * A means of determining the context for derivation of message | |||
components from an HTTP message and its application context. | components from an HTTP message and its application context. | |||
While this is normally the target HTTP message itself, the context | While this is normally the target HTTP message itself, the context | |||
could include additional information known to the application | could include additional information known to the application | |||
through configuration, such as an external host name. | through configuration, such as an external hostname. | |||
* If binding between a request and response is needed using the | * If binding between a request and response is needed using the | |||
mechanism in Section 2.4, all elements of the request and response | mechanism provided in Section 2.4, all elements of the request | |||
message that would be required to provide properties of such a | message and the response message that would be required to provide | |||
binding. | properties of such a binding. | |||
* The error messages and codes that are returned from the verifier | * The error messages and codes that are returned from the verifier | |||
to the signer when the signature is invalid, the key material is | to the signer when the signature is invalid, the key material is | |||
inappropriate, the validity time window is out of specification, a | inappropriate, the validity time window is out of specification, a | |||
component value cannot be calculated, or any other errors in the | component value cannot be calculated, or any other errors occur | |||
signature verification process. For example, if a signature is | during the signature verification process. For example, if a | |||
being used as an authentication mechanism, an HTTP status code of | signature is being used as an authentication mechanism, an HTTP | |||
401 Unauthorized or 403 Forbidden could be appropriate. If the | status code of 401 (Unauthorized) or 403 (Forbidden) could be | |||
response is from an HTTP API, a response with an HTTP status code | appropriate. If the response is from an HTTP API, a response with | |||
of 400 Bad Request could include details as described in | an HTTP status code such as 400 (Bad Request) could include more | |||
[RFC7807], such as an indicator that the wrong key material was | details [RFC7807] [RFC9457], such as an indicator that the wrong | |||
used. | key material was used. | |||
When choosing these parameters, an application of HTTP message | When choosing these parameters, an application of HTTP message | |||
signatures has to ensure that the verifier will have access to all | signatures has to ensure that the verifier will have access to all | |||
required information needed to re-create the signature base. For | required information needed to recreate the signature base. For | |||
example, a server behind a reverse proxy would need to know the | example, a server behind a reverse proxy would need to know the | |||
original request URI to make use of the derived component @target- | original request URI to make use of the derived component @target- | |||
uri, even though the apparent target URI would be changed by the | uri, even though the apparent target URI would be changed by the | |||
reverse proxy (see also Section 7.4.3). Additionally, an application | reverse proxy (see also Section 7.4.3). Additionally, an application | |||
using signatures in responses would need to ensure that clients | using signatures in responses would need to ensure that clients | |||
receiving signed responses have access to all the signed portions of | receiving signed responses have access to all the signed portions of | |||
the message, including any portions of the request that were signed | the message, including any portions of the request that were signed | |||
by the server using the related-response parameter. | by the server using the req ("request-response") parameter | |||
(Section 2.4). | ||||
The details of this kind of profiling are the purview of the | Details regarding this kind of profiling are within the purview of | |||
application and outside the scope of this specification, however some | the application and outside the scope of this specification; however, | |||
additional considerations are discussed in Section 7. In particular, | some additional considerations are discussed in Section 7. In | |||
when choosing the required set of component identifiers, care has to | particular, when choosing the required set of component identifiers, | |||
be taken to make sure that the coverage is sufficient for the | care has to be taken to make sure that the coverage is sufficient for | |||
application, as discussed in Section 7.2.1 and Section 7.2.8. This | the application, as discussed in Sections 7.2.1 and 7.2.8. This | |||
specification defines only part of a full security system for an | specification defines only part of a full security system for an | |||
application. When building a complete security system based on this | application. When building a complete security system based on this | |||
tool, it is important to perform a security analysis of the entire | tool, it is important to perform a security analysis of the entire | |||
system of which HTTP Message Signatures is a part. Historical | system, of which HTTP message signatures is a part. Historical | |||
systems, such as [AWS-SIGv4], can provide inspiration and examples of | systems, such as AWS Signature Version 4 [AWS-SIGv4], can provide | |||
how to apply similar mechanisms to an application, though review of | inspiration and examples of how to apply similar mechanisms to an | |||
such historical systems does not negate the need for a security | application, though review of such historical systems does not negate | |||
analysis of an application of HTTP Message Signatures. | the need for a security analysis of an application of HTTP message | |||
signatures. | ||||
2. HTTP Message Components | 2. HTTP Message Components | |||
In order to allow signers and verifiers to establish which components | In order to allow signers and verifiers to establish which components | |||
are covered by a signature, this document defines component | are covered by a signature, this document defines component | |||
identifiers for components covered by an HTTP Message Signature, a | identifiers for components covered by an HTTP message signature, a | |||
set of rules for deriving and canonicalizing the values associated | set of rules for deriving and canonicalizing the values associated | |||
with these component identifiers from the HTTP Message, and the means | with these component identifiers from the HTTP message, and the means | |||
for combining these canonicalized values into a signature base. | for combining these canonicalized values into a signature base. | |||
The signature context for deriving these values MUST be accessible to | The signature context for deriving these values MUST be accessible to | |||
both the signer and the verifier of the message. The context MUST be | both the signer and the verifier of the message. The context MUST be | |||
the same across all components in a given signature. For example, it | the same across all components in a given signature. For example, it | |||
would be an error to use the raw query string for the @query derived | would be an error to use the raw query string for the @query derived | |||
component but combined query and form parameters for the @query-param | component but combined query and form parameters for the @query-param | |||
derived component. For more considerations of the message component | derived component. For more considerations regarding the message | |||
context, see Section 7.4.3. | component context, see Section 7.4.3. | |||
A component identifier is composed of a component name and any | A component identifier is composed of a component name and any | |||
parameters associated with that name. Each component name is either | parameters associated with that name. Each component name is either | |||
an HTTP field name (Section 2.1) or a registered derived component | an HTTP field name (Section 2.1) or a registered derived component | |||
name (Section 2.2). The possible parameters for a component | name (Section 2.2). The possible parameters for a component | |||
identifier are dependent on the component identifier, and the HTTP | identifier are dependent on the component identifier. The "HTTP | |||
Signature Component Parameters registry cataloging all possible | Signature Component Parameters" registry, which catalogs all possible | |||
parameters is defined in Section 6.5. | parameters, is defined in Section 6.5. | |||
Within a single list of covered components, each component identifier | Within a single list of covered components, each component identifier | |||
MUST occur only once. One component identifier is distinct from | MUST occur only once. One component identifier is distinct from | |||
another if the component name differs, or if any of the parameters | another if the component name differs or if any of the parameters | |||
differ for the same component name. Multiple component identifiers | differ for the same component name. Multiple component identifiers | |||
having the same component name MAY be included if they have | having the same component name MAY be included if they have | |||
parameters that make them distinct, such as "foo";bar and "foo";baz. | parameters that make them distinct, such as "foo";bar and "foo";baz. | |||
The order of parameters MUST be preserved when processing a component | The order of parameters MUST be preserved when processing a component | |||
identifier (such as when parsing during verification), but the order | identifier (such as when parsing during verification), but the order | |||
of parameters is not significant when comparing two component | of parameters is not significant when comparing two component | |||
identifiers for equality checks. That is to say, "foo";bar;baz | identifiers for equality checks. That is to say, "foo";bar;baz | |||
cannot be in the same message as "foo";baz;bar, since these two | cannot be in the same message as "foo";baz;bar, since these two | |||
component identifiers are equivalent, but a system processing one | component identifiers are equivalent, but a system processing one | |||
form is not allowed to transform it into the other form. | form is not allowed to transform it into the other form. | |||
skipping to change at page 15, line 9 ¶ | skipping to change at line 641 ¶ | |||
The following sections define component identifier names, their | The following sections define component identifier names, their | |||
parameters, their associated values, and the canonicalization rules | parameters, their associated values, and the canonicalization rules | |||
for their values. The method for combining message components into | for their values. The method for combining message components into | |||
the signature base is defined in Section 2.5. | the signature base is defined in Section 2.5. | |||
2.1. HTTP Fields | 2.1. HTTP Fields | |||
The component name for an HTTP field is the lowercased form of its | The component name for an HTTP field is the lowercased form of its | |||
field name as defined in Section 5.1 of [HTTP]. While HTTP field | field name as defined in Section 5.1 of [HTTP]. While HTTP field | |||
names are case-insensitive, implementations MUST use lowercased field | names are case insensitive, implementations MUST use lowercased field | |||
names (e.g., content-type, date, etag) when using them as component | names (e.g., content-type, date, etag) when using them as component | |||
names. | names. | |||
The component value for an HTTP field is the field value for the | The component value for an HTTP field is the field value for the | |||
named field as defined in Section 5.5 of [HTTP]. The field value | named field as defined in Section 5.5 of [HTTP]. The field value | |||
MUST be taken from the named header field of the target message | MUST be taken from the named header field of the target message | |||
unless this behavior is overridden by additional parameters and | unless this behavior is overridden by additional parameters and | |||
rules, such as the req and tr flags, below. For most fields, the | rules, such as the req and tr flags, below. For most fields, the | |||
field value is an ASCII string as recommended by [HTTP], and the | field value is an ASCII string as recommended by [HTTP], and the | |||
component value is exactly that string. Other encodings could exist | component value is exactly that string. Other encodings could exist | |||
in some implementations, and all non-ASCII field values MUST be | in some implementations, and all non-ASCII field values MUST be | |||
encoded to ASCII before being added to the signature base. The bs | encoded to ASCII before being added to the signature base. The bs | |||
parameter defined in Section 2.1.3 provides a method for wrapping | parameter, as described in Section 2.1.3, provides a method for | |||
such problematic field values. | wrapping such problematic field values. | |||
Unless overridden by additional parameters and rules, HTTP field | Unless overridden by additional parameters and rules, HTTP field | |||
values MUST be combined into a single value as defined in Section 5.2 | values MUST be combined into a single value as defined in Section 5.2 | |||
of [HTTP] to create the component value. Specifically, HTTP fields | of [HTTP] to create the component value. Specifically, HTTP fields | |||
sent as multiple fields MUST be combined by concatenating the values | sent as multiple fields MUST be combined by concatenating the values | |||
using a single comma and a single space as a separator ("," + " "). | using a single comma and a single space as a separator ("," + " "). | |||
Note that intermediaries are allowed to combine values of HTTP fields | Note that intermediaries are allowed to combine values of HTTP fields | |||
with any amount of whitespace between the commas, and if this | with any amount of whitespace between the commas, and if this | |||
behavior is not accounted for by the verifier, the signature can fail | behavior is not accounted for by the verifier, the signature can | |||
since the signer and verifier will see a different component value in | fail, since the signer and verifier will see a different component | |||
their respective signature bases. For robustness, it is RECOMMENDED | value in their respective signature bases. For robustness, it is | |||
that signed messages include only a single instance of any field | RECOMMENDED that signed messages include only a single instance of | |||
covered under the signature, particularly with the value for any | any field covered under the signature, particularly with the value | |||
list-based fields serialized using the algorithm below. This | for any list-based fields serialized using the algorithm below. This | |||
approach increases the chances of the field value remaining untouched | approach increases the chances of the field value remaining untouched | |||
through intermediaries. Where that approach is not possible and | through intermediaries. Where that approach is not possible and | |||
multiple instances of a field need to be sent separately, it is | multiple instances of a field need to be sent separately, it is | |||
RECOMMENDED that signers and verifiers process any list-based fields | RECOMMENDED that signers and verifiers process any list-based fields | |||
taking all individual field values and combining them based on the | taking all individual field values and combining them based on the | |||
strict algorithm below, to counter possible intermediary behavior. | strict algorithm below, to counter possible intermediary behavior. | |||
When the field in question is a structured field of type List or | When the field in question is a Structured Field of type List or | |||
Dictionary, this effect can be accomplished more directly by | Dictionary, this effect can be accomplished more directly by | |||
requiring the strict structured field serialization of the field | requiring the strict Structured Field serialization of the field | |||
value, as described in Section 2.1.1. | value, as described in Section 2.1.1. | |||
Note that some HTTP fields, such as Set-Cookie ([COOKIE]), do not | Note that some HTTP fields, such as Set-Cookie [COOKIE], do not | |||
follow a syntax that allows for combination of field values in this | follow a syntax that allows for the combination of field values in | |||
manner (such that the combined output is unambiguous from multiple | this manner (such that the combined output is unambiguous from | |||
inputs). Even though the component value is never parsed by the | multiple inputs). Even though the component value is never parsed by | |||
message signature process and used only as part of the signature base | the message signature process and is used only as part of the | |||
in Section 2.5, caution needs to be taken when including such fields | signature base (Section 2.5), caution needs to be taken when | |||
in signatures since the combined value could be ambiguous. The bs | including such fields in signatures, since the combined value could | |||
parameter defined in Section 2.1.3 provides a method for wrapping | be ambiguous. The bs parameter, as described in Section 2.1.3, | |||
such problematic fields. See Section 7.5.6 for more discussion of | provides a method for wrapping such problematic fields. See | |||
this issue. | Section 7.5.6 for more discussion regarding this issue. | |||
If the correctly combined value is not directly available for a given | If the correctly combined value is not directly available for a given | |||
field by an implementation, the following algorithm will produce | field by an implementation, the following algorithm will produce | |||
canonicalized results for list-based fields: | canonicalized results for list-based fields: | |||
1. Create an ordered list of the field values of each instance of | 1. Create an ordered list of the field values of each instance of | |||
the field in the message, in the order that they occur (or will | the field in the message, in the order they occur (or will occur) | |||
occur) in the message. | in the message. | |||
2. Strip leading and trailing whitespace from each item in the list. | 2. Strip leading and trailing whitespace from each item in the list. | |||
Note that since HTTP field values are not allowed to contain | Note that since HTTP field values are not allowed to contain | |||
leading and trailing whitespace, this will be a no-op in a | leading and trailing whitespace, this would be a no-op in a | |||
compliant implementation. | compliant implementation. | |||
3. Remove any obsolete line-folding within the line and replace it | 3. Remove any obsolete line folding within the line, and replace it | |||
with a single space (" "), as discussed in Section 5.2 of | with a single space (" "), as discussed in Section 5.2 of | |||
[HTTP/1.1]. Note that this behavior is specific to HTTP/1.1 and | [HTTP/1.1]. Note that this behavior is specific to HTTP/1.1 and | |||
does not apply to other versions of the HTTP specification which | does not apply to other versions of the HTTP specification, which | |||
do not allow internal line folding. | do not allow internal line folding. | |||
4. Concatenate the list of values together with a single comma (",") | 4. Concatenate the list of values with a single comma (",") and a | |||
and a single space (" ") between each item. | single space (" ") between each item. | |||
The resulting string is the component value for the field. | The resulting string is the component value for the field. | |||
Note that some HTTP fields have values with multiple valid | Note that some HTTP fields have values with multiple valid | |||
serializations that have equivalent semantics, such as allow case- | serializations that have equivalent semantics, such as allowing case- | |||
insensitive values that intermediaries could change. Applications | insensitive values that intermediaries could change. Applications | |||
signing and processing such fields MUST consider how to handle the | signing and processing such fields MUST consider how to handle the | |||
values of such fields to ensure that the signer and verifier can | values of such fields to ensure that the signer and verifier can | |||
derive the same value, as discussed in Section 7.5.2. | derive the same value, as discussed in Section 7.5.2. | |||
Following are non-normative examples of component values for header | The following are non-normative examples of component values for | |||
fields, given the following example HTTP message fragment: | header fields, given the following example HTTP message fragment: | |||
Host: www.example.com | Host: www.example.com | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
X-OWS-Header: Leading and trailing whitespace. | X-OWS-Header: Leading and trailing whitespace. | |||
X-Obs-Fold-Header: Obsolete | X-Obs-Fold-Header: Obsolete | |||
line folding. | line folding. | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | |||
skipping to change at page 17, line 27 ¶ | skipping to change at line 748 ¶ | |||
"host": www.example.com | "host": www.example.com | |||
"date": Tue, 20 Apr 2021 02:07:56 GMT | "date": Tue, 20 Apr 2021 02:07:56 GMT | |||
"x-ows-header": Leading and trailing whitespace. | "x-ows-header": Leading and trailing whitespace. | |||
"x-obs-fold-header": Obsolete line folding. | "x-obs-fold-header": Obsolete line folding. | |||
"cache-control": max-age=60, must-revalidate | "cache-control": max-age=60, must-revalidate | |||
"example-dict": a=1, b=2;x=1;y=2, c=(a b c) | "example-dict": a=1, b=2;x=1;y=2, c=(a b c) | |||
Empty HTTP fields can also be signed when present in a message. The | Empty HTTP fields can also be signed when present in a message. The | |||
canonicalized value is the empty string. This means that the | canonicalized value is the empty string. This means that the | |||
following empty header, with (SP) indicating a single trailing space | following empty header field, with (SP) indicating a single trailing | |||
character before the empty field value: | space character before the empty field value: | |||
X-Empty-Header:(SP) | X-Empty-Header:(SP) | |||
Is serialized by the signature base generation algorithm | is serialized by the signature base generation algorithm | |||
(Section 2.5) with an empty string value following the colon and | (Section 2.5) with an empty string value following the colon and | |||
space added after the content identifier. | space added after the component identifier. | |||
"x-empty-header":(SP) | "x-empty-header":(SP) | |||
Any HTTP field component identifiers MAY have the following | Any HTTP field component identifiers MAY have the following | |||
parameters in specific circumstances, each described in detail in | parameters in specific circumstances, each described in detail in | |||
their own sections: | their own sections: | |||
sf A boolean flag indicating that the component value is serialized | sf A Boolean flag indicating that the component value is serialized | |||
using strict encoding of the structured field value | using strict encoding of the Structured Field value | |||
(Section 2.1.1). | (Section 2.1.1). | |||
key A string parameter used to select a single member value from a | key A String parameter used to select a single member value from a | |||
Dictionary structured field (Section 2.1.2). | Dictionary Structured Field (Section 2.1.2). | |||
bs A boolean flag indicating that individual field values are | bs A Boolean flag indicating that individual field values are | |||
encoded using Byte Sequence data structures before being combined | encoded using Byte Sequence data structures before being combined | |||
into the component value (Section 2.1.3). | into the component value (Section 2.1.3). | |||
req A boolean flag for signed responses indicating that the | req A Boolean flag for signed responses indicating that the | |||
component value is derived from the request that triggered this | component value is derived from the request that triggered this | |||
response message and not from the response message directly. Note | response message and not from the response message directly. Note | |||
that this parameter can also be applied to any derived component | that this parameter can also be applied to any derived component | |||
identifiers that target the request (Section 2.4). | identifiers that target the request (Section 2.4). | |||
tr A boolean flag indicating that the field value is taken from the | tr A Boolean flag indicating that the field value is taken from the | |||
trailers of the message as defined in Section 6.5 of [HTTP]. If | trailers of the message as defined in Section 6.5 of [HTTP]. If | |||
this flag is absent, the field value is taken from the headers of | this flag is absent, the field value is taken from the header | |||
the message as defined in Section 6.3 of [HTTP] (Section 2.1.4). | fields of the message as defined in Section 6.3 of [HTTP] | |||
(Section 2.1.4). | ||||
Multiple parameters MAY be specified together, though some | Multiple parameters MAY be specified together, though some | |||
combinations are redundant or incompatible. For example, the sf | combinations are redundant or incompatible. For example, the sf | |||
parameter's functionality is already covered when the key parameter | parameter's functionality is already covered when the key parameter | |||
is used on a dictionary item, since key requires strict serialization | is used on a Dictionary item, since key requires strict serialization | |||
of the value. The bs parameter, which requires the raw bytes of the | of the value. The bs parameter, which requires the raw bytes of the | |||
field values from the message, is not compatible with use of the sf | field values from the message, is not compatible with the use of the | |||
or key parameters, which require the parsed data structures of the | sf or key parameters, which require the parsed data structures of the | |||
field values after combination. | field values after combination. | |||
Additional parameters can be defined in the HTTP Signature Component | Additional parameters can be defined in the "HTTP Signature Component | |||
Parameters registry established in Section 6.5. | Parameters" registry established in Section 6.5. | |||
2.1.1. Strict Serialization of HTTP Structured Fields | 2.1.1. Strict Serialization of HTTP Structured Fields | |||
If the value of an HTTP field is known by the application to be a | If the value of an HTTP field is known by the application to be a | |||
structured field type (as defined in [STRUCTURED-FIELDS] or its | Structured Field type (as defined in [STRUCTURED-FIELDS] or its | |||
extensions or updates), and the expected type of the structured field | extensions or updates) and the expected type of the Structured Field | |||
is known, the signer MAY include the sf parameter in the component | is known, the signer MAY include the sf parameter in the component | |||
identifier. If this parameter is included with a component | identifier. If this parameter is included with a component | |||
identifier, the HTTP field value MUST be serialized using the formal | identifier, the HTTP field value MUST be serialized using the formal | |||
serialization rules specified in Section 4 of [STRUCTURED-FIELDS] (or | serialization rules specified in Section 4 of [STRUCTURED-FIELDS] (or | |||
the applicable formal serialization section of its extensions or | the applicable formal serialization section of its extensions or | |||
updates) applicable to the type of the HTTP field. Note that this | updates) applicable to the type of the HTTP field. Note that this | |||
process will replace any optional internal whitespace with a single | process will replace any optional internal whitespace with a single | |||
space character, among other potential transformations of the value. | space character, among other potential transformations of the value. | |||
If multiple field values occur within a message, these values MUST be | If multiple field values occur within a message, these values MUST be | |||
combined into a single List or Dictionary structure before | combined into a single List or Dictionary structure before | |||
serialization. | serialization. | |||
If the application does not know the type of the field, or the | If the application does not know the type of the field or does not | |||
application does not know how to serialize the type of the field, the | know how to serialize the type of the field, the use of this flag | |||
use of this flag will produce an error. As a consequence, the signer | will produce an error. As a consequence, the signer can only | |||
can only reliably sign fields using this flag when the verifier's | reliably sign fields using this flag when the verifier's system knows | |||
system knows the type as well. | the type as well. | |||
For example, the following dictionary field is a valid serialization: | For example, the following Dictionary field is a valid serialization: | |||
Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | |||
If included in the signature base without parameters, its value would | If included in the signature base without parameters, its value would | |||
be: | be: | |||
"example-dict": a=1, b=2;x=1;y=2, c=(a b c) | "example-dict": a=1, b=2;x=1;y=2, c=(a b c) | |||
However, if the sf parameter is added, the value is re-serialized as | However, if the sf parameter is added, the value is reserialized as | |||
follows: | follows: | |||
"example-dict";sf: a=1, b=2;x=1;y=2, c=(a b c) | "example-dict";sf: a=1, b=2;x=1;y=2, c=(a b c) | |||
The resulting string is used as the component value in Section 2.1. | The resulting string is used as the component value; see Section 2.1. | |||
2.1.2. Dictionary Structured Field Members | 2.1.2. Dictionary Structured Field Members | |||
If a given field is known by the application to be a Dictionary | If a given field is known by the application to be a Dictionary | |||
structured field, an individual member in the value of that | Structured Field, an individual member in the value of that | |||
Dictionary is identified by using the parameter key and the | Dictionary is identified by using the parameter key and the | |||
Dictionary member key as a String value. | Dictionary member key as a String value. | |||
If multiple field values occur within a message, these values MUST be | If multiple field values occur within a message, these values MUST be | |||
combined into a single Dictionary structure before serialization. | combined into a single Dictionary structure before serialization. | |||
An individual member value of a Dictionary Structured Field is | An individual member value of a Dictionary Structured Field is | |||
canonicalized by applying the serialization algorithm described in | canonicalized by applying the serialization algorithm described in | |||
Section 4.1.2 of [STRUCTURED-FIELDS] on the member_value and its | Section 4.1.2 of [STRUCTURED-FIELDS] on the member_value and its | |||
parameters, not including the dictionary key itself. Specifically, | parameters, not including the Dictionary key itself. Specifically, | |||
the value is serialized as an Item or Inner List (the two possible | the value is serialized as an Item or Inner List (the two possible | |||
values of a Dictionary member), with all parameters and possible sub- | values of a Dictionary member), with all parameters and possible | |||
fields serialized using the strict serialization rules defined in | subfields serialized using the strict serialization rules defined in | |||
Section 4 of [STRUCTURED-FIELDS] (or the applicable section of its | Section 4 of [STRUCTURED-FIELDS] (or the applicable section of its | |||
extensions or updates). | extensions or updates). | |||
Each parameterized key for a given field MUST NOT appear more than | Each parameterized key for a given field MUST NOT appear more than | |||
once in the signature base. Parameterized keys MAY appear in any | once in the signature base. Parameterized keys MAY appear in any | |||
order in the signature base, regardless of the order they occur in | order in the signature base, regardless of the order they occur in | |||
the source Dictionary. | the source Dictionary. | |||
If a Dictionary key is named as a covered component but it does not | If a Dictionary key is named as a covered component but it does not | |||
occur in the Dictionary, this MUST cause an error in the signature | occur in the Dictionary, this MUST cause an error in the signature | |||
base generation. | base generation. | |||
Following are non-normative examples of canonicalized values for | The following are non-normative examples of canonicalized values for | |||
Dictionary structured field members given the following example | Dictionary Structured Field members, given the following example | |||
header field, whose value is known by the application to be a | header field, whose value is known by the application to be a | |||
Dictionary: | Dictionary: | |||
Example-Dict: a=1, b=2;x=1;y=2, c=(a b c), d | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c), d | |||
The following example shows canonicalized values for different | The following example shows canonicalized values for different | |||
component identifiers of this field, presented using the signature | component identifiers of this field, presented using the signature | |||
base format discussed in Section 2.5: | base format discussed in Section 2.5: | |||
"example-dict";key="a": 1 | "example-dict";key="a": 1 | |||
"example-dict";key="d": ?1 | "example-dict";key="d": ?1 | |||
"example-dict";key="b": 2;x=1;y=2 | "example-dict";key="b": 2;x=1;y=2 | |||
"example-dict";key="c": (a b c) | "example-dict";key="c": (a b c) | |||
Note that the value for key="c" has been re-serialized according to | Note that the value for key="c" has been reserialized according to | |||
the strict member_value algorithm, and the value for key="d" has been | the strict member_value algorithm, and the value for key="d" has been | |||
serialized as a Boolean value. | serialized as a Boolean value. | |||
2.1.3. Binary-wrapped HTTP Fields | 2.1.3. Binary-Wrapped HTTP Fields | |||
If the value of the HTTP field in question is known by the | If the value of the HTTP field in question is known by the | |||
application to cause problems with serialization, particularly with | application to cause problems with serialization, particularly with | |||
the combination of multiple values into a single line as discussed in | the combination of multiple values into a single line as discussed in | |||
Section 7.5.6, the signer SHOULD include the bs parameter in a | Section 7.5.6, the signer SHOULD include the bs parameter in a | |||
component identifier to indicate the values of the field need to be | component identifier to indicate that the values of the field need to | |||
wrapped as binary structures before being combined. | be wrapped as binary structures before being combined. | |||
If this parameter is included with a component identifier, the | If this parameter is included with a component identifier, the | |||
component value MUST be calculated using the following algorithm: | component value MUST be calculated using the following algorithm: | |||
1. Let the input be the ordered set of values for a field, in the | 1. Let the input be the ordered set of values for a field, in the | |||
order they appear in the message. | order they appear in the message. | |||
2. Create an empty List for accumulating processed field values. | 2. Create an empty List for accumulating processed field values. | |||
3. For each field value in the set: | 3. For each field value in the set: | |||
1. Strip leading and trailing whitespace from the field value. | 3.1. Strip leading and trailing whitespace from the field value. | |||
Note that since HTTP field values are not allowed to contain | Note that since HTTP field values are not allowed to | |||
leading and trailing whitespace, this will be a no-op in a | contain leading and trailing whitespace, this would be a | |||
compliant implementation. | no-op in a compliant implementation. | |||
2. Remove any obsolete line-folding within the line and replace | 3.2. Remove any obsolete line folding within the line, and | |||
it with a single space (" "), as discussed in Section 5.2 of | replace it with a single space (" "), as discussed in | |||
[HTTP/1.1]. Note that this behavior is specific to | Section 5.2 of [HTTP/1.1]. Note that this behavior is | |||
[HTTP/1.1] and does not apply to other versions of the HTTP | specific to [HTTP/1.1] and does not apply to other versions | |||
specification. | of the HTTP specification. | |||
3. Encode the bytes of the resulting field value as a Byte | 3.3. Encode the bytes of the resulting field value as a Byte | |||
Sequence. Note that most fields are restricted to ASCII | Sequence. Note that most fields are restricted to ASCII | |||
characters, but other octets could be included in the value | characters, but other octets could be included in the value | |||
in some implementations. | in some implementations. | |||
4. Add the Byte Sequence to the List accumulator. | 3.4. Add the Byte Sequence to the List accumulator. | |||
4. The intermediate result is a List of Byte Sequence values. | 4. The intermediate result is a List of Byte Sequence values. | |||
5. Follow the strict serialization of a List as described in | 5. Follow the strict serialization of a List as described in | |||
Section 4.1.1 of [STRUCTURED-FIELDS] and return this output. | Section 4.1.1 of [STRUCTURED-FIELDS], and return this output. | |||
For example, the following field with internal commas prevents the | For example, the following field with internal commas prevents the | |||
distinct field values from being safely combined: | distinct field values from being safely combined: | |||
Example-Header: value, with, lots | Example-Header: value, with, lots | |||
Example-Header: of, commas | Example-Header: of, commas | |||
In our example, the same field can be sent with a semantically | In our example, the same field can be sent with a semantically | |||
different single value: | different single value: | |||
skipping to change at page 21, line 45 ¶ | skipping to change at line 957 ¶ | |||
encoded and serialized as follows: | encoded and serialized as follows: | |||
"example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHM=:, :b2YsIGNvbW1hcw==: | "example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHM=:, :b2YsIGNvbW1hcw==: | |||
For the single-instance field above, the encoding with the bs | For the single-instance field above, the encoding with the bs | |||
parameter is: | parameter is: | |||
"example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHMsIG9mLCBjb21tYXM=: | "example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHMsIG9mLCBjb21tYXM=: | |||
This component value is distinct from the multiple-instance field | This component value is distinct from the multiple-instance field | |||
above, preventing a collision which could potentially be exploited. | above, preventing a collision that could potentially be exploited. | |||
2.1.4. Trailer Fields | 2.1.4. Trailer Fields | |||
If the signer wants to include a trailer field in the signature, the | If the signer wants to include a trailer field in the signature, the | |||
signer MUST include the tr boolean parameter to indicate the value | signer MUST include the tr Boolean parameter to indicate that the | |||
MUST be taken from the trailer fields and not from the header fields. | value MUST be taken from the trailer fields and not from the header | |||
fields. | ||||
For example, given the following message: | For example, given the following message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Content-Type: text/plain | Content-Type: text/plain | |||
Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
Trailer: Expires | Trailer: Expires | |||
4 | 4 | |||
HTTP | HTTP | |||
7 | 7 | |||
Message | Message | |||
a | a | |||
Signatures | Signatures | |||
0 | 0 | |||
Expires: Wed, 9 Nov 2022 07:28:00 GMT | Expires: Wed, 9 Nov 2022 07:28:00 GMT | |||
The signer decides to add both the Trailer header field as well as | The signer decides to add both the Trailer header field and the | |||
the Expires trailer to the signature base, along with the status code | Expires trailer field to the signature base, along with the status | |||
derived component: | code derived component: | |||
"@status": 200 | "@status": 200 | |||
"trailer": Expires | "trailer": Expires | |||
"expires";tr: Wed, 9 Nov 2022 07:28:00 GMT | "expires";tr: Wed, 9 Nov 2022 07:28:00 GMT | |||
If a field is available as both a header and trailer in a message, | If a field is available as both a header and a trailer in a message, | |||
both values MAY be signed, but the values MUST be signed separately. | both values MAY be signed, but the values MUST be signed separately. | |||
The values of header fields and trailer fields of the same name MUST | The values of header fields and trailer fields of the same name MUST | |||
NOT be combined for purposes of the signature. | NOT be combined for purposes of the signature. | |||
Since trailer fields could be merged into the header fields or | Since trailer fields could be merged into the header fields or | |||
dropped entirely by intermediaries as per Section 6.5.1 of [HTTP], it | dropped entirely by intermediaries as per Section 6.5.1 of [HTTP], it | |||
is NOT RECOMMENDED to include trailers in the signature unless the | is NOT RECOMMENDED to include trailers in the signature unless the | |||
signer knows that the verifier will have access to the values of the | signer knows that the verifier will have access to the values of the | |||
trailers as sent. | trailers as sent. | |||
2.2. Derived Components | 2.2. Derived Components | |||
In addition to HTTP fields, there are a number of different | In addition to HTTP fields, there are a number of different | |||
components that can be derived from the control data, signature | components that can be derived from the control data, signature | |||
context, or other aspects of the HTTP message being signed. Such | context, or other aspects of the HTTP message being signed. Such | |||
derived components can be included in the signature base by defining | derived components can be included in the signature base by defining | |||
a component name, possible parameters, message target, and the | a component name, possible parameters, message targets, and the | |||
derivation method for its component value. | derivation method for its component value. | |||
Derived component names MUST start with the "at" @ character. This | Derived component names MUST start with the "at" (@) character. This | |||
differentiates derived component names from HTTP field names, which | differentiates derived component names from HTTP field names, which | |||
cannot contain the @ character as per Section 5.1 of [HTTP]. | cannot contain the @ character as per Section 5.1 of [HTTP]. | |||
Processors of HTTP Message Signatures MUST treat derived component | Processors of HTTP message signatures MUST treat derived component | |||
names separately from field names, as discussed in Section 7.5.1. | names separately from field names, as discussed in Section 7.5.1. | |||
This specification defines the following derived components: | This specification defines the following derived components: | |||
@method The method used for a request. (Section 2.2.1) | @method The method used for a request (Section 2.2.1). | |||
@target-uri The full target URI for a request. (Section 2.2.2) | @target-uri The full target URI for a request (Section 2.2.2). | |||
@authority The authority of the target URI for a request. | @authority The authority of the target URI for a request | |||
(Section 2.2.3) | (Section 2.2.3). | |||
@scheme The scheme of the target URI for a request. (Section 2.2.4) | @scheme The scheme of the target URI for a request (Section 2.2.4). | |||
@request-target The request target. (Section 2.2.5) | @request-target The request target (Section 2.2.5). | |||
@path The absolute path portion of the target URI for a request. | @path The absolute path portion of the target URI for a request | |||
(Section 2.2.6) | (Section 2.2.6). | |||
@query The query portion of the target URI for a request. | @query The query portion of the target URI for a request | |||
(Section 2.2.7) | (Section 2.2.7). | |||
@query-param A parsed and encoded query parameter of the target URI | @query-param A parsed and encoded query parameter of the target URI | |||
for a request. (Section 2.2.8) | for a request (Section 2.2.8). | |||
@status The status code for a response. (Section 2.2.9) | @status The status code for a response (Section 2.2.9). | |||
Additional derived component names are defined in the HTTP Signature | Additional derived component names are defined in the "HTTP Signature | |||
Derived Component Names Registry. (Section 6.4) | Derived Component Names" registry (Section 6.4). | |||
Derived component values are taken from the context of the target | Derived component values are taken from the context of the target | |||
message for the signature. This context includes information about | message for the signature. This context includes information about | |||
the message itself, such as its control data, as well as any | the message itself, such as its control data, as well as any | |||
additional state and context held by the signer or verifier. In | additional state and context held by the signer or verifier. In | |||
particular, when signing a response, the signer can include any | particular, when signing a response, the signer can include any | |||
derived components from the originating request by using the | derived components from the originating request by using the req | |||
request-response parameter (Section 2.4). | parameter (Section 2.4). | |||
request: Values derived from and results applied to an HTTP request | request: Values derived from, and results applied to, an HTTP | |||
message as described in Section 3.4 of [HTTP]. If the target | request message as described in Section 3.4 of [HTTP]. If the | |||
message of the signature is a response, using the req parameter | target message of the signature is a response, derived components | |||
allows a request-targeted derived component to be included in the | that target request messages can be included by using the req | |||
signature (see Section 2.4). | parameter as defined in Section 2.4. | |||
response: Values derived from and results applied to an HTTP | response: Values derived from, and results applied to, an HTTP | |||
response message as described in Section 3.4 of [HTTP]. | response message as described in Section 3.4 of [HTTP]. | |||
request, response: Values derived from, and results applied to, | ||||
either a request message or a response message. | ||||
A derived component definition MUST define all target message types | A derived component definition MUST define all target message types | |||
to which it can be applied. | to which it can be applied. | |||
Derived component values MUST be limited to printable characters and | Derived component values MUST be limited to printable characters and | |||
spaces and MUST NOT contain any newline characters. Derived | spaces and MUST NOT contain any newline characters. Derived | |||
component values MUST NOT start or end with whitespace characters. | component values MUST NOT start or end with whitespace characters. | |||
2.2.1. Method | 2.2.1. Method | |||
The @method derived component refers to the HTTP method of a request | The @method derived component refers to the HTTP method of a request | |||
message. The component value is canonicalized by taking the value of | message. The component value is canonicalized by taking the value of | |||
the method as a string. Note that the method name is case-sensitive | the method as a string. Note that the method name is case sensitive | |||
as per [HTTP], Section 9.1. While conventionally standardized method | as per [HTTP], Section 9.1. While conventionally standardized method | |||
names are uppercase [ASCII], no transformation to the input method | names are uppercase [ASCII], no transformation to the input method | |||
value's case is performed. | value's case is performed. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @method component value: | would result in the following @method component value: | |||
POST | POST | |||
And the following signature base line: | and the following signature base line: | |||
"@method": POST | "@method": POST | |||
2.2.2. Target URI | 2.2.2. Target URI | |||
The @target-uri derived component refers to the target URI of a | The @target-uri derived component refers to the target URI of a | |||
request message. The component value is the full absolute target URI | request message. The component value is the target URI of the | |||
of the request, potentially assembled from all available parts | request ([HTTP], Section 7.1), assembled from all available URI | |||
including the authority and request target as described in [HTTP], | components, including the authority. | |||
Section 7.1. | ||||
For example, the following message sent over HTTPS: | For example, the following message sent over HTTPS: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @target-uri component value: | would result in the following @target-uri component value: | |||
https://www.example.com/path?param=value | https://www.example.com/path?param=value | |||
And the following signature base line: | ||||
and the following signature base line: | ||||
"@target-uri": https://www.example.com/path?param=value | "@target-uri": https://www.example.com/path?param=value | |||
2.2.3. Authority | 2.2.3. Authority | |||
The @authority derived component refers to the authority component of | The @authority derived component refers to the authority component of | |||
the target URI of the HTTP request message, as defined in [HTTP], | the target URI of the HTTP request message, as defined in [HTTP], | |||
Section 7.2. In HTTP/1.1, this is usually conveyed using the Host | Section 7.2. In HTTP/1.1, this is usually conveyed using the Host | |||
header, while in HTTP/2 and HTTP/3 it is conveyed using the | header field, while in HTTP/2 and HTTP/3 it is conveyed using the | |||
:authority pseudo-header. The value is the fully-qualified authority | :authority pseudo-header. The value is the fully qualified authority | |||
component of the request, comprised of the host and, optionally, port | component of the request, comprised of the host and, optionally, port | |||
of the request target, as a string. The component value MUST be | of the request target, as a string. The component value MUST be | |||
normalized according to the rules in [HTTP], Section 4.2.3. Namely, | normalized according to the rules provided in [HTTP], Section 4.2.3. | |||
the host name is normalized to lowercase and the default port is | Namely, the hostname is normalized to lowercase, and the default port | |||
omitted. | is omitted. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @authority component value: | would result in the following @authority component value: | |||
www.example.com | www.example.com | |||
And the following signature base line: | and the following signature base line: | |||
"@authority": www.example.com | "@authority": www.example.com | |||
The @authority derived component SHOULD be used instead of signing | The @authority derived component SHOULD be used instead of signing | |||
the Host header directly, see Section 7.2.4. | the Host header field directly. See Section 7.2.4. | |||
2.2.4. Scheme | 2.2.4. Scheme | |||
The @scheme derived component refers to the scheme of the target URL | The @scheme derived component refers to the scheme of the target URL | |||
of the HTTP request message. The component value is the scheme as a | of the HTTP request message. The component value is the scheme as a | |||
lowercase string as defined in [HTTP], Section 4.2. While the scheme | lowercase string as defined in [HTTP], Section 4.2. While the scheme | |||
itself is case-insensitive, it MUST be normalized to lowercase for | itself is case insensitive, it MUST be normalized to lowercase for | |||
inclusion in the signature base. | inclusion in the signature base. | |||
For example, the following request message requested over plain HTTP: | For example, the following request message sent over plain HTTP: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @scheme component value: | would result in the following @scheme component value: | |||
http | http | |||
And the following signature base line: | and the following signature base line: | |||
"@scheme": http | "@scheme": http | |||
2.2.5. Request Target | 2.2.5. Request Target | |||
The @request-target derived component refers to the full request | The @request-target derived component refers to the full request | |||
target of the HTTP request message, as defined in [HTTP], | target of the HTTP request message, as defined in [HTTP], | |||
Section 7.1. The component value of the request target can take | Section 7.1. The component value of the request target can take | |||
different forms, depending on the type of request, as described | different forms, depending on the type of request, as described | |||
below. | below. | |||
For HTTP/1.1, the component value is equivalent to the request target | For HTTP/1.1, the component value is equivalent to the request target | |||
portion of the request line. However, this value is more difficult | portion of the request line. However, this value is more difficult | |||
to reliably construct in other versions of HTTP. Therefore, it is | to reliably construct in other versions of HTTP. Therefore, it is | |||
NOT RECOMMENDED that this component be used when versions of HTTP | NOT RECOMMENDED that this component be used when versions of HTTP | |||
other than 1.1 might be in use. | other than 1.1 might be in use. | |||
The origin form value is combination of the absolute path and query | The origin form value is a combination of the absolute path and query | |||
components of the request URL. For example, the following request | components of the request URL. | |||
message: | ||||
For example, the following request message: | ||||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @request-target component value: | would result in the following @request-target component value: | |||
/path?param=value | /path?param=value | |||
And the following signature base line: | and the following signature base line: | |||
"@request-target": /path?param=value | "@request-target": /path?param=value | |||
The following request to an HTTP proxy with the absolute-form value, | The following request to an HTTP proxy with the absolute-form value, | |||
containing the fully qualified target URI: | containing the fully qualified target URI: | |||
GET https://www.example.com/path?param=value HTTP/1.1 | GET https://www.example.com/path?param=value HTTP/1.1 | |||
Would result in the following @request-target component value: | would result in the following @request-target component value: | |||
https://www.example.com/path?param=value | https://www.example.com/path?param=value | |||
And the following signature base line: | and the following signature base line: | |||
"@request-target": https://www.example.com/path?param=value | "@request-target": https://www.example.com/path?param=value | |||
The following CONNECT request with an authority-form value, | The following CONNECT request with an authority-form value, | |||
containing the host and port of the target: | containing the host and port of the target: | |||
CONNECT www.example.com:80 HTTP/1.1 | CONNECT www.example.com:80 HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @request-target component value: | would result in the following @request-target component value: | |||
www.example.com:80 | www.example.com:80 | |||
And the following signature base line: | and the following signature base line: | |||
"@request-target": www.example.com:80 | "@request-target": www.example.com:80 | |||
The following OPTIONS request message with the asterisk-form value, | The following OPTIONS request message with the asterisk-form value, | |||
containing a single asterisk * character: | containing a single asterisk (*) character: | |||
OPTIONS * HTTP/1.1 | OPTIONS * HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @request-target component value: | would result in the following @request-target component value: | |||
* | * | |||
And the following signature base line: | and the following signature base line: | |||
"@request-target": * | "@request-target": * | |||
2.2.6. Path | 2.2.6. Path | |||
The @path derived component refers to the target path of the HTTP | The @path derived component refers to the target path of the HTTP | |||
request message. The component value is the absolute path of the | request message. The component value is the absolute path of the | |||
request target defined by [URI], with no query component and no | request target defined by [URI], with no query component and no | |||
trailing ? character. The value is normalized according to the rules | trailing question mark (?) character. The value is normalized | |||
in [HTTP], Section 4.2.3. Namely, an empty path string is normalized | according to the rules provided in [HTTP], Section 4.2.3. Namely, an | |||
as a single slash / character. Path components are represented by | empty path string is normalized as a single slash (/) character. | |||
their values before decoding any percent-encoded octets, as described | Path components are represented by their values before decoding any | |||
in the simple string comparison rules in Section 6.2.1 of [URI]. | percent-encoded octets, as described in the simple string comparison | |||
rules provided in Section 6.2.1 of [URI]. | ||||
For example, the following request message: | For example, the following request message: | |||
GET /path?param=value HTTP/1.1 | GET /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @path component value: | would result in the following @path component value: | |||
/path | /path | |||
And the following signature base line: | ||||
and the following signature base line: | ||||
"@path": /path | "@path": /path | |||
2.2.7. Query | 2.2.7. Query | |||
The @query derived component refers to the query component of the | The @query derived component refers to the query component of the | |||
HTTP request message. The component value is the entire normalized | HTTP request message. The component value is the entire normalized | |||
query string defined by [URI], including the leading ? character. | query string defined by [URI], including the leading ? character. | |||
The value is read using the simple string comparison rules in | The value is read using the simple string comparison rules provided | |||
Section 6.2.1 of [URI]. Namely, percent-encoded octets are not | in Section 6.2.1 of [URI]. Namely, percent-encoded octets are not | |||
decoded. | decoded. | |||
For example, the following request message: | For example, the following request message: | |||
GET /path?param=value&foo=bar&baz=bat%2Dman HTTP/1.1 | GET /path?param=value&foo=bar&baz=bat%2Dman HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @query component value: | would result in the following @query component value: | |||
?param=value&foo=bar&baz=bat%2Dman | ?param=value&foo=bar&baz=bat%2Dman | |||
And the following signature base line: | and the following signature base line: | |||
"@query": ?param=value&foo=bar&baz=bat%2Dman | "@query": ?param=value&foo=bar&baz=bat%2Dman | |||
The following request message: | The following request message: | |||
POST /path?queryString HTTP/1.1 | POST /path?queryString HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following @query component value: | would result in the following @query component value: | |||
?queryString | ?queryString | |||
And the following signature base line: | and the following signature base line: | |||
"@query": ?queryString | "@query": ?queryString | |||
Just like including an empty path component, the signer can include | Just like including an empty path component, the signer can include | |||
an empty query component to indicate that this component is not used | an empty query component to indicate that this component is not used | |||
in the message. If the query string is absent from the request | in the message. If the query string is absent from the request | |||
message, the component value is the leading ? character alone: | message, the component value is the leading ? character alone: | |||
? | ? | |||
Resulting in the following signature base line: | resulting in the following signature base line: | |||
"@query": ? | "@query": ? | |||
2.2.8. Query Parameters | 2.2.8. Query Parameters | |||
If a request target URI uses HTML form parameters in the query string | If the query portion of a request target URI uses HTML form | |||
as defined in the "application/x-www-form-urlencoded" section of | parameters in the format defined in Section 5 ("application/ | |||
[HTMLURL], the @query-param derived component allows addressing of | x-www-form-urlencoded") of [HTMLURL], the @query-param derived | |||
individual query parameters. The query parameters MUST be parsed | component allows addressing of these individual query parameters. | |||
according to the "application/x-www-form-urlencoded parsing" section | The query parameters MUST be parsed according to Section 5.1 | |||
of [HTMLURL], resulting in a list of (nameString, valueString) | ("application/x-www-form-urlencoded parsing") of [HTMLURL], resulting | |||
tuples. The REQUIRED name parameter of each component identifier | in a list of (nameString, valueString) tuples. The REQUIRED name | |||
contains the encoded nameString of a single query parameter as a | parameter of each component identifier contains the encoded | |||
String value. The component value of a single named parameter is the | nameString of a single query parameter as a String value. The | |||
encoded valueString of that single query parameter. Several | component value of a single named parameter is the encoded | |||
different named query parameters MAY be included in the covered | valueString of that single query parameter. Several different named | |||
components. Single named parameters MAY occur in any order in the | query parameters MAY be included in the covered components. Single | |||
covered components, regardless of the order they occur in the query | named parameters MAY occur in any order in the covered components, | |||
string. | regardless of the order they occur in the query string. | |||
The value of the name parameter and the component value of a single | The value of the name parameter and the component value of a single | |||
named parameter are calculated by the following process: | named parameter are calculated via the following process: | |||
1. Parse the nameString or valueString of the named query parameter | 1. Parse the nameString or valueString of the named query parameter | |||
defined by the "application/x-www-form-urlencoded parsing" | defined by Section 5.1 ("application/x-www-form-urlencoded | |||
section of [HTMLURL], which is the value after percent-encoded | parsing") of [HTMLURL]; this is the value after percent-encoded | |||
octets are decoded. | octets are decoded. | |||
2. Encode the nameString or valueString using the "percent-encode | 2. Encode the nameString or valueString using the "percent-encode | |||
after encoding" process defined by the "application/x-www-form- | after encoding" process defined by Section 5.2 ("application/ | |||
urlencoded serializing" section of [HTMLURL], which results in an | x-www-form-urlencoded serializing") of [HTMLURL]; this results in | |||
[ASCII] string. | an ASCII string [ASCII]. | |||
3. Output the ASCII string, | 3. Output the ASCII string. | |||
Note that the component value does not include any leading ? | Note that the component value does not include any leading question | |||
characters, equals sign =, or separating & characters. Named query | mark (?) characters, equals sign (=) characters, or separating | |||
parameters with an empty valueString have an empty string as the | ampersand (&) characters. Named query parameters with an empty | |||
component value. Note that due to inconsistencies in | valueString have an empty string as the component value. Note that | |||
implementations, some query parameter parsing libraries drop such | due to inconsistencies in implementations, some query parameter | |||
empty values. | parsing libraries drop such empty values. | |||
If a query parameter is named as a covered component but it does not | If a query parameter is named as a covered component but it does not | |||
occur in the query parameters, this MUST cause an error in the | occur in the query parameters, this MUST cause an error in the | |||
signature base generation. | signature base generation. | |||
For example for the following request: | For example, for the following request: | |||
GET /path?param=value&foo=bar&baz=batman&qux= HTTP/1.1 | GET /path?param=value&foo=bar&baz=batman&qux= HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Indicating the baz, qux and param named query parameters would result | Indicating the baz, qux, and param named query parameters would | |||
in the following @query-param component values: | result in the following @query-param component values: | |||
_baz_: batman | _baz_: batman | |||
_qux_: an empty string | _qux_: an empty string | |||
_param_: value | _param_: value | |||
And the following signature base lines, with (SP) indicating a single | and the following signature base lines, with (SP) indicating a single | |||
trailing space character before the empty component value: | trailing space character before the empty component value: | |||
"@query-param";name="baz": batman | "@query-param";name="baz": batman | |||
"@query-param";name="qux":(SP) | "@query-param";name="qux":(SP) | |||
"@query-param";name="param": value | "@query-param";name="param": value | |||
This derived component has some limitations. Specifically, the | This derived component has some limitations. Specifically, the | |||
algorithm in [HTMLURL] only supports query parameters using percent- | algorithms provided in Section 5 ("application/ | |||
escaped UTF-8 encoding. Other encodings are not supported. | x-www-form-urlencoded") of [HTMLURL] only support query parameters | |||
Additionally, multiple instances of a named parameter are not | using percent-escaped UTF-8 encoding. Other encodings are not | |||
reliably supported in the wild. If a parameter name occurs multiple | supported. Additionally, multiple instances of a named parameter are | |||
times in a request, the named query parameter MUST NOT be included. | not reliably supported in the wild. If a parameter name occurs | |||
If multiple parameters are common within an application, it is | multiple times in a request, the named query parameter MUST NOT be | |||
RECOMMENDED to sign the entire query string using the @query | included. If multiple parameters are common within an application, | |||
it is RECOMMENDED to sign the entire query string using the @query | ||||
component identifier defined in Section 2.2.7. | component identifier defined in Section 2.2.7. | |||
The encoding process allows query parameters that include newlines or | The encoding process allows query parameters that include newlines or | |||
other problematic characters in their values, or with alternative | other problematic characters in their values, or with alternative | |||
encodings such as using the plus character to represent spaces. For | encodings such as using the plus (+) character to represent spaces. | |||
the query parameters in this message: | For the query parameters in this message: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /parameters?var=this%20is%20a%20big%0Amultiline%20value&\ | GET /parameters?var=this%20is%20a%20big%0Amultiline%20value&\ | |||
bar=with+plus+whitespace&fa%C3%A7ade%22%3A%20=something HTTP/1.1 | bar=with+plus+whitespace&fa%C3%A7ade%22%3A%20=something HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
The resulting values are encoded as follows: | The resulting values are encoded as follows: | |||
skipping to change at page 31, line 11 ¶ | skipping to change at line 1405 ¶ | |||
"@query-param";name="fa%C3%A7ade%22%3A%20": something | "@query-param";name="fa%C3%A7ade%22%3A%20": something | |||
If the encoding were not applied, the resultant values would be: | If the encoding were not applied, the resultant values would be: | |||
"@query-param";name="var": this is a big | "@query-param";name="var": this is a big | |||
multiline value | multiline value | |||
"@query-param";name="bar": with plus whitespace | "@query-param";name="bar": with plus whitespace | |||
"@query-param";name="façade\": ": something | "@query-param";name="façade\": ": something | |||
This base string contains characters that violate the constraints on | This base string contains characters that violate the constraints on | |||
component names and values, and is therefore invalid. | component names and values and is therefore invalid. | |||
2.2.9. Status Code | 2.2.9. Status Code | |||
The @status derived component refers to the three-digit numeric HTTP | The @status derived component refers to the three-digit numeric HTTP | |||
status code of a response message as defined in [HTTP], Section 15. | status code of a response message as defined in [HTTP], Section 15. | |||
The component value is the serialized three-digit integer of the HTTP | The component value is the serialized three-digit integer of the HTTP | |||
status code, with no descriptive text. | status code, with no descriptive text. | |||
For example, the following response message: | For example, the following response message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Date: Fri, 26 Mar 2010 00:05:00 GMT | Date: Fri, 26 Mar 2010 00:05:00 GMT | |||
Would result in the following @status component value: | would result in the following @status component value: | |||
200 | 200 | |||
And the following signature base line: | and the following signature base line: | |||
"@status": 200 | "@status": 200 | |||
The @status component identifier MUST NOT be used in a request | The @status component identifier MUST NOT be used in a request | |||
message. | message. | |||
2.3. Signature Parameters | 2.3. Signature Parameters | |||
HTTP Message Signatures have metadata properties that provide | HTTP message signatures have metadata properties that provide | |||
information regarding the signature's generation and verification, | information regarding the signature's generation and verification, | |||
consisting of the ordered set of covered components and the ordered | consisting of the ordered set of covered components and the ordered | |||
set of parameters including a timestamp of signature creation, | set of parameters, where the parameters include a timestamp of | |||
identifiers for verification key material, and other utilities. This | signature creation, identifiers for verification key material, and | |||
metadata is represented by a special message component in the | other utilities. This metadata is represented by a special message | |||
signature base for signature parameters, and it is treated slightly | component in the signature base for signature parameters; this | |||
differently from other message components. Specifically, the | special message component is treated slightly differently from other | |||
signature parameters message component is REQUIRED as the last line | message components. Specifically, the signature parameters message | |||
of the signature base (Section 2.5), and the component identifier | component is REQUIRED as the last line of the signature base | |||
MUST NOT be enumerated within the set of covered components for any | (Section 2.5), and the component identifier MUST NOT be enumerated | |||
signature, including itself. | within the set of covered components for any signature, including | |||
itself. | ||||
The signature parameters component name is @signature-params. | The signature parameters component name is @signature-params. | |||
The signature parameters component value is the serialization of the | The signature parameters component value is the serialization of the | |||
signature parameters for this signature, including the covered | signature parameters for this signature, including the covered | |||
components ordered set with all associated parameters. These | components ordered set with all associated parameters. These | |||
parameters include any of the following: | parameters include any of the following: | |||
* created: Creation time as an Integer UNIX timestamp value. Sub- | created: Creation time as a UNIX timestamp value of type Integer. | |||
second precision is not supported. Inclusion of this parameter is | Sub-second precision is not supported. The inclusion of this | |||
RECOMMENDED. | parameter is RECOMMENDED. | |||
* expires: Expiration time as an Integer UNIX timestamp value. Sub- | expires: Expiration time as a UNIX timestamp value of type Integer. | |||
second precision is not supported. | Sub-second precision is not supported. | |||
* nonce: A random unique value generated for this signature as a | nonce: A random unique value generated for this signature as a | |||
String value. | String value. | |||
* alg: The HTTP message signature algorithm from the HTTP Signature | alg: The HTTP message signature algorithm from the "HTTP Signature | |||
Algorithms registry, as a String value. | Algorithms" registry, as a String value. | |||
* keyid: The identifier for the key material as a String value. | keyid: The identifier for the key material as a String value. | |||
* tag: An application-specific tag for the signature as a String | tag: An application-specific tag for the signature as a String | |||
value. This value is used by applications to help identify | value. This value is used by applications to help identify | |||
signatures relevant for specific applications or protocols. | signatures relevant for specific applications or protocols. | |||
Additional parameters can be defined in the HTTP Signature Metadata | Additional parameters can be defined in the "HTTP Signature Metadata | |||
Parameters Registry (Section 6.3). Note that there is no general | Parameters" registry (Section 6.3). Note that the parameters are not | |||
ordering to the parameters, but once an ordering is chosen for a | in any general order, but once an ordering is chosen for a given set | |||
given set of parameters, it cannot be changed without altering the | of parameters, it cannot be changed without altering the signature | |||
signature parameters value. | parameters value. | |||
The signature parameters component value is serialized as a | The signature parameters component value is serialized as a | |||
parameterized Inner List using the rules in Section 4 of | parameterized Inner List using the rules provided in Section 4 of | |||
[STRUCTURED-FIELDS] as follows: | [STRUCTURED-FIELDS] as follows: | |||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. Determine an order for the component identifiers of the covered | 2. Determine an order for the component identifiers of the covered | |||
components, not including the @signature-params component | components, not including the @signature-params component | |||
identifier itself. Once this order is chosen, it cannot be | identifier itself. Once this order is chosen, it cannot be | |||
changed. This order MUST be the same order as used in creating | changed. This order MUST be the same order as that used in | |||
the signature base (Section 2.5). | creating the signature base (Section 2.5). | |||
3. Serialize the component identifiers of the covered components, | 3. Serialize the component identifiers of the covered components, | |||
including all parameters, as an ordered Inner List of String | including all parameters, as an ordered Inner List of String | |||
values according to Section 4.1.1.1 of [STRUCTURED-FIELDS] and | values according to Section 4.1.1.1 of [STRUCTURED-FIELDS]; then, | |||
append this to the output. Note that the component identifiers | append this to the output. Note that the component identifiers | |||
can include their own parameters, and these parameters are | can include their own parameters, and these parameters are | |||
ordered sets. Once an order is chosen for a component's | ordered sets. Once an order is chosen for a component's | |||
parameters, the order cannot be changed. | parameters, the order cannot be changed. | |||
4. Determine an order for any signature parameters. Once this order | 4. Determine an order for any signature parameters. Once this order | |||
is chosen, it cannot be changed. | is chosen, it cannot be changed. | |||
5. Append the parameters to the Inner List in order according to | 5. Append the parameters to the Inner List in order according to | |||
Section 4.1.1.2 of [STRUCTURED-FIELDS], skipping parameters that | Section 4.1.1.2 of [STRUCTURED-FIELDS], skipping parameters that | |||
skipping to change at page 33, line 47 ¶ | skipping to change at line 1532 ¶ | |||
Note that an HTTP message could contain multiple signatures | Note that an HTTP message could contain multiple signatures | |||
(Section 4.3), but only the signature parameters used for a single | (Section 4.3), but only the signature parameters used for a single | |||
signature are included in a given signature parameters entry. | signature are included in a given signature parameters entry. | |||
2.4. Signing Request Components in a Response Message | 2.4. Signing Request Components in a Response Message | |||
When a request message results in a signed response message, the | When a request message results in a signed response message, the | |||
signer can include portions of the request message in the signature | signer can include portions of the request message in the signature | |||
base by adding the req parameter to the component identifier. | base by adding the req parameter to the component identifier. | |||
req A boolean flag indicating that the component value is derived | req A Boolean flag indicating that the component value is derived | |||
from the request that triggered this response message and not from | from the request that triggered this response message and not from | |||
the response message directly. | the response message directly. | |||
This parameter can be applied to both HTTP fields and derived | This parameter can be applied to both HTTP fields and derived | |||
components that target the request, with the same semantics. The | components that target the request, with the same semantics. The | |||
component value for a message component using this parameter is | component value for a message component using this parameter is | |||
calculated in the same manner as it is normally, but data is pulled | calculated in the same manner as it is normally, but data is pulled | |||
from the request message instead of the target response message to | from the request message instead of the target response message to | |||
which the signature is applied. | which the signature is applied. | |||
Note that the same component name MAY be included with and without | Note that the same component name MAY be included with and without | |||
the req parameter in a single signature base, indicating the same | the req parameter in a single signature base, indicating the same | |||
named component from both the request and response message, | named component from both the request message and the response | |||
respectively. | message. | |||
The req parameter MAY be combined with other parameters as | The req parameter MAY be combined with other parameters as | |||
appropriate for the component identifier, such as the key parameter | appropriate for the component identifier, such as the key parameter | |||
for a dictionary field. | for a Dictionary field. | |||
For example, when serving a response for this request: | For example, when serving a response for this request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
skipping to change at page 35, line 6 ¶ | skipping to change at line 1586 ¶ | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
The server signs the response with its own key, including the @status | The server signs the response with its own key, including the @status | |||
code and several header fields in the covered components. While this | code and several header fields in the covered components. While this | |||
covers a reasonable amount of the response for this application, the | covers a reasonable amount of the response for this application, the | |||
server additionally includes several components derived from the | server additionally includes several components derived from the | |||
original request message that triggered this response. In this | original request message that triggered this response. In this | |||
example, the server includes the method, authority, path, and content | example, the server includes the method, authority, path, and content | |||
digest from the request in the covered components of the response. | digest from the request in the covered components of the response. | |||
The Content-Digest for both the request and the response are included | The Content-Digest for both the request and the response is included | |||
under the response signature. For the application in this example, | under the response signature. For the application in this example, | |||
the query is deemed not to be relevant to the response and is | the query is deemed not to be relevant to the response and is | |||
therefore not covered. Other applications would make different | therefore not covered. Other applications would make different | |||
decisions based on application needs as discussed in Section 1.4. | decisions based on application needs, as discussed in Section 1.4. | |||
The signature base for this example is: | The signature base for this example is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 503 | "@status": 503 | |||
"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ | "content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ | |||
wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | |||
"content-type": application/json | "content-type": application/json | |||
"@authority";req: example.com | "@authority";req: example.com | |||
skipping to change at page 35, line 47 ¶ | skipping to change at line 1627 ¶ | |||
Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\ | Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\ | |||
HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | |||
Signature-Input: reqres=("@status" "content-digest" "content-type" \ | Signature-Input: reqres=("@status" "content-digest" "content-type" \ | |||
"@authority";req "@method";req "@path";req "content-digest";req)\ | "@authority";req "@method";req "@path";req "content-digest";req)\ | |||
;created=1618884479;keyid="test-key-ecc-p256" | ;created=1618884479;keyid="test-key-ecc-p256" | |||
Signature: reqres=:dMT/A/76ehrdBTD/2Xx8QuKV6FoyzEP/I9hdzKN8LQJLNgzU\ | Signature: reqres=:dMT/A/76ehrdBTD/2Xx8QuKV6FoyzEP/I9hdzKN8LQJLNgzU\ | |||
4W767HK05rx1i8meNQQgQPgQp8wq2ive3tV5Ag==: | 4W767HK05rx1i8meNQQgQPgQp8wq2ive3tV5Ag==: | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
Note that the ECDSA algorithm in use here is non-deterministic, | Note that the ECDSA signature algorithm in use here is non- | |||
meaning a different signature value will be created every time the | deterministic, meaning that a different signature value will be | |||
algorithm is run. The signature value provided here can be validated | created every time the algorithm is run. The signature value | |||
against the given keys, but newly-generated signature values are not | provided here can be validated against the given keys, but newly | |||
expected to match the example. See Section 7.3.5. | generated signature values are not expected to match the example. | |||
See Section 7.3.5. | ||||
Since the component values from the request are not repeated in the | Since the component values from the request are not repeated in the | |||
response message, the requester MUST keep the original message | response message, the requester MUST keep the original message | |||
component values around long enough to validate the signature of the | component values around long enough to validate the signature of the | |||
response that uses this component identifier parameter. In most | response that uses this component identifier parameter. In most | |||
cases, this means the requester needs to keep the original request | cases, this means the requester needs to keep the original request | |||
message around, since the signer could choose to include any portions | message around, since the signer could choose to include any portions | |||
of the request in its response, according to the needs of the | of the request in its response, according to the needs of the | |||
application. Since it is possible for an intermediary to alter a | application. Since it is possible for an intermediary to alter a | |||
request message before it is processed by the server, applications | request message before it is processed by the server, applications | |||
need to take care not to sign such altered values as the client would | need to take care not to sign such altered values, as the client | |||
not be able to validate the resulting signature. | would not be able to validate the resulting signature. | |||
It is additionally possible for a server to create a signed response | It is also possible for a server to create a signed response in | |||
in response to a signed request. For example, this signed request: | response to a signed request. For this example of a signed request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
skipping to change at page 36, line 42 ¶ | skipping to change at line 1671 ¶ | |||
Signature: sig1=:e8UJ5wMiRaonlth5ERtE8GIiEH7Akcr493nQ07VPNo6y3qvjdK\ | Signature: sig1=:e8UJ5wMiRaonlth5ERtE8GIiEH7Akcr493nQ07VPNo6y3qvjdK\ | |||
t0fo8VHO8xXDjmtYoatGYBGJVlMfIp06eVMEyNW2I4vN7XDAz7m5v1108vGzaDljr\ | t0fo8VHO8xXDjmtYoatGYBGJVlMfIp06eVMEyNW2I4vN7XDAz7m5v1108vGzaDljr\ | |||
d0H8+SJ28g7bzn6h2xeL/8q+qUwahWA/JmC8aOC9iVnwbOKCc0WSrLgWQwTY6VLp4\ | d0H8+SJ28g7bzn6h2xeL/8q+qUwahWA/JmC8aOC9iVnwbOKCc0WSrLgWQwTY6VLp4\ | |||
2Qt7jjhYT5W7/wCvfK9A1VmHH1lJXsV873Z6hpxesd50PSmO+xaNeYvDLvVdZlhtw\ | 2Qt7jjhYT5W7/wCvfK9A1VmHH1lJXsV873Z6hpxesd50PSmO+xaNeYvDLvVdZlhtw\ | |||
5PCtUYzKjHqwmaQ6DEuM8udRjYsoNqp2xZKcuCO1nKc0V3RjpqMZLuuyVbHDAbCzr\ | 5PCtUYzKjHqwmaQ6DEuM8udRjYsoNqp2xZKcuCO1nKc0V3RjpqMZLuuyVbHDAbCzr\ | |||
0pg2d2VM/OC33JAU7meEjjaNz+d7LWPg==: | 0pg2d2VM/OC33JAU7meEjjaNz+d7LWPg==: | |||
{"hello": "world"} | {"hello": "world"} | |||
The server could choose to sign portions of this response, including | The server could choose to sign portions of this response, including | |||
several portions of the request resulting in this signature base: | several portions of the request, resulting in this signature base: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 503 | "@status": 503 | |||
"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ | "content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ | |||
wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | |||
"content-type": application/json | "content-type": application/json | |||
"@authority";req: example.com | "@authority";req: example.com | |||
"@method";req: POST | "@method";req: POST | |||
"@path";req: /foo | "@path";req: /foo | |||
"@query";req: ?param=Value&Pet=dog | "@query";req: ?param=Value&Pet=dog | |||
"content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\ | "content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\ | |||
2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | 2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"content-type";req: application/json | "content-type";req: application/json | |||
"content-length";req: 18 | "content-length";req: 18 | |||
"@signature-params": ("@status" "content-digest" "content-type" \ | "@signature-params": ("@status" "content-digest" "content-type" \ | |||
"@authority";req "@method";req "@path";req "@query";req \ | "@authority";req "@method";req "@path";req "@query";req \ | |||
"content-digest";req "content-type";req "content-length";req)\ | "content-digest";req "content-type";req "content-length";req)\ | |||
;created=1618884479;keyid="test-key-ecc-p256" | ;created=1618884479;keyid="test-key-ecc-p256" | |||
And the following signed response: | and the following signed response: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
HTTP/1.1 503 Service Unavailable | HTTP/1.1 503 Service Unavailable | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 62 | Content-Length: 62 | |||
Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\ | Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\ | |||
HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: | |||
Signature-Input: reqres=("@status" "content-digest" "content-type" \ | Signature-Input: reqres=("@status" "content-digest" "content-type" \ | |||
"@authority";req "@method";req "@path";req "@query";req \ | "@authority";req "@method";req "@path";req "@query";req \ | |||
"content-digest";req "content-type";req "content-length";req)\ | "content-digest";req "content-type";req "content-length";req)\ | |||
;created=1618884479;keyid="test-key-ecc-p256" | ;created=1618884479;keyid="test-key-ecc-p256" | |||
Signature: reqres=:C73J41GVKc+TYXbSobvZf0CmNcptRiWN+NY1Or0A36ISg6ym\ | Signature: reqres=:C73J41GVKc+TYXbSobvZf0CmNcptRiWN+NY1Or0A36ISg6ym\ | |||
dRN6ZgR2QfrtopFNzqAyv+CeWrMsNbcV2Ojsgg==: | dRN6ZgR2QfrtopFNzqAyv+CeWrMsNbcV2Ojsgg==: | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
Note that the ECDSA algorithm in use here is non-deterministic, | Note that the ECDSA signature algorithm in use here is non- | |||
meaning a different signature value will be created every time the | deterministic, meaning that a different signature value will be | |||
algorithm is run. The signature value provided here can be validated | created every time the algorithm is run. The signature value | |||
against the given keys, but newly-generated signature values are not | provided here can be validated against the given keys, but newly | |||
expected to match the example. See Section 7.3.5. | generated signature values are not expected to match the example. | |||
See Section 7.3.5. | ||||
Applications signing a response to a signed request SHOULD sign all | Applications signing a response to a signed request SHOULD sign all | |||
of the components of the request signature value to provide | of the components of the request signature value to provide | |||
sufficient coverage and protection against a class of collision | sufficient coverage and protection against a class of collision | |||
attacks, as discussed in Section 7.3.7. The server in this example | attacks, as discussed in Section 7.3.7. The server in this example | |||
has included all components listed in the Signature-Input of the | has included all components listed in the Signature-Input field of | |||
client's signature on the request in the response signature, in | the client's signature on the request in the response signature, in | |||
addition to components of the response. | addition to components of the response. | |||
While it is syntactically possible to include the Signature and | While it is syntactically possible to include the Signature and | |||
Signature-Input fields of the request message in the signature | Signature-Input fields of the request message in the signature | |||
components of a response a message using this mechanism, this | components of a response to a message using this mechanism, this | |||
practice is NOT RECOMMENDED. This is because signatures of | practice is NOT RECOMMENDED. This is because signatures of | |||
signatures do not provide transitive coverage of covered components | signatures do not provide transitive coverage of covered components | |||
as one might expect and the practice is susceptible to several | as one might expect, and the practice is susceptible to several | |||
attacks as discussed in Section 7.3.7. An application that needs to | attacks as discussed in Section 7.3.7. An application that needs to | |||
signal successful processing or receipt of a signature would need to | signal successful processing or receipt of a signature would need to | |||
carefully specify alternative mechanisms for sending such a signal | carefully specify alternative mechanisms for sending such a signal | |||
securely. | securely. | |||
The response signature can only ever cover what is included in the | The response signature can only ever cover what is included in the | |||
request message when using this flag. Consequently, if an | request message when using this flag. Consequently, if an | |||
application needs to include the message content of the request under | application needs to include the message content of the request under | |||
the signature of its response, the client needs to include a means | the signature of its response, the client needs to include a means | |||
for covering that content, such as a Content-Digest field. See the | for covering that content, such as a Content-Digest field. See the | |||
discussion in Section 7.2.8 for more information. | discussion in Section 7.2.8 for more information. | |||
The req parameter MUST NOT be used for any component in a signature | The req parameter MUST NOT be used for any component in a signature | |||
that targets a request message. | that targets a request message. | |||
2.5. Creating the Signature Base | 2.5. Creating the Signature Base | |||
The signature base is a [ASCII] string containing the canonicalized | The signature base is an ASCII string [ASCII] containing the | |||
HTTP message components covered by the signature. The input to the | canonicalized HTTP message components covered by the signature. The | |||
signature base creation algorithm is the ordered set of covered | input to the signature base creation algorithm is the ordered set of | |||
component identifiers and their associated values, along with any | covered component identifiers and their associated values, along with | |||
additional signature parameters discussed in Section 2.3. | any additional signature parameters discussed in Section 2.3. | |||
Component identifiers are serialized using the strict serialization | Component identifiers are serialized using the strict serialization | |||
rules defined by [STRUCTURED-FIELDS], Section 4. The component | rules defined by [STRUCTURED-FIELDS], Section 4. The component | |||
identifier has a component name, which is a String Item value | identifier has a component name, which is a String Item value | |||
serialized using the sf-string ABNF rule. The component identifier | serialized using the sf-string ABNF rule. The component identifier | |||
MAY also include defined parameters which are serialized using the | MAY also include defined parameters that are serialized using the | |||
parameters ABNF rule. The signature parameters line defined in | parameters ABNF rule. The signature parameters line defined in | |||
Section 2.3 follows this same pattern, but the component identifier | Section 2.3 follows this same pattern, but the component identifier | |||
is a String Item with a fixed value and no parameters, and the | is a String Item with a fixed value and no parameters, and the | |||
component value is always an Inner List with optional parameters. | component value is always an Inner List with optional parameters. | |||
Note that this means the serialization of the component name itself | Note that this means the serialization of the component name itself | |||
is encased in double quotes, with parameters following as a | is encased in double quotes, with parameters following as a | |||
semicolon-separated list, such as "cache-control", "@authority", | semicolon-separated list, such as "cache-control", "@authority", | |||
"@signature-params", or "example-dictionary";key="foo". | "@signature-params", or "example-dictionary";key="foo". | |||
skipping to change at page 39, line 19 ¶ | skipping to change at line 1784 ¶ | |||
signature-base-line = component-identifier ":" SP | signature-base-line = component-identifier ":" SP | |||
( derived-component-value / *field-content ) | ( derived-component-value / *field-content ) | |||
; no obs-fold nor obs-text | ; no obs-fold nor obs-text | |||
component-identifier = component-name parameters | component-identifier = component-name parameters | |||
component-name = sf-string | component-name = sf-string | |||
derived-component-value = *( VCHAR / SP ) | derived-component-value = *( VCHAR / SP ) | |||
signature-params-line = DQUOTE "@signature-params" DQUOTE | signature-params-line = DQUOTE "@signature-params" DQUOTE | |||
":" SP inner-list | ":" SP inner-list | |||
To create the signature base, the signer or verifier concatenates | To create the signature base, the signer or verifier concatenates | |||
together entries for each component identifier in the signature's | entries for each component identifier in the signature's covered | |||
covered components (including their parameters) using the following | components (including their parameters) using the following | |||
algorithm. All errors produced as described immediately MUST fail | algorithm. All errors produced as described MUST fail the algorithm | |||
the algorithm with no signature output base output. | immediately, without outputting a signature base. | |||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. For each message component item in the covered components set (in | 2. For each message component item in the covered components set (in | |||
order): | order): | |||
1. If the component identifier (including its parameters) has | 2.1. If the component identifier (including its parameters) has | |||
already been added to the signature base, produce an error. | already been added to the signature base, produce an error. | |||
2. Append the component identifier for the covered component | 2.2. Append the component identifier for the covered component | |||
serialized according to the component-identifier ABNF rule. | serialized according to the component-identifier ABNF rule. | |||
Note that this serialization places the component name in | Note that this serialization places the component name in | |||
double quotes and appends any parameters outside of the | double quotes and appends any parameters outside of the | |||
quotes. | quotes. | |||
3. Append a single colon : | 2.3. Append a single colon (:). | |||
4. Append a single space " " | 2.4. Append a single space (" "). | |||
5. Determine the component value for the component identifier. | 2.5. Determine the component value for the component identifier. | |||
* If the component identifier has a parameter that is not | * If the component identifier has a parameter that is not | |||
understood, produce an error. | understood, produce an error. | |||
* If the component identifier has parameters that are | * If the component identifier has parameters that are | |||
mutually incompatible with one another, such as bs and sf, | mutually incompatible with one another, such as bs and | |||
produce an error. | sf, produce an error. | |||
* If the component identifier contains the req parameter and | * If the component identifier contains the req parameter | |||
the target message is a request, produce an error. | and the target message is a request, produce an error. | |||
* If the component identifier contains the req parameter and | * If the component identifier contains the req parameter | |||
the target message is a response, the context for the | and the target message is a response, the context for | |||
component value is the related request message of the | the component value is the related request message of | |||
target response message. Otherwise, the context for the | the target response message. Otherwise, the context for | |||
component value is the target message. | the component value is the target message. | |||
* If the component name starts with an "at" character (@), | * If the component name starts with an "at" (@) character, | |||
derive the component's value from the message according to | derive the component's value from the message according | |||
the specific rules defined for the derived component, as | to the specific rules defined for the derived component, | |||
in Section 2.2, including processing of any known valid | as provided in Section 2.2, including processing of any | |||
parameters. If the derived component name is unknown or | known valid parameters. If the derived component name | |||
the value cannot be derived, produce an error. | is unknown or the value cannot be derived, produce an | |||
error. | ||||
* If the component name does not start with an "at" | * If the component name does not start with an "at" (@) | |||
character (@), canonicalize the HTTP field value as | character, canonicalize the HTTP field value as | |||
described in Section 2.1, including processing of any | described in Section 2.1, including processing of any | |||
known valid parameters. If the field cannot be found in | known valid parameters. If the field cannot be found in | |||
the message, or the value cannot be obtained in the | the message or the value cannot be obtained in the | |||
context, produce an error. | context, produce an error. | |||
6. Append the covered component's canonicalized component value. | 2.6. Append the covered component's canonicalized component | |||
value. | ||||
7. Append a single newline \n | 2.7. Append a single newline (\n). | |||
3. Append the signature parameters component (Section 2.3) according | 3. Append the signature parameters component (Section 2.3) according | |||
to the signature-params-line rule as follows: | to the signature-params-line rule as follows: | |||
1. Append the component identifier for the signature parameters | 3.1. Append the component identifier for the signature | |||
serialized according to the component-identifier rule, i.e. | parameters serialized according to the component-identifier | |||
the exact value "@signature-params" (including double quotes) | rule, i.e., the exact value "@signature-params" (including | |||
double quotes). | ||||
2. Append a single colon : | 3.2. Append a single colon (:). | |||
3. Append a single space " " | 3.3. Append a single space (" "). | |||
4. Append the signature parameters' canonicalized component | 3.4. Append the signature parameters' canonicalized component | |||
value as defined in Section 2.3, i.e. an Inner List | values as defined in Section 2.3, i.e., Inner List | |||
structured field value with parameters | Structured Field values with parameters. | |||
4. Produce an error if the output string contains any non-ASCII | 4. Produce an error if the output string contains any non-ASCII | |||
([ASCII]) characters. | characters [ASCII]. | |||
5. Return the output string. | 5. Return the output string. | |||
If covered components reference a component identifier that cannot be | If covered components reference a component identifier that cannot be | |||
resolved to a component value in the message, the implementation MUST | resolved to a component value in the message, the implementation MUST | |||
produce an error and not create a signature base. Such situations | produce an error and not create a signature base. Such situations | |||
include, but are not limited to: | include, but are not limited to, the following: | |||
* The signer or verifier does not understand the derived component | * The signer or verifier does not understand the derived component | |||
name. | name. | |||
* The component name identifies a field that is not present in the | * The component name identifies a field that is not present in the | |||
message or whose value is malformed. | message or whose value is malformed. | |||
* The component identifier includes a parameter that is unknown or | * The component identifier includes a parameter that is unknown or | |||
does not apply to the component identifier to which it is | does not apply to the component identifier to which it is | |||
attached. | attached. | |||
* The component identifier indicates that a structured field | * The component identifier indicates that a Structured Field | |||
serialization is used (via the sf parameter), but the field in | serialization is used (via the sf parameter), but the field in | |||
question is known to not be a structured field or the type of | question is known to not be a Structured Field or the type of | |||
structured field is not known to the implementation. | Structured Field is not known to the implementation. | |||
* The component identifier is a dictionary member identifier that | * The component identifier is a Dictionary member identifier that | |||
references a field that is not present in the message, is not a | references a field that is not present in the message, that is not | |||
Dictionary Structured Field, or whose value is malformed. | a Dictionary Structured Field, or whose value is malformed. | |||
* The component identifier is a dictionary member identifier or a | * The component identifier is a Dictionary member identifier or a | |||
named query parameter identifier that references a member that is | named query parameter identifier that references a member that is | |||
not present in the component value, or whose value is malformed. | not present in the component value or whose value is malformed. | |||
E.g., the identifier is "example-dict";key="c" and the value of | For example, the identifier is "example-dict";key="c", and the | |||
the Example-Dict header field is a=1, b=2, which does not have the | value of the Example-Dict header field is a=1, b=2, which does not | |||
c value. | have the c value. | |||
In the following non-normative example, the HTTP message being signed | In the following non-normative example, the HTTP message being signed | |||
is the following request: | is the following request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
skipping to change at page 42, line 4 ¶ | skipping to change at line 1911 ¶ | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
The covered components consist of the @method, @authority, and @path | The covered components consist of the @method, @authority, and @path | |||
derived components followed by the Content-Digest, Content-Length, | derived components followed by the Content-Digest, Content-Length, | |||
and Content-Type HTTP header fields, in order. The signature | and Content-Type HTTP header fields, in order. The signature | |||
parameters consist of a creation timestamp of 1618884473 and a key | parameters consist of a creation timestamp of 1618884473 and a key | |||
identifier of test-key-rsa-pss. Note that no explicit alg parameter | identifier of test-key-rsa-pss. Note that no explicit alg parameter | |||
is given here since the verifier is known by the application to use | is given here, since the verifier is known by the application to use | |||
the RSA PSS algorithm based on the identified key. The signature | the RSA-PSS algorithm based on the identified key. The signature | |||
base for this message with these parameters is: | base for this message with these parameters is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@method": POST | "@method": POST | |||
"@authority": example.com | "@authority": example.com | |||
"@path": /foo | "@path": /foo | |||
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"content-length": 18 | "content-length": 18 | |||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("@method" "@authority" "@path" \ | "@signature-params": ("@method" "@authority" "@path" \ | |||
"content-digest" "content-length" "content-type")\ | "content-digest" "content-length" "content-type")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Figure 1: Non-normative example Signature Base | Figure 1: Non-normative Example Signature Base | |||
Note that the example signature base here, or anywhere else within | Note that the example signature base above does not include the final | |||
this specification, does not include the final newline that ends the | newline that ends the displayed example, nor do other example | |||
displayed example. | signature bases displayed elsewhere in this specification. | |||
3. HTTP Message Signatures | 3. HTTP Message Signatures | |||
An HTTP Message Signature is a signature over a string generated from | An HTTP message signature is a signature over a string generated from | |||
a subset of the components of an HTTP message in addition to metadata | a subset of the components of an HTTP message in addition to metadata | |||
about the signature itself. When successfully verified against an | about the signature itself. When successfully verified against an | |||
HTTP message, an HTTP Message Signature provides cryptographic proof | HTTP message, an HTTP message signature provides cryptographic proof | |||
that the message is semantically equivalent to the message for which | that the message is semantically equivalent to the message for which | |||
the signature was generated, with respect to the subset of message | the signature was generated, with respect to the subset of message | |||
components that was signed. | components that was signed. | |||
3.1. Creating a Signature | 3.1. Creating a Signature | |||
Creation of an HTTP message signature is a process that takes as its | Creation of an HTTP message signature is a process that takes as its | |||
input the signature context (including the target message) and the | input the signature context (including the target message) and the | |||
requirements for the application. The output is a signature value | requirements for the application. The output is a signature value | |||
and set of signature parameters that can be communicated to the | and set of signature parameters that can be communicated to the | |||
verifier by adding them to the message. | verifier by adding them to the message. | |||
In order to create a signature, a signer MUST follow the following | In order to create a signature, a signer MUST apply the following | |||
algorithm: | algorithm: | |||
1. The signer chooses an HTTP signature algorithm and key material | 1. The signer chooses an HTTP signature algorithm and key material | |||
for signing from the set of potential signing algorithms. The | for signing from the set of potential signing algorithms. The | |||
set of potential algorithms is determined by the application and | set of potential algorithms is determined by the application and | |||
is out of scope for this document. The signer MUST choose key | is out of scope for this document. The signer MUST choose key | |||
material that is appropriate for the signature's algorithm, and | material that is appropriate for the signature's algorithm and | |||
that conforms to any requirements defined by the algorithm, such | that conforms to any requirements defined by the algorithm, such | |||
as key size or format. The mechanism by which the signer chooses | as key size or format. The mechanism by which the signer chooses | |||
the algorithm and key material is out of scope for this document. | the algorithm and key material is out of scope for this document. | |||
2. The signer sets the signature's creation time to the current | 2. The signer sets the signature's creation time to the current | |||
time. | time. | |||
3. If applicable, the signer sets the signature's expiration time | 3. If applicable, the signer sets the signature's expiration time | |||
property to the time at which the signature is to expire. The | property to the time at which the signature is to expire. The | |||
expiration is a hint to the verifier, expressing the time at | expiration is a hint to the verifier, expressing the time at | |||
which the signer is no longer willing to vouch for the signature. | which the signer is no longer willing to vouch for the signature. | |||
An appropriate expiration length, and the processing requirements | An appropriate expiration length, and the processing requirements | |||
of this parameter, are application-specific. | of this parameter, are application specific. | |||
4. The signer creates an ordered set of component identifiers | 4. The signer creates an ordered set of component identifiers | |||
representing the message components to be covered by the | representing the message components to be covered by the | |||
signature, and attaches signature metadata parameters to this | signature and attaches signature metadata parameters to this set. | |||
set. The serialized value of this is later used as the value of | The serialized value of this set is later used as the value of | |||
the Signature-Input field as described in Section 4.1. | the Signature-Input field as described in Section 4.1. | |||
* Once an order of covered components is chosen, the order MUST | * Once an order of covered components is chosen, the order MUST | |||
NOT change for the life of the signature. | NOT change for the life of the signature. | |||
* Each covered component identifier MUST be either an HTTP field | * Each covered component identifier MUST be either (1) an HTTP | |||
in the signature context Section 2.1 or a derived component | field (Section 2.1) in the signature context or (2) a derived | |||
listed in Section 2.2 or the HTTP Signature Derived Component | component listed in Section 2.2 or in the "HTTP Signature | |||
Names registry. | Derived Component Names" registry. | |||
* Signers of a request SHOULD include some or all of the message | * Signers of a request SHOULD include some or all of the message | |||
control data in the covered components, such as the @method, | control data in the covered components, such as the @method, | |||
@authority, @target-uri, or some combination thereof. | @authority, @target-uri, or some combination thereof. | |||
* Signers SHOULD include the created signature metadata | * Signers SHOULD include the created signature metadata | |||
parameter to indicate when the signature was created. | parameter to indicate when the signature was created. | |||
* The @signature-params derived component identifier MUST NOT be | * The @signature-params derived component identifier MUST NOT be | |||
listed in the list of covered component identifiers. The | present in the list of covered component identifiers. The | |||
derived component is required to always be the last line in | derived component is required to always be the last line in | |||
the signature base, ensuring that a signature always covers | the signature base, ensuring that a signature always covers | |||
its own metadata and the metadata cannot be substituted. | its own metadata and the metadata cannot be substituted. | |||
* Further guidance on what to include in this set and in what | * Further guidance on what to include in this set and in what | |||
order is out of scope for this document. | order is out of scope for this document. | |||
5. The signer creates the signature base using these parameters and | 5. The signer creates the signature base using these parameters and | |||
the signature base creation algorithm. (Section 2.5) | the signature base creation algorithm (Section 2.5). | |||
6. The signer uses the HTTP_SIGN primitive function to sign the | 6. The signer uses the HTTP_SIGN primitive function to sign the | |||
signature base with the chosen signing algorithm using the key | signature base with the chosen signing algorithm using the key | |||
material chosen by the signer. The HTTP_SIGN primitive and | material chosen by the signer. The HTTP_SIGN primitive and | |||
several concrete applications of signing algorithms are defined | several concrete applications of signing algorithms are defined | |||
in Section 3.3. | in Section 3.3. | |||
7. The byte array output of the signature function is the HTTP | 7. The byte array output of the signature function is the HTTP | |||
message signature output value to be included in the Signature | message signature output value to be included in the Signature | |||
field as defined in Section 4.2. | field as defined in Section 4.2. | |||
For example, given the HTTP message and signature parameters in the | For example, given the HTTP message and signature parameters in the | |||
example in Section 2.5, the example signature base is signed with the | example in Section 2.5, the example signature base is signed with the | |||
test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS algorithm | test-key-rsa-pss key (see Appendix B.1.2) and the RSASSA-PSS | |||
described in Section 3.3.1, giving the following message signature | algorithm described in Section 3.3.1, giving the following message | |||
output value, encoded in Base64: | signature output value, encoded in Base64: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ | HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ | |||
YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ | YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ | |||
+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ | +xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ | |||
VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ | VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ | |||
E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ | E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ | |||
RalVc/g== | RalVc/g== | |||
Figure 2: Non-normative example signature value | Figure 2: Non-normative Example Signature Value | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | Note that the RSA-PSS algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning that a different signature value will be created every time | |||
algorithm is run. The signature value provided here can be validated | the algorithm is run. The signature value provided here can be | |||
against the given keys, but newly-generated signature values are not | validated against the given keys, but newly generated signature | |||
expected to match the example. See Section 7.3.5. | values are not expected to match the example. See Section 7.3.5. | |||
3.2. Verifying a Signature | 3.2. Verifying a Signature | |||
Verification of an HTTP message signature is a process that takes as | Verification of an HTTP message signature is a process that takes as | |||
its input the signature context (including the target message, | its input the signature context (including the target message, | |||
particularly its Signature and Signature-Input fields) and the | particularly its Signature and Signature-Input fields) and the | |||
requirements for the application. The output of the verification is | requirements for the application. The output of the verification is | |||
either a positive verification or an error. | either a positive verification or an error. | |||
In order to verify a signature, a verifier MUST follow the following | In order to verify a signature, a verifier MUST apply the following | |||
algorithm: | algorithm: | |||
1. Parse the Signature and Signature-Input fields as described in | 1. Parse the Signature and Signature-Input fields as described in | |||
Section 4.1 and Section 4.2, and extract the signatures to be | Sections 4.1 and 4.2, and extract the signatures to be verified | |||
verified. | and their labels. | |||
1. If there is more than one signature value present, determine | 1.1. If there is more than one signature value present, | |||
which signature should be processed for this message based on | determine which signature should be processed for this | |||
the policy and configuration of the verifier. If an | message based on the policy and configuration of the | |||
applicable signature is not found, produce an error. | verifier. If an applicable signature is not found, produce | |||
an error. | ||||
2. If the chosen Signature value does not have a corresponding | 1.2. If the chosen Signature field value does not have a | |||
Signature-Input value, produce an error. | corresponding Signature-Input field value (i.e., one with | |||
the same label), produce an error. | ||||
2. Parse the values of the chosen Signature-Input field as a | 2. Parse the values of the chosen Signature-Input field as a | |||
parameterized Inner List to get the ordered list of covered | parameterized Inner List to get the ordered list of covered | |||
components and the signature parameters for the signature to be | components and the signature parameters for the signature to be | |||
verified. | verified. | |||
3. Parse the value of the corresponding Signature field to get the | 3. Parse the value of the corresponding Signature field to get the | |||
byte array value of the signature to be verified. | byte array value of the signature to be verified. | |||
4. Examine the signature parameters to confirm that the signature | 4. Examine the signature parameters to confirm that the signature | |||
meets the requirements described in this document, as well as any | meets the requirements described in this document, as well as any | |||
additional requirements defined by the application such as which | additional requirements defined by the application such as which | |||
message components are required to be covered by the signature. | message components are required to be covered by the signature | |||
(Section 3.2.1) | (Section 3.2.1). | |||
5. Determine the verification key material for this signature. If | 5. Determine the verification key material for this signature. If | |||
the key material is known through external means such as static | the key material is known through external means such as static | |||
configuration or external protocol negotiation, the verifier will | configuration or external protocol negotiation, the verifier will | |||
use that. If the key is identified in the signature parameters, | use the applicable technique to obtain the key material from this | |||
the verifier will dereference this to appropriate key material to | external knowledge. If the key is identified in the signature | |||
use with the signature. The verifier has to determine the | parameters, the verifier will dereference the key identifier to | |||
trustworthiness of the key material for the context in which the | appropriate key material to use with the signature. The verifier | |||
signature is presented. If a key is identified that the verifier | has to determine the trustworthiness of the key material for the | |||
does not know, does not trust for this request, or does not match | context in which the signature is presented. If a key is | |||
something preconfigured, the verification MUST fail. | identified that the verifier does not know or trust for this | |||
request or that does not match something preconfigured, the | ||||
verification MUST fail. | ||||
6. Determine the algorithm to apply for verification: | 6. Determine the algorithm to apply for verification: | |||
1. Start with the set of allowable algorithms known to the | 6.1. Start with the set of allowable algorithms known to the | |||
application. If any of the following steps selects an | application. If any of the following steps select an | |||
algorithm that is not in this set, the signature validation | algorithm that is not in this set, the signature validation | |||
fails. | fails. | |||
2. If the algorithm is known through external means such as | 6.2. If the algorithm is known through external means such as | |||
static configuration or external protocol negotiation, the | static configuration or external protocol negotiation, the | |||
verifier will use this algorithm. | verifier will use that algorithm. | |||
3. If the algorithm can be determined from the keying material, | 6.3. If the algorithm can be determined from the keying | |||
such as through an algorithm field on the key value itself, | material, such as through an algorithm field on the key | |||
the verifier will use this algorithm. | value itself, the verifier will use that algorithm. | |||
4. If the algorithm is explicitly stated in the signature | 6.4. If the algorithm is explicitly stated in the signature | |||
parameters using a value from the HTTP Signature Algorithms | parameters using a value from the "HTTP Signature | |||
registry, the verifier will use the referenced algorithm. | Algorithms" registry, the verifier will use the referenced | |||
algorithm. | ||||
5. If the algorithm is specified in more than one location, such | 6.5. If the algorithm is specified in more than one location | |||
as through static configuration and the algorithm signature | (e.g., a combination of static configuration, the algorithm | |||
parameter, or the algorithm signature parameter and from the | signature parameter, and the key material itself), the | |||
key material itself, the resolved algorithms MUST be the | resolved algorithms MUST be the same. If the algorithms | |||
same. If the algorithms are not the same, the verifier MUST | are not the same, the verifier MUST fail the verification. | |||
fail the verification. | ||||
7. Use the received HTTP message and the parsed signature parameters | 7. Use the received HTTP message and the parsed signature parameters | |||
to re-create the signature base, using the algorithm defined in | to recreate the signature base, using the algorithm defined in | |||
Section 2.5. The value of the @signature-params input is the | Section 2.5. The value of the @signature-params input is the | |||
value of the Signature-Input field for this signature serialized | value of the Signature-Input field for this signature serialized | |||
according to the rules described in Section 2.3. Note that this | according to the rules described in Section 2.3. Note that this | |||
does not include the signature's label from the Signature-Input | does not include the signature's label from the Signature-Input | |||
field. | field. | |||
8. If the key material is appropriate for the algorithm, apply the | 8. If the key material is appropriate for the algorithm, apply the | |||
appropriate HTTP_VERIFY cryptographic verification algorithm to | appropriate HTTP_VERIFY cryptographic verification algorithm to | |||
the signature, recalculated signature base, key material, | the signature, recalculated signature base, key material, and | |||
signature value. The HTTP_VERIFY primitive and several concrete | signature value. The HTTP_VERIFY primitive and several concrete | |||
algorithms are defined in Section 3.3. | algorithms are defined in Section 3.3. | |||
9. The results of the verification algorithm function are the final | 9. The results of the verification algorithm function are the final | |||
results of the cryptographic verification function. | results of the cryptographic verification function. | |||
If any of the above steps fail or produce an error, the signature | If any of the above steps fail or produce an error, the signature | |||
validation fails. | validation fails. | |||
For example, verifying the signature with the key sig1 of the | For example, verifying the signature with the label sig1 of the | |||
following message with the test-key-rsa-pss key in Appendix B.1.2 and | following message with the test-key-rsa-pss key (see Appendix B.1.2) | |||
the RSA PSS algorithm described in Section 3.3.1: | and the RSASSA-PSS algorithm described in Section 3.3.1: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Content-Length: 18 | Content-Length: 18 | |||
skipping to change at page 47, line 27 ¶ | skipping to change at line 2170 ¶ | |||
Signature: sig1=:HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrl\ | Signature: sig1=:HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrl\ | |||
FrCGUDih47vAxi4L2YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxH\ | FrCGUDih47vAxi4L2YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxH\ | |||
LMCy8uqK488o+9jrptQ+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSf\ | LMCy8uqK488o+9jrptQ+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSf\ | |||
SvzPuBCh+ARHBmWuNo1UzVVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y\ | SvzPuBCh+ARHBmWuNo1UzVVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y\ | |||
9TP5FsZYzHvDqbInkTNigBcE9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7\ | 9TP5FsZYzHvDqbInkTNigBcE9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7\ | |||
aXq6Am6sfOrpIC49yXjj3ae6HRalVc/g==: | aXq6Am6sfOrpIC49yXjj3ae6HRalVc/g==: | |||
{"hello": "world"} | {"hello": "world"} | |||
With the additional requirements that at least the method, authority, | With the additional requirements that at least the method, authority, | |||
path, content-digest, content-length, and content-type be signed, and | path, content-digest, content-length, and content-type entries be | |||
that the signature creation timestamp is recent enough at the time of | signed, and that the signature creation timestamp be recent enough at | |||
verification, the verification passes. | the time of verification, the verification passes. | |||
3.2.1. Enforcing Application Requirements | 3.2.1. Enforcing Application Requirements | |||
The verification requirements specified in this document are intended | The verification requirements specified in this document are intended | |||
as a baseline set of restrictions that are generally applicable to | as a baseline set of restrictions that are generally applicable to | |||
all use cases. Applications using HTTP Message Signatures MAY impose | all use cases. Applications using HTTP message signatures MAY impose | |||
requirements above and beyond those specified by this document, as | requirements above and beyond those specified by this document, as | |||
appropriate for their use case. | appropriate for their use case. | |||
Some non-normative examples of additional requirements an application | Some non-normative examples of additional requirements an application | |||
might define are: | might define are: | |||
* Requiring a specific set of header fields to be signed (e.g., | * Requiring a specific set of header fields to be signed (e.g., | |||
Authorization, Digest). | Authorization, Content-Digest). | |||
* Enforcing a maximum signature age from the time of the created | * Enforcing a maximum signature age from the time of the created | |||
time stamp. | timestamp. | |||
* Rejection of signatures past the expiration time in the expires | * Rejecting signatures past the expiration time in the expires | |||
time stamp. Note that the expiration time is a hint from the | timestamp. Note that the expiration time is a hint from the | |||
signer and that a verifier can always reject a signature ahead of | signer and that a verifier can always reject a signature ahead of | |||
its expiration time. | its expiration time. | |||
* Prohibition of certain signature metadata parameters, such as | * Prohibiting certain signature metadata parameters, such as runtime | |||
runtime algorithm signaling with the alg parameter when the | algorithm signaling with the alg parameter when the algorithm is | |||
algorithm is determined from the key information. | determined from the key information. | |||
* Ensuring successful dereferencing of the keyid parameter to valid | * Ensuring successful dereferencing of the keyid parameter to valid | |||
and appropriate key material. | and appropriate key material. | |||
* Prohibiting the use of certain algorithms, or mandating the use of | * Prohibiting the use of certain algorithms or mandating the use of | |||
a specific algorithm. | a specific algorithm. | |||
* Requiring keys to be of a certain size (e.g., 2048 bits vs. 1024 | * Requiring keys to be of a certain size (e.g., 2048 bits vs. 1024 | |||
bits). | bits). | |||
* Enforcing uniqueness of the nonce parameter. | * Enforcing uniqueness of the nonce parameter. | |||
* Requiring an application-specific value for the tag parameter. | * Requiring an application-specific value for the tag parameter. | |||
Application-specific requirements are expected and encouraged. When | Application-specific requirements are expected and encouraged. When | |||
skipping to change at page 48, line 34 ¶ | skipping to change at line 2225 ¶ | |||
during the signature verification process, and signature verification | during the signature verification process, and signature verification | |||
MUST fail if the signature does not conform to the application's | MUST fail if the signature does not conform to the application's | |||
requirements. | requirements. | |||
Applications MUST enforce the requirements defined in this document. | Applications MUST enforce the requirements defined in this document. | |||
Regardless of use case, applications MUST NOT accept signatures that | Regardless of use case, applications MUST NOT accept signatures that | |||
do not conform to these requirements. | do not conform to these requirements. | |||
3.3. Signature Algorithms | 3.3. Signature Algorithms | |||
An HTTP Message signature MUST use a cryptographic digital signature | An HTTP message signature MUST use a cryptographic digital signature | |||
or MAC method that is appropriate for the key material, environment, | or MAC method that is appropriate for the key material, environment, | |||
and needs of the signer and verifier. This specification does not | and needs of the signer and verifier. This specification does not | |||
strictly limit the available signature algorithms, and any signature | strictly limit the available signature algorithms, and any signature | |||
algorithm that meets these basic requirements MAY be used by an | algorithm that meets these basic requirements MAY be used by an | |||
application of HTTP message signatures. | application of HTTP message signatures. | |||
Each signing method HTTP_SIGN takes as its input the signature base | For each signing method, HTTP_SIGN takes as its input the signature | |||
defined in Section 2.5 as a byte array (M), the signing key material | base defined in Section 2.5 as a byte array (M) and the signing key | |||
(Ks), and outputs the signature output as a byte array (S): | material (Ks), and outputs the resultant signature as a byte array | |||
(S): | ||||
HTTP_SIGN (M, Ks) -> S | HTTP_SIGN (M, Ks) -> S | |||
Each verification method HTTP_VERIFY takes as its input the re- | For each verification method, HTTP_VERIFY takes as its input the | |||
generated signature base defined in Section 2.5 as a byte array (M), | regenerated signature base defined in Section 2.5 as a byte array | |||
the verification key material (Kv), and the presented signature to be | (M), the verification key material (Kv), and the presented signature | |||
verified as a byte array (S) and outputs the verification result (V) | to be verified as a byte array (S), and outputs the verification | |||
as a boolean: | result (V) as a Boolean: | |||
HTTP_VERIFY (M, Kv, S) -> V | HTTP_VERIFY (M, Kv, S) -> V | |||
The following sections contain several common signature algorithms | The following sections contain several common signature algorithms | |||
and demonstrate how these cryptographic primitives map to the | and demonstrate how these cryptographic primitives map to the | |||
HTTP_SIGN and HTTP_VERIFY definitions here. Which method to use can | HTTP_SIGN and HTTP_VERIFY definitions above. Which method to use can | |||
be communicated through the explicit algorithm signature parameter | be communicated through the explicit algorithm (alg) signature | |||
alg defined in Section 2.3, by reference to the key material, or | parameter (Section 2.3), by reference to the key material, or through | |||
through mutual agreement between the signer and verifier. Signature | mutual agreement between the signer and verifier. Signature | |||
algorithms selected using the alg parameter MUST use values from the | algorithms selected using the alg parameter MUST use values from the | |||
HTTP Signature Algorithms registry (Section 6.2). | "HTTP Signature Algorithms" registry (Section 6.2). | |||
3.3.1. RSASSA-PSS using SHA-512 | 3.3.1. RSASSA-PSS Using SHA-512 | |||
To sign using this algorithm, the signer applies the RSASSA-PSS-SIGN | To sign using this algorithm, the signer applies the RSASSA-PSS-SIGN | |||
(K, M) function defined in [RFC8017] with the signer's private | (K, M) function defined in [RFC8017] with the signer's private | |||
signing key (K) and the signature base (M) (Section 2.5). The mask | signing key (K) and the signature base (M) (Section 2.5). The mask | |||
generation function is MGF1 as specified in [RFC8017] with a hash | generation function is MGF1 as specified in [RFC8017] with a hash | |||
function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | |||
The hash function (Hash) SHA-512 [RFC6234] is applied to the | The hash function (Hash) SHA-512 [RFC6234] is applied to the | |||
signature base to create the digest content to which the digital | signature base to create the digest content to which the digital | |||
signature is applied. The resulting signed content byte array (S) is | signature is applied. The resulting signed content byte array (S) is | |||
the HTTP message signature output used in Section 3.1. | the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the RSASSA-PSS- | To verify using this algorithm, the verifier applies the RSASSA-PSS- | |||
VERIFY ((n, e), M, S) function [RFC8017] using the public key portion | VERIFY ((n, e), M, S) function [RFC8017] using the public key portion | |||
of the verification key material ((n, e)) and the signature base (M) | of the verification key material (n, e) and the signature base (M) | |||
re-created as described in Section 3.2. The mask generation function | recreated as described in Section 3.2. The mask generation function | |||
is MGF1 as specified in [RFC8017] with a hash function of SHA-512 | is MGF1 as specified in [RFC8017] with a hash function of SHA-512 | |||
[RFC6234]. The salt length (sLen) is 64 bytes. The hash function | [RFC6234]. The salt length (sLen) is 64 bytes. The hash function | |||
(Hash) SHA-512 [RFC6234] is applied to the signature base to create | (Hash) SHA-512 [RFC6234] is applied to the signature base to create | |||
the digest content to which the verification function is applied. | the digest content to which the verification function is applied. | |||
The verifier extracts the HTTP message signature to be verified (S) | The verifier extracts the HTTP message signature to be verified (S) | |||
as described in Section 3.2. The results of the verification | as described in Section 3.2. The results of the verification | |||
function indicate if the signature presented is valid. | function indicate whether the signature presented is valid. | |||
Note that the output of RSA PSS algorithms are non-deterministic, and | Note that the output of the RSASSA-PSS algorithm is non- | |||
therefore it is not correct to re-calculate a new signature on the | deterministic; therefore, it is not correct to recalculate a new | |||
signature base and compare the results to an existing signature. | signature on the signature base and compare the results to an | |||
Instead, the verification algorithm defined here needs to be used. | existing signature. Instead, the verification algorithm defined here | |||
See Section 7.3.5. | needs to be used. See Section 7.3.5. | |||
Use of this algorithm can be indicated at runtime using the rsa-pss- | The use of this algorithm can be indicated at runtime using the rsa- | |||
sha512 value for the alg signature parameter. | pss-sha512 value for the alg signature parameter. | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 | 3.3.2. RSASSA-PKCS1-v1_5 Using SHA-256 | |||
To sign using this algorithm, the signer applies the RSASSA- | To sign using this algorithm, the signer applies the RSASSA- | |||
PKCS1-V1_5-SIGN (K, M) function defined in [RFC8017] with the | PKCS1-V1_5-SIGN (K, M) function defined in [RFC8017] with the | |||
signer's private signing key (K) and the signature base (M) | signer's private signing key (K) and the signature base (M) | |||
(Section 2.5). The hash SHA-256 [RFC6234] is applied to the | (Section 2.5). The hash SHA-256 [RFC6234] is applied to the | |||
signature base to create the digest content to which the digital | signature base to create the digest content to which the digital | |||
signature is applied. The resulting signed content byte array (S) is | signature is applied. The resulting signed content byte array (S) is | |||
the HTTP message signature output used in Section 3.1. | the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the RSASSA- | To verify using this algorithm, the verifier applies the RSASSA- | |||
PKCS1-V1_5-VERIFY ((n, e), M, S) function [RFC8017] using the public | PKCS1-V1_5-VERIFY ((n, e), M, S) function [RFC8017] using the public | |||
key portion of the verification key material ((n, e)) and the | key portion of the verification key material (n, e) and the signature | |||
signature base (M) re-created as described in Section 3.2. The hash | base (M) recreated as described in Section 3.2. The hash function | |||
function SHA-256 [RFC6234] is applied to the signature base to create | SHA-256 [RFC6234] is applied to the signature base to create the | |||
the digest content to which the verification function is applied. | digest content to which the verification function is applied. The | |||
The verifier extracts the HTTP message signature to be verified (S) | verifier extracts the HTTP message signature to be verified (S) as | |||
as described in Section 3.2. The results of the verification | described in Section 3.2. The results of the verification function | |||
function indicate if the signature presented is valid. | indicate whether the signature presented is valid. | |||
Use of this algorithm can be indicated at runtime using the rsa- | The use of this algorithm can be indicated at runtime using the rsa- | |||
v1_5-sha256 value for the alg signature parameter. | v1_5-sha256 value for the alg signature parameter. | |||
3.3.3. HMAC using SHA-256 | 3.3.3. HMAC Using SHA-256 | |||
To sign and verify using this algorithm, the signer applies the HMAC | To sign and verify using this algorithm, the signer applies the HMAC | |||
function [RFC2104] with the shared signing key (K) and the signature | function [RFC2104] with the shared signing key (K) and the signature | |||
base (text) (Section 2.5). The hash function SHA-256 [RFC6234] is | base (text) (Section 2.5). The hash function SHA-256 [RFC6234] is | |||
applied to the signature base to create the digest content to which | applied to the signature base to create the digest content to which | |||
the HMAC is applied, giving the signature result. | the HMAC is applied, giving the signature result. | |||
For signing, the resulting value is the HTTP message signature output | For signing, the resulting value is the HTTP message signature output | |||
used in Section 3.1. | used in Section 3.1. | |||
For verification, the verifier extracts the HTTP message signature to | For verification, the verifier extracts the HTTP message signature to | |||
be verified (S) as described in Section 3.2. The output of the HMAC | be verified (S) as described in Section 3.2. The output of the HMAC | |||
function is compared bytewise to the value of the HTTP message | function is compared bytewise to the value of the HTTP message | |||
signature, and the results of the comparison determine the validity | signature, and the results of the comparison determine the validity | |||
of the signature presented. | of the signature presented. | |||
Use of this algorithm can be indicated at runtime using the hmac- | The use of this algorithm can be indicated at runtime using the hmac- | |||
sha256 value for the alg signature parameter. | sha256 value for the alg signature parameter. | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 | 3.3.4. ECDSA Using Curve P-256 DSS and SHA-256 | |||
To sign using this algorithm, the signer applies the ECDSA algorithm | To sign using this algorithm, the signer applies the ECDSA signature | |||
defined in [FIPS186-4] using curve P-256 with the signer's private | algorithm defined in [FIPS186-5] using curve P-256 with the signer's | |||
signing key and the signature base (Section 2.5). The hash SHA-256 | private signing key and the signature base (Section 2.5). The hash | |||
[RFC6234] is applied to the signature base to create the digest | SHA-256 [RFC6234] is applied to the signature base to create the | |||
content to which the digital signature is applied, (M). The | digest content to which the digital signature is applied (M). The | |||
signature algorithm returns two integer values, r and s. These are | signature algorithm returns two integer values: r and s. These are | |||
both encoded as big-endian unsigned integers, zero-padded to | both encoded as big-endian unsigned integers, zero-padded to 32 | |||
32-octets each. These encoded values are concatenated into a single | octets each. These encoded values are concatenated into a single | |||
64-octet array consisting of the encoded value of r followed by the | 64-octet array consisting of the encoded value of r followed by the | |||
encoded value of s. The resulting concatenation of (r, s) is byte | encoded value of s. The resulting concatenation of (r, s) is a byte | |||
array of the HTTP message signature output used in Section 3.1. | array of the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the ECDSA | To verify using this algorithm, the verifier applies the ECDSA | |||
algorithm defined in [FIPS186-4] using the public key portion of the | signature algorithm defined in [FIPS186-5] using the public key | |||
verification key material and the signature base re-created as | portion of the verification key material and the signature base | |||
described in Section 3.2. The hash function SHA-256 [RFC6234] is | recreated as described in Section 3.2. The hash function SHA-256 | |||
applied to the signature base to create the digest content to which | [RFC6234] is applied to the signature base to create the digest | |||
the signature verification function is applied, (M). The verifier | content to which the signature verification function is applied (M). | |||
extracts the HTTP message signature to be verified (S) as described | The verifier extracts the HTTP message signature to be verified (S) | |||
in Section 3.2. This value is a 64-octet array consisting of the | as described in Section 3.2. This value is a 64-octet array | |||
encoded values of r and s concatenated in order. These are both | consisting of the encoded values of r and s concatenated in order. | |||
encoded in big-endian unsigned integers, zero-padded to 32-octets | These are both encoded as big-endian unsigned integers, zero-padded | |||
each. The resulting signature value (r, s) is used as input to the | to 32 octets each. The resulting signature value (r, s) is used as | |||
signature verification function. The results of the verification | input to the signature verification function. The results of the | |||
function indicate if the signature presented is valid. | verification function indicate whether the signature presented is | |||
valid. | ||||
Note that the output of ECDSA algorithms are non-deterministic, and | Note that the output of ECDSA signature algorithms is non- | |||
therefore it is not correct to re-calculate a new signature on the | deterministic; therefore, it is not correct to recalculate a new | |||
signature base and compare the results to an existing signature. | signature on the signature base and compare the results to an | |||
Instead, the verification algorithm defined here needs to be used. | existing signature. Instead, the verification algorithm defined here | |||
See Section 7.3.5. | needs to be used. See Section 7.3.5. | |||
Use of this algorithm can be indicated at runtime using the ecdsa- | The use of this algorithm can be indicated at runtime using the | |||
p256-sha256 value for the alg signature parameter. | ecdsa-p256-sha256 value for the alg signature parameter. | |||
3.3.5. ECDSA using curve P-384 DSS and SHA-384 | 3.3.5. ECDSA Using Curve P-384 DSS and SHA-384 | |||
To sign using this algorithm, the signer applies the ECDSA algorithm | To sign using this algorithm, the signer applies the ECDSA signature | |||
defined in [FIPS186-4] using curve P-384 with the signer's private | algorithm defined in [FIPS186-5] using curve P-384 with the signer's | |||
signing key and the signature base (Section 2.5). The hash SHA-384 | private signing key and the signature base (Section 2.5). The hash | |||
[RFC6234] is applied to the signature base to create the digest | SHA-384 [RFC6234] is applied to the signature base to create the | |||
content to which the digital signature is applied, (M). The | digest content to which the digital signature is applied (M). The | |||
signature algorithm returns two integer values, r and s. These are | signature algorithm returns two integer values: r and s. These are | |||
both encoded as big-endian unsigned integers, zero-padded to | both encoded as big-endian unsigned integers, zero-padded to 48 | |||
48-octets each. These encoded values are concatenated into a single | octets each. These encoded values are concatenated into a single | |||
96-octet array consisting of the encoded value of r followed by the | 96-octet array consisting of the encoded value of r followed by the | |||
encoded value of s. The resulting concatenation of (r, s) is byte | encoded value of s. The resulting concatenation of (r, s) is a byte | |||
array of the HTTP message signature output used in Section 3.1. | array of the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the ECDSA | To verify using this algorithm, the verifier applies the ECDSA | |||
algorithm defined in [FIPS186-4] using the public key portion of the | signature algorithm defined in [FIPS186-5] using the public key | |||
verification key material and the signature base re-created as | portion of the verification key material and the signature base | |||
described in Section 3.2. The hash function SHA-384 [RFC6234] is | recreated as described in Section 3.2. The hash function SHA-384 | |||
applied to the signature base to create the digest content to which | [RFC6234] is applied to the signature base to create the digest | |||
the signature verification function is applied, (M). The verifier | content to which the signature verification function is applied (M). | |||
extracts the HTTP message signature to be verified (S) as described | The verifier extracts the HTTP message signature to be verified (S) | |||
in Section 3.2. This value is a 96-octet array consisting of the | as described in Section 3.2. This value is a 96-octet array | |||
encoded values of r and s concatenated in order. These are both | consisting of the encoded values of r and s concatenated in order. | |||
encoded in big-endian unsigned integers, zero-padded to 48-octets | These are both encoded as big-endian unsigned integers, zero-padded | |||
each. The resulting signature value (r, s) is used as input to the | to 48 octets each. The resulting signature value (r, s) is used as | |||
signature verification function. The results of the verification | input to the signature verification function. The results of the | |||
function indicate if the signature presented is valid. | verification function indicate whether the signature presented is | |||
valid. | ||||
Note that the output of ECDSA algorithms are non-deterministic, and | Note that the output of ECDSA signature algorithms is non- | |||
therefore it is not correct to re-calculate a new signature on the | deterministic; therefore, it is not correct to recalculate a new | |||
signature base and compare the results to an existing signature. | signature on the signature base and compare the results to an | |||
Instead, the verification algorithm defined here needs to be used. | existing signature. Instead, the verification algorithm defined here | |||
See Section 7.3.5. | needs to be used. See Section 7.3.5. | |||
Use of this algorithm can be indicated at runtime using the ecdsa- | The use of this algorithm can be indicated at runtime using the | |||
p384-sha384 value for the alg signature parameter. | ecdsa-p384-sha384 value for the alg signature parameter. | |||
3.3.6. EdDSA using curve edwards25519 | 3.3.6. EdDSA Using Curve edwards25519 | |||
To sign using this algorithm, the signer applies the Ed25519 | To sign using this algorithm, the signer applies the Ed25519 | |||
algorithm defined in Section 5.1.6 of [RFC8032] with the signer's | algorithm defined in Section 5.1.6 of [RFC8032] with the signer's | |||
private signing key and the signature base (Section 2.5). The | private signing key and the signature base (Section 2.5). The | |||
signature base is taken as the input message (M) with no pre-hash | signature base is taken as the input message (M) with no prehash | |||
function. The signature is a 64-octet concatenation of R and S as | function. The signature is a 64-octet concatenation of R and S as | |||
specified in Section 5.1.6 of [RFC8032], and this is taken as a byte | specified in Section 5.1.6 of [RFC8032], and this is taken as a byte | |||
array for the HTTP message signature output used in Section 3.1. | array for the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the signer applies the Ed25519 | To verify using this algorithm, the signer applies the Ed25519 | |||
algorithm defined in Section 5.1.7 of [RFC8032] using the public key | algorithm defined in Section 5.1.7 of [RFC8032] using the public key | |||
portion of the verification key material (A) and the signature base | portion of the verification key material (A) and the signature base | |||
re-created as described in Section 3.2. The signature base is taken | recreated as described in Section 3.2. The signature base is taken | |||
as the input message (M) with no pre-hash function. The signature to | as the input message (M) with no prehash function. The signature to | |||
be verified is processed as the 64-octet concatenation of R and S as | be verified is processed as the 64-octet concatenation of R and S as | |||
specified in Section 5.1.7 of [RFC8032]. The results of the | specified in Section 5.1.7 of [RFC8032]. The results of the | |||
verification function indicate if the signature presented is valid. | verification function indicate whether the signature presented is | |||
valid. | ||||
Use of this algorithm can be indicated at runtime using the ed25519 | The use of this algorithm can be indicated at runtime using the | |||
value for the alg signature parameter. | ed25519 value for the alg signature parameter. | |||
3.3.7. JSON Web Signature (JWS) algorithms | 3.3.7. JSON Web Signature (JWS) Algorithms | |||
If the signing algorithm is a JOSE signing algorithm from the JSON | If the signing algorithm is a JSON Object Signing and Encryption | |||
Web Signature and Encryption Algorithms Registry established by | (JOSE) signing algorithm from the "JSON Web Signature and Encryption | |||
[RFC7518], the JWS algorithm definition determines the signature and | Algorithms" registry established by [RFC7518], the JWS algorithm | |||
hashing algorithms to apply for both signing and verification. | definition determines the signature and hashing algorithms to apply | |||
for both signing and verification. | ||||
For both signing and verification, the HTTP messages signature base | For both signing and verification, the HTTP message's signature base | |||
(Section 2.5) is used as the entire "JWS Signing Input". The JOSE | (Section 2.5) is used as the entire "JWS Signing Input". The JOSE | |||
Header defined in [RFC7517] is not used, and the signature base is | Header [JWS] [RFC7517] is not used, and the signature base is not | |||
not first encoded in Base64 before applying the algorithm. The | first encoded in Base64 before applying the algorithm. The output of | |||
output of the JWS signature is taken as a byte array prior to the | the JWS Signature is taken as a byte array prior to the Base64url | |||
Base64url encoding used in JOSE. | encoding used in JOSE. | |||
The JWS algorithm MUST NOT be none and MUST NOT be any algorithm with | The JWS algorithm MUST NOT be "none" and MUST NOT be any algorithm | |||
a JOSE Implementation Requirement of Prohibited. | with a JOSE Implementation Requirement of "Prohibited". | |||
JWA algorithm values from the JSON Web Signature and Encryption | JSON Web Algorithm (JWA) values from the "JSON Web Signature and | |||
Algorithms Registry are not included as signature parameters. | Encryption Algorithms" registry are not included as signature | |||
Typically, the JWS algorithm can be signaled using JSON Web Keys or | parameters. Typically, the JWS algorithm can be signaled using JSON | |||
other mechanisms common to JOSE implementations. In fact, JWA | Web Keys (JWKs) or other mechanisms common to JOSE implementations. | |||
algorithm values are not registered in the HTTP Signature Algorithms | In fact, JWA values are not registered in the "HTTP Signature | |||
registry (Section 6.2), and so the explicit alg signature parameter | Algorithms" registry (Section 6.2), and so the explicit alg signature | |||
is not used at all when using JOSE signing algorithms. | parameter is not used at all when using JOSE signing algorithms. | |||
4. Including a Message Signature in a Message | 4. Including a Message Signature in a Message | |||
HTTP message signatures can be included within an HTTP message via | HTTP message signatures can be included within an HTTP message via | |||
the Signature-Input and Signature fields, both defined within this | the Signature-Input and Signature fields, both defined within this | |||
specification. | specification. | |||
The Signature-Input field identifies the covered components and | The Signature-Input field identifies the covered components and | |||
parameters that describe how the signature was generated, while the | parameters that describe how the signature was generated, while the | |||
Signature field contains the signature value. Each field MAY contain | Signature field contains the signature value. Each field MAY contain | |||
multiple labeled values. | multiple labeled values. | |||
An HTTP message signature is identified by a label within an HTTP | An HTTP message signature is identified by a label within an HTTP | |||
message. This label MUST be unique within a given HTTP message and | message. This label MUST be unique within a given HTTP message and | |||
MUST be used in both the Signature-Input and Signature fields. The | MUST be used in both the Signature-Input field and the Signature | |||
label is chosen by the signer, except where a specific label is | field. The label is chosen by the signer, except where a specific | |||
dictated by protocol negotiations such as described in Section 5. | label is dictated by protocol negotiations such as those described in | |||
Section 5. | ||||
An HTTP message signature MUST use both Signature-Input and Signature | An HTTP message signature MUST use both the Signature-Input field and | |||
fields and each field MUST contain the same labels. The presence of | the Signature field, and each field MUST contain the same labels. | |||
a label in one field but not in the other is an error. | The presence of a label in one field but not the other is an error. | |||
4.1. The Signature-Input HTTP Field | 4.1. The Signature-Input HTTP Field | |||
The Signature-Input field is a Dictionary structured field (defined | The Signature-Input field is a Dictionary Structured Field (defined | |||
in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for | in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for | |||
one or more message signatures generated from components within the | one or more message signatures generated from components within the | |||
HTTP message. Each member describes a single message signature. The | HTTP message. Each member describes a single message signature. The | |||
member's key is the label that uniquely identifies the message | member's key is the label that uniquely identifies the message | |||
signature within the HTTP message. The member's value is the | signature within the HTTP message. The member's value is the covered | |||
serialization of the covered components Inner List plus all signature | components ordered set serialized as an Inner List, including all | |||
metadata parameters identified by the label. | signature metadata parameters identified by the label: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@method" "@target-uri" "@authority" \ | Signature-Input: sig1=("@method" "@target-uri" "@authority" \ | |||
"content-digest" "cache-control");\ | "content-digest" "cache-control");\ | |||
created=1618884475;keyid="test-key-rsa-pss" | created=1618884475;keyid="test-key-rsa-pss" | |||
To facilitate signature validation, the Signature-Input field value | To facilitate signature validation, the Signature-Input field value | |||
MUST contain the same serialized value used in generating the | MUST contain the same serialized value used in generating the | |||
signature base's @signature-params value defined in Section 2.3. | signature base's @signature-params value defined in Section 2.3. | |||
Note that in a structured field value, list order and parameter order | Note that in a Structured Field value, list order and parameter order | |||
have to be preserved. | have to be preserved. | |||
The signer MAY include the Signature-Input field as a trailer to | The signer MAY include the Signature-Input field as a trailer to | |||
facilitate signing a message after its content has been processed by | facilitate signing a message after its content has been processed by | |||
the signer. However, since intermediaries are allowed to drop | the signer. However, since intermediaries are allowed to drop | |||
trailers as per [HTTP], it is RECOMMENDED that the Signature-Input | trailers as per [HTTP], it is RECOMMENDED that the Signature-Input | |||
field be included only as a header to avoid signatures being | field be included only as a header field to avoid signatures being | |||
inadvertently stripped from a message. | inadvertently stripped from a message. | |||
Multiple Signature-Input fields MAY be included in a single HTTP | Multiple Signature-Input fields MAY be included in a single HTTP | |||
message. The signature labels MUST be unique across all field | message. The signature labels MUST be unique across all field | |||
values. | values. | |||
4.2. The Signature HTTP Field | 4.2. The Signature HTTP Field | |||
The Signature field is a Dictionary structured field defined in | The Signature field is a Dictionary Structured Field (defined in | |||
Section 3.2 of [STRUCTURED-FIELDS] containing one or more message | Section 3.2 of [STRUCTURED-FIELDS]) containing one or more message | |||
signatures generated from the signature context of the target | signatures generated from the signature context of the target | |||
message. The member's key is the label that uniquely identifies the | message. The member's key is the label that uniquely identifies the | |||
message signature within the HTTP message. The member's value is a | message signature within the HTTP message. The member's value is a | |||
Byte Sequence containing the signature value for the message | Byte Sequence containing the signature value for the message | |||
signature identified by the label. | signature identified by the label: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHz\ | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHz\ | |||
C87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8\ | C87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8\ | |||
gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58Rmp\ | gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58Rmp\ | |||
Z+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxA\ | Z+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxA\ | |||
BNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | BNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | |||
The signer MAY include the Signature field as a trailer to facilitate | The signer MAY include the Signature field as a trailer to facilitate | |||
signing a message after its content has been processed by the signer. | signing a message after its content has been processed by the signer. | |||
However, since intermediaries are allowed to drop trailers as per | However, since intermediaries are allowed to drop trailers as per | |||
[HTTP], it is RECOMMENDED that the Signature field be included only | [HTTP], it is RECOMMENDED that the Signature field be included only | |||
as a header to avoid signatures being inadvertently stripped from a | as a header field to avoid signatures being inadvertently stripped | |||
message. | from a message. | |||
Multiple Signature fields MAY be included in a single HTTP message. | Multiple Signature fields MAY be included in a single HTTP message. | |||
The signature labels MUST be unique across all field values. | The signature labels MUST be unique across all field values. | |||
4.3. Multiple Signatures | 4.3. Multiple Signatures | |||
Multiple distinct signatures MAY be included in a single message. | Multiple distinct signatures MAY be included in a single message. | |||
Each distinct signature MUST have a unique label. These multiple | Each distinct signature MUST have a unique label. These multiple | |||
signatures could be added all by the same signer or could come from | signatures could all be added by the same signer, or they could come | |||
several different signers. For example, a signer may include | from several different signers. For example, a signer may include | |||
multiple signatures signing the same message components with | multiple signatures signing the same message components with | |||
different keys or algorithms to support verifiers with different | different keys or algorithms to support verifiers with different | |||
capabilities, or a reverse proxy may include information about the | capabilities, or a reverse proxy may include information about the | |||
client in fields when forwarding the request to a service host, | client in fields when forwarding the request to a service host, | |||
including a signature over the client's original signature values. | including a signature over the client's original signature values. | |||
The following non-normative example starts with a signed request from | The following non-normative example starts with a signed request from | |||
the client. A reverse proxy takes this request and validates the | the client. A reverse proxy takes this request and validates the | |||
client's signature. | client's signature: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Signature-Input: sig1=("@method" "@authority" "@path" \ | Signature-Input: sig1=("@method" "@authority" "@path" \ | |||
"content-digest" "content-type" "content-length")\ | "content-digest" "content-type" "content-length")\ | |||
;created=1618884475;keyid="test-key-ecc-p256" | ;created=1618884475;keyid="test-key-ecc-p256" | |||
Signature: sig1=:X5spyd6CFnAG5QnDyHfqoSNICd+BUP4LYMz2Q0JXlb//4Ijpzp\ | Signature: sig1=:X5spyd6CFnAG5QnDyHfqoSNICd+BUP4LYMz2Q0JXlb//4Ijpzp\ | |||
+kve2w4NIyqeAuM7jTDX+sNalzA8ESSaHD3A==: | +kve2w4NIyqeAuM7jTDX+sNalzA8ESSaHD3A==: | |||
{"hello": "world"} | {"hello": "world"} | |||
The proxy then alters the message before forwarding it on to the | The proxy then alters the message before forwarding it on to the | |||
origin server, changing the target host and adding the Forwarded | origin server, changing the target host and adding the Forwarded | |||
header field defined in [RFC7239]. | header field defined in [RFC7239]: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: origin.host.internal.example | Host: origin.host.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Forwarded: for=192.0.2.123;host=example.com;proto=https | Forwarded: for=192.0.2.123;host=example.com;proto=https | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
skipping to change at page 56, line 51 ¶ | skipping to change at line 2604 ¶ | |||
{"hello": "world"} | {"hello": "world"} | |||
The proxy is in a position to validate the incoming client's | The proxy is in a position to validate the incoming client's | |||
signature and make its own statement to the origin server about the | signature and make its own statement to the origin server about the | |||
nature of the request that it is forwarding by adding its own | nature of the request that it is forwarding by adding its own | |||
signature over the new message before passing it along to the origin | signature over the new message before passing it along to the origin | |||
server. The proxy also includes all the elements from the original | server. The proxy also includes all the elements from the original | |||
message that are relevant to the origin server's processing. In many | message that are relevant to the origin server's processing. In many | |||
cases, the proxy will want to cover all the same components that were | cases, the proxy will want to cover all the same components that were | |||
covered by the client's signature, which is the case in this example. | covered by the client's signature, which is the case in the following | |||
Note that in this example, the proxy is signing over the new | example. Note that in this example, the proxy is signing over the | |||
authority value, which it has changed. The proxy also adds the | new authority value, which it has changed. The proxy also adds the | |||
Forwarded header to its own signature value. The proxy identifies | Forwarded header field to its own signature value. The proxy | |||
its own key and algorithm and, in this example, includes an | identifies its own key and algorithm and, in this example, includes | |||
expiration for the signature to indicate to downstream systems that | an expiration for the signature to indicate to downstream systems | |||
the proxy will not vouch for this signed message past this short time | that the proxy will not vouch for this signed message past this short | |||
window. This results in a signature base of: | time window. This results in a signature base of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@method": POST | "@method": POST | |||
"@authority": origin.host.internal.example | "@authority": origin.host.internal.example | |||
"@path": /foo | "@path": /foo | |||
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"content-type": application/json | "content-type": application/json | |||
"content-length": 18 | "content-length": 18 | |||
"forwarded": for=192.0.2.123;host=example.com;proto=https | "forwarded": for=192.0.2.123;host=example.com;proto=https | |||
"@signature-params": ("@method" "@authority" "@path" \ | "@signature-params": ("@method" "@authority" "@path" \ | |||
"content-digest" "content-type" "content-length" "forwarded")\ | "content-digest" "content-type" "content-length" "forwarded")\ | |||
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256"\ | ;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256"\ | |||
;expires=1618884540 | ;expires=1618884540 | |||
And a signature output value of: | and a signature output value of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+JH+8XY1I6+8Cy\ | S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+JH+8XY1I6+8Cy\ | |||
+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49GwiyUpZ10KHgOEe11s\ | +CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49GwiyUpZ10KHgOEe11s\ | |||
x3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7LB5YAv0RAGhB8tmpv7sFn\ | x3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7LB5YAv0RAGhB8tmpv7sFn\ | |||
Im9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtflzvZdXAsD3LH2TwevU+/PBPv0\ | Im9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtflzvZdXAsD3LH2TwevU+/PBPv0\ | |||
B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbLVdp770I6VHR6WfgS9ddzirrswsE1w\ | B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbLVdp770I6VHR6WfgS9ddzirrswsE1w\ | |||
5o0LV/g== | 5o0LV/g== | |||
These values are added to the HTTP request message by the proxy. The | These values are added to the HTTP request message by the proxy. The | |||
original signature is included under the identifier sig1, and the | original signature is included under the label sig1, and the reverse | |||
reverse proxy's signature is included under the label proxy_sig. The | proxy's signature is included under the label proxy_sig. The proxy | |||
proxy uses the key test-key-rsa to create its signature using the | uses the key test-key-rsa to create its signature using the rsa- | |||
rsa-v1_5-sha256 signature algorithm, while the client's original | v1_5-sha256 signature algorithm, while the client's original | |||
signature was made using the key id of test-key-rsa-pss and an RSA | signature was made using the key test-key-rsa-pss and an RSA-PSS | |||
PSS signature algorithm. | signature algorithm: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: origin.host.internal.example | Host: origin.host.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Forwarded: for=192.0.2.123;host=example.com;proto=https | Forwarded: for=192.0.2.123;host=example.com;proto=https | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
skipping to change at page 58, line 34 ¶ | skipping to change at line 2676 ¶ | |||
proxy_sig=:S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+\ | proxy_sig=:S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+\ | |||
JH+8XY1I6+8Cy+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49G\ | JH+8XY1I6+8Cy+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49G\ | |||
wiyUpZ10KHgOEe11sx3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7\ | wiyUpZ10KHgOEe11sx3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7\ | |||
LB5YAv0RAGhB8tmpv7sFnIm9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtf\ | LB5YAv0RAGhB8tmpv7sFnIm9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtf\ | |||
lzvZdXAsD3LH2TwevU+/PBPv0B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbL\ | lzvZdXAsD3LH2TwevU+/PBPv0B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbL\ | |||
Vdp770I6VHR6WfgS9ddzirrswsE1w5o0LV/g==: | Vdp770I6VHR6WfgS9ddzirrswsE1w5o0LV/g==: | |||
{"hello": "world"} | {"hello": "world"} | |||
While the proxy could additionally include the client's Signature | While the proxy could additionally include the client's Signature | |||
value and Signature-Input fields from the original message in the new | field value and Signature-Input fields from the original message in | |||
signature's covered components, this practice is NOT RECOMMENDED due | the new signature's covered components, this practice is NOT | |||
to known weaknesses in signing signature values as discussed in | RECOMMENDED due to known weaknesses in signing signature values as | |||
Section 7.3.7. The proxy is in a position to validate the client's | discussed in Section 7.3.7. The proxy is in a position to validate | |||
signature, the changes the proxy makes to the message will invalidate | the client's signature; the changes the proxy makes to the message | |||
the existing signature when the message is seen by the origin server. | will invalidate the existing signature when the message is seen by | |||
In this example, it is possible for the origin server to have | the origin server. In this example, it is possible for the origin | |||
additional information in its signature context to account for the | server to have additional information in its signature context to | |||
change in authority, though this practice requires additional | account for the change in authority, though this practice requires | |||
configuration and extra care as discussed in Section 7.4.4. In other | additional configuration and extra care as discussed in | |||
applications, the origin server will not be able to verify the | Section 7.4.4. In other applications, the origin server will not be | |||
original signature itself but will still want to verify that the | able to verify the original signature itself but will still want to | |||
proxy has done the appropriate validation of the client's signature. | verify that the proxy has done the appropriate validation of the | |||
An application that needs to signal successful processing or receipt | client's signature. An application that needs to signal successful | |||
of a signature would need to carefully specify alternative mechanisms | processing or receipt of a signature would need to carefully specify | |||
for sending such a signal securely. | alternative mechanisms for sending such a signal securely. | |||
5. Requesting Signatures | 5. Requesting Signatures | |||
While a signer is free to attach a signature to a request or response | While a signer is free to attach a signature to a request or response | |||
without prompting, it is often desirable for a potential verifier to | without prompting, it is often desirable for a potential verifier to | |||
signal that it expects a signature from a potential signer using the | signal that it expects a signature from a potential signer using the | |||
Accept-Signature field. | Accept-Signature field. | |||
When the Accept-Signature field is sent in an HTTP request message, | When the Accept-Signature field is sent in an HTTP request message, | |||
the field indicates that the client desires the server to sign the | the field indicates that the client desires the server to sign the | |||
skipping to change at page 59, line 29 ¶ | skipping to change at line 2717 ¶ | |||
for a different request. | for a different request. | |||
When the Accept-Signature field is used in an HTTP response message, | When the Accept-Signature field is used in an HTTP response message, | |||
the field indicates that the server desires the client to sign its | the field indicates that the server desires the client to sign its | |||
next request to the server with the identified parameters, and the | next request to the server with the identified parameters, and the | |||
target message is the client's next request. The client can choose | target message is the client's next request. The client can choose | |||
to also continue signing future requests to the same server in the | to also continue signing future requests to the same server in the | |||
same way. | same way. | |||
The target message of an Accept-Signature field MUST include all | The target message of an Accept-Signature field MUST include all | |||
labeled signatures indicated in the Accept-Header signature, each | labeled signatures indicated in the Accept-Signature field, each | |||
covering the same identified components of the Accept-Signature | covering the same identified components of the Accept-Signature | |||
field. | field. | |||
The sender of an Accept-Signature field MUST include only identifiers | The sender of an Accept-Signature field MUST include only identifiers | |||
that are appropriate for the type of the target message. For | that are appropriate for the type of the target message. For | |||
example, if the target message is a request, the covered components | example, if the target message is a request, the covered components | |||
can not include the @status component identifier. | cannot include the @status component identifier. | |||
5.1. The Accept-Signature Field | 5.1. The Accept-Signature Field | |||
The Accept-Signature field is a Dictionary structured field (defined | The Accept-Signature field is a Dictionary Structured Field (defined | |||
in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for | in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for | |||
one or more requested message signatures to be generated from message | one or more requested message signatures to be generated from message | |||
components of the target HTTP message. Each member describes a | components of the target HTTP message. Each member describes a | |||
single message signature. The member's key is the label that | single message signature. The member's key is the label that | |||
uniquely identifies the requested message signature within the | uniquely identifies the requested message signature within the | |||
context of the target HTTP message. | context of the target HTTP message. | |||
The member's value is the serialization of the desired covered | The member's value is the serialization of the desired covered | |||
components of the target message, including any allowed component | components of the target message, including any allowed component | |||
metadata parameters, using the serialization process defined in | metadata parameters, using the serialization process defined in | |||
Section 2.3. | Section 2.3: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Accept-Signature: sig1=("@method" "@target-uri" "@authority" \ | Accept-Signature: sig1=("@method" "@target-uri" "@authority" \ | |||
"content-digest" "cache-control");\ | "content-digest" "cache-control");\ | |||
keyid="test-key-rsa-pss";created;tag="app-123" | keyid="test-key-rsa-pss";created;tag="app-123" | |||
The list of component identifiers indicates the exact set of | The list of component identifiers indicates the exact set of | |||
component identifiers to be included in the requested signature, | component identifiers to be included in the requested signature, | |||
including all applicable component parameters. | including all applicable component parameters. | |||
The signature request MAY include signature metadata parameters that | The signature request MAY include signature metadata parameters that | |||
indicate desired behavior for the signer. The following behavior is | indicate desired behavior for the signer. The following behavior is | |||
defined by this specification: | defined by this specification: | |||
* created: The signer is requested to generate and include a | created: The signer is requested to generate and include a creation | |||
creation time. This parameter has no associated value when sent | time. This parameter has no associated value when sent as a | |||
as a signature request. | signature request. | |||
* expires: The signer is requested to generate and include an | expires: The signer is requested to generate and include an | |||
expiration time. This parameter has no associated value when sent | expiration time. This parameter has no associated value when sent | |||
as a signature request. | as a signature request. | |||
* nonce: The signer is requested to include the value of this | nonce: The signer is requested to include the value of this | |||
parameter as the signature nonce in the target signature. | parameter as the signature nonce in the target signature. | |||
* alg: The signer is requested to use the indicated signature | alg: The signer is requested to use the indicated signature | |||
algorithm from the HTTP Signature Algorithms Registry to create | algorithm from the "HTTP Signature Algorithms" registry to create | |||
the target signature. | the target signature. | |||
* keyid: The signer is requested to use the indicated key material | keyid: The signer is requested to use the indicated key material to | |||
to create the target signature. | create the target signature. | |||
* tag: The signer is requested to include the value of this | tag: The signer is requested to include the value of this parameter | |||
parameter as the signature tag in the target signature. | as the signature tag in the target signature. | |||
5.2. Processing an Accept-Signature | 5.2. Processing an Accept-Signature | |||
The receiver of an Accept-Signature field fulfills that header as | The receiver of an Accept-Signature field fulfills that header as | |||
follows: | follows: | |||
1. Parse the field value as a Dictionary | 1. Parse the field value as a Dictionary. | |||
2. For each member of the dictionary: | 2. For each member of the Dictionary: | |||
1. The key is taken as the label of the output signature as | 2.1. The key is taken as the label of the output signature as | |||
specified in Section 4.1. | specified in Section 4.1. | |||
2. Parse the value of the member to obtain the set of covered | 2.2. Parse the value of the member to obtain the set of covered | |||
component identifiers. | component identifiers. | |||
3. Determine that the covered components are applicable to the | 2.3. Determine that the covered components are applicable to the | |||
target message. If not, the process fails and returns an | target message. If not, the process fails and returns an | |||
error. | error. | |||
4. Process the requested parameters, such as the signing | 2.4. Process the requested parameters, such as the signing | |||
algorithm and key material. If any requested parameters | algorithm and key material. If any requested parameters | |||
cannot be fulfilled, or if the requested parameters conflict | cannot be fulfilled or if the requested parameters conflict | |||
with those deemed appropriate to the target message, the | with those deemed appropriate to the target message, the | |||
process fails and returns an error. | process fails and returns an error. | |||
5. Select and generate any additional parameters necessary for | 2.5. Select and generate any additional parameters necessary for | |||
completing the signature. | completing the signature. | |||
6. Create the HTTP message signature over the target message. | 2.6. Create the HTTP message signature over the target message. | |||
7. Create the Signature-Input and Signature values and associate | 2.7. Create the Signature-Input and Signature field values, and | |||
them with the label. | associate them with the label. | |||
3. Optionally create any additional Signature-Input and Signature | 3. Optionally create any additional Signature-Input and Signature | |||
values, with unique labels not found in the Accept-Signature | field values, with unique labels not found in the Accept- | |||
field. | Signature field. | |||
4. Combine all labeled Signature-Input and Signature values and | 4. Combine all labeled Signature-Input and Signature field values, | |||
attach both fields to the target message. | and attach both fields to the target message. | |||
By this process, a signature applied to a target message MUST have | By this process, a signature applied to a target message MUST have | |||
the same label, MUST include the same set of covered component, MUST | the same label, MUST include the same set of covered components, MUST | |||
process all requested parameters, and MAY have additional parameters. | process all requested parameters, and MAY have additional parameters. | |||
The receiver of an Accept-Signature field MAY ignore any signature | The receiver of an Accept-Signature field MAY ignore any signature | |||
request that does not fit application parameters. | request that does not fit application parameters. | |||
The target message MAY include additional signatures not specified by | The target message MAY include additional signatures not specified by | |||
the Accept-Signature field. For example, to cover additional message | the Accept-Signature field. For example, to cover additional message | |||
components, the signer can create a second signature that includes | components, the signer can create a second signature that includes | |||
the additional components as well as the signature output of the | the additional components as well as the signature output of the | |||
requested signature. | requested signature. | |||
6. IANA Considerations | 6. IANA Considerations | |||
IANA is asked to update one registry and create four new registries, | IANA has updated one registry and created four new registries, | |||
according to the following sections. | according to the following sections. | |||
6.1. HTTP Field Name Registration | 6.1. HTTP Field Name Registration | |||
IANA is asked to update the "Hypertext Transfer Protocol (HTTP) Field | IANA has updated the entries in the "Hypertext Transfer Protocol | |||
Name Registry" registry, registering the following entries according | (HTTP) Field Name Registry" as follows: | |||
to the table below: | ||||
+==================+===========+=========================+ | +==================+===========+=========================+ | |||
| Field Name | Status | Reference | | | Field Name | Status | Reference | | |||
+==================+===========+=========================+ | +==================+===========+=========================+ | |||
| Signature-Input | permanent | Section 4.1 of RFC nnnn | | | Signature-Input | permanent | Section 4.1 of RFC 9421 | | |||
+------------------+-----------+-------------------------+ | +------------------+-----------+-------------------------+ | |||
| Signature | permanent | Section 4.2 of RFC nnnn | | | Signature | permanent | Section 4.2 of RFC 9421 | | |||
+------------------+-----------+-------------------------+ | +------------------+-----------+-------------------------+ | |||
| Accept-Signature | permanent | Section 5.1 of RFC nnnn | | | Accept-Signature | permanent | Section 5.1 of RFC 9421 | | |||
+------------------+-----------+-------------------------+ | +------------------+-----------+-------------------------+ | |||
Table 1 | Table 1: Updates to the Hypertext Transfer Protocol | |||
(HTTP) Field Name Registry | ||||
6.2. HTTP Signature Algorithms Registry | 6.2. HTTP Signature Algorithms Registry | |||
This document defines HTTP Signature Algorithms, for which IANA is | This document defines HTTP signature algorithms, for which IANA has | |||
asked to create and maintain a new registry titled "HTTP Signature | created and now maintains a new registry titled "HTTP Signature | |||
Algorithms". Initial values for this registry are given in | Algorithms". Initial values for this registry are given in | |||
Section 6.2.2. Future assignments and modifications to existing | Section 6.2.2. Future assignments and modifications to existing | |||
assignment are to be made through the Specification Required | assignments are to be made through the Specification Required | |||
registration policy [RFC8126]. | registration policy [RFC8126]. | |||
The algorithms listed in this registry identify some possible | The algorithms listed in this registry identify some possible | |||
cryptographic algorithms for applications to use with this | cryptographic algorithms for applications to use with this | |||
specification, but the entries neither represent an exhaustive list | specification, but the entries neither represent an exhaustive list | |||
of possible algorithms nor indicate fitness for purpose with any | of possible algorithms nor indicate fitness for purpose with any | |||
particular application of this specification. An application is free | particular application of this specification. An application is free | |||
to implement any algorithm that suits its needs, provided the signer | to implement any algorithm that suits its needs, provided the signer | |||
and verifier can agree to the parameters of that algorithm in a | and verifier can agree to the parameters of that algorithm in a | |||
secure and deterministic fashion. When an application has a need to | secure and deterministic fashion. When an application needs to | |||
signal the use of a particular algorithm at runtime using the alg | signal the use of a particular algorithm at runtime using the alg | |||
signature parameter, this registry provides a mapping between the | signature parameter, this registry provides a mapping between the | |||
value of that parameter to a particular algorithm. However, use of | value of that parameter and a particular algorithm. However, the use | |||
the alg parameter needs to be treated with caution to avoid various | of the alg parameter needs to be treated with caution to avoid | |||
forms of algorithm confusion and substitution attacks, such as | various forms of algorithm confusion and substitution attacks, as | |||
discussed in Section 7.3.6 and others. | discussed in Section 7. | |||
The Status value should reflect standardization status and the broad | The Status value should reflect standardization status and the broad | |||
opinion of relevant interest groups such as the IETF or security- | opinion of relevant interest groups such as the IETF or security- | |||
related SDOs. When an algorithm is first registered, the Designated | related Standards Development Organizations (SDOs). When an | |||
Expert (DE) should set the Status field to "Active" if there is | algorithm is first registered, the designated expert (DE) should set | |||
consensus for the algorithm to be generally recommended as secure or | the Status field to "Active" if there is consensus for the algorithm | |||
"Provisional" if the algorithm has not reached that consensus, such | to be generally recommended as secure or "Provisional" if the | |||
as for an experimental algorithm. A status of "Provisional" does not | algorithm has not reached that consensus, e.g., for an experimental | |||
mean that the algorithm is known to be insecure, but instead | algorithm. A status of "Provisional" does not mean that the | |||
indicates that the algorithm has not reached consensus regarding its | algorithm is known to be insecure but instead indicates that the | |||
properties. If at a future time the algorithm as registered is found | algorithm has not reached consensus regarding its properties. If at | |||
to have flaws, the registry entry can be updated and the algorithm | a future time the algorithm as registered is found to have flaws, the | |||
can be marked as "Deprecated" to indicate that the algorithm has been | registry entry can be updated and the algorithm can be marked as | |||
found to have problems. This status does not preclude an application | "Deprecated" to indicate that the algorithm has been found to have | |||
from using a particular algorithm, but serves to provide warning of | problems. This status does not preclude an application from using a | |||
possible known issues with an algorithm that need to be considered by | particular algorithm; rather, it serves to provide a warning | |||
the application. The DE can further ensure that the registration | regarding possible known issues with an algorithm that need to be | |||
includes an explanation and reference for the Status value, which is | considered by the application. The DE can further ensure that the | |||
particularly important for deprecated algorithms. | registration includes an explanation and reference for the Status | |||
value; this is particularly important for deprecated algorithms. | ||||
The DE is expected to ensure that the algorithms referenced by a | The DE is expected to do the following: | |||
registered algorithm identifier are fully defined with all parameters | ||||
(such as salt, hash, required key length, etc) fixed by the defining | * Ensure that the algorithms referenced by a registered algorithm | |||
text. The DE is expected to ensure that the algorithm definition | identifier are fully defined with all parameters (e.g., salt, | |||
fully specifies the HTTP_SIGN and HTTP_VERIFY primitive functions, | hash, required key length) fixed by the defining text. | |||
including how all defined inputs and outputs map to the underlying | ||||
cryptographic algorithm. The DE is expected to reject any | * Ensure that the algorithm definition fully specifies the HTTP_SIGN | |||
registrations that are aliases of existing registrations. The DE is | and HTTP_VERIFY primitive functions, including how all defined | |||
expected to ensure all registrations follow the template presented in | inputs and outputs map to the underlying cryptographic algorithm. | |||
Section 6.2.1, including that the length of the name is not excessive | ||||
while still being unique and recognizable. | * Reject any registrations that are aliases of existing | |||
registrations. | ||||
* Ensure that all registrations follow the template presented in | ||||
Section 6.2.1; this includes ensuring that the length of the name | ||||
is not excessive while still being unique and recognizable. | ||||
This specification creates algorithm identifiers by including major | This specification creates algorithm identifiers by including major | |||
parameters in the identifier string in order to make the algorithm | parameters in the identifier String in order to make the algorithm | |||
name unique and recognizable by developers. However, algorithm | name unique and recognizable by developers. However, algorithm | |||
identifiers in this registry are to be interpreted as whole string | identifiers in this registry are to be interpreted as whole String | |||
values and not as a combination of parts. That is to say, it is | values and not as a combination of parts. That is to say, it is | |||
expected that implementors understand rsa-pss-sha512 as referring to | expected that implementors understand rsa-pss-sha512 as referring to | |||
one specific algorithm with its hash, mask, and salt values set as | one specific algorithm with its hash, mask, and salt values set as | |||
defined in the defining text that establishes this identifier. | defined in the defining text that establishes the identifier in | |||
Implementors do not parse out the rsa, pss, and sha512 portions of | question. Implementors do not parse out the rsa, pss, and sha512 | |||
the identifier to determine parameters of the signing algorithm from | portions of the identifier to determine parameters of the signing | |||
the string, and the registry of one combination of parameters does | algorithm from the String, and the registration of one combination of | |||
not imply the registration of other combinations. | parameters does not imply the registration of other combinations. | |||
6.2.1. Registration Template | 6.2.1. Registration Template | |||
Algorithm Name: | Algorithm Name: | |||
An identifier for the HTTP Signature Algorithm. The name MUST be | An identifier for the HTTP signature algorithm. The name MUST be | |||
an ASCII string that conforms to the sf-string ABNF rule in | an ASCII string that conforms to the sf-string ABNF rule in | |||
Section 3.3.3 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 | Section 3.3.3 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 | |||
characters in length. The identifier MUST be unique within the | characters in length. The identifier MUST be unique within the | |||
context of the registry. | context of the registry. | |||
Description: | Description: | |||
A brief description of the algorithm used to sign the signature | A brief description of the algorithm used to sign the signature | |||
base. | base. | |||
Status: | Status: | |||
The status of the algorithm. MUST start with one of the following | The status of the algorithm. MUST start with one of the following | |||
values and MAY contain additional explanatory text. The options | values and MAY contain additional explanatory text. The options | |||
are: - "Active": for algorithms without known problems. The | are: | |||
signature algorithm is fully specified and its security properties | ||||
are understood. - "Provisional": for unproven algorithms. The | ||||
signature algorithm is fully specified but its security properties | ||||
are not known or proven. - "Deprecated": for algorithms with know | ||||
security issues. The signature algorithm is no longer recommended | ||||
for general use and might be insecure or unsafe in some known | ||||
circumstances. | ||||
Specification document(s): | "Active": For algorithms without known problems. The signature | |||
Reference to the document(s) that specify the algorithm, | algorithm is fully specified, and its security properties are | |||
understood. | ||||
"Provisional": For unproven algorithms. The signature algorithm | ||||
is fully specified, but its security properties are not known | ||||
or proven. | ||||
"Deprecated": For algorithms with known security issues. The | ||||
signature algorithm is no longer recommended for general use | ||||
and might be insecure or unsafe in some known circumstances. | ||||
Reference: | ||||
Reference to the document or documents that specify the algorithm, | ||||
preferably including a URI that can be used to retrieve a copy of | preferably including a URI that can be used to retrieve a copy of | |||
the document(s). An indication of the relevant sections may also | the document(s). An indication of the relevant sections may also | |||
be included but is not required. | be included but is not required. | |||
6.2.2. Initial Contents | 6.2.2. Initial Contents | |||
The table below contains the initial contents of the "HTTP Signature | ||||
Algorithms" registry. | ||||
+===================+===================+========+===============+ | +===================+===================+========+===============+ | |||
| Algorithm Name | Description | Status | Specification | | | Algorithm Name | Description | Status | Reference | | |||
| | | | document(s) | | ||||
+===================+===================+========+===============+ | +===================+===================+========+===============+ | |||
| rsa-pss-sha512 | RSASSA-PSS using | Active | Section 3.3.1 | | | rsa-pss-sha512 | RSASSA-PSS using | Active | Section 3.3.1 | | |||
| | SHA-512 | | of RFC nnnn | | | | SHA-512 | | of RFC 9421 | | |||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
| rsa-v1_5-sha256 | RSASSA-PKCS1-v1_5 | Active | Section 3.3.2 | | | rsa-v1_5-sha256 | RSASSA-PKCS1-v1_5 | Active | Section 3.3.2 | | |||
| | using SHA-256 | | of RFC nnnn | | | | using SHA-256 | | of RFC 9421 | | |||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
| hmac-sha256 | HMAC using | Active | Section 3.3.3 | | | hmac-sha256 | HMAC using | Active | Section 3.3.3 | | |||
| | SHA-256 | | of RFC nnnn | | | | SHA-256 | | of RFC 9421 | | |||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
| ecdsa-p256-sha256 | ECDSA using curve | Active | Section 3.3.4 | | | ecdsa-p256-sha256 | ECDSA using curve | Active | Section 3.3.4 | | |||
| | P-256 DSS and | | of RFC nnnn | | | | P-256 DSS and | | of RFC 9421 | | |||
| | SHA-256 | | | | | | SHA-256 | | | | |||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
| ecdsa-p384-sha384 | ECDSA using curve | Active | Section 3.3.5 | | | ecdsa-p384-sha384 | ECDSA using curve | Active | Section 3.3.5 | | |||
| | P-384 DSS and | | of RFC nnnn | | | | P-384 DSS and | | of RFC 9421 | | |||
| | SHA-384 | | | | | | SHA-384 | | | | |||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
| ed25519 | Edwards Curve DSA | Active | Section 3.3.6 | | | ed25519 | EdDSA using curve | Active | Section 3.3.6 | | |||
| | using curve | | of RFC nnnn | | | | edwards25519 | | of RFC 9421 | | |||
| | edwards25519 | | | | ||||
+-------------------+-------------------+--------+---------------+ | +-------------------+-------------------+--------+---------------+ | |||
Table 2: Initial contents of the HTTP Signature Algorithms | ||||
Registry. | Table 2: Initial Contents of the HTTP Signature Algorithms | |||
Registry | ||||
6.3. HTTP Signature Metadata Parameters Registry | 6.3. HTTP Signature Metadata Parameters Registry | |||
This document defines the signature parameters structure in | This document defines the signature parameters structure | |||
Section 2.3, which may have parameters containing metadata about a | (Section 2.3), which may have parameters containing metadata about a | |||
message signature. IANA is asked to create and maintain a new | message signature. IANA has created and now maintains a new registry | |||
registry titled "HTTP Signature Metadata Parameters" to record and | titled "HTTP Signature Metadata Parameters" to record and maintain | |||
maintain the set of parameters defined for use with member values in | the set of parameters defined for use with member values in the | |||
the signature parameters structure. Initial values for this registry | signature parameters structure. Initial values for this registry are | |||
are given in Section 6.3.2. Future assignments and modifications to | given in Section 6.3.2. Future assignments and modifications to | |||
existing assignments are to be made through the Expert Review | existing assignments are to be made through the Expert Review | |||
registration policy [RFC8126]. | registration policy [RFC8126]. | |||
The DE is expected to ensure that the name follows the template | The DE is expected to do the following: | |||
presented in Section 6.3.1, including that the length of the name is | ||||
not excessive while still being unique and recognizable for its | * Ensure that the name follows the template presented in | |||
defined function. The DE is expected to ensure that the defined | Section 6.3.1; this includes ensuring that the length of the name | |||
functionality is clear and does not conflict with other registered | is not excessive while still being unique and recognizable for its | |||
parameters. The DE is expected to ensure that the definition of the | defined function. | |||
metadata parameter includes its behavior when used as part of the | ||||
normal signature process as well as when used in an Accept-Signature | * Ensure that the defined functionality is clear and does not | |||
field. | conflict with other registered parameters. | |||
* Ensure that the definition of the metadata parameter includes its | ||||
behavior when used as part of the normal signature process as well | ||||
as when used in an Accept-Signature field. | ||||
6.3.1. Registration Template | 6.3.1. Registration Template | |||
Name: | Name: | |||
An identifier for the HTTP signature metadata parameter. The name | An identifier for the HTTP signature metadata parameter. The name | |||
MUST be an ASCII string that conforms to the key ABNF rule defined | MUST be an ASCII string that conforms to the key ABNF rule defined | |||
in Section 3.1.2 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 | in Section 3.1.2 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 | |||
characters in length. The identifier MUST be unique within the | characters in length. The identifier MUST be unique within the | |||
context of the registry. | context of the registry. | |||
Description: | Description: | |||
A brief description of the metadata parameter and what it | A brief description of the metadata parameter and what it | |||
represents. | represents. | |||
Specification document(s): | Reference: | |||
Reference to the document(s) that specify the parameter, | Reference to the document or documents that specify the parameter, | |||
preferably including a URI that can be used to retrieve a copy of | preferably including a URI that can be used to retrieve a copy of | |||
the document(s). An indication of the relevant sections may also | the document(s). An indication of the relevant sections may also | |||
be included but is not required. | be included but is not required. | |||
6.3.2. Initial Contents | 6.3.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the "HTTP Signature | |||
Metadata Parameters Registry. Each row in the table represents a | Metadata Parameters" registry. Each row in the table represents a | |||
distinct entry in the registry. | distinct entry in the registry. | |||
+=========+===============================+===============+ | +=========+===============================+=============+ | |||
| Name | Description | Specification | | | Name | Description | Reference | | |||
| | | document(s) | | +=========+===============================+=============+ | |||
+=========+===============================+===============+ | | alg | Explicitly declared signature | Section 2.3 | | |||
| alg | Explicitly declared signature | Section 2.3 | | | | algorithm | of RFC 9421 | | |||
| | algorithm | of RFC nnnn | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | | created | Timestamp of signature | Section 2.3 | | |||
| created | Timestamp of signature | Section 2.3 | | | | creation | of RFC 9421 | | |||
| | creation | of RFC nnnn | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | | expires | Timestamp of proposed | Section 2.3 | | |||
| expires | Timestamp of proposed | Section 2.3 | | | | signature expiration | of RFC 9421 | | |||
| | signature expiration | of RFC nnnn | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | | keyid | Key identifier for the | Section 2.3 | | |||
| keyid | Key identifier for the | Section 2.3 | | | | signing and verification keys | of RFC 9421 | | |||
| | signing and verification keys | of RFC nnnn | | | | used to create this signature | | | |||
| | used to create this signature | | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | | nonce | A single-use nonce value | Section 2.3 | | |||
| nonce | A single-use nonce value | Section 2.3 | | | | | of RFC 9421 | | |||
| | | of RFC nnnn | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | | tag | An application-specific tag | Section 2.3 | | |||
| tag | An application-specific tag | Section 2.3 | | | | for a signature | of RFC 9421 | | |||
| | for a signature | of RFC nnnn | | +---------+-------------------------------+-------------+ | |||
+---------+-------------------------------+---------------+ | ||||
Table 3: Initial contents of the HTTP Signature | Table 3: Initial Contents of the HTTP Signature | |||
Metadata Parameters Registry. | Metadata Parameters Registry | |||
6.4. HTTP Signature Derived Component Names Registry | 6.4. HTTP Signature Derived Component Names Registry | |||
This document defines a method for canonicalizing HTTP message | This document defines a method for canonicalizing HTTP message | |||
components, including components that can be derived from the context | components, including components that can be derived from the context | |||
of the target message outside of the HTTP fields. These derived | of the target message outside of the HTTP fields. These derived | |||
components are identified by a unique string, known as the component | components are identified by a unique String, known as the component | |||
name. Component names for derived components always start with the | name. Component names for derived components always start with the | |||
"@" (at) symbol to distinguish them from HTTP field names. IANA is | "at" (@) symbol to distinguish them from HTTP field names. IANA has | |||
asked to create and maintain a new registry typed "HTTP Signature | created and now maintains a new registry titled "HTTP Signature | |||
Derived Component Names" to record and maintain the set of non-field | Derived Component Names" to record and maintain the set of non-field | |||
component names and the methods to produce their associated component | component names and the methods used to produce their associated | |||
values. Initial values for this registry are given in Section 6.4.2. | component values. Initial values for this registry are given in | |||
Future assignments and modifications to existing assignments are to | Section 6.4.2. Future assignments and modifications to existing | |||
be made through the Expert Review registration policy [RFC8126]. | assignments are to be made through the Expert Review registration | |||
policy [RFC8126]. | ||||
The DE is expected to ensure that the name follows the template | The DE is expected to do the following: | |||
presented in Section 6.4.1, including that the length of the name is | ||||
not excessive while still being unique and recognizable for its | * Ensure that the name follows the template presented in | |||
defined function. The DE is expected to ensure that the component | Section 6.4.1; this includes ensuring that the length of the name | |||
value represented by the registration request can be | is not excessive while still being unique and recognizable for its | |||
deterministically derived from the target HTTP message. The DE is | defined function. | |||
expected to ensure that any parameters defined for the registration | ||||
request are clearly documented, along with their effects on the | * Ensure that the component value represented by the registration | |||
component value. The DE should also ensure that the registration | request can be deterministically derived from the target HTTP | |||
request is not sufficiently distinct from existing derived component | message. | |||
definitions to warrant its registration. When setting a registered | ||||
item's status to "Deprecated", the DE should ensure that a reason for | * Ensure that any parameters defined for the registration request | |||
the deprecation is documented, along with instructions for moving | are clearly documented, along with their effects on the component | |||
away from the deprecated functionality. | value. | |||
The DE should ensure that a registration is sufficiently distinct | ||||
from existing derived component definitions to warrant its | ||||
registration. | ||||
When setting a registered item's status to "Deprecated", the DE | ||||
should ensure that a reason for the deprecation is documented, along | ||||
with instructions for moving away from the deprecated functionality. | ||||
6.4.1. Registration Template | 6.4.1. Registration Template | |||
Name: | Name: | |||
A name for the HTTP derived component. The name MUST begin with | A name for the HTTP derived component. The name MUST begin with | |||
the "@" character followed by an ASCII string consisting only of | the "at" (@) character followed by an ASCII string consisting only | |||
lower-case characters ("a" - "z"), digits ("0" - "9"), and hyphens | of lowercase characters ("a"-"z"), digits ("0"-"9"), and hyphens | |||
("-"), and SHOULD NOT exceed 20 characters in length. The name | ("-"), and SHOULD NOT exceed 20 characters in length. The name | |||
MUST be unique within the context of the registry. | MUST be unique within the context of the registry. | |||
Description: | Description: | |||
A description of the derived component. | A description of the derived component. | |||
Status: | Status: | |||
A brief text description of the status of the algorithm. The | A brief text description of the status of the algorithm. The | |||
description MUST begin with one of "Active" or "Deprecated", and | description MUST begin with one of "Active" or "Deprecated" and | |||
MAY provide further context or explanation as to the reason for | MAY provide further context or explanation as to the reason for | |||
the status. A value of "Deprecated" indicates that the derived | the status. A value of "Deprecated" indicates that the derived | |||
component name is no longer recommended for use. | component name is no longer recommended for use. | |||
Target: | Target: | |||
The valid message targets for the derived parameter. MUST be one | The valid message targets for the derived parameter. MUST be one | |||
of the values "Request", "Response", or "Request, Response". The | of the values "Request", "Response", or "Request, Response". The | |||
semantics of these are defined in Section 2.2. | semantics of these entries are defined in Section 2.2. | |||
Specification document(s): | Reference: | |||
Reference to the document(s) that specify the derived component, | Reference to the document or documents that specify the derived | |||
preferably including a URI that can be used to retrieve a copy of | component, preferably including a URI that can be used to retrieve | |||
the document(s). An indication of the relevant sections may also | a copy of the document(s). An indication of the relevant sections | |||
be included but is not required. | may also be included but is not required. | |||
6.4.2. Initial Contents | 6.4.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the "HTTP Signature | |||
Derived Component Names Registry. | Derived Component Names" registry. | |||
+===================+==============+======+========+===============+ | +===================+==============+========+==========+===========+ | |||
| Name | Description |Status|Target | Specification | | | Name | Description | Status | Target | Reference | | |||
| | | | | document(s) | | +===================+==============+========+==========+===========+ | |||
+===================+==============+======+========+===============+ | | @signature-params | Reserved for | Active | Request, | Section | | |||
| @signature-params | Reserved for |Active|Request,| Section 2.3 | | | | signature | | Response | 2.3 of | | |||
| | signature | |Response| of RFC nnnn | | | | parameters | | | RFC 9421 | | |||
| | parameters | | | | | | | line in | | | | | |||
| | line in | | | | | | | signature | | | | | |||
| | signature | | | | | | | base | | | | | |||
| | base | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @method | The HTTP | Active | Request | Section | | |||
| @method | The HTTP |Active|Request | Section 2.2.1 | | | | request | | | 2.2.1 of | | |||
| | request | | | of RFC nnnn | | | | method | | | RFC 9421 | | |||
| | method | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @authority | The HTTP | Active | Request | Section | | |||
| @authority | The HTTP |Active|Request | Section 2.2.3 | | | | authority, | | | 2.2.3 of | | |||
| | authority, | | | of RFC nnnn | | | | or target | | | RFC 9421 | | |||
| | or target | | | | | | | host | | | | | |||
| | host | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @scheme | The URI | Active | Request | Section | | |||
| @scheme | The URI |Active|Request | Section 2.2.4 | | | | scheme of | | | 2.2.4 of | | |||
| | scheme of | | | of RFC nnnn | | | | the request | | | RFC 9421 | | |||
| | the request | | | | | | | URI | | | | | |||
| | URI | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @target-uri | The full | Active | Request | Section | | |||
| @target-uri | The full |Active|Request | Section 2.2.2 | | | | target URI | | | 2.2.2 of | | |||
| | target URI | | | of RFC nnnn | | | | of the | | | RFC 9421 | | |||
| | of the | | | | | | | request | | | | | |||
| | request | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @request-target | The request | Active | Request | Section | | |||
| @request-target | The request |Active|Request | Section 2.2.5 | | | | target of | | | 2.2.5 of | | |||
| | target of | | | of RFC nnnn | | | | the request | | | RFC 9421 | | |||
| | the request | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @path | The full | Active | Request | Section | | |||
| @path | The full |Active|Request | Section 2.2.6 | | | | path of the | | | 2.2.6 of | | |||
| | path of the | | | of RFC nnnn | | | | request URI | | | RFC 9421 | | |||
| | request URI | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @query | The full | Active | Request | Section | | |||
| @query | The full |Active|Request | Section 2.2.7 | | | | query of the | | | 2.2.7 of | | |||
| | query of the | | | of RFC nnnn | | | | request URI | | | RFC 9421 | | |||
| | request URI | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @query-param | A single | Active | Request | Section | | |||
| @query-param | A single |Active|Request | Section 2.2.8 | | | | named query | | | 2.2.8 of | | |||
| | named query | | | of RFC nnnn | | | | parameter | | | RFC 9421 | | |||
| | parameter | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | | @status | The status | Active | Response | Section | | |||
| @status | The status |Active|Response| Section 2.2.9 | | | | code of the | | | 2.2.9 of | | |||
| | code of the | | | of RFC nnnn | | | | response | | | RFC 9421 | | |||
| | response | | | | | +-------------------+--------------+--------+----------+-----------+ | |||
+-------------------+--------------+------+--------+---------------+ | ||||
Table 4: Initial contents of the HTTP Signature Derived | Table 4: Initial Contents of the HTTP Signature Derived | |||
Component Names Registry. | Component Names Registry | |||
6.5. HTTP Signature Component Parameters Registry | 6.5. HTTP Signature Component Parameters Registry | |||
This document defines several kinds of component identifiers, some of | This document defines several kinds of component identifiers, some of | |||
which can be parameterized in specific circumstances to provide | which can be parameterized in specific circumstances to provide | |||
unique modified behavior. IANA is asked to create and maintain a new | unique modified behavior. IANA has created and now maintains a new | |||
registry typed "HTTP Signature Component Parameters" to record and | registry titled "HTTP Signature Component Parameters" to record and | |||
maintain the set of parameters names, the component identifiers they | maintain the set of parameter names, the component identifiers they | |||
are associated with, and the modifications these parameters make to | are associated with, and the modifications these parameters make to | |||
the component value. Definitions of parameters MUST define the | the component value. Definitions of parameters MUST define the | |||
targets to which they apply (such as specific field types, derived | targets to which they apply (such as specific field types, derived | |||
components, or contexts). Initial values for this registry are given | components, or contexts). Initial values for this registry are given | |||
in Section 6.5.2. Future assignments and modifications to existing | in Section 6.5.2. Future assignments and modifications to existing | |||
assignments are to be made through the Expert Review registration | assignments are to be made through the Expert Review registration | |||
policy [RFC8126]. | policy [RFC8126]. | |||
The DE is expected to ensure that the name follows the template | The DE is expected to do the following: | |||
presented in Section 6.5.1, including that the length of the name is | ||||
not excessive while still being unique and recognizable for its | * Ensure that the name follows the template presented in | |||
defined function. The DE is expected to ensure that the definition | Section 6.5.1; this includes ensuring that the length of the name | |||
of the field sufficiently defines any interactions incompatibilities | is not excessive while still being unique and recognizable for its | |||
with other existing parameters known at the time of the registration | defined function. | |||
request. If the parameter changes the component value, the DE is | ||||
expected to ensure that the component value defined by the component | * Ensure that the definition of the field sufficiently defines any | |||
identifier with the parameter applied can be deterministically | interactions or incompatibilities with other existing parameters | |||
derived from the target HTTP message. | known at the time of the registration request. | |||
* Ensure that the component value defined by the component | ||||
identifier with the parameter applied can be deterministically | ||||
derived from the target HTTP message in cases where the parameter | ||||
changes the component value. | ||||
6.5.1. Registration Template | 6.5.1. Registration Template | |||
Name: | Name: | |||
A name for the parameter. The name MUST be an ASCII string that | A name for the parameter. The name MUST be an ASCII string that | |||
conforms to the key ABNF rule defined in Section 3.1.2 of | conforms to the key ABNF rule defined in Section 3.1.2 of | |||
[STRUCTURED-FIELDS] and SHOULD NOT exceed 20 characters in length. | [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 characters in length. | |||
The name MUST be unique within the context of the registry. | The name MUST be unique within the context of the registry. | |||
Description: | Description: | |||
A description of the parameter's function. | A description of the parameter's function. | |||
Specification document(s): | Reference: | |||
Reference to the document(s) that specify the derived component, | Reference to the document or documents that specify the derived | |||
preferably including a URI that can be used to retrieve a copy of | component, preferably including a URI that can be used to retrieve | |||
the document(s). An indication of the relevant sections may also | a copy of the document(s). An indication of the relevant sections | |||
be included but is not required. | may also be included but is not required. | |||
6.5.2. Initial Contents | 6.5.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the "HTTP Signature | |||
Derived Component Names Registry. | Component Parameters" registry. | |||
+======+==============================+===========================+ | +======+=======================================+===============+ | |||
| Name | Description | Specification document(s) | | | Name | Description | Reference | | |||
+======+==============================+===========================+ | +======+=======================================+===============+ | |||
| sf | Strict structured field | Section 2.1.1 of RFC nnnn | | | sf | Strict Structured Field serialization | Section 2.1.1 | | |||
| | serialization | | | | | | of RFC 9421 | | |||
+------+------------------------------+---------------------------+ | +------+---------------------------------------+---------------+ | |||
| key | Single key value of | Section 2.1.2 of RFC nnnn | | | key | Single key value of Dictionary | Section 2.1.2 | | |||
| | dictionary structured fields | | | | | Structured Fields | of RFC 9421 | | |||
+------+------------------------------+---------------------------+ | +------+---------------------------------------+---------------+ | |||
| bs | Byte Sequence wrapping | Section 2.1.3 of RFC nnnn | | | bs | Byte Sequence wrapping indicator | Section 2.1.3 | | |||
| | indicator | | | | | | of RFC 9421 | | |||
+------+------------------------------+---------------------------+ | +------+---------------------------------------+---------------+ | |||
| tr | Trailer | Section 2.1.4 of RFC nnnn | | | tr | Trailer | Section 2.1.4 | | |||
+------+------------------------------+---------------------------+ | | | | of RFC 9421 | | |||
| req | Related request indicator | Section 2.2.4 of RFC nnnn | | +------+---------------------------------------+---------------+ | |||
+------+------------------------------+---------------------------+ | | req | Related request indicator | Section 2.4 | | |||
| name | Single named query parameter | Section 2.2.8 of RFC nnnn | | | | | of RFC 9421 | | |||
+------+------------------------------+---------------------------+ | +------+---------------------------------------+---------------+ | |||
| name | Single named query parameter | Section 2.2.8 | | ||||
| | | of RFC 9421 | | ||||
+------+---------------------------------------+---------------+ | ||||
Table 5: Initial contents of the HTTP Signature Component | Table 5: Initial Contents of the HTTP Signature Component | |||
Parameters Registry. | Parameters Registry | |||
7. Security Considerations | 7. Security Considerations | |||
In order for an HTTP message to be considered _covered_ by a | In order for an HTTP message to be considered _covered_ by a | |||
signature, all of the following conditions have to be true: | signature, all of the following conditions have to be true: | |||
* a signature is expected or allowed on the message by the verifier | * A signature is expected or allowed on the message by the verifier. | |||
* the signature exists on the message | * The signature exists on the message. | |||
* the signature is verified against the identified key material and | * The signature is verified against the identified key material and | |||
algorithm | algorithm. | |||
* the key material and algorithm are appropriate for the context of | * The key material and algorithm are appropriate for the context of | |||
the message | the message. | |||
* the signature is within expected time boundaries | * The signature is within expected time boundaries. | |||
* the signature covers the expected content, including any critical | * The signature covers the expected content, including any critical | |||
components | components. | |||
* the list of covered components is applicable to the context of the | * The list of covered components is applicable to the context of the | |||
message | message. | |||
In addition to the application requirement definitions listed in | In addition to the application requirement definitions listed in | |||
Section 1.4, the following security considerations provide discussion | Section 1.4, the following security considerations provide discussion | |||
and context to the requirements of creating and verifying signatures | and context regarding the requirements of creating and verifying | |||
on HTTP messages. | signatures on HTTP messages. | |||
7.1. General Considerations | 7.1. General Considerations | |||
7.1.1. Skipping Signature Verification | 7.1.1. Skipping Signature Verification | |||
HTTP Message Signatures only provide security if the signature is | HTTP message signatures only provide security if the signature is | |||
verified by the verifier. Since the message to which the signature | verified by the verifier. Since the message to which the signature | |||
is attached remains a valid HTTP message without the signature | is attached remains a valid HTTP message without the Signature or | |||
fields, it is possible for a verifier to ignore the output of the | Signature-Input fields, it is possible for a verifier to ignore the | |||
verification function and still process the message. Common reasons | output of the verification function and still process the message. | |||
for this could be relaxed requirements in a development environment | Common reasons for this could be relaxed requirements in a | |||
or a temporary suspension of enforcing verification during debugging | development environment or a temporary suspension of enforcing | |||
an overall system. Such temporary suspensions are difficult to | verification while debugging an overall system. Such temporary | |||
detect under positive-example testing since a good signature will | suspensions are difficult to detect under positive-example testing, | |||
always trigger a valid response whether or not it has been checked. | since a good signature will always trigger a valid response whether | |||
or not it has been checked. | ||||
To detect this, verifiers should be tested using both valid and | To detect this, verifiers should be tested using both valid and | |||
invalid signatures, ensuring that the invalid signature fails as | invalid signatures, ensuring that an invalid signature fails as | |||
expected. | expected. | |||
7.1.2. Use of TLS | 7.1.2. Use of TLS | |||
The use of HTTP Message Signatures does not negate the need for TLS | The use of HTTP message signatures does not negate the need for TLS | |||
or its equivalent to protect information in transit. Message | or its equivalent to protect information in transit. Message | |||
signatures provide message integrity over the covered message | signatures provide message integrity over the covered message | |||
components but do not provide any confidentiality for the | components but do not provide any confidentiality for communication | |||
communication between parties. | between parties. | |||
TLS provides such confidentiality between the TLS endpoints. As part | TLS provides such confidentiality between the TLS endpoints. As part | |||
of this, TLS also protects the signature data itself from being | of this, TLS also protects the signature data itself from being | |||
captured by an attacker, which is an important step in preventing | captured by an attacker. This is an important step in preventing | |||
signature replay (Section 7.2.2). | signature replay (Section 7.2.2). | |||
When TLS is used, it needs to be deployed according to the | When TLS is used, it needs to be deployed according to the | |||
recommendations in [BCP195]. | recommendations provided in [BCP195]. | |||
7.2. Message Processing and Selection | 7.2. Message Processing and Selection | |||
7.2.1. Insufficient Coverage | 7.2.1. Insufficient Coverage | |||
Any portions of the message not covered by the signature are | Any portions of the message not covered by the signature are | |||
susceptible to modification by an attacker without affecting the | susceptible to modification by an attacker without affecting the | |||
signature. An attacker can take advantage of this by introducing or | signature. An attacker can take advantage of this by introducing or | |||
modifying a header field or other message component that will change | modifying a header field or other message component that will change | |||
the processing of the message but will not be covered by the | the processing of the message but will not be covered by the | |||
skipping to change at page 72, line 29 ¶ | skipping to change at line 3364 ¶ | |||
To combat this, an application of this specification should require | To combat this, an application of this specification should require | |||
as much of the message as possible to be signed, within the limits of | as much of the message as possible to be signed, within the limits of | |||
the application and deployment. The verifier should only trust | the application and deployment. The verifier should only trust | |||
message components that have been signed. Verifiers could also strip | message components that have been signed. Verifiers could also strip | |||
out any sensitive unsigned portions of the message before processing | out any sensitive unsigned portions of the message before processing | |||
of the message continues. | of the message continues. | |||
7.2.2. Signature Replay | 7.2.2. Signature Replay | |||
Since HTTP Message Signatures allows sub-portions of the HTTP message | Since HTTP message signatures allow sub-portions of the HTTP message | |||
to be signed, it is possible for two different HTTP messages to | to be signed, it is possible for two different HTTP messages to | |||
validate against the same signature. The most extreme form of this | validate against the same signature. The most extreme form of this | |||
would be a signature over no message components. If such a signature | would be a signature over no message components. If such a signature | |||
were intercepted, it could be replayed at will by an attacker, | were intercepted, it could be replayed at will by an attacker, | |||
attached to any HTTP message. Even with sufficient component | attached to any HTTP message. Even with sufficient component | |||
coverage, a given signature could be applied to two similar HTTP | coverage, a given signature could be applied to two similar HTTP | |||
messages, allowing a message to be replayed by an attacker with the | messages, allowing a message to be replayed by an attacker with the | |||
signature intact. | signature intact. | |||
To counteract these kinds of attacks, it's first important for the | To counteract these kinds of attacks, it's first important for the | |||
skipping to change at page 73, line 7 ¶ | skipping to change at line 3391 ¶ | |||
considers the signature to be expired, limiting the utility of a | considers the signature to be expired, limiting the utility of a | |||
captured signature value. | captured signature value. | |||
If a verifier wants to trigger a new signature from a signer, it can | If a verifier wants to trigger a new signature from a signer, it can | |||
send the Accept-Signature header field with a new nonce parameter. | send the Accept-Signature header field with a new nonce parameter. | |||
An attacker that is simply replaying a signature would not be able to | An attacker that is simply replaying a signature would not be able to | |||
generate a new signature with the chosen nonce value. | generate a new signature with the chosen nonce value. | |||
7.2.3. Choosing Message Components | 7.2.3. Choosing Message Components | |||
Applications of HTTP Message Signatures need to decide which message | Applications of HTTP message signatures need to decide which message | |||
components will be covered by the signature. Depending on the | components will be covered by the signature. Depending on the | |||
application, some components could be expected to be changed by | application, some components could be expected to be changed by | |||
intermediaries prior to the signature's verification. If these | intermediaries prior to the signature's verification. If these | |||
components are covered, such changes would, by design, break the | components are covered, such changes would, by design, break the | |||
signature. | signature. | |||
However, the HTTP Message Signature standard allows for flexibility | However, this document allows for flexibility in determining which | |||
in determining which components are signed precisely so that a given | components are signed precisely so that a given application can | |||
application can choose the appropriate portions of the message that | choose the appropriate portions of the message that need to be | |||
need to be signed, avoiding problematic components. For example, a | signed, avoiding problematic components. For example, a web | |||
web application framework that relies on rewriting query parameters | application framework that relies on rewriting query parameters might | |||
might avoid use of the @query derived component in favor of sub- | avoid using the @query derived component in favor of sub-indexing the | |||
indexing the query value using @query-param derived components | query value using @query-param derived components instead. | |||
instead. | ||||
Some components are expected to be changed by intermediaries and | Some components are expected to be changed by intermediaries and | |||
ought not to be signed under most circumstance. The Via and | ought not to be signed under most circumstances. The Via and | |||
Forwarded header fields, for example, are expected to be manipulated | Forwarded header fields, for example, are expected to be manipulated | |||
by proxies and other middle-boxes, including replacing or entirely | by proxies and other middleboxes, including replacing or entirely | |||
dropping existing values. These fields should not be covered by the | dropping existing values. These fields should not be covered by the | |||
signature except in very limited and tightly-coupled scenarios. | signature, except in very limited and tightly coupled scenarios. | |||
Additional considerations for choosing signature aspects are | Additional considerations for choosing signature aspects are | |||
discussed in Section 1.4. | discussed in Section 1.4. | |||
7.2.4. Choosing Signature Parameters and Derived Components over HTTP | 7.2.4. Choosing Signature Parameters and Derived Components over HTTP | |||
Fields | Fields | |||
Some HTTP fields have values and interpretations that are similar to | Some HTTP fields have values and interpretations that are similar to | |||
HTTP signature parameters or derived components. In most cases, it | HTTP signature parameters or derived components. In most cases, it | |||
is more desirable to sign the non-field alternative. In particular, | is more desirable to sign the non-field alternative. In particular, | |||
the following fields should usually not be included in the signature | the following fields should usually not be included in the signature | |||
unless the application specifically requires it: | unless the application specifically requires it: | |||
"date" The "date" field value represents the timestamp of the HTTP | "date" The Date header field value represents the timestamp of the | |||
message. However, the creation time of the signature itself is | HTTP message. However, the creation time of the signature itself | |||
encoded in the created signature parameter. These two values can | is encoded in the created signature parameter. These two values | |||
be different, depending on how the signature and the HTTP message | can be different, depending on how the signature and the HTTP | |||
are created and serialized. Applications processing signatures | message are created and serialized. Applications processing | |||
for valid time windows should use the created signature parameter | signatures for valid time windows should use the created signature | |||
for such calculations. An application could also put limits on | parameter for such calculations. An application could also put | |||
how much skew there is between the "date" field and the created | limits on how much skew there is between the Date field and the | |||
signature parameter, in order to limit the application of a | created signature parameter, in order to limit the application of | |||
generated signature to different HTTP messages. See also | a generated signature to different HTTP messages. See also | |||
Section 7.2.2 and Section 7.2.1. | Sections 7.2.2 and 7.2.1. | |||
"host" The "host" header field is specific to HTTP/1.1, and its | "host" The Host header field is specific to HTTP/1.1, and its | |||
functionality is subsumed by the "@authority" derived component, | functionality is subsumed by the @authority derived component, | |||
defined in Section 2.2.3. In order to preserve the value across | defined in Section 2.2.3. In order to preserve the value across | |||
different HTTP versions, applications should always use the | different HTTP versions, applications should always use the | |||
"@authority" derived component. See also Section 7.5.4. | @authority derived component. See also Section 7.5.4. | |||
7.2.5. Signature Labels | 7.2.5. Signature Labels | |||
HTTP Message Signature values are identified in the Signature and | HTTP message signature values are identified in the Signature and | |||
Signature-Input field values by unique labels. These labels are | Signature-Input field values by unique labels. These labels are | |||
chosen only when attaching the signature values to the message and | chosen only when attaching the signature values to the message and | |||
are not accounted for in the signing process. An intermediary is | are not accounted for during the signing process. An intermediary is | |||
allowed to re-label an existing signature when processing the | allowed to relabel an existing signature when processing the message. | |||
message. | ||||
Therefore, applications should not rely on specific labels being | Therefore, applications should not rely on specific labels being | |||
present, and applications should not put semantic meaning on the | present, and applications should not put semantic meaning on the | |||
labels themselves. Instead, additional signature parameters can be | labels themselves. Instead, additional signature parameters can be | |||
used to convey whatever additional meaning is required to be attached | used to convey whatever additional meaning is required to be attached | |||
to and covered by the signature. In particular, the tag parameter | to, and covered by, the signature. In particular, the tag parameter | |||
can be used to define an application-specific value as described in | can be used to define an application-specific value as described in | |||
Section 7.2.7. | Section 7.2.7. | |||
7.2.6. Multiple Signature Confusion | 7.2.6. Multiple Signature Confusion | |||
Since multiple signatures can be applied to one message | Since multiple signatures can be applied to one message | |||
(Section 4.3), it is possible for an attacker to attach their own | (Section 4.3), it is possible for an attacker to attach their own | |||
signature to a captured message without modifying existing | signature to a captured message without modifying existing | |||
signatures. This new signature could be completely valid based on | signatures. This new signature could be completely valid based on | |||
the attacker's key, or it could be an invalid signature for any | the attacker's key, or it could be an invalid signature for any | |||
number of reasons. Each of these situations need to be accounted | number of reasons. Each of these situations needs to be accounted | |||
for. | for. | |||
A verifier processing a set of valid signatures needs to account for | A verifier processing a set of valid signatures needs to account for | |||
all of the signers, identified by the signing keys. Only signatures | all of the signers, identified by the signing keys. Only signatures | |||
from expected signers should be accepted, regardless of the | from expected signers should be accepted, regardless of the | |||
cryptographic validity of the signature itself. | cryptographic validity of the signature itself. | |||
A verifier processing a set of signatures on a message also needs to | A verifier processing a set of signatures on a message also needs to | |||
determine what to do when one or more of the signatures are not | determine what to do when one or more of the signatures are not | |||
valid. If a message is accepted when at least one signature is | valid. If a message is accepted when at least one signature is | |||
valid, then a verifier could drop all invalid signatures from the | valid, then a verifier could drop all invalid signatures from the | |||
request before processing the message further. Alternatively, if the | request before processing the message further. Alternatively, if the | |||
verifier rejects a message for a single invalid signature, an | verifier rejects a message for a single invalid signature, an | |||
attacker could use this to deny service to otherwise valid messages | attacker could use this to deny service to otherwise valid messages | |||
by injecting invalid signatures alongside the valid ones. | by injecting invalid signatures alongside the valid signatures. | |||
7.2.7. Collision of Application-Specific Signature Tag | 7.2.7. Collision of Application-Specific Signature Tag | |||
Multiple applications and protocols could apply HTTP signatures on | Multiple applications and protocols could apply HTTP signatures on | |||
the same message simultaneously. In fact, this is a desired feature | the same message simultaneously. In fact, this is a desired feature | |||
in many circumstances as described in Section 4.3. A naive verifier | in many circumstances; see Section 4.3. A naive verifier could | |||
could become confused in processing multiple signatures, either | become confused while processing multiple signatures, either | |||
accepting or rejecting a message based on an unrelated or irrelevant | accepting or rejecting a message based on an unrelated or irrelevant | |||
signature. In order to help an application select which signatures | signature. In order to help an application select which signatures | |||
apply to its own processing, the application can declare a specific | apply to its own processing, the application can declare a specific | |||
value for the tag signature parameter as defined in Section 2.3. For | value for the tag signature parameter as defined in Section 2.3. For | |||
example, a signature targeting an application gateway could require | example, a signature targeting an application gateway could require | |||
tag="app-gateway" as part of the signature parameters for that | tag="app-gateway" as part of the signature parameters for that | |||
application. | application. | |||
The use of the tag parameter does not prevent an attacker from also | The use of the tag parameter does not prevent an attacker from also | |||
using the same value as a target application, since the parameter's | using the same value as a target application, since the parameter's | |||
value is public and otherwise unrestricted. As a consequence, a | value is public and otherwise unrestricted. As a consequence, a | |||
verifier should only use value of the tag parameter to limit which | verifier should only use a value of the tag parameter to limit which | |||
signatures to check. Each signature still needs to be examined by | signatures to check. Each signature still needs to be examined by | |||
the verifier to ensure that sufficient coverage is provided, as | the verifier to ensure that sufficient coverage is provided, as | |||
discussed in Section 7.2.1. | discussed in Section 7.2.1. | |||
7.2.8. Message Content | 7.2.8. Message Content | |||
On its own, this specification does not provide coverage for the | On its own, this specification does not provide coverage for the | |||
content of an HTTP message under the signature, either in request or | content of an HTTP message under the signature, in either a request | |||
response. However, [DIGEST] defines a set of fields that allow a | or a response. However, [DIGEST] defines a set of fields that allow | |||
cryptographic digest of the content to be represented in a field. | a cryptographic digest of the content to be represented in a field. | |||
Once this field is created, it can be included just like any other | Once this field is created, it can be included just like any other | |||
field as defined in Section 2.1. | field as defined in Section 2.1. | |||
For example, in the following response message: | For example, in the following response message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Content-Type: application/json | Content-Type: application/json | |||
{"hello": "world"} | {"hello": "world"} | |||
skipping to change at page 76, line 36 ¶ | skipping to change at line 3555 ¶ | |||
itself against the actual received content. Unless the verifier | itself against the actual received content. Unless the verifier | |||
performs this step, it would be possible for an attacker to | performs this step, it would be possible for an attacker to | |||
substitute the message content but leave the Content-Digest field | substitute the message content but leave the Content-Digest field | |||
value untouched to pass the signature. Since only the field value is | value untouched to pass the signature. Since only the field value is | |||
covered by the signature directly, checking only the signature is not | covered by the signature directly, checking only the signature is not | |||
sufficient protection against such a substitution attack. | sufficient protection against such a substitution attack. | |||
As discussed in [DIGEST], the value of the Content-Digest field is | As discussed in [DIGEST], the value of the Content-Digest field is | |||
dependent on the content encoding of the message. If an intermediary | dependent on the content encoding of the message. If an intermediary | |||
changes the content encoding, the resulting Content-Digest value | changes the content encoding, the resulting Content-Digest value | |||
would change, which would in turn invalidate the signature. Any | would change. This would in turn invalidate the signature. Any | |||
intermediary performing such an action would need to apply a new | intermediary performing such an action would need to apply a new | |||
signature with the updated Content-Digest field value, similar to the | signature with the updated Content-Digest field value, similar to the | |||
reverse proxy use case discussed in Section 4.3. | reverse proxy use case discussed in Section 4.3. | |||
Applications that make use of the request-response parameter | Applications that make use of the req parameter (Section 2.4) also | |||
(Section 2.4) also need to be aware of the limitations in this | need to be aware of the limitations of this functionality. | |||
functionality. Specifically, if a client does not include something | Specifically, if a client does not include something like a Content- | |||
like a Content-Digest header field in the request, the server is | Digest header field in the request, the server is unable to include a | |||
unable to include a signature that covers the request's content. | signature that covers the request's content. | |||
7.3. Cryptographic Considerations | 7.3. Cryptographic Considerations | |||
7.3.1. Cryptography and Signature Collision | 7.3.1. Cryptography and Signature Collision | |||
The HTTP Message Signatures specification does not define any of its | This document does not define any of its own cryptographic primitives | |||
own cryptographic primitives, and instead relies on other | and instead relies on other specifications to define such elements. | |||
specifications to define such elements. If the signature algorithm | If the signature algorithm or key used to process the signature base | |||
or key used to process the signature base is vulnerable to any | is vulnerable to any attacks, the resulting signature will also be | |||
attacks, the resulting signature will also be susceptible to these | susceptible to these same attacks. | |||
same attacks. | ||||
A common attack against signature systems is to force a signature | A common attack against signature systems is to force a signature | |||
collision, where the same signature value successfully verifies | collision, where the same signature value successfully verifies | |||
against multiple different inputs. Since this specification relies | against multiple different inputs. Since this specification relies | |||
on reconstruction of the signature base from an HTTP message, and the | on reconstruction of the signature base from an HTTP message and the | |||
list of components signed is fixed in the signature, it is difficult | list of components signed is fixed in the signature, it is difficult | |||
but not impossible for an attacker to effect such a collision. An | but not impossible for an attacker to effect such a collision. An | |||
attacker would need to manipulate the HTTP message and its covered | attacker would need to manipulate the HTTP message and its covered | |||
message components in order to make the collision effective. | message components in order to make the collision effective. | |||
To counter this, only vetted keys and signature algorithms should be | To counter this, only vetted keys and signature algorithms should be | |||
used to sign HTTP messages. The HTTP Message Signatures Algorithm | used to sign HTTP messages. The "HTTP Signature Algorithms" registry | |||
Registry is one source of trusted signature algorithms for | is one source of trusted signature algorithms for applications to | |||
applications to apply to their messages. | apply to their messages. | |||
While it is possible for an attacker to substitute the signature | While it is possible for an attacker to substitute the signature | |||
parameters value or the signature value separately, the signature | parameters value or the signature value separately, the signature | |||
base generation algorithm (Section 2.5) always covers the signature | base generation algorithm (Section 2.5) always covers the signature | |||
parameters as the final value in the signature base using a | parameters as the final value in the signature base using a | |||
deterministic serialization method. This step strongly binds the | deterministic serialization method. This step strongly binds the | |||
signature base with the signature value in a way that makes it much | signature base with the signature value in a way that makes it much | |||
more difficult for an attacker to perform a partial substitution on | more difficult for an attacker to perform a partial substitution on | |||
the signature bases. | the signature base. | |||
7.3.2. Key Theft | 7.3.2. Key Theft | |||
A foundational assumption of signature-based cryptographic systems is | A foundational assumption of signature-based cryptographic systems is | |||
that the signing key is not compromised by an attacker. If the keys | that the signing key is not compromised by an attacker. If the keys | |||
used to sign the message are exfiltrated or stolen, the attacker will | used to sign the message are exfiltrated or stolen, the attacker will | |||
be able to generate their own signatures using those keys. As a | be able to generate their own signatures using those keys. As a | |||
consequence, signers have to protect any signing key material from | consequence, signers have to protect any signing key material from | |||
exfiltration, capture, and use by an attacker. | exfiltration, capture, and use by an attacker. | |||
To combat this, signers can rotate keys over time to limit the amount | To combat this, signers can rotate keys over time to limit the amount | |||
of time stolen keys are useful. Signers can also use key escrow and | of time that stolen keys are useful. Signers can also use key escrow | |||
storage systems to limit the attack surface against keys. | and storage systems to limit the attack surface against keys. | |||
Furthermore, the use of asymmetric signing algorithms exposes key | Furthermore, the use of asymmetric signing algorithms exposes key | |||
material less than the use of symmetric signing algorithms | material less than the use of symmetric signing algorithms | |||
(Section 7.3.3). | (Section 7.3.3). | |||
7.3.3. Symmetric Cryptography | 7.3.3. Symmetric Cryptography | |||
The HTTP Message Signatures specification allows for both asymmetric | This document allows both asymmetric and symmetric cryptography to be | |||
and symmetric cryptography to be applied to HTTP messages. By its | applied to HTTP messages. By their nature, symmetric cryptographic | |||
nature, symmetric cryptographic methods require the same key material | methods require the same key material to be known by both the signer | |||
to be known by both the signer and verifier. This effectively means | and verifier. This effectively means that a verifier is capable of | |||
that a verifier is capable of generating a valid signature, since | generating a valid signature, since they have access to the same key | |||
they have access to the same key material. An attacker that is able | material. An attacker that is able to compromise a verifier would be | |||
to compromise a verifier would be able to then impersonate a signer. | able to then impersonate a signer. | |||
Where possible, asymmetric methods or secure key agreement mechanisms | Where possible, asymmetric methods or secure key agreement mechanisms | |||
should be used in order to avoid this type of attack. When symmetric | should be used in order to avoid this type of attack. When symmetric | |||
methods are used, distribution of the key material needs to be | methods are used, distribution of the key material needs to be | |||
protected by the overall system. One technique for this is the use | protected by the overall system. One technique for this is the use | |||
of separate cryptographic modules that separate the verification | of separate cryptographic modules that separate the verification | |||
process (and therefore the key material) from other code, minimizing | process (and therefore the key material) from other code, minimizing | |||
the vulnerable attack surface. Another technique is the use of key | the vulnerable attack surface. Another technique is the use of key | |||
derivation functions that allow the signer and verifier to agree on | derivation functions that allow the signer and verifier to agree on | |||
unique keys for each message without having to share the key values | unique keys for each message without having to share the key values | |||
directly. | directly. | |||
Additionally, if symmetric algorithms are allowed within a system, | Additionally, if symmetric algorithms are allowed within a system, | |||
special care must be taken to avoid key downgrade attacks | special care must be taken to avoid key downgrade attacks | |||
(Section 7.3.6). | (Section 7.3.6). | |||
7.3.4. Key Specification Mix-Up | 7.3.4. Key Specification Mixup | |||
The existence of a valid signature on an HTTP message is not | The existence of a valid signature on an HTTP message is not | |||
sufficient to prove that the message has been signed by the | sufficient to prove that the message has been signed by the | |||
appropriate party. It is up to the verifier to ensure that a given | appropriate party. It is up to the verifier to ensure that a given | |||
key and algorithm are appropriate for the message in question. If | key and algorithm are appropriate for the message in question. If | |||
the verifier does not perform such a step, an attacker could | the verifier does not perform such a step, an attacker could | |||
substitute their own signature using their own key on a message and | substitute their own signature using their own key on a message and | |||
force a verifier to accept and process it. To combat this, the | force a verifier to accept and process it. To combat this, the | |||
verifier needs to ensure that not only does the signature validate | verifier needs to ensure not only that the signature can be validated | |||
for a message, but that the key and algorithm used are appropriate. | for a message but that the key and algorithm used are appropriate. | |||
7.3.5. Non-deterministic Signature Primitives | 7.3.5. Non-deterministic Signature Primitives | |||
Some cryptographic primitives such as RSA PSS and ECDSA have non- | Some cryptographic primitives, such as RSA-PSS and ECDSA, have non- | |||
deterministic outputs, which include some amount of entropy within | deterministic outputs, which include some amount of entropy within | |||
the algorithm. For such algorithms, multiple signatures generated in | the algorithm. For such algorithms, multiple signatures generated in | |||
succession will not match. A lazy implementation of a verifier could | succession will not match. A lazy implementation of a verifier could | |||
ignore this distinction and simply check for the same value being | ignore this distinction and simply check for the same value being | |||
created by re-signing the signature base. Such an implementation | created by re-signing the signature base. Such an implementation | |||
would work for deterministic algorithms such as HMAC and EdDSA but | would work for deterministic algorithms such as HMAC and EdDSA but | |||
fail to verify valid signatures made using non-deterministic | fail to verify valid signatures made using non-deterministic | |||
algorithms. It is therefore important that a verifier always use the | algorithms. It is therefore important that a verifier always use the | |||
correctly-defined verification function for the algorithm in question | correctly defined verification function for the algorithm in question | |||
and not do a simple comparison. | and not do a simple comparison. | |||
7.3.6. Key and Algorithm Specification Downgrades | 7.3.6. Key and Algorithm Specification Downgrades | |||
Applications of this specification need to protect against key | Applications of this specification need to protect against key | |||
specification downgrade attacks. For example, the same RSA key can | specification downgrade attacks. For example, the same RSA key can | |||
be used for both RSA-PSS and RSA v1.5 signatures. If an application | be used for both RSA-PSS and RSA v1.5 signatures. If an application | |||
expects a key to only be used with RSA-PSS, it needs to reject | expects a key to only be used with RSA-PSS, it needs to reject | |||
signatures for that key using the weaker RSA 1.5 specification. | signatures for any key that uses the weaker RSA 1.5 specification. | |||
Another example of a downgrade attack occurs when an asymmetric | Another example of a downgrade attack would be when an asymmetric | |||
algorithm is expected, such as RSA-PSS, but an attacker substitutes a | algorithm is expected, such as RSA-PSS, but an attacker substitutes a | |||
signature using symmetric algorithm, such as HMAC. A naive verifier | signature using a symmetric algorithm, such as HMAC. A naive | |||
implementation could use the value of the public RSA key as the input | verifier implementation could use the value of the public RSA key as | |||
to the HMAC verification function. Since the public key is known to | the input to the HMAC verification function. Since the public key is | |||
the attacker, this would allow the attacker to create a valid HMAC | known to the attacker, this would allow the attacker to create a | |||
signature against this known key. To prevent this, the verifier | valid HMAC signature against this known key. To prevent this, the | |||
needs to ensure that both the key material and the algorithm are | verifier needs to ensure that both the key material and the algorithm | |||
appropriate for the usage in question. Additionally, while this | are appropriate for the usage in question. Additionally, while this | |||
specification does allow runtime specification of the algorithm using | specification does allow runtime specification of the algorithm using | |||
the alg signature parameter, applications are encouraged to use other | the alg signature parameter, applications are encouraged to use other | |||
mechanisms such as static configuration or higher protocol-level | mechanisms such as static configuration or a higher-protocol-level | |||
algorithm specification instead, preventing an attacker from | algorithm specification instead, preventing an attacker from | |||
substituting the algorithm specified. | substituting the algorithm specified. | |||
7.3.7. Signing Signature Values | 7.3.7. Signing Signature Values | |||
When applying the request-response parameter (Section 2.4) or | When applying the req parameter (Section 2.4) or multiple signatures | |||
multiple signatures (Section 4.3) to a message, it is possible to | (Section 4.3) to a message, it is possible to sign the value of an | |||
sign the value of an existing Signature field, thereby covering the | existing Signature field, thereby covering the bytes of the existing | |||
bytes of the existing signature output in the new signature's value. | signature output in the new signature's value. While it would seem | |||
While it would seem that this practice would transitively cover the | that this practice would transitively cover the components under the | |||
components under the original signature in a verifiable fashion, the | original signature in a verifiable fashion, the attacks described in | |||
attacks described in [JACKSON2019] can be used to impersonate a | [JACKSON2019] can be used to impersonate a signature output value on | |||
signature output value on an unrelated message. | an unrelated message. | |||
In this example, Alice intends to send a signed request to Bob, and | In this example, Alice intends to send a signed request to Bob, and | |||
Bob wants to provide a signed response to Alice that includes a | Bob wants to provide a signed response to Alice that includes a | |||
cryptographic proof that Bob is responding to Alice's incoming | cryptographic proof that Bob is responding to Alice's incoming | |||
message. Mallory wants to intercept this traffic and replace Alice's | message. Mallory wants to intercept this traffic and replace Alice's | |||
message with her own, without Alice being aware that the interception | message with her own, without Alice being aware that the interception | |||
has taken place. | has taken place. | |||
1. Alice creates a message, Req_A and applies a signature Sig_A | 1. Alice creates a message Req_A and applies a signature Sig_A | |||
using her private key Key_A_Sign. | using her private key Key_A_Sign. | |||
2. Alice believes she is sending Req_A to Bob. | 2. Alice believes she is sending Req_A to Bob. | |||
3. Mallory intercepts Req_A and reads the value Sig_A from this | 3. Mallory intercepts Req_A and reads the value Sig_A from this | |||
message. | message. | |||
4. Mallory generates a different message Req_M to send to Bob | 4. Mallory generates a different message Req_M to send to Bob | |||
instead. | instead. | |||
5. Mallory crafts a signing key Key_M_Sign such that she can create | 5. Mallory crafts a signing key Key_M_Sign such that she can create | |||
a valid signature Sig_M over her request Req_M using this key, | a valid signature Sig_M over her request Req_M using this key, | |||
but the byte value of Sig_M exactly equals that of Sig_A. | but the byte value of Sig_M exactly equals that of Sig_A. | |||
6. Mallory sends Req_M with Sig_M to Bob. | 6. Mallory sends Req_M with Sig_M to Bob. | |||
7. Bob validates Sig_M against Mallory's verification key, | 7. Bob validates Sig_M against Mallory's verification key | |||
Key_M_Verify. At no time does Bob think that he's responding to | Key_M_Verify. At no time does Bob think that he's responding to | |||
Alice. | Alice. | |||
8. Bob responds with response message Res_B to Req_M and creates | 8. Bob responds with response message Res_B to Req_M and creates | |||
signature Sig_B over this message using his key, Key_B_Sign. | signature Sig_B over this message using his key Key_B_Sign. Bob | |||
Bob includes the value of Sig_M under Sig_B's covered | includes the value of Sig_M under Sig_B's covered components but | |||
components, but nothing elese from the request message. | does not include anything else from the request message. | |||
9. Mallory receives the response Res_B from Bob, including the | 9. Mallory receives the response Res_B from Bob, including the | |||
signature Sig_B value. Mallory replays this response to Alice. | signature Sig_B value. Mallory replays this response to Alice. | |||
10. Alice reads Res_B from Mallory and verifies Sig_B using Bob's | 10. Alice reads Res_B from Mallory and verifies Sig_B using Bob's | |||
verification key, Key_B_Verify. Alice includes the bytes of her | verification key Key_B_Verify. Alice includes the bytes of her | |||
original signature Sig_A in the signature base, and the | original signature Sig_A in the signature base, and the | |||
signature verifies. | signature verifies. | |||
11. Alice is led to believe that Bob has responded to her message, | 11. Alice is led to believe that Bob has responded to her message | |||
and believes she has cryptographic proof of this happening, but | and believes she has cryptographic proof of this happening, but | |||
in fact Bob responded to Mallory's malicious request and Alice | in fact Bob responded to Mallory's malicious request and Alice | |||
is none the wiser. | is none the wiser. | |||
To mitigate this, Bob can sign more portions of the request message | To mitigate this, Bob can sign more portions of the request message | |||
than just the Signature field, in order to more fully differentiate | than just the Signature field, in order to more fully differentiate | |||
Alice's message from Mallory's. Applications using this feature, | Alice's message from Mallory's. Applications using this feature, | |||
particularly for non-repudiation purposes, can stipulate that any | particularly for non-repudiation purposes, can stipulate that any | |||
components required in the original signature also be covered | components required in the original signature also be covered | |||
separately in the second signature. For signed messages, requiring | separately in the second signature. For signed messages, requiring | |||
coverage of the corresponding Signature-Input field of the first | coverage of the corresponding Signature-Input field of the first | |||
signature ensures that unique items such as nonces and timestamps are | signature ensures that unique items such as nonces and timestamps are | |||
also covered sufficiently by the second signature. | also covered sufficiently by the second signature. | |||
7.4. Matching Covered Components to Message | 7.4. Matching Signature Parameters to the Target Message | |||
7.4.1. Modification of Required Message Parameters | 7.4.1. Modification of Required Message Parameters | |||
An attacker could effectively deny a service by modifying an | An attacker could effectively deny a service by modifying an | |||
otherwise benign signature parameter or signed message component. | otherwise benign signature parameter or signed message component. | |||
While rejecting a modified message is the desired behavior, | While rejecting a modified message is the desired behavior, | |||
consistently failing signatures could lead to the verifier turning | consistently failing signatures could lead to (1) the verifier | |||
off signature checking in order to make systems work again (see | turning off signature checking in order to make systems work again | |||
Section 7.1.1), or to the application minimizing the signed component | (see Section 7.1.1) or (2) the application minimizing the | |||
requirements. | requirements related to the signed component. | |||
If such failures are common within an application, the signer and | If such failures are common within an application, the signer and | |||
verifier should compare their generated signature bases with each | verifier should compare their generated signature bases with each | |||
other to determine which part of the message is being modified. If | other to determine which part of the message is being modified. If | |||
an expected modification is found, the signer and verifier can agree | an expected modification is found, the signer and verifier can agree | |||
on an alternative set of requirements that will pass. However, the | on an alternative set of requirements that will pass. However, the | |||
signer and verifier should not remove the requirement to sign the | signer and verifier should not remove the requirement to sign the | |||
modified component when it is suspected an attacker is modifying the | modified component when it is suspected that an attacker is modifying | |||
component. | the component. | |||
7.4.2. Mismatch of Signature Parameters from Message | 7.4.2. Matching Values of Covered Components to Values in the Target | |||
Message | ||||
The verifier needs to make sure that the signed message components | The verifier needs to make sure that the signed message components | |||
match those in the message itself. For example, the @method derived | match those in the message itself. For example, the @method derived | |||
component requires that the value within the signature base be the | component requires that the value within the signature base be the | |||
same as the HTTP method used when presenting this message. This | same as the HTTP method used when presenting this message. This | |||
specification encourages this by requiring the verifier to derive the | specification encourages this by requiring the verifier to derive the | |||
signature base from the message, but lazy caching or conveyance of a | signature base from the message, but lazy caching or conveyance of a | |||
raw signature base to a processing subsystem could lead to downstream | raw signature base to a processing subsystem could lead to downstream | |||
verifiers accepting a message that does not match the presented | verifiers accepting a message that does not match the presented | |||
signature. | signature. | |||
To counter this, the component that generates the signature base | To counter this, the component that generates the signature base | |||
needs to be trusted by both the signer and verifier within a system. | needs to be trusted by both the signer and verifier within a system. | |||
7.4.3. Message Component Source and Context | 7.4.3. Message Component Source and Context | |||
The signature context for deriving message component values includes | The signature context for deriving message component values includes | |||
the target HTTP Message itself, any associated messages (such as the | the target HTTP message itself, any associated messages (such as the | |||
request that triggered a response), and additional information that | request that triggered a response), and additional information that | |||
the signer or verifier has access to. Both signers and verifiers | the signer or verifier has access to. Both signers and verifiers | |||
need to carefully consider the source of all information when | need to carefully consider the source of all information when | |||
creating component values for the signature base and take care not to | creating component values for the signature base and take care not to | |||
take information from untrusted sources. Otherwise, an attacker | take information from untrusted sources. Otherwise, an attacker | |||
could leverage such a loosely-defined message context to inject their | could leverage such a loosely defined message context to inject their | |||
own values into the signature base string, overriding or corrupting | own values into the signature base string, overriding or corrupting | |||
the intended values. | the intended values. | |||
For example, in most situations, the target URI of the message is | For example, in most situations, the target URI of the message is as | |||
defined in [HTTP], Section 7.1. However, let's say that there is an | defined in [HTTP], Section 7.1. However, let's say that there is an | |||
application that requires signing of the @authority of the incoming | application that requires signing of the @authority of the incoming | |||
request, but the application doing the processing is behind a reverse | request, but the application doing the processing is behind a reverse | |||
proxy. Such an application would expect a change in the @authority | proxy. Such an application would expect a change in the @authority | |||
value, and it could be configured to know the external target URI as | value, and it could be configured to know the external target URI as | |||
seen by the client on the other side of the proxy. This application | seen by the client on the other side of the proxy. This application | |||
would use this configured value as its target URI for the purposes of | would use this configured value as its target URI for the purposes of | |||
deriving message component values such as @authority instead of using | deriving message component values such as @authority instead of using | |||
the target URI of the incoming message. | the target URI of the incoming message. | |||
This approach is not without problems, as a misconfigured system | This approach is not without problems, as a misconfigured system | |||
could accept signed requests intended for different components in the | could accept signed requests intended for different components in the | |||
system. For this scenario, an intermediary could instead add its own | system. For this scenario, an intermediary could instead add its own | |||
signature to be verified by the application directly, as demonstrated | signature to be verified by the application directly, as demonstrated | |||
in Section 4.3. This alternative approach requires a more active | in Section 4.3. This alternative approach requires a more active | |||
intermediary but relies less on the target application knowing | intermediary but relies less on the target application knowing | |||
external configuration values. | external configuration values. | |||
For another example, Section 2.4 defines a method for signing | As another example, Section 2.4 defines a method for signing response | |||
response messages but including portions of the request message that | messages and also including portions of the request message that | |||
triggered the response. In this case, the context for component | triggered the response. In this case, the context for component | |||
value calculation is the combination of the response and request | value calculation is the combination of the response and request | |||
message, not just the single message to which the signature is | messages, not just the single message to which the signature is | |||
applied. For this feature, the req flag allows both signer to | applied. For this feature, the req flag allows both signers to | |||
explicitly signal which part of the context is being sourced for a | explicitly signal which part of the context is being sourced for a | |||
component identifier's value. Implementations need to ensure that | component identifier's value. Implementations need to ensure that | |||
only the intended message is being referred to for each component, | only the intended message is being referred to for each component; | |||
otherwise an attacker could attempt to subvert a signature by | otherwise, an attacker could attempt to subvert a signature by | |||
manipulating one side or the other. | manipulating one side or the other. | |||
7.4.4. Multiple Message Component Contexts | 7.4.4. Multiple Message Component Contexts | |||
It is possible that the context for deriving message component values | It is possible that the context for deriving message component values | |||
could be distinct for each signature present within a single message. | could be distinct for each signature present within a single message. | |||
This is particularly the case when proxies mutate messages and | This is particularly the case when proxies mutate messages and | |||
include signatures over the mutated values, in addition to any | include signatures over the mutated values, in addition to any | |||
existing signatures. For example, a reverse proxy can replace a | existing signatures. For example, a reverse proxy can replace a | |||
public hostname in a request to a service with the hostname for the | public hostname in a request to a service with the hostname for the | |||
individual service host that it is forwarding the request on to. If | individual service host to which it is forwarding the request. If | |||
both the client and the reverse proxy add signatures covering | both the client and the reverse proxy add signatures covering | |||
@authority, the service host will see two signatures on the request, | @authority, the service host will see two signatures on the request, | |||
each signing different values for the @authority message component, | each signing different values for the @authority message component, | |||
reflecting the change to that component as the message made its way | reflecting the change to that component as the message made its way | |||
from the client to the service host. | from the client to the service host. | |||
In such a case, it's common for the internal service to verify only | In such a case, it's common for the internal service to verify only | |||
one of the signatures or to use externally-configured information, as | one of the signatures or to use externally configured information, as | |||
discussed in Section 7.4.3. However, a verifier processing both | discussed in Section 7.4.3. However, a verifier processing both | |||
signatures has to use a different message component context for each | signatures has to use a different message component context for each | |||
signature, since the component value for the @authority component | signature, since the component value for the @authority component | |||
will be different for each signature. Verifiers like this need to be | will be different for each signature. Verifiers like this need to be | |||
aware of both the reverse proxy's context for incoming messages as | aware of both the reverse proxy's context for incoming messages and | |||
well as the target service's context for the message coming from the | the target service's context for the message coming from the reverse | |||
reverse proxy. The verifier needs to take particular care to apply | proxy. The verifier needs to take particular care to apply the | |||
the correct context to the correct signature, otherwise an attacker | correct context to the correct signature; otherwise, an attacker | |||
could use knowledge of this complex setup to confuse the inputs to | could use knowledge of this complex setup to confuse the inputs to | |||
the verifier. | the verifier. | |||
Such verifiers also need to ensure that any differences in message | Such verifiers also need to ensure that any differences in message | |||
component contexts between signatures are expected and permitted. | component contexts between signatures are expected and permitted. | |||
For example, in the above scenario, the reverse proxy could include | For example, in the above scenario, the reverse proxy could include | |||
the original hostname in a Forwarded header field, and sign | the original hostname in a Forwarded header field and could sign | |||
@authority, forwarded, and the client's entry in the signature field. | @authority, forwarded, and the client's entry in the Signature field. | |||
The verifier can use the hostname from the Forwarded header field to | The verifier can use the hostname from the Forwarded header field to | |||
confirm that the hostname was transformed as expected. | confirm that the hostname was transformed as expected. | |||
7.5. HTTP Processing | 7.5. HTTP Processing | |||
7.5.1. Confusing HTTP Field Names for Derived Component Names | 7.5.1. Processing Invalid HTTP Field Names as Derived Component Names | |||
The definition of HTTP field names does not allow for the use of the | The definition of HTTP field names does not allow for the use of the | |||
@ character anywhere in the name. As such, since all derived | @ character anywhere in the name. As such, since all derived | |||
component names start with the @ character, these namespaces should | component names start with the @ character, these namespaces should | |||
be completely separate. However, some HTTP implementations are not | be completely separate. However, some HTTP implementations are not | |||
sufficiently strict about the characters accepted in HTTP field | sufficiently strict about the characters accepted in HTTP field | |||
names. In such implementations, a sender (or attacker) could inject | names. In such implementations, a sender (or attacker) could inject | |||
a header field starting with an @ character and have it passed | a header field starting with an @ character and have it passed | |||
through to the application code. These invalid header fields could | through to the application code. These invalid header fields could | |||
be used to override a portion of the derived message content and | be used to override a portion of the derived message content and | |||
substitute an arbitrary value, providing a potential place for an | substitute an arbitrary value, providing a potential place for an | |||
attacker to mount a signature collision (Section 7.3.1) attack or | attacker to mount a signature collision (Section 7.3.1) attack or | |||
other functional substitution attack (such as using the signature | other functional substitution attack (such as using the signature | |||
from a GET request on a crafted POST request). | from a GET request on a crafted POST request). | |||
To combat this, when selecting values for a message component, if the | To combat this, when selecting values for a message component, if the | |||
component name starts with the @ character, it needs to be processed | component name starts with the @ character, it needs to be processed | |||
as a derived component and never taken as a fields. Only if the | as a derived component and never processed as an HTTP field. Only if | |||
component name does not start with the @ character can it be taken | the component name does not start with the @ character can it be | |||
from the fields of the message. The algorithm discussed in | taken from the fields of the message. The algorithm discussed in | |||
Section 2.5 provides a safe order of operations. | Section 2.5 provides a safe order of operations. | |||
7.5.2. Semantically Equivalent Field Values | 7.5.2. Semantically Equivalent Field Values | |||
The signature base generation algorithm (Section 2.5) uses the value | The signature base generation algorithm (Section 2.5) uses the value | |||
of an HTTP field as its component value. In the common case, this | of an HTTP field as its component value. In the common case, this | |||
amounts to taking the actual bytes of the field value as the | amounts to taking the actual bytes of the field value as the | |||
component value for both the signer and verifier. However, some | component value for both the signer and verifier. However, some | |||
field values allow for transformation of the values in semantically | field values allow for transformation of the values in semantically | |||
equivalent ways that alter the bytes used in the value itself. For | equivalent ways that alter the bytes used in the value itself. For | |||
example, a field definition can declare some or all of its value to | example, a field definition can declare some or all of its values to | |||
be case-insensitive, or to have special handling of internal | be case insensitive or to have special handling of internal | |||
whitespace characters. Other fields have expected transformations | whitespace characters. Other fields have expected transformations | |||
from intermediaries, such as the removal of comments in the Via | from intermediaries, such as the removal of comments in the Via | |||
header field. In such cases, a verifier could be tripped up by using | header field. In such cases, a verifier could be tripped up by using | |||
the equivalent transformed field value, which would differ from the | the equivalent transformed field value, which would differ from the | |||
byte value used by the signer. The verifier would have a difficult | byte value used by the signer. The verifier would have a difficult | |||
time finding this class of errors since the value of the field is | time finding this class of errors, since the value of the field is | |||
still acceptable for the application, but the actual bytes required | still acceptable for the application but the actual bytes required by | |||
by the signature base would not match. | the signature base would not match. | |||
When processing such fields, the signer and verifier have to agree | When processing such fields, the signer and verifier have to agree on | |||
how to handle such transformations, if at all. One option is to not | how to handle such transformations, if at all. One option is to not | |||
sign problematic fields, but care must be taken to ensure that there | sign problematic fields, but care must be taken to ensure that there | |||
is still sufficient signature coverage (Section 7.2.1) for the | is still sufficient signature coverage (Section 7.2.1) for the | |||
application. Another option is to define an application-specific | application. Another option is to define an application-specific | |||
canonicalization value for the field before it is added to the HTTP | canonicalization value for the field before it is added to the HTTP | |||
message, such as to always remove internal comments before signing, | message, such as to always remove internal comments before signing or | |||
or to always transform values to lowercase. Since these | to always transform values to lowercase. Since these transformations | |||
transformations are applied prior to the field being used as input to | are applied prior to the field being used as input to the signature | |||
the signature base generation algorithm, the signature base will | base generation algorithm, the signature base will still simply | |||
still simply contain the byte value of the field as it appears within | contain the byte value of the field as it appears within the message. | |||
the message. If the transformations were to be applied after the | If the transformations were to be applied after the value is | |||
value is extracted from the message but before it is added to the | extracted from the message but before it is added to the signature | |||
signature base, different attack surfaces such as value substitution | base, different attack surfaces such as value substitution attacks | |||
attacks could be launched against the application. All application- | could be launched against the application. All application-specific | |||
specific additional rules are outside the scope of this | additional rules are outside the scope of this specification, and by | |||
specification, and by their very nature these transformations would | their very nature these transformations would harm interoperability | |||
harm interoperability of the implementation outside of this specific | of the implementation outside of this specific application. It is | |||
application. It is recommended that applications avoid the use of | recommended that applications avoid the use of such additional rules | |||
such additional rules wherever possible. | wherever possible. | |||
7.5.3. Parsing Structured Field Values | 7.5.3. Parsing Structured Field Values | |||
Several parts of this specification rely on the parsing of structured | Several parts of this specification rely on the parsing of Structured | |||
field values [STRUCTURED-FIELDS]. In particular, normalization of | Field values [STRUCTURED-FIELDS] -- in particular, strict | |||
HTTP structured field values (Section 2.1.1), referencing members of | serialization of HTTP Structured Field values (Section 2.1.1), | |||
a dictionary structured field (Section 2.1.2), and processing the | referencing members of a Dictionary Structured Field (Section 2.1.2), | |||
@signature-input value when verifying a signature (Section 3.2). | and processing the @signature-input value when verifying a signature | |||
While structured field values are designed to be relatively simple to | (Section 3.2). While Structured Field values are designed to be | |||
parse, a naive or broken implementation of such a parser could lead | relatively simple to parse, a naive or broken implementation of such | |||
to subtle attack surfaces being exposed in the implementation. | a parser could lead to subtle attack surfaces being exposed in the | |||
implementation. | ||||
For example, if a buggy parser of the @signature-input value does not | For example, if a buggy parser of the @signature-input value does not | |||
enforce proper closing of quotes around string values within the list | enforce proper closing of quotes around string values within the list | |||
of component identifiers, an attacker could take advantage of this | of component identifiers, an attacker could take advantage of this | |||
and inject additional content into the signature base through | and inject additional content into the signature base through | |||
manipulating the Signature-Input field value on a message. | manipulating the Signature-Input field value on a message. | |||
To counteract this, implementations should use fully compliant and | To counteract this, implementations should use fully compliant and | |||
trusted parsers for all structured field processing, both on the | trusted parsers for all Structured Field processing, on both the | |||
signer and verifier side. | signer side and the verifier side. | |||
7.5.4. HTTP Versions and Component Ambiguity | 7.5.4. HTTP Versions and Component Ambiguity | |||
Some message components are expressed in different ways across HTTP | Some message components are expressed in different ways across HTTP | |||
versions. For example, the authority of the request target is sent | versions. For example, the authority of the request target is sent | |||
using the Host header field in HTTP/1.1 but with the :authority | using the Host header field in HTTP/1.1 but with the :authority | |||
pseudo-header in HTTP/2. If a signer sends an HTTP/1.1 message and | pseudo-header in HTTP/2. If a signer sends an HTTP/1.1 message and | |||
signs the Host field, but the message is translated to HTTP/2 before | signs the Host header field but the message is translated to HTTP/2 | |||
it reaches the verifier, the signature will not validate as the Host | before it reaches the verifier, the signature will not validate, as | |||
header field could be dropped. | the Host header field could be dropped. | |||
It is for this reason that HTTP Message Signatures defines a set of | It is for this reason that HTTP message signatures define a set of | |||
derived components that define a single way to get value in question, | derived components that define a single way to get the value in | |||
such as the @authority derived component (Section 2.2.3) in lieu of | question, such as the @authority derived component (Section 2.2.3) in | |||
the Host header field. Applications should therefore prefer derived | lieu of the Host header field. Applications should therefore prefer | |||
components for such options where possible. | derived components for such options where possible. | |||
7.5.5. Canonicalization Attacks | 7.5.5. Canonicalization Attacks | |||
Any ambiguity in the generation of the signature base could provide | Any ambiguity in the generation of the signature base could provide | |||
an attacker with leverage to substitute or break a signature on a | an attacker with leverage to substitute or break a signature on a | |||
message. Some message component values, particularly HTTP field | message. Some message component values, particularly HTTP field | |||
values, are potentially susceptible to broken implementations that | values, are potentially susceptible to broken implementations that | |||
could lead to unexpected and insecure behavior. Naive | could lead to unexpected and insecure behavior. Naive | |||
implementations of this specification might implement HTTP field | implementations of this specification might implement HTTP field | |||
processing by taking the single value of a field and using it as the | processing by taking the single value of a field and using it as the | |||
direct component value without processing it appropriately. | direct component value without processing it appropriately. | |||
For example, if the handling of obs-fold field values does not remove | For example, if the handling of obs-fold field values does not remove | |||
the internal line folding and whitespace, additional newlines could | the internal line folding and whitespace, additional newlines could | |||
be introduced into the signature base by the signer, providing a | be introduced into the signature base by the signer, providing a | |||
potential place for an attacker to mount a signature collision | potential place for an attacker to mount a signature collision | |||
(Section 7.3.1) attack. Alternatively, if header fields that appear | (Section 7.3.1) attack. Alternatively, if header fields that appear | |||
multiple times are not joined into a single string value, as is | multiple times are not joined into a single string value, as required | |||
required by this specification, similar attacks can be mounted as a | by this specification, similar attacks can be mounted, as a signed | |||
signed component value would show up in the signature base more than | component value would show up in the signature base more than once | |||
once and could be substituted or otherwise attacked in this way. | and could be substituted or otherwise attacked in this way. | |||
To counter this, the entire field value processing algorithm needs to | To counter this, the entire field value processing algorithm needs to | |||
be implemented by all implementations of signers and verifiers. | be implemented by all implementations of signers and verifiers. | |||
7.5.6. Non-List Field Values | 7.5.6. Non-List Field Values | |||
When an HTTP field occurs multiple times in a single message, these | When an HTTP field occurs multiple times in a single message, these | |||
values need to be combined into a single one-line string value to be | values need to be combined into a single one-line string value to be | |||
included in the HTTP signature base, as described in Section 2.5. | included in the HTTP signature base, as described in Section 2.5. | |||
Not all HTTP fields can be combined into a single value in this way | Not all HTTP fields can be combined into a single value in this way | |||
and still be a valid value for the field. For the purposes of | and still be a valid value for the field. For the purposes of | |||
generating the signature base, the message component value is never | generating the signature base, the message component value is never | |||
meant to be read back out of the signature base string or used in the | meant to be read back out of the signature base string or used in the | |||
application. Therefore it is considered best practice to treat the | application. Therefore, it is considered best practice to treat the | |||
signature base generation algorithm separately from processing the | signature base generation algorithm separately from processing the | |||
field values by the application, particularly for fields that are | field values by the application, particularly for fields that are | |||
known to have this property. If the field values that are being | known to have this property. If the field values that are being | |||
signed do not validate, the signed message should also be rejected. | signed do not validate, the signed message should also be rejected. | |||
If an HTTP field allows for unquoted commas within its values, | If an HTTP field allows for unquoted commas within its values, | |||
combining multiple field values can lead to a situation where two | combining multiple field values can lead to a situation where two | |||
semantically different messages produce the same line in a signature | semantically different messages produce the same line in a signature | |||
base. For example, take the following hypothetical header field with | base. For example, take the following hypothetical header field with | |||
an internal comma in its syntax, here used to define two separate | an internal comma in its syntax, here used to define two separate | |||
skipping to change at page 87, line 4 ¶ | skipping to change at line 4034 ¶ | |||
For this header field, sending all of these values as a single field | For this header field, sending all of these values as a single field | |||
value results in a single list of values: | value results in a single list of values: | |||
Example-Header: value, with, lots, of, commas | Example-Header: value, with, lots, of, commas | |||
Both of these messages would create the following line in the | Both of these messages would create the following line in the | |||
signature base: | signature base: | |||
"example-header": value, with, lots, of, commas | "example-header": value, with, lots, of, commas | |||
Since two semantically distinct inputs can create the same output in | Since two semantically distinct inputs can create the same output in | |||
the signature base, special care has to be taken when handling such | the signature base, special care has to be taken when handling such | |||
values. | values. | |||
Specifically, the Set-Cookie field [COOKIE] defines an internal | Specifically, the Set-Cookie field [COOKIE] defines an internal | |||
syntax that does not conform to the List syntax in | syntax that does not conform to the List syntax provided in | |||
[STRUCTURED-FIELDS]. In particular some portions allow unquoted | [STRUCTURED-FIELDS]. In particular, some portions allow unquoted | |||
commas, and the field is typically sent as multiple separate field | commas, and the field is typically sent as multiple separate field | |||
lines with distinct values when sending multiple cookies. When | lines with distinct values when sending multiple cookies. When | |||
multiple Set-Cookie fields are sent in the same message, it is not | multiple Set-Cookie fields are sent in the same message, it is not | |||
generally possible to combine these into a single line and be able to | generally possible to combine these into a single line and be able to | |||
parse and use the results, as discussed in [HTTP], Section 5.3. | parse and use the results, as discussed in [HTTP], Section 5.3. | |||
Therefore, all the cookies need to be processed from their separate | Therefore, all the cookies need to be processed from their separate | |||
header values, without being combined, while the signature base needs | field values, without being combined, while the signature base needs | |||
to be processed from the special combined value generated solely for | to be processed from the special combined value generated solely for | |||
this purpose. If the cookie value is invalid, the signed message | this purpose. If the cookie value is invalid, the signed message | |||
ought to be rejected as this is a possible padding attack as | ought to be rejected, as this is a possible padding attack as | |||
described in Section 7.5.7. | described in Section 7.5.7. | |||
To deal with this, an application can choose to limit signing of | To deal with this, an application can choose to limit signing of | |||
problematic fields like Set-Cookie, such as including the field in a | problematic fields like Set-Cookie, such as including the field in a | |||
signature only when a single field value is present and the results | signature only when a single field value is present and the results | |||
would be unambiguous. Similar caution needs to be taken with all | would be unambiguous. Similar caution needs to be taken with all | |||
fields that could have non-deterministic mappings into the signature | fields that could have non-deterministic mappings into the signature | |||
base. Signers can also make use of the bs parameter to armor such | base. Signers can also make use of the bs parameter to armor such | |||
fields, as described in Section 2.1.3. | fields, as described in Section 2.1.3. | |||
7.5.7. Padding Attacks with Multiple Field Values | 7.5.7. Padding Attacks with Multiple Field Values | |||
Since HTTP field values need to be combined in a single string value | Since HTTP field values need to be combined into a single string | |||
to be included in the HTTP signature base, as described in | value to be included in the HTTP signature base (see Section 2.5), it | |||
Section 2.5, it is possible for an attacker to inject an additional | is possible for an attacker to inject an additional value for a given | |||
value for a given field and add this to the signature base of the | field and add this to the signature base of the verifier. | |||
verifier. | ||||
In most circumstances, this causes the signature validation to fail | In most circumstances, this causes the signature validation to fail | |||
as expected, since the new signature base value will not match the | as expected, since the new signature base value will not match the | |||
one used by the signer to create the signature. However, it is | one used by the signer to create the signature. However, it is | |||
theoretically possible for the attacker to inject both a garbage | theoretically possible for the attacker to inject both a garbage | |||
value to a field and a desired value to another field in order to | value into a field and a desired value into another field in order to | |||
force a particular input. This is a variation of the collision | force a particular input. This is a variation of the collision | |||
attack described in Section 7.3.1, where the attacker accomplishes | attack described in Section 7.3.1, where the attacker accomplishes | |||
their change in the message by adding to existing field values. | their change in the message by adding to existing field values. | |||
To counter this, an application needs to validate the content of the | To counter this, an application needs to validate the content of the | |||
fields covered in the signature in addition to ensuring that the | fields covered in the signature in addition to ensuring that the | |||
signature itself validates. With such protections, the attacker's | signature itself validates. With such protections, the attacker's | |||
padding attack would be rejected by the field value processor, even | padding attack would be rejected by the field value processor, even | |||
in the case where the attacker could force a signature collision. | in the case where the attacker could force a signature collision. | |||
7.5.8. Ambiguous Handling of Query Elements | 7.5.8. Ambiguous Handling of Query Elements | |||
The HTML form parameters format defined in the "application/x-www- | The HTML form parameters format defined in Section 5 ("application/ | |||
form-urlencoded" section of [HTMLURL], is widely deployed and | x-www-form-urlencoded") of [HTMLURL] is widely deployed and supported | |||
supported by many application frameworks. For convenience, some of | by many application frameworks. For convenience, some of these | |||
these frameworks in particular combine query parameters that are | frameworks in particular combine query parameters that are found in | |||
found in the HTTP query and those found in the message content, | the HTTP query and those found in the message content, particularly | |||
particularly for POST message with a Content-Type value of | for POST messages with a Content-Type value of "application/x-www- | |||
"application/x-www-form-urlencoded". The @query-param derived | form-urlencoded". The @query-param derived component identifier | |||
component identifier defined in Section 2.2.8 draws its values only | defined in Section 2.2.8 draws its values only from the query section | |||
from the query section of the target URI of the request. As such, it | of the target URI of the request. As such, it would be possible for | |||
would be possible for an attacker to shadow or replace query | an attacker to shadow or replace query parameters in a request by | |||
parameters in a request by overriding the signed query parameter with | overriding a signed query parameter with an unsigned form parameter, | |||
an unsigned form parameter, or vice versa. | or vice versa. | |||
To counter this, an application needs to make sure that values used | To counter this, an application needs to make sure that values used | |||
for the signature base and the application are drawn from a | for the signature base and the application are drawn from a | |||
consistent context, in this case the query component of the target | consistent context, in this case the query component of the target | |||
URI. Additionally, when the HTTP request has content, an application | URI. Additionally, when the HTTP request has content, an application | |||
should sign the message content as well, as discussed in | should sign the message content as well, as discussed in | |||
Section 7.2.8. | Section 7.2.8. | |||
8. Privacy Considerations | 8. Privacy Considerations | |||
8.1. Identification through Keys | 8.1. Identification through Keys | |||
If a signer uses the same key with multiple verifiers, or uses the | If a signer uses the same key with multiple verifiers or uses the | |||
same key over time with a single verifier, the ongoing use of that | same key over time with a single verifier, the ongoing use of that | |||
key can be used to track the signer throughout the set of verifiers | key can be used to track the signer throughout the set of verifiers | |||
that messages are sent to. Since cryptographic keys are meant to be | that messages are sent to. Since cryptographic keys are meant to be | |||
functionally unique, the use of the same key over time is a strong | functionally unique, the use of the same key over time is a strong | |||
indicator that it is the same party signing multiple messages. | indicator that it is the same party signing multiple messages. | |||
In many applications, this is a desirable trait, and it allows HTTP | In many applications, this is a desirable trait, and it allows HTTP | |||
Message Signatures to be used as part of authenticating the signer to | message signatures to be used as part of authenticating the signer to | |||
the verifier. However, it could be unintentional tracking that a | the verifier. However, it could also result in unintentional | |||
signer might not be aware of. To counter this kind of tracking, a | tracking that a signer might not be aware of. To counter this kind | |||
signer can use a different key for each verifier that it is in | of tracking, a signer can use a different key for each verifier that | |||
communication with. Sometimes, a signer could also rotate their key | it is in communication with. Sometimes, a signer could also rotate | |||
when sending messages to a given verifier. These approaches do not | their key when sending messages to a given verifier. These | |||
negate the need for other anti-tracking techniques to be applied as | approaches do not negate the need for other anti-tracking techniques | |||
necessary. | to be applied as necessary. | |||
8.2. Signatures do not provide confidentiality | 8.2. Signatures do not provide confidentiality | |||
HTTP Message Signatures do not provide confidentiality of any of the | HTTP message signatures do not provide confidentiality for any of the | |||
information protected by the signature. The content of the HTTP | information protected by the signature. The content of the HTTP | |||
message, including the value of all fields and the value of the | message, including the value of all fields and the value of the | |||
signature itself, is presented in plaintext to any party with access | signature itself, is presented in plaintext to any party with access | |||
to the message. | to the message. | |||
To provide confidentiality at the transport level, TLS or its | To provide confidentiality at the transport level, TLS or its | |||
equivalent can be used as discussed in Section 7.1.2. | equivalent can be used, as discussed in Section 7.1.2. | |||
8.3. Oracles | 8.3. Oracles | |||
It is important to balance the need for providing useful feedback to | It is important to balance the need for providing useful feedback to | |||
developers on error conditions without providing additional | developers regarding error conditions without providing additional | |||
information to an attacker. For example, a naive but helpful server | information to an attacker. For example, a naive but helpful server | |||
implementation might try to indicate the required key identifier | implementation might try to indicate the required key identifier | |||
needed for requesting a resource. If someone knows who controls that | needed for requesting a resource. If someone knows who controls that | |||
key, a correlation can be made between the resource's existence and | key, a correlation can be made between the resource's existence and | |||
the party identified by the key. Access to such information could be | the party identified by the key. Access to such information could be | |||
used by an attacker as a means to target the legitimate owner of the | used by an attacker as a means to target the legitimate owner of the | |||
resource for further attacks. | resource for further attacks. | |||
8.4. Required Content | 8.4. Required Content | |||
A core design tenet of this specification is that all message | A core design tenet of this specification is that all message | |||
components covered by the signature need to be available to the | components covered by the signature need to be available to the | |||
verifier in order to recreate the signature base and verify the | verifier in order to recreate the signature base and verify the | |||
signature. As a consequence, if an application of this specification | signature. As a consequence, if an application of this specification | |||
requires that a particular field be signed, the verifier will need | requires that a particular field be signed, the verifier will need | |||
access to the value of that field. | access to the value of that field. | |||
For example, in some complex systems with intermediary processors | For example, in some complex systems with intermediary processors, | |||
this could cause the surprising behavior of an intermediary not being | this could cause surprising behavior where, for fear of breaking the | |||
able to remove privacy-sensitive information from a message before | signature, an intermediary cannot remove privacy-sensitive | |||
forwarding it on for processing, for fear of breaking the signature. | information from a message before forwarding it on for processing. | |||
A possible mitigation for this specific situation would be for the | One way to mitigate this specific situation would be for the | |||
intermediary to verify the signature itself, and then modify the | intermediary to verify the signature itself and then modify the | |||
message to remove the privacy-sensitive information. The | message to remove the privacy-sensitive information. The | |||
intermediary can add its own signature at this point to signal to the | intermediary can add its own signature at this point to signal to the | |||
next destination that the incoming signature was validated, as is | next destination that the incoming signature was validated, as shown | |||
shown in the example in Section 4.3. | in the example in Section 4.3. | |||
9. References | 9. References | |||
9.1. Normative References | 9.1. Normative References | |||
[ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | [ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | |||
Specifications: ABNF", STD 68, RFC 5234, | Specifications: ABNF", STD 68, RFC 5234, | |||
DOI 10.17487/RFC5234, January 2008, | DOI 10.17487/RFC5234, January 2008, | |||
<https://www.rfc-editor.org/rfc/rfc5234>. | <https://www.rfc-editor.org/info/rfc5234>. | |||
[ASCII] Cerf, V., "ASCII format for network interchange", STD 80, | [ASCII] Cerf, V., "ASCII format for network interchange", STD 80, | |||
RFC 20, DOI 10.17487/RFC0020, October 1969, | RFC 20, DOI 10.17487/RFC0020, October 1969, | |||
<https://www.rfc-editor.org/rfc/rfc20>. | <https://www.rfc-editor.org/info/rfc20>. | |||
[FIPS186-4] | [FIPS186-5] | |||
"Digital Signature Standard (DSS)", 2013, | NIST, "Digital Signature Standard (DSS)", | |||
<https://csrc.nist.gov/publications/detail/fips/186/4/ | DOI 10.6028/NIST.FIPS.186-5, February 2023, | |||
final>. | <https://doi.org/10.6028/NIST.FIPS.186-5>. | |||
[HTMLURL] "URL (Living Standard)", 2021, | [HTMLURL] WHATWG, "URL (Living Standard)", January 2024, | |||
<https://url.spec.whatwg.org/#application/x-www-form- | <https://url.spec.whatwg.org/>. | |||
urlencoded>. | ||||
[HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | [HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
Ed., "HTTP Semantics", STD 97, RFC 9110, | Ed., "HTTP Semantics", STD 97, RFC 9110, | |||
DOI 10.17487/RFC9110, June 2022, | DOI 10.17487/RFC9110, June 2022, | |||
<https://www.rfc-editor.org/rfc/rfc9110>. | <https://www.rfc-editor.org/info/rfc9110>. | |||
[HTTP/1.1] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | [HTTP/1.1] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, | Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, | |||
June 2022, <https://www.rfc-editor.org/rfc/rfc9112>. | June 2022, <https://www.rfc-editor.org/info/rfc9112>. | |||
[POSIX.1] "The Open Group Base Specifications Issue 7, 2018 | [POSIX.1] IEEE, "The Open Group Base Specifications Issue 7, 2018 | |||
edition", 2018, | edition", 2018, | |||
<https://pubs.opengroup.org/onlinepubs/9699919799/>. | <https://pubs.opengroup.org/onlinepubs/9699919799/>. | |||
[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | |||
Hashing for Message Authentication", RFC 2104, | Hashing for Message Authentication", RFC 2104, | |||
DOI 10.17487/RFC2104, February 1997, | DOI 10.17487/RFC2104, February 1997, | |||
<https://www.rfc-editor.org/rfc/rfc2104>. | <https://www.rfc-editor.org/info/rfc2104>. | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/rfc/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | |||
(SHA and SHA-based HMAC and HKDF)", RFC 6234, | (SHA and SHA-based HMAC and HKDF)", RFC 6234, | |||
DOI 10.17487/RFC6234, May 2011, | DOI 10.17487/RFC6234, May 2011, | |||
<https://www.rfc-editor.org/rfc/rfc6234>. | <https://www.rfc-editor.org/info/rfc6234>. | |||
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, | [RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, | |||
DOI 10.17487/RFC7517, May 2015, | DOI 10.17487/RFC7517, May 2015, | |||
<https://www.rfc-editor.org/rfc/rfc7517>. | <https://www.rfc-editor.org/info/rfc7517>. | |||
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, | [RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, | |||
DOI 10.17487/RFC7518, May 2015, | DOI 10.17487/RFC7518, May 2015, | |||
<https://www.rfc-editor.org/rfc/rfc7518>. | <https://www.rfc-editor.org/info/rfc7518>. | |||
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | [RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | |||
"PKCS #1: RSA Cryptography Specifications Version 2.2", | "PKCS #1: RSA Cryptography Specifications Version 2.2", | |||
RFC 8017, DOI 10.17487/RFC8017, November 2016, | RFC 8017, DOI 10.17487/RFC8017, November 2016, | |||
<https://www.rfc-editor.org/rfc/rfc8017>. | <https://www.rfc-editor.org/info/rfc8017>. | |||
[RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital | [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital | |||
Signature Algorithm (EdDSA)", RFC 8032, | Signature Algorithm (EdDSA)", RFC 8032, | |||
DOI 10.17487/RFC8032, January 2017, | DOI 10.17487/RFC8032, January 2017, | |||
<https://www.rfc-editor.org/rfc/rfc8032>. | <https://www.rfc-editor.org/info/rfc8032>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
[STRUCTURED-FIELDS] | [STRUCTURED-FIELDS] | |||
Nottingham, M. and P. Kamp, "Structured Field Values for | Nottingham, M. and P. Kamp, "Structured Field Values for | |||
HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, | HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, | |||
<https://www.rfc-editor.org/rfc/rfc8941>. | <https://www.rfc-editor.org/info/rfc8941>. | |||
[URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | [URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | |||
Resource Identifier (URI): Generic Syntax", STD 66, | Resource Identifier (URI): Generic Syntax", STD 66, | |||
RFC 3986, DOI 10.17487/RFC3986, January 2005, | RFC 3986, DOI 10.17487/RFC3986, January 2005, | |||
<https://www.rfc-editor.org/rfc/rfc3986>. | <https://www.rfc-editor.org/info/rfc3986>. | |||
9.2. Informative References | 9.2. Informative References | |||
[AWS-SIGv4] | [AWS-SIGv4] | |||
"Authenticating Requests (AWS Signature Version 4)", n.d., | Amazon Simple Storage Service, "Authenticating Requests | |||
(AWS Signature Version 4)", March 2006, | ||||
<https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4- | <https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4- | |||
authenticating-requests.html>. | authenticating-requests.html>. | |||
[BCP195] Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS | [BCP195] Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS | |||
1.1", BCP 195, RFC 8996, March 2021. | 1.1", BCP 195, RFC 8996, March 2021. | |||
Sheffer, Y., Saint-Andre, P., and T. Fossati, | Sheffer, Y., Saint-Andre, P., and T. Fossati, | |||
"Recommendations for Secure Use of Transport Layer | "Recommendations for Secure Use of Transport Layer | |||
Security (TLS) and Datagram Transport Layer Security | Security (TLS) and Datagram Transport Layer Security | |||
(DTLS)", BCP 195, RFC 9325, November 2022. | (DTLS)", BCP 195, RFC 9325, November 2022. | |||
<https://www.rfc-editor.org/info/bcp195> | ||||
[CLIENT-CERT] | [CLIENT-CERT] | |||
Campbell, B. and M. Bishop, "Client-Cert HTTP Header | Campbell, B. and M. Bishop, "Client-Cert HTTP Header | |||
Field", RFC 9440, DOI 10.17487/RFC9440, July 2023, | Field", RFC 9440, DOI 10.17487/RFC9440, July 2023, | |||
<https://www.rfc-editor.org/rfc/rfc9440>. | <https://www.rfc-editor.org/info/rfc9440>. | |||
[COOKIE] Barth, A., "HTTP State Management Mechanism", RFC 6265, | [COOKIE] Barth, A., "HTTP State Management Mechanism", RFC 6265, | |||
DOI 10.17487/RFC6265, April 2011, | DOI 10.17487/RFC6265, April 2011, | |||
<https://www.rfc-editor.org/rfc/rfc6265>. | <https://www.rfc-editor.org/info/rfc6265>. | |||
[DIGEST] Polli, R. and L. Pardue, "Digest Fields", Work in | ||||
Progress, Internet-Draft, draft-ietf-httpbis-digest- | ||||
headers-13, 10 July 2023, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | ||||
digest-headers-13>. | ||||
[I-D.cavage-http-signatures] | ||||
Cavage, M. and M. Sporny, "Signing HTTP Messages", Work in | ||||
Progress, Internet-Draft, draft-cavage-http-signatures-12, | ||||
21 October 2019, <https://datatracker.ietf.org/doc/html/ | ||||
draft-cavage-http-signatures-12>. | ||||
[I-D.ietf-oauth-signed-http-request] | [DIGEST] Polli, R. and L. Pardue, "Digest Fields", RFC 9530, | |||
Richer, J., Bradley, J., and H. Tschofenig, "A Method for | DOI 10.17487/RFC9530, February 2024, | |||
Signing HTTP Requests for OAuth", Work in Progress, | <https://www.rfc-editor.org/info/rfc9530>. | |||
Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8 | ||||
August 2016, <https://datatracker.ietf.org/doc/html/draft- | ||||
ietf-oauth-signed-http-request-03>. | ||||
[JACKSON2019] | [JACKSON2019] | |||
Jackson, D., Cremers, C., Cohn-Gordon, K., and R. Sasse, | Jackson, D., Cremers, C., Cohn-Gordon, K., and R. Sasse, | |||
"Seems Legit: Automated Analysis of Subtle Attacks on | "Seems Legit: Automated Analysis of Subtle Attacks on | |||
Protocols that Use Signatures", November 2019, | Protocols that Use Signatures", CCS '19: Proceedings of | |||
<https://dennis-jackson.uk/assets/pdfs/signatures.pdf>. | the 2019 ACM SIGSAC Conference on Computer and | |||
Communications Security, pp. 2165-2180, | ||||
DOI 10.1145/3319535.3339813, November 2019, | ||||
<https://dl.acm.org/doi/10.1145/3319535.3339813>. | ||||
[JWS] Jones, M., Bradley, J., and N. Sakimura, "JSON Web | [JWS] Jones, M., Bradley, J., and N. Sakimura, "JSON Web | |||
Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May | Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May | |||
2015, <https://www.rfc-editor.org/rfc/rfc7515>. | 2015, <https://www.rfc-editor.org/info/rfc7515>. | |||
[RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | [RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | |||
RFC 7239, DOI 10.17487/RFC7239, June 2014, | RFC 7239, DOI 10.17487/RFC7239, June 2014, | |||
<https://www.rfc-editor.org/rfc/rfc7239>. | <https://www.rfc-editor.org/info/rfc7239>. | |||
[RFC7468] Josefsson, S. and S. Leonard, "Textual Encodings of PKIX, | ||||
PKCS, and CMS Structures", RFC 7468, DOI 10.17487/RFC7468, | ||||
April 2015, <https://www.rfc-editor.org/info/rfc7468>. | ||||
[RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP | [RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP | |||
APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016, | APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016, | |||
<https://www.rfc-editor.org/rfc/rfc7807>. | <https://www.rfc-editor.org/info/rfc7807>. | |||
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/rfc/rfc8126>. | <https://www.rfc-editor.org/info/rfc8126>. | |||
[RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, | [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, | |||
"Handling Long Lines in Content of Internet-Drafts and | "Handling Long Lines in Content of Internet-Drafts and | |||
RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, | RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, | |||
<https://www.rfc-editor.org/rfc/rfc8792>. | <https://www.rfc-editor.org/info/rfc8792>. | |||
[RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details | ||||
for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, | ||||
<https://www.rfc-editor.org/info/rfc9457>. | ||||
[SIGNING-HTTP-MESSAGES] | ||||
Cavage, M. and M. Sporny, "Signing HTTP Messages", Work in | ||||
Progress, Internet-Draft, draft-cavage-http-signatures-12, | ||||
21 October 2019, <https://datatracker.ietf.org/doc/html/ | ||||
draft-cavage-http-signatures-12>. | ||||
[SIGNING-HTTP-REQS-OAUTH] | ||||
Richer, J., Ed., Bradley, J., and H. Tschofenig, "A Method | ||||
for Signing HTTP Requests for OAuth", Work in Progress, | ||||
Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8 | ||||
August 2016, <https://datatracker.ietf.org/doc/html/draft- | ||||
ietf-oauth-signed-http-request-03>. | ||||
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
<https://www.rfc-editor.org/rfc/rfc8446>. | <https://www.rfc-editor.org/info/rfc8446>. | |||
Appendix A. Detecting HTTP Message Signatures | Appendix A. Detecting HTTP Message Signatures | |||
There have been many attempts to create signed HTTP messages in the | There have been many attempts to create signed HTTP messages in the | |||
past, including other non-standardized definitions of the Signature | past, including other non-standardized definitions of the Signature | |||
field, which is used within this specification. It is recommended | field that is used within this specification. It is recommended that | |||
that developers wishing to support both this specification and other | developers wishing to support this specification, other published | |||
historical drafts do so carefully and deliberately, as | documents, or other historical drafts do so carefully and | |||
incompatibilities between this specification and various versions of | deliberately, as incompatibilities between this specification and | |||
other drafts could lead to unexpected problems. | other documents or various versions of other drafts could lead to | |||
unexpected problems. | ||||
It is recommended that implementers first detect and validate the | It is recommended that implementors first detect and validate the | |||
Signature-Input field defined in this specification to detect that | Signature-Input field defined in this specification to detect that | |||
this standard is in use and not an alternative. If the Signature- | the mechanism described in this document is in use and not an | |||
Input field is present, all Signature fields can be parsed and | alternative. If the Signature-Input field is present, all Signature | |||
interpreted in the context of this specification. | fields can be parsed and interpreted in the context of this | |||
specification. | ||||
Appendix B. Examples | Appendix B. Examples | |||
The following non-normative examples are provided as a means of | The following non-normative examples are provided as a means of | |||
testing implementations of HTTP Message Signatures. The signed | testing implementations of HTTP message signatures. The signed | |||
messages given can be used to create the signature base with the | messages given can be used to create the signature base with the | |||
stated parameters, creating signatures using the stated algorithms | stated parameters, creating signatures using the stated algorithms | |||
and keys. | and keys. | |||
The private keys given can be used to generate signatures, though | The private keys given can be used to generate signatures, though | |||
since several of the demonstrated algorithms are nondeterministic, | since several of the demonstrated algorithms are non-deterministic, | |||
the results of a signature are expected to be different from the | the results of a signature are expected to be different from the | |||
exact bytes of the examples. The public keys given can be used to | exact bytes of the examples. The public keys given can be used to | |||
validate all signed examples. | validate all signed examples. | |||
B.1. Example Keys | B.1. Example Keys | |||
This section provides cryptographic keys that are referenced in | This section provides cryptographic keys that are referenced in | |||
example signatures throughout this document. These keys MUST NOT be | example signatures throughout this document. These keys MUST NOT be | |||
used for any purpose other than testing. | used for any purpose other than testing. | |||
The key identifiers for each key are used throughout the examples in | The key identifiers for each key are used throughout the examples in | |||
this specification. It is assumed for these examples that the signer | this specification. It is assumed for these examples that the signer | |||
and verifier can unambiguously dereference all key identifiers used | and verifier can unambiguously dereference all key identifiers used | |||
here, and that the keys and algorithms used are appropriate for the | here and that the keys and algorithms used are appropriate for the | |||
context in which the signature is presented. | context in which the signature is presented. | |||
The components for each private key in PEM format can be displayed by | The components for each private key, in PEM format [RFC7468], can be | |||
executing the following OpenSSL command: | displayed by executing the following OpenSSL command: | |||
openssl pkey -text | openssl pkey -text | |||
This command was tested with all the example keys on OpenSSL version | This command was tested with all the example keys on OpenSSL version | |||
1.1.1m. Note that some systems cannot produce or use all of these | 1.1.1m. Note that some systems cannot produce or use all of these | |||
keys directly, and may require additional processing. All keys are | keys directly and may require additional processing. All keys are | |||
also made available in JWK format. | also made available in JWK format. | |||
B.1.1. Example Key RSA test | B.1.1. Example RSA Key | |||
The following key is a 2048-bit RSA public and private key pair, | The following key is a 2048-bit RSA public and private key pair, | |||
referred to in this document as test-key-rsa. This key is encoded in | referred to in this document as test-key-rsa. This key is encoded in | |||
PEM Format, with no encryption. | PEM format, with no encryption. | |||
-----BEGIN RSA PUBLIC KEY----- | -----BEGIN RSA PUBLIC KEY----- | |||
MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | |||
WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | |||
MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | |||
kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | |||
uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | |||
PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | |||
-----END RSA PUBLIC KEY----- | -----END RSA PUBLIC KEY----- | |||
skipping to change at page 95, line 42 ¶ | skipping to change at line 4435 ¶ | |||
9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn | 9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn | |||
f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo | f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo | |||
81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa | 81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa | |||
/2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | /2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | |||
IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | |||
qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | |||
WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | |||
EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | |||
-----END RSA PRIVATE KEY----- | -----END RSA PRIVATE KEY----- | |||
The same public and private keypair in JWK format: | The same public and private key pair in JWK format: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
{ | { | |||
"kty": "RSA", | "kty": "RSA", | |||
"kid": "test-key-rsa", | "kid": "test-key-rsa", | |||
"p": "sqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOMcCNq8Sy\ | "p": "sqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOMcCNq8Sy\ | |||
YbTqgnWlB9ZfcAm_cFpA8tYci9m5vYK8HNxQr-8FS3Qo8N9RJ8d0U5CswDzMYfRgh\ | YbTqgnWlB9ZfcAm_cFpA8tYci9m5vYK8HNxQr-8FS3Qo8N9RJ8d0U5CswDzMYfRgh\ | |||
AfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1mw", | AfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1mw", | |||
"q": "vSlgXQbvHzWmuUBFRHAejRh_naQTDV3GnH4lcRHuFBFZCSLn82xQS2_7xFO\ | "q": "vSlgXQbvHzWmuUBFRHAejRh_naQTDV3GnH4lcRHuFBFZCSLn82xQS2_7xFO\ | |||
skipping to change at page 96, line 40 ¶ | skipping to change at line 4472 ¶ | |||
Gtt4NBiBMiY6V9br8a5gjEpiAQoIUcWokBMAYjEeurU8M6JLBd3YaZVVjISaFmdty\ | Gtt4NBiBMiY6V9br8a5gjEpiAQoIUcWokBMAYjEeurU8M6JLBd3YaZVVjISaFmdty\ | |||
nwLFoQxCh6_EC1rSywwrfDpSwO29S9i8Xbaap", | nwLFoQxCh6_EC1rSywwrfDpSwO29S9i8Xbaap", | |||
"n": "hAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrwWEBnez6\ | "n": "hAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrwWEBnez6\ | |||
d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFqMGmXCQvE\ | d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFqMGmXCQvE\ | |||
G7YemcxDTRPxAleIAgYYRjTSd_QBwVW9OwNFhekro3RtlinV0a75jfZgkne_YiktS\ | G7YemcxDTRPxAleIAgYYRjTSd_QBwVW9OwNFhekro3RtlinV0a75jfZgkne_YiktS\ | |||
vLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0PuKxI4T-HIa\ | vLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0PuKxI4T-HIa\ | |||
Fpv8-rdV6eUgOrB2xeI1dSFFn_nnv5OoZJEIB-VmuKn3DCUcCZSFlQPSXSfBDiUGh\ | Fpv8-rdV6eUgOrB2xeI1dSFFn_nnv5OoZJEIB-VmuKn3DCUcCZSFlQPSXSfBDiUGh\ | |||
wOw76WuSSsf1D4b_vLoJ10w" | wOw76WuSSsf1D4b_vLoJ10w" | |||
} | } | |||
B.1.2. Example RSA PSS Key | B.1.2. Example RSA-PSS Key | |||
The following key is a 2048-bit RSA public and private key pair, | The following key is a 2048-bit RSA public and private key pair, | |||
referred to in this document as test-key-rsa-pss. This key is PCKS#8 | referred to in this document as test-key-rsa-pss. This key is PKCS | |||
encoded in PEM format, with no encryption. | #8 encoded in PEM format, with no encryption. | |||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | |||
+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | +QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | |||
oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | |||
gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | |||
Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | |||
aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | |||
2wIDAQAB | 2wIDAQAB | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
skipping to change at page 97, line 44 ¶ | skipping to change at line 4517 ¶ | |||
OGIHDRp6HjMUcxHpHw7U+S1TETxePwKLnLKj6hw8jnX2/nZRgWHzgVcY+sPsReRx | OGIHDRp6HjMUcxHpHw7U+S1TETxePwKLnLKj6hw8jnX2/nZRgWHzgVcY+sPsReRx | |||
NJVf+Cfh6yOtznfX00p+JWOXdSY8glSSHJwRAMog+hFGW1AYdt7w80XBAoGBAImR | NJVf+Cfh6yOtznfX00p+JWOXdSY8glSSHJwRAMog+hFGW1AYdt7w80XBAoGBAImR | |||
NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ | NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ | |||
3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | 3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | |||
t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | |||
dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | |||
S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | |||
rOjr9w349JooGXhOxbu8nOxX | rOjr9w349JooGXhOxbu8nOxX | |||
-----END PRIVATE KEY----- | -----END PRIVATE KEY----- | |||
The same public and private keypair in JWK format: | The same public and private key pair in JWK format: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
{ | { | |||
"kty": "RSA", | "kty": "RSA", | |||
"kid": "test-key-rsa-pss", | "kid": "test-key-rsa-pss", | |||
"p": "5V-6ISI5yEaCFXm-fk1EM2xwAWekePVCAyvr9QbTlFOCZwt9WwjUjhtKRus\ | "p": "5V-6ISI5yEaCFXm-fk1EM2xwAWekePVCAyvr9QbTlFOCZwt9WwjUjhtKRus\ | |||
i5Uq-IYZ_tq2WRE4As4b_FHEMtp2AER43IcvmXPqKFBoUktVDS7dThIHrsnRi1U7d\ | i5Uq-IYZ_tq2WRE4As4b_FHEMtp2AER43IcvmXPqKFBoUktVDS7dThIHrsnRi1U7d\ | |||
HqVdwiMEMe5jxKNgnsKLpnq-4NyhoS6OeWu1SFozG9J9xQk", | HqVdwiMEMe5jxKNgnsKLpnq-4NyhoS6OeWu1SFozG9J9xQk", | |||
"q": "w-wIde17W5Y0Cphp3ZZ0uM8OUq1AkrV2IKauqYHaDxAT32EM4ci2MMER2nI\ | "q": "w-wIde17W5Y0Cphp3ZZ0uM8OUq1AkrV2IKauqYHaDxAT32EM4ci2MMER2nI\ | |||
skipping to change at page 98, line 43 ¶ | skipping to change at line 4557 ¶ | |||
s8ct-Lh1GH45x28Rw3Ry53mm-oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95An\ | s8ct-Lh1GH45x28Rw3Ry53mm-oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95An\ | |||
dTrifbIFPNU8PPMO7OyrFAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL-Wokqltd11\ | dTrifbIFPNU8PPMO7OyrFAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL-Wokqltd11\ | |||
nqqzi-bJ9cvSKADYdUAAN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSy\ | nqqzi-bJ9cvSKADYdUAAN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSy\ | |||
ZYoA485mqcO0GVAdVw9lq4aOT9v6d-nb4bnNkQVklLQ3fVAvJm-xdDOp9LCNCN48V\ | ZYoA485mqcO0GVAdVw9lq4aOT9v6d-nb4bnNkQVklLQ3fVAvJm-xdDOp9LCNCN48V\ | |||
2pnDOkFV6-U9nV5oyc6XI2w" | 2pnDOkFV6-U9nV5oyc6XI2w" | |||
} | } | |||
B.1.3. Example ECC P-256 Test Key | B.1.3. Example ECC P-256 Test Key | |||
The following key is a public and private elliptical curve key pair | The following key is a public and private elliptical curve key pair | |||
over the curve P-256, referred to in this document as `test-key-ecc- | over the curve P-256, referred to in this document as test-key-ecc- | |||
p256. This key is encoded in PEM format, with no encryption. | p256. This key is encoded in PEM format, with no encryption. | |||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | |||
w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
-----BEGIN EC PRIVATE KEY----- | -----BEGIN EC PRIVATE KEY----- | |||
MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | |||
AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | |||
4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | 4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | |||
-----END EC PRIVATE KEY----- | -----END EC PRIVATE KEY----- | |||
The same public and private keypair in JWK format: | The same public and private key pair in JWK format: | |||
{ | { | |||
"kty": "EC", | "kty": "EC", | |||
"crv": "P-256", | "crv": "P-256", | |||
"kid": "test-key-ecc-p256", | "kid": "test-key-ecc-p256", | |||
"d": "UpuF81l-kOxbjf7T4mNSv0r5tN67Gim7rnf6EFpcYDs", | "d": "UpuF81l-kOxbjf7T4mNSv0r5tN67Gim7rnf6EFpcYDs", | |||
"x": "qIVYZVLCrPZHGHjP17CTW0_-D9Lfw0EkjqF7xB4FivA", | "x": "qIVYZVLCrPZHGHjP17CTW0_-D9Lfw0EkjqF7xB4FivA", | |||
"y": "Mc4nN9LTDOBhfoUeg8Ye9WedFRhnZXZJA12Qp0zZ6F0" | "y": "Mc4nN9LTDOBhfoUeg8Ye9WedFRhnZXZJA12Qp0zZ6F0" | |||
} | } | |||
B.1.4. Example Ed25519 Test Key | B.1.4. Example Ed25519 Test Key | |||
The following key is an elliptical curve key over the Edwards curve | The following key is an elliptical curve key over the Edwards curve | |||
ed25519, referred to in this document as test-key-ed25519. This key | ed25519, referred to in this document as test-key-ed25519. This key | |||
is PCKS#8 encoded in PEM format, with no encryption. | is PKCS #8 encoded in PEM format, with no encryption. | |||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= | MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
-----BEGIN PRIVATE KEY----- | -----BEGIN PRIVATE KEY----- | |||
MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF | MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF | |||
-----END PRIVATE KEY----- | -----END PRIVATE KEY----- | |||
The same public and private keypair in JWK format: | The same public and private key pair in JWK format: | |||
{ | { | |||
"kty": "OKP", | "kty": "OKP", | |||
"crv": "Ed25519", | "crv": "Ed25519", | |||
"kid": "test-key-ed25519", | "kid": "test-key-ed25519", | |||
"d": "n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU", | "d": "n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU", | |||
"x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs" | "x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs" | |||
} | } | |||
B.1.5. Example Shared Secret | B.1.5. Example Shared Secret | |||
The following shared secret is 64 randomly-generated bytes encoded in | The following shared secret is 64 randomly generated bytes encoded in | |||
Base64, referred to in this document as test-shared-secret. | Base64, referred to in this document as test-shared-secret: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | |||
bmHhIDi6pcl8jsasjlTMtDQ== | bmHhIDi6pcl8jsasjlTMtDQ== | |||
B.2. Test Cases | B.2. Test Cases | |||
This section provides non-normative examples that may be used as test | This section provides non-normative examples that may be used as test | |||
cases to validate implementation correctness. These examples are | cases to validate implementation correctness. These examples are | |||
skipping to change at page 100, line 42 ¶ | skipping to change at line 4643 ¶ | |||
{"hello": "world"} | {"hello": "world"} | |||
For responses, this test-response message is used: | For responses, this test-response message is used: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Digest: sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6sN\ | Content-Digest: sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ41Q\ | |||
HpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==: | JgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: | |||
Content-Length: 23 | Content-Length: 23 | |||
{"message": "good dog"} | {"message": "good dog"} | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 | B.2.1. Minimal Signature Using rsa-pss-sha512 | |||
This example presents a minimal signature using the rsa-pss-sha512 | This example presents a minimal signature using the rsa-pss-sha512 | |||
algorithm over test-request, covering none of the components of the | algorithm over test-request, covering none of the components of the | |||
HTTP message, but providing a timestamped signature proof of | HTTP message but providing a timestamped signature proof of | |||
possession of the key with a signer-provided nonce. | possession of the key with a signer-provided nonce. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ | "@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ | |||
;nonce="b3k2pp5k7z-50gnwp.yemd" | ;nonce="b3k2pp5k7z-50gnwp.yemd" | |||
This results in the following Signature-Input and Signature header | This results in the following Signature-Input and Signature header | |||
skipping to change at page 101, line 39 ¶ | skipping to change at line 4683 ¶ | |||
2VjBqJzsPLMIQKhO4DGezXehhWwE56YCE+O6c0mKZsfxVrogUvA4HELjVKWmAvtl6\ | 2VjBqJzsPLMIQKhO4DGezXehhWwE56YCE+O6c0mKZsfxVrogUvA4HELjVKWmAvtl6\ | |||
UnCh8jYzuVG5WSb/QEVPnP5TmcAnLH1g+s++v6d4s8m0gCw1fV5/SITLq9mhho8K3\ | UnCh8jYzuVG5WSb/QEVPnP5TmcAnLH1g+s++v6d4s8m0gCw1fV5/SITLq9mhho8K3\ | |||
+7EPYTU8IU1bLhdxO5Nyt8C8ssinQ98Xw9Q==: | +7EPYTU8IU1bLhdxO5Nyt8C8ssinQ98Xw9Q==: | |||
Note that since the covered components list is empty, this signature | Note that since the covered components list is empty, this signature | |||
could be applied by an attacker to an unrelated HTTP message. In | could be applied by an attacker to an unrelated HTTP message. In | |||
this example, the nonce parameter is included to prevent the same | this example, the nonce parameter is included to prevent the same | |||
signature from being replayed more than once, but if an attacker | signature from being replayed more than once, but if an attacker | |||
intercepts the signature and prevents its delivery to the verifier, | intercepts the signature and prevents its delivery to the verifier, | |||
the attacker could apply this signature to another message. | the attacker could apply this signature to another message. | |||
Therefore, use of an empty covered components set is discouraged. | Therefore, the use of an empty covered components set is discouraged. | |||
See Section 7.2.1 for more discussion. | See Section 7.2.1 for more discussion. | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | Note that the RSA-PSS algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning that a different signature value will be created every time | |||
algorithm is run. The signature value provided here can be validated | the algorithm is run. The signature value provided here can be | |||
against the given keys, but newly-generated signature values are not | validated against the given keys, but newly generated signature | |||
expected to match the example. See Section 7.3.5. | values are not expected to match the example. See Section 7.3.5. | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 | B.2.2. Selective Covered Components Using rsa-pss-sha512 | |||
This example covers additional components (the authority, the | This example covers additional components (the authority, the | |||
Content-Digest header field, and a single named query parameter) in | Content-Digest header field, and a single named query parameter) in | |||
test-request using the rsa-pss-sha512 algorithm. This example also | test-request using the rsa-pss-sha512 algorithm. This example also | |||
adds a tag parameter with the application-specific value of header- | adds a tag parameter with the application-specific value of header- | |||
example. | example. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
skipping to change at page 102, line 41 ¶ | skipping to change at line 4728 ¶ | |||
Signature-Input: sig-b22=("@authority" "content-digest" \ | Signature-Input: sig-b22=("@authority" "content-digest" \ | |||
"@query-param";name="Pet");created=1618884473\ | "@query-param";name="Pet");created=1618884473\ | |||
;keyid="test-key-rsa-pss";tag="header-example" | ;keyid="test-key-rsa-pss";tag="header-example" | |||
Signature: sig-b22=:LjbtqUbfmvjj5C5kr1Ugj4PmLYvx9wVjZvD9GsTT4F7GrcQ\ | Signature: sig-b22=:LjbtqUbfmvjj5C5kr1Ugj4PmLYvx9wVjZvD9GsTT4F7GrcQ\ | |||
EdJzgI9qHxICagShLRiLMlAJjtq6N4CDfKtjvuJyE5qH7KT8UCMkSowOB4+ECxCmT\ | EdJzgI9qHxICagShLRiLMlAJjtq6N4CDfKtjvuJyE5qH7KT8UCMkSowOB4+ECxCmT\ | |||
8rtAmj/0PIXxi0A0nxKyB09RNrCQibbUjsLS/2YyFYXEu4TRJQzRw1rLEuEfY17SA\ | 8rtAmj/0PIXxi0A0nxKyB09RNrCQibbUjsLS/2YyFYXEu4TRJQzRw1rLEuEfY17SA\ | |||
RYhpTlaqwZVtR8NV7+4UKkjqpcAoFqWFQh62s7Cl+H2fjBSpqfZUJcsIk4N6wiKYd\ | RYhpTlaqwZVtR8NV7+4UKkjqpcAoFqWFQh62s7Cl+H2fjBSpqfZUJcsIk4N6wiKYd\ | |||
4je2U/lankenQ99PZfB4jY3I5rSV2DSBVkSFsURIjYErOs0tFTQosMTAoxk//0RoK\ | 4je2U/lankenQ99PZfB4jY3I5rSV2DSBVkSFsURIjYErOs0tFTQosMTAoxk//0RoK\ | |||
UqiYY8Bh0aaUEb0rQl3/XaVe4bXTugEjHSw==: | UqiYY8Bh0aaUEb0rQl3/XaVe4bXTugEjHSw==: | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | Note that the RSA-PSS algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning that a different signature value will be created every time | |||
algorithm is run. The signature value provided here can be validated | the algorithm is run. The signature value provided here can be | |||
against the given keys, but newly-generated signature values are not | validated against the given keys, but newly generated signature | |||
expected to match the example. See Section 7.3.5. | values are not expected to match the example. See Section 7.3.5. | |||
B.2.3. Full Coverage using rsa-pss-sha512 | B.2.3. Full Coverage Using rsa-pss-sha512 | |||
This example covers all applicable message components in test-request | This example covers all applicable message components in test-request | |||
(including the content type and length) plus many derived components, | (including the content type and length) plus many derived components, | |||
again using the rsa-pss-sha512 algorithm. Note that the Host header | again using the rsa-pss-sha512 algorithm. Note that the Host header | |||
field is not covered because the @authority derived component is | field is not covered because the @authority derived component is | |||
included instead. | included instead. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
skipping to change at page 103, line 45 ¶ | skipping to change at line 4774 ¶ | |||
Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ | Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "content-digest" "content-length")\ | "@authority" "content-type" "content-digest" "content-length")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Signature: sig-b23=:bbN8oArOxYoyylQQUU6QYwrTuaxLwjAC9fbY2F6SVWvh0yB\ | Signature: sig-b23=:bbN8oArOxYoyylQQUU6QYwrTuaxLwjAC9fbY2F6SVWvh0yB\ | |||
iMIRGOnMYwZ/5MR6fb0Kh1rIRASVxFkeGt683+qRpRRU5p2voTp768ZrCUb38K0fU\ | iMIRGOnMYwZ/5MR6fb0Kh1rIRASVxFkeGt683+qRpRRU5p2voTp768ZrCUb38K0fU\ | |||
xN0O0iC59DzYx8DFll5GmydPxSmme9v6ULbMFkl+V5B1TP/yPViV7KsLNmvKiLJH1\ | xN0O0iC59DzYx8DFll5GmydPxSmme9v6ULbMFkl+V5B1TP/yPViV7KsLNmvKiLJH1\ | |||
pFkh/aYA2HXXZzNBXmIkoQoLd7YfW91kE9o/CCoC1xMy7JA1ipwvKvfrs65ldmlu9\ | pFkh/aYA2HXXZzNBXmIkoQoLd7YfW91kE9o/CCoC1xMy7JA1ipwvKvfrs65ldmlu9\ | |||
bpG6A9BmzhuzF8Eim5f8ui9eH8LZH896+QIF61ka39VBrohr9iyMUJpvRX2Zbhl5Z\ | bpG6A9BmzhuzF8Eim5f8ui9eH8LZH896+QIF61ka39VBrohr9iyMUJpvRX2Zbhl5Z\ | |||
JzSRxpJyoEZAFL2FUo5fTIztsDZKEgM4cUA==: | JzSRxpJyoEZAFL2FUo5fTIztsDZKEgM4cUA==: | |||
Note in this example that the value of the Date header and the value | Note in this example that the value of the Date header field and the | |||
of the created signature parameter need not be the same. This is due | value of the created signature parameter need not be the same. This | |||
to the fact that the Date header is added when creating the HTTP | is due to the fact that the Date header field is added when creating | |||
Message and the created parameter is populated when creating the | the HTTP message and the created parameter is populated when creating | |||
signature over that message, and these two times could vary. If the | the signature over that message, and these two times could vary. If | |||
Date header is covered by the signature, it is up to the verifier to | the Date header field is covered by the signature, it is up to the | |||
determine whether its value has to match that of the created | verifier to determine whether its value has to match that of the | |||
parameter or not. See Section 7.2.4 for more discussion. | created parameter or not. See Section 7.2.4 for more discussion. | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | Note that the RSA-PSS algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning that a different signature value will be created every time | |||
algorithm is run. The signature value provided here can be validated | the algorithm is run. The signature value provided here can be | |||
against the given keys, but newly-generated signature values are not | validated against the given keys, but newly generated signature | |||
expected to match the example. See Section 7.3.5. | values are not expected to match the example. See Section 7.3.5. | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 | B.2.4. Signing a Response Using ecdsa-p256-sha256 | |||
This example covers portions of the test-response response message | This example covers portions of the test-response message using the | |||
using the ecdsa-p256-sha256 algorithm and the key test-key-ecc-p256. | ecdsa-p256-sha256 algorithm and the key test-key-ecc-p256. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 200 | "@status": 200 | |||
"content-type": application/json | "content-type": application/json | |||
"content-digest": sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ4\ | "content-digest": sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ4\ | |||
1QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: | 1QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: | |||
"content-length": 23 | "content-length": 23 | |||
skipping to change at page 104, line 39 ¶ | skipping to change at line 4817 ¶ | |||
fields being added to the message under the label sig-b24: | fields being added to the message under the label sig-b24: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig-b24=("@status" "content-type" \ | Signature-Input: sig-b24=("@status" "content-type" \ | |||
"content-digest" "content-length");created=1618884473\ | "content-digest" "content-length");created=1618884473\ | |||
;keyid="test-key-ecc-p256" | ;keyid="test-key-ecc-p256" | |||
Signature: sig-b24=:wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NK\ | Signature: sig-b24=:wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NK\ | |||
ocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==: | ocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==: | |||
Note that the ECDSA algorithm in use here is non-deterministic, | Note that the ECDSA signature algorithm in use here is non- | |||
meaning a different signature value will be created every time the | deterministic, meaning that a different signature value will be | |||
algorithm is run. The signature value provided here can be validated | created every time the algorithm is run. The signature value | |||
against the given keys, but newly-generated signature values are not | provided here can be validated against the given keys, but newly | |||
expected to match the example. See Section 7.3.5. | generated signature values are not expected to match the example. | |||
See Section 7.3.5. | ||||
B.2.5. Signing a Request using hmac-sha256 | B.2.5. Signing a Request Using hmac-sha256 | |||
This example covers portions of the test-request using the hmac- | This example covers portions of the test-request message using the | |||
sha256 algorithm and the secret test-shared-secret. | hmac-sha256 algorithm and the secret test-shared-secret. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:55 GMT | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("date" "@authority" "content-type")\ | "@signature-params": ("date" "@authority" "content-type")\ | |||
;created=1618884473;keyid="test-shared-secret" | ;created=1618884473;keyid="test-shared-secret" | |||
This results in the following Signature-Input and Signature header | This results in the following Signature-Input and Signature header | |||
fields being added to the message under the label sig-b25: | fields being added to the message under the label sig-b25: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig-b25=("date" "@authority" "content-type")\ | Signature-Input: sig-b25=("date" "@authority" "content-type")\ | |||
;created=1618884473;keyid="test-shared-secret" | ;created=1618884473;keyid="test-shared-secret" | |||
Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: | Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: | |||
Before using symmetric signatures in practice, see the discussion of | Before using symmetric signatures in practice, see the discussion | |||
the security tradeoffs in Section 7.3.3. | regarding security trade-offs in Section 7.3.3. | |||
B.2.6. Signing a Request using ed25519 | B.2.6. Signing a Request Using ed25519 | |||
This example covers portions of the test-request using the ed25519 | This example covers portions of the test-request message using the | |||
algorithm and the key test-key-ed25519. | Ed25519 algorithm and the key test-key-ed25519. | |||
The corresponding signature base is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:55 GMT | |||
"@method": POST | "@method": POST | |||
"@path": /foo | "@path": /foo | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
skipping to change at page 106, line 18 ¶ | skipping to change at line 4886 ¶ | |||
"content-type" "content-length");created=1618884473\ | "content-type" "content-length");created=1618884473\ | |||
;keyid="test-key-ed25519" | ;keyid="test-key-ed25519" | |||
Signature: sig-b26=:wqcAqbmYJ2ji2glfAMaRy4gruYYnx2nEFN2HN6jrnDnQCK1\ | Signature: sig-b26=:wqcAqbmYJ2ji2glfAMaRy4gruYYnx2nEFN2HN6jrnDnQCK1\ | |||
u02Gb04v9EDgwUPiu4A0w6vuQv5lIp5WPpBKRCw==: | u02Gb04v9EDgwUPiu4A0w6vuQv5lIp5WPpBKRCw==: | |||
B.3. TLS-Terminating Proxies | B.3. TLS-Terminating Proxies | |||
In this example, there is a TLS-terminating reverse proxy sitting in | In this example, there is a TLS-terminating reverse proxy sitting in | |||
front of the resource. The client does not sign the request but | front of the resource. The client does not sign the request but | |||
instead uses mutual TLS to make its call. The terminating proxy | instead uses mutual TLS to make its call. The terminating proxy | |||
validates the TLS stream and injects a Client-Cert header according | validates the TLS stream and injects a Client-Cert header field | |||
to [CLIENT-CERT], and then applies a signature to this field. By | according to [CLIENT-CERT], and then applies a signature to this | |||
signing this header field, a reverse proxy can not only attest to its | field. By signing this header field, a reverse proxy not only can | |||
own validation of the initial request's TLS parameters but also | attest to its own validation of the initial request's TLS parameters | |||
authenticate itself to the backend system independently of the | but can also authenticate itself to the backend system independently | |||
client's actions. | of the client's actions. | |||
The client makes the following request to the TLS terminating proxy | The client makes the following request to the TLS-terminating proxy | |||
using mutual TLS: | using mutual TLS: | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
skipping to change at page 107, line 26 ¶ | skipping to change at line 4930 ¶ | |||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | |||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | |||
8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | |||
4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | |||
bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | |||
{"hello": "world"} | {"hello": "world"} | |||
Without a signature, the internal service would need to trust that | Without a signature, the internal service would need to trust that | |||
the incoming connection has the right information. By signing the | the incoming connection has the right information. By signing the | |||
Client-Cert header and other portions of the internal request, the | Client-Cert header field and other portions of the internal request, | |||
internal service can be assured that the correct party, the trusted | the internal service can be assured that the correct party, the | |||
proxy, has processed the request and presented it to the correct | trusted proxy, has processed the request and presented it to the | |||
service. The proxy's signature base consists of the following: | correct service. The proxy's signature base consists of the | |||
following: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@path": /foo | "@path": /foo | |||
"@query": ?param=Value&Pet=dog | "@query": ?param=Value&Pet=dog | |||
"@method": POST | "@method": POST | |||
"@authority": service.internal.example | "@authority": service.internal.example | |||
"client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ | "client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ | |||
KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ | KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ | |||
QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ | QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ | |||
skipping to change at page 108, line 10 ¶ | skipping to change at line 4961 ¶ | |||
"@signature-params": ("@path" "@query" "@method" "@authority" \ | "@signature-params": ("@path" "@query" "@method" "@authority" \ | |||
"client-cert");created=1618884473;keyid="test-key-ecc-p256" | "client-cert");created=1618884473;keyid="test-key-ecc-p256" | |||
This results in the following signature: | This results in the following signature: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6Mce9315T6xoklyy0y\ | xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6Mce9315T6xoklyy0y\ | |||
zhD9ah4JHRwMLOgmizw== | zhD9ah4JHRwMLOgmizw== | |||
Which results in the following signed request sent from the proxy to | which results in the following signed request sent from the proxy to | |||
the internal service with the proxy's signature under the label ttrp: | the internal service with the proxy's signature under the label ttrp: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: service.internal.example | Host: service.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | |||
skipping to change at page 108, line 42 ¶ | skipping to change at line 4993 ¶ | |||
Mce9315T6xoklyy0yzhD9ah4JHRwMLOgmizw==: | Mce9315T6xoklyy0yzhD9ah4JHRwMLOgmizw==: | |||
{"hello": "world"} | {"hello": "world"} | |||
The internal service can validate the proxy's signature and therefore | The internal service can validate the proxy's signature and therefore | |||
be able to trust that the client's certificate has been appropriately | be able to trust that the client's certificate has been appropriately | |||
processed. | processed. | |||
B.4. HTTP Message Transformations | B.4. HTTP Message Transformations | |||
The HTTP protocol allows intermediaries and applications to transform | HTTP allows intermediaries and applications to transform an HTTP | |||
an HTTP message without affecting the semantics of the message | message without affecting the semantics of the message itself. HTTP | |||
itself. HTTP message signatures are designed to be robust against | message signatures are designed to be robust against many of these | |||
many of these transformations in different circumstances. | transformations in different circumstances. | |||
For example, the following HTTP request message has been signed using | For example, the following HTTP request message has been signed using | |||
the ed25519 algorithm and the key test-key-ed25519. | the Ed25519 algorithm and the key test-key-ed25519: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Date: Fri, 15 Jul 2022 14:24:55 GMT | Date: Fri, 15 Jul 2022 14:24:55 GMT | |||
Accept: application/json | Accept: application/json | |||
Accept: */* | Accept: */* | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
skipping to change at page 109, line 27 ¶ | skipping to change at line 5023 ¶ | |||
The signature base string for this message is: | The signature base string for this message is: | |||
"@method": GET | "@method": GET | |||
"@path": /demo | "@path": /demo | |||
"@authority": example.org | "@authority": example.org | |||
"accept": application/json, */* | "accept": application/json, */* | |||
"@signature-params": ("@method" "@path" "@authority" "accept")\ | "@signature-params": ("@method" "@path" "@authority" "accept")\ | |||
;created=1618884473;keyid="test-key-ed25519" | ;created=1618884473;keyid="test-key-ed25519" | |||
The following message has been altered by adding the Accept-Language | The following message has been altered by adding the Accept-Language | |||
header as well as adding a query parameter. However, since neither | header field as well as adding a query parameter. However, since | |||
the Accept-Language header nor the query are covered by the | neither the Accept-Language header field nor the query is covered by | |||
signature, the same signature is still valid: | the signature, the same signature is still valid: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /demo?name1=Value1&Name2=value2¶m=added HTTP/1.1 | GET /demo?name1=Value1&Name2=value2¶m=added HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Date: Fri, 15 Jul 2022 14:24:55 GMT | Date: Fri, 15 Jul 2022 14:24:55 GMT | |||
Accept: application/json | Accept: application/json | |||
Accept: */* | Accept: */* | |||
Accept-Language: en-US,en;q=0.5 | Accept-Language: en-US,en;q=0.5 | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | |||
Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | |||
The following message has been altered by removing the Date header, | The following message has been altered by removing the Date header | |||
adding a Referer header, and collapsing the Accept header into a | field, adding a Referer header field, and collapsing the Accept | |||
single line. The Date and Referrer headers are not covered by the | header field into a single line. The Date and Referer header fields | |||
signature, and the collapsing of the Accept header is an allowed | are not covered by the signature, and the collapsing of the Accept | |||
transformation that is already accounted for by the canonicalization | header field is an allowed transformation that is already accounted | |||
algorithm for HTTP field values. The same signature is still valid: | for by the canonicalization algorithm for HTTP field values. The | |||
same signature is still valid: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Referer: https://developer.example.org/demo | Referer: https://developer.example.org/demo | |||
Accept: application/json, */* | Accept: application/json, */* | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | |||
Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | |||
The following message has been altered by re-ordering the field | The following message has been altered by reordering the field values | |||
values of the original message, but not re-ordering the individual | of the original message but not reordering the individual Accept | |||
Accept headers. The same signature is still valid: | header fields. The same signature is still valid: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | |||
Accept: application/json | Accept: application/json | |||
Accept: */* | Accept: */* | |||
Date: Fri, 15 Jul 2022 14:24:55 GMT | Date: Fri, 15 Jul 2022 14:24:55 GMT | |||
Host: example.org | Host: example.org | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | |||
Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | |||
The following message has been altered by changing the method to POST | The following message has been altered by changing the method to POST | |||
and the authority to "example.com" (inside the Host header). Since | and the authority to "example.com" (inside the Host header field). | |||
both the method and authority are covered by the signature, the same | Since both the method and authority are covered by the signature, the | |||
signature is NOT still valid: | same signature is NOT still valid: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /demo?name1=Value1&Name2=value2 HTTP/1.1 | POST /demo?name1=Value1&Name2=value2 HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Fri, 15 Jul 2022 14:24:55 GMT | Date: Fri, 15 Jul 2022 14:24:55 GMT | |||
Accept: application/json | Accept: application/json | |||
Accept: */* | Accept: */* | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | |||
Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | |||
The following message has been altered by changing the order of the | The following message has been altered by changing the order of the | |||
two instances of the Accept header. Since the order of fields with | two instances of the Accept header field. Since the order of fields | |||
the same name is semantically significant in HTTP, this changes the | with the same name is semantically significant in HTTP, this changes | |||
value used in the signature base, and the same signature is NOT still | the value used in the signature base, and the same signature is NOT | |||
valid: | still valid: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | GET /demo?name1=Value1&Name2=value2 HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Date: Fri, 15 Jul 2022 14:24:55 GMT | Date: Fri, 15 Jul 2022 14:24:55 GMT | |||
Accept: */* | Accept: */* | |||
Accept: application/json | Accept: application/json | |||
Signature-Input: transform=("@method" "@path" "@authority" \ | Signature-Input: transform=("@method" "@path" "@authority" \ | |||
"accept");created=1618884473;keyid="test-key-ed25519" | "accept");created=1618884473;keyid="test-key-ed25519" | |||
Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ | |||
Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: | |||
Acknowledgements | Acknowledgements | |||
This specification was initially based on the | This specification was initially based on [SIGNING-HTTP-MESSAGES]. | |||
[I-D.cavage-http-signatures] internet draft. The editors would like | The editors would like to thank the authors of | |||
to thank the authors of that draft, Mark Cavage and Manu Sporny, for | [SIGNING-HTTP-MESSAGES] -- Mark Cavage and Manu Sporny -- for their | |||
their work on that draft and their continuing contributions. The | work on that Internet-Draft and their continuing contributions. This | |||
specification also includes contributions from the | specification also includes contributions from | |||
[I-D.ietf-oauth-signed-http-request] internet draft and other similar | [SIGNING-HTTP-REQS-OAUTH] and other similar efforts. | |||
efforts. | ||||
The editors would also like to thank the following individuals for | ||||
feedback, insight, and implementation of this draft and its | ||||
predecessors (in alphabetical order): Mark Adamcin, Mark Allen, Paul | ||||
Annesley, Karl Böhlmark, Stéphane Bortzmeyer, Sarven Capadisli, Liam | ||||
Dennehy, Stephen Farrell, Phillip Hallam-Baker, Tyler Ham, Eric | ||||
Holmes, Andrey Kislyuk, Adam Knight, Dave Lehn, Dave Longley, Ilari | ||||
Liusvaara, James H. Manger, Kathleen Moriarty, Mark Nottingham, Yoav | ||||
Nir, Adrian Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, | ||||
Michael Richardson, Wojciech Rygielski, Rich Salz, Adam Scarr, Cory | ||||
J. Slep, Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and | ||||
Jeffrey Yasskin. | ||||
Document History | ||||
_RFC EDITOR: please remove this section before publication_ | ||||
* draft-ietf-httpbis-message-signatures | ||||
- -19 | ||||
o Update IANA registration instructions. | ||||
- -18 | ||||
o Update IANA registration instructions. | ||||
o Editorial updates from IESG review. | ||||
- -17 | ||||
o Change encoding | ||||
o Remove sign-the-signature examples and add explanations of | ||||
why not to do that. | ||||
o Query parameter values must be re-encoded for safety. | ||||
o Query parameters now carry a warning of limitations. | ||||
o Address field value encodings. | ||||
o Discuss history and positioning of this specification. | ||||
o Import obs-fold, reference US-ASCII, enforce ASCII-ness of | ||||
Signature Base | ||||
- -16 | ||||
o Editorial cleanup from AD review. | ||||
o Clarified dependency on structured field serialization | ||||
rules. | ||||
o Define use of all parameters in Accept-Signature. | ||||
o Update example signature calculations. | ||||
o Clarify how combined fields are handled. | ||||
o Add more detailed instructions for IANA DE's. | ||||
o Fix some references and anchors. | ||||
- -15 | ||||
o Editorial cleanup. | ||||
o Defined "signature context". | ||||
- -14 | ||||
o Target raw non-decoded values for "@query" and "@path". | ||||
o Add method for signing trailers. | ||||
o Call out potential issues of list-based field values. | ||||
o Update IANA registry for header fields. | ||||
o Call out potential issues with Content-Digest in example. | ||||
o Add JWK formats for all keys. | ||||
- -13 | ||||
o Renamed "context" parameter to "tag". | ||||
o Added discussion on messages with multiple known contexts. | ||||
- -12 | ||||
o Added "context" parameter. | ||||
o Added set of safe transformation examples. | ||||
o Added ECDSA over P-384. | ||||
o Expanded definiton of message component source context. | ||||
o Sorted security considerations into categories. | ||||
- -11 | ||||
o Added ABNF references, coalesced ABNF rules. | ||||
o Editorial and formatting fixes. | ||||
o Update examples. | ||||
o Added Byte Sequence field value wrapping. | ||||
- -10 | ||||
o Removed "related response" and "@request-response" in favor | ||||
of generic "req" parameter. | ||||
o Editorial fixes to comply with HTTP extension style | ||||
guidelines. | ||||
o Add security consideration on message content. | ||||
- -09 | ||||
o Explained key formats better. | ||||
o Removed "host" and "date" from most examples. | ||||
o Fixed query component generation. | ||||
o Renamed "signature input" and "signature input string" to | ||||
"signature base". | ||||
o Added consideration for semantically equivalent field | ||||
values. | ||||
- -08 | ||||
o Editorial fixes. | ||||
o Changed "specialty component" to "derived component". | ||||
o Expanded signature input generation and ABNF rules. | ||||
o Added Ed25519 algorithm. | ||||
o Clarified encoding of ECDSA signature. | ||||
o Clarified use of non-deterministic algorithms. | ||||
- -07 | ||||
o Added security and privacy considerations. | ||||
o Added pointers to algorithm values from definition sections. | ||||
o Expanded IANA registry sections. | ||||
o Clarified that the signing and verification algorithms take | ||||
application requirements as inputs. | ||||
o Defined "signature targets" of request, response, and | ||||
related-response for specialty components. | ||||
- -06 | ||||
o Updated language for message components, including | ||||
identifiers and values. | ||||
o Clarified that Signature-Input and Signature are fields | ||||
which can be used as headers or trailers. | ||||
o Add "Accept-Signature" field and semantics for signature | ||||
negotiation. | ||||
o Define new specialty content identifiers, re-defined | ||||
request-target identifier. | ||||
o Added request-response binding. | ||||
- -05 | ||||
o Remove list prefixes. | ||||
o Clarify signature algorithm parameters. | ||||
o Update and fix examples. | ||||
o Add examples for ECC and HMAC. | ||||
- -04 | ||||
o Moved signature component definitions up to intro. | ||||
o Created formal function definitions for algorithms to | ||||
fulfill. | ||||
o Updated all examples. | ||||
o Added nonce parameter field. | ||||
- -03 | ||||
o Clarified signing and verification processes. | ||||
o Updated algorithm and key selection method. | ||||
o Clearly defined core algorithm set. | ||||
o Defined JOSE signature mapping process. | ||||
o Removed legacy signature methods. | ||||
o Define signature parameters separately from "signature" | ||||
object model. | ||||
o Define serialization values for signature-input header based | ||||
on signature input. | ||||
- -02 | ||||
o Removed editorial comments on document sources. | ||||
o Removed in-document issues list in favor of tracked issues. | ||||
o Replaced unstructured Signature header with Signature-Input | ||||
and Signature Dictionary Structured Header Fields. | ||||
o Defined content identifiers for individual Dictionary | ||||
members, e.g., "x-dictionary-field";key=member-name. | ||||
o Defined content identifiers for first N members of a List, | ||||
e.g., "x-list-field":prefix=4. | ||||
o Fixed up examples. | ||||
o Updated introduction now that it's adopted. | ||||
o Defined specialty content identifiers and a means to extend | ||||
them. | ||||
o Required signature parameters to be included in signature. | ||||
o Added guidance on backwards compatibility, detection, and | ||||
use of signature methods. | ||||
- -01 | ||||
o Strengthened requirement for content identifiers for header | ||||
fields to be lower-case (changed from SHOULD to MUST). | ||||
o Added real example values for Creation Time and Expiration | ||||
Time. | ||||
o Minor editorial corrections and readability improvements. | ||||
- -00 | ||||
o Initialized from draft-richanna-http-message-signatures-00, | ||||
following adoption by the working group. | ||||
* draft-richanna-http-message-signatures | ||||
- -00 | ||||
o Converted to xml2rfc v3 and reformatted to comply with RFC | ||||
style guides. | ||||
o Removed Signature auth-scheme definition and related | ||||
content. | ||||
o Removed conflicting normative requirements for use of | ||||
algorithm parameter. Now MUST NOT be relied upon. | ||||
o Removed Extensions appendix. | ||||
o Rewrote abstract and introduction to explain context and | ||||
need, and challenges inherent in signing HTTP messages. | ||||
o Rewrote and heavily expanded algorithm definition, retaining | ||||
normative requirements. | ||||
o Added definitions for key terms, referenced RFC 7230 for | ||||
HTTP terms. | ||||
o Added examples for canonicalization and signature generation | ||||
steps. | ||||
o Rewrote Signature header definition, retaining normative | ||||
requirements. | ||||
o Added default values for algorithm and expires parameters. | ||||
o Rewrote HTTP Signature Algorithms registry definition. | ||||
Added change control policy and registry template. Removed | ||||
suggested URI. | ||||
o Added IANA HTTP Signature Parameter registry. | ||||
o Added additional normative and informative references. | ||||
o Added Topics for Working Group Discussion section, to be | The editors would also like to thank the following individuals | |||
removed prior to publication as an RFC. | (listed in alphabetical order) for feedback, insight, and | |||
implementation of this document and its predecessors: Mark Adamcin, | ||||
Mark Allen, Paul Annesley, Karl Böhlmark, Stéphane Bortzmeyer, Sarven | ||||
Capadisli, Liam Dennehy, Stephen Farrell, Phillip Hallam-Baker, Tyler | ||||
Ham, Eric Holmes, Andrey Kislyuk, Adam Knight, Dave Lehn, Ilari | ||||
Liusvaara, Dave Longley, James H. Manger, Kathleen Moriarty, Yoav | ||||
Nir, Mark Nottingham, Adrian Palmer, Lucas Pardue, Roberto Polli, | ||||
Julian Reschke, Michael Richardson, Wojciech Rygielski, Rich Salz, | ||||
Adam Scarr, Cory J. Slep, Dirk Stein, Henry Story, Lukasz Szewc, | ||||
Chris Webber, and Jeffrey Yasskin. | ||||
Authors' Addresses | Authors' Addresses | |||
Annabelle Backman (editor) | Annabelle Backman (editor) | |||
Amazon | Amazon | |||
P.O. Box 81226 | P.O. Box 81226 | |||
Seattle, WA 98108-1226 | Seattle, WA 98108-1226 | |||
United States of America | United States of America | |||
Email: richanna@amazon.com | Email: richanna@amazon.com | |||
URI: https://www.amazon.com/ | URI: https://www.amazon.com/ | |||
Justin Richer (editor) | Justin Richer (editor) | |||
Bespoke Engineering | Bespoke Engineering | |||
Email: ietf@justin.richer.org | Email: ietf@justin.richer.org | |||
URI: https://bspk.io/ | URI: https://bspk.io/ | |||
Manu Sporny | Manu Sporny | |||
Digital Bazaar | Digital Bazaar | |||
203 Roanoke Street W. | 203 Roanoke Street W. | |||
Blacksburg, VA 24060 | Blacksburg, VA 24060 | |||
United States of America | United States of America | |||
Email: msporny@digitalbazaar.com | Email: msporny@digitalbazaar.com | |||
URI: https://manu.sporny.org/ | ||||
End of changes. 570 change blocks. | ||||
1868 lines changed or deleted | 1641 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |