draft-ietf-httpbis-message-signatures-05.txt | draft-ietf-httpbis-message-signatures-06.txt | |||
---|---|---|---|---|
HTTP A. Backman, Ed. | HTTP A. Backman, Ed. | |||
Internet-Draft Amazon | Internet-Draft Amazon | |||
Intended status: Standards Track J. Richer | Intended status: Standards Track J. Richer | |||
Expires: 10 December 2021 Bespoke Engineering | Expires: 14 February 2022 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
8 June 2021 | 13 August 2021 | |||
Signing HTTP Messages | HTTP Message Signatures | |||
draft-ietf-httpbis-message-signatures-05 | draft-ietf-httpbis-message-signatures-06 | |||
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 | |||
content within 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. | reaching the verifier. This document also describes a means for | |||
requesting that a signature be applied to a subsequent HTTP message | ||||
in an ongoing HTTP exchange. | ||||
Note to Readers | Note to Readers | |||
_RFC EDITOR: please remove this section before publication_ | _RFC EDITOR: please remove this section before publication_ | |||
Discussion of this draft takes place on the HTTP working group | Discussion of this draft takes place on the HTTP working group | |||
mailing list (ietf-http-wg@w3.org), which is archived at | mailing list (ietf-http-wg@w3.org), which is archived at | |||
https://lists.w3.org/Archives/Public/ietf-http-wg/ | https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
(https://lists.w3.org/Archives/Public/ietf-http-wg/). | (https://lists.w3.org/Archives/Public/ietf-http-wg/). | |||
skipping to change at page 2, line 10 ¶ | skipping to change at page 2, line 10 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on 10 December 2021. | This Internet-Draft will expire on 14 February 2022. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2021 IETF Trust and the persons identified as the | Copyright (c) 2021 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 (https://trustee.ietf.org/ | |||
license-info) in effect on the date of publication of this document. | license-info) in effect on the date of publication of this document. | |||
Please review these documents carefully, as they describe your rights | Please review these documents carefully, as they describe your rights | |||
and restrictions with respect to this document. Code Components | and restrictions with respect to this document. Code Components | |||
extracted from this document must include Simplified BSD License text | extracted from this document must include Simplified BSD License text | |||
as described in Section 4.e of the Trust Legal Provisions and are | as described in Section 4.e of the Trust Legal Provisions and are | |||
provided without warranty as described in the Simplified BSD License. | provided without warranty as described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 4 | 1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 5 | |||
1.2. HTTP Message Transformations . . . . . . . . . . . . . . 5 | 1.2. HTTP Message Transformations . . . . . . . . . . . . . . 5 | |||
1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 5 | 1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 6 | |||
1.4. Conventions and Terminology . . . . . . . . . . . . . . . 6 | 1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | |||
1.5. Application of HTTP Message Signatures . . . . . . . . . 8 | 1.5. Application of HTTP Message Signatures . . . . . . . . . 9 | |||
2. HTTP Message Signature Covered Content . . . . . . . . . . . 8 | 2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | |||
2.1. HTTP Headers . . . . . . . . . . . . . . . . . . . . . . 9 | 2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
2.1.1. Canonicalized Structured HTTP Headers . . . . . . . . 10 | 2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 11 | |||
2.1.2. Canonicalization Examples . . . . . . . . . . . . . . 10 | 2.1.2. Canonicalization Examples . . . . . . . . . . . . . . 11 | |||
2.2. Dictionary Structured Field Members . . . . . . . . . . . 11 | 2.2. Dictionary Structured Field Members . . . . . . . . . . . 12 | |||
2.2.1. Canonicalization Examples . . . . . . . . . . . . . . 11 | 2.2.1. Canonicalization Examples . . . . . . . . . . . . . . 12 | |||
2.3. Specialty Content Fields . . . . . . . . . . . . . . . . 11 | 2.3. Specialty Components . . . . . . . . . . . . . . . . . . 13 | |||
2.3.1. Request Target . . . . . . . . . . . . . . . . . . . 12 | 2.3.1. Signature Parameters . . . . . . . . . . . . . . . . 14 | |||
2.3.2. Signature Parameters . . . . . . . . . . . . . . . . 13 | 2.3.2. Method . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
2.4. Creating the Signature Input String . . . . . . . . . . . 14 | 2.3.3. Target URI . . . . . . . . . . . . . . . . . . . . . 16 | |||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 16 | 2.3.4. Authority . . . . . . . . . . . . . . . . . . . . . . 16 | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 17 | 2.3.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 18 | 2.3.6. Request Target . . . . . . . . . . . . . . . . . . . 17 | |||
3.2.1. Enforcing Application Requirements . . . . . . . . . 20 | 2.3.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 21 | 2.3.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 21 | 2.3.9. Query Parameters . . . . . . . . . . . . . . . . . . 20 | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 22 | 2.3.10. Status Code . . . . . . . . . . . . . . . . . . . . . 21 | |||
3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 22 | 2.3.11. Request-Response Signature Binding . . . . . . . . . 21 | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 23 | 2.4. Creating the Signature Input String . . . . . . . . . . . 23 | |||
3.3.5. JSON Web Signature (JWS) algorithms . . . . . . . . . 23 | ||||
4. Including a Message Signature in a Message . . . . . . . . . 23 | 3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 25 | |||
4.1. The 'Signature-Input' HTTP Header . . . . . . . . . . . . 24 | 3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 25 | |||
4.2. The 'Signature' HTTP Header . . . . . . . . . . . . . . . 24 | 3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 27 | |||
4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 25 | 3.2.1. Enforcing Application Requirements . . . . . . . . . 29 | |||
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 | 3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 29 | |||
5.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 26 | 3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 30 | |||
5.1.1. Registration Template . . . . . . . . . . . . . . . . 26 | 3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 31 | |||
5.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 27 | 3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 31 | |||
5.2. HTTP Signature Metadata Parameters Registry . . . . . . . 28 | 3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 31 | |||
5.2.1. Registration Template . . . . . . . . . . . . . . . . 28 | 3.3.5. JSON Web Signature (JWS) algorithms . . . . . . . . . 32 | |||
5.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 29 | 4. Including a Message Signature in a Message . . . . . . . . . 32 | |||
5.3. HTTP Signature Specialty Content Identifiers Registry . . 29 | 4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 33 | |||
5.3.1. Registration Template . . . . . . . . . . . . . . . . 29 | 4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 33 | |||
5.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 29 | 4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 34 | |||
6. Security Considerations . . . . . . . . . . . . . . . . . . . 30 | 5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 36 | |||
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 30 | 5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 37 | |||
7.1. Normative References . . . . . . . . . . . . . . . . . . 30 | 5.2. Processing an Accept-Signature . . . . . . . . . . . . . 37 | |||
7.2. Informative References . . . . . . . . . . . . . . . . . 31 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 38 | |||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 32 | 6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 38 | |||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 32 | 6.1.1. Registration Template . . . . . . . . . . . . . . . . 39 | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 32 | 6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 39 | |||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 33 | 6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 41 | |||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 33 | 6.2.1. Registration Template . . . . . . . . . . . . . . . . 41 | |||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 34 | 6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 41 | |||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 35 | 6.3. HTTP Signature Specialty Component Identifiers | |||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 35 | Registry . . . . . . . . . . . . . . . . . . . . . . . . 41 | |||
B.2.1. Minimal Signature Header using rsa-pss-sha512 . . . . 36 | 6.3.1. Registration Template . . . . . . . . . . . . . . . . 42 | |||
B.2.2. Header Coverage using rsa-pss-sha512 . . . . . . . . 36 | 6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 42 | |||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 37 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 43 | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 37 | 8. References . . . . . . . . . . . . . . . . . . . . . . . . . 44 | |||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 38 | 8.1. Normative References . . . . . . . . . . . . . . . . . . 44 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 38 | 8.2. Informative References . . . . . . . . . . . . . . . . . 45 | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 39 | Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 46 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 | Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 46 | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 46 | ||||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 46 | ||||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 47 | ||||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 48 | ||||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 49 | ||||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 49 | ||||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 50 | ||||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 50 | ||||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 51 | ||||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 52 | ||||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 53 | ||||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 53 | ||||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 55 | ||||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 56 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 59 | ||||
1. Introduction | 1. Introduction | |||
Message integrity and authenticity are important security properties | Message integrity and authenticity are important security properties | |||
that are critical to the secure operation of many HTTP applications. | that are 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 | However, TLS only guarantees these properties over a single TLS | |||
connection, and the path between client and application may be | connection, and the path between client and application may be | |||
composed of multiple independent TLS connections (for example, if the | composed of multiple independent TLS connections (for example, if the | |||
skipping to change at page 4, line 14 ¶ | skipping to change at page 4, line 28 ¶ | |||
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, | |||
or to use features necessary to provide message authenticity. | or to use features necessary to provide message authenticity. | |||
Furthermore, some applications require the binding of an application- | Furthermore, some applications require the binding of an application- | |||
level key to the HTTP message, separate from any TLS certificates in | level key to the HTTP message, separate from any TLS certificates in | |||
use. Consequently, while TLS can meet message integrity and | use. Consequently, while TLS can meet message integrity and | |||
authenticity needs for many HTTP-based applications, it is not a | authenticity needs for many HTTP-based applications, it is not a | |||
universal solution. | universal solution. | |||
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 content within an HTTP message. The mechanism | and authenticity for components of an HTTP message. The mechanism | |||
allows applications to create digital signatures or message | allows applications to create digital signatures or message | |||
authentication codes (MACs) over only that content within the message | authentication codes (MACs) over only the components of the message | |||
that is meaningful and appropriate for the application. Strict | that are 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 any of the many | signature even if the message has been transformed in any of the many | |||
ways permitted by HTTP. | ways permitted by HTTP. | |||
The mechanism described in this document consists of three parts: | The signing mechanism described in this document consists of three | |||
parts: | ||||
* A common nomenclature and canonicalization rule set for the | * A common nomenclature and canonicalization rule set for the | |||
different protocol elements and other content within HTTP | different protocol elements and other components of HTTP messages. | |||
messages. | ||||
* Algorithms for generating and verifying signatures over HTTP | * Algorithms for generating and verifying signatures over HTTP | |||
message content using this nomenclature and rule set. | message components using this nomenclature and rule set. | |||
* A mechanism for attaching a signature and related metadata to an | * A mechanism for attaching a signature and related metadata to an | |||
HTTP message. | HTTP message. | |||
This document also provides a mechanism for one party to signal to | ||||
another party that a signature is desired in one or more subsequent | ||||
messages. This optional negotiation mechanism can be used along with | ||||
opportunistic or application-driven message signatures by either | ||||
party. | ||||
1.1. Requirements Discussion | 1.1. Requirements Discussion | |||
HTTP permits and sometimes requires intermediaries to transform | HTTP permits and sometimes requires intermediaries to transform | |||
messages in a variety of ways. This may result in a recipient | messages in a variety of ways. This may 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 a signature over the raw bytes of the sender's HTTP | unable to verify a signature over the raw bytes of the sender's HTTP | |||
message, as verifying digital signatures or MACs requires both signer | message, as verifying digital signatures or MACs requires both signer | |||
and verifier to have the exact same signed content. Since the raw | and verifier to have the exact same signature input. Since the exact | |||
bytes of the message cannot be relied upon as signed content, the | raw bytes of the message cannot be relied upon as a reliable source | |||
signer and verifier must derive the signed content from their | of signature input, the signer and verifier must derive the signature | |||
respective versions of the message, via a mechanism that is resilient | input from their respective versions of the message, via a mechanism | |||
to safe changes that do not alter the meaning of the message. | that is resilient to safe 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 body, or the | particular piece of information in a message (e.g., the body, or the | |||
"Date" header field) is relevant. Thus a general purpose solution | "Date" header field) is relevant. Thus a general purpose solution | |||
must provide signers with some degree of control over which message | must provide signers with some degree of control over which message | |||
content is signed. | 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 | |||
HTTPClient library (https://openjdk.java.net/groups/net/httpclient/ | HTTPClient library (https://openjdk.java.net/groups/net/httpclient/ | |||
intro.html)). These applications need to be able to generate and | intro.html)). These applications need to be able to generate and | |||
verify signatures despite incomplete knowledge of the HTTP message. | verify signatures despite incomplete knowledge of the HTTP message. | |||
1.2. HTTP Message Transformations | 1.2. HTTP Message Transformations | |||
skipping to change at page 5, line 47 ¶ | skipping to change at page 6, line 24 ¶ | |||
* Addition or removal of a transfer coding ([MESSAGING], | * Addition or removal of a transfer coding ([MESSAGING], | |||
Section 5.7.2). | Section 5.7.2). | |||
* Addition of header fields such as "Via" ([MESSAGING], | * Addition of header fields such as "Via" ([MESSAGING], | |||
Section 5.7.1) and "Forwarded" ([RFC7239], Section 4). | Section 5.7.1) and "Forwarded" ([RFC7239], Section 4). | |||
1.3. Safe Transformations | 1.3. Safe Transformations | |||
Based on the definition of HTTP and the requirements described above, | Based on the definition of HTTP and the requirements described above, | |||
we can identify certain types of transformations that should not | we can identify certain types of transformations that should not | |||
prevent signature verification, even when performed on content | prevent signature verification, even when performed on message | |||
covered by the signature. The following list describes those | components covered by the signature. The following list describes | |||
transformations: | those transformations: | |||
* Combination of header fields with the same field name. | * Combination of header fields with the same field name. | |||
* Reordering of header fields with different names. | * Reordering of header fields with different names. | |||
* Conversion between different versions of the HTTP protocol (e.g., | * Conversion between different versions of the HTTP protocol (e.g., | |||
HTTP/1.x to HTTP/2, or vice-versa). | HTTP/1.x to HTTP/2, or vice-versa). | |||
* Changes in casing (e.g., "Origin" to "origin") of any case- | * Changes in casing (e.g., "Origin" to "origin") of any case- | |||
insensitive content such as header field names, request URI | insensitive components such as header field names, request URI | |||
scheme, or host. | scheme, or host. | |||
* Addition or removal of leading or trailing whitespace to a header | * Addition or removal of leading or trailing whitespace to a header | |||
field value. | field value. | |||
* Addition or removal of "obs-folds". | * Addition or removal of "obs-folds". | |||
* Changes to the "request-target" and "Host" header field that when | * Changes to the "request-target" and "Host" header field that when | |||
applied together do not result in a change to the message's | applied together do not result in a change to the message's | |||
effective request URI, as defined in Section 5.5 of [MESSAGING]. | effective request URI, as defined in Section 5.5 of [MESSAGING]. | |||
Additionally, all changes to content not covered by the signature are | Additionally, all changes to components not covered by the signature | |||
considered safe. | are considered safe. | |||
1.4. Conventions and Terminology | 1.4. 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", "absolute- | The terms "HTTP message", "HTTP request", "HTTP response", "absolute- | |||
skipping to change at page 6, line 52 ¶ | skipping to change at page 7, line 31 ¶ | |||
For brevity, the term "signature" on its own is used in this document | For brevity, the term "signature" on its own is used in this document | |||
to refer to both digital signatures and keyed MACs. Similarly, the | to refer to both digital signatures and keyed MACs. Similarly, the | |||
verb "sign" refers to the generation of either a digital signature or | verb "sign" refers to the generation of either a digital signature or | |||
keyed MAC over a given input string. The qualified term "digital | keyed MAC over a given input string. The qualified term "digital | |||
signature" refers specifically to the output of an asymmetric | signature" refers specifically to the output of an asymmetric | |||
cryptographic signing operation. | cryptographic signing operation. | |||
In addition to those listed above, this document uses the following | In addition to those listed above, this document uses the following | |||
terms: | terms: | |||
Signer: | HTTP Message Signature: | |||
A digital signature or keyed MAC that covers one or more portions | ||||
of an HTTP message. Note that a given HTTP Message can contain | ||||
multiple HTTP Message Signatures. | ||||
Signer: | ||||
The entity that is generating or has generated an HTTP Message | The entity that is generating or has generated an HTTP Message | |||
Signature. | Signature. Note that multiple entities can act as signers and | |||
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. | |||
Covered Content: | HTTP Message Component: | |||
An ordered list of content identifiers for headers (Section 2.1) | A portion of an HTTP message that is capable of being covered by | |||
and specialty content (Section 2.3) that indicates the metadata | an HTTP Message Signature. | |||
and message content that is covered by the signature, not | ||||
including the "@signature-params" specialty field itself. | ||||
HTTP Signature Algorithm: | HTTP Message Component Identifier: | |||
A value that uniquely identifies a specific HTTP Message Component | ||||
in respect to a particular HTTP Message Signature and the HTTP | ||||
Message it applies to. | ||||
HTTP Message Component Value: | ||||
The value associated with a given component identifier within the | ||||
context of a particular HTTP Message. Component values are | ||||
derived from the HTTP Message and are usually subject to a | ||||
canonicalization process. | ||||
Covered Components: | ||||
An ordered set of HTTP message component identifiers for fields | ||||
(Section 2.1) and specialty components (Section 2.3) that | ||||
indicates the set of message components covered by the signature, | ||||
not including the "@signature-params" specialty identifier itself. | ||||
The order of this set is preserved and communicated between the | ||||
signer and verifier to facilitate reconstruction of the signature | ||||
input. | ||||
Signature Input: | ||||
The sequence of bytes processed by the HTTP Message Signature | ||||
algorithm to produce the HTTP Message Signature. The signature | ||||
input is generated by the signer and verifier using the covered | ||||
components set and the HTTP Message. | ||||
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. When expressed | verification process for the signature. When expressed | |||
explicitly, the value maps to a string defined in the HTTP | explicitly, the value maps to a string defined in the HTTP | |||
Signature Algorithms Registry defined in this document. | Signature Algorithms Registry defined in this document. | |||
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 | |||
used. | used. | |||
skipping to change at page 8, line 13 ¶ | skipping to change at page 9, line 23 ¶ | |||
value. | value. | |||
1.5. Application of HTTP Message Signatures | 1.5. Application of HTTP Message Signatures | |||
HTTP Message Signatures are designed to be a general-purpose security | HTTP Message Signatures are designed to be a general-purpose security | |||
mechanism applicable in a wide variety of circumstances and | mechanism applicable in a wide variety of circumstances and | |||
applications. In order to properly and safely apply HTTP Message | applications. In order to properly and safely apply HTTP Message | |||
Signatures, an application or profile of this specification MUST | Signatures, an application or profile of this specification MUST | |||
specify all of the following items: | specify all of the following items: | |||
* The set of content identifiers (Section 2) that are expected and | * The set of component identifiers (Section 2) that are expected and | |||
required. For example, an authorization protocol could mandate | required. For example, an authorization protocol could mandate | |||
that the "Authorization" header be covered to protect the | that the "Authorization" header be covered to protect the | |||
authorization credentials and mandate the signature parameters | authorization credentials and mandate the signature parameters | |||
contain a "created" parameter, while an API expecting HTTP message | contain a "created" parameter, while an API expecting HTTP message | |||
bodies could require the "Digest" header to be present and | bodies could require the "Digest" header to be present and | |||
covered. | covered. | |||
* 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 | signature. An application will usually use the "keyid" parameter | |||
of the signature parameters (Section 2.3.2) and define rules for | of the signature parameters (Section 2.3.1) 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. | known from other means. | |||
* A means of determining the signature algorithm used to verify the | * A means of determining the signature algorithm used to verify the | |||
signature content is appropriate for the key material. For | signature is appropriate for the key material. For example, the | |||
example, the process could use the "alg" parameter of the | process could use the "alg" parameter of the signature parameters | |||
signature parameters (Section 2.3.2) to state the algorithm | (Section 2.3.1) to state the algorithm explicitly, derive the | |||
explicitly, derive the algorithm from the key material, or use | algorithm from the key material, or use some pre-configured | |||
some pre-configured algorithm agreed upon by the signer and | algorithm agreed upon by the signer and verifier. | |||
verifier. | ||||
* A means of determining that a given key and algorithm presented in | * A means of determining that a given key and algorithm presented in | |||
the request are appropriate for the request being made. For | the request are appropriate for the request being made. 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. | |||
An application using signatures also has to ensure that the verifier | ||||
will have access to all required information to re-create the | ||||
signature input string. For example, a server behind a reverse proxy | ||||
would need to know the original request URI to make use of | ||||
identifiers like "@target-uri". Additionally, an application using | ||||
signatures in responses would need to ensure that clients receiving | ||||
signed responses have access to all the signed portions, including | ||||
any portions of the request that were signed by the server. | ||||
The details of this kind of profiling are the purview of the | The details of this kind of profiling are the purview of the | |||
application and outside the scope of this specification. | application and outside the scope of this specification. | |||
2. HTTP Message Signature Covered Content | 2. HTTP Message Components | |||
In order to allow signers and verifiers to establish which content is | In order to allow signers and verifiers to establish which components | |||
covered by a signature, this document defines content identifiers for | are covered by a signature, this document defines component | |||
data items covered by an HTTP Message Signature as well as the means | identifiers for components covered by an HTTP Message Signature, a | |||
set of rules for deriving and canonicalizing the values associated | ||||
with these component identifiers from the HTTP Message, and the means | ||||
for combining these canonicalized values into a signature input | for combining these canonicalized values into a signature input | |||
string. | string. The values for these items MUST be accessible to both the | |||
signer and the verifier of the message, which means these are usually | ||||
derived from aspects of the HTTP message or signature itself. | ||||
Some content within HTTP messages can undergo transformations that | Some HTTP message components can undergo transformations that change | |||
change the bitwise value without altering meaning of the content (for | the bitwise value without altering meaning of the component's value | |||
example, the merging together of header fields with the same name). | (for example, the merging together of header fields with the same | |||
Message content must therefore be canonicalized before it is signed, | name). Message component values must therefore be canonicalized | |||
to ensure that a signature can be verified despite such intermediary | before it is signed, to ensure that a signature can be verified | |||
transformations. This document defines rules for each content | despite such intermediary transformations. This document defines | |||
identifier that transform the identifier's associated content into | rules for each component identifier that transform the identifier's | |||
such a canonical form. | associated component value into such a canonical form. | |||
Content identifiers are defined using production grammar defined by | Component identifiers are serialized using the production grammar | |||
RFC8941, Section 4 [RFC8941]. The content identifier is an "sf- | defined by RFC8941, Section 4 [RFC8941]. The component identifier | |||
string" value. The content identifier type MAY define parameters | itself is an "sf-string" value and MAY define parameters which are | |||
which are included using the "parameters" rule. | included using the "parameters" rule. | |||
content-identifier = sf-string parameters | component-identifier = sf-string parameters | |||
Note that this means the value of the identifier itself is encased in | Note that this means the value of the component identifier itself is | |||
double quotes, with parameters following as a semicolon-separated | encased in double quotes, with parameters following as a semicolon- | |||
list, such as ""cache-control"", ""date"", or ""@signature-params"". | separated list, such as ""cache-control"", ""date"", or ""@signature- | |||
params"". | ||||
The following sections define content identifier types, their | The following sections define component identifier types, their | |||
parameters, their associated content, and their canonicalization | parameters, their associated values, and the canonicalization rules | |||
rules. The method for combining content identifiers into the | for their values. The method for combining component identifiers | |||
signature input string is defined in Section 2.4. | into the signature input is defined in Section 2.4. | |||
2.1. HTTP Headers | 2.1. HTTP Fields | |||
The content identifier for an HTTP header is the lowercased form of | The component identifier for an HTTP field is the lowercased form of | |||
its header field name. While HTTP header field names are case- | its field name. While HTTP field names are case-insensitive, | |||
insensitive, implementations MUST use lowercased field names (e.g., | implementations MUST use lowercased field names (e.g., "content- | |||
"content-type", "date", "etag") when using them as content | type", "date", "etag") when using them as component identifiers. | |||
identifiers. | ||||
Unless overridden by additional parameters and rules, the HTTP header | Unless overridden by additional parameters and rules, the HTTP field | |||
field value MUST be canonicalized with the following steps: | value MUST be canonicalized with the following steps: | |||
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 header field in the message, in the order that they occur (or | the field in the message, in the order that they occur (or will | |||
will occur) in the message. | occur) 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. | |||
3. Concatenate the list items together, with a comma "," and space " | 3. Concatenate the list items together, with a comma "," and space " | |||
" between each item. | " between each item. | |||
The resulting string is the canonicalized value. | The resulting string is the canonicalized component value. | |||
2.1.1. Canonicalized Structured HTTP Headers | 2.1.1. Canonicalized Structured HTTP Fields | |||
If value of the the HTTP header in question is a structured field | If value of the the HTTP field in question is a structured field | |||
([RFC8941]), the content identifier MAY include the "sf" parameter. | ([RFC8941]), the component identifier MAY include the "sf" parameter. | |||
If this parameter is included, the HTTP header value MUST be | If this parameter is included, the HTTP field value MUST be | |||
canonicalized using the rules specified in Section 4 of RFC8941 | canonicalized using the rules specified in Section 4 of RFC8941 | |||
[RFC8941]. Note that this process will replace any optional | [RFC8941]. For example, this process will replace any optional | |||
whitespace with a single space. | internal whitespace with a single space character. | |||
The resulting string is used as the field value input in Section 2.1. | The resulting string is used as the component value in Section 2.1. | |||
2.1.2. Canonicalization Examples | 2.1.2. Canonicalization Examples | |||
This section contains non-normative examples of canonicalized values | This section contains non-normative examples of canonicalized values | |||
for header fields, given the following example HTTP message: | for header fields, given the following example HTTP message: | |||
Server: www.example.com | Host: www.example.com | |||
Date: Tue, 07 Jun 2014 20:51:35 GMT | Date: Tue, 07 Jun 2014 20:51:35 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. | |||
X-Empty-Header: | X-Empty-Header: | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | ||||
The following table shows example canonicalized values for header | The following table shows example canonicalized values for header | |||
fields, given that message: | fields, given that message: | |||
+=====================+==================================+ | +=====================+==================================+ | |||
| Header Field | Canonicalized Value | | | Header Field | Canonicalized Value | | |||
+=====================+==================================+ | +=====================+==================================+ | |||
| "cache-control" | max-age=60, must-revalidate | | | "cache-control" | max-age=60, must-revalidate | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "date" | Tue, 07 Jun 2014 20:51:35 GMT | | | "date" | Tue, 07 Jun 2014 20:51:35 GMT | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "server" | www.example.com | | | "host" | www.example.com | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "x-empty-header" | | | | "x-empty-header" | | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "x-obs-fold-header" | Obsolete line folding. | | | "x-obs-fold-header" | Obsolete line folding. | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "x-ows-header" | Leading and trailing whitespace. | | | "x-ows-header" | Leading and trailing whitespace. | | |||
+---------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| "x-dictionary" | a=1, b=2;x=1;y=2, c=(a b c) | | ||||
+---------------------+----------------------------------+ | ||||
| "x-dictionary";sf | a=1, b=2;x=1;y=2, c=(a b c) | | ||||
+---------------------+----------------------------------+ | ||||
Table 1: Non-normative examples of header field | Table 1: Non-normative examples of header field | |||
canonicalization. | canonicalization. | |||
2.2. Dictionary Structured Field Members | 2.2. Dictionary Structured Field Members | |||
An individual member in the value of a Dictionary Structured Field is | An individual member in the value of a Dictionary Structured Field is | |||
identified by using the parameter "key" on the content identifier for | identified by using the parameter "key" on the component identifier | |||
the header. The value of this parameter is a the key being | for the field. The value of this parameter is a the key being | |||
identified, without any parameters present on that key in the | identified, without any parameters present on that key in the | |||
original dictionary. | original dictionary. | |||
An individual member in the value of a Dictionary Structured Field is | An individual member in the 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 RFC8941 [RFC8941] on a Dictionary containing only | Section 4.1.2 of RFC8941 [RFC8941] on a Dictionary containing only | |||
that member. | that item. | |||
2.2.1. Canonicalization Examples | 2.2.1. Canonicalization Examples | |||
This section contains non-normative examples of canonicalized values | This section contains non-normative examples of canonicalized values | |||
for Dictionary Structured Field Members given the following example | for Dictionary Structured Field Members given the following example | |||
header field, whose value is assumed to be a Dictionary: | header field, whose value is known to be a Dictionary: | |||
X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | |||
The following table shows example canonicalized values for different | The following table shows example canonicalized values for different | |||
content identifiers, given that field: | component identifiers, given that field: | |||
+======================+=====================+ | +======================+=================+ | |||
| Content Identifier | Canonicalized Value | | | Component Identifier | Component Value | | |||
+======================+=====================+ | +======================+=================+ | |||
| "x-dictionary";key=a | 1 | | | "x-dictionary";key=a | 1 | | |||
+----------------------+---------------------+ | +----------------------+-----------------+ | |||
| "x-dictionary";key=b | 2;x=1;y=2 | | | "x-dictionary";key=b | 2;x=1;y=2 | | |||
+----------------------+---------------------+ | +----------------------+-----------------+ | |||
| "x-dictionary";key=c | (a, b, c) | | | "x-dictionary";key=c | (a, b, c) | | |||
+----------------------+---------------------+ | +----------------------+-----------------+ | |||
Table 2: Non-normative examples of | Table 2: Non-normative examples of | |||
Dictionary member canonicalization. | Dictionary member canonicalization. | |||
2.3. Specialty Content Fields | 2.3. Specialty Components | |||
Content not found in an HTTP header can be included in the signature | ||||
base string by defining a content identifier and the canonicalization | ||||
method for its content. | ||||
To differentiate specialty content identifiers from HTTP headers, | Message components not found in an HTTP field can be included in the | |||
specialty content identifiers MUST start with the "at" "@" character. | signature input by defining a component identifier and the | |||
This specification defines the following specialty content | canonicalization method for its component value. | |||
identifiers: | ||||
@request-target The target request endpoint. (Section 2.3.1) | To differentiate specialty component identifiers from HTTP fields, | |||
specialty component identifiers MUST start with the "at" "@" | ||||
character. This specification defines the following specialty | ||||
component identifiers: | ||||
@signature-params The signature metadata parameters for this | @signature-params The signature metadata parameters for this | |||
signature. (Section 2.3.2) | signature. (Section 2.3.1) | |||
Additional specialty content identifiers MAY be defined and | @method The method used for a request. (Section 2.3.2) | |||
registered in the HTTP Signatures Specialty Content Identifier | ||||
Registry. (Section 5.3) | ||||
2.3.1. Request Target | @target-uri The full target URI for a request. (Section 2.3.3) | |||
The request target endpoint, consisting of the request method and the | @authority The authority of the target URI for a request. | |||
path and query of the effective request URI, is identified by the | (Section 2.3.4) | |||
"@request-target" identifier. | ||||
Its value is canonicalized as follows: | @scheme The scheme of the target URI for a request. (Section 2.3.5) | |||
1. Take the lowercased HTTP method of the message. | @request-target The request target. (Section 2.3.6) | |||
2. Append a space " ". | @path The absolute path portion of the target URI for a request. | |||
(Section 2.3.7) | ||||
3. Append the path and query of the request target of the message, | @query The query portion of the target URI for a request. | |||
formatted according to the rules defined for the :path pseudo- | (Section 2.3.8) | |||
header in [HTTP2], Section 8.1.2.3. The resulting string is the | ||||
canonicalized value. | ||||
2.3.1.1. Canonicalization Examples | @query-params The parsed query parameters of the target URI for a | |||
request. (Section 2.3.9) | ||||
The following table contains non-normative example HTTP messages and | @status The status code for a response. (Section 2.3.10). | |||
their canonicalized "@request-target" values. | ||||
+=========================+=================+ | @request-response A signature from a request message that resulted | |||
|HTTP Message | @request-target | | in this response message. (Section 2.3.11) | |||
+=========================+=================+ | ||||
| POST /?param=value HTTP/1.1| post | | ||||
| Host: www.example.com | /?param=value | | ||||
+-------------------------+-----------------+ | ||||
| POST /a/b HTTP/1.1 | post /a/b | | ||||
| Host: www.example.com | | | ||||
+-------------------------+-----------------+ | ||||
| GET http://www.example.com/a/ HTTP/1.1| get /a/ | | ||||
+-------------------------+-----------------+ | ||||
| GET http://www.example.com HTTP/1.1| get / | | ||||
+-------------------------+-----------------+ | ||||
| CONNECT server.example.com:80 HTTP/1.1| connect / | | ||||
| Host: server.example.com| | | ||||
+-------------------------+-----------------+ | ||||
| OPTIONS * HTTP/1.1 | options * | | ||||
| Host: server.example.com| | | ||||
+-------------------------+-----------------+ | ||||
Table 3: Non-normative examples of "@request-target" | Additional specialty component identifiers MAY be defined and | |||
canonicalization. | registered in the HTTP Signatures Specialty Component Identifier | |||
Registry. (Section 6.3) | ||||
2.3.2. Signature Parameters | 2.3.1. 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/or verification. | information regarding the signature's generation and verification, | |||
such as the set of covered components, a timestamp, identifiers for | ||||
The signature parameters specialty content is identified by the | verification key material, and other utilities. | |||
"@signature-params" identifier. | ||||
Its canonicalized value is the serialization of the signature | ||||
parameters for this signature, including the covered content list | ||||
with all associated parameters. | ||||
* "alg": The HTTP message signature algorithm from the HTTP Message | The signature parameters component identifier is "@signature-params". | |||
Signature Algorithm Registry, as an "sf-string" value. | ||||
* "keyid": The identifier for the key material as an "sf-string" | The signature parameters component value is the serialization of the | |||
value. | signature parameters for this signature, including the covered | |||
components set with all associated parameters. These parameters | ||||
include any of the following: | ||||
* "created": Creation time as an "sf-integer" UNIX timestamp value. | * "created": Creation time as an "sf-integer" UNIX timestamp value. | |||
Sub-second precision is not supported. | Sub-second precision is not supported. Inclusion of this | |||
parameter is RECOMMENDED. | ||||
* "expires": Expiration time as an "sf-integer" UNIX timestamp | * "expires": Expiration time as an "sf-integer" UNIX timestamp | |||
value. Sub-second precision is not supported. | value. Sub-second precision is not supported. | |||
* "nonce": A random unique value generated for this signature. | * "nonce": A random unique value generated for this signature. | |||
* "alg": The HTTP message signature algorithm from the HTTP Message | ||||
Signature Algorithm Registry, as an "sf-string" value. | ||||
* "keyid": The identifier for the key material as an "sf-string" | ||||
value. | ||||
Additional parameters can be defined in the HTTP Signature Parameters | Additional parameters can be defined in the HTTP Signature Parameters | |||
Registry (Section 5.2.2). | Registry (Section 6.2.2). | |||
The signature parameters are serialized using the rules in Section 4 | The signature parameters component value is serialized as a | |||
of RFC8941 [RFC8941] as follows: | parameterized inner list using the rules in Section 4 of RFC8941 | |||
[RFC8941] as follows: | ||||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. Determine an order for the content identifiers of the covered | 2. Determine an order for the component identifiers of the covered | |||
content. Once this order is chosen, it cannot be changed. | components. Once this order is chosen, it cannot be changed. | |||
This order MUST be the same order as used in creating the | ||||
signature input (Section 2.4). | ||||
3. Serialize the content identifiers of the covered content, | 3. Serialize the component identifiers of the covered components, | |||
including all parameters, as an ordered "inner-list" according to | including all parameters, as an ordered "inner-list" according to | |||
Section 4.1.1.1 of RFC8941 [RFC8941] and append this to the | Section 4.1.1.1 of RFC8941 [RFC8941] and append this to the | |||
output. | output. | |||
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 the chosen order | 5. Append the parameters to the "inner-list" in the chosen order | |||
according to Section 4.1.1.2 of RFC8941 [RFC8941], skipping | according to Section 4.1.1.2 of RFC8941 [RFC8941], skipping | |||
parameters that are not available or not used for this signature. | parameters that are not available or not used for this message | |||
signature. | ||||
6. The output contains the signature parameters value. | 6. The output contains the signature parameters component value. | |||
Note that the "inner-list" serialization is used for the covered | Note that the "inner-list" serialization is used for the covered | |||
content value instead of the "sf-list" serialization in order to | component value instead of the "sf-list" serialization in order to | |||
facilitate this value's additional inclusion in the "Signature-Input" | facilitate this value's inclusion in message fields such as the | |||
header's dictionary, as discussed in Section 4.1. | "Signature-Input" field's dictionary, as discussed in Section 4.1. | |||
This example shows a canonicalized value for the parameters of a | This example shows a canonicalized value for the parameters of a | |||
given signature: | given signature: | |||
("@request-target" "host" "date" "cache-control" "x-empty-header" \ | NOTE: '\' line wrapping per RFC 8792 | |||
("@target-uri" "@authority" "date" "cache-control" "x-empty-header" \ | ||||
"x-example");keyid="test-key-rsa-pss";alg="rsa-pss-sha512";\ | "x-example");keyid="test-key-rsa-pss";alg="rsa-pss-sha512";\ | |||
created=1618884475;expires=1618884775 | created=1618884475;expires=1618884775 | |||
Note that an HTTP message could contain multiple signatures, but only | Note that an HTTP message could contain multiple signatures, but only | |||
the signature parameters used for the current signature are included | the signature parameters used for the current signature are included | |||
in this field. | in the entry. | |||
2.3.2. Method | ||||
The "@method" component identifier refers to the HTTP method of a | ||||
request message. The component value of is canonicalized by taking | ||||
the value of the method as a string. Note that the method name is | ||||
case-sensitive as per [SEMANTICS] Section 9.1, and conventionally | ||||
standardized method names are uppercase US-ASCII. If used, the | ||||
"@method" component identifier MUST occur only once in the covered | ||||
components. | ||||
For example, the following request message: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@method" value: | ||||
"@method": POST | ||||
If used in a response message, the "@method" component identifier | ||||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
2.3.3. Target URI | ||||
The "@target-uri" component identifier refers to the target URI of a | ||||
request message. The component value is the full absolute target URI | ||||
of the request, potentially assembled from all available parts | ||||
including the authority and request target as described in | ||||
[SEMANTICS] Section 7.1. If used, the "@target-uri" component | ||||
identifier MUST occur only once in the covered components. | ||||
For example, the following message sent over HTTPS: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@target-uri" value: | ||||
"@target-uri": https://www.example.com/path?param=value | ||||
If used in a response message, the "@target-uri" component identifier | ||||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
2.3.4. Authority | ||||
The "@authority" component identifier refers to the authority | ||||
component of the target URI of the HTTP request message, as defined | ||||
in [SEMANTICS] 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 ":authority" pseudo-header. The value is the fully- | ||||
qualified authority component of the request, comprised of the host | ||||
and, optionally, port of the request target, as a string. The | ||||
component value MUST be normalized according to the rules in | ||||
[SEMANTICS] Section 4.2.3. Namely, the host name is normalized to | ||||
lowercase and the default port is omitted. If used, the "@authority" | ||||
component identifier MUST occur only once in the covered components. | ||||
For example, the following request message: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@authority" component value: | ||||
"@authority": www.example.com | ||||
If used in a response message, the "@authority" component identifier | ||||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
2.3.5. Scheme | ||||
The "@scheme" component identifier refers to the scheme of the target | ||||
URL of the HTTP request message. The component value is the scheme | ||||
as a string as defined in [SEMANTICS] Section 4.2. While the scheme | ||||
itself is case-insensitive, it MUST be normalized to lowercase for | ||||
inclusion in the signature input string. If used, the "@scheme" | ||||
component identifier MUST occur only once in the covered components. | ||||
For example, the following request message requested over plain HTTP: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@scheme" value: | ||||
"@scheme": http | ||||
If used in a response message, the "@scheme" component identifier | ||||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
2.3.6. Request Target | ||||
The "@request-target" component identifier refers to the full request | ||||
target of the HTTP request message, as defined in [SEMANTICS] | ||||
Section 7.1. The component value of the request target can take | ||||
different forms, depending on the type of request, as described | ||||
below. If used, the "@request-target" component identifier MUST | ||||
occur only once in the covered components. | ||||
For HTTP 1.1, the component value is equivalent to the request target | ||||
portion of the request line. However, this value is more difficult | ||||
to reliably construct in other versions of HTTP. Therefore, it is | ||||
NOT RECOMMENDED that this identifier be used when versions of HTTP | ||||
other than 1.1 might be in use. | ||||
The origin form value is combination of the absolute path and query | ||||
components of the request URL. For example, the following request | ||||
message: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@request-target" component value: | ||||
"@request-target": /path?param=value | ||||
The following request to an HTTP proxy with the absolute-form value, | ||||
containing the fully qualified target URI: | ||||
GET https://www.example.com/path?param=value HTTP/1.1 | ||||
Would result in the following "@request-target" component value: | ||||
"@request-target": https://www.example.com/path?param=value | ||||
The following CONNECT request with an authority-form value, | ||||
containing the host and port of the target: | ||||
CONNECT www.example.com:80 HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@request-target" component value: | ||||
"@request-target": www.example.com:80 | ||||
The following OPTIONS request message with the asterisk-form value, | ||||
containing a single asterisk "*" character: | ||||
OPTIONS * HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@request-target" component value: | ||||
"@request-target": * | ||||
If used in a response message, the "@request-target" component | ||||
identifier refers to the associated component value of the request | ||||
that triggered the response message being signed. | ||||
2.3.7. Path | ||||
The "@path" component identifier refers to the target path of the | ||||
HTTP request message. The component value is the absolute path of | ||||
the request target defined by [RFC3986], with no query component and | ||||
no trailing "?" character. The value is normalized according to the | ||||
rules in [SEMANTICS] Section 4.2.3. Namely, an empty path string is | ||||
normalized as a single slash "/" character, and path components are | ||||
represented by their values after decoding any percent-encoded | ||||
octets. If used, the "@path" component identifier MUST occur only | ||||
once in the covered components. | ||||
For example, the following request message: | ||||
POST /path?param=value HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@path" value: | ||||
"@path": /path | ||||
If used in a response message, the "@path" identifier refers to the | ||||
associated component value of the request that triggered the response | ||||
message being signed. | ||||
2.3.8. Query | ||||
The "@query" component identifier refers to the query component of | ||||
the HTTP request message. The component value is the entire | ||||
normalized query string defined by [RFC3986], including the leading | ||||
"?" character. The value is normalized according to the rules in | ||||
[SEMANTICS] Section 4.2.3. Namely, percent-encoded octets are | ||||
decoded. If used, the "@query" component identifier MUST occur only | ||||
once in the covered components. | ||||
For example, the following request message: | ||||
POST /path?param=value&foo=bar&baz=batman HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@query" value: | ||||
"@query": ?param=value&foo=bar&baz=batman | ||||
The following request message: | ||||
POST /path?queryString HTTP/1.1 | ||||
Host: www.example.com | ||||
Would result in the following "@query" value: | ||||
"@query": ?queryString | ||||
If used in a response message, the "@query" component identifier | ||||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
2.3.9. Query Parameters | ||||
If a request target URI uses HTML form parameters in the query string | ||||
as defined in [HTMLURL] Section 5, the "@query-params" component | ||||
identifier allows addressing of individual query parameters. The | ||||
query parameters MUST be parsed according to [HTMLURL] Section 5.1, | ||||
resulting in a list of ("nameString", "valueString") tuples. The | ||||
REQUIRED "name" parameter of each input identifier contains the | ||||
"nameString" of a single query parameter. Several different named | ||||
query parameters MAY be included in the covered components. Single | ||||
named parameters MAY occur in any order in the covered components. | ||||
The component value of a single named parameter is the the | ||||
"valueString" of the named query parameter defined by [HTMLURL] | ||||
Section 5.1, which is the value after percent-encoded octets are | ||||
decoded. Note that this value does not include any leading "?" | ||||
characters, equals sign "=", or separating "&" characters. Named | ||||
query parameters with an empty "valueString" are included with an | ||||
empty string as the component value. | ||||
If a parameter name occurs multiple times in a request, all parameter | ||||
values of that name MUST be included in separate signature input | ||||
lines in the order in which the parameters occur in the target URI. | ||||
For example for the following request: | ||||
POST /path?param=value&foo=bar&baz=batman&qux= HTTP/1.1 | ||||
Host: www.example.com | ||||
Indicating the "baz", "qux" and "param" named query parameters in | ||||
would result in the following "@query-param" value: | ||||
"@query-params";name="baz": batman | ||||
"@query-params";name="qux": | ||||
"@query-params";name="param": value | ||||
If used in a response message, the "@query-params" component | ||||
identifier refers to the associated component value of the request | ||||
that triggered the response message being signed. | ||||
2.3.10. Status Code | ||||
The "@status" component identifier refers to the three-digit numeric | ||||
HTTP status code of a response message as defined in [SEMANTICS] | ||||
Section 15. The component value is the serialized three-digit | ||||
integer of the HTTP response code, with no descriptive text. If | ||||
used, the "@status" component identifier MUST occur only once in the | ||||
covered components. | ||||
For example, the following response message: | ||||
HTTP/1.1 200 OK | ||||
Date: Fri, 26 Mar 2010 00:05:00 GMT | ||||
Would result in the following "@status" value: | ||||
"@status": 200 | ||||
The "@status" component identifier MUST NOT be used in a request | ||||
message. | ||||
2.3.11. Request-Response Signature Binding | ||||
When a signed request message results in a signed response message, | ||||
the "@request-response" component identifier can be used to | ||||
cryptographically link the request and the response to each other by | ||||
including the identified request signature value in the response's | ||||
signature input without copying the value of the request's signature | ||||
to the response directly. This component identifier has a single | ||||
REQUIRED parameter: | ||||
"key" Identifies which signature from the response to sign. | ||||
The component value is the "sf-binary" representation of the | ||||
signature value of the referenced request identified by the "key" | ||||
parameter. | ||||
For example, when serving this signed request: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
POST /foo?param=value&pet=dog HTTP/1.1 | ||||
Host: example.com | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 18 | ||||
Signature-Input: sig1=("@authority" "content-type")\ | ||||
;created=1618884475;keyid="test-key-rsa-pss" | ||||
Signature: sig1=:KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu5rif3g7ckTbbX7C4\ | ||||
Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79gBeqvHNUO4bhI27p\ | ||||
4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7OjkfsHAm/enxf1fA\ | ||||
wkk15xj0n6kmriwZfgUlOqyff0XLwuH4XFvZ+ZTyxYNoo2+EfFg4NVfqtSJch2WDY\ | ||||
7n/qmhZOzMfyHlggWYFnDpyP27VrzQCQg8rM1Crp6MrwGLa94v6qP8pq0sQVq2DLt\ | ||||
4NJSoRRqXTvqlWIRnexmcKXjQFVz6YSA==: | ||||
{"hello": "world"} | ||||
This would result in the following unsigned response message: | ||||
HTTP/1.1 200 OK | ||||
Date: Tue, 20 Apr 2021 02:07:56 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 62 | ||||
{"busy": true, "message": "Your call is very important to us"} | ||||
The server signs the response with its own key and includes the | ||||
signature of "sig1" from the request in the covered components of the | ||||
response. The signature input string for this example is: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
"content-type": application/json | ||||
"content-length": 62 | ||||
"@status": 200 | ||||
"@request-response";key="sig1": :KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu\ | ||||
5rif3g7ckTbbX7C4Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79\ | ||||
gBeqvHNUO4bhI27p4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7\ | ||||
OjkfsHAm/enxf1fAwkk15xj0n6kmriwZfgUlOqyff0XLwuH4XFvZ+ZTyxYNoo2+Ef\ | ||||
Fg4NVfqtSJch2WDY7n/qmhZOzMfyHlggWYFnDpyP27VrzQCQg8rM1Crp6MrwGLa94\ | ||||
v6qP8pq0sQVq2DLt4NJSoRRqXTvqlWIRnexmcKXjQFVz6YSA==: | ||||
"@signature-params": ("content-type" "content-length" "@status" \ | ||||
"@request-response";key="sig1");created=1618884475\ | ||||
;keyid="test-key-ecc-p256" | ||||
The signed response message is: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
HTTP/1.1 200 OK | ||||
Date: Tue, 20 Apr 2021 02:07:56 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 62 | ||||
Signature-Input: sig1=("content-type" "content-length" "@status" \ | ||||
"@request-response";key="sig1");created=1618884475\ | ||||
;keyid="test-key-ecc-p256" | ||||
Signature: sig1=:crVqK54rxvdx0j7qnt2RL1oQSf+o21S/6Uk2hyFpoIfOT0q+Hv\ | ||||
msYAXUXzo0Wn8NFWh/OjWQOXHAQdVnTk87Pw==: | ||||
{"busy": true, "message": "Your call is very important to us"} | ||||
Since the request's signature value itself is not repeated in the | ||||
response, the requester MUST keep the original signature value around | ||||
long enough to validate the signature of the response. | ||||
The "@request-response" component identifier MUST NOT be used in a | ||||
request message. | ||||
2.4. Creating the Signature Input String | 2.4. Creating the Signature Input String | |||
The signature input is a US-ASCII string containing the content that | The signature input is a US-ASCII string containing the canonicalized | |||
is covered by the signature. To create the signature input string, | HTTP message components covered by the signature. To create the | |||
the signer or verifier concatenates together entries for each | signature input string, the signer or verifier concatenates together | |||
identifier in the signature's covered content and parameters using | entries for each identifier in the signature's covered components | |||
the following algorithm: | (including their parameters) using the following algorithm: | |||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. For each covered content item in the covered content list (in | 2. For each message component item in the covered components set (in | |||
order): | order): | |||
1. Append the identifier for the covered content serialized | 1. Append the component identifier for the covered component | |||
according to the "content-identifier" rule. | serialized according to the "component-identifier" rule. | |||
2. Append a single colon "":"" | 2. Append a single colon "":"" | |||
3. Append a single space "" "" | 3. Append a single space "" "" | |||
4. Append the covered content's canonicalized value, as defined | 4. Append the covered component's canonicalized component value, | |||
by the covered content type. (Section 2.1 and Section 2.3) | as defined by the HTTP message component type. (Section 2.1 | |||
and Section 2.3) | ||||
5. Append a single newline ""\\n"" | 5. Append a single newline ""\\n"" | |||
3. Append the signature parameters (Section 2.3.2) as follows: | 3. Append the signature parameters component (Section 2.3.1) as | |||
follows: | ||||
1. Append the identifier for the signature parameters serialized | 1. Append the component identifier for the signature parameters | |||
according to the "content-identifier" rule, ""@signature- | serialized according to the "component-identifier" rule, i.e. | |||
params"" | ""@signature-params"" | |||
2. Append a single colon "":"" | 2. Append a single colon "":"" | |||
3. Append a single space "" "" | 3. Append a single space "" "" | |||
4. Append the signature parameters' canonicalized value as | 4. Append the signature parameters' canonicalized component | |||
defined in Section 2.3.2 | value as defined in Section 2.3.1 | |||
4. Return the output string. | 4. Return the output string. | |||
If covered content references an identifier that cannot be resolved | If covered components reference a component identifier that cannot be | |||
to a value in the message, the implementation MUST produce an error. | resolved to a component value in the message, the implementation MUST | |||
Such situations are included but not limited to: | produce an error. Such situations are included but not limited to: | |||
* The signer or verifier does not understand the content identifier. | * The signer or verifier does not understand the component | |||
identifier. | ||||
* The identifier identifies a header field that is not present in | * The component identifier identifies a field that is not present in | |||
the message or whose value is malformed. | the message or whose value is malformed. | |||
* The identifier is a Dictionary member identifier that references a | * The component identifier is a Dictionary member identifier that | |||
header field that is not present in the message, is not a | references a field that is not present in the message, is not a | |||
Dictionary Structured Field, or whose value is malformed. | Dictionary Structured Field, or whose value is malformed. | |||
* The identifier is a Dictionary member identifier that references a | * The component identifier is a Dictionary member identifier that | |||
member that is not present in the header field value, or whose | references a member that is not present in the field value, or | |||
value is malformed. E.g., the identifier is | whose value is malformed. E.g., the identifier is | |||
""x-dictionary";key="c"" and the value of the "x-dictionary" | ""x-dictionary";key="c"" and the value of the "x-dictionary" | |||
header field is "a=1, b=2" | header field is "a=1, b=2" | |||
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: | |||
GET /foo HTTP/1.1 | GET /foo HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
X-Example: Example header | X-Example: Example header | |||
with some whitespace. | with some whitespace. | |||
X-Empty-Header: | X-Empty-Header: | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
The covered components consist of the "@method", "@path", and | ||||
"@authority" specialty component identifiers followed by the "Cache- | ||||
Control", "X-Empty-Header", "X-Example" HTTP headers, in order. The | ||||
signature parameters consist of a creation timestamp is "1618884475" | ||||
and the key identifier is "test-key-rsa-pss". The signature input | ||||
string for this message with these parameters is: | ||||
The covered content consists of the "@request-target" specialty | NOTE: '\' line wrapping per RFC 8792 | |||
content followed by the "Host", "Date", "Cache-Control", "X-Empty- | ||||
Header", "X-Example" HTTP headers, in order. The signature creation | ||||
timestamp is "1618884475" and the key identifier is "test-key-rsa- | ||||
pss". The signature input string for this message with these | ||||
parameters is: | ||||
"@request-target": get /foo | "@method": GET | |||
"host": example.org | "@path": /foo | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "@authority": example.org | |||
"cache-control": max-age=60, must-revalidate | "cache-control": max-age=60, must-revalidate | |||
"x-empty-header": | "x-empty-header": | |||
"x-example": Example header with some whitespace. | "x-example": Example header with some whitespace. | |||
"@signature-params": ("@request-target" "host" "date" "cache-control" \ | "@signature-params": ("@method" "@path" "@authority" \ | |||
"x-empty-header" "x-example");created=1618884475;\ | "cache-control" "x-empty-header" "x-example");created=1618884475\ | |||
keyid="test-key-rsa-pss" | ;keyid="test-key-rsa-pss" | |||
Figure 1: Non-normative example Signature Input | Figure 1: Non-normative example Signature Input | |||
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 content in an HTTP message and metadata about the | a subset of the components of an HTTP message in addition to metadata | |||
signature itself. When successfully verified against an HTTP | about the signature itself. When successfully verified against an | |||
message, it provides cryptographic proof that with respect to the | HTTP message, an HTTP Message Signature provides cryptographic proof | |||
subset of content that was signed, the message is semantically | that the message is semantically equivalent to the message for which | |||
equivalent to the message for which the signature was generated. | the signature was generated, with respect to the subset of message | |||
components that was signed. | ||||
3.1. Creating a Signature | 3.1. Creating a Signature | |||
In order to create a signature, a signer MUST follow the following | In order to create a signature, a signer MUST follow 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. The signer MUST choose key material that is | for signing. The signer MUST choose key material that is | |||
appropriate for the signature's algorithm, and that conforms to | appropriate for the signature's algorithm, and that conforms to | |||
any requirements defined by the algorithm, such as key size or | any requirements defined by the algorithm, such as key size or | |||
format. The mechanism by which the signer chooses the algorithm | format. The mechanism by which the signer chooses the algorithm | |||
and key material is out of scope for this document. | 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. | property to the time at which the signature is to expire. | |||
4. The signer creates an ordered list of content identifiers | 4. The signer creates an ordered set of component identifiers | |||
representing the message content and signature metadata to be | representing the message components to be covered by the | |||
covered by the signature, and assigns this list as the | signature, and attaches signature metadata parameters to this | |||
signature's Covered Content. | set. The serialized value of this is later used as the value of | |||
the "Signature-Input" field as described in Section 4.1. | ||||
* Once an order of covered content is chosen, the order MUST NOT | * Once an order of covered components is chosen, the order MUST | |||
change for the life of the signature. | NOT change for the life of the signature. | |||
* Each covered content identifier MUST either reference an HTTP | * Each covered component identifier MUST be either an HTTP field | |||
header in the request message Section 2.1 or reference a | in the message Section 2.1 or a specialty component identifier | |||
specialty content field listed in Section 2.3 or its | listed in Section 2.3 or its associated registry. | |||
associated registry. | ||||
* Signers SHOULD include "@request-target" in the covered | * Signers of a request SHOULD include some or all of the message | |||
content list. | control data in the covered components, such as the "@method", | |||
"@authority", "@target-uri", or some combination thereof. | ||||
* Signers SHOULD include a date stamp in some form, such as | * Signers SHOULD include the "created" signature metadata | |||
using the "date" header. Alternatively, the "created" | parameter to indicate when the signature was created. | |||
signature metadata parameter can fulfil this role. | ||||
* Further guidance on what to include in this list and in what | * The "@signature-params" specialty component identifier is not | |||
order is out of scope for this document. However, note that | explicitly listed in the list of covered component | |||
the list order is significant and once established for a given | identifiers, because it is required to always be present as | |||
signature it MUST be preserved for that signature. | the last line in the signature input. This ensures that a | |||
signature always covers its own metadata. | ||||
* Note that the "@signature-params" specialty identifier is not | * Further guidance on what to include in this set and in what | |||
explicitly listed in the list of covered content identifiers, | order is out of scope for this document. | |||
because it is required to always be present as the last line | ||||
in the signature input. This ensures that a signature always | ||||
covers its own metadata. | ||||
5. The signer creates the signature input string. (Section 2.4) | 5. The signer creates the signature input string based on these | |||
signature parameters. (Section 2.4) | ||||
6. The signer signs the signature input with the chosen signing | 6. The signer signs the signature input with the chosen signing | |||
algorithm using the key material chosen by the signer. Several | algorithm using the key material chosen by the signer. Several | |||
signing algorithms are defined in in Section 3.3. | signing algorithms are defined in 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" | |||
header 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.4, the example signature input string when | example in Section 2.4, the example signature input string when | |||
signed with the "test-key-rsa-pss" key in Appendix B.1.2 gives the | signed with the "test-key-rsa-pss" key in Appendix B.1.2 gives the | |||
following message signature output value, encoded in Base64: | following message signature output value, encoded in Base64: | |||
lPxkxqDEPhgrx1yPaKLO7eJ+oPjSwsQ5NjWNRfYP7Jw0FwnK1k8/GH7g5s2q0VTTKVm\ | NOTE: '\' line wrapping per RFC 8792 | |||
xyfpUDp/HsDphh5Z7Fa/lvtujHyFe/0EP9z7bnVb7YBZrxV52LGvP8p4APhOYuG4yaH\ | ||||
z478GsJav9BQYK0B2IOHdLFJe8qwWPJs07J47gPewpNwCt0To/zZ2KPpylGX5UHVgJP\ | P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1RSHi+oEF1FuX6O29\ | |||
Uom64KjX43u2OwIvSoPEYk4nuBvLR9yxYAHURaTfLoEDUCtY1FsU1hOfG3jAlcT6ill\ | d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC87qmSQjvu1CFyFuWSj\ | |||
fnyS72PEdSSzw1KsxroMj9IYpFhva77YxmJRk4pCIW0F0Kj0ukl7J4y2aZJHMCYI3g8\ | dGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gyarxAiWI97mPXU+OVM64\ | |||
yfqh/wQ== | +HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix\ | |||
5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3r5S9IXf2fYJK+eyW4AiG\ | ||||
VMvMcOg== | ||||
Figure 2: Non-normative example signature value | Figure 2: Non-normative example signature value | |||
3.2. Verifying a Signature | 3.2. Verifying a Signature | |||
A verifier processes a signature and its associated signature input | A verifier processes a signature and its associated signature input | |||
parameters in concert with each other. | parameters in concert with each other. | |||
In order to verify a signature, a verifier MUST follow the following | In order to verify a signature, a verifier MUST follow the following | |||
algorithm: | algorithm: | |||
1. Parse the "Signature" and "Signature-Input" headers and extract | 1. Parse the "Signature" and "Signature-Input" fields and extract | |||
the signatures to be verified. | the signatures to be verified. | |||
1. If there is more than one signature value present, determine | 1. If there is more than one signature value present, determine | |||
which signature should be processed for this request. If an | which signature should be processed for this message. If an | |||
appropriate signature is not found, produce an error. | applicable signature is not found, produce an error. | |||
2. If the chosen "Signature" value does not have a corresponding | 2. If the chosen "Signature" value does not have a corresponding | |||
"Signature-Input" value, produce an error. | "Signature-Input" value, produce an error. | |||
2. Parse the values of the chosen "Signature-Input" header field to | 2. Parse the values of the chosen "Signature-Input" field to get the | |||
get the parameters for the signature to be verified. | parameters for the signature to be verified. | |||
3. Parse the value of the corresponding "Signature" header field to | 3. Parse the value of the corresponding "Signature" field to get the | |||
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 | |||
contents 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 that. If the key is identified in the signature parameters, | |||
the verifier will dereference this to appropriate key material to | the verifier will dereference this to appropriate key material to | |||
use with the signature. The verifier has to determine the | use with the signature. The verifier has to determine the | |||
trustworthiness of the key material for the context in which the | trustworthiness of the key material for the context in which the | |||
signature is presented. If a key is identified that the verifier | signature is presented. If a key is identified that the verifier | |||
skipping to change at page 19, line 46 ¶ | skipping to change at page 28, line 32 ¶ | |||
4. If the algorithm is specified in more that one location, such | 4. If the algorithm is specified in more that one location, such | |||
as through static configuration and the algorithm signature | as through static configuration and the algorithm signature | |||
parameter, or the algorithm signature parameter and from the | parameter, or the algorithm signature parameter and from the | |||
key material itself, the resolved algorithms MUST be the | key material itself, the resolved algorithms MUST be the | |||
same. If the algorithms are not the same, the verifier MUST | same. If the algorithms are not the same, the verifier MUST | |||
vail the verification. | vail the verification. | |||
7. Use the received HTTP message and the signature's metadata to | 7. Use the received HTTP message and the signature's metadata to | |||
recreate the signature input, using the process described in | recreate the signature input, using the process described in | |||
Section 2.4. The value of the "@signature-params" input is the | Section 2.4. The value of the "@signature-params" input is the | |||
value of the SignatureInput header field for this signature | value of the "SignatureInput" field for this signature serialized | |||
serialized according to the rules described in Section 2.3.2, not | according to the rules described in Section 2.3.1, not including | |||
including the signature's label from the "Signature-Input" | the signature's label from the "Signature-Input" field. | |||
header. | ||||
8. If the key material is appropriate for the algorithm, apply the | 8. If the key material is appropriate for the algorithm, apply the | |||
verification algorithm to the signature, recalculated signature | verification algorithm to the signature, recalculated signature | |||
input, signature parameters, key material, and algorithm. | input, signature parameters, key material, and algorithm. | |||
Several algorithms are defined in Section 3.3. | Several 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 signature verification. | results of the signature verification. | |||
If any of the above steps fail, the signature validation fails. | If any of the above steps fail or produce an error, the signature | |||
validation fails. | ||||
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", "Digest"). | |||
* Enforcing a maximum signature age. | * Enforcing a maximum signature age. | |||
* Prohibition of signature metadata parameters, such as runtime | ||||
algorithm signaling with the "alg" parameter. | ||||
* Prohibiting the use of certain algorithms, or mandating the use of | * Prohibiting the use of certain algorithms, or mandating the use of | |||
an 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 a nonce value. | * Enforcing uniqueness of a "nonce" value. | |||
Application-specific requirements are expected and encouraged. When | Application-specific requirements are expected and encouraged. When | |||
an application defines additional requirements, it MUST enforce them | an application defines additional requirements, it MUST enforce them | |||
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. | |||
skipping to change at page 21, line 15 ¶ | skipping to change at page 30, line 7 ¶ | |||
3.3. Signature Algorithm Methods | 3.3. Signature Algorithm Methods | |||
HTTP Message signatures MAY use any cryptographic digital signature | HTTP Message signatures MAY use any 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. All signatures are generated | and needs of the signer and verifier. All signatures are generated | |||
from and verified against the byte values of the signature input | from and verified against the byte values of the signature input | |||
string defined in Section 2.4. | string defined in Section 2.4. | |||
Each signature algorithm method takes as its input the signature | Each signature algorithm method takes as its input the signature | |||
input string as a set of byte values ("I"), the signing key material | input string as a set of byte values ("I"), the signing key material | |||
("Ks"), and outputs the signed content as a set of byte values ("S"): | ("Ks"), and outputs the signature output as a set of byte values | |||
("S"): | ||||
HTTP_SIGN (I, Ks) -> S | HTTP_SIGN (I, Ks) -> S | |||
Each verification algorithm method takes as its input the | Each verification algorithm method takes as its input the | |||
recalculated signature input string as a set of byte values ("I"), | recalculated signature input string as a set of byte values ("I"), | |||
the verification key material ("Kv"), and the presented signature to | the verification key material ("Kv"), and the presented signature to | |||
be verified as a set of byte values ("S") and outputs the | be verified as a set of byte values ("S") and outputs the | |||
verification result ("V") as a boolean: | verification result ("V") as a boolean: | |||
HTTP_VERIFY (I, Kv, S) -> V | HTTP_VERIFY (I, Kv, S) -> V | |||
This section contains several common algorithm methods. The method | This section contains several common algorithm methods. The method | |||
to use can be communicated through the algorithm signature parameter | to use can be communicated through the algorithm signature parameter | |||
defined in Section 2.3.2, by reference to the key material, or | defined in Section 2.3.1, by reference to the key material, or | |||
through mutual agreement between the signer and verifier. | through mutual agreement between the signer and verifier. | |||
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 [RFC8017] with the signer's private signing key | (K, M)" function [RFC8017] with the signer's private signing key | |||
("K") and the signature input string ("M") (Section 2.4). The mask | ("K") and the signature input string ("M") (Section 2.4). 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 | |||
skipping to change at page 23, line 48 ¶ | skipping to change at page 32, line 38 ¶ | |||
string is not first encoded in Base64 before applying the algorithm. | string is not first encoded in Base64 before applying the algorithm. | |||
The output of the JWS signature is taken as a byte array prior to the | The output of the JWS signature is taken as a byte array prior to the | |||
Base64url encoding used in JOSE. | Base64url encoding used in JOSE. | |||
The JWS algorithm MUST NOT be "none" and MUST NOT be any algorithm | The JWS algorithm MUST NOT be "none" and MUST NOT be any algorithm | |||
with a JOSE Implementation Requirement of "Prohibited". | with a JOSE Implementation Requirement of "Prohibited". | |||
4. Including a Message Signature in a Message | 4. Including a Message Signature in a Message | |||
Message signatures can be included within an HTTP message via the | Message signatures can be included within an HTTP message via the | |||
"Signature-Input" and "Signature" HTTP header fields, both defined | "Signature-Input" and "Signature" HTTP fields, both defined within | |||
within this specification. | this specification. When attached to a message, an HTTP message | |||
signature is identified by a label. This label MUST be unique within | ||||
a given HTTP message and MUST be used in both the "Signature-Input" | ||||
and "Signature". The label is chosen by the signer, except where a | ||||
specific label is dictated by protocol negotiations. | ||||
An HTTP message signature MUST use both headers: the "Signature" HTTP | An HTTP message signature MUST use both fields containing the same | |||
header field contains the signature value, while the "Signature- | labels: the "Signature" HTTP field contains the signature value, | |||
Input" HTTP header field identifies the covered content and | while the "Signature-Input" HTTP field identifies the covered | |||
parameters that describe how the signature was generated. Each | components and parameters that describe how the signature was | |||
header MAY contain multiple labeled values, where the labels | generated. Each field contains labeled values and MAY contain | |||
determine the correlation between the "Signature" and "Signature- | multiple labeled values, where the labels determine the correlation | |||
Input" fields. | between the "Signature" and "Signature-Input" fields. | |||
4.1. The 'Signature-Input' HTTP Header | 4.1. The 'Signature-Input' HTTP Field | |||
The "Signature-Input" HTTP header field is a Dictionary Structured | The "Signature-Input" HTTP field is a Dictionary Structured Field | |||
Header [RFC8941] containing the metadata for one or more message | [RFC8941] containing the metadata for one or more message signatures | |||
signatures generated from content within the HTTP message. Each | generated from components within the HTTP message. Each member | |||
member describes a single message signature. The member's name is an | describes a single message signature. The member's name is an | |||
identifier that uniquely identifies the message signature within the | identifier that uniquely identifies the message signature within the | |||
context of the HTTP message. The member's value is the serialization | context of the HTTP message. The member's value is the serialization | |||
of the covered content including all signature metadata parameters, | of the covered components including all signature metadata | |||
using the serialization process defined in Section 2.3.2. | parameters, using the serialization process defined in Section 2.3.1. | |||
Signature-Input: sig1=("@request-target" "host" "date" \ | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@method" "@target-uri" "host" "date" \ | ||||
"cache-control" "x-empty-header" "x-example");created=1618884475\ | "cache-control" "x-empty-header" "x-example");created=1618884475\ | |||
;keyid="test-key-rsa-pss" | ;keyid="test-key-rsa-pss" | |||
To facilitate signature validation, the "Signature-Input" header | To facilitate signature validation, the "Signature-Input" field value | |||
value MUST contain the same serialized value used in generating the | MUST contain the same serialized value used in generating the | |||
signature input string's "@signature-params" value. | signature input string's "@signature-params" value. | |||
4.2. The 'Signature' HTTP Header | The signer MAY include the "Signature-Input" field as a trailer to | |||
facilitate signing a message after its content has been processed by | ||||
the signer. However, since intermediaries are allowed to drop | ||||
trailers as per [SEMANTICS], it is RECOMMENDED that the "Signature- | ||||
Input" HTTP field be included only as a header to avoid signatures | ||||
being inadvertently stripped from a message. | ||||
The "Signature" HTTP header field is a Dictionary Structured Header | Multiple "Signature-Input" fields MAY be included in a single HTTP | |||
[RFC8941] containing one or more message signatures generated from | message. The signature labels MUST be unique across all field | |||
content within the HTTP message. Each member's name is a signature | values. | |||
4.2. The 'Signature' HTTP Field | ||||
The "Signature" HTTP field is a Dictionary Structured field [RFC8941] | ||||
containing one or more message signatures generated from components | ||||
within the HTTP message. Each member's name is a signature | ||||
identifier that is present as a member name in the "Signature-Input" | identifier that is present as a member name in the "Signature-Input" | |||
Structured Header within the HTTP message. Each member's value is a | Structured field within the HTTP message. Each 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 member name. Any member in the | signature identified by the member name. Any member in the | |||
"Signature" HTTP header field that does not have a corresponding | "Signature" HTTP field that does not have a corresponding member in | |||
member in the HTTP message's "Signature-Input" HTTP header field MUST | the HTTP message's "Signature-Input" HTTP field MUST be ignored. | |||
be ignored. | ||||
Signature: sig1=:lPxkxqDEPhgrx1yPaKLO7eJ+oPjSwsQ5NjWNRfYP7Jw0FwnK1k\ | NOTE: '\' line wrapping per RFC 8792 | |||
8/GH7g5s2q0VTTKVmxyfpUDp/HsDphh5Z7Fa/lvtujHyFe/0EP9z7bnVb7YBZrxV5\ | ||||
2LGvP8p4APhOYuG4yaHz478GsJav9BQYK0B2IOHdLFJe8qwWPJs07J47gPewpNwCt\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
0To/zZ2KPpylGX5UHVgJPUom64KjX43u2OwIvSoPEYk4nuBvLR9yxYAHURaTfLoED\ | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHz\ | |||
UCtY1FsU1hOfG3jAlcT6illfnyS72PEdSSzw1KsxroMj9IYpFhva77YxmJRk4pCIW\ | C87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8\ | |||
0F0Kj0ukl7J4y2aZJHMCYI3g8yfqh/wQ==: | gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58Rmp\ | |||
Z+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxA\ | ||||
BNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | ||||
The signer MAY include the "Signature" field as a trailer to | ||||
facilitate signing a message after its content has been processed by | ||||
the signer. However, since intermediaries are allowed to drop | ||||
trailers as per [SEMANTICS], it is RECOMMENDED that the "Signature- | ||||
Input" HTTP field be included only as a header to avoid signatures | ||||
being inadvertently stripped from a message. | ||||
Multiple "Signature" fields MAY be included in a single HTTP message. | ||||
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. | ||||
Since "Signature-Input" and "Signature" are both defined as | Since "Signature-Input" and "Signature" are both defined as | |||
Dictionary Structured Headers, they can be used to include multiple | Dictionary Structured fields, they can be used to include multiple | |||
signatures within the same HTTP message. For example, a signer may | signatures within the same HTTP message by using distinct signature | |||
include multiple signatures signing the same content with different | labels. For example, a signer may include multiple signatures | |||
keys or algorithms to support verifiers with different capabilities, | signing the same message components with different keys or algorithms | |||
or a reverse proxy may include information about the client in header | to support verifiers with different capabilities, or a reverse proxy | |||
fields when forwarding the request to a service host, including a | may include information about the client in fields when forwarding | |||
signature over those fields and the client's original signature. | the request to a service host, including a signature over the | |||
client's original signature values. | ||||
The following is a non-normative example of header fields a reverse | The following is a non-normative example of header fields a reverse | |||
proxy sets in addition to the examples in the previous sections. The | proxy sets in addition to the examples in the previous sections. | |||
original signature is included under the identifier "sig1", and the | ||||
reverse proxy's signature is included under "proxy_sig". The proxy | ||||
uses the key "rsa-test-key" to create its signature using the "rsa- | ||||
v1_5-sha256" signature value. This results in a signature input | ||||
string of: | ||||
"signature";key="sig1": \ | NOTE: '\' line wrapping per RFC 8792 | |||
:lPxkxqDEPhgrx1yPaKLO7eJ+oPjSwsQ5NjWNRfYP7Jw0FwnK1k8/GH7g5s2q0VTT\ | ||||
KVmxyfpUDp/HsDphh5Z7Fa/lvtujHyFe/0EP9z7bnVb7YBZrxV52LGvP8p4APhOYu\ | Forwarded: for=192.0.2.123 | |||
G4yaHz478GsJav9BQYK0B2IOHdLFJe8qwWPJs07J47gPewpNwCt0To/zZ2KPpylGX\ | Signature-Input: sig1=("@method" "@path" "@authority" \ | |||
5UHVgJPUom64KjX43u2OwIvSoPEYk4nuBvLR9yxYAHURaTfLoEDUCtY1FsU1hOfG3\ | "cache-control" "x-empty-header" "x-example")\ | |||
jAlcT6illfnyS72PEdSSzw1KsxroMj9IYpFhva77YxmJRk4pCIW0F0Kj0ukl7J4y2\ | ;created=1618884475;keyid="test-key-rsa-pss" | |||
aZJHMCYI3g8yfqh/wQ==: | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
"x-forwarded-for": 192.0.2.123 | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | |||
"@signature-params": ("signature";key="sig1" "x-forwarded-for")\ | HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | |||
4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | ||||
r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | ||||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | ||||
The client's request includes a signature value under the label | ||||
"sig1", which the proxy signs in addition to the "Forwarded" header | ||||
defined in [RFC7239]. Note that since the client's signature already | ||||
covers the client's "Signature-Input" value for "sig1", this value is | ||||
transitively covered by the proxy's signature and need not be added | ||||
explicitly. This results in a signature input string of: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
"signature";key="sig1": :P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP\ | ||||
4uKwxyJo1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9Gl\ | ||||
yntiCiHzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyo\ | ||||
yZW84jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg\ | ||||
53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | ||||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | ||||
"forwarded": for=192.0.2.123 | ||||
"@signature-params": ("signature";key="sig1" "forwarded")\ | ||||
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | ;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | |||
And a signature output value of: | And a signature output value of: | |||
XD1O/vEh772WVpY7jYvReXop2+b7xTIIPKH8/OCYzPn78Wd9jodCwAJPF5TYCn9L6n6\ | NOTE: '\' line wrapping per RFC 8792 | |||
8j4EjGsqFOMkVLVdSQEZqMLjEbvMEdIe8m1a0CLd5kydeaAwoHoglqod6ijkwhhEtxt\ | ||||
aD8tDZmihQw2mZEH8u4aMSnRntqy7ExCNld0JLharsHV0iCbRO9jIP+d2ApD7gB+eZp\ | cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZxNiE+797dXK2cj\ | |||
n3pIvvVJZlxTwPkahFpxKlQtNMPaSqa1lvejURx+ST8CEuz4sS+G/oLJiX3MZenuUoO\ | PPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8keB8xzFt4inv3J3zP0\ | |||
R8HeOHDnjN/VLzrEN4x44iF7WIL+iY2PtK87LUWRAsJAX9GqHL/upsGh1nxIdoVaoLV\ | k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1XSg03iUa0sju1yj6rcKbMA\ | |||
V5w+fRw== | BBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hmcDHkNaavcokmq+3EBDCQTzgwL\ | |||
qfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+j8kSydKoFg6EbVuGbrQijth6I0dDX\ | ||||
2/HYcJg== | ||||
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 | |||
different signature values are wrapped onto separate lines to | original signature is included under the identifier "sig1", and the | |||
increase human-readability of the result. | reverse proxy's signature is included under the label "proxy_sig". | |||
The proxy uses the key "test-key-rsa" to create its signature using | ||||
the "rsa-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 PSS signature algorithm. | ||||
X-Forwarded-For: 192.0.2.123 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@request-target" "host" "date" \ | ||||
Forwarded: for=192.0.2.123 | ||||
Signature-Input: sig1=("@method" "@path" "@authority" \ | ||||
"cache-control" "x-empty-header" "x-example")\ | "cache-control" "x-empty-header" "x-example")\ | |||
;created=1618884475;keyid="test-key-rsa-pss", \ | ;created=1618884475;keyid="test-key-rsa-pss", \ | |||
proxy_sig=("signature";key="sig1" "x-forwarded-for")\ | proxy_sig=("signature";key="sig1" "forwarded")\ | |||
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | ;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | |||
Signature: sig1=:lPxkxqDEPhgrx1yPaKLO7eJ+oPjSwsQ5NjWNRfYP7Jw0FwnK1k\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
8/GH7g5s2q0VTTKVmxyfpUDp/HsDphh5Z7Fa/lvtujHyFe/0EP9z7bnVb7YBZrx\ | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | |||
V52LGvP8p4APhOYuG4yaHz478GsJav9BQYK0B2IOHdLFJe8qwWPJs07J47gPewp\ | HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | |||
NwCt0To/zZ2KPpylGX5UHVgJPUom64KjX43u2OwIvSoPEYk4nuBvLR9yxYAHURa\ | 4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | |||
TfLoEDUCtY1FsU1hOfG3jAlcT6illfnyS72PEdSSzw1KsxroMj9IYpFhva77Yxm\ | r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | |||
JRk4pCIW0F0Kj0ukl7J4y2aZJHMCYI3g8yfqh/wQ==:, \ | Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==:, \ | |||
proxy_sig=:XD1O/vEh772WVpY7jYvReXop2+b7xTIIPKH8/OCYzPn78Wd9jodCwA\ | proxy_sig=:cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZx\ | |||
JPF5TYCn9L6n68j4EjGsqFOMkVLVdSQEZqMLjEbvMEdIe8m1a0CLd5kydeaAwoH\ | NiE+797dXK2cjPPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8k\ | |||
oglqod6ijkwhhEtxtaD8tDZmihQw2mZEH8u4aMSnRntqy7ExCNld0JLharsHV0i\ | eB8xzFt4inv3J3zP0k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1X\ | |||
CbRO9jIP+d2ApD7gB+eZpn3pIvvVJZlxTwPkahFpxKlQtNMPaSqa1lvejURx+ST\ | Sg03iUa0sju1yj6rcKbMABBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hm\ | |||
8CEuz4sS+G/oLJiX3MZenuUoOR8HeOHDnjN/VLzrEN4x44iF7WIL+iY2PtK87LU\ | cDHkNaavcokmq+3EBDCQTzgwLqfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+\ | |||
WRAsJAX9GqHL/upsGh1nxIdoVaoLVV5w+fRw==: | j8kSydKoFg6EbVuGbrQijth6I0dDX2/HYcJg==: | |||
The proxy's signature and the client's original signature can be | The proxy's signature and the client's original signature can be | |||
verified independently for the same message, depending on the needs | verified independently for the same message, based on the needs of | |||
of the application. | the application. Since the proxy's signature covers the client | |||
signature, the backend service fronted by the proxy can trust that | ||||
the proxy has validated the incoming signature. | ||||
5. IANA Considerations | 5. Requesting Signatures | |||
5.1. HTTP Signature Algorithms Registry | 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 | ||||
signal that it expects a signature from a potential signer using the | ||||
"Accept-Signature" field. | ||||
The message to which the requested signature is applied is known as | ||||
the "target 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 response using the identified parameters and | ||||
the target message is the response to this request. All responses | ||||
from resources that support such signature negotiation SHOULD either | ||||
be uncacheable or contain a "Vary" header field that lists "Accept- | ||||
Signature", in order to prevent a cache from returning a response | ||||
with a signature intended for a different request. | ||||
When the "Accept-Signature" field is used in an HTTP Response | ||||
message, the field indicates that the server desires the client to | ||||
sign its next request to the server with the identified parameters, | ||||
and the target message is the client's next request. The client can | ||||
choose to also continue signing future requests to the same server in | ||||
the same way. | ||||
The target message of an "Accept-Signature" field MUST include all | ||||
labeled signatures indicated in the "Accept-Header" signature, each | ||||
covering the same identified components of the "Accept-Signature" | ||||
field. | ||||
The sender of an "Accept-Signature" field MUST include identifiers | ||||
that are appropriate for the type of the target message. For | ||||
example, if the target message is a response, the identifiers can not | ||||
include the "@status" identifier. | ||||
5.1. The Accept-Signature Field | ||||
The "Accept-Signature" HTTP header field is a Dictionary Structured | ||||
field [RFC8941] containing the metadata for one or more requested | ||||
message signatures to be generated from message components of the | ||||
target HTTP message. Each member describes a single message | ||||
signature. The member's name is an identifier that uniquely | ||||
identifies the requested message signature within the context of the | ||||
target HTTP message. The member's value is the serialization of the | ||||
desired covered components of the target message, including any | ||||
allowed signature metadata parameters, using the serialization | ||||
process defined in Section 2.3.1. | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
Accept-Signature: sig1=("@method" "@target-uri" "host" "date" \ | ||||
"cache-control" "x-empty-header" "x-example")\ | ||||
;keyid="test-key-rsa-pss" | ||||
The requested signature MAY include parameters, such as a desired | ||||
algorithm or key identifier. These parameters MUST NOT include | ||||
parameters that the signer is expected to generate, including the | ||||
"created" and "nonce" parameters. | ||||
5.2. Processing an Accept-Signature | ||||
The receiver of an "Accept-Signature" field fulfills that header as | ||||
follows: | ||||
1. Parse the field value as a Dictionary | ||||
2. For each member of the dictionary: | ||||
1. The name of the member is the label of the output signature | ||||
as specified in Section 4.1 | ||||
2. Parse the value of the member to obtain the set of covered | ||||
component identifiers | ||||
3. Process the requested parameters, such as the signing | ||||
algorithm and key material. If any requested parameters | ||||
cannot be fulfilled, or if the requested parameters conflict | ||||
with those deemed appropriate to the target message, the | ||||
process fails and returns an error. | ||||
4. Select any additional parameters necessary for completing the | ||||
signature | ||||
5. Create the "Signature-Input" and "Signature" header values | ||||
and associate them with the label | ||||
3. Optionally create any additional "Signature-Input" and | ||||
"Signature" values, with unique labels not found in the "Accept- | ||||
Signature" field | ||||
4. Combine all labeled "Signature-Input" and "Signature" values and | ||||
attach both headers to the target message | ||||
Note that by this process, a signature applied to a target message | ||||
MUST have the same label, MUST have the same set of covered | ||||
component, and MAY have additional parameters. Also note that the | ||||
target message MAY include additional signatures not specified by the | ||||
"Accept-Signature" field. | ||||
6. IANA Considerations | ||||
6.1. HTTP Signature Algorithms Registry | ||||
This document defines HTTP Signature Algorithms, for which IANA is | This document defines HTTP Signature Algorithms, for which IANA is | |||
asked to create and maintain a new registry titled "HTTP Signature | asked to create and maintain 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 5.1.2. Future assignments and modifications to existing | Section 6.1.2. Future assignments and modifications to existing | |||
assignment are to be made through the Expert Review registration | assignment are to be made through the Expert Review registration | |||
policy [RFC8126] and shall follow the template presented in | policy [RFC8126] and shall follow the template presented in | |||
Section 5.1.1. | Section 6.1.1. | |||
Algorithms referenced by algorithm identifiers have to be fully | Algorithms referenced by algorithm identifiers have to be fully | |||
defined with all parameters fixed. Algorithm identifiers in this | defined with all parameters fixed. Algorithm identifiers in this | |||
registry are to be interpreted as whole string values and not as a | registry are to be interpreted as whole string values and not as a | |||
combination of parts. That is to say, it is expected that | combination of parts. That is to say, it is expected that | |||
implementors understand "rsa-pss-sha512" as referring to one specific | implementors understand "rsa-pss-sha512" as referring to one specific | |||
algorithm with its hash, mask, and salt values set as defined here. | algorithm with its hash, mask, and salt values set as defined here. | |||
Implementors do not parse out the "rsa", "pss", and "sha512" portions | Implementors do not parse out the "rsa", "pss", and "sha512" portions | |||
of the identifier to determine parameters of the signing algorithm | of the identifier to determine parameters of the signing algorithm | |||
from the string. | from the string. | |||
5.1.1. Registration Template | 6.1.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 consisting only of lower-case characters (""a"" - | an ASCII string consisting only of lower-case characters (""a"" - | |||
""z""), digits (""0"" - ""9""), and hyphens (""-""), and SHOULD | ""z""), digits (""0"" - ""9""), and hyphens (""-""), and SHOULD | |||
NOT exceed 20 characters in length. The identifier MUST be unique | NOT exceed 20 characters in length. The identifier MUST be unique | |||
within the context of the registry. | within the context of the registry. | |||
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 | |||
skipping to change at page 27, line 27 ¶ | skipping to change at page 39, line 36 ¶ | |||
Description: | Description: | |||
A brief description of the algorithm used to sign the signature | A brief description of the algorithm used to sign the signature | |||
input string. | input string. | |||
Specification document(s): | Specification document(s): | |||
Reference to the document(s) that specify the token endpoint | Reference to the document(s) that specify the token endpoint | |||
authorization method, preferably including a URI that can be used | authorization method, preferably including a URI that can be used | |||
to retrieve a copy of the document(s). An indication of the | to retrieve a copy of the document(s). An indication of the | |||
relevant sections may also be included but is not required. | relevant sections may also be included but is not required. | |||
5.1.2. Initial Contents | 6.1.2. Initial Contents | |||
5.1.2.1. rsa-pss-sha512 | 6.1.2.1. rsa-pss-sha512 | |||
Algorithm Name: | Algorithm Name: | |||
"rsa-pss-sha512" | "rsa-pss-sha512" | |||
Status: | Status: | |||
Active | Active | |||
Definition: | Definition: | |||
RSASSA-PSS using SHA-256 | RSASSA-PSS using SHA-256 | |||
Specification document(s): | Specification document(s): | |||
[[This document]], Section 3.3.1 | [[This document]], Section 3.3.1 | |||
5.1.2.2. rsa-v1_5-sha256 | 6.1.2.2. rsa-v1_5-sha256 | |||
Algorithm Name: | Algorithm Name: | |||
"rsa-v1_5-sha256" | "rsa-v1_5-sha256" | |||
Status: | Status: | |||
Active | Active | |||
Description: | Description: | |||
RSASSA-PKCS1-v1_5 using SHA-256 | RSASSA-PKCS1-v1_5 using SHA-256 | |||
Specification document(s): | Specification document(s): | |||
[[This document]], Section 3.3.2 | [[This document]], Section 3.3.2 | |||
5.1.2.3. hmac-sha256 | 6.1.2.3. hmac-sha256 | |||
Algorithm Name: | Algorithm Name: | |||
"hmac-sha256" | "hmac-sha256" | |||
Status: | Status: | |||
Active | Active | |||
Description: | Description: | |||
HMAC using SHA-256 | HMAC using SHA-256 | |||
Specification document(s): | Specification document(s): | |||
[[This document]], Section 3.3.3 | [[This document]], Section 3.3.3 | |||
5.1.2.4. ecdsa-p256-sha256 | 6.1.2.4. ecdsa-p256-sha256 | |||
Algorithm Name: | Algorithm Name: | |||
"ecdsa-p256-sha256" | "ecdsa-p256-sha256" | |||
Status: | Status: | |||
Active | Active | |||
Description: | Description: | |||
ECDSA using curve P-256 DSS and SHA-256 | ECDSA using curve P-256 DSS and SHA-256 | |||
Specification document(s): | Specification document(s): | |||
[[This document]], Section 3.3.4 | [[This document]], Section 3.3.4 | |||
5.2. HTTP Signature Metadata Parameters Registry | 6.2. HTTP Signature Metadata Parameters Registry | |||
This document defines the "Signature-Input" Structured Header, whose | This document defines the signature parameters structure, the values | |||
member values may have parameters containing metadata about a message | of which may have parameters containing metadata about a message | |||
signature. IANA is asked to create and maintain a new registry | signature. IANA is asked to create and maintain a new registry | |||
titled "HTTP Signature Metadata Parameters" to record and maintain | titled "HTTP Signature Metadata Parameters" to record and maintain | |||
the set of parameters defined for use with member values in the | the set of parameters defined for use with member values in the | |||
"Signature-Input" Structured Header. Initial values for this | signature parameters structure. Initial values for this registry are | |||
registry are given in Section 5.2.2. Future assignments and | given in Section 6.2.2. Future assignments and modifications to | |||
modifications to existing assignments are to be made through the | existing assignments are to be made through the Expert Review | |||
Expert Review registration policy [RFC8126] and shall follow the | registration policy [RFC8126] and shall follow the template presented | |||
template presented in Section 5.2.1. | in Section 6.2.1. | |||
5.2.1. Registration Template | 6.2.1. Registration Template | |||
5.2.2. Initial Contents | ||||
6.2.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 | Status | Reference(s) | | | Name | Status | Reference(s) | | |||
+=========+========+================================+ | +=========+========+================================+ | |||
| alg | Active | Section 2.3.2 of this document | | | alg | Active | Section 2.3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+--------------------------------+ | |||
| created | Active | Section 2.3.2 of this document | | | created | Active | Section 2.3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+--------------------------------+ | |||
| expires | Active | Section 2.3.2 of this document | | | expires | Active | Section 2.3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+--------------------------------+ | |||
| keyid | Active | Section 2.3.2 of this document | | | keyid | Active | Section 2.3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+--------------------------------+ | |||
| nonce | Active | Section 2.3.2 of this document | | | nonce | Active | Section 2.3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+--------------------------------+ | |||
Table 4: Initial contents of the HTTP Signature | Table 3: Initial contents of the HTTP Signature | |||
Metadata Parameters Registry. | Metadata Parameters Registry. | |||
5.3. HTTP Signature Specialty Content Identifiers Registry | 6.3. HTTP Signature Specialty Component Identifiers Registry | |||
This document defines a method for canonicalizing HTTP message | This document defines a method for canonicalizing HTTP message | |||
content, including content that can be generated from the context of | components, including components that can be generated from the | |||
the HTTP message outside of the HTTP headers. This content is | context of the HTTP message outside of the HTTP fields. These | |||
identified by a unique key. IANA is asked to create and maintain a | components are identified by a unique string, known as the component | |||
new registry typed "HTTP Signature Specialty Content Identifiers" to | identifier. IANA is asked to create and maintain a new registry | |||
record and maintain the set of non-header content identifiers and | typed "HTTP Signature Specialty Component Identifiers" to record and | |||
their canonicalization method. Initial values for this registry are | maintain the set of non-field component identifiers and the methods | |||
given in Section 5.3.2. Future assignments and modifications to | to produce their associated component values. Initial values for | |||
existing assignments are to be made through the Expert Review | this registry are given in Section 6.3.2. Future assignments and | |||
registration policy [RFC8126] and shall follow the template presented | modifications to existing assignments are to be made through the | |||
in Section 5.3.1. | Expert Review registration policy [RFC8126] and shall follow the | |||
template presented in Section 6.3.1. | ||||
5.3.1. Registration Template | 6.3.1. Registration Template | |||
5.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 | |||
Specialty Content Identifiers Registry. | Specialty Component Identifiers Registry. | |||
+===================+========+================================+ | +===================+========+===================+==================+ | |||
| Name | Status | Reference(s) | | | Name | Status | Target | Reference | | |||
+===================+========+================================+ | +===================+========+===================+==================+ | |||
| @request-target | Active | Section 2.3.1 of this document | | | @signature-params | Active | Request, | Section 2.3.1 of | | |||
+-------------------+--------+--------------------------------+ | | | | Response | this document | | |||
| @signature-params | Active | Section 2.3.2 of this document | | +-------------------+--------+-------------------+------------------+ | |||
+-------------------+--------+--------------------------------+ | | @method | Active | Request, | Section 2.3.2 of | | |||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @authority | Active | Request, | Section 2.3.4 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @scheme | Active | Request, | Section 2.3.5 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @target-uri | Active | Request, | Section 2.3.3 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @request-target | Active | Request, | Section 2.3.6 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @path | Active | Request, | Section 2.3.7 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @query | Active | Request, | Section 2.3.8 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @query-params | Active | Request, | Section 2.3.9 of | | ||||
| | | Related-Response | this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @status | Active | Response | Section 2.3.10 | | ||||
| | | | of this document | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
| @request-response | Active | Section 2.3.11 | | | ||||
| | | of this document | | | ||||
+-------------------+--------+-------------------+------------------+ | ||||
Table 5: Initial contents of the HTTP Signature Specialty | Table 4: Initial contents of the HTTP Signature Specialty Component | |||
Content Identifiers Registry. | Identifiers Registry. | |||
6. Security Considerations | 7. Security Considerations | |||
(( TODO: need to dive deeper on this section; not sure how much of | (( TODO: need to dive deeper on this section; not sure how much of | |||
what's referenced below is actually applicable, or if it covers | what's referenced below is actually applicable, or if it covers | |||
everything we need to worry about. )) | everything we need to worry about. )) | |||
(( TODO: Should provide some recommendations on how to determine what | (( TODO: Should provide some recommendations on how to determine what | |||
content needs to be signed for a given use case. )) | components need to be signed for a given use case. )) | |||
There are a number of security considerations to take into account | There are a number of security considerations to take into account | |||
when implementing or utilizing this specification. A thorough | when implementing or utilizing this specification. A thorough | |||
security analysis of this protocol, including its strengths and | security analysis of this protocol, including its strengths and | |||
weaknesses, can be found in [WP-HTTP-Sig-Audit]. | weaknesses, can be found in [WP-HTTP-Sig-Audit]. | |||
7. References | 8. References | |||
7.1. Normative References | 8.1. Normative References | |||
[FIPS186-4] | [FIPS186-4] | |||
"Digital Signature Standard (DSS)", 2013, | "Digital Signature Standard (DSS)", 2013, | |||
<https://csrc.nist.gov/publications/detail/fips/186/4/ | <https://csrc.nist.gov/publications/detail/fips/186/4/ | |||
final>. | final>. | |||
[HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [HTMLURL] "URL (Living Standard)", 2021, | |||
Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | <https://url.spec.whatwg.org/>. | |||
DOI 10.17487/RFC7540, May 2015, | ||||
<https://www.rfc-editor.org/rfc/rfc7540>. | ||||
[MESSAGING] | [MESSAGING] | |||
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | Fielding, R. T., Nottingham, M., and J. Reschke, | |||
Protocol (HTTP/1.1): Message Syntax and Routing", | "HTTP/1.1", Work in Progress, Internet-Draft, draft-ietf- | |||
RFC 7230, DOI 10.17487/RFC7230, June 2014, | httpbis-messaging-17, 25 July 2021, | |||
<https://www.rfc-editor.org/rfc/rfc7230>. | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
messaging-17>. | ||||
[POSIX.1] "The Open Group Base Specifications Issue 7, 2018 | [POSIX.1] "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/rfc/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/rfc/rfc2119>. | |||
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | ||||
Resource Identifier (URI): Generic Syntax", STD 66, | ||||
RFC 3986, DOI 10.17487/RFC3986, January 2005, | ||||
<https://www.rfc-editor.org/rfc/rfc3986>. | ||||
[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/rfc/rfc8174>. | |||
[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/rfc/rfc8792>. | |||
[RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for | [RFC8941] Nottingham, M. and P-H. 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/rfc/rfc8941>. | |||
[SEMANTICS] | [SEMANTICS] | |||
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | Fielding, R. T., Nottingham, M., and J. Reschke, "HTTP | |||
Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | Semantics", Work in Progress, Internet-Draft, draft-ietf- | |||
DOI 10.17487/RFC7231, June 2014, | httpbis-semantics-17, 25 July 2021, | |||
<https://www.rfc-editor.org/rfc/rfc7231>. | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
semantics-17>. | ||||
7.2. Informative References | 8.2. Informative References | |||
[I-D.ietf-httpbis-client-cert-field] | ||||
Campbell, B. and M. Bishop, "Client-Cert HTTP Header | ||||
Field: Conveying Client Certificate Information from TLS | ||||
Terminating Reverse Proxies to Origin Server | ||||
Applications", Work in Progress, Internet-Draft, draft- | ||||
ietf-httpbis-client-cert-field-00, 8 June 2021, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | ||||
client-cert-field-00>. | ||||
[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/rfc/rfc6234>. | |||
[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/rfc/rfc7239>. | |||
skipping to change at page 32, line 28 ¶ | skipping to change at page 46, line 23 ¶ | |||
[WP-HTTP-Sig-Audit] | [WP-HTTP-Sig-Audit] | |||
"Security Considerations for HTTP Signatures", 2013, | "Security Considerations for HTTP Signatures", 2013, | |||
<https://web-payments.org/specs/source/http-signatures- | <https://web-payments.org/specs/source/http-signatures- | |||
audit/>. | audit/>. | |||
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-standard definitions of the "Signature" | past, including other non-standard definitions of the "Signature" | |||
header used within this specification. It is recommended that | field used within this specification. It is recommended that | |||
developers wishing to support both this specification and other | developers wishing to support both this specification and other | |||
historical drafts do so carefully and deliberately, as | historical drafts do so carefully and deliberately, as | |||
incompatibilities between this specification and various versions of | incompatibilities between this specification and various versions of | |||
other drafts could lead to unexpected problems. | other drafts could lead to unexpected problems. | |||
It is recommended that implementers first detect and validate the | It is recommended that implementers first detect and validate the | |||
"Signature-Input" header 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- | this standard is in use and not an alternative. If the "Signature- | |||
Input" header is present, all "Signature" headers can be parsed and | Input" field is present, all "Signature" fields can be parsed and | |||
interpreted in the context of this draft. | interpreted in the context of this draft. | |||
Appendix B. Examples | Appendix B. 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. | |||
skipping to change at page 35, line 21 ¶ | skipping to change at page 49, line 21 ¶ | |||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | |||
w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
B.1.4. Example Shared Secret | B.1.4. 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 | ||||
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 | |||
based on the following HTTP messages: | based on the following HTTP messages: | |||
For requests, this "test-request" message is used: | For requests, this "test-request" message is used: | |||
skipping to change at page 36, line 5 ¶ | skipping to change at page 50, line 5 ¶ | |||
For responses, this "test-response" message is used: | For responses, this "test-response" message is used: | |||
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 | |||
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
B.2.1. Minimal Signature Header using rsa-pss-sha512 | B.2.1. Minimal Signature Using rsa-pss-sha512 | |||
This example presents a minimal "Signature-Input" and "Signature" | This example presents a minimal "Signature-Input" and "Signature" | |||
header for a signature using the "rsa-pss-sha512" algorithm over | header for a signature using the "rsa-pss-sha512" algorithm over | |||
"test-request", covering none of the content of the HTTP message | "test-request", covering none of the components of the HTTP message | |||
request but providing a timestamped signature proof of possession of | request but providing a timestamped signature proof of possession of | |||
the key. | the key. | |||
The corresponding signature input is: | The corresponding signature input is: | |||
NOTE: '\' line wrapping per RFC 8792 | ||||
"@signature-params": ();created=1618884475\ | "@signature-params": ();created=1618884475\ | |||
;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | ;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | |||
This results in the following "Signature-Input" and "Signature" | This results in the following "Signature-Input" and "Signature" | |||
headers being added to the message: | headers being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | ||||
Signature-Input: sig1=();created=1618884475\ | Signature-Input: sig1=();created=1618884475\ | |||
;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | ;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | |||
Signature: sig1=:VrfdC2KEFFLoGMYTbQz4PSlKat4hAxcr5XkVN7Mm/7OQQJG+uX\ | Signature: sig1=:HWP69ZNiom9Obu1KIdqPPcu/C1a5ZUMBbqS/xwJECV8bhIQVmE\ | |||
gOez7kA6n/yTCaR1VL+FmJd2IVFCsUfcc/jO9siZK3siadoK1Dfgp2ieh9eO781ty\ | AAAzz8LQPvtP1iFSxxluDO1KE9b8L+O64LEOvhwYdDctV5+E39Jy1eJiD7nYREBgx\ | |||
SS70OwvAkdORuQLWDnaDMRDlQhg5sNP6JaQghFLqD4qgFrM9HMPxLrznhAQugJ0Fd\ | TpdUfzTO+Trath0vZdTylFlxK4H3l3s/cuFhnOCxmFYgEa+cw+StBRgY1JtafSFwN\ | |||
RZLtSpnjECW6qsu2PVRoCYfnwe4gu8TfqH5GDx2SkpCF9BQ8CijuIWlOg7QP73tKt\ | cZgLxVwialuH5VnqJS4JN8PHD91XLfkjMscTo4jmVMpFd3iLVe0hqVFl7MDt6TMkw\ | |||
QNp65u14Si9VEVXHWGiLw4blyPLzWz/fqJbdLaq94Ep60Nq8WjYEAInYH6KyV7EAD\ | IyVFnEZ7B/VIQofdShO+C/7MuupCSLVjQz5xA+Zs6Hw+W9ESD/6BuGs6LF1TcKLxW\ | |||
60LXdspwF50R3dkWXJP/x+gkAHSMsxbg==: | +5K+2zvDY/Cia34HNpRW5io7Iv9/b7iQ==: | |||
B.2.2. Header Coverage using rsa-pss-sha512 | Note that since the covered components list is empty, this signature | |||
could be applied by an attacker to an unrelated HTTP message. | ||||
Therefore, use of an empty covered components set is discouraged. | ||||
This example covers all the specified headers in "test-request" | B.2.2. Selective Covered Components using rsa-pss-sha512 | |||
except for the body digest header using the "rsa-pss-sha512" | ||||
algorithm. | This example covers additional components in "test-request" using the | |||
"rsa-pss-sha512" algorithm. | ||||
The corresponding signature input is: | The corresponding signature input is: | |||
"host": example.com | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | ||||
"@authority": example.com | ||||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("host" "date" "content-type")\ | "@signature-params": ("@authority" "content-type")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
This results in the following "Signature-Input" and "Signature" | This results in the following "Signature-Input" and "Signature" | |||
headers being added to the message: | headers being added to the message: | |||
Signature-Input: sig1=("host" "date" "content-type")\ | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "content-type")\ | ||||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
Signature: sig1=:Zu48JBrHlXN+hVj3T5fPQUjMNEEhABM5vNmiWuUUl7BWNid5Rz\ | Signature: sig1=:ik+OtGmM/kFqENDf9Plm8AmPtqtC7C9a+zYSaxr58b/E6h81gh\ | |||
OH1tEjVi+jObYkYT8p09lZ2hrNuU3xm+JUBT8WNIlopJtt0EzxFnjGlHvkhu3KbJf\ | JS3PcH+m1asiMp8yvccnO/RfaexnqanVB3C72WRNZN7skPTJmUVmoIeqZncdP2mlf\ | |||
xNlvCJVlOEdR4AivDLMeK/ZgASpZ7py1UNHJqRyGCYkYpeedinXUertL/ySNp+VbK\ | xlLP6UbkrgYsk91NS6nwkKC6RRgLhBFqzP42oq8D2336OiQPDAo/04SxZt4Wx9nDG\ | |||
2O/qCoui2jFgff2kXQd6rjL1Up83Fpr+/KoZ6HQkv3qwBdMBDyHQykfZHhLn4AO1I\ | uy2SfZJUhsJqZyEWRk4204x7YEB3VxDAAlVgGt8ewilWbIKKTOKp3ymUeQIwptqYw\ | |||
G+vKhOLJQDfaLsJ/fYfzsgc1s46j3GpPPD/W2nEEtdhNwu7oXq81qVRsENChIu1XI\ | v0l8mN404PPzRBTpB7+HpClyK4CNp+SVv46+6sHMfJU4taz10s/NoYRmYCGXyadzY\ | |||
FKR9q7WpyHDKEWTtaNZDS8TFvIQRU22w==: | YDj0BYnFdERB6NblI/AOWFGl5Axhhmjg==: | |||
B.2.3. Full Coverage using rsa-pss-sha512 | B.2.3. Full Coverage using rsa-pss-sha512 | |||
This example covers all headers in "test-request" plus the request | This example covers all headers in "test-request" (including the | |||
target and message body digest using the "rsa-pss-sha512" algorithm. | message body "Digest") plus various elements of the control data, | |||
using the "rsa-pss-sha512" algorithm. | ||||
The corresponding signature input is: | The corresponding signature input is: | |||
"@request-target": post /foo?param=value&pet=dog | NOTE: '\' line wrapping per RFC 8792 | |||
"host": example.com | ||||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:56 GMT | |||
"@method": POST | ||||
"@path": /foo | ||||
"@query": ?param=value&pet=dog | ||||
"@authority": example.com | ||||
"content-type": application/json | "content-type": application/json | |||
"digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | "digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
"content-length": 18 | "content-length": 18 | |||
"@signature-params": ("@request-target" "host" "date" \ | "@signature-params": ("date" "@method" "@path" "@query" \ | |||
"content-type" "digest" "content-length");created=1618884475\ | "@authority" "content-type" "digest" "content-length")\ | |||
;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
This results in the following "Signature-Input" and "Signature" | This results in the following "Signature-Input" and "Signature" | |||
headers being added to the message: | headers being added to the message: | |||
Signature-Input: sig1=("@request-target" "host" "date" \ | NOTE: '\' line wrapping per RFC 8792 | |||
"content-type" "digest" "content-length");created=1618884475\ | ||||
;keyid="test-key-rsa-pss" | Signature-Input: sig1=("date" "@method" "@path" "@query" \ | |||
Signature: \ | "@authority" "content-type" "digest" "content-length")\ | |||
sig1=:iD5NhkJoGSuuTpWMzS0BI47DfbWwsGmHHLTwOxT0n+0cQFSC+1c26B7IOfI\ | ;created=1618884475;keyid="test-key-rsa-pss" | |||
RTYofqD0sfYYrnSwCvWJfA1zthAEv9J1CxS/CZXe7CQvFpuKuFJxMpkAzVYdE/TA6\ | Signature: sig1=:JuJnJMFGD4HMysAGsfOY6N5ZTZUknsQUdClNG51VezDgPUOW03\ | |||
fELxNZy9RJEWZUPBU4+aJ26d8PC0XhPObXe6JkP6/C7XvG2QinsDde7rduMdhFN/H\ | QMe74vbIdndKwW1BBrHOHR3NzKGYZJ7X3ur23FMCdANe4VmKb3Rc1Q/5YxOO8p7Ko\ | |||
j2MuX1Ipzvv4EgbHJdKwmWRNamfmKJZC4U5Tn0F58lzGF+WIpU73V67/6aSGvJGM5\ | yfVa4uUcMk5jB9KAn1M1MbgBnqwZkRWsbv8ocCqrnD85Kavr73lx51k1/gU8w673W\ | |||
7U9bRHrBB7ExuQhOX2J2dvJMYkE33pEJA70XBUp9ZvciTI+vjIUgUQ2oRww3huWML\ | T/oBtxPtAn1eFjUyIKyA+XD7kYph82I+ahvm0pSgDPagu917SlqUjeaQaNnlZzO03\ | |||
mMMqEc95CliwIoL5aBdCnlQ==: | Iy1RZ5XpgbNeDLCqSLuZFVID80EohC2CQ1cL5svjslrlCNstd2JCLmhjL7xV3NYXe\ | |||
rLim4bqUQGRgDwNJRnqobpS6C1NBns/Q==: | ||||
Note in this example that the value of the "Date" header and the | ||||
value of the "created" signature parameter need not be the same. | ||||
This is due to the fact that the "Date" header is added when creating | ||||
the HTTP Message and the "created" parameter is populated when | ||||
creating the signature over that message, and these two times could | ||||
vary. If the "Date" header is covered by the signature, it is up to | ||||
the verifier to determine whether its value has to match that of the | ||||
"created" parameter or not. | ||||
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" response message | |||
using the "ecdsa-p256-sha256" algorithm and the key "test-key-ecc- | using the "ecdsa-p256-sha256" algorithm and the key "test-key-ecc- | |||
p256". | p256". | |||
The corresponding signature input is: | The corresponding signature input is: | |||
"date": Tue, 20 Apr 2021 02:07:56 GMT | NOTE: '\' line wrapping per RFC 8792 | |||
"content-type": application/json | "content-type": application/json | |||
"digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | "digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
"content-length": 18 | "content-length": 18 | |||
"@signature-params": ("date" "content-type" "digest" \ | "@signature-params": ("content-type" "digest" "content-length")\ | |||
"content-length");created=1618884475;keyid="test-key-ecc-p256" | ;created=1618884475;keyid="test-key-ecc-p256" | |||
This results in the following "Signature-Input" and "Signature" | This results in the following "Signature-Input" and "Signature" | |||
headers being added to the message: | headers being added to the message: | |||
Signature-Input: sig1=("date" "content-type" "digest" \ | NOTE: '\' line wrapping per RFC 8792 | |||
"content-length");created=1618884475;keyid="test-key-ecc-p256" | ||||
Signature: \ | Signature-Input: sig1=("content-type" "digest" "content-length")\ | |||
sig1=:3zmRDW6r50/RETqqhtx/N5sdd5eTh8xmHdsrYRK9wK4rCNEwLjCOBlcQxTL\ | ;created=1618884475;keyid="test-key-ecc-p256" | |||
2oJTCWGRkuqE2r9KyqZFY9jd+NQ==: | Signature: sig1=:n8RKXkj0iseWDmC6PNSQ1GX2R9650v+lhbb6rTGoSrSSx18zmn\ | |||
6fPOtBx48/WffYLO0n1RHHf9scvNGAgGq52Q==: | ||||
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" using the "hmac- | |||
sha256" algorithm and the secret "test-shared-secret". | sha256" algorithm and the secret "test-shared-secret". | |||
The corresponding signature input is: | The corresponding signature input is: | |||
"host": example.com | NOTE: '\' line wrapping per RFC 8792 | |||
"@authority": 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 | |||
"@signature-params": ("host" "date" "content-type")\ | "@signature-params": ("@authority" "date" "content-type")\ | |||
;created=1618884475;keyid="test-shared-secret" | ;created=1618884475;keyid="test-shared-secret" | |||
This results in the following "Signature-Input" and "Signature" | This results in the following "Signature-Input" and "Signature" | |||
headers being added to the message: | headers being added to the message: | |||
Signature-Input: sig1=("host" "date" "content-type")\ | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "date" "content-type")\ | ||||
;created=1618884475;keyid="test-shared-secret" | ;created=1618884475;keyid="test-shared-secret" | |||
Signature: sig1=:x54VEvVOb0TMw8fUbsWdUHqqqOre+K7sB/LqHQvnfaQ=: | Signature: sig1=:fN3AMNGbx0V/cIEKkZOvLOoC3InI+lM2+gTv22x3ia8=: | |||
B.3. TLS-Terminating Proxies | ||||
In this example, there is a TLS-terminating reverse proxy sitting in | ||||
front of the resource. The client does not sign the request but | ||||
instead uses mutual TLS to make its call. The terminating proxy | ||||
validates the TLS stream and injects a "Client-Cert" header according | ||||
to [I-D.ietf-httpbis-client-cert-field]. By signing this header | ||||
field, a reverse proxy can not only attest to its own validation of | ||||
the initial request but also authenticate itself to the backend | ||||
system independently of the client's actions. The client makes the | ||||
following request to the TLS terminating proxy using mutual TLS: | ||||
POST /foo?Param=value&pet=Dog HTTP/1.1 | ||||
Host: example.com | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 18 | ||||
{"hello": "world"} | ||||
The proxy processes the TLS connection and extracts the client's TLS | ||||
certificate to a "Client-Cert" header field and passes it along to | ||||
the internal service hosted at "service.internal.example". This | ||||
results in the following unsigned request: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
POST /foo?Param=value&pet=Dog HTTP/1.1 | ||||
Host: service.internal.example | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 18 | ||||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | ||||
BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | ||||
AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | ||||
wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | ||||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | ||||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | ||||
8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | ||||
4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | ||||
bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | ||||
{"hello": "world"} | ||||
Without a signature, the internal service would need to trust that | ||||
the incoming connection has the right information. By signing the | ||||
"Client-Cert" header and other portions of the internal request, the | ||||
internal service can be assured that the correct party, the trusted | ||||
proxy, has processed the request and presented it to the correct | ||||
service. The proxy's signature input consists of the following: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
"@path": /foo | ||||
"@query": Param=value&pet=Dog | ||||
"@method": POST | ||||
"@authority": service.internal.example | ||||
"client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ | ||||
KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ | ||||
QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ | ||||
FkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXm\ | ||||
ckC8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQY\ | ||||
DVR0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8B\ | ||||
Af8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQ\ | ||||
GV4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0\ | ||||
Q6bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | ||||
"@signature-params": ("@path" "@query" "@method" "@authority" \ | ||||
"client-cert");created=1618884475;keyid="test-key-ecc-p256" | ||||
This results in the following signature: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
5gudRjXaHrAYbEaQUOoY9TuvqWOdPcspkp7YyKCB0XhyAG9cB715hucPPanEK0OVyiN\ | ||||
LJqcoq2Yn1DPWQcnbog== | ||||
Which results in the following signed request sent from the proxy to | ||||
the internal service: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
POST /foo?Param=value&pet=Dog HTTP/1.1 | ||||
Host: service.internal.example | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
Content-Type: application/json | ||||
Content-Length: 18 | ||||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | ||||
BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | ||||
AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | ||||
wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | ||||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | ||||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | ||||
8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | ||||
4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | ||||
bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | ||||
Signature-Input: ttrp=("@path" "@query" "@method" "@authority" \ | ||||
"client-cert");created=1618884475;keyid="test-key-ecc-p256" | ||||
Signature: ttrp=:5gudRjXaHrAYbEaQUOoY9TuvqWOdPcspkp7YyKCB0XhyAG9cB7\ | ||||
15hucPPanEK0OVyiNLJqcoq2Yn1DPWQcnbog==: | ||||
{"hello": "world"} | ||||
The internal service can validate the proxy's signature and therefore | ||||
be able to trust that the client's certificate has been appropriately | ||||
processed. | ||||
Acknowledgements | Acknowledgements | |||
This specification was initially based on the draft-cavage-http- | This specification was initially based on the draft-cavage-http- | |||
signatures internet draft. The editors would like to thank the | signatures internet draft. The editors would like to thank the | |||
authors of that draft, Mark Cavage and Manu Sporny, for their work on | authors of that draft, Mark Cavage and Manu Sporny, for their work on | |||
that draft and their continuing contributions. | that draft and their continuing contributions. | |||
The editors would also like to thank the following individuals for | The editors would also like to thank the following individuals for | |||
feedback, insight, and implementation of this draft and its | feedback, insight, and implementation of this draft and its | |||
skipping to change at page 39, line 17 ¶ | skipping to change at page 56, line 16 ¶ | |||
Michael Richardson, Wojciech Rygielski, Adam Scarr, Cory J. Slep, | Michael Richardson, Wojciech Rygielski, Adam Scarr, Cory J. Slep, | |||
Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey | Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey | |||
Yasskin. | Yasskin. | |||
Document History | Document History | |||
_RFC EDITOR: please remove this section before publication_ | _RFC EDITOR: please remove this section before publication_ | |||
* draft-ietf-httpbis-message-signatures | * draft-ietf-httpbis-message-signatures | |||
- -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 | - -05 | |||
o Remove list prefixes. | o Remove list prefixes. | |||
o Clarify signature algorithm parameters. | o Clarify signature algorithm parameters. | |||
o Update and fix examples. | o Update and fix examples. | |||
o Add examples for ECC and HMAC. | o Add examples for ECC and HMAC. | |||
End of changes. 211 change blocks. | ||||
538 lines changed or deleted | 1310 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |