draft-ietf-httpbis-message-signatures-06.txt | draft-ietf-httpbis-message-signatures-07.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: 14 February 2022 Bespoke Engineering | Expires: 23 June 2022 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
13 August 2021 | 20 December 2021 | |||
HTTP Message Signatures | HTTP Message Signatures | |||
draft-ietf-httpbis-message-signatures-06 | draft-ietf-httpbis-message-signatures-07 | |||
Abstract | Abstract | |||
This document describes a mechanism for creating, encoding, and | This document describes a mechanism for creating, encoding, and | |||
verifying digital signatures or message authentication codes over | verifying digital signatures or message authentication codes over | |||
components of an HTTP message. This mechanism supports use cases | components of an HTTP message. This mechanism supports use cases | |||
where the full HTTP message may not be known to the signer, and where | where the full HTTP message may not be known to the signer, and where | |||
the message may be transformed (e.g., by intermediaries) before | the message may be transformed (e.g., by intermediaries) before | |||
reaching the verifier. This document also describes a means for | reaching the verifier. This document also describes a means for | |||
requesting that a signature be applied to a subsequent HTTP message | requesting that a signature be applied to a subsequent HTTP message | |||
in an ongoing HTTP exchange. | in an ongoing HTTP exchange. | |||
Note to Readers | About This Document | |||
_RFC EDITOR: please remove this section before publication_ | This note is to be removed before publishing as an RFC. | |||
Discussion of this draft takes place on the HTTP working group | Status information for this document may be found at | |||
mailing list (ietf-http-wg@w3.org), which is archived at | https://datatracker.ietf.org/doc/draft-ietf-httpbis-message- | |||
https://lists.w3.org/Archives/Public/ietf-http-wg/ | signatures/. | |||
(https://lists.w3.org/Archives/Public/ietf-http-wg/). | ||||
Working Group information can be found at https://httpwg.org/ | Discussion of this document takes place on the HTTP Working Group | |||
(https://httpwg.org/); source code and issues list for this draft can | mailing list (mailto:ietf-http-wg@w3.org), which is archived at | |||
be found at https://github.com/httpwg/http-extensions/labels/ | https://lists.w3.org/Archives/Public/ietf-http-wg/. Working Group | |||
signatures (https://github.com/httpwg/http-extensions/labels/ | information can be found at https://httpwg.org/. | |||
signatures). | ||||
Source for this draft and an issue tracker can be found at | ||||
https://github.com/httpwg/http-extensions/labels/signatures. | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
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 14 February 2022. | This Internet-Draft will expire on 23 June 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 Revised BSD License text as | |||
as described in Section 4.e of the Trust Legal Provisions and are | 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 Revised BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 5 | 1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 5 | |||
1.2. HTTP Message Transformations . . . . . . . . . . . . . . 5 | 1.2. HTTP Message Transformations . . . . . . . . . . . . . . 6 | |||
1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 6 | 1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 6 | |||
1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | 1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | |||
1.5. Application of HTTP Message Signatures . . . . . . . . . 9 | 1.5. Application of HTTP Message Signatures . . . . . . . . . 9 | |||
2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | 2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | |||
2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | 2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 11 | 2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 12 | |||
2.1.2. Canonicalization Examples . . . . . . . . . . . . . . 11 | 2.1.2. HTTP Field Examples . . . . . . . . . . . . . . . . . 12 | |||
2.2. Dictionary Structured Field Members . . . . . . . . . . . 12 | 2.1.3. Dictionary Structured Field Members . . . . . . . . . 12 | |||
2.2.1. Canonicalization Examples . . . . . . . . . . . . . . 12 | 2.2. Specialty Components . . . . . . . . . . . . . . . . . . 13 | |||
2.3. Specialty Components . . . . . . . . . . . . . . . . . . 13 | 2.2.1. Signature Parameters . . . . . . . . . . . . . . . . 14 | |||
2.3.1. Signature Parameters . . . . . . . . . . . . . . . . 14 | 2.2.2. Method . . . . . . . . . . . . . . . . . . . . . . . 16 | |||
2.3.2. Method . . . . . . . . . . . . . . . . . . . . . . . 15 | 2.2.3. Target URI . . . . . . . . . . . . . . . . . . . . . 16 | |||
2.3.3. Target URI . . . . . . . . . . . . . . . . . . . . . 16 | 2.2.4. Authority . . . . . . . . . . . . . . . . . . . . . . 17 | |||
2.3.4. Authority . . . . . . . . . . . . . . . . . . . . . . 16 | 2.2.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
2.3.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 17 | 2.2.6. Request Target . . . . . . . . . . . . . . . . . . . 18 | |||
2.3.6. Request Target . . . . . . . . . . . . . . . . . . . 17 | 2.2.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
2.3.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 19 | 2.2.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
2.3.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 19 | 2.2.9. Query Parameters . . . . . . . . . . . . . . . . . . 20 | |||
2.3.9. Query Parameters . . . . . . . . . . . . . . . . . . 20 | 2.2.10. Status Code . . . . . . . . . . . . . . . . . . . . . 21 | |||
2.3.10. Status Code . . . . . . . . . . . . . . . . . . . . . 21 | 2.2.11. Request-Response Signature Binding . . . . . . . . . 22 | |||
2.3.11. Request-Response Signature Binding . . . . . . . . . 21 | 2.3. Creating the Signature Input String . . . . . . . . . . . 23 | |||
2.4. Creating the Signature Input String . . . . . . . . . . . 23 | 3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 26 | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 26 | ||||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 25 | 3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 28 | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 25 | 3.2.1. Enforcing Application Requirements . . . . . . . . . 30 | |||
3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 27 | 3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 31 | |||
3.2.1. Enforcing Application Requirements . . . . . . . . . 29 | 3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 32 | |||
3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 29 | 3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 32 | |||
3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 30 | 3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 33 | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 31 | 3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 33 | |||
3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 31 | 3.3.5. JSON Web Signature (JWS) algorithms . . . . . . . . . 34 | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 31 | 4. Including a Message Signature in a Message . . . . . . . . . 34 | |||
3.3.5. JSON Web Signature (JWS) algorithms . . . . . . . . . 32 | 4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 35 | |||
4. Including a Message Signature in a Message . . . . . . . . . 32 | 4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 35 | |||
4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 33 | 4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 36 | |||
4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 33 | 5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 38 | |||
4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 34 | 5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 39 | |||
5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 36 | 5.2. Processing an Accept-Signature . . . . . . . . . . . . . 40 | |||
5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 37 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 | |||
5.2. Processing an Accept-Signature . . . . . . . . . . . . . 37 | 6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 41 | |||
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 38 | 6.1.1. Registration Template . . . . . . . . . . . . . . . . 41 | |||
6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 38 | 6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 42 | |||
6.1.1. Registration Template . . . . . . . . . . . . . . . . 39 | 6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 42 | |||
6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 39 | 6.2.1. Registration Template . . . . . . . . . . . . . . . . 42 | |||
6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 41 | 6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 43 | |||
6.2.1. Registration Template . . . . . . . . . . . . . . . . 41 | ||||
6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 41 | ||||
6.3. HTTP Signature Specialty Component Identifiers | 6.3. HTTP Signature Specialty Component Identifiers | |||
Registry . . . . . . . . . . . . . . . . . . . . . . . . 41 | Registry . . . . . . . . . . . . . . . . . . . . . . . . 43 | |||
6.3.1. Registration Template . . . . . . . . . . . . . . . . 42 | 6.3.1. Registration Template . . . . . . . . . . . . . . . . 44 | |||
6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 42 | 6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 44 | |||
7. Security Considerations . . . . . . . . . . . . . . . . . . . 43 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 45 | |||
8. References . . . . . . . . . . . . . . . . . . . . . . . . . 44 | 7.1. Signature Verification Skipping . . . . . . . . . . . . . 46 | |||
8.1. Normative References . . . . . . . . . . . . . . . . . . 44 | 7.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 46 | |||
8.2. Informative References . . . . . . . . . . . . . . . . . 45 | 7.3. Signature Replay . . . . . . . . . . . . . . . . . . . . 47 | |||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 46 | 7.4. Insufficient Coverage . . . . . . . . . . . . . . . . . . 47 | |||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 46 | 7.5. Cryptography and Signature Collision . . . . . . . . . . 48 | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 46 | 7.6. Key Theft . . . . . . . . . . . . . . . . . . . . . . . . 48 | |||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 46 | 7.7. Modification of Required Message Parameters . . . . . . . 49 | |||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 47 | 7.8. Mismatch of Signature Parameters from Message . . . . . . 49 | |||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 48 | 7.9. Multiple Signature Confusion . . . . . . . . . . . . . . 49 | |||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 49 | 7.10. Signature Labels . . . . . . . . . . . . . . . . . . . . 50 | |||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 49 | 7.11. Symmetric Cryptography . . . . . . . . . . . . . . . . . 50 | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 50 | 7.12. Canonicalization Attacks . . . . . . . . . . . . . . . . 50 | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 50 | 7.13. Key Specification Mix-Up . . . . . . . . . . . . . . . . 51 | |||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 51 | 7.14. HTTP Versions and Component Ambiguity . . . . . . . . . . 51 | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 52 | 7.15. Key and Algorithm Specification Downgrades . . . . . . . 52 | |||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 53 | 7.16. Parsing Structured Field Values . . . . . . . . . . . . . 52 | |||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 53 | 7.17. Choosing Message Components . . . . . . . . . . . . . . . 53 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 55 | 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 53 | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 56 | 8.1. Identification through Keys . . . . . . . . . . . . . . . 53 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 59 | 8.2. Signatures do not provide confidentiality . . . . . . . . 54 | |||
8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 54 | ||||
8.4. Required Content . . . . . . . . . . . . . . . . . . . . 54 | ||||
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 54 | ||||
9.1. Normative References . . . . . . . . . . . . . . . . . . 54 | ||||
9.2. Informative References . . . . . . . . . . . . . . . . . 56 | ||||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 57 | ||||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 57 | ||||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 57 | ||||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 57 | ||||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 58 | ||||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 59 | ||||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 60 | ||||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 60 | ||||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 61 | ||||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 61 | ||||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 62 | ||||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 63 | ||||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 63 | ||||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 64 | ||||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 66 | ||||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 67 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 70 | ||||
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 40 ¶ | skipping to change at page 5, line 13 ¶ | |||
authentication codes (MACs) over only the components of the message | authentication codes (MACs) over only the components of the message | |||
that are 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 signing mechanism described in this document consists of three | The signing mechanism described in this document consists of three | |||
parts: | parts: | |||
* A common nomenclature and canonicalization rule set for the | * A common nomenclature and canonicalization rule set for the | |||
different protocol elements and other components of HTTP messages. | different protocol elements and other components of HTTP messages, | |||
used to create a signature input. | ||||
* Algorithms for generating and verifying signatures over HTTP | * Algorithms for generating and verifying signatures over HTTP | |||
message components using this nomenclature and rule set. | message components using this signature input through application | |||
of cryptographic primitives. | ||||
* 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, and for parsing attached signatures and metadata | |||
from HTTP messages. | ||||
This document also provides a mechanism for one party to signal to | This document also provides a mechanism for a potential verifier to | |||
another party that a signature is desired in one or more subsequent | signal to a potential signer that a signature is desired in one or | |||
messages. This optional negotiation mechanism can be used along with | more subsequent messages. This optional negotiation mechanism can be | |||
opportunistic or application-driven message signatures by either | used along with opportunistic or application-driven message | |||
party. | 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 signature input. Since the exact | and verifier to have the exact same signature input. Since the exact | |||
raw bytes of the message cannot be relied upon as a reliable source | raw bytes of the message cannot be relied upon as a reliable source | |||
of signature input, the signer and verifier must derive the signature | of signature input, the signer and verifier must derive the signature | |||
input from their respective versions of the message, via a mechanism | input from their respective versions of the message, via a mechanism | |||
that is resilient to safe changes that do not alter the meaning of | that is resilient to safe changes that do not alter the meaning of | |||
the message. | 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 | |||
must provide signers with some degree of control over which message | provide signers with some degree of control over which message | |||
components are 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 | |||
As mentioned earlier, HTTP explicitly permits and in some cases | As mentioned earlier, HTTP explicitly permits and in some cases | |||
requires implementations to transform messages in a variety of ways. | requires implementations to transform messages in a variety of ways. | |||
Implementations are required to tolerate many of these | Implementations are required to tolerate many of these | |||
transformations. What follows is a non-normative and non-exhaustive | transformations. What follows is a non-normative and non-exhaustive | |||
list of transformations that may occur under HTTP, provided as | list of transformations that may occur under HTTP, provided as | |||
context: | context: | |||
* Re-ordering of header fields with different header field names | * Re-ordering of header fields with different header field names | |||
([MESSAGING], Section 3.2.2). | (Section 3.2.2 of [MESSAGING]). | |||
* Combination of header fields with the same field name | * Combination of header fields with the same field name | |||
([MESSAGING], Section 3.2.2). | (Section 3.2.2 of [MESSAGING]). | |||
* Removal of header fields listed in the "Connection" header field | * Removal of header fields listed in the Connection header field | |||
([MESSAGING], Section 6.1). | (Section 6.1 of [MESSAGING]). | |||
* Addition of header fields that indicate control options | * Addition of header fields that indicate control options | |||
([MESSAGING], Section 6.1). | (Section 6.1 of [MESSAGING]). | |||
* Addition or removal of a transfer coding ([MESSAGING], | * Addition or removal of a transfer coding (Section 5.7.2 of | |||
Section 5.7.2). | [MESSAGING]). | |||
* Addition of header fields such as "Via" ([MESSAGING], | * Addition of header fields such as Via (Section 5.7.1 of | |||
Section 5.7.1) and "Forwarded" ([RFC7239], Section 4). | [MESSAGING]) and Forwarded (Section 4 of [RFC7239]). | |||
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 message | prevent signature verification, even when performed on message | |||
components covered by the signature. The following list describes | components covered by the signature. The following list describes | |||
those transformations: | those transformations: | |||
* Combination of header fields with the same field name. | * Combination of header fields with the same field name. | |||
skipping to change at page 6, line 42 ¶ | skipping to change at page 7, line 15 ¶ | |||
* 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 components 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 components not covered by the signature | Additionally, all changes to components not covered by the signature | |||
are 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- | |||
form", "absolute-path", "effective request URI", "gateway", "header | form, absolute-path, "effective request URI", "gateway", "header | |||
field", "intermediary", "request-target", "sender", and "recipient" | field", "intermediary", request-target, "sender", and "recipient" are | |||
are used as defined in [MESSAGING]. | used as defined in [MESSAGING]. | |||
The term "method" is to be interpreted as defined in Section 4 of | The term "method" is to be interpreted as defined in Section 4 of | |||
[SEMANTICS]. | [SEMANTICS]. | |||
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 (which use asymmetric | |||
verb "sign" refers to the generation of either a digital signature or | cryptography) and keyed MACs (which use symmetric cryptography). | |||
keyed MAC over a given input string. The qualified term "digital | Similarly, the verb "sign" refers to the generation of either a | |||
signature" refers specifically to the output of an asymmetric | digital signature or keyed MAC over a given input string. The | |||
cryptographic signing operation. | qualified term "digital signature" refers specifically to the output | |||
of an asymmetric 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: | |||
HTTP Message Signature: | HTTP Message Signature: | |||
A digital signature or keyed MAC that covers one or more portions | A digital signature or keyed MAC that covers one or more portions | |||
of an HTTP message. Note that a given HTTP Message can contain | of an HTTP message. Note that a given HTTP Message can contain | |||
multiple HTTP Message Signatures. | multiple HTTP Message Signatures. | |||
Signer: | Signer: | |||
The entity that is generating or has generated an HTTP Message | The entity that is generating or has generated an HTTP Message | |||
Signature. Note that multiple entities can act as signers and | Signature. Note that multiple entities can act as signers and | |||
apply separate HTTP Message Signatures to a given HTTP Message. | apply separate HTTP Message Signatures to a given HTTP Message. | |||
Verifier: | Verifier: | |||
skipping to change at page 8, line 17 ¶ | skipping to change at page 8, line 37 ¶ | |||
Message it applies to. | Message it applies to. | |||
HTTP Message Component Value: | HTTP Message Component Value: | |||
The value associated with a given component identifier within the | The value associated with a given component identifier within the | |||
context of a particular HTTP Message. Component values are | context of a particular HTTP Message. Component values are | |||
derived from the HTTP Message and are usually subject to a | derived from the HTTP Message and are usually subject to a | |||
canonicalization process. | canonicalization process. | |||
Covered Components: | Covered Components: | |||
An ordered set of HTTP message component identifiers for fields | An ordered set of HTTP message component identifiers for fields | |||
(Section 2.1) and specialty components (Section 2.3) that | (Section 2.1) and specialty components (Section 2.2) that | |||
indicates the set of message components covered by the signature, | indicates the set of message components covered by the signature, | |||
not including the "@signature-params" specialty identifier itself. | not including the @signature-params specialty identifier itself. | |||
The order of this set is preserved and communicated between the | The order of this set is preserved and communicated between the | |||
signer and verifier to facilitate reconstruction of the signature | signer and verifier to facilitate reconstruction of the signature | |||
input. | input. | |||
Signature Input: | Signature Input: | |||
The sequence of bytes processed by the HTTP Message Signature | The sequence of bytes processed by the cryptographic algorithm to | |||
algorithm to produce the HTTP Message Signature. The signature | produce or verify the HTTP Message Signature. The signature input | |||
input is generated by the signer and verifier using the covered | is generated by the signer and verifier using the covered | |||
components set and the HTTP Message. | components set and the HTTP Message. | |||
HTTP Message Signature Algorithm: | HTTP Message Signature Algorithm: | |||
A cryptographic algorithm that describes the signing and | A cryptographic algorithm that describes the signing and | |||
verification process for the signature. When expressed | verification process for the signature, defined in terms of the | |||
explicitly, the value maps to a string defined in the HTTP | HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | |||
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. | |||
Creation Time: | Creation Time: | |||
A timestamp representing the point in time that the signature was | A timestamp representing the point in time that the signature was | |||
generated, as asserted by the signer. | generated, as asserted by the signer. | |||
Expiration Time: | Expiration Time: | |||
A timestamp representing the point in time at which the signature | A timestamp representing the point in time after which the | |||
expires, as asserted by the signer. A signature's expiration time | signature should no longer be accepted by the verifier, as | |||
could be undefined, indicating that the signature does not expire | asserted by the signer. | |||
from the perspective of the signer. | ||||
The term "Unix time" is defined by [POSIX.1], Section 4.16 | The term "Unix time" is defined by [POSIX.1], Section 4.16 | |||
(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ | (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ | |||
V1_chap04.html#tag_04_16). | V1_chap04.html#tag_04_16). | |||
This document contains non-normative examples of partial and complete | This document contains non-normative examples of partial and complete | |||
HTTP messages. Some examples use a single trailing backslash '' to | HTTP messages. Some examples use a single trailing backslash '' to | |||
indicate line wrapping for long values, as per [RFC8792]. The "\" | indicate line wrapping for long values, as per [RFC8792]. The \ | |||
character and leading spaces on wrapped lines are not part of the | character and leading spaces on wrapped lines are not part of the | |||
value. | value. | |||
1.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 component 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 | |||
of the signature parameters (Section 2.3.1) and define rules for | the signature parameters (Section 2.2.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 is appropriate for the key material. For example, the | signature is appropriate for the key material. For example, the | |||
process could use the "alg" parameter of the signature parameters | process could use the alg parameter of the signature parameters | |||
(Section 2.3.1) to state the algorithm explicitly, derive the | (Section 2.2.1) to state the algorithm explicitly, derive the | |||
algorithm from the key material, or use some pre-configured | algorithm from the key material, or use some pre-configured | |||
algorithm agreed upon by the signer and verifier. | algorithm agreed upon by the signer and 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 | An application using signatures also has to ensure that the verifier | |||
will have access to all required information to re-create the | will have access to all required information to re-create the | |||
signature input string. For example, a server behind a reverse proxy | signature input string. For example, a server behind a reverse proxy | |||
would need to know the original request URI to make use of | would need to know the original request URI to make use of | |||
identifiers like "@target-uri". Additionally, an application using | identifiers like @target-uri. Additionally, an application using | |||
signatures in responses would need to ensure that clients receiving | signatures in responses would need to ensure that clients receiving | |||
signed responses have access to all the signed portions, including | signed responses have access to all the signed portions, including | |||
any portions of the request that were signed by the server. | 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, however some | |||
additional considerations are discussed in Section 7. | ||||
2. HTTP Message Components | 2. HTTP Message Components | |||
In order to allow signers and verifiers to establish which components | In order to allow signers and verifiers to establish which components | |||
are covered by a signature, this document defines component | are covered by a signature, this document defines component | |||
identifiers for components covered by an HTTP Message Signature, a | identifiers for components covered by an HTTP Message Signature, a | |||
set of rules for deriving and canonicalizing the values associated | set of rules for deriving and canonicalizing the values associated | |||
with these component identifiers from the HTTP Message, and the means | with these component identifiers from the HTTP Message, and the means | |||
for combining these canonicalized values into a signature input | for combining these canonicalized values into a signature input | |||
string. The values for these items MUST be accessible to both the | string. The values for these items MUST be accessible to both the | |||
skipping to change at page 10, line 35 ¶ | skipping to change at page 11, line 10 ¶ | |||
Some HTTP message components can undergo transformations that change | Some HTTP message components can undergo transformations that change | |||
the bitwise value without altering meaning of the component's value | the bitwise value without altering meaning of the component's value | |||
(for example, the merging together of header fields with the same | (for example, the merging together of header fields with the same | |||
name). Message component values must therefore be canonicalized | name). Message component values must therefore be canonicalized | |||
before it is signed, to ensure that a signature can be verified | before it is signed, to ensure that a signature can be verified | |||
despite such intermediary transformations. This document defines | despite such intermediary transformations. This document defines | |||
rules for each component identifier that transform the identifier's | rules for each component identifier that transform the identifier's | |||
associated component value into such a canonical form. | associated component value into such a canonical form. | |||
Component identifiers are serialized using the production grammar | Component identifiers are serialized using the production grammar | |||
defined by RFC8941, Section 4 [RFC8941]. The component identifier | defined by [RFC8941], Section 4. The component identifier itself is | |||
itself is an "sf-string" value and MAY define parameters which are | an sf-string value and MAY define parameters which are included using | |||
included using the "parameters" rule. | the parameters rule. | |||
component-identifier = sf-string parameters | component-identifier = sf-string parameters | |||
Note that this means the value of the component identifier itself is | Note that this means the serialization of the component identifier | |||
encased in double quotes, with parameters following as a semicolon- | itself is encased in double quotes, with parameters following as a | |||
separated list, such as ""cache-control"", ""date"", or ""@signature- | semicolon-separated list, such as "cache-control", "date", or | |||
params"". | "@signature-params". | |||
Component identifiers including their parameters MUST NOT be repeated | ||||
within a single list of covered components. | ||||
The component value associated with a component identifier is defined | ||||
by the identifier itself. Component values MUST NOT contain newline | ||||
(\n) characters. | ||||
The following sections define component identifier types, their | The following sections define component identifier types, their | |||
parameters, their associated values, and the canonicalization rules | parameters, their associated values, and the canonicalization rules | |||
for their values. The method for combining component identifiers | for their values. The method for combining component identifiers | |||
into the signature input is defined in Section 2.4. | into the signature input is defined in Section 2.3. | |||
2.1. HTTP Fields | 2.1. HTTP Fields | |||
The component identifier for an HTTP field is the lowercased form of | The component identifier for an HTTP field is the lowercased form of | |||
its field name. While HTTP field names are case-insensitive, | its field name. While HTTP field names are case-insensitive, | |||
implementations MUST use lowercased field names (e.g., "content- | implementations MUST use lowercased field names (e.g., content-type, | |||
type", "date", "etag") when using them as component identifiers. | date, etag) when using them as component identifiers. | |||
Unless overridden by additional parameters and rules, the HTTP field | Unless overridden by additional parameters and rules, the HTTP 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 field in the message, in the order that they occur (or will | the field in the message, in the order that they occur (or 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 single comma "," and | |||
" between each item. | space " " between each item. | |||
The resulting string is the canonicalized component value. | The resulting string is the canonicalized component value. | |||
2.1.1. Canonicalized Structured HTTP Fields | 2.1.1. Canonicalized Structured HTTP Fields | |||
If value of the the HTTP field in question is a structured field | If value of the the HTTP field in question is a structured field | |||
([RFC8941]), the component identifier MAY include the "sf" parameter. | ([RFC8941]), the component identifier MAY include the sf parameter. | |||
If this parameter is included, the HTTP field 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]. For example, this process will replace any optional | For example, this process will replace any optional internal | |||
internal whitespace with a single space character. | whitespace with a single space character. | |||
The resulting string is used as the component value 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. HTTP Field Examples | |||
This section contains non-normative examples of canonicalized values | Following are non-normative examples of canonicalized values for | |||
for header fields, given the following example HTTP message: | header fields, given the following example HTTP message: | |||
Host: 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) | X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | |||
The following table shows example canonicalized values for header | ||||
fields, given that message: | ||||
+=====================+==================================+ | The following example shows canonicalized values for these example | |||
| Header Field | Canonicalized Value | | header fields, presented using the signature input string format | |||
+=====================+==================================+ | discussed in Section 2.3: | |||
| "cache-control" | max-age=60, must-revalidate | | ||||
+---------------------+----------------------------------+ | ||||
| "date" | Tue, 07 Jun 2014 20:51:35 GMT | | ||||
+---------------------+----------------------------------+ | ||||
| "host" | www.example.com | | ||||
+---------------------+----------------------------------+ | ||||
| "x-empty-header" | | | ||||
+---------------------+----------------------------------+ | ||||
| "x-obs-fold-header" | Obsolete line folding. | | ||||
+---------------------+----------------------------------+ | ||||
| "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 | "cache-control": max-age=60, must-revalidate| | |||
canonicalization. | "date": Tue, 07 Jun 2014 20:51:35 GMT| | |||
"host": www.example.com| | ||||
"x-empty-header": | ||||
"x-obs-fold-header": Obsolete line folding. | ||||
"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) | ||||
2.2. Dictionary Structured Field Members | 2.1.3. 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 component identifier | identified by using the parameter key to indicate the member key as | |||
for the field. The value of this parameter is a the key being | an sf-string value. | |||
identified, without any parameters present on that key in the | ||||
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] on a Dictionary containing only that item. | |||
that item. | ||||
2.2.1. Canonicalization Examples | Each parameterized key for a given field MUST NOT appear more than | |||
once in the signature input. Parameterized keys MAY appear in any | ||||
order. | ||||
This section contains non-normative examples of canonicalized values | Following are non-normative examples of canonicalized values for | |||
for Dictionary Structured Field Members given the following example | Dictionary Structured Field Members given the following example | |||
header field, whose value is known 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 | ||||
component identifiers, given that field: | ||||
+======================+=================+ | The following example shows canonicalized values for different | |||
| Component Identifier | Component Value | | component identifiers of this field, presented using the signature | |||
+======================+=================+ | input string format discussed in Section 2.3: | |||
| "x-dictionary";key=a | 1 | | ||||
+----------------------+-----------------+ | ||||
| "x-dictionary";key=b | 2;x=1;y=2 | | ||||
+----------------------+-----------------+ | ||||
| "x-dictionary";key=c | (a, b, c) | | ||||
+----------------------+-----------------+ | ||||
Table 2: Non-normative examples of | "x-dictionary";key="a": 1 | |||
Dictionary member canonicalization. | "x-dictionary";key="b": 2;x=1;y=2 | |||
"x-dictionary";key="c": (a, b, c) | ||||
2.3. Specialty Components | 2.2. Specialty Components | |||
Message components not found in an HTTP field can be included in the | Message components not found in an HTTP field can be included in the | |||
signature input by defining a component identifier and the | signature input by defining a component identifier and the | |||
canonicalization method for its component value. | canonicalization method for its component value. | |||
To differentiate specialty component identifiers from HTTP fields, | To differentiate specialty component identifiers from HTTP fields, | |||
specialty component identifiers MUST start with the "at" "@" | specialty component identifiers MUST start with the "at" @ character. | |||
character. This specification defines the following specialty | This specification defines the following specialty component | |||
component identifiers: | identifiers: | |||
@signature-params The signature metadata parameters for this | @signature-params The signature metadata parameters for this | |||
signature. (Section 2.3.1) | signature. (Section 2.2.1) | |||
@method The method used for a request. (Section 2.3.2) | @method The method used for a request. (Section 2.2.2) | |||
@target-uri The full target URI for a request. (Section 2.3.3) | @target-uri The full target URI for a request. (Section 2.2.3) | |||
@authority The authority of the target URI for a request. | @authority The authority of the target URI for a request. | |||
(Section 2.3.4) | (Section 2.2.4) | |||
@scheme The scheme of the target URI for a request. (Section 2.3.5) | @scheme The scheme of the target URI for a request. (Section 2.2.5) | |||
@request-target The request target. (Section 2.3.6) | @request-target The request target. (Section 2.2.6) | |||
@path The absolute path portion of the target URI for a request. | @path The absolute path portion of the target URI for a request. | |||
(Section 2.3.7) | ||||
(Section 2.2.7) | ||||
@query The query portion of the target URI for a request. | @query The query portion of the target URI for a request. | |||
(Section 2.3.8) | (Section 2.2.8) | |||
@query-params The parsed query parameters of the target URI for a | @query-params The parsed query parameters of the target URI for a | |||
request. (Section 2.3.9) | request. (Section 2.2.9) | |||
@status The status code for a response. (Section 2.3.10). | @status The status code for a response. (Section 2.2.10). | |||
@request-response A signature from a request message that resulted | @request-response A signature from a request message that resulted | |||
in this response message. (Section 2.3.11) | in this response message. (Section 2.2.11) | |||
Additional specialty component identifiers MAY be defined and | Additional specialty component identifiers MAY be defined and | |||
registered in the HTTP Signatures Specialty Component Identifier | registered in the HTTP Signatures Specialty Component Identifier | |||
Registry. (Section 6.3) | Registry. (Section 6.3) | |||
2.3.1. Signature Parameters | Specialty components can be applied in one or more of three targets: | |||
request: Values derived from and results applied to an HTTP request | ||||
message as described in {{Section 3.4 of SEMANTICS. | ||||
response: Values derived from and results applied to an HTTP | ||||
response message as described in Section 3.4 of [SEMANTICS]. | ||||
related-response: Values derived from an HTTP request message and | ||||
results applied to the HTTP response message that is responding to | ||||
that specific request. | ||||
A component identifier definition MUST define all targets to which it | ||||
can be applied. | ||||
2.2.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 verification, | information regarding the signature's generation and verification, | |||
such as the set of covered components, a timestamp, identifiers for | such as the set of covered components, a timestamp, identifiers for | |||
verification key material, and other utilities. | verification key material, and other utilities. | |||
The signature parameters component identifier is "@signature-params". | The signature parameters component identifier is @signature-params. | |||
This message component's value is REQUIRED as part of the signature | ||||
input string (Section 2.3) but the component identifier MUST NOT be | ||||
enumerated within the set of covered components itself. | ||||
The signature parameters component value is the serialization of the | The signature parameters component value is the serialization of the | |||
signature parameters for this signature, including the covered | signature parameters for this signature, including the covered | |||
components set with all associated parameters. These parameters | components set with all associated parameters. These parameters | |||
include any of the following: | 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. Inclusion of this | Sub-second precision is not supported. Inclusion of this | |||
parameter is RECOMMENDED. | parameter is RECOMMENDED. | |||
* "expires": Expiration time as an "sf-integer" UNIX timestamp | * expires: Expiration time as an sf-integer UNIX timestamp value. | |||
value. Sub-second precision is not supported. | Sub-second precision is not supported. | |||
* "nonce": A random unique value generated for this signature. | * nonce: A random unique value generated for this signature as an | |||
sf-string value. | ||||
* "alg": The HTTP message signature algorithm from the HTTP Message | * alg: The HTTP message signature algorithm from the HTTP Message | |||
Signature Algorithm Registry, as an "sf-string" value. | Signature Algorithm Registry, as an sf-string value. | |||
* "keyid": The identifier for the key material as an "sf-string" | * keyid: The identifier for the key material as an sf-string value. | |||
value. | ||||
Additional parameters can be defined in the HTTP Signature Parameters | Additional parameters can be defined in the HTTP Signature Parameters | |||
Registry (Section 6.2.2). | Registry (Section 6.2.2). | |||
The signature parameters component value is serialized as a | The signature parameters component value is serialized as a | |||
parameterized inner list using the rules in Section 4 of RFC8941 | parameterized inner list using the rules in Section 4 of [RFC8941] as | |||
[RFC8941] as follows: | follows: | |||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. Determine an order for the component identifiers of the covered | 2. Determine an order for the component identifiers of the covered | |||
components. Once this order is chosen, it cannot be changed. | components, not including the @signature-params component | |||
This order MUST be the same order as used in creating the | identifier itself. Once this order is chosen, it cannot be | |||
signature input (Section 2.4). | changed. This order MUST be the same order as used in creating | |||
the signature input (Section 2.3). | ||||
3. Serialize the component identifiers of the covered components, | 3. Serialize the component identifiers of the covered components, | |||
including all parameters, as an ordered "inner-list" 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] 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], skipping parameters | |||
parameters that are not available or not used for this message | that are not available or not used for this message signature. | |||
signature. | ||||
6. The output contains the signature parameters component 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 | |||
component 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 inclusion in message fields such as the | facilitate this value's inclusion in message fields such as the | |||
"Signature-Input" field'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: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
("@target-uri" "@authority" "date" "cache-control" "x-empty-header" \ | ("@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 | |||
the signature parameters used for the current signature are included | (Section 4.3), but only the signature parameters used for a single | |||
in the entry. | signature are included in an entry. | |||
2.3.2. Method | 2.2.2. Method | |||
The "@method" component identifier refers to the HTTP method of a | The @method component identifier refers to the HTTP method of a | |||
request message. The component value of is canonicalized by taking | request message. The component value of is canonicalized by taking | |||
the value of the method as a string. Note that the method name is | the value of the method as a string. Note that the method name is | |||
case-sensitive as per [SEMANTICS] Section 9.1, and conventionally | case-sensitive as per [SEMANTICS], Section 9.1, and conventionally | |||
standardized method names are uppercase US-ASCII. If used, the | standardized method names are uppercase US-ASCII. If used, the | |||
"@method" component identifier MUST occur only once in the covered | @method component identifier MUST occur only once in the covered | |||
components. | components. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@method" value: | Would result in the following @method value: | |||
"@method": POST | "@method": POST | |||
If used in a response message, the "@method" component identifier | If used in a related-response, the @method component identifier | |||
refers to the associated component value of the request that | refers to the associated component value of the request that | |||
triggered the response message being signed. | triggered the response message being signed. | |||
2.3.3. Target URI | 2.2.3. Target URI | |||
The "@target-uri" component identifier refers to the target URI of a | The @target-uri component identifier refers to the target URI of a | |||
request message. The component value is the full absolute target URI | request message. The component value is the full absolute target URI | |||
of the request, potentially assembled from all available parts | of the request, potentially assembled from all available parts | |||
including the authority and request target as described in | including the authority and request target as described in | |||
[SEMANTICS] Section 7.1. If used, the "@target-uri" component | [SEMANTICS], Section 7.1. If used, the @target-uri component | |||
identifier MUST occur only once in the covered components. | identifier MUST occur only once in the covered components. | |||
For example, the following message sent over HTTPS: | For example, the following message sent over HTTPS: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@target-uri" value: | Would result in the following @target-uri value: | |||
"@target-uri": https://www.example.com/path?param=value | "@target-uri": https://www.example.com/path?param=value | |||
If used in a response message, the "@target-uri" component identifier | If used in a related-response, the @target-uri component identifier | |||
refers to the associated component value of the request that | refers to the associated component value of the request that | |||
triggered the response message being signed. | triggered the response message being signed. | |||
2.3.4. Authority | 2.2.4. Authority | |||
The "@authority" component identifier refers to the authority | The @authority component identifier refers to the authority component | |||
component of the target URI of the HTTP request message, as defined | of the target URI of the HTTP request message, as defined in | |||
in [SEMANTICS] Section 7.2. In HTTP 1.1, this is usually conveyed | [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 Host header, while in HTTP 2 and HTTP 3 it is conveyed | |||
using the ":authority" pseudo-header. The value is the fully- | using the :authority pseudo-header. The value is the fully-qualified | |||
qualified authority component of the request, comprised of the host | authority component of the request, comprised of the host and, | |||
and, optionally, port of the request target, as a string. The | optionally, port of the request target, as a string. The component | |||
component value MUST be normalized according to the rules in | value MUST be normalized according to the rules in [SEMANTICS], | |||
[SEMANTICS] Section 4.2.3. Namely, the host name is normalized to | Section 4.2.3. Namely, the host name is normalized to lowercase and | |||
lowercase and the default port is omitted. If used, the "@authority" | the default port is omitted. If used, the @authority component | |||
component identifier MUST occur only once in the covered components. | identifier MUST occur only once in the covered components. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@authority" component value: | Would result in the following @authority component value: | |||
"@authority": www.example.com | "@authority": www.example.com | |||
If used in a response message, the "@authority" component identifier | If used in a related-response, the @authority component identifier | |||
refers to the associated component value of the request that | refers to the associated component value of the request that | |||
triggered the response message being signed. | triggered the response message being signed. | |||
2.3.5. Scheme | 2.2.5. Scheme | |||
The "@scheme" component identifier refers to the scheme of the target | The @scheme component identifier refers to the scheme of the target | |||
URL of the HTTP request message. The component value is the scheme | 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 | as a string as defined in [SEMANTICS], Section 4.2. While the scheme | |||
itself is case-insensitive, it MUST be normalized to lowercase for | itself is case-insensitive, it MUST be normalized to lowercase for | |||
inclusion in the signature input string. If used, the "@scheme" | inclusion in the signature input string. If used, the @scheme | |||
component identifier MUST occur only once in the covered components. | component identifier MUST occur only once in the covered components. | |||
For example, the following request message requested over plain HTTP: | For example, the following request message requested over plain HTTP: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@scheme" value: | Would result in the following @scheme value: | |||
"@scheme": http | "@scheme": http | |||
If used in a response message, the "@scheme" component identifier | If used in a related-response, the @scheme component identifier | |||
refers to the associated component value of the request that | refers to the associated component value of the request that | |||
triggered the response message being signed. | triggered the response message being signed. | |||
2.3.6. Request Target | 2.2.6. Request Target | |||
The "@request-target" component identifier refers to the full request | The @request-target component identifier refers to the full request | |||
target of the HTTP request message, as defined in [SEMANTICS] | target of the HTTP request message, as defined in [SEMANTICS], | |||
Section 7.1. The component value of the request target can take | Section 7.1. The component value of the request target can take | |||
different forms, depending on the type of request, as described | different forms, depending on the type of request, as described | |||
below. If used, the "@request-target" component identifier MUST | below. If used, the @request-target component identifier MUST occur | |||
occur only once in the covered components. | only once in the covered components. | |||
For HTTP 1.1, the component value is equivalent to the request target | For HTTP 1.1, the component value is equivalent to the request target | |||
portion of the request line. However, this value is more difficult | portion of the request line. However, this value is more difficult | |||
to reliably construct in other versions of HTTP. Therefore, it is | to reliably construct in other versions of HTTP. Therefore, it is | |||
NOT RECOMMENDED that this identifier be used when versions of HTTP | NOT RECOMMENDED that this identifier be used when versions of HTTP | |||
other than 1.1 might be in use. | other than 1.1 might be in use. | |||
The origin form value is combination of the absolute path and query | The origin form value is combination of the absolute path and query | |||
components of the request URL. For example, the following request | components of the request URL. For example, the following request | |||
message: | message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@request-target" component value: | Would result in the following @request-target component value: | |||
"@request-target": /path?param=value | "@request-target": /path?param=value | |||
The following request to an HTTP proxy with the absolute-form value, | The following request to an HTTP proxy with the absolute-form value, | |||
containing the fully qualified target URI: | containing the fully qualified target URI: | |||
GET https://www.example.com/path?param=value HTTP/1.1 | GET https://www.example.com/path?param=value HTTP/1.1 | |||
Would result in the following "@request-target" component value: | Would result in the following @request-target component value: | |||
"@request-target": https://www.example.com/path?param=value | "@request-target": https://www.example.com/path?param=value | |||
The following CONNECT request with an authority-form value, | The following CONNECT request with an authority-form value, | |||
containing the host and port of the target: | containing the host and port of the target: | |||
CONNECT www.example.com:80 HTTP/1.1 | CONNECT www.example.com:80 HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@request-target" component value: | Would result in the following @request-target component value: | |||
"@request-target": www.example.com:80 | "@request-target": www.example.com:80 | |||
The following OPTIONS request message with the asterisk-form value, | The following OPTIONS request message with the asterisk-form value, | |||
containing a single asterisk "*" character: | containing a single asterisk * character: | |||
OPTIONS * HTTP/1.1 | OPTIONS * HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@request-target" component value: | Would result in the following @request-target component value: | |||
"@request-target": * | "@request-target": * | |||
If used in a response message, the "@request-target" component | ||||
If used in a related-response, the @request-target component | ||||
identifier refers to the associated component value of the request | identifier refers to the associated component value of the request | |||
that triggered the response message being signed. | that triggered the response message being signed. | |||
2.3.7. Path | 2.2.7. Path | |||
The "@path" component identifier refers to the target path of the | The @path component identifier refers to the target path of the HTTP | |||
HTTP request message. The component value is the absolute path of | request message. The component value is the absolute path of the | |||
the request target defined by [RFC3986], with no query component and | request target defined by [RFC3986], with no query component and no | |||
no trailing "?" character. The value is normalized according to the | trailing ? character. The value is normalized according to the rules | |||
rules in [SEMANTICS] Section 4.2.3. Namely, an empty path string is | in [SEMANTICS], Section 4.2.3. Namely, an empty path string is | |||
normalized as a single slash "/" character, and path components are | normalized as a single slash / character, and path components are | |||
represented by their values after decoding any percent-encoded | represented by their values after decoding any percent-encoded | |||
octets. If used, the "@path" component identifier MUST occur only | octets. If used, the @path component identifier MUST occur only once | |||
once in the covered components. | in the covered components. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value HTTP/1.1 | POST /path?param=value HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@path" value: | Would result in the following @path value: | |||
"@path": /path | "@path": /path | |||
If used in a response message, the "@path" identifier refers to the | If used in a related-response, the @path identifier refers to the | |||
associated component value of the request that triggered the response | associated component value of the request that triggered the response | |||
message being signed. | message being signed. | |||
2.3.8. Query | 2.2.8. Query | |||
The "@query" component identifier refers to the query component of | The @query component identifier refers to the query component of the | |||
the HTTP request message. The component value is the entire | HTTP request message. The component value is the entire normalized | |||
normalized query string defined by [RFC3986], including the leading | query string defined by [RFC3986], including the leading ? character. | |||
"?" character. The value is normalized according to the rules in | The value is normalized according to the rules in [SEMANTICS], | |||
[SEMANTICS] Section 4.2.3. Namely, percent-encoded octets are | Section 4.2.3. Namely, percent-encoded octets are decoded. If used, | |||
decoded. If used, the "@query" component identifier MUST occur only | the @query component identifier MUST occur only once in the covered | |||
once in the covered components. | components. | |||
For example, the following request message: | For example, the following request message: | |||
POST /path?param=value&foo=bar&baz=batman HTTP/1.1 | POST /path?param=value&foo=bar&baz=batman HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@query" value: | Would result in the following @query value: | |||
"@query": ?param=value&foo=bar&baz=batman | "@query": ?param=value&foo=bar&baz=batman | |||
The following request message: | The following request message: | |||
POST /path?queryString HTTP/1.1 | POST /path?queryString HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Would result in the following "@query" value: | Would result in the following @query value: | |||
"@query": ?queryString | "@query": ?queryString | |||
If used in a response message, the "@query" component identifier | If used in a related-response, the @query component identifier refers | |||
refers to the associated component value of the request that | to the associated component value of the request that triggered the | |||
triggered the response message being signed. | response message being signed. | |||
2.3.9. Query Parameters | 2.2.9. Query Parameters | |||
If a request target URI uses HTML form parameters in the query string | If a request target URI uses HTML form parameters in the query string | |||
as defined in [HTMLURL] Section 5, the "@query-params" component | as defined in HTMLURL, Section 5 [HTMLURL], the @query-params | |||
identifier allows addressing of individual query parameters. The | component identifier allows addressing of individual query | |||
query parameters MUST be parsed according to [HTMLURL] Section 5.1, | parameters. The query parameters MUST be parsed according to | |||
resulting in a list of ("nameString", "valueString") tuples. The | HTMLURL, Section 5.1 [HTMLURL], resulting in a list of (nameString, | |||
REQUIRED "name" parameter of each input identifier contains the | valueString) tuples. The REQUIRED name parameter of each input | |||
"nameString" of a single query parameter. Several different named | identifier contains the nameString of a single query parameter as an | |||
query parameters MAY be included in the covered components. Single | sf-string value. Several different named query parameters MAY be | |||
named parameters MAY occur in any order in the covered components. | 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 | The component value of a single named parameter is the the | |||
"valueString" of the named query parameter defined by [HTMLURL] | valueString of the named query parameter defined by HTMLURL, | |||
Section 5.1, which is the value after percent-encoded octets are | Section 5.1 [HTMLURL], which is the value after percent-encoded | |||
decoded. Note that this value does not include any leading "?" | octets are decoded. Note that this value does not include any | |||
characters, equals sign "=", or separating "&" characters. Named | leading ? characters, equals sign =, or separating & characters. | |||
query parameters with an empty "valueString" are included with an | Named query parameters with an empty valueString are included with an | |||
empty string as the component value. | empty string as the component value. | |||
If a parameter name occurs multiple times in a request, all parameter | If a parameter name occurs multiple times in a request, all parameter | |||
values of that name MUST be included in separate signature input | values of that name MUST be included in separate signature input | |||
lines in the order in which the parameters occur in the target URI. | lines in the order in which the parameters occur in the target URI. | |||
For example for the following request: | For example for the following request: | |||
POST /path?param=value&foo=bar&baz=batman&qux= HTTP/1.1 | POST /path?param=value&foo=bar&baz=batman&qux= HTTP/1.1 | |||
Host: www.example.com | Host: www.example.com | |||
Indicating the "baz", "qux" and "param" named query parameters in | Indicating the baz, qux and param named query parameters in would | |||
would result in the following "@query-param" value: | result in the following @query-param value: | |||
"@query-params";name="baz": batman | "@query-params";name="baz": batman | |||
"@query-params";name="qux": | "@query-params";name="qux": | |||
"@query-params";name="param": value | "@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 | If used in a related-response, the @query-params component identifier | |||
refers to the associated component value of the request that | ||||
triggered the response message being signed. | ||||
The "@status" component identifier refers to the three-digit numeric | 2.2.10. Status Code | |||
HTTP status code of a response message as defined in [SEMANTICS] | ||||
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 | Section 15. The component value is the serialized three-digit | |||
integer of the HTTP response code, with no descriptive text. If | integer of the HTTP response code, with no descriptive text. If | |||
used, the "@status" component identifier MUST occur only once in the | used, the @status component identifier MUST occur only once in the | |||
covered components. | covered components. | |||
For example, the following response message: | For example, the following response message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Date: Fri, 26 Mar 2010 00:05:00 GMT | Date: Fri, 26 Mar 2010 00:05:00 GMT | |||
Would result in the following "@status" value: | Would result in the following @status value: | |||
"@status": 200 | "@status": 200 | |||
The "@status" component identifier MUST NOT be used in a request | The @status component identifier MUST NOT be used in a request | |||
message. | message. | |||
2.3.11. Request-Response Signature Binding | 2.2.11. Request-Response Signature Binding | |||
When a signed request message results in a signed response message, | When a signed request message results in a signed response message, | |||
the "@request-response" component identifier can be used to | the @request-response component identifier can be used to | |||
cryptographically link the request and the response to each other by | cryptographically link the request and the response to each other by | |||
including the identified request signature value in the response's | including the identified request signature value in the response's | |||
signature input without copying the value of the request's signature | signature input without copying the value of the request's signature | |||
to the response directly. This component identifier has a single | to the response directly. This component identifier has a single | |||
REQUIRED parameter: | REQUIRED parameter: | |||
"key" Identifies which signature from the response to sign. | key Identifies which signature from the response to sign. | |||
The component value is the "sf-binary" representation of the | The component value is the sf-binary representation of the signature | |||
signature value of the referenced request identified by the "key" | value of the referenced request identified by the key parameter. | |||
parameter. | ||||
For example, when serving this signed request: | For example, when serving this signed request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=value&pet=dog HTTP/1.1 | POST /foo?param=value&pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
skipping to change at page 22, line 33 ¶ | skipping to change at page 22, line 50 ¶ | |||
This would result in the following unsigned response message: | This would result in the following unsigned response message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 62 | Content-Length: 62 | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
The server signs the response with its own key and includes the | The server signs the response with its own key and includes the | |||
signature of "sig1" from the request in the covered components of the | signature of sig1 from the request in the covered components of the | |||
response. The signature input string for this example is: | response. The signature input string for this example is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"content-type": application/json | "content-type": application/json | |||
"content-length": 62 | "content-length": 62 | |||
"@status": 200 | "@status": 200 | |||
"@request-response";key="sig1": :KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu\ | "@request-response";key="sig1": :KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu\ | |||
5rif3g7ckTbbX7C4Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79\ | 5rif3g7ckTbbX7C4Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79\ | |||
gBeqvHNUO4bhI27p4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7\ | gBeqvHNUO4bhI27p4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7\ | |||
skipping to change at page 23, line 21 ¶ | skipping to change at page 23, line 38 ¶ | |||
Signature-Input: sig1=("content-type" "content-length" "@status" \ | Signature-Input: sig1=("content-type" "content-length" "@status" \ | |||
"@request-response";key="sig1");created=1618884475\ | "@request-response";key="sig1");created=1618884475\ | |||
;keyid="test-key-ecc-p256" | ;keyid="test-key-ecc-p256" | |||
Signature: sig1=:crVqK54rxvdx0j7qnt2RL1oQSf+o21S/6Uk2hyFpoIfOT0q+Hv\ | Signature: sig1=:crVqK54rxvdx0j7qnt2RL1oQSf+o21S/6Uk2hyFpoIfOT0q+Hv\ | |||
msYAXUXzo0Wn8NFWh/OjWQOXHAQdVnTk87Pw==: | msYAXUXzo0Wn8NFWh/OjWQOXHAQdVnTk87Pw==: | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
Since the request's signature value itself is not repeated in the | Since the request's signature value itself is not repeated in the | |||
response, the requester MUST keep the original signature value around | response, the requester MUST keep the original signature value around | |||
long enough to validate the signature of the response. | long enough to validate the signature of the response that uses this | |||
component identifier. | ||||
The "@request-response" component identifier MUST NOT be used in a | The @request-response component identifier MUST NOT be used in a | |||
request message. | request message. | |||
2.4. Creating the Signature Input String | 2.3. Creating the Signature Input String | |||
The signature input is a US-ASCII string containing the canonicalized | The signature input is a US-ASCII string containing the canonicalized | |||
HTTP message components covered by the signature. To create the | HTTP message components covered by the signature. The input to the | |||
signature input string, the signer or verifier concatenates together | signature creation algorithm is the list of covered component | |||
entries for each identifier in the signature's covered components | identifiers and their associated values, along with an additional | |||
(including their parameters) using the following algorithm: | signature parameters. To create the signature input string, the | |||
signer or verifier concatenates together entries for each identifier | ||||
in the signature's covered components (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 message component item in the covered components set (in | 2. For each message component item in the covered components set (in | |||
order): | order): | |||
1. Append the component identifier for the covered component | 1. Append the component identifier for the covered component | |||
serialized according to the "component-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 component's canonicalized component value, | 4. Append the covered component's canonicalized component value, | |||
as defined by the HTTP message component type. (Section 2.1 | as defined by the HTTP message component type. (Section 2.1 | |||
and Section 2.3) | and Section 2.2) | |||
5. Append a single newline ""\\n"" | 5. Append a single newline \n | |||
3. Append the signature parameters component (Section 2.3.1) as | 3. Append the signature parameters component (Section 2.2.1) as | |||
follows: | follows: | |||
1. Append the component identifier for the signature parameters | 1. Append the component identifier for the signature parameters | |||
serialized according to the "component-identifier" rule, i.e. | serialized according to the component-identifier rule, i.e. | |||
""@signature-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 component | 4. Append the signature parameters' canonicalized component | |||
value as defined in Section 2.3.1 | value as defined in Section 2.2.1 | |||
4. Return the output string. | 4. Return the output string. | |||
If covered components reference a component identifier that cannot be | If covered components reference a component identifier that cannot be | |||
resolved to a component value in the message, the implementation MUST | resolved to a component value in the message, the implementation MUST | |||
produce an error. 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 component | * The signer or verifier does not understand the component | |||
identifier. | identifier. | |||
* The component identifier identifies a 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 component identifier is a Dictionary member identifier that | * The component identifier indicates that a structured field | |||
serialization is used, but the field in question is known to not | ||||
be a structured field or the type of structured field is not known | ||||
to the verifier. | ||||
* The component identifier is a dictionary member identifier that | ||||
references a field that is not present in the message, is not a | references a field that is not present in the message, is not a | |||
Dictionary Structured Field, or whose value is malformed. | Dictionary Structured Field, or whose value is malformed. | |||
* The component identifier is a Dictionary member identifier that | * The component identifier is a dictionary member identifier or a | |||
references a member that is not present in the field value, or | named query parameter identifier that references a member that is | |||
whose value is malformed. E.g., the identifier is | not present in the component value, or whose value is malformed. | |||
""x-dictionary";key="c"" and the value of the "x-dictionary" | E.g., the identifier is "x-dictionary";key="c" and the value of | |||
header field is "a=1, b=2" | the x-dictionary 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- | The covered components consist of the @method, @path, and @authority | |||
Control", "X-Empty-Header", "X-Example" HTTP headers, in order. The | specialty component identifiers followed by the Cache-Control, X- | |||
signature parameters consist of a creation timestamp is "1618884475" | Empty-Header, X-Example HTTP headers, in order. The signature | |||
and the key identifier is "test-key-rsa-pss". The signature input | parameters consist of a creation timestamp is 1618884475 and the key | |||
string for this message with these parameters is: | identifier is test-key-rsa-pss. The signature input string for this | |||
message with these parameters is: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@method": GET | "@method": GET | |||
"@path": /foo | "@path": /foo | |||
"@authority": example.org | "@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": ("@method" "@path" "@authority" \ | "@signature-params": ("@method" "@path" "@authority" \ | |||
skipping to change at page 25, line 37 ¶ | skipping to change at page 26, line 17 ¶ | |||
An HTTP Message Signature is a signature over a string generated from | An HTTP Message Signature is a signature over a string generated from | |||
a subset of the components of an HTTP message in addition to metadata | a subset of the components of an HTTP message in addition to metadata | |||
about the signature itself. When successfully verified against an | about the signature itself. When successfully verified against an | |||
HTTP message, an HTTP Message Signature provides cryptographic proof | HTTP message, an HTTP Message Signature provides cryptographic proof | |||
that the message is semantically equivalent to the message for which | that the message is semantically equivalent to the message for which | |||
the signature was generated, with respect to the subset of message | the signature was generated, with respect to the subset of message | |||
components that was signed. | components that was signed. | |||
3.1. Creating a Signature | 3.1. Creating a Signature | |||
Creation of an HTTP message signature is a process that takes as its | ||||
input the message and the requirements for the application. The | ||||
output is a signature value and set of signature parameters that can | ||||
be applied to the message. | ||||
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. The | |||
expiration is a hint to the verifier, expressing the time at | ||||
which the signer is no longer willing to vouch for the safety of | ||||
the signature. | ||||
4. The signer creates an ordered set of component identifiers | 4. The signer creates an ordered set of component identifiers | |||
representing the message components to be covered by the | representing the message components to be covered by the | |||
signature, and attaches signature metadata parameters to this | signature, and attaches signature metadata parameters to this | |||
set. The serialized value of this is later used as the value of | set. The serialized value of this is later used as the value of | |||
the "Signature-Input" field as described in Section 4.1. | the Signature-Input field as described in Section 4.1. | |||
* Once an order of covered components is chosen, the order MUST | * Once an order of covered components is chosen, the order MUST | |||
NOT change for the life of the signature. | NOT change for the life of the signature. | |||
* Each covered component identifier MUST be either an HTTP field | * Each covered component identifier MUST be either an HTTP field | |||
in the message Section 2.1 or a specialty component identifier | in the message Section 2.1 or a specialty component identifier | |||
listed in Section 2.3 or its associated registry. | listed in Section 2.2 or its associated registry. | |||
* Signers of a request SHOULD include some or all of the message | * Signers of a request SHOULD include some or all of the message | |||
control data in the covered components, such as the "@method", | control data in the covered components, such as the @method, | |||
"@authority", "@target-uri", or some combination thereof. | @authority, @target-uri, or some combination thereof. | |||
* Signers SHOULD include the "created" signature metadata | * Signers SHOULD include the created signature metadata | |||
parameter to indicate when the signature was created. | parameter to indicate when the signature was created. | |||
* The "@signature-params" specialty component identifier is not | * The @signature-params specialty component identifier is not | |||
explicitly listed in the list of covered component | explicitly listed in the list of covered component | |||
identifiers, because it is required to always be present as | identifiers, because it is required to always be present as | |||
the last line in the signature input. This ensures that a | the last line in the signature input. This ensures that a | |||
signature always covers its own metadata. | signature always covers its own metadata. | |||
* Further guidance on what to include in this set and in what | * Further guidance on what to include in this set and in what | |||
order is out of scope for this document. | order is out of scope for this document. | |||
5. The signer creates the signature input string based on these | 5. The signer creates the signature input string based on these | |||
signature parameters. (Section 2.4) | signature parameters. (Section 2.3) | |||
6. The signer signs the signature input with the chosen signing | 6. The signer uses the HTTP_SIGN function to sign the signature | |||
algorithm using the key material chosen by the signer. Several | input with the chosen signing algorithm using the key material | |||
signing algorithms are defined in in Section 3.3. | chosen by the signer. The HTTP_SIGN primitive and several | |||
concrete 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 | |||
field as defined in Section 4.2. | field as defined in Section 4.2. | |||
For example, given the HTTP message and signature parameters in the | For example, given the HTTP message and signature parameters in the | |||
example in Section 2.4, the example signature input string when | example in Section 2.3, the example signature input string is signed | |||
signed with the "test-key-rsa-pss" key in Appendix B.1.2 gives the | with the test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS | |||
following message signature output value, encoded in Base64: | algorithm described in Section 3.3.1, giving the following message | |||
signature output value, encoded in Base64: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1RSHi+oEF1FuX6O29\ | P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1RSHi+oEF1FuX6O29\ | |||
d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC87qmSQjvu1CFyFuWSj\ | d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC87qmSQjvu1CFyFuWSj\ | |||
dGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gyarxAiWI97mPXU+OVM64\ | dGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gyarxAiWI97mPXU+OVM64\ | |||
+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix\ | +HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix\ | |||
5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3r5S9IXf2fYJK+eyW4AiG\ | 5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3r5S9IXf2fYJK+eyW4AiG\ | |||
VMvMcOg== | 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 | Verification of an HTTP message signature is a process that takes as | |||
parameters in concert with each other. | its input the message (including Signature and Signature-Input | |||
fields) and the requirements for the application. The output of the | ||||
verification is either a positive verification or an error. | ||||
In order to verify a signature, a verifier MUST follow the following | In order to verify a signature, a verifier MUST follow the following | |||
algorithm: | algorithm: | |||
1. Parse the "Signature" and "Signature-Input" fields and extract | 1. Parse the Signature and Signature-Input fields as described in | |||
the signatures to be verified. | Section 4.1 and Section 4.2, and extract 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 message. If an | which signature should be processed for this message based on | |||
the policy and configuration of the verifier. If an | ||||
applicable 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" field to get the | 2. Parse the values of the chosen Signature-Input field as a | |||
parameters for the signature to be verified. | parameterized structured field inner list item (inner-list) to | |||
get the signature parameters for the signature to be verified. | ||||
3. Parse the value of the corresponding "Signature" field to get the | 3. Parse the value of the corresponding Signature field to get the | |||
byte array value of the signature to be verified. | byte array value of the signature to be verified. | |||
4. Examine the signature parameters to confirm that the signature | 4. Examine the signature parameters to confirm that the signature | |||
meets the requirements described in this document, as well as any | meets the requirements described in this document, as well as any | |||
additional requirements defined by the application such as which | additional requirements defined by the application such as which | |||
message components are required to be covered by the signature. | message components are required to be covered by the signature. | |||
(Section 3.2.1) | (Section 3.2.1) | |||
5. Determine the verification key material for this signature. If | 5. Determine the verification key material for this signature. If | |||
the key material is known through external means such as static | the key material is known through external means such as static | |||
skipping to change at page 28, line 31 ¶ | skipping to change at page 29, line 26 ¶ | |||
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.3. The value of the @signature-params input is the | |||
value of the "SignatureInput" field for this signature serialized | value of the Signature-Input field for this signature serialized | |||
according to the rules described in Section 2.3.1, not including | according to the rules described in Section 2.2.1, not including | |||
the signature's label from the "Signature-Input" field. | the signature's label from the Signature-Input field. | |||
8. If the key material is appropriate for the algorithm, apply the | 8. If the key material is appropriate for the algorithm, apply the | |||
verification algorithm to the signature, recalculated signature | appropriate HTTP_VERIFY cryptographic verification algorithm to | |||
input, signature parameters, key material, and algorithm. | the signature, recalculated signature input, key material, | |||
Several algorithms are defined in Section 3.3. | signature value. The HTTP_VERIFY primitive and several concrete | |||
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 cryptographic verification function. | |||
If any of the above steps fail or produce an error, the signature | If any of the above steps fail or produce an error, the signature | |||
validation fails. | validation fails. | |||
For example, verifying the signature with the key sig1 of the | ||||
following message with the test-key-rsa-pss key in Appendix B.1.2 and | ||||
the RSA PSS algorithm described in Section 3.3.1: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
GET /foo HTTP/1.1 | ||||
Host: example.org | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
X-Example: Example header | ||||
with some whitespace. | ||||
X-Empty-Header: | ||||
Cache-Control: max-age=60 | ||||
Cache-Control: must-revalidate | ||||
Signature-Input: sig1=("@method" "@path" "@authority" \ | ||||
"cache-control" "x-empty-header" "x-example");created=1618884475\ | ||||
;keyid="test-key-rsa-pss" | ||||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1\ | ||||
RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC8\ | ||||
7qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gya\ | ||||
rxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9\ | ||||
eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3\ | ||||
r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | ||||
With the additional requirements that at least the method, path, | ||||
authority, and cache-control be signed, and that the signature | ||||
creation timestamp is recent enough at the time of verification, the | ||||
verification passes. | ||||
3.2.1. Enforcing Application Requirements | 3.2.1. Enforcing Application Requirements | |||
The verification requirements specified in this document are intended | The verification requirements specified in this document are intended | |||
as a baseline set of restrictions that are generally applicable to | as a baseline set of restrictions that are generally applicable to | |||
all use cases. Applications using HTTP Message Signatures MAY impose | all use cases. Applications using HTTP Message Signatures MAY impose | |||
requirements above and beyond those specified by this document, as | requirements above and beyond those specified by this document, as | |||
appropriate for their use case. | appropriate for their use case. | |||
Some non-normative examples of additional requirements an application | Some non-normative examples of additional requirements an application | |||
might define are: | might define are: | |||
* Requiring a specific set of header fields to be signed (e.g., | * Requiring a specific set of header fields to be signed (e.g., | |||
"Authorization", "Digest"). | Authorization, Digest). | |||
* Enforcing a maximum signature age. | * Enforcing a maximum signature age from the time of the created | |||
time stamp. | ||||
* Prohibition of signature metadata parameters, such as runtime | * Rejection of signatures past the expiration time in the expires | |||
algorithm signaling with the "alg" parameter. | time stamp. Note that the expiration time is a hint from the | |||
signer and that a verifier can always reject a signature ahead of | ||||
its expiration time. | ||||
* Prohibition of certain signature metadata parameters, such as | ||||
runtime algorithm signaling with the alg parameter when the | ||||
algorithm is determined from the key information. | ||||
* Ensuring successful dereferencing of the keyid parameter to valid | ||||
and appropriate key material. | ||||
* Prohibiting the use of certain algorithms, or mandating the use of | * Prohibiting the use of certain algorithms, or mandating the use of | |||
a specific algorithm. | a specific algorithm. | |||
* Requiring keys to be of a certain size (e.g., 2048 bits vs. 1024 | * Requiring keys to be of a certain size (e.g., 2048 bits vs. 1024 | |||
bits). | bits). | |||
* Enforcing uniqueness of 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. | |||
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.3. | |||
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 signature output as a set of byte values | (Ks), and outputs the signature output as a set of byte values (S): | |||
("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 | |||
the verification key material ("Kv"), and the presented signature to | verification key material (Kv), and the presented signature to be | |||
be verified as a set of byte values ("S") and outputs the | verified as a set of byte values (S) and outputs the verification | |||
verification result ("V") as a boolean: | 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.1, by reference to the key material, or | defined in Section 2.2.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) | |||
("K") and the signature input string ("M") (Section 2.4). The mask | and the signature input string (M) (Section 2.3). The mask | |||
generation function is "MGF1" as specified in [RFC8017] with a hash | generation function is MGF1 as specified in [RFC8017] with a hash | |||
function of SHA-512 [RFC6234]. The salt length ("sLen") is 64 bytes. | function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | |||
The hash function ("Hash") SHA-512 [RFC6234] is applied to the | The hash function (Hash) SHA-512 [RFC6234] is applied to the | |||
signature input string to create the digest content to which the | signature input string to create the digest content to which the | |||
digital signature is applied. The resulting signed content byte | digital signature is applied. The resulting signed content byte | |||
array ("S") is the HTTP message signature output used in Section 3.1. | array (S) is the HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the "RSASSA-PSS- | To verify using this algorithm, the verifier applies the RSASSA-PSS- | |||
VERIFY ((n, e), M, S)" function [RFC8017] using the public key | VERIFY ((n, e), M, S) function [RFC8017] using the public key portion | |||
portion of the verification key material ("(n, e)") and the signature | of the verification key material ((n, e)) and the signature input | |||
input string ("M") re-created as described in Section 3.2. The mask | string (M) re-created as described in Section 3.2. The mask | |||
generation function is "MGF1" as specified in [RFC8017] with a hash | generation function is MGF1 as specified in [RFC8017] with a hash | |||
function of SHA-512 [RFC6234]. The salt length ("sLen") is 64 bytes. | function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | |||
The hash function ("Hash") SHA-512 [RFC6234] is applied to the | The hash function (Hash) SHA-512 [RFC6234] is applied to the | |||
signature input string to create the digest content to which the | signature input string to create the digest content to which the | |||
verification function is applied. The verifier extracts the HTTP | verification function is applied. The verifier extracts the HTTP | |||
message signature to be verified ("S") as described in Section 3.2. | message signature to be verified (S) as described in Section 3.2. | |||
The results of the verification function are compared to the http | The results of the verification function are compared to the http | |||
message signature to determine if the signature presented is valid. | message signature to determine if the signature presented is valid. | |||
Use of this algorithm can be indicated at runtime using the rsa-pss- | ||||
sha512 value for the alg signature parameter. | ||||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 | 3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 | |||
To sign using this algorithm, the signer applies the "RSASSA- | To sign using this algorithm, the signer applies the RSASSA- | |||
PKCS1-V1_5-SIGN (K, M)" function [RFC8017] with the signer's private | PKCS1-V1_5-SIGN (K, M) function [RFC8017] with the signer's private | |||
signing key ("K") and the signature input string ("M") (Section 2.4). | signing key (K) and the signature input string (M) (Section 2.3). | |||
The hash SHA-256 [RFC6234] is applied to the signature input string | The hash SHA-256 [RFC6234] is applied to the signature input string | |||
to create the digest content to which the digital signature is | to create the digest content to which the digital signature is | |||
applied. The resulting signed content byte array ("S") is the HTTP | applied. The resulting signed content byte array (S) is the HTTP | |||
message signature output used in Section 3.1. | message signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the "RSASSA- | To verify using this algorithm, the verifier applies the RSASSA- | |||
PKCS1-V1_5-VERIFY ((n, e), M, S)" function [RFC8017] using the public | PKCS1-V1_5-VERIFY ((n, e), M, S) function [RFC8017] using the public | |||
key portion of the verification key material ("(n, e)") and the | key portion of the verification key material ((n, e)) and the | |||
signature input string ("M") re-created as described in Section 3.2. | signature input string (M) re-created as described in Section 3.2. | |||
The hash function SHA-256 [RFC6234] is applied to the signature input | The hash function SHA-256 [RFC6234] is applied to the signature input | |||
string to create the digest content to which the verification | string to create the digest content to which the verification | |||
function is applied. The verifier extracts the HTTP message | function is applied. The verifier extracts the HTTP message | |||
signature to be verified ("S") as described in Section 3.2. The | signature to be verified (S) as described in Section 3.2. The | |||
results of the verification function are compared to the http message | results of the verification function are compared to the http message | |||
signature to determine if the signature presented is valid. | signature to determine if the signature presented is valid. | |||
Use of this algorithm can be indicated at runtime using the rsa- | ||||
v1_5-sha256 value for the alg signature parameter. | ||||
3.3.3. HMAC using SHA-256 | 3.3.3. HMAC using SHA-256 | |||
To sign and verify using this algorithm, the signer applies the | To sign and verify using this algorithm, the signer applies the HMAC | |||
"HMAC" function [RFC2104] with the shared signing key ("K") and the | function [RFC2104] with the shared signing key (K) and the signature | |||
signature input string ("text") (Section 2.4). The hash function | input string (text) (Section 2.3). The hash function SHA-256 | |||
SHA-256 [RFC6234] is applied to the signature input string to create | [RFC6234] is applied to the signature input string to create the | |||
the digest content to which the HMAC is applied, giving the signature | digest content to which the HMAC is applied, giving the signature | |||
result. | result. | |||
For signing, the resulting value is the HTTP message signature output | For signing, the resulting value is the HTTP message signature output | |||
used in Section 3.1. | used in Section 3.1. | |||
For verification, the verifier extracts the HTTP message signature to | For verification, the verifier extracts the HTTP message signature to | |||
be verified ("S") as described in Section 3.2. The output of the | be verified (S) as described in Section 3.2. The output of the HMAC | |||
HMAC function is compared to the value of the HTTP message signature, | function is compared to the value of the HTTP message signature, and | |||
and the results of the comparison determine the validity of the | the results of the comparison determine the validity of the signature | |||
signature presented. | presented. | |||
Use of this algorithm can be indicated at runtime using the hmac- | ||||
sha256 value for the alg signature parameter. | ||||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 | 3.3.4. ECDSA using curve P-256 DSS and SHA-256 | |||
To sign using this algorithm, the signer applies the "ECDSA" | To sign using this algorithm, the signer applies the ECDSA algorithm | |||
algorithm [FIPS186-4] using curve P-256 with the signer's private | [FIPS186-4] using curve P-256 with the signer's private signing key | |||
signing key and the signature input string (Section 2.4). The hash | and the signature input string (Section 2.3). The hash SHA-256 | |||
SHA-256 [RFC6234] is applied to the signature input string to create | [RFC6234] is applied to the signature input string to create the | |||
the digest content to which the digital signature is applied. The | digest content to which the digital signature is applied. The | |||
resulting signed content byte array is the HTTP message signature | resulting signed content byte array is the HTTP message signature | |||
output used in Section 3.1. | output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the "ECDSA" | To verify using this algorithm, the verifier applies the ECDSA | |||
algorithm [FIPS186-4] using the public key portion of the | algorithm [FIPS186-4] using the public key portion of the | |||
verification key material and the signature input string re-created | verification key material and the signature input string re-created | |||
as described in Section 3.2. The hash function SHA-256 [RFC6234] is | as described in Section 3.2. The hash function SHA-256 [RFC6234] is | |||
applied to the signature input string to create the digest content to | applied to the signature input string to create the digest content to | |||
which the verification function is applied. The verifier extracts | which the verification function is applied. The verifier extracts | |||
the HTTP message signature to be verified ("S") as described in | the HTTP message signature to be verified (S) as described in | |||
Section 3.2. The results of the verification function are compared | Section 3.2. The results of the verification function are compared | |||
to the http message signature to determine if the signature presented | to the http message signature to determine if the signature presented | |||
is valid. | is valid. | |||
Use of this algorithm can be indicated at runtime using the ecdsa- | ||||
p256-sha256 value for the alg signature parameter. | ||||
3.3.5. JSON Web Signature (JWS) algorithms | 3.3.5. JSON Web Signature (JWS) algorithms | |||
If the signing algorithm is a JOSE signing algorithm from the JSON | If the signing algorithm is a JOSE signing algorithm from the JSON | |||
Web Signature and Encryption Algorithms Registry established by | Web Signature and Encryption Algorithms Registry established by | |||
[RFC7518], the JWS algorithm definition determines the signature and | [RFC7518], the JWS algorithm definition determines the signature and | |||
hashing algorithms to apply for both signing and verification. There | hashing algorithms to apply for both signing and verification. | |||
is no use of the explicit "alg" signature parameter when using JOSE | ||||
signing algorithms. | ||||
For both signing and verification, the HTTP messages signature input | For both signing and verification, the HTTP messages signature input | |||
string (Section 2.4) is used as the entire "JWS Signing Input". The | string (Section 2.3) is used as the entire "JWS Signing Input". The | |||
JOSE Header defined in [RFC7517] is not used, and the signature input | JOSE Header defined in [RFC7517] is not used, and the signature input | |||
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 | |||
with a JOSE Implementation Requirement of "Prohibited". | a JOSE Implementation Requirement of Prohibited. | |||
There is no use of the explicit alg signature parameter when using | ||||
JOSE signing algorithms, as they can be signaled using JSON Web Keys | ||||
or other mechanisms. | ||||
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 fields, both defined within | Signature-Input and Signature HTTP fields, both defined within this | |||
this specification. When attached to a message, an HTTP message | specification. When attached to a message, an HTTP message signature | |||
signature is identified by a label. This label MUST be unique within | is identified by a label. This label MUST be unique within a given | |||
a given HTTP message and MUST be used in both the "Signature-Input" | HTTP message and MUST be used in both the Signature-Input and | |||
and "Signature". The label is chosen by the signer, except where a | Signature. The label is chosen by the signer, except where a | |||
specific label is dictated by protocol negotiations. | specific label is dictated by protocol negotiations. | |||
An HTTP message signature MUST use both fields containing the same | An HTTP message signature MUST use both fields containing the same | |||
labels: the "Signature" HTTP field contains the signature value, | labels: the Signature HTTP field contains the signature value, while | |||
while the "Signature-Input" HTTP field identifies the covered | the Signature-Input HTTP field identifies the covered components and | |||
components and parameters that describe how the signature was | parameters that describe how the signature was generated. Each field | |||
generated. Each field contains labeled values and MAY contain | contains labeled values and MAY contain multiple labeled values, | |||
multiple labeled values, where the labels determine the correlation | where the labels determine the correlation between the Signature and | |||
between the "Signature" and "Signature-Input" fields. | Signature-Input fields. | |||
4.1. The 'Signature-Input' HTTP Field | 4.1. The 'Signature-Input' HTTP Field | |||
The "Signature-Input" HTTP field is a Dictionary Structured Field | The Signature-Input HTTP field is a Dictionary Structured Field | |||
[RFC8941] containing the metadata for one or more message signatures | [RFC8941] containing the metadata for one or more message signatures | |||
generated from components within the HTTP message. Each member | generated from components within the HTTP message. Each 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 components including all signature metadata | of the covered components including all signature metadata | |||
parameters, using the serialization process defined in Section 2.3.1. | parameters, using the serialization process defined in Section 2.2.1. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@method" "@target-uri" "host" "date" \ | 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" field value | To facilitate signature validation, the Signature-Input field value | |||
MUST contain the same serialized value used in generating the | MUST contain the same serialized value used in generating the | |||
signature input string's "@signature-params" value. | signature input string's @signature-params value. | |||
The signer MAY include the "Signature-Input" field as a trailer to | The signer MAY include the Signature-Input field as a trailer to | |||
facilitate signing a message after its content has been processed by | facilitate signing a message after its content has been processed by | |||
the signer. However, since intermediaries are allowed to drop | the signer. However, since intermediaries are allowed to drop | |||
trailers as per [SEMANTICS], it is RECOMMENDED that the "Signature- | trailers as per [SEMANTICS], it is RECOMMENDED that the Signature- | |||
Input" HTTP field be included only as a header to avoid signatures | Input HTTP field be included only as a header to avoid signatures | |||
being inadvertently stripped from a message. | being inadvertently stripped from a message. | |||
Multiple "Signature-Input" fields MAY be included in a single HTTP | Multiple Signature-Input fields MAY be included in a single HTTP | |||
message. The signature labels MUST be unique across all field | message. The signature labels MUST be unique across all field | |||
values. | values. | |||
4.2. The 'Signature' HTTP Field | 4.2. The 'Signature' HTTP Field | |||
The "Signature" HTTP field is a Dictionary Structured field [RFC8941] | The Signature HTTP field is a Dictionary Structured field [RFC8941] | |||
containing one or more message signatures generated from components | containing one or more message signatures generated from components | |||
within the HTTP message. Each member's name is a signature | 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 field 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 | |||
"Signature" HTTP field that does not have a corresponding member in | HTTP field that does not have a corresponding member in the HTTP | |||
the HTTP message's "Signature-Input" HTTP field MUST be ignored. | message's Signature-Input HTTP field MUST be ignored. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHz\ | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHz\ | |||
C87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8\ | C87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8\ | |||
gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58Rmp\ | gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58Rmp\ | |||
Z+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxA\ | Z+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxA\ | |||
BNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | BNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | |||
The signer MAY include the "Signature" field as a trailer to | The signer MAY include the Signature field as a trailer to facilitate | |||
facilitate signing a message after its content has been processed by | signing a message after its content has been processed by the signer. | |||
the signer. However, since intermediaries are allowed to drop | However, since intermediaries are allowed to drop trailers as per | |||
trailers as per [SEMANTICS], it is RECOMMENDED that the "Signature- | [SEMANTICS], it is RECOMMENDED that the Signature-Input HTTP field be | |||
Input" HTTP field be included only as a header to avoid signatures | included only as a header to avoid signatures being inadvertently | |||
being inadvertently stripped from a message. | stripped from a message. | |||
Multiple "Signature" fields MAY be included in a single HTTP message. | Multiple Signature fields MAY be included in a single HTTP message. | |||
The signature labels MUST be unique across all field values. | The signature labels MUST be unique across all field values. | |||
4.3. Multiple Signatures | 4.3. Multiple Signatures | |||
Multiple distinct signatures MAY be included in a single message. | Multiple distinct signatures MAY be included in a single message. | |||
Since "Signature-Input" and "Signature" are both defined as | Each distinct signature MUST have a unique label. Since Signature- | |||
Dictionary Structured fields, they can be used to include multiple | Input and Signature are both defined as Dictionary Structured fields, | |||
signatures within the same HTTP message by using distinct signature | they can be used to include multiple signatures within the same HTTP | |||
labels. For example, a signer may include multiple signatures | message by using distinct signature labels. These multiple | |||
signing the same message components with different keys or algorithms | signatures could be added all by the same signer or could come from | |||
to support verifiers with different capabilities, or a reverse proxy | several different signers. For example, a signer may include | |||
may include information about the client in fields when forwarding | multiple signatures signing the same message components with | |||
the request to a service host, including a signature over the | different keys or algorithms to support verifiers with different | |||
client's original signature values. | capabilities, or a reverse proxy may include information about the | |||
client in fields when forwarding 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. | proxy sets in addition to the examples in the previous sections. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Forwarded: for=192.0.2.123 | Forwarded: for=192.0.2.123 | |||
Signature-Input: sig1=("@method" "@path" "@authority" \ | 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" | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | 1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | |||
HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | |||
4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | 4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | |||
r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | |||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | |||
The client's request includes a signature value under the label | The client's request includes a signature value under the label sig1, | |||
"sig1", which the proxy signs in addition to the "Forwarded" header | which the proxy signs in addition to the Forwarded header defined in | |||
defined in [RFC7239]. Note that since the client's signature already | [RFC7239]. Note that since the client's signature already covers the | |||
covers the client's "Signature-Input" value for "sig1", this value is | client's Signature-Input value for sig1, this value is transitively | |||
transitively covered by the proxy's signature and need not be added | covered by the proxy's signature and need not be added explicitly. | |||
explicitly. This results in a signature input string of: | This results in a signature input string of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"signature";key="sig1": :P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP\ | "signature";key="sig1": :P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP\ | |||
4uKwxyJo1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9Gl\ | 4uKwxyJo1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9Gl\ | |||
yntiCiHzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyo\ | yntiCiHzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyo\ | |||
yZW84jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg\ | yZW84jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg\ | |||
53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | 53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | |||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | |||
"forwarded": for=192.0.2.123 | "forwarded": for=192.0.2.123 | |||
skipping to change at page 35, line 34 ¶ | skipping to change at page 38, line 4 ¶ | |||
And a signature output value of: | And a signature output value of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZxNiE+797dXK2cj\ | cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZxNiE+797dXK2cj\ | |||
PPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8keB8xzFt4inv3J3zP0\ | PPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8keB8xzFt4inv3J3zP0\ | |||
k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1XSg03iUa0sju1yj6rcKbMA\ | k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1XSg03iUa0sju1yj6rcKbMA\ | |||
BBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hmcDHkNaavcokmq+3EBDCQTzgwL\ | BBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hmcDHkNaavcokmq+3EBDCQTzgwL\ | |||
qfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+j8kSydKoFg6EbVuGbrQijth6I0dDX\ | qfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+j8kSydKoFg6EbVuGbrQijth6I0dDX\ | |||
2/HYcJg== | 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 | |||
original signature is included under the identifier "sig1", and the | original signature is included under the identifier sig1, and the | |||
reverse proxy's signature is included under the label "proxy_sig". | reverse proxy's signature is included under the label proxy_sig. The | |||
The proxy uses the key "test-key-rsa" to create its signature using | proxy uses the key test-key-rsa to create its signature using the | |||
the "rsa-v1_5-sha256" signature algorithm, while the client's | rsa-v1_5-sha256 signature algorithm, while the client's original | |||
original signature was made using the key id of "test-key-rsa-pss" | signature was made using the key id of test-key-rsa-pss and an RSA | |||
and an RSA PSS signature algorithm. | PSS signature algorithm. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Forwarded: for=192.0.2.123 | Forwarded: for=192.0.2.123 | |||
Signature-Input: sig1=("@method" "@path" "@authority" \ | 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" "forwarded")\ | 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=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | |||
skipping to change at page 36, line 37 ¶ | skipping to change at page 38, line 44 ¶ | |||
verified independently for the same message, based on the needs of | verified independently for the same message, based on the needs of | |||
the application. Since the proxy's signature covers the client | the application. Since the proxy's signature covers the client | |||
signature, the backend service fronted by the proxy can trust that | signature, the backend service fronted by the proxy can trust that | |||
the proxy has validated the incoming signature. | the proxy has validated the incoming signature. | |||
5. Requesting Signatures | 5. Requesting Signatures | |||
While a signer is free to attach a signature to a request or response | While a signer is free to attach a signature to a request or response | |||
without prompting, it is often desirable for a potential verifier to | without prompting, it is often desirable for a potential verifier to | |||
signal that it expects a signature from a potential signer using the | signal that it expects a signature from a potential signer using the | |||
"Accept-Signature" field. | Accept-Signature field. | |||
The message to which the requested signature is applied is known as | The message to which the requested signature is applied is known as | |||
the "target message". When the "Accept-Signature" field is sent in | the "target message". When the Accept-Signature field is sent in an | |||
an HTTP Request message, the field indicates that the client desires | HTTP Request message, the field indicates that the client desires the | |||
the server to sign the response using the identified parameters and | server to sign the response using the identified parameters and the | |||
the target message is the response to this request. All responses | target message is the response to this request. All responses from | |||
from resources that support such signature negotiation SHOULD either | resources that support such signature negotiation SHOULD either be | |||
be uncacheable or contain a "Vary" header field that lists "Accept- | uncacheable or contain a Vary header field that lists Accept- | |||
Signature", in order to prevent a cache from returning a response | Signature, in order to prevent a cache from returning a response with | |||
with a signature intended for a different request. | a signature intended for a different request. | |||
When the "Accept-Signature" field is used in an HTTP Response | When the Accept-Signature field is used in an HTTP Response message, | |||
message, the field indicates that the server desires the client to | the field indicates that the server desires the client to sign its | |||
sign its next request to the server with the identified parameters, | next request to the server with the identified parameters, and the | |||
and the target message is the client's next request. The client can | target message is the client's next request. The client can choose | |||
choose to also continue signing future requests to the same server in | to also continue signing future requests to the same server in the | |||
the same way. | same way. | |||
The target message of an "Accept-Signature" field MUST include all | The target message of an Accept-Signature field MUST include all | |||
labeled signatures indicated in the "Accept-Header" signature, each | labeled signatures indicated in the Accept-Header signature, each | |||
covering the same identified components of the "Accept-Signature" | covering the same identified components of the Accept-Signature | |||
field. | field. | |||
The sender of an "Accept-Signature" field MUST include identifiers | The sender of an Accept-Signature field MUST include identifiers that | |||
that are appropriate for the type of the target message. For | are appropriate for the type of the target message. For example, if | |||
example, if the target message is a response, the identifiers can not | the target message is a response, the identifiers can not include the | |||
include the "@status" identifier. | @status identifier. | |||
5.1. The Accept-Signature Field | 5.1. The Accept-Signature Field | |||
The "Accept-Signature" HTTP header field is a Dictionary Structured | The Accept-Signature HTTP header field is a Dictionary Structured | |||
field [RFC8941] containing the metadata for one or more requested | field [RFC8941] containing the metadata for one or more requested | |||
message signatures to be generated from message components of the | message signatures to be generated from message components of the | |||
target HTTP message. Each member describes a single message | target HTTP message. Each member describes a single message | |||
signature. The member's name is an identifier that uniquely | signature. The member's name is an identifier that uniquely | |||
identifies the requested message signature within the context of the | identifies the requested message signature within the context of the | |||
target HTTP message. The member's value is the serialization of the | target HTTP message. The member's value is the serialization of the | |||
desired covered components of the target message, including any | desired covered components of the target message, including any | |||
allowed signature metadata parameters, using the serialization | allowed signature metadata parameters, using the serialization | |||
process defined in Section 2.3.1. | process defined in Section 2.2.1. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Accept-Signature: sig1=("@method" "@target-uri" "host" "date" \ | Accept-Signature: sig1=("@method" "@target-uri" "host" "date" \ | |||
"cache-control" "x-empty-header" "x-example")\ | "cache-control" "x-empty-header" "x-example")\ | |||
;keyid="test-key-rsa-pss" | ;keyid="test-key-rsa-pss" | |||
The requested signature MAY include parameters, such as a desired | The requested signature MAY include parameters, such as a desired | |||
algorithm or key identifier. These parameters MUST NOT include | algorithm or key identifier. These parameters MUST NOT include | |||
parameters that the signer is expected to generate, including the | parameters that the signer is expected to generate, including the | |||
"created" and "nonce" parameters. | created and nonce parameters. | |||
5.2. Processing an Accept-Signature | 5.2. Processing an Accept-Signature | |||
The receiver of an "Accept-Signature" field fulfills that header as | The receiver of an Accept-Signature field fulfills that header as | |||
follows: | follows: | |||
1. Parse the field value as a Dictionary | 1. Parse the field value as a Dictionary | |||
2. For each member of the dictionary: | 2. For each member of the dictionary: | |||
1. The name of the member is the label of the output signature | 1. The name of the member is the label of the output signature | |||
as specified in Section 4.1 | as specified in Section 4.1 | |||
2. Parse the value of the member to obtain the set of covered | 2. Parse the value of the member to obtain the set of covered | |||
component identifiers | component identifiers | |||
3. Process the requested parameters, such as the signing | 3. Process the requested parameters, such as the signing | |||
algorithm and key material. If any requested parameters | algorithm and key material. If any requested parameters | |||
skipping to change at page 38, line 21 ¶ | skipping to change at page 40, line 29 ¶ | |||
3. Process the requested parameters, such as the signing | 3. Process the requested parameters, such as the signing | |||
algorithm and key material. If any requested parameters | algorithm and key material. If any requested parameters | |||
cannot be fulfilled, or if the requested parameters conflict | cannot be fulfilled, or if the requested parameters conflict | |||
with those deemed appropriate to the target message, the | with those deemed appropriate to the target message, the | |||
process fails and returns an error. | process fails and returns an error. | |||
4. Select any additional parameters necessary for completing the | 4. Select any additional parameters necessary for completing the | |||
signature | signature | |||
5. Create the "Signature-Input" and "Signature" header values | 5. Create the Signature-Input and Signature header values and | |||
and associate them with the label | associate them with the label | |||
3. Optionally create any additional "Signature-Input" and | 3. Optionally create any additional Signature-Input and Signature | |||
"Signature" values, with unique labels not found in the "Accept- | values, with unique labels not found in the Accept-Signature | |||
Signature" field | field | |||
4. Combine all labeled "Signature-Input" and "Signature" values and | 4. Combine all labeled Signature-Input and Signature values and | |||
attach both headers to the target message | attach both headers to the target message | |||
Note that by this process, a signature applied to a 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 | MUST have the same label, MUST have the same set of covered | |||
component, and MAY have additional parameters. Also note that the | component, and MAY have additional parameters. Also note that the | |||
target message MAY include additional signatures not specified by the | target message MAY include additional signatures not specified by the | |||
"Accept-Signature" field. | Accept-Signature field. | |||
6. IANA Considerations | 6. IANA Considerations | |||
IANA is requested to create three registries and to populate those | ||||
registries with initial values as described in this section. | ||||
6.1. HTTP Signature Algorithms Registry | 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 6.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 6.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 | |||
of the identifier to determine parameters of the signing algorithm | the identifier to determine parameters of the signing algorithm from | |||
from the string. | the string. | |||
Algorithms added to this registry MUST NOT be aliases for other | ||||
entries in the registry. | ||||
6.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 | |||
NOT exceed 20 characters in length. The identifier MUST be unique | 20 characters in length. The identifier MUST be unique within the | |||
within the context of the registry. | 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 | |||
the status. | the status. | |||
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. | |||
6.1.2. Initial Contents | 6.1.2. Initial Contents | |||
6.1.2.1. rsa-pss-sha512 | +===================+========+===================+===============+ | |||
| Algorithm Name | Status | Description | Specification | | ||||
Algorithm Name: | | | | | document(s) | | |||
"rsa-pss-sha512" | +===================+========+===================+===============+ | |||
| rsa-pss-sha512 | Active | RSASSA-PSS using | [[This | | ||||
Status: | | | | SHA-512 | document]], | | |||
Active | | | | | Section 3.3.1 | | |||
+-------------------+--------+-------------------+---------------+ | ||||
Definition: | | rsa-v1_5-sha256 | Active | RSASSA-PKCS1-v1_5 | [[This | | |||
RSASSA-PSS using SHA-256 | | | | using SHA-256 | document]], | | |||
| | | | Section 3.3.2 | | ||||
Specification document(s): | +-------------------+--------+-------------------+---------------+ | |||
[[This document]], Section 3.3.1 | | hmac-sha256 | Active | HMAC using | [[This | | |||
| | | SHA-256 | document]], | | ||||
6.1.2.2. rsa-v1_5-sha256 | | | | | Section 3.3.3 | | |||
+-------------------+--------+-------------------+---------------+ | ||||
Algorithm Name: | | ecdsa-p256-sha256 | Active | ECDSA using curve | [[This | | |||
"rsa-v1_5-sha256" | | | | P-256 DSS and | document]], | | |||
| | | SHA-256 | Section 3.3.4 | | ||||
Status: | +-------------------+--------+-------------------+---------------+ | |||
Active | ||||
Description: | ||||
RSASSA-PKCS1-v1_5 using SHA-256 | ||||
Specification document(s): | ||||
[[This document]], Section 3.3.2 | ||||
6.1.2.3. hmac-sha256 | ||||
Algorithm Name: | ||||
"hmac-sha256" | ||||
Status: | ||||
Active | ||||
Description: | ||||
HMAC using SHA-256 | ||||
Specification document(s): | ||||
[[This document]], Section 3.3.3 | ||||
6.1.2.4. ecdsa-p256-sha256 | ||||
Algorithm Name: | ||||
"ecdsa-p256-sha256" | ||||
Status: | ||||
Active | ||||
Description: | ||||
ECDSA using curve P-256 DSS and SHA-256 | ||||
Specification document(s): | Table 1 | |||
[[This document]], Section 3.3.4 | ||||
6.2. HTTP Signature Metadata Parameters Registry | 6.2. HTTP Signature Metadata Parameters Registry | |||
This document defines the signature parameters structure, the values | This document defines the signature parameters structure, the values | |||
of which 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 parameters structure. Initial values for this registry are | signature parameters structure. Initial values for this registry are | |||
given in Section 6.2.2. Future assignments and modifications to | given in Section 6.2.2. Future assignments and modifications to | |||
existing assignments are to be made through the Expert Review | existing assignments are to be made through the Expert Review | |||
registration policy [RFC8126] and shall follow the template presented | registration policy [RFC8126] and shall follow the template presented | |||
in Section 6.2.1. | in Section 6.2.1. | |||
6.2.1. Registration Template | 6.2.1. Registration Template | |||
Name: | ||||
An identifier for the HTTP signature metadata parameter. The name | ||||
MUST be an ASCII string consisting only of lower-case characters | ||||
("a" - "z"), digits ("0" - "9"), and hyphens ("-"), and SHOULD NOT | ||||
exceed 20 characters in length. The identifier MUST be unique | ||||
within the context of the registry. | ||||
Description: | ||||
A brief description of the metadata parameter and what it | ||||
represents. | ||||
Specification document(s): | ||||
Reference to the document(s) that specify the token endpoint | ||||
authorization method, preferably including a URI that can be used | ||||
to retrieve a copy of the document(s). An indication of the | ||||
relevant sections may also be included but is not required. | ||||
6.2.2. Initial Contents | 6.2.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | 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 | Description | Specification | | |||
+=========+========+================================+ | | | | document(s) | | |||
| alg | Active | Section 2.3.1 of this document | | +=========+===============================+==================+ | |||
+---------+--------+--------------------------------+ | | alg | Explicitly declared signature | Section 2.2.1 of | | |||
| created | Active | Section 2.3.1 of this document | | | | algorithm | this document | | |||
+---------+--------+--------------------------------+ | +---------+-------------------------------+------------------+ | |||
| expires | Active | Section 2.3.1 of this document | | | created | Timestamp of signature | Section 2.2.1 of | | |||
+---------+--------+--------------------------------+ | | | creation | this document | | |||
| keyid | Active | Section 2.3.1 of this document | | +---------+-------------------------------+------------------+ | |||
+---------+--------+--------------------------------+ | | expires | Timestamp of proposed | Section 2.2.1 of | | |||
| nonce | Active | Section 2.3.1 of this document | | | | signature expiration | this document | | |||
+---------+--------+--------------------------------+ | +---------+-------------------------------+------------------+ | |||
| keyid | Key identifier for the | Section 2.2.1 of | | ||||
| | signing and verification keys | this document | | ||||
| | used to create this signature | | | ||||
+---------+-------------------------------+------------------+ | ||||
| nonce | A single-use nonce value | Section 2.2.1 of | | ||||
| | | this document | | ||||
+---------+-------------------------------+------------------+ | ||||
Table 3: Initial contents of the HTTP Signature | Table 2: Initial contents of the HTTP Signature Metadata | |||
Metadata Parameters Registry. | Parameters Registry. | |||
6.3. HTTP Signature Specialty Component 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 | |||
components, including components that can be generated from the | components, including components that can be derived from the context | |||
context of the HTTP message outside of the HTTP fields. These | of the HTTP message outside of the HTTP fields. These components are | |||
components are identified by a unique string, known as the component | identified by a unique string, known as the component identifier. | |||
identifier. IANA is asked to create and maintain a new registry | Component identifiers for specialty components always start with the | |||
typed "HTTP Signature Specialty Component Identifiers" to record and | "@" (at) symbol to distinguish them from HTTP header fields. IANA is | |||
maintain the set of non-field component identifiers and the methods | asked to create and maintain a new registry typed "HTTP Signature | |||
to produce their associated component values. Initial values for | Specialty Component Identifiers" to record and maintain the set of | |||
this registry are given in Section 6.3.2. Future assignments and | non-field component identifiers and the methods to produce their | |||
modifications to existing assignments are to be made through the | associated component values. Initial values for this registry are | |||
Expert Review registration policy [RFC8126] and shall follow the | given in Section 6.3.2. Future assignments and modifications to | |||
template presented in Section 6.3.1. | existing assignments are to be made through the Expert Review | |||
registration policy [RFC8126] and shall follow the template presented | ||||
in Section 6.3.1. | ||||
6.3.1. Registration Template | 6.3.1. Registration Template | |||
Identifier: | ||||
An identifier for the HTTP specialty component identifier. The | ||||
name MUST begin with the "@" character followed by an ASCII string | ||||
consisting only of lower-case characters ("a" - "z"), digits ("0" | ||||
- "9"), and hyphens ("-"), and SHOULD NOT exceed 20 characters in | ||||
length. The identifier MUST be unique within the context of the | ||||
registry. | ||||
Status: | ||||
A brief text description of the status of the algorithm. The | ||||
description MUST begin with one of "Active" or "Deprecated", and | ||||
MAY provide further context or explanation as to the reason for | ||||
the status. | ||||
Target: | ||||
The valid message targets for the specialty parameter. MUST be | ||||
one of the values "Request", "Request, Response", "Request, | ||||
Related-Response", or "Related-Response". The semantics of these | ||||
are defined in Section 2.2. | ||||
Specification document(s): | ||||
Reference to the document(s) that specify the token endpoint | ||||
authorization method, preferably including a URI that can be used | ||||
to retrieve a copy of the document(s). An indication of the | ||||
relevant sections may also be included but is not required. | ||||
6.3.2. Initial Contents | 6.3.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the HTTP Signature | |||
Specialty Component Identifiers Registry. | Specialty Component Identifiers Registry. | |||
+===================+========+===================+==================+ | +===================+========+==================+==================+ | |||
| Name | Status | Target | Reference | | | Identifier | Status | Target | Specification | | |||
+===================+========+===================+==================+ | | | | | document(s) | | |||
| @signature-params | Active | Request, | Section 2.3.1 of | | +===================+========+==================+==================+ | |||
| | | Response | this document | | | @signature-params | Active | Request, | Section 2.2.1 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Response | this document | | |||
| @method | Active | Request, | Section 2.3.2 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @method | Active | Request, | Section 2.2.2 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @authority | Active | Request, | Section 2.3.4 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @authority | Active | Request, | Section 2.2.4 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @scheme | Active | Request, | Section 2.3.5 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @scheme | Active | Request, | Section 2.2.5 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @target-uri | Active | Request, | Section 2.3.3 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @target-uri | Active | Request, | Section 2.2.3 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @request-target | Active | Request, | Section 2.3.6 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @request-target | Active | Request, | Section 2.2.6 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @path | Active | Request, | Section 2.3.7 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @path | Active | Request, | Section 2.2.7 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @query | Active | Request, | Section 2.3.8 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @query | Active | Request, | Section 2.2.8 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @query-params | Active | Request, | Section 2.3.9 of | | +-------------------+--------+------------------+------------------+ | |||
| | | Related-Response | this document | | | @query-params | Active | Request, | Section 2.2.9 of | | |||
+-------------------+--------+-------------------+------------------+ | | | | Related-Response | this document | | |||
| @status | Active | Response | Section 2.3.10 | | +-------------------+--------+------------------+------------------+ | |||
| | | | of this document | | | @status | Active | Response | Section 2.2.10 | | |||
+-------------------+--------+-------------------+------------------+ | | | | | of this document | | |||
| @request-response | Active | Section 2.3.11 | | | +-------------------+--------+------------------+------------------+ | |||
| | | of this document | | | | @request-response | Active | Related-Response | Section 2.2.11 | | |||
+-------------------+--------+-------------------+------------------+ | | | | | of this document | | |||
+-------------------+--------+------------------+------------------+ | ||||
Table 4: Initial contents of the HTTP Signature Specialty Component | Table 3: Initial contents of the HTTP Signature Specialty Component | |||
Identifiers Registry. | Identifiers Registry. | |||
7. Security Considerations | 7. Security Considerations | |||
(( TODO: need to dive deeper on this section; not sure how much of | In order for an HTTP message to be considered covered by a signature, | |||
what's referenced below is actually applicable, or if it covers | all of the following conditions have to be true: | |||
everything we need to worry about. )) | ||||
(( TODO: Should provide some recommendations on how to determine what | * a signature is expected or allowed on the message by the verifier | |||
components need to be signed for a given use case. )) | * the signature exists on the message | |||
There are a number of security considerations to take into account | ||||
when implementing or utilizing this specification. A thorough | ||||
security analysis of this protocol, including its strengths and | ||||
weaknesses, can be found in [WP-HTTP-Sig-Audit]. | ||||
8. References | * the signature is verified against the identified key material and | |||
algorithm | ||||
8.1. Normative References | * the key material and algorithm are appropriate for the context of | |||
the message | ||||
* the signature is within expected time boundaries | ||||
* the signature covers the expected content, including any critical | ||||
components | ||||
7.1. Signature Verification Skipping | ||||
HTTP Message Signatures only provide security if the signature is | ||||
verified by the verifier. Since the message to which the signature | ||||
is attached remains a valid HTTP message without the signature | ||||
fields, it is possible for a verifier to ignore the output of the | ||||
verification function and still process the message. Common reasons | ||||
for this could be relaxed requirements in a development environment | ||||
or a temporary suspension of enforcing verification during debugging | ||||
an overall system. Such temporary suspensions are difficult to | ||||
detect under positive-example testing since a good signature will | ||||
always trigger a valid response whether or not it has been checked. | ||||
To detect this, verifiers should be tested using both valid and | ||||
invalid signatures, ensuring that the invalid signature fails as | ||||
expected. | ||||
7.2. Use of TLS | ||||
The use of HTTP Message Signatures does not negate the need for TLS | ||||
or its equivalent to protect information in transit. Message | ||||
signatures provide message integrity over the covered message | ||||
components but do not provide any confidentiality for the | ||||
communication between parties. | ||||
TLS provides such confidentiality between the TLS endpoints. As part | ||||
of this, TLS also protects the signature data itself from being | ||||
captured by an attacker, which is an important step in preventing | ||||
signature replay (Section 7.3). | ||||
When TLS is used, it needs to be deployed according to the | ||||
recommendations in [BCP195]. | ||||
7.3. Signature Replay | ||||
Since HTTP Message Signatures allows sub-portions of the HTTP message | ||||
to be signed, it is possible for two different HTTP messages to | ||||
validate against the same signature. The most extreme form of this | ||||
would be a signature over no message components. If such a signature | ||||
were intercepted, it could be replayed at will by an attacker, | ||||
attached to any HTTP message. Even with sufficient component | ||||
coverage, a given signature could be applied to two similar HTTP | ||||
messages, allowing a message to be replayed by an attacker with the | ||||
signature intact. | ||||
To counteract these kinds of attacks, it's first important for the | ||||
signer to cover sufficient portions of the message to differentiate | ||||
it from other messages. In addition, the signature can use the nonce | ||||
signature parameter to provide a per-message unique value to allow | ||||
the verifier to detect replay of the signature itself if a nonce | ||||
value is repeated. Furthermore, the signer can provide a timestamp | ||||
for when the signature was created and a time at which the signer | ||||
considers the signature to be invalid, limiting the utility of a | ||||
captured signature value. | ||||
If a verifier wants to trigger a new signature from a signer, it can | ||||
send the Accept-Signature header field with a new nonce parameter. | ||||
An attacker that is simply replaying a signature would not be able to | ||||
generate a new signature with the chosen nonce value. | ||||
7.4. Insufficient Coverage | ||||
Any portions of the message not covered by the signature are | ||||
susceptible to modification by an attacker without affecting the | ||||
signature. An attacker can take advantage of this by introducing a | ||||
header field or other message component that will change the | ||||
processing of the message but will not be covered by the signature. | ||||
Such an altered message would still pass signature verification, but | ||||
when the verifier processes the message as a whole, the unsigned | ||||
content injected by the attacker would subvert the trust conveyed by | ||||
the valid signature and change the outcome of processing the message. | ||||
To combat this, an application of this specification should require | ||||
as much of the message as possible to be signed, within the limits of | ||||
the application and deployment. The verifier should only trust | ||||
message components that have been signed. Verifiers could also strip | ||||
out any sensitive unsigned portions of the message before processing | ||||
of the message continues. | ||||
7.5. Cryptography and Signature Collision | ||||
The HTTP Message Signatures specification does not define any of its | ||||
own cryptographic primitives, and instead relies on other | ||||
specifications to define such elements. If the signature algorithm | ||||
or key used to process the signature input string is vulnerable to | ||||
any attacks, the resulting signature will also be susceptible to | ||||
these same attacks. | ||||
A common attack against signature systems is to force a signature | ||||
collision, where the same signature value successfully verifies | ||||
against multiple different inputs. Since this specification relies | ||||
on reconstruction of the input string based on an HTTP message, and | ||||
the list of components signed is fixed in the signature, it is | ||||
difficult but not impossible for an attacker to effect such a | ||||
collision. An attacker would need to manipulate the HTTP message and | ||||
its covered message components in order to make the collision | ||||
effective. | ||||
To counter this, only vetted keys and signature algorithms should be | ||||
used to sign HTTP messages. The HTTP Message Signatures Algorithm | ||||
Registry is one source of potential trusted algorithms. | ||||
While it is possible for an attacker to substitute the signature | ||||
parameters value or the signature value separately, the signature | ||||
input generation algorithm (Section 2.3) always covers the signature | ||||
parameters as the final value in the input string using a | ||||
deterministic serialization method. This step strongly binds the | ||||
signature input with the signature value in a way that makes it much | ||||
more difficult for an attacker to perform a partial substitution on | ||||
the signature inputs. | ||||
7.6. Key Theft | ||||
A foundational assumption of signature-based cryptographic systems is | ||||
that the signing key is not compromised by an attacker. If the keys | ||||
used to sign the message are exfiltrated or stolen, the attacker will | ||||
be able to generate their own signatures using those keys. As a | ||||
consequence, signers have to protect any signing key material from | ||||
exfiltration, capture, and use by an attacker. | ||||
To combat this, signers can rotate keys over time to limit the amount | ||||
of time stolen keys are useful. Signers can also use key escrow and | ||||
storage systems to limit the attack surface against keys. | ||||
Furthermore, the use of asymmetric signing algorithms exposes key | ||||
material less than the use of symmetric signing algorithms | ||||
(Section 7.11). | ||||
7.7. Modification of Required Message Parameters | ||||
An attacker could effectively deny a service by modifying an | ||||
otherwise benign signature parameter or signed message component. | ||||
While rejecting a modified message is the desired behavior, | ||||
consistently failing signatures could lead to the verifier turning | ||||
off signature checking in order to make systems work again (see | ||||
Section 7.1). | ||||
If such failures are common within an application, the signer and | ||||
verifier should compare their generated signature input strings with | ||||
each other to determine which part of the message is being modified. | ||||
However, the signer and verifier should not remove the requirement to | ||||
sign the modified component when it is suspected an attacker is | ||||
modifying the component. | ||||
7.8. Mismatch of Signature Parameters from Message | ||||
The verifier needs to make sure that the signed message components | ||||
match those in the message itself. This specification encourages | ||||
this by requiring the verifier to derive these values from the | ||||
message, but lazy cacheing or conveyance of the signature input | ||||
string to a processing system could lead to downstream verifiers | ||||
accepting a message that does not match the presented signature. | ||||
7.9. Multiple Signature Confusion | ||||
Since multiple signatures can be applied to one message | ||||
(Section 4.3), it is possible for an attacker to attach their own | ||||
signature to a captured message without modifying existing | ||||
signatures. This new signature could be completely valid based on | ||||
the attacker's key, or it could be an invalid signature for any | ||||
number of reasons. Each of these situations need to be accounted | ||||
for. | ||||
A verifier processing a set of valid signatures needs to account for | ||||
all of the signers, identified by the signing keys. Only signatures | ||||
from expected signers should be accepted, regardless of the | ||||
cryptographic validity of the signature itself. | ||||
A verifier processing a set of signatures on a message also needs to | ||||
determine what to do when one or more of the signatures are not | ||||
valid. If a message is accepted when at least one signature is | ||||
valid, then a verifier could drop all invalid signatures from the | ||||
request before processing the message further. Alternatively, if the | ||||
verifier rejects a message for a single invalid signature, an | ||||
attacker could use this to deny service to otherwise valid messages | ||||
by injecting invalid signatures alongside the valid ones. | ||||
7.10. Signature Labels | ||||
HTTP Message Signature values are identified in the Signature and | ||||
Signature-Input field values by unique labels. These labels are | ||||
chosen only when attaching the signature values to the message and | ||||
are not accounted for in the signing process. An intermediary adding | ||||
its own signature is allowed to re-label an existing signature when | ||||
processing the message. | ||||
Therefore, applications should not rely on specific labels being | ||||
present, and applications should not put semantic meaning on the | ||||
labels themselves. Instead, additional signature parmeters can be | ||||
used to convey whatever additional meaning is required to be attached | ||||
to and covered by the signature. | ||||
7.11. Symmetric Cryptography | ||||
The HTTP Message Signatures specification allows for both asymmetric | ||||
and symmetric cryptography to be applied to HTTP messages. By its | ||||
nature, symmetric cryptographic methods require the same key material | ||||
to be known by both the signer and verifier. This effectively means | ||||
that a verifier is capable of generating a valid signature, since | ||||
they have access to the same key material. An attacker that is able | ||||
to compromise a verifier would be able to then impersonate a signer. | ||||
Where possible, asymmetric methods or secure key agreement mechanisms | ||||
should be used in order to avoid this type of attack. When symmetric | ||||
methods are used, distribution of the key material needs to be | ||||
protected by the overall system. One technique for this is the use | ||||
of separate cryptographic modules that separate the verification | ||||
process (and therefore the key material) from other code, minimizing | ||||
the vulnerable attack surface. Another technique is the use of key | ||||
derivation functions that allow the signer and verifier to agree on | ||||
unique keys for each message without having to share the key values | ||||
directly. | ||||
Additionally, if symmetric algorithms are allowed within a system, | ||||
special care must be taken to avoid key downgrade attacks | ||||
(Section 7.15). | ||||
7.12. Canonicalization Attacks | ||||
Any ambiguity in the generation of the signature input string could | ||||
provide an attacker with leverage to substitute or break a signature | ||||
on a message. Some message component values, particularly HTTP field | ||||
values, are potentially susceptible to broken implementations that | ||||
could lead to unexpected and insecure behavior. Naive | ||||
implementations of this specification might implement HTTP field | ||||
processing by taking the single value of a field and using it as the | ||||
direct component value without processing it appropriately. | ||||
For example, if the handling of obs-fold field values does not remove | ||||
the internal line folding and whitespace, additional newlines could | ||||
be introduced into the signature input string by the signer, | ||||
providing a potential place for an attacker to mount a signature | ||||
collision (Section 7.5) attack. Alternatively, if header fields that | ||||
appear multiple times are not joined into a single string value, as | ||||
is required by this specification, similar attacks can be mounted as | ||||
a signed component value would show up in the input string more than | ||||
once and could be substituted or otherwise attacked in this way. | ||||
To counter this, the entire field processing algorithm needs to be | ||||
implemented by all implementations of signers and verifiers. | ||||
7.13. Key Specification Mix-Up | ||||
The existence of a valid signature on an HTTP message is not | ||||
sufficient to prove that the message has been signed by the | ||||
appropriate party. It is up to the verifier to ensure that a given | ||||
key and algorithm are appropriate for the message in question. If | ||||
the verifier does not perform such a step, an attacker could | ||||
substitute their own signature using their own key on a message and | ||||
force a verifier to accept and process it. To combat this, the | ||||
verifier needs to ensure that not only does the signature validate | ||||
for a message, but that the key and algorithm used are appropriate. | ||||
7.14. HTTP Versions and Component Ambiguity | ||||
Some message components are expressed in different ways across HTTP | ||||
versions. For example, the authority of the request target is sent | ||||
using the Host header field in HTTP 1.1 but with the :authority | ||||
pseudo-header in HTTP 2. If a signer sends an HTTP 1.1 message and | ||||
signs the Host field, but the message is translated to HTTP 2 before | ||||
it reaches the verifier, the signature will not validate as the Host | ||||
header field could be dropped. | ||||
It is for this reason that HTTP Message Signatures defines a set of | ||||
specialty components that define a single way to get value in | ||||
question, such as the @authority specialty component identifier | ||||
(Section 2.2.4). Applications should therefore prefer specialty | ||||
component identifiers for such options where possible. | ||||
7.15. Key and Algorithm Specification Downgrades | ||||
Applications of this specification need to protect against key | ||||
specification downgrade attacks. For example, the same RSA key can | ||||
be used for both RSA-PSS and RSA v1.5 signatures. If an application | ||||
expects a key to only be used with RSA-PSS, it needs to reject | ||||
signatures for that key using the weaker RSA 1.5 specification. | ||||
Another example of a downgrade attack occurs when an asymmetric | ||||
algorithm is expected, such as RSA-PSS, but an attacker substitutes a | ||||
signature using symmetric algorithm, such as HMAC. A naive verifier | ||||
implementation could use the value of the public RSA key as the input | ||||
to the HMAC verification function. Since the public key is known to | ||||
the attacker, this would allow the attacker to create a valid HMAC | ||||
signature against this known key. To prevent this, the verifier | ||||
needs to ensure that both the key material and the algorithm are | ||||
appropriate for the usage in question. Additionally, while this | ||||
specification does allow runtime specification of the algorithm using | ||||
the alg signature parameter, applications are encouraged to use other | ||||
mechanisms such as static configuration or higher protocol-level | ||||
algorithm specification instead. | ||||
7.16. Parsing Structured Field Values | ||||
Several parts of this specification rely on the parsing of structured | ||||
field values [RFC8941]. In particular, normalization of HTTP | ||||
structured field values (Section 2.1.1), referencing members of a | ||||
dictionary structured field (Section 2.1.3), and processing the | ||||
@signature-input value when verifying a signature (Section 3.2). | ||||
While structured field values are designed to be relatively simple to | ||||
parse, a naive or broken implementation of such a parser could lead | ||||
to subtle attack surfaces being exposed in the implementation. | ||||
For example, if a buggy parser of the @signature-input value does not | ||||
enforce proper closing of quotes around string values within the list | ||||
of component identifiers, an attacker could take advantage of this | ||||
and inject additional content into the signature input string through | ||||
manipulating the Signature-Input field value on a message. | ||||
To counteract this, implementations should use fully compliant and | ||||
trusted parsers for all structured field processing, both on the | ||||
signer and verifier side. | ||||
7.17. Choosing Message Components | ||||
Applications of HTTP Message Signatures need to decide which message | ||||
components will be covered by the signature. Depending on the | ||||
application, some components could be expected to be changed by | ||||
intermediaries prior to the signature's verification. If these | ||||
components are covered, such changes would, by design, break the | ||||
signature. | ||||
However, the HTTP Message Signature standard allows for flexibility | ||||
in determining which components are signed precisely so that a given | ||||
application can choose the appropriate portions of the message that | ||||
need to be signed, avoiding problematic components. For example, a | ||||
web application framework that relies on rewriting query parameters | ||||
might avoid use of the @query content identifier in favor of sub- | ||||
indexing the query value using @query-params content identifier | ||||
instead. | ||||
Some components are expected to be changed by intermediaries and | ||||
ought not to be signed under most circumstance. The Via and | ||||
Forwarded header fields, for example, are expected to be manipulated | ||||
by proxies and other middle-boxes, including replacing or entirely | ||||
dropping existing values. These fields should not be covered by the | ||||
signature except in very limited and tightly-coupled scenarios. | ||||
Additional considerations for choosing signature aspects are | ||||
discussed in Section 1.5. | ||||
8. Privacy Considerations | ||||
8.1. Identification through Keys | ||||
If a signer uses the same key with multiple verifiers, or uses the | ||||
same key over time with a single verifier, the ongoing use of that | ||||
key can be used to track the signer throughout the set of verifiers | ||||
that messages are sent to. Since cryptographic keys are meant to be | ||||
functionally unique, the use of the same key over time is a strong | ||||
indicator that it is the same party signing multiple messages. | ||||
In many applications, this is a desirable trait, and it allows HTTP | ||||
Message Signatures to be used as part of authenticating the signer to | ||||
the verifier. However, unintentional tracking that a signer might | ||||
not be aware of. To counter this kind of tracking, a signer can use | ||||
a different key for each verifier that it is in communication with. | ||||
Sometimes, a signer could also rotate their key when sending messages | ||||
to a given verifier. These approaches do not negate the need for | ||||
other anti-tracking techniques to be applied as necessary. | ||||
8.2. Signatures do not provide confidentiality | ||||
HTTP Message Signatures do not provide confidentiality of any of the | ||||
information protected by the signature. The content of the HTTP | ||||
message, including the value of all fields and the value of the | ||||
signature itself, is presented in plaintext to any party with access | ||||
to the message. | ||||
To provide confidentiality at the transport level, TLS or its | ||||
equivalent can be used as discussed in Section 7.2. | ||||
8.3. Oracles | ||||
It is important to balance the need for providing useful feedback to | ||||
developers on error conditions without providing additional | ||||
information to an attacker. For example, a naive but helpful server | ||||
implementation might try to indicate the required key identifier | ||||
needed for requesting a resource. If someone knows who controls that | ||||
key, a correlation can be made between the resource's existence and | ||||
the party identified by the key. Access to such information could be | ||||
used by an attacker as a means to target the legitimate owner of the | ||||
resource for further attacks. | ||||
8.4. Required Content | ||||
A core design tenet of this specification is that all message | ||||
components covered by the signature need to be available to the | ||||
verifier in order to recreate the signature input string and verify | ||||
the signature. As a consequence, if an application of this | ||||
specification requires that a particular field be signed, the | ||||
verifier will need access to the value of that field. | ||||
For example, in some complex systems with intermediary processors | ||||
this could cause the surprising behavior of an intermediary not being | ||||
able to remove privacy-sensitive information from a message before | ||||
forwarding it on for processing, for fear of breaking the signature. | ||||
A possible mitigation for this specific situation would be for the | ||||
intermediary to verify the signature itself, then modifying the | ||||
message to remove the privacy-sensitive information. The | ||||
intermediary can add its own signature at this point to signal to the | ||||
next destination that the incoming signature was validated, as is | ||||
shown in the example in Section 4.3. | ||||
9. References | ||||
9.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>. | |||
[HTMLURL] "URL (Living Standard)", 2021, | [HTMLURL] "URL (Living Standard)", 2021, | |||
<https://url.spec.whatwg.org/>. | <https://url.spec.whatwg.org/>. | |||
[MESSAGING] | [MESSAGING] | |||
Fielding, R. T., Nottingham, M., and J. Reschke, | Fielding, R. T., Nottingham, M., and J. Reschke, | |||
"HTTP/1.1", Work in Progress, Internet-Draft, draft-ietf- | "HTTP/1.1", Work in Progress, Internet-Draft, draft-ietf- | |||
httpbis-messaging-17, 25 July 2021, | httpbis-messaging-19, 12 September 2021, | |||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
messaging-17>. | messaging-19>. | |||
[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>. | |||
skipping to change at page 45, line 17 ¶ | skipping to change at page 56, line 8 ¶ | |||
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. T., Nottingham, M., and J. Reschke, "HTTP | Fielding, R. T., Nottingham, M., and J. Reschke, "HTTP | |||
Semantics", Work in Progress, Internet-Draft, draft-ietf- | Semantics", Work in Progress, Internet-Draft, draft-ietf- | |||
httpbis-semantics-17, 25 July 2021, | httpbis-semantics-19, 12 September 2021, | |||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
semantics-17>. | semantics-19>. | |||
8.2. Informative References | 9.2. Informative References | |||
[BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, | ||||
"Recommendations for Secure Use of Transport Layer | ||||
Security (TLS) and Datagram Transport Layer Security | ||||
(DTLS)", BCP 195, RFC 7525, May 2015. | ||||
Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS | ||||
1.1", BCP 195, RFC 8996, March 2021. | ||||
<https://www.rfc-editor.org/info/bcp195> | ||||
[I-D.ietf-httpbis-client-cert-field] | [I-D.ietf-httpbis-client-cert-field] | |||
Campbell, B. and M. Bishop, "Client-Cert HTTP Header | Campbell, B. and M. Bishop, "Client-Cert HTTP Header | |||
Field: Conveying Client Certificate Information from TLS | Field: Conveying Client Certificate Information from TLS | |||
Terminating Reverse Proxies to Origin Server | Terminating Reverse Proxies to Origin Server | |||
Applications", Work in Progress, Internet-Draft, draft- | Applications", Work in Progress, Internet-Draft, draft- | |||
ietf-httpbis-client-cert-field-00, 8 June 2021, | ietf-httpbis-client-cert-field-00, 8 June 2021, | |||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
client-cert-field-00>. | client-cert-field-00>. | |||
skipping to change at page 46, line 14 ¶ | skipping to change at page 57, line 19 ¶ | |||
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/rfc/rfc8126>. | <https://www.rfc-editor.org/rfc/rfc8126>. | |||
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
<https://www.rfc-editor.org/rfc/rfc8446>. | <https://www.rfc-editor.org/rfc/rfc8446>. | |||
[WP-HTTP-Sig-Audit] | ||||
"Security Considerations for HTTP Signatures", 2013, | ||||
<https://web-payments.org/specs/source/http-signatures- | ||||
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-standardized definitions of the Signature | |||
field used within this specification. It is recommended that | field, which is used within this specification. It is recommended | |||
developers wishing to support both this specification and other | that 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" field defined in this specification to detect that | Signature-Input field defined in this specification to detect that | |||
this standard is in use and not an alternative. If the "Signature- | this standard is in use and not an alternative. If the Signature- | |||
Input" field is present, all "Signature" fields 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. | |||
The key identifiers for each key are used throughout the examples in | The key identifiers for each key are used throughout the examples in | |||
this specification. It is assumed for these examples that the signer | this specification. It is assumed for these examples that the signer | |||
and verifier can unambiguously dereference all key identifiers used | and verifier can unambiguously dereference all key identifiers used | |||
here, and that the keys and algorithms used are appropriate for the | here, and that the keys and algorithms used are appropriate for the | |||
context in which the signature is presented. | context in which the signature is presented. | |||
B.1.1. Example Key RSA test | B.1.1. Example Key RSA test | |||
The following key is a 2048-bit RSA public and private key pair, | The following key is a 2048-bit RSA public and private key pair, | |||
referred to in this document as "test-key-rsa": | referred to in this document as test-key-rsa: | |||
-----BEGIN RSA PUBLIC KEY----- | -----BEGIN RSA PUBLIC KEY----- | |||
MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | |||
WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | |||
MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | |||
kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | |||
uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | |||
PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | |||
-----END RSA PUBLIC KEY----- | -----END RSA PUBLIC KEY----- | |||
skipping to change at page 47, line 45 ¶ | skipping to change at page 58, line 45 ¶ | |||
/2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | /2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | |||
IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | |||
qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | |||
WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | |||
EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | |||
-----END RSA PRIVATE KEY----- | -----END RSA PRIVATE KEY----- | |||
B.1.2. Example RSA PSS Key | B.1.2. Example RSA PSS Key | |||
The following key is a 2048-bit RSA public and private key pair, | The following key is a 2048-bit RSA public and private key pair, | |||
referred to in this document as "test-key-rsa-pss": | referred to in this document as test-key-rsa-pss: | |||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | |||
+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | +QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | |||
oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | |||
gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | |||
Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | |||
aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | |||
2wIDAQAB | 2wIDAQAB | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
skipping to change at page 48, line 47 ¶ | skipping to change at page 59, line 47 ¶ | |||
3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | 3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | |||
t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | |||
dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | |||
S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | |||
rOjr9w349JooGXhOxbu8nOxX | rOjr9w349JooGXhOxbu8nOxX | |||
-----END PRIVATE KEY----- | -----END PRIVATE KEY----- | |||
B.1.3. Example ECC P-256 Test Key | B.1.3. Example ECC P-256 Test Key | |||
The following key is an elliptical curve key over the curve P-256, | The following key is an elliptical curve key over the curve P-256, | |||
referred to in this document as "test-key-ecc-p256". | referred to in this document as test-key-ecc-p256. | |||
-----BEGIN EC PRIVATE KEY----- | -----BEGIN EC PRIVATE KEY----- | |||
MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | |||
AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | |||
4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | 4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | |||
-----END EC PRIVATE KEY----- | -----END EC PRIVATE KEY----- | |||
-----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 | 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: | |||
POST /foo?param=value&pet=dog HTTP/1.1 | POST /foo?param=value&pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
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 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 | |||
header for a signature using the "rsa-pss-sha512" algorithm over | for a signature using the rsa-pss-sha512 algorithm over test-request, | |||
"test-request", covering none of the components of the HTTP message | covering none of the components of the HTTP message request but | |||
request but providing a timestamped signature proof of possession of | 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 | 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 | |||
headers being added to the message: | being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | 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=:HWP69ZNiom9Obu1KIdqPPcu/C1a5ZUMBbqS/xwJECV8bhIQVmE\ | Signature: sig1=:HWP69ZNiom9Obu1KIdqPPcu/C1a5ZUMBbqS/xwJECV8bhIQVmE\ | |||
AAAzz8LQPvtP1iFSxxluDO1KE9b8L+O64LEOvhwYdDctV5+E39Jy1eJiD7nYREBgx\ | AAAzz8LQPvtP1iFSxxluDO1KE9b8L+O64LEOvhwYdDctV5+E39Jy1eJiD7nYREBgx\ | |||
TpdUfzTO+Trath0vZdTylFlxK4H3l3s/cuFhnOCxmFYgEa+cw+StBRgY1JtafSFwN\ | TpdUfzTO+Trath0vZdTylFlxK4H3l3s/cuFhnOCxmFYgEa+cw+StBRgY1JtafSFwN\ | |||
cZgLxVwialuH5VnqJS4JN8PHD91XLfkjMscTo4jmVMpFd3iLVe0hqVFl7MDt6TMkw\ | cZgLxVwialuH5VnqJS4JN8PHD91XLfkjMscTo4jmVMpFd3iLVe0hqVFl7MDt6TMkw\ | |||
IyVFnEZ7B/VIQofdShO+C/7MuupCSLVjQz5xA+Zs6Hw+W9ESD/6BuGs6LF1TcKLxW\ | IyVFnEZ7B/VIQofdShO+C/7MuupCSLVjQz5xA+Zs6Hw+W9ESD/6BuGs6LF1TcKLxW\ | |||
+5K+2zvDY/Cia34HNpRW5io7Iv9/b7iQ==: | +5K+2zvDY/Cia34HNpRW5io7Iv9/b7iQ==: | |||
Note that since the covered components list is empty, this signature | Note that since the covered components list is empty, this signature | |||
could be applied by an attacker to an unrelated HTTP message. | could be applied by an attacker to an unrelated HTTP message. | |||
Therefore, use of an empty covered components set is discouraged. | Therefore, use of an empty covered components set is discouraged. | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 | B.2.2. Selective Covered Components using rsa-pss-sha512 | |||
This example covers additional components in "test-request" using the | This example covers additional components in test-request using the | |||
"rsa-pss-sha512" algorithm. | rsa-pss-sha512 algorithm. | |||
The corresponding signature input is: | The corresponding signature input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("@authority" "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 | |||
headers being added to the message: | being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "content-type")\ | Signature-Input: sig1=("@authority" "content-type")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
Signature: sig1=:ik+OtGmM/kFqENDf9Plm8AmPtqtC7C9a+zYSaxr58b/E6h81gh\ | Signature: sig1=:ik+OtGmM/kFqENDf9Plm8AmPtqtC7C9a+zYSaxr58b/E6h81gh\ | |||
JS3PcH+m1asiMp8yvccnO/RfaexnqanVB3C72WRNZN7skPTJmUVmoIeqZncdP2mlf\ | JS3PcH+m1asiMp8yvccnO/RfaexnqanVB3C72WRNZN7skPTJmUVmoIeqZncdP2mlf\ | |||
xlLP6UbkrgYsk91NS6nwkKC6RRgLhBFqzP42oq8D2336OiQPDAo/04SxZt4Wx9nDG\ | xlLP6UbkrgYsk91NS6nwkKC6RRgLhBFqzP42oq8D2336OiQPDAo/04SxZt4Wx9nDG\ | |||
uy2SfZJUhsJqZyEWRk4204x7YEB3VxDAAlVgGt8ewilWbIKKTOKp3ymUeQIwptqYw\ | uy2SfZJUhsJqZyEWRk4204x7YEB3VxDAAlVgGt8ewilWbIKKTOKp3ymUeQIwptqYw\ | |||
v0l8mN404PPzRBTpB7+HpClyK4CNp+SVv46+6sHMfJU4taz10s/NoYRmYCGXyadzY\ | v0l8mN404PPzRBTpB7+HpClyK4CNp+SVv46+6sHMfJU4taz10s/NoYRmYCGXyadzY\ | |||
YDj0BYnFdERB6NblI/AOWFGl5Axhhmjg==: | 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" (including the | This example covers all headers in test-request (including the | |||
message body "Digest") plus various elements of the control data, | message body Digest) plus various elements of the control data, using | |||
using the "rsa-pss-sha512" algorithm. | the rsa-pss-sha512 algorithm. | |||
The corresponding signature input is: | The corresponding signature input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:56 GMT | "date": Tue, 20 Apr 2021 02:07:56 GMT | |||
"@method": POST | "@method": POST | |||
"@path": /foo | "@path": /foo | |||
"@query": ?param=value&pet=dog | "@query": ?param=value&pet=dog | |||
"@authority": example.com | "@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": ("date" "@method" "@path" "@query" \ | "@signature-params": ("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "digest" "content-length")\ | "@authority" "content-type" "digest" "content-length")\ | |||
;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 | |||
headers being added to the message: | being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("date" "@method" "@path" "@query" \ | Signature-Input: sig1=("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "digest" "content-length")\ | "@authority" "content-type" "digest" "content-length")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
Signature: sig1=:JuJnJMFGD4HMysAGsfOY6N5ZTZUknsQUdClNG51VezDgPUOW03\ | Signature: sig1=:JuJnJMFGD4HMysAGsfOY6N5ZTZUknsQUdClNG51VezDgPUOW03\ | |||
QMe74vbIdndKwW1BBrHOHR3NzKGYZJ7X3ur23FMCdANe4VmKb3Rc1Q/5YxOO8p7Ko\ | QMe74vbIdndKwW1BBrHOHR3NzKGYZJ7X3ur23FMCdANe4VmKb3Rc1Q/5YxOO8p7Ko\ | |||
yfVa4uUcMk5jB9KAn1M1MbgBnqwZkRWsbv8ocCqrnD85Kavr73lx51k1/gU8w673W\ | yfVa4uUcMk5jB9KAn1M1MbgBnqwZkRWsbv8ocCqrnD85Kavr73lx51k1/gU8w673W\ | |||
T/oBtxPtAn1eFjUyIKyA+XD7kYph82I+ahvm0pSgDPagu917SlqUjeaQaNnlZzO03\ | T/oBtxPtAn1eFjUyIKyA+XD7kYph82I+ahvm0pSgDPagu917SlqUjeaQaNnlZzO03\ | |||
Iy1RZ5XpgbNeDLCqSLuZFVID80EohC2CQ1cL5svjslrlCNstd2JCLmhjL7xV3NYXe\ | Iy1RZ5XpgbNeDLCqSLuZFVID80EohC2CQ1cL5svjslrlCNstd2JCLmhjL7xV3NYXe\ | |||
rLim4bqUQGRgDwNJRnqobpS6C1NBns/Q==: | rLim4bqUQGRgDwNJRnqobpS6C1NBns/Q==: | |||
Note in this example that the value of the "Date" header and the | Note in this example that the value of the Date header and the value | |||
value of the "created" signature parameter need not be the same. | of the created signature parameter need not be the same. This is due | |||
This is due to the fact that the "Date" header is added when creating | to the fact that the Date header is added when creating the HTTP | |||
the HTTP Message and the "created" parameter is populated when | Message and the created parameter is populated when creating the | |||
creating the signature over that message, and these two times could | signature over that message, and these two times could vary. If the | |||
vary. If the "Date" header is covered by the signature, it is up to | Date header is covered by the signature, it is up to the verifier to | |||
the verifier to determine whether its value has to match that of the | determine whether its value has to match that of the created | |||
"created" parameter or not. | 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: | |||
NOTE: '\' line wrapping per RFC 8792 | 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": ("content-type" "digest" "content-length")\ | "@signature-params": ("content-type" "digest" "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 | |||
headers being added to the message: | being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("content-type" "digest" "content-length")\ | Signature-Input: sig1=("content-type" "digest" "content-length")\ | |||
;created=1618884475;keyid="test-key-ecc-p256" | ;created=1618884475;keyid="test-key-ecc-p256" | |||
Signature: sig1=:n8RKXkj0iseWDmC6PNSQ1GX2R9650v+lhbb6rTGoSrSSx18zmn\ | Signature: sig1=:n8RKXkj0iseWDmC6PNSQ1GX2R9650v+lhbb6rTGoSrSSx18zmn\ | |||
6fPOtBx48/WffYLO0n1RHHf9scvNGAgGq52Q==: | 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: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@authority": example.com | "@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": ("@authority" "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 | |||
headers being added to the message: | being added to the message: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "date" "content-type")\ | Signature-Input: sig1=("@authority" "date" "content-type")\ | |||
;created=1618884475;keyid="test-shared-secret" | ;created=1618884475;keyid="test-shared-secret" | |||
Signature: sig1=:fN3AMNGbx0V/cIEKkZOvLOoC3InI+lM2+gTv22x3ia8=: | Signature: sig1=:fN3AMNGbx0V/cIEKkZOvLOoC3InI+lM2+gTv22x3ia8=: | |||
B.3. TLS-Terminating Proxies | B.3. TLS-Terminating Proxies | |||
In this example, there is a TLS-terminating reverse proxy sitting in | In this example, there is a TLS-terminating reverse proxy sitting in | |||
front of the resource. The client does not sign the request but | front of the resource. The client does not sign the request but | |||
instead uses mutual TLS to make its call. The terminating proxy | instead uses mutual TLS to make its call. The terminating proxy | |||
validates the TLS stream and injects a "Client-Cert" header according | validates the TLS stream and injects a Client-Cert header according | |||
to [I-D.ietf-httpbis-client-cert-field]. By signing this header | to [I-D.ietf-httpbis-client-cert-field], and then applies a signature | |||
field, a reverse proxy can not only attest to its own validation of | to this field. By signing this header field, a reverse proxy can not | |||
the initial request but also authenticate itself to the backend | only attest to its own validation of the initial request's TLS | |||
system independently of the client's actions. The client makes the | parameters but also authenticate itself to the backend system | |||
following request to the TLS terminating proxy using mutual TLS: | 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 | POST /foo?Param=value&pet=Dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
The proxy processes the TLS connection and extracts the client's TLS | The proxy processes the TLS connection and extracts the client's TLS | |||
certificate to a "Client-Cert" header field and passes it along to | certificate to a Client-Cert header field and passes it along to the | |||
the internal service hosted at "service.internal.example". This | internal service hosted at service.internal.example. This results in | |||
results in the following unsigned request: | the following unsigned request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?Param=value&pet=Dog HTTP/1.1 | POST /foo?Param=value&pet=Dog HTTP/1.1 | |||
Host: service.internal.example | Host: service.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | |||
BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | |||
skipping to change at page 54, line 26 ¶ | skipping to change at page 65, line 26 ¶ | |||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | |||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | |||
8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | |||
4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | |||
bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | |||
{"hello": "world"} | {"hello": "world"} | |||
Without a signature, the internal service would need to trust that | Without a signature, the internal service would need to trust that | |||
the incoming connection has the right information. By signing the | the incoming connection has the right information. By signing the | |||
"Client-Cert" header and other portions of the internal request, the | Client-Cert header and other portions of the internal request, the | |||
internal service can be assured that the correct party, the trusted | internal service can be assured that the correct party, the trusted | |||
proxy, has processed the request and presented it to the correct | proxy, has processed the request and presented it to the correct | |||
service. The proxy's signature input consists of the following: | service. The proxy's signature input consists of the following: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@path": /foo | "@path": /foo | |||
"@query": Param=value&pet=Dog | "@query": Param=value&pet=Dog | |||
"@method": POST | "@method": POST | |||
"@authority": service.internal.example | "@authority": service.internal.example | |||
skipping to change at page 55, line 45 ¶ | skipping to change at page 66, line 45 ¶ | |||
The internal service can validate the proxy's signature and therefore | The internal service can validate the proxy's signature and therefore | |||
be able to trust that the client's certificate has been appropriately | be able to trust that the client's certificate has been appropriately | |||
processed. | processed. | |||
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 specification | |||
also includes contributions from the draft-oauth-signed-http-request | ||||
internet draft and other similar efforts. | ||||
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 | |||
predecessors (in alphabetical order): Mark Adamcin, Mark Allen, Paul | predecessors (in alphabetical order): Mark Adamcin, Mark Allen, Paul | |||
Annesley, Karl Boehlmark, Stephane Bortzmeyer, Sarven Capadisli, Liam | Annesley, Karl Böhlmark, Stéphane Bortzmeyer, Sarven Capadisli, Liam | |||
Dennehy, ductm54, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, | Dennehy, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, Andrey | |||
Andrey Kislyuk, Adam Knight, Dave Lehn, Dave Longley, Ilari | Kislyuk, Adam Knight, Dave Lehn, Dave Longley, Ilari Liusvaara, James | |||
Liusvaara, James H. Manger, Kathleen Moriarty, Mark Nottingham, Yoav | H. Manger, Kathleen Moriarty, Mark Nottingham, Yoav Nir, Adrian | |||
Nir, Adrian Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, | Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, Michael | |||
Michael Richardson, Wojciech Rygielski, Adam Scarr, Cory J. Slep, | Richardson, Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk | |||
Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey | 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 | |||
- -07 | ||||
o Added security and privacy considerations. | ||||
o Added pointers to algorithm values from definition sections. | ||||
o Expanded IANA registry sections. | ||||
o Clarified that the signing and verification algorithms take | ||||
application requirements as inputs. | ||||
o Defined "signature targets" of request, response, and | ||||
related-response for specialty components. | ||||
- -06 | - -06 | |||
o Updated language for message components, including | o Updated language for message components, including | |||
identifiers and values. | identifiers and values. | |||
o Clarified that Signature-Input and Signature are fields | o Clarified that Signature-Input and Signature are fields | |||
which can be used as headers or trailers. | which can be used as headers or trailers. | |||
o Add "Accept-Signature" field and semantics for signature | o Add "Accept-Signature" field and semantics for signature | |||
negotiation. | negotiation. | |||
skipping to change at page 57, line 29 ¶ | skipping to change at page 68, line 44 ¶ | |||
o Define serialization values for signature-input header based | o Define serialization values for signature-input header based | |||
on signature input. | on signature input. | |||
- -02 | - -02 | |||
o Removed editorial comments on document sources. | o Removed editorial comments on document sources. | |||
o Removed in-document issues list in favor of tracked issues. | o Removed in-document issues list in favor of tracked issues. | |||
o Replaced unstructured "Signature" header with "Signature- | o Replaced unstructured Signature header with Signature-Input | |||
Input" and "Signature" Dictionary Structured Header Fields. | and Signature Dictionary Structured Header Fields. | |||
o Defined content identifiers for individual Dictionary | o Defined content identifiers for individual Dictionary | |||
members, e.g., ""x-dictionary-field";key=member-name". | members, e.g., "x-dictionary-field";key=member-name. | |||
o Defined content identifiers for first N members of a List, | o Defined content identifiers for first N members of a List, | |||
e.g., ""x-list-field":prefix=4". | e.g., "x-list-field":prefix=4. | |||
o Fixed up examples. | o Fixed up examples. | |||
o Updated introduction now that it's adopted. | o Updated introduction now that it's adopted. | |||
o Defined specialty content identifiers and a means to extend | o Defined specialty content identifiers and a means to extend | |||
them. | them. | |||
o Required signature parameters to be included in signature. | o Required signature parameters to be included in signature. | |||
End of changes. 293 change blocks. | ||||
769 lines changed or deleted | 1337 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/ |