draft-ietf-httpbis-message-signatures-08.txt | draft-ietf-httpbis-message-signatures-09.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: 1 August 2022 Bespoke Engineering | Expires: 7 September 2022 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
28 January 2022 | 6 March 2022 | |||
HTTP Message Signatures | HTTP Message Signatures | |||
draft-ietf-httpbis-message-signatures-08 | draft-ietf-httpbis-message-signatures-09 | |||
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 | |||
skipping to change at page 2, line 10 ¶ | skipping to change at page 2, line 10 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on 1 August 2022. | This Internet-Draft will expire on 7 September 2022. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2022 IETF Trust and the persons identified as the | Copyright (c) 2022 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 Revised BSD License text as | extracted from this document must include Revised BSD License text 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 Revised 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 . . . . . . . . . . . . . . 6 | 1.2. HTTP Message Transformations . . . . . . . . . . . . . . 6 | |||
1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 6 | 1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 7 | |||
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 . . . . . . . . . 10 | |||
2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | 2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 11 | |||
2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | 2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 13 | 2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 14 | |||
2.1.2. Dictionary Structured Field Members . . . . . . . . . 13 | 2.1.2. Dictionary Structured Field Members . . . . . . . . . 14 | |||
2.2. Derived Components . . . . . . . . . . . . . . . . . . . 14 | 2.2. Derived Components . . . . . . . . . . . . . . . . . . . 15 | |||
2.2.1. Signature Parameters . . . . . . . . . . . . . . . . 16 | 2.2.1. Signature Parameters . . . . . . . . . . . . . . . . 16 | |||
2.2.2. Method . . . . . . . . . . . . . . . . . . . . . . . 17 | 2.2.2. Method . . . . . . . . . . . . . . . . . . . . . . . 18 | |||
2.2.3. Target URI . . . . . . . . . . . . . . . . . . . . . 18 | 2.2.3. Target URI . . . . . . . . . . . . . . . . . . . . . 19 | |||
2.2.4. Authority . . . . . . . . . . . . . . . . . . . . . . 18 | 2.2.4. Authority . . . . . . . . . . . . . . . . . . . . . . 19 | |||
2.2.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 19 | 2.2.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
2.2.6. Request Target . . . . . . . . . . . . . . . . . . . 19 | 2.2.6. Request Target . . . . . . . . . . . . . . . . . . . 20 | |||
2.2.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 20 | 2.2.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 21 | |||
2.2.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 21 | 2.2.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 22 | |||
2.2.9. Query Parameters . . . . . . . . . . . . . . . . . . 22 | 2.2.9. Query Parameters . . . . . . . . . . . . . . . . . . 23 | |||
2.2.10. Status Code . . . . . . . . . . . . . . . . . . . . . 23 | 2.2.10. Status Code . . . . . . . . . . . . . . . . . . . . . 24 | |||
2.2.11. Request-Response Signature Binding . . . . . . . . . 23 | 2.2.11. Request-Response Signature Binding . . . . . . . . . 24 | |||
2.3. Creating the Signature Input String . . . . . . . . . . . 26 | 2.3. Creating the Signature Base . . . . . . . . . . . . . . . 27 | |||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 28 | 3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 30 | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 29 | 3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 30 | |||
3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 31 | 3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 32 | |||
3.2.1. Enforcing Application Requirements . . . . . . . . . 33 | 3.2.1. Enforcing Application Requirements . . . . . . . . . 34 | |||
3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 34 | 3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 35 | |||
3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 35 | 3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 36 | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 35 | 3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 36 | |||
3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 36 | 3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 37 | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 36 | 3.3.4. ECDSA using curve P-256 DSS and SHA-256 . . . . . . . 37 | |||
3.3.5. EdDSA using curve edwards25519 . . . . . . . . . . . 37 | 3.3.5. EdDSA using curve edwards25519 . . . . . . . . . . . 38 | |||
3.3.6. JSON Web Signature (JWS) algorithms . . . . . . . . . 38 | 3.3.6. JSON Web Signature (JWS) algorithms . . . . . . . . . 39 | |||
4. Including a Message Signature in a Message . . . . . . . . . 38 | 4. Including a Message Signature in a Message . . . . . . . . . 39 | |||
4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 38 | 4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 40 | |||
4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 39 | 4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 40 | |||
4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 40 | 4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 41 | |||
5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 43 | 5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 44 | |||
5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 44 | 5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 45 | |||
5.2. Processing an Accept-Signature . . . . . . . . . . . . . 45 | 5.2. Processing an Accept-Signature . . . . . . . . . . . . . 46 | |||
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 45 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 46 | |||
6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 46 | 6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 47 | |||
6.1.1. Registration Template . . . . . . . . . . . . . . . . 46 | 6.1.1. Registration Template . . . . . . . . . . . . . . . . 47 | |||
6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 47 | 6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 48 | |||
6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 47 | 6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 48 | |||
6.2.1. Registration Template . . . . . . . . . . . . . . . . 47 | 6.2.1. Registration Template . . . . . . . . . . . . . . . . 48 | |||
6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 48 | 6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 49 | |||
6.3. HTTP Signature Derived Component Identifiers Registry . . 49 | 6.3. HTTP Signature Derived Component Identifiers Registry . . 50 | |||
6.3.1. Registration Template . . . . . . . . . . . . . . . . 49 | 6.3.1. Registration Template . . . . . . . . . . . . . . . . 50 | |||
6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 50 | 6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 51 | |||
7. Security Considerations . . . . . . . . . . . . . . . . . . . 51 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 52 | |||
7.1. Signature Verification Skipping . . . . . . . . . . . . . 51 | 7.1. Signature Verification Skipping . . . . . . . . . . . . . 52 | |||
7.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 51 | 7.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 52 | |||
7.3. Signature Replay . . . . . . . . . . . . . . . . . . . . 52 | 7.3. Signature Replay . . . . . . . . . . . . . . . . . . . . 53 | |||
7.4. Insufficient Coverage . . . . . . . . . . . . . . . . . . 52 | 7.4. Insufficient Coverage . . . . . . . . . . . . . . . . . . 53 | |||
7.5. Cryptography and Signature Collision . . . . . . . . . . 53 | 7.5. Cryptography and Signature Collision . . . . . . . . . . 54 | |||
7.6. Key Theft . . . . . . . . . . . . . . . . . . . . . . . . 53 | 7.6. Key Theft . . . . . . . . . . . . . . . . . . . . . . . . 54 | |||
7.7. Modification of Required Message Parameters . . . . . . . 54 | 7.7. Modification of Required Message Parameters . . . . . . . 55 | |||
7.8. Mismatch of Signature Parameters from Message . . . . . . 54 | 7.8. Mismatch of Signature Parameters from Message . . . . . . 55 | |||
7.9. Multiple Signature Confusion . . . . . . . . . . . . . . 54 | 7.9. Multiple Signature Confusion . . . . . . . . . . . . . . 55 | |||
7.10. Signature Labels . . . . . . . . . . . . . . . . . . . . 55 | 7.10. Signature Labels . . . . . . . . . . . . . . . . . . . . 56 | |||
7.11. Symmetric Cryptography . . . . . . . . . . . . . . . . . 55 | 7.11. Symmetric Cryptography . . . . . . . . . . . . . . . . . 56 | |||
7.12. Canonicalization Attacks . . . . . . . . . . . . . . . . 56 | 7.12. Canonicalization Attacks . . . . . . . . . . . . . . . . 57 | |||
7.13. Key Specification Mix-Up . . . . . . . . . . . . . . . . 56 | 7.13. Key Specification Mix-Up . . . . . . . . . . . . . . . . 57 | |||
7.14. HTTP Versions and Component Ambiguity . . . . . . . . . . 56 | 7.14. HTTP Versions and Component Ambiguity . . . . . . . . . . 57 | |||
7.15. Key and Algorithm Specification Downgrades . . . . . . . 57 | 7.15. Key and Algorithm Specification Downgrades . . . . . . . 58 | |||
7.16. Parsing Structured Field Values . . . . . . . . . . . . . 57 | 7.16. Parsing Structured Field Values . . . . . . . . . . . . . 58 | |||
7.17. Choosing Message Components . . . . . . . . . . . . . . . 58 | 7.17. Choosing Message Components . . . . . . . . . . . . . . . 59 | |||
7.18. Confusing HTTP Field Names for Derived Component | 7.18. Confusing HTTP Field Names for Derived Component | |||
Identifiers . . . . . . . . . . . . . . . . . . . . . . 58 | Identifiers . . . . . . . . . . . . . . . . . . . . . . 59 | |||
7.19. Non-deterministic Signature Primitives . . . . . . . . . 59 | 7.19. Non-deterministic Signature Primitives . . . . . . . . . 60 | |||
8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 59 | 7.20. Choosing Signature Parameters and Derived Components over | |||
8.1. Identification through Keys . . . . . . . . . . . . . . . 59 | HTTP Fields . . . . . . . . . . . . . . . . . . . . . . 60 | |||
8.2. Signatures do not provide confidentiality . . . . . . . . 59 | 7.21. Semantically Equivalent Field Values . . . . . . . . . . 61 | |||
8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 60 | 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 61 | |||
8.4. Required Content . . . . . . . . . . . . . . . . . . . . 60 | 8.1. Identification through Keys . . . . . . . . . . . . . . . 62 | |||
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 60 | 8.2. Signatures do not provide confidentiality . . . . . . . . 62 | |||
9.1. Normative References . . . . . . . . . . . . . . . . . . 60 | 8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 62 | |||
9.2. Informative References . . . . . . . . . . . . . . . . . 62 | 8.4. Required Content . . . . . . . . . . . . . . . . . . . . 63 | |||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 63 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 63 | |||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 63 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 63 | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 63 | 9.2. Informative References . . . . . . . . . . . . . . . . . 65 | |||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 63 | Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 65 | |||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 64 | Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 66 | |||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 65 | B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 66 | |||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 66 | B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 66 | |||
B.1.5. Example Ed25519 Test Key . . . . . . . . . . . . . . 66 | B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 67 | |||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 66 | B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 68 | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 67 | B.1.4. Example Ed25519 Test Key . . . . . . . . . . . . . . 69 | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 68 | B.1.5. Example Shared Secret . . . . . . . . . . . . . . . . 69 | |||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 69 | B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 69 | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 70 | B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 70 | |||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 71 | B.2.2. Selective Covered Components using rsa-pss-sha512 . . 71 | |||
B.2.6. Signing a Request using ed25519 . . . . . . . . . . . 71 | B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 72 | |||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 72 | B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 73 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 74 | B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 74 | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 75 | B.2.6. Signing a Request using ed25519 . . . . . . . . . . . 74 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 78 | B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 75 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 77 | ||||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 78 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 82 | ||||
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 5, line 19 ¶ | skipping to change at page 5, line 22 ¶ | |||
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. | used to create the signature base. | |||
* Algorithms for generating and verifying signatures over HTTP | * Algorithms for generating and verifying signatures over HTTP | |||
message components using this signature input through application | message components using this signature base through application | |||
of cryptographic primitives. | 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, and for parsing attached signatures and metadata | HTTP message, and for parsing attached signatures and metadata | |||
from HTTP messages. | from HTTP messages. | |||
This document also provides a mechanism for a potential verifier to | This document also provides a mechanism for a potential verifier to | |||
signal to a potential signer that a signature is desired in one or | signal to a potential signer that a signature is desired in one or | |||
more subsequent messages. This optional negotiation mechanism can be | more subsequent messages. This optional negotiation mechanism can be | |||
used along with opportunistic or application-driven message | used along with opportunistic or application-driven message | |||
signatures by either 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 base. 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 | for a signature base, the signer and verifier must independently | |||
input from their respective versions of the message, via a mechanism | create the signature base from their respective versions of the | |||
that is resilient to safe changes that do not alter the meaning of | message, via a mechanism that is resilient to safe changes that do | |||
the message. | not alter the meaning of the message. | |||
For a variety of reasons, it is impractical to strictly define what | For a variety of reasons, it is impractical to strictly define what | |||
constitutes a safe change versus an unsafe one. Applications use | constitutes a safe change versus an unsafe one. Applications use | |||
HTTP in a wide variety of ways, and may disagree on whether a | HTTP in a wide variety of ways, and may disagree on whether a | |||
particular piece of information in a message (e.g., the body, or the | particular piece of information in a message (e.g., the body, or the | |||
Date header field) is relevant. Thus a general purpose solution must | Date header field) is relevant. Thus a general purpose solution 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 | |||
skipping to change at page 8, line 40 ¶ | skipping to change at page 9, line 4 ¶ | |||
in respect to a particular HTTP Message Signature and the HTTP | in respect to a particular HTTP Message Signature and the HTTP | |||
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 derived components (Section 2.2) that indicates | (Section 2.1) and derived components (Section 2.2) that indicates | |||
the set of message components covered by the signature, never | the set of message components covered by the signature, never | |||
including the @signature-params identifier itself. The order of | including the @signature-params identifier itself. The order of | |||
this set is preserved and communicated between the signer and | this set is preserved and communicated between the signer and | |||
verifier to facilitate reconstruction of the signature input. | verifier to facilitate reconstruction of the signature base. | |||
Signature Input: | Signature Base: | |||
The sequence of bytes processed by the cryptographic algorithm to | The sequence of bytes processed by the cryptographic algorithm to | |||
produce or verify the HTTP Message Signature. The signature input | produce or verify the HTTP Message Signature. The signature base | |||
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, defined in terms of the | verification process for the signature, defined in terms of the | |||
HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | |||
Key Material: | Key Material: | |||
The key material required to create or verify the signature. The | The key material required to create or verify the signature. The | |||
skipping to change at page 10, line 26 ¶ | skipping to change at page 10, line 41 ¶ | |||
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 base. For example, a server behind a reverse proxy would | |||
would need to know the original request URI to make use of | need to know the original request URI to make use of identifiers like | |||
identifiers like @target-uri. Additionally, an application using | @target-uri. Additionally, an application using signatures in | |||
signatures in responses would need to ensure that clients receiving | responses would need to ensure that clients receiving signed | |||
signed responses have access to all the signed portions, including | responses have access to all the signed portions, including any | |||
any portions of the request that were signed by the server. | 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, however some | application and outside the scope of this specification, however some | |||
additional considerations are discussed in Section 7. | 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 base. The | |||
string. The values for these items MUST be accessible to both the | values for these items MUST be accessible to both the signer and the | |||
signer and the verifier of the message, which means these are usually | verifier of the message, which means these are usually derived from | |||
derived from aspects of the HTTP message or signature itself. | aspects of the HTTP message or signature itself. | |||
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. | |||
skipping to change at page 11, line 33 ¶ | skipping to change at page 11, line 50 ¶ | |||
components. Component identifiers with different parameter values | components. Component identifiers with different parameter values | |||
MAY be repeated within a single list of covered components. | MAY be repeated within a single list of covered components. | |||
The component value associated with a component identifier is defined | The component value associated with a component identifier is defined | |||
by the identifier itself. Component values MUST NOT contain newline | by the identifier itself. Component values MUST NOT contain newline | |||
(\n) characters. | (\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.3. | into the signature base 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-type, | implementations MUST use lowercased field names (e.g., content-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 as a single combined value as defined in | value MUST be canonicalized as a single combined value as defined in | |||
skipping to change at page 12, line 15 ¶ | skipping to change at page 12, line 30 ¶ | |||
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. | |||
Note that since HTTP field values are not allowed to contain | Note that since HTTP field values are not allowed to contain | |||
leading and trailing whitespace, this will be a no-op in a | leading and trailing whitespace, this will be a no-op in a | |||
compliant implementation. | compliant implementation. | |||
3. Remove any obsolete line-folding within the line and replace it | 3. Remove any obsolete line-folding within the line and replace it | |||
with a single space (), as discussed in Section 5.2 of | with a single space (" "), as discussed in Section 5.2 of | |||
[MESSAGING]. Note that this behavior is specific to [MESSAGING] | [MESSAGING]. Note that this behavior is specific to [MESSAGING] | |||
and does not apply to other versions of the HTTP specification. | and does not apply to other versions of the HTTP specification. | |||
4. Concatenate the list of values together with a single comma (,) | 4. Concatenate the list of values together with a single comma (",") | |||
and a single space () between each item. | and a single space (" ") between each item. | |||
The resulting string is the canonicalized component value. | The resulting string is the canonicalized component value. | |||
Note that some HTTP fields have values with multiple valid | ||||
serializations that have equivalent semantics. Applications signing | ||||
and processing such fields MUST consider how to handle the values of | ||||
such fields to ensure that the signer and verifier can derive the | ||||
same value, as discussed in Section 7.21. | ||||
Following are non-normative examples of canonicalized values for | Following are non-normative examples of canonicalized values for | |||
header fields, given the following example HTTP message fragment: | header fields, given the following example HTTP message fragment: | |||
Host: www.example.com | Host: www.example.com | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
X-OWS-Header: Leading and trailing whitespace. | X-OWS-Header: Leading and trailing whitespace. | |||
X-Obs-Fold-Header: Obsolete | X-Obs-Fold-Header: Obsolete | |||
line folding. | line folding. | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
Example-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | |||
The following example shows canonicalized values for these example | The following example shows canonicalized values for these example | |||
header fields, presented using the signature input string format | header fields, presented using the signature base format discussed in | |||
discussed in Section 2.3: | Section 2.3: | |||
"host": www.example.com | "host": www.example.com | |||
"date": Tue, 20 Apr 2021 02:07:56 GMT | "date": Tue, 20 Apr 2021 02:07:56 GMT | |||
"x-ows-header": Leading and trailing whitespace. | "x-ows-header": Leading and trailing whitespace. | |||
"x-obs-fold-header": Obsolete line folding. | "x-obs-fold-header": Obsolete line folding. | |||
"cache-control": max-age=60, must-revalidate | "cache-control": max-age=60, must-revalidate | |||
"Example-dictionary": a=1, b=2;x=1;y=2, c=(a b c) | "example-dict": a=1, b=2;x=1;y=2, c=(a b c) | |||
Since empty HTTP header fields are allowed, they are also able to be | Since empty HTTP header fields are allowed, they are also able to be | |||
signed when present in a message. The canonicalized value is the | signed when present in a message. The canonicalized value is the | |||
empty string. This means that the following empty header: | empty string. This means that the following empty header: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
X-Empty-Header: \ | X-Empty-Header: \ | |||
Is serialized by the signature input generation algorithm | Is serialized by the signature base generation algorithm | |||
(Section 2.3) with an empty string value following the colon and | (Section 2.3) with an empty string value following the colon and | |||
space added after the content identifier. | space added after the content identifier. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"x-empty-header": \ | "x-empty-header": \ | |||
Note: these are shown here using the line wrapping algorithm in | Note: these are shown here using the line wrapping algorithm in | |||
[RFC8792] due to limitations in the document format that strips | [RFC8792] due to limitations in the document format that strips | |||
trailing spaces from diagrams. | trailing spaces from diagrams. | |||
Any HTTP field component identifiers MAY have the following | ||||
parameters in specific circumstances. | ||||
sf A boolean flag indicating that the field value is to be | ||||
canonicalized using strict encoding of the structured field value. | ||||
Section 2.1.1 | ||||
key A string parameter used to select a single member value from a | ||||
dictionary structured field. Section 2.1.2 | ||||
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 to | ([RFC8941]), the component identifier MAY include the sf parameter to | |||
indicate it is a known structured field. If this parameter is | indicate it is a known structured field. If this parameter is | |||
included with a component identifier, the HTTP field value MUST be | included with a component identifier, the HTTP field value MUST be | |||
serialized using the rules specified in Section 4 of [RFC8941] | serialized using the rules specified in Section 4 of [RFC8941] | |||
applicable to the type of the HTTP field. Note that this process | applicable to the type of the HTTP field. Note that this process | |||
will replace any optional internal whitespace with a single space | will replace any optional internal whitespace with a single space | |||
character, among other potential transformations of the value. | character, among other potential transformations of the value. | |||
For example, the following dictionary field is a valid serialization: | For example, the following dictionary field is a valid serialization: | |||
Example-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | |||
If included in the input string as-is, it would be: | If included in the input string as-is, it would be: | |||
"example-dictionary": a=1, b=2;x=1;y=2, c=(a b c) | "example-dict": a=1, b=2;x=1;y=2, c=(a b c) | |||
However, if the sf parameter is added, the value is re-serialized as | However, if the sf parameter is added, the value is re-serialized as | |||
follows: | follows: | |||
"example-dictionary";sf: a=1, b=2;x=1;y=2, c=(a b c) | "example-dict";sf: a=1, b=2;x=1;y=2, c=(a b c) | |||
The resulting string is used as the component value in Section 2.1. | The resulting string is used as the component value in Section 2.1. | |||
2.1.2. Dictionary Structured Field Members | 2.1.2. Dictionary Structured Field Members | |||
An individual member in the value of a Dictionary Structured Field is | An individual member in the value of a Dictionary Structured Field is | |||
identified by using the parameter key to indicate the member key as | identified by using the parameter key to indicate the member key as | |||
an sf-string value. | an sf-string value. | |||
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] on the member value and its parameters, | Section 4.1.2 of [RFC8941] on the member value and its parameters, | |||
without the dictionary key. | without the dictionary key. | |||
Each parameterized key for a given field MUST NOT appear more than | Each parameterized key for a given field MUST NOT appear more than | |||
once in the signature input. Parameterized keys MAY appear in any | once in the signature base. Parameterized keys MAY appear in any | |||
order. | order. | |||
If a dictionary key is named as a covered component but it does not | ||||
occur in the dictionary, this MUST cause an error in the signature | ||||
base generation. | ||||
Following are non-normative examples of canonicalized values for | Following are non-normative examples of canonicalized values for | |||
Dictionary Structured Field Members given the following example | Dictionary Structured Field Members given the following example | |||
header field, whose value is known to be a Dictionary: | header field, whose value is known to be a Dictionary: | |||
Example-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dict: a=1, b=2;x=1;y=2, c=(a b c) | |||
The following example shows canonicalized values for different | The following example shows canonicalized values for different | |||
component identifiers of this field, presented using the signature | component identifiers of this field, presented using the signature | |||
input string format discussed in Section 2.3: | base format discussed in Section 2.3: | |||
"example-dictionary";key="a": 1 | "example-dict";key="a": 1 | |||
"example-dictionary";key="b": 2;x=1;y=2 | "example-dict";key="b": 2;x=1;y=2 | |||
"example-dictionary";key="c": (a b c) | "example-dict";key="c": (a b c) | |||
Note that the value for key="c" has been re-serialized. | Note that the value for key="c" has been re-serialized. | |||
2.2. Derived Components | 2.2. Derived Components | |||
In addition to HTTP fields, there are a number of different | In addition to HTTP fields, there are a number of different | |||
components that can be derived from the control data, processing | components that can be derived from the control data, processing | |||
context, or other aspects of the HTTP message being signed. Such | context, or other aspects of the HTTP message being signed. Such | |||
derived components can be included in the signature input by defining | derived components can be included in the signature base by defining | |||
a component identifier and the derivation method for its component | a component identifier and the derivation method for its component | |||
value. | value. | |||
Derived component identifiers MUST start with the "at" @ character. | Derived component identifiers MUST start with the "at" @ character. | |||
This differentiates derived component identifiers from HTTP field | This differentiates derived component identifiers from HTTP field | |||
names, which cannot contain the @ character as per Section 5.1 of | names, which cannot contain the @ character as per Section 5.1 of | |||
[SEMANTICS]. Processors of HTTP Message Signatures MUST treat | [SEMANTICS]. Processors of HTTP Message Signatures MUST treat | |||
derived component identifiers separately from field names, as | derived component identifiers separately from field names, as | |||
discussed in Section 7.18. | discussed in Section 7.18. | |||
skipping to change at page 16, line 14 ¶ | skipping to change at page 17, line 7 ¶ | |||
2.2.1. Signature Parameters | 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 | This message component's value is REQUIRED as part of the signature | |||
input string (Section 2.3) but the component identifier MUST NOT be | base (Section 2.3) but the component identifier MUST NOT be | |||
enumerated within the set of covered components itself. | 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. | |||
skipping to change at page 16, line 50 ¶ | skipping to change at page 17, line 43 ¶ | |||
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] as | parameterized inner list using the rules in Section 4 of [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, not including the @signature-params component | components, not including the @signature-params component | |||
identifier itself. Once this order is chosen, it cannot be | identifier itself. Once this order is chosen, it cannot be | |||
changed. This order MUST be the same order as used in creating | changed. This order MUST be the same order as used in creating | |||
the signature input (Section 2.3). | the signature base (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] and append this to the output. | Section 4.1.1.1 of [RFC8941] and append this to the 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], skipping parameters | according to Section 4.1.1.2 of [RFC8941], skipping parameters | |||
skipping to change at page 19, line 11 ¶ | skipping to change at page 20, line 5 ¶ | |||
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 related-response, 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. | |||
The @authority derived component SHOULD be used instead signing the | ||||
Host header directly, see Section 7.20. | ||||
2.2.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 base. If used, the @scheme 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 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 | |||
skipping to change at page 21, line 49 ¶ | skipping to change at page 22, line 44 ¶ | |||
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 the query string is absent from the request message, the value is | ||||
the leading ? character alone: | ||||
"@query": ? | ||||
If used in a related-response, the @query component identifier refers | If used in a related-response, the @query component identifier refers | |||
to the associated component value of the request that triggered the | to the associated component value of the request that triggered the | |||
response message being signed. | response message being signed. | |||
2.2.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 [HTMLURL], the @query-params | as defined in HTMLURL, Section 5 [HTMLURL], the @query-params | |||
component identifier allows addressing of individual query | component identifier allows addressing of individual query | |||
parameters. The query parameters MUST be parsed according to | parameters. The query parameters MUST be parsed according to | |||
skipping to change at page 22, line 26 ¶ | skipping to change at page 23, line 26 ¶ | |||
occur in any order in the covered components. | 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 [HTMLURL], which is the value after percent-encoded | Section 5.1 [HTMLURL], which is the value after percent-encoded | |||
octets are decoded. Note that this value does not include any | octets are decoded. Note that this value does not include any | |||
leading ? characters, equals sign =, or separating & characters. | leading ? characters, equals sign =, or separating & characters. | |||
Named 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 query parameter is named as a covered component but it does not | |||
values of that name MUST be included in separate signature input | occur in the query parameters, this MUST cause an error in the | |||
lines in the order in which the parameters occur in the target URI. | signature base generation. | |||
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 would | Indicating the baz, qux and param named query parameters in 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 a parameter name occurs multiple times in a request, all parameter | ||||
values of that name MUST be included in separate signature base lines | ||||
in the order in which the parameters occur in the target URI. Note | ||||
that in some implementations, the order of parsed query parameters is | ||||
not stable, and this situation could lead to unexpected results. If | ||||
multiple parameters are common within an application, it is | ||||
RECOMMENDED to sign the entire query string using the @query | ||||
component identifier defined in Section 2.2.8. | ||||
If used in a related-response, the @query-params component identifier | If used in a related-response, the @query-params 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.2.10. Status Code | 2.2.10. Status Code | |||
The @status component identifier refers to the three-digit numeric | The @status component identifier refers to the three-digit numeric | |||
HTTP status code of a response message as defined in [SEMANTICS], | 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 | |||
skipping to change at page 23, line 32 ¶ | skipping to change at page 24, line 36 ¶ | |||
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.2.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 base 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 signature | The component value is the sf-binary representation of the signature | |||
value of the referenced request identified by the key parameter. | value of the referenced request identified by the key parameter. | |||
For example, when serving this signed request: | For example, when serving this signed request: | |||
skipping to change at page 24, line 38 ¶ | skipping to change at page 25, line 38 ¶ | |||
HTTP/1.1 503 Service Unavailable | HTTP/1.1 503 Service Unavailable | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 62 | Content-Length: 62 | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
To cryptographically link the response to the request, the server | To cryptographically link the response to the request, the server | |||
signs the response with its own key and includes the signature of | signs the response with its own key and includes the signature of | |||
sig1 from the request in the covered components of the response. The | sig1 from the request in the covered components of the response. The | |||
signature input string for this example is: | signature base for this example is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 503 | "@status": 503 | |||
"content-length": 62 | "content-length": 62 | |||
"content-type": application/json | "content-type": application/json | |||
"@request-response";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJR\ | "@request-response";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJR\ | |||
GziCLuD8r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVd\ | GziCLuD8r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVd\ | |||
wXyY/UkBIS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMT\ | wXyY/UkBIS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMT\ | |||
e0QE3IpWINTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuT\ | e0QE3IpWINTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuT\ | |||
skipping to change at page 26, line 5 ¶ | skipping to change at page 27, line 5 ¶ | |||
Note that the ECDSA algorithm in use here is non-deterministic, | Note that the ECDSA algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning a different signature value will be created every time the | |||
algorithm is run. The signature value provided here can be validated | algorithm is run. The signature value provided here can be validated | |||
against the given keys, but newly-generated signature values are not | against the given keys, but newly-generated signature values are not | |||
expected to match the example. See Section 7.19. | expected to match the example. See Section 7.19. | |||
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.3. Creating the Signature Input String | 2.3. Creating the Signature Base | |||
The signature input is a US-ASCII string containing the canonicalized | The signature base is a US-ASCII string containing the canonicalized | |||
HTTP message components covered by the signature. The input to the | HTTP message components covered by the signature. The input to the | |||
signature input creation algorithm is the list of covered component | signature base creation algorithm is the list of covered component | |||
identifiers and their associated values, along with any additional | identifiers and their associated values, along with any additional | |||
signature parameters. The output is the signature input string, | signature parameters. The output is the ordered set of bytes that | |||
which has the following form: | form the signature base, which conforms to the following ABNF: | |||
signature-input = *( signature-input-line LF ) signature-params-line | signature-base = *( signature-base-line LF ) signature-params-line | |||
signature-input-line = component-identifier ":" SP ( derived-component-value / field-value ) | signature-base-line = component-identifier ":" SP | |||
( derived-component-value / field-value ) | ||||
signature-params-line = DQUOTE "@signature-params" DQUOTE ":" SP inner-list | signature-params-line = DQUOTE "@signature-params" DQUOTE ":" SP inner-list | |||
To create the signature input string, the signer or verifier | To create the signature base, the signer or verifier concatenates | |||
concatenates together entries for each identifier in the signature's | together entries for each identifier in the signature's covered | |||
covered components (including their parameters) using the following | components (including their parameters) using the following | |||
algorithm: | 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. Note | serialized according to the component-identifier rule. Note | |||
that this serialization places the component identifier in | that this serialization places the component identifier in | |||
skipping to change at page 27, line 46 ¶ | skipping to change at page 28, line 48 ¶ | |||
question is known to not be a structured field or the type of | question is known to not be a structured field or the type of | |||
structured field is not known to the implementation. | structured field is not known to the implementation. | |||
* The component identifier is a dictionary member identifier that | * The component identifier is a dictionary member identifier that | |||
references a field that is not present in the message, is not a | references a field that is not present in the message, 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 or a | * The component identifier is a dictionary member identifier or a | |||
named query parameter identifier that references a member that is | named query parameter identifier that references a member that is | |||
not present in the component value, or whose value is malformed. | not present in the component value, or whose value is malformed. | |||
E.g., the identifier is "example-dictionary";key="c" and the value | E.g., the identifier is "example-dict";key="c" and the value of | |||
of the Example-Dictionary header field is a=1, b=2, which does not | the Example-Dict header field is a=1, b=2, which does not have the | |||
have the c value. | c value. | |||
In the following non-normative example, the HTTP message being signed | In the following non-normative example, the HTTP message being signed | |||
is the following request: | is the following request: | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
skipping to change at page 28, line 22 ¶ | skipping to change at page 29, line 25 ¶ | |||
{"hello": "world"} | {"hello": "world"} | |||
The covered components consist of the @method, @path, and @authority | The covered components consist of the @method, @path, and @authority | |||
derived component identifiers followed by the Content-Digest, | derived component identifiers followed by the Content-Digest, | |||
Content-Length, and Content-Type HTTP header fields, in order. The | Content-Length, and Content-Type HTTP header fields, in order. The | |||
signature parameters consist of a creation timestamp of 1618884473 | signature parameters consist of a creation timestamp of 1618884473 | |||
and a key identifier of test-key-rsa-pss. Note that no explicit alg | and a key identifier of test-key-rsa-pss. Note that no explicit alg | |||
parameter is given here since the verifier is assumed by the | parameter is given here since the verifier is assumed by the | |||
application to correctly use the RSA PSS algorithm based on the | application to correctly use the RSA PSS algorithm based on the | |||
identified key. The signature input string for this message with | identified key. The signature base for this message with these | |||
these parameters is: | parameters is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@method": POST | "@method": POST | |||
"@authority": example.com | "@authority": example.com | |||
"@path": /foo | "@path": /foo | |||
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"content-length": 18 | "content-length": 18 | |||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("@method" "@authority" "@path" \ | "@signature-params": ("@method" "@authority" "@path" \ | |||
"content-digest" "content-length" "content-type")\ | "content-digest" "content-length" "content-type")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Figure 1: Non-normative example Signature Input | Figure 1: Non-normative example Signature Base | |||
Note that the example signature input here, or anywhere else within | Note that the example signature base here, or anywhere else within | |||
this specification, does not include the final newline that ends the | this specification, does not include the final newline that ends the | |||
example. | displayed example. | |||
3. HTTP Message Signatures | 3. HTTP Message Signatures | |||
An HTTP Message Signature is a signature over a string generated from | An HTTP Message Signature is a signature over a string generated from | |||
a subset of the components of an HTTP message in addition to metadata | a subset of the components of an HTTP message in addition to metadata | |||
about the signature itself. When successfully verified against an | about the signature itself. When successfully verified against an | |||
HTTP message, an HTTP Message Signature provides cryptographic proof | HTTP message, an HTTP Message Signature provides cryptographic proof | |||
that the message is semantically equivalent to the message for which | that the message is semantically equivalent to the message for which | |||
the signature was generated, with respect to the subset of message | the signature was generated, with respect to the subset of message | |||
components that was signed. | components that was signed. | |||
skipping to change at page 30, line 8 ¶ | skipping to change at page 31, line 15 ¶ | |||
* Signers of a request SHOULD include some or all of the message | * Signers of a request SHOULD include some or all of the message | |||
control data in the covered components, such as the @method, | control data in the covered components, such as the @method, | |||
@authority, @target-uri, or some combination thereof. | @authority, @target-uri, or some combination thereof. | |||
* Signers SHOULD include the created signature metadata | * Signers SHOULD include the created signature metadata | |||
parameter to indicate when the signature was created. | parameter to indicate when the signature was created. | |||
* The @signature-params derived component identifier is not | * The @signature-params derived 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 base. 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 base using these parameters and | |||
signature parameters. (Section 2.3) | the signature base creation algorithm. (Section 2.3) | |||
6. The signer uses the HTTP_SIGN function to sign the signature | 6. The signer uses the HTTP_SIGN primitive function to sign the | |||
input with the chosen signing algorithm using the key material | signature base with the chosen signing algorithm using the key | |||
chosen by the signer. The HTTP_SIGN primitive and several | material chosen by the signer. The HTTP_SIGN primitive and | |||
concrete signing algorithms are defined in in Section 3.3. | several concrete applications of 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.3, the example signature input string is signed | example in Section 2.3, the example signature base is signed with the | |||
with the test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS | test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS algorithm | |||
algorithm described in Section 3.3.1, giving the following message | described in Section 3.3.1, giving the following message signature | |||
signature output value, encoded in Base64: | output value, encoded in Base64: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ | HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ | |||
YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ | YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ | |||
+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ | +xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ | |||
VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ | VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ | |||
E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ | E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ | |||
RalVc/g== | RalVc/g== | |||
skipping to change at page 32, line 25 ¶ | skipping to change at page 33, line 30 ¶ | |||
the verifier will use this algorithm. | the verifier will use this algorithm. | |||
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 base, using the algorithm defined in | |||
Section 2.3. The value of the @signature-params input is the | Section 2.3. The value of the @signature-params input is the | |||
value of the Signature-Input field for this signature serialized | value of the Signature-Input field for this signature serialized | |||
according to the rules described in Section 2.2.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 | |||
appropriate HTTP_VERIFY cryptographic verification algorithm to | appropriate HTTP_VERIFY cryptographic verification algorithm to | |||
the signature, recalculated signature input, key material, | the signature, recalculated signature base, key material, | |||
signature value. The HTTP_VERIFY primitive and several concrete | signature value. The HTTP_VERIFY primitive and several concrete | |||
algorithms are defined in Section 3.3. | algorithms are defined in Section 3.3. | |||
9. The results of the verification algorithm function are the final | 9. The results of the verification algorithm function are the final | |||
results of the cryptographic verification function. | results of the cryptographic verification function. | |||
If any of the above steps fail or produce an error, the signature | If any of the above steps fail or produce an error, the signature | |||
validation fails. | validation fails. | |||
For example, verifying the signature with the key sig1 of the | For example, verifying the signature with the key sig1 of the | |||
skipping to change at page 34, line 36 ¶ | skipping to change at page 35, line 36 ¶ | |||
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. | and needs of the signer and verifier. | |||
Each signature algorithm method takes as its input the signature | Each signature algorithm method takes as its input the signature base | |||
input string defined in Section 2.3 as a byte array (M), the signing | defined in Section 2.3 as a byte array (M), the signing key material | |||
key material (Ks), and outputs the signature output as a byte array | (Ks), and outputs the signature output as a byte array (S): | |||
(S): | ||||
HTTP_SIGN (M, Ks) -> S | HTTP_SIGN (M, Ks) -> S | |||
Each verification algorithm method takes as its input the | Each verification algorithm method takes as its input the | |||
recalculated signature input string defined in Section 2.3 as a byte | recalculated signature base defined in Section 2.3 as a byte array | |||
array (M), the verification key material (Kv), and the presented | (M), the verification key material (Kv), and the presented signature | |||
signature to be verified as a byte array (S) and outputs the | to be verified as a byte array (S) and outputs the verification | |||
verification result (V) as a boolean: | result (V) as a boolean: | |||
HTTP_VERIFY (M, Kv, S) -> V | HTTP_VERIFY (M, 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 explicit algorithm signature | |||
defined in Section 2.2.1, by reference to the key material, or | parameter alg defined in Section 2.2.1, by reference to the key | |||
through mutual agreement between the signer and verifier. | material, or 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) | (K, M) function [RFC8017] with the signer's private signing key (K) | |||
and the signature input string (M) (Section 2.3). The mask | and the signature base (M) (Section 2.3). The mask generation | |||
generation function is MGF1 as specified in [RFC8017] with a hash | function is MGF1 as specified in [RFC8017] with a hash function of | |||
function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. The hash | |||
The hash function (Hash) SHA-512 [RFC6234] is applied to the | function (Hash) SHA-512 [RFC6234] is applied to the signature base to | |||
signature input string to create the digest content to which the | create the digest content to which the digital signature is applied. | |||
digital signature is applied. The resulting signed content byte | The resulting signed content byte array (S) is the HTTP message | |||
array (S) is the HTTP message signature output used in Section 3.1. | signature output used in Section 3.1. | |||
To verify using this algorithm, the verifier applies the RSASSA-PSS- | To verify using this algorithm, the verifier applies the RSASSA-PSS- | |||
VERIFY ((n, e), M, S) function [RFC8017] using the public key portion | VERIFY ((n, e), M, S) function [RFC8017] using the public key portion | |||
of the verification key material ((n, e)) and the signature input | of the verification key material ((n, e)) and the signature base (M) | |||
string (M) re-created as described in Section 3.2. The mask | re-created as described in Section 3.2. The mask generation function | |||
generation function is MGF1 as specified in [RFC8017] with a hash | is MGF1 as specified in [RFC8017] with a hash function of SHA-512 | |||
function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | [RFC6234]. The salt length (sLen) is 64 bytes. The hash function | |||
The hash function (Hash) SHA-512 [RFC6234] is applied to the | (Hash) SHA-512 [RFC6234] is applied to the signature base to create | |||
signature input string to create the digest content to which the | the digest content to which the verification function is applied. | |||
verification function is applied. The verifier extracts the HTTP | The verifier extracts the HTTP message signature to be verified (S) | |||
message signature to be verified (S) as described in Section 3.2. | as described in Section 3.2. The results of the verification | |||
The results of the verification function indicate if the signature | function indicate if the signature presented is valid. | |||
presented is valid. | ||||
Note that the output of RSA PSS algorithms are non-deterministic, and | Note that the output of RSA PSS algorithms are non-deterministic, and | |||
therefore it is not correct to re-calculate a new signature on the | therefore it is not correct to re-calculate a new signature on the | |||
signature input and compare the results to an existing signature. | signature base and compare the results to an existing signature. | |||
Instead, the verification algorithm defined here needs to be used. | Instead, the verification algorithm defined here needs to be used. | |||
See Section 7.19. | See Section 7.19. | |||
Use of this algorithm can be indicated at runtime using the rsa-pss- | Use of this algorithm can be indicated at runtime using the rsa-pss- | |||
sha512 value for the alg signature parameter. | 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.3). | signing key (K) and the signature base (M) (Section 2.3). The hash | |||
The hash SHA-256 [RFC6234] is applied to the signature input string | SHA-256 [RFC6234] is applied to the signature base to create the | |||
to create the digest content to which the digital signature is | digest content to which the digital signature is applied. The | |||
applied. The resulting signed content byte array (S) is the HTTP | resulting signed content byte array (S) is the HTTP message signature | |||
message signature output used in Section 3.1. | 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 base (M) re-created as described in Section 3.2. The hash | |||
The hash function SHA-256 [RFC6234] is applied to the signature input | function SHA-256 [RFC6234] is applied to the signature base to create | |||
string to create the digest content to which the verification | the digest content to which the verification function is applied. | |||
function is applied. The verifier extracts the HTTP message | The verifier extracts the HTTP message signature to be verified (S) | |||
signature to be verified (S) as described in Section 3.2. The | as described in Section 3.2. The results of the verification | |||
results of the verification function are compared to the http message | function are compared to the http message signature to determine if | |||
signature to determine if the signature presented is valid. | the signature presented is valid. | |||
Use of this algorithm can be indicated at runtime using the rsa- | Use of this algorithm can be indicated at runtime using the rsa- | |||
v1_5-sha256 value for the alg signature parameter. | v1_5-sha256 value for the alg signature parameter. | |||
3.3.3. HMAC using SHA-256 | 3.3.3. HMAC using SHA-256 | |||
To sign and verify using this algorithm, the signer applies the HMAC | To sign and verify using this algorithm, the signer applies the HMAC | |||
function [RFC2104] with the shared signing key (K) and the signature | function [RFC2104] with the shared signing key (K) and the signature | |||
input string (text) (Section 2.3). The hash function SHA-256 | base (text) (Section 2.3). The hash function SHA-256 [RFC6234] is | |||
[RFC6234] is applied to the signature input string to create the | applied to the signature base to create the digest content to which | |||
digest content to which the HMAC is applied, giving the signature | 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 HMAC | be verified (S) as described in Section 3.2. The output of the HMAC | |||
function is compared to the value of the HTTP message signature, and | function is compared to the value of the HTTP message signature, and | |||
the results of the comparison determine the validity of the signature | the results of the comparison determine the validity of the signature | |||
presented. | presented. | |||
Use of this algorithm can be indicated at runtime using the hmac- | Use of this algorithm can be indicated at runtime using the hmac- | |||
sha256 value for the alg signature parameter. | sha256 value for the alg signature parameter. | |||
3.3.4. ECDSA using curve P-256 DSS and SHA-256 | 3.3.4. ECDSA using curve P-256 DSS and SHA-256 | |||
To sign using this algorithm, the signer applies the ECDSA algorithm | To sign using this algorithm, the signer applies the ECDSA algorithm | |||
[FIPS186-4] using curve P-256 with the signer's private signing key | [FIPS186-4] using curve P-256 with the signer's private signing key | |||
and the signature input string (Section 2.3). The hash SHA-256 | and the signature base (Section 2.3). The hash SHA-256 [RFC6234] is | |||
[RFC6234] is applied to the signature input string to create the | applied to the signature base to create the digest content to which | |||
digest content to which the digital signature is applied, (M). The | the digital signature is applied, (M). The signature algorithm | |||
signature algorithm returns two integer values, r and s. These are | returns two integer values, r and s. These are both encoded in big- | |||
both encoded in big-endian unsigned integers, zero-padded to | endian unsigned integers, zero-padded to 32-octets each. These | |||
32-octets each. These encoded values are concatenated into a single | encoded values are concatenated into a single 64-octet array | |||
64-octet array consisting of the encoded value of r followed by the | consisting of the encoded value of r followed by the encoded value of | |||
encoded value of s. The resulting concatenation of (r, s) is byte | s. The resulting concatenation of (r, s) is byte array of the HTTP | |||
array of 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 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 base re-created as | |||
as described in Section 3.2. The hash function SHA-256 [RFC6234] is | 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 base to create the digest content to which | |||
which the signature verification function is applied, (M). The | the signature verification function is applied, (M). The verifier | |||
verifier extracts the HTTP message signature to be verified (S) as | extracts the HTTP message signature to be verified (S) as described | |||
described in Section 3.2. This value is a 64-octet array consisting | in Section 3.2. This value is a 64-octet array consisting of the | |||
of the encoded values of r and s concatenated in order. These are | encoded values of r and s concatenated in order. These are both | |||
both encoded in big-endian unsigned integers, zero-padded to | encoded in big-endian unsigned integers, zero-padded to 32-octets | |||
32-octets each. The resulting signature value (r, s) is used as | each. The resulting signature value (r, s) is used as input to the | |||
input to the signature verification function. The results of the | signature verification function. The results of the verification | |||
verification function indicate if the signature presented is valid. | function indicate if the signature presented is valid. | |||
Note that the output of ECDSA algorithms are non-deterministic, and | Note that the output of ECDSA algorithms are non-deterministic, and | |||
therefore it is not correct to re-calculate a new signature on the | therefore it is not correct to re-calculate a new signature on the | |||
signature input and compare the results to an existing signature. | signature base and compare the results to an existing signature. | |||
Instead, the verification algorithm defined here needs to be used. | Instead, the verification algorithm defined here needs to be used. | |||
See Section 7.19. | See Section 7.19. | |||
Use of this algorithm can be indicated at runtime using the ecdsa- | Use of this algorithm can be indicated at runtime using the ecdsa- | |||
p256-sha256 value for the alg signature parameter. | p256-sha256 value for the alg signature parameter. | |||
3.3.5. EdDSA using curve edwards25519 | 3.3.5. EdDSA using curve edwards25519 | |||
To sign using this algorithm, the signer applies the Ed25519 | To sign using this algorithm, the signer applies the Ed25519 | |||
algorithm Section 5.1.6 of [RFC8032] with the signer's private | algorithm Section 5.1.6 of [RFC8032] with the signer's private | |||
signing key and the signature input string (Section 2.3). The | signing key and the signature base (Section 2.3). The signature base | |||
signature input string is taken as the input message (M) with no pre- | is taken as the input message (M) with no pre-hash function. The | |||
hash function. The signature is a 64-octet concatenation of R and S | signature is a 64-octet concatenation of R and S as specified in | |||
as specified in Section 5.1.6 of [RFC8032], and this is taken as a | Section 5.1.6 of [RFC8032], and this is taken as a byte array for the | |||
byte array for the HTTP message signature output used in Section 3.1. | HTTP message signature output used in Section 3.1. | |||
To verify using this algorithm, the signer applies the Ed25519 | To verify using this algorithm, the signer applies the Ed25519 | |||
algorithm Section 5.1.7 of [RFC8032] using the public key portion of | algorithm Section 5.1.7 of [RFC8032] using the public key portion of | |||
the verification key material (A) and the signature input string re- | the verification key material (A) and the signature base re-created | |||
created as described in Section 3.2. The signature input string is | as described in Section 3.2. The signature base is taken as the | |||
taken as the input message (M) with no pre-hash function. The | input message (M) with no pre-hash function. The signature to be | |||
signature to be verified is processed as the 64-octet concatenation | verified is processed as the 64-octet concatenation of R and S as | |||
of R and S as specified in Section 5.1.7 of [RFC8032]. The results | specified in Section 5.1.7 of [RFC8032]. The results of the | |||
of the verification function indicate if the signature presented is | verification function indicate if the signature presented is valid. | |||
valid. | ||||
Use of this algorithm can be indicated at runtime using the ed25519 | Use of this algorithm can be indicated at runtime using the ed25519 | |||
value for the alg signature parameter. | value for the alg signature parameter. | |||
3.3.6. JSON Web Signature (JWS) algorithms | 3.3.6. 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. | hashing algorithms to apply for both signing and verification. | |||
For both signing and verification, the HTTP messages signature input | For both signing and verification, the HTTP messages signature base | |||
string (Section 2.3) is used as the entire "JWS Signing Input". The | (Section 2.3) is used as the entire "JWS Signing Input". The JOSE | |||
JOSE Header defined in [RFC7517] is not used, and the signature input | Header defined in [RFC7517] is not used, and the signature base is | |||
string is not first encoded in Base64 before applying the algorithm. | not first encoded in Base64 before applying the algorithm. The | |||
The output of the JWS signature is taken as a byte array prior to 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 with | The JWS algorithm MUST NOT be none and MUST NOT be any algorithm 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 | JWA algorithm values from the JSON Web Signature and Encryption | |||
JOSE signing algorithms, as they can be signaled using JSON Web Keys | Algorithms Registry are not included as signature parameters. In | |||
or other mechanisms. | fact, the explicit alg signature parameter is not used at all when | |||
using JOSE signing algorithms, as the JWS algorithm can be signaled | ||||
using JSON Web Keys or other mechanisms common to JOSE | ||||
implementations. | ||||
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 this | Signature-Input and Signature HTTP fields, both defined within this | |||
specification. When attached to a message, an HTTP message signature | specification. When attached to a message, an HTTP message signature | |||
is identified by a label. This label MUST be unique within a given | is identified by a label. This label MUST be unique within a given | |||
HTTP message and MUST be used in both the Signature-Input and | HTTP message and MUST be used in both the Signature-Input 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. | |||
skipping to change at page 39, line 8 ¶ | skipping to change at page 40, line 18 ¶ | |||
[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.2.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" "@authority" \ | |||
"cache-control");created=1618884475\ | "content-digest" "cache-control");\ | |||
;keyid="test-key-rsa-pss" | created=1618884475;keyid="test-key-rsa-pss" | |||
To facilitate signature validation, the Signature-Input field value | To facilitate signature validation, the Signature-Input field value | |||
MUST contain the same serialized value used in generating the | MUST contain the same serialized value used in generating the | |||
signature input string's @signature-params value. | signature base'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 | |||
skipping to change at page 42, line 12 ¶ | skipping to change at page 43, line 12 ¶ | |||
{"hello": "world"} | {"hello": "world"} | |||
The proxy includes the client's signature value under the label sig1, | The proxy includes the client's signature value under the label sig1, | |||
which the proxy signs in addition to the Forwarded header. Note that | which the proxy signs in addition to the Forwarded header. Note that | |||
since the client's signature already covers the client's Signature- | since the client's signature already covers the client's Signature- | |||
Input value for sig1, this value is transitively covered by the | Input value for sig1, this value is transitively covered by the | |||
proxy's signature and need not be added explicitly. The proxy | proxy's signature and need not be added explicitly. The proxy | |||
identifies its own key and algorithm and, in this example, includes | identifies its own key and algorithm and, in this example, includes | |||
an expiration for the signature to indicate to downstream systems | an expiration for the signature to indicate to downstream systems | |||
that the proxy will not vouch for this signed message past this short | that the proxy will not vouch for this signed message past this short | |||
time window. This results in a signature input string of: | time window. This results in a signature base of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"signature";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8\ | "signature";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8\ | |||
r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkB\ | r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkB\ | |||
IS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpW\ | IS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpW\ | |||
INTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2T\ | INTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2T\ | |||
r65+BXeTG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZEl\ | r65+BXeTG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZEl\ | |||
YyUKaAIjZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | YyUKaAIjZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | |||
"forwarded": for=192.0.2.123 | "forwarded": for=192.0.2.123 | |||
skipping to change at page 44, line 42 ¶ | skipping to change at page 45, line 42 ¶ | |||
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.2.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" "@authority" \ | |||
"cache-control")\ | "content-digest" "cache-control");\ | |||
;keyid="test-key-rsa-pss" | created=1618884475;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: | |||
skipping to change at page 46, line 45 ¶ | skipping to change at page 47, line 45 ¶ | |||
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. | base. | |||
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 | |||
+===================+========+===================+===============+ | +===================+========+===================+===============+ | |||
skipping to change at page 53, line 17 ¶ | skipping to change at page 54, line 17 ¶ | |||
the application and deployment. The verifier should only trust | the application and deployment. The verifier should only trust | |||
message components that have been signed. Verifiers could also strip | message components that have been signed. Verifiers could also strip | |||
out any sensitive unsigned portions of the message before processing | out any sensitive unsigned portions of the message before processing | |||
of the message continues. | of the message continues. | |||
7.5. Cryptography and Signature Collision | 7.5. Cryptography and Signature Collision | |||
The HTTP Message Signatures specification does not define any of its | The HTTP Message Signatures specification does not define any of its | |||
own cryptographic primitives, and instead relies on other | own cryptographic primitives, and instead relies on other | |||
specifications to define such elements. If the signature algorithm | specifications to define such elements. If the signature algorithm | |||
or key used to process the signature input string is vulnerable to | or key used to process the signature base is vulnerable to any | |||
any attacks, the resulting signature will also be susceptible to | attacks, the resulting signature will also be susceptible to these | |||
these same attacks. | same attacks. | |||
A common attack against signature systems is to force a signature | A common attack against signature systems is to force a signature | |||
collision, where the same signature value successfully verifies | collision, where the same signature value successfully verifies | |||
against multiple different inputs. Since this specification relies | against multiple different inputs. Since this specification relies | |||
on reconstruction of the input string based on an HTTP message, and | on reconstruction of the input string based on an HTTP message, and | |||
the list of components signed is fixed in the signature, it is | the list of components signed is fixed in the signature, it is | |||
difficult but not impossible for an attacker to effect such a | difficult but not impossible for an attacker to effect such a | |||
collision. An attacker would need to manipulate the HTTP message and | collision. An attacker would need to manipulate the HTTP message and | |||
its covered message components in order to make the collision | its covered message components in order to make the collision | |||
effective. | effective. | |||
To counter this, only vetted keys and signature algorithms should be | To counter this, only vetted keys and signature algorithms should be | |||
used to sign HTTP messages. The HTTP Message Signatures Algorithm | used to sign HTTP messages. The HTTP Message Signatures Algorithm | |||
Registry is one source of potential trusted algorithms. | Registry is one source of potential trusted algorithms. | |||
While it is possible for an attacker to substitute the signature | While it is possible for an attacker to substitute the signature | |||
parameters value or the signature value separately, the signature | parameters value or the signature value separately, the signature | |||
input generation algorithm (Section 2.3) always covers the signature | base generation algorithm (Section 2.3) always covers the signature | |||
parameters as the final value in the input string using a | parameters as the final value in the input string using a | |||
deterministic serialization method. This step strongly binds the | deterministic serialization method. This step strongly binds the | |||
signature input with the signature value in a way that makes it much | signature base with the signature value in a way that makes it much | |||
more difficult for an attacker to perform a partial substitution on | more difficult for an attacker to perform a partial substitution on | |||
the signature inputs. | the signature bases. | |||
7.6. Key Theft | 7.6. Key Theft | |||
A foundational assumption of signature-based cryptographic systems is | A foundational assumption of signature-based cryptographic systems is | |||
that the signing key is not compromised by an attacker. If the keys | that the signing key is not compromised by an attacker. If the keys | |||
used to sign the message are exfiltrated or stolen, the attacker will | used to sign the message are exfiltrated or stolen, the attacker will | |||
be able to generate their own signatures using those keys. As a | be able to generate their own signatures using those keys. As a | |||
consequence, signers have to protect any signing key material from | consequence, signers have to protect any signing key material from | |||
exfiltration, capture, and use by an attacker. | exfiltration, capture, and use by an attacker. | |||
skipping to change at page 54, line 22 ¶ | skipping to change at page 55, line 22 ¶ | |||
7.7. Modification of Required Message Parameters | 7.7. Modification of Required Message Parameters | |||
An attacker could effectively deny a service by modifying an | An attacker could effectively deny a service by modifying an | |||
otherwise benign signature parameter or signed message component. | otherwise benign signature parameter or signed message component. | |||
While rejecting a modified message is the desired behavior, | While rejecting a modified message is the desired behavior, | |||
consistently failing signatures could lead to the verifier turning | consistently failing signatures could lead to the verifier turning | |||
off signature checking in order to make systems work again (see | off signature checking in order to make systems work again (see | |||
Section 7.1). | Section 7.1). | |||
If such failures are common within an application, the signer and | If such failures are common within an application, the signer and | |||
verifier should compare their generated signature input strings with | verifier should compare their generated signature bases with each | |||
each other to determine which part of the message is being modified. | other to determine which part of the message is being modified. | |||
However, the signer and verifier should not remove the requirement to | However, the signer and verifier should not remove the requirement to | |||
sign the modified component when it is suspected an attacker is | sign the modified component when it is suspected an attacker is | |||
modifying the component. | modifying the component. | |||
7.8. Mismatch of Signature Parameters from Message | 7.8. Mismatch of Signature Parameters from Message | |||
The verifier needs to make sure that the signed message components | The verifier needs to make sure that the signed message components | |||
match those in the message itself. This specification encourages | match those in the message itself. This specification encourages | |||
this by requiring the verifier to derive these values from the | this by requiring the verifier to derive these values from the | |||
message, but lazy cacheing or conveyance of the signature input | message, but lazy cacheing or conveyance of the signature base to a | |||
string to a processing system could lead to downstream verifiers | processing system could lead to downstream verifiers accepting a | |||
accepting a message that does not match the presented signature. | message that does not match the presented signature. | |||
7.9. Multiple Signature Confusion | 7.9. Multiple Signature Confusion | |||
Since multiple signatures can be applied to one message | Since multiple signatures can be applied to one message | |||
(Section 4.3), it is possible for an attacker to attach their own | (Section 4.3), it is possible for an attacker to attach their own | |||
signature to a captured message without modifying existing | signature to a captured message without modifying existing | |||
signatures. This new signature could be completely valid based on | signatures. This new signature could be completely valid based on | |||
the attacker's key, or it could be an invalid signature for any | the attacker's key, or it could be an invalid signature for any | |||
number of reasons. Each of these situations need to be accounted | number of reasons. Each of these situations need to be accounted | |||
for. | for. | |||
skipping to change at page 56, line 7 ¶ | skipping to change at page 57, line 7 ¶ | |||
derivation functions that allow the signer and verifier to agree on | derivation functions that allow the signer and verifier to agree on | |||
unique keys for each message without having to share the key values | unique keys for each message without having to share the key values | |||
directly. | directly. | |||
Additionally, if symmetric algorithms are allowed within a system, | Additionally, if symmetric algorithms are allowed within a system, | |||
special care must be taken to avoid key downgrade attacks | special care must be taken to avoid key downgrade attacks | |||
(Section 7.15). | (Section 7.15). | |||
7.12. Canonicalization Attacks | 7.12. Canonicalization Attacks | |||
Any ambiguity in the generation of the signature input string could | Any ambiguity in the generation of the signature base could provide | |||
provide an attacker with leverage to substitute or break a signature | an attacker with leverage to substitute or break a signature on a | |||
on a message. Some message component values, particularly HTTP field | message. Some message component values, particularly HTTP field | |||
values, are potentially susceptible to broken implementations that | values, are potentially susceptible to broken implementations that | |||
could lead to unexpected and insecure behavior. Naive | could lead to unexpected and insecure behavior. Naive | |||
implementations of this specification might implement HTTP field | implementations of this specification might implement HTTP field | |||
processing by taking the single value of a field and using it as the | processing by taking the single value of a field and using it as the | |||
direct component value without processing it appropriately. | direct component value without processing it appropriately. | |||
For example, if the handling of obs-fold field values does not remove | For example, if the handling of obs-fold field values does not remove | |||
the internal line folding and whitespace, additional newlines could | the internal line folding and whitespace, additional newlines could | |||
be introduced into the signature input string by the signer, | be introduced into the signature base by the signer, providing a | |||
providing a potential place for an attacker to mount a signature | potential place for an attacker to mount a signature collision | |||
collision (Section 7.5) attack. Alternatively, if header fields that | (Section 7.5) attack. Alternatively, if header fields that appear | |||
appear multiple times are not joined into a single string value, as | multiple times are not joined into a single string value, as is | |||
is required by this specification, similar attacks can be mounted as | required by this specification, similar attacks can be mounted as a | |||
a signed component value would show up in the input string more than | signed component value would show up in the input string more than | |||
once and could be substituted or otherwise attacked in this way. | once and could be substituted or otherwise attacked in this way. | |||
To counter this, the entire field processing algorithm needs to be | To counter this, the entire field processing algorithm needs to be | |||
implemented by all implementations of signers and verifiers. | implemented by all implementations of signers and verifiers. | |||
7.13. Key Specification Mix-Up | 7.13. Key Specification Mix-Up | |||
The existence of a valid signature on an HTTP message is not | The existence of a valid signature on an HTTP message is not | |||
sufficient to prove that the message has been signed by the | sufficient to prove that the message has been signed by the | |||
appropriate party. It is up to the verifier to ensure that a given | appropriate party. It is up to the verifier to ensure that a given | |||
skipping to change at page 57, line 47 ¶ | skipping to change at page 58, line 47 ¶ | |||
structured field values (Section 2.1.1), referencing members of a | structured field values (Section 2.1.1), referencing members of a | |||
dictionary structured field (Section 2.1.2), and processing the | dictionary structured field (Section 2.1.2), and processing the | |||
@signature-input value when verifying a signature (Section 3.2). | @signature-input value when verifying a signature (Section 3.2). | |||
While structured field values are designed to be relatively simple to | While structured field values are designed to be relatively simple to | |||
parse, a naive or broken implementation of such a parser could lead | parse, a naive or broken implementation of such a parser could lead | |||
to subtle attack surfaces being exposed in the implementation. | to subtle attack surfaces being exposed in the implementation. | |||
For example, if a buggy parser of the @signature-input value does not | For example, if a buggy parser of the @signature-input value does not | |||
enforce proper closing of quotes around string values within the list | enforce proper closing of quotes around string values within the list | |||
of component identifiers, an attacker could take advantage of this | of component identifiers, an attacker could take advantage of this | |||
and inject additional content into the signature input string through | and inject additional content into the signature base through | |||
manipulating the Signature-Input field value on a message. | manipulating the Signature-Input field value on a message. | |||
To counteract this, implementations should use fully compliant and | To counteract this, implementations should use fully compliant and | |||
trusted parsers for all structured field processing, both on the | trusted parsers for all structured field processing, both on the | |||
signer and verifier side. | signer and verifier side. | |||
7.17. Choosing Message Components | 7.17. Choosing Message Components | |||
Applications of HTTP Message Signatures need to decide which message | Applications of HTTP Message Signatures need to decide which message | |||
components will be covered by the signature. Depending on the | components will be covered by the signature. Depending on the | |||
skipping to change at page 59, line 12 ¶ | skipping to change at page 60, line 12 ¶ | |||
it be taken from the fields of the message. The algorithm discussed | it be taken from the fields of the message. The algorithm discussed | |||
in Section 2.3 provides a safe order of operations. | in Section 2.3 provides a safe order of operations. | |||
7.19. Non-deterministic Signature Primitives | 7.19. Non-deterministic Signature Primitives | |||
Some cryptographic primitives such as RSA PSS and ECDSA have non- | Some cryptographic primitives such as RSA PSS and ECDSA have non- | |||
deterministic outputs, which include some amount of entropy within | deterministic outputs, which include some amount of entropy within | |||
the algorithm. For such algorithms, multiple signatures generated in | the algorithm. For such algorithms, multiple signatures generated in | |||
succession will not match. A lazy implementation of a verifier could | succession will not match. A lazy implementation of a verifier could | |||
ignore this distinction and simply check for the same value being | ignore this distinction and simply check for the same value being | |||
created by re-signing the signature input. Such an implementation | created by re-signing the signature base. Such an implementation | |||
would work for deterministic algorithms such as HMAC and EdDSA but | would work for deterministic algorithms such as HMAC and EdDSA but | |||
fail to verify valid signatures made using non-deterministic | fail to verify valid signatures made using non-deterministic | |||
algorithms. It is therefore important that a verifier always use the | algorithms. It is therefore important that a verifier always use the | |||
correctly-defined verification function for the algorithm in question | correctly-defined verification function for the algorithm in question | |||
and not do a simple comparison. | and not do a simple comparison. | |||
8. Privacy Considerations | 7.20. Choosing Signature Parameters and Derived Components over HTTP | |||
Fields | ||||
Some HTTP fields have values and interpretations that are similar to | ||||
HTTP signature parameters or derived components. In most cases, it | ||||
is more desirable to sign the non-field alternative. In particular, | ||||
the following fields should usually not be included in the signature | ||||
unless the application specifically requires it: | ||||
"date" The "date" field value represents the timestamp of the HTTP | ||||
message. However, the creation time of the signature itself is | ||||
encoded in the created signature parameter. These two values can | ||||
be different, depending on how the signature and the HTTP message | ||||
are created and serialized. Applications processing signatures | ||||
for valid time windows should use the created signature parameter | ||||
for such calculations. An application could also put limits on | ||||
how much skew there is between the "date" field and the created | ||||
signature parameter, in order to limit the application of a | ||||
generated signature to different HTTP messages. See also | ||||
Section 7.3 and Section 7.4. | ||||
"host" The "host" header field is specific to HTTP 1.1, and its | ||||
functionality is subsumed by the "@authority" derived component, | ||||
defined in Section 2.2.4. In order to preserve the value across | ||||
different HTTP versions, applications should always use the | ||||
"@authority" derived component. | ||||
7.21. Semantically Equivalent Field Values | ||||
The signature base generation algorithm (Section 2.3) uses the value | ||||
of an HTTP field as its component value. In the common case, this | ||||
amounts to taking the actual bytes of the field value as the | ||||
component value for both the signer and verifier. However, some | ||||
field values allow for transformation of the values in semantically | ||||
equivalent ways that alter the bytes used in the value itself. For | ||||
example, a field definition can declare some or all of its value to | ||||
be case-insensitive, or to have special handling of internal | ||||
whitespace characters. Other fields have expected transformations | ||||
from intermediaries, such as the removal of comments in the Via | ||||
header field. In such cases, a verifier could be tripped up by using | ||||
the equivalent transformed field value, which would differ from the | ||||
byte value used by the signer. The verifier would have have a | ||||
difficult time finding this class of errors since the value of the | ||||
field is still acceptable for the application, but the actual bytes | ||||
required by the signature base would not match. | ||||
When processing such fields, the signer and verifier have to agree | ||||
how to handle such transformations, if at all. One option is to not | ||||
sign problematic fields, but care must be taken to ensure that there | ||||
is still sufficient signature coverage (Section 7.4) for the | ||||
application. Another option is to define an application-specific | ||||
canonicalization value for the field before it is added to the HTTP | ||||
message, such as to always remove internal comments before signing, | ||||
or to always transform values to lowercase. Since these | ||||
transformations are applied prior to the field being used as input to | ||||
the signature base generation algorithm, the signature base will | ||||
still simply contain the byte value of the field as it appears within | ||||
the message. If the transformations were to be applied after the | ||||
value is extracted from the message but before it is added to the | ||||
signature base, different attack surfaces such as value substitution | ||||
attacks could be launched against the application. All application- | ||||
specific additional rules are outside the scope of this | ||||
specification, and by their very nature these transformations would | ||||
harm interoperability of the implementation outside of this specific | ||||
application. It is recommended that applications avoid the use of | ||||
such additional rules wherever possible. | ||||
8. Privacy Considerations | ||||
8.1. Identification through Keys | 8.1. Identification through Keys | |||
If a signer uses the same key with multiple verifiers, or uses the | If a signer uses the same key with multiple verifiers, or uses the | |||
same key over time with a single verifier, the ongoing use of that | same key over time with a single verifier, the ongoing use of that | |||
key can be used to track the signer throughout the set of verifiers | key can be used to track the signer throughout the set of verifiers | |||
that messages are sent to. Since cryptographic keys are meant to be | that messages are sent to. Since cryptographic keys are meant to be | |||
functionally unique, the use of the same key over time is a strong | functionally unique, the use of the same key over time is a strong | |||
indicator that it is the same party signing multiple messages. | indicator that it is the same party signing multiple messages. | |||
In many applications, this is a desirable trait, and it allows HTTP | In many applications, this is a desirable trait, and it allows HTTP | |||
skipping to change at page 60, line 21 ¶ | skipping to change at page 63, line 9 ¶ | |||
needed for requesting a resource. If someone knows who controls that | needed for requesting a resource. If someone knows who controls that | |||
key, a correlation can be made between the resource's existence and | key, a correlation can be made between the resource's existence and | |||
the party identified by the key. Access to such information could be | the party identified by the key. Access to such information could be | |||
used by an attacker as a means to target the legitimate owner of the | used by an attacker as a means to target the legitimate owner of the | |||
resource for further attacks. | resource for further attacks. | |||
8.4. Required Content | 8.4. Required Content | |||
A core design tenet of this specification is that all message | A core design tenet of this specification is that all message | |||
components covered by the signature need to be available to the | components covered by the signature need to be available to the | |||
verifier in order to recreate the signature input string and verify | verifier in order to recreate the signature base and verify the | |||
the signature. As a consequence, if an application of this | signature. As a consequence, if an application of this specification | |||
specification requires that a particular field be signed, the | requires that a particular field be signed, the verifier will need | |||
verifier will need access to the value of that field. | access to the value of that field. | |||
For example, in some complex systems with intermediary processors | For example, in some complex systems with intermediary processors | |||
this could cause the surprising behavior of an intermediary not being | this could cause the surprising behavior of an intermediary not being | |||
able to remove privacy-sensitive information from a message before | able to remove privacy-sensitive information from a message before | |||
forwarding it on for processing, for fear of breaking the signature. | forwarding it on for processing, for fear of breaking the signature. | |||
A possible mitigation for this specific situation would be for the | A possible mitigation for this specific situation would be for the | |||
intermediary to verify the signature itself, then modifying the | intermediary to verify the signature itself, then modifying the | |||
message to remove the privacy-sensitive information. The | message to remove the privacy-sensitive information. The | |||
intermediary can add its own signature at this point to signal to the | intermediary can add its own signature at this point to signal to the | |||
next destination that the incoming signature was validated, as is | next destination that the incoming signature was validated, as is | |||
skipping to change at page 63, line 27 ¶ | skipping to change at page 66, line 13 ¶ | |||
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 | |||
The following non-normative examples are provided as a means of | ||||
testing implementations of HTTP Message Signatures. The signed | ||||
messages given can be used to create the signature base with the | ||||
stated parameters, creating signatures using the stated algorithms | ||||
and keys. | ||||
The private keys given can be used to generate signatures, though | ||||
since several of the demonstrated algorithms are nondeterministic, | ||||
the results of a signature are expected to be different from the | ||||
exact bytes of the examples. The public keys given can be used to | ||||
validate all signed examples. | ||||
B.1. Example Keys | B.1. Example Keys | |||
This section provides cryptographic keys that are referenced in | This section provides cryptographic keys that are referenced in | |||
example signatures throughout this document. These keys MUST NOT be | example signatures throughout this document. These keys MUST NOT be | |||
used for any purpose other than testing. | used for any purpose other than testing. | |||
The key identifiers for each key are used throughout the examples in | The key identifiers for each key are used throughout the examples in | |||
this specification. It is assumed for these examples that the signer | this specification. It is assumed for these examples that the signer | |||
and verifier can unambiguously dereference all key identifiers used | and verifier can unambiguously dereference all key identifiers used | |||
here, and that the keys and algorithms used are appropriate for the | here, and that the keys and algorithms used are appropriate for the | |||
context in which the signature is presented. | context in which the signature is presented. | |||
The components for each private key in PEM format can be displayed by | ||||
executing the following OpenSSL command: | ||||
openssl pkey -text | ||||
This command was tested with all the example keys on OpenSSL version | ||||
1.1.1m. Note that some systems cannot produce or use these keys | ||||
directly, and may require additional processing. | ||||
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. This key is encoded in | |||
PEM Format, with no encryption. | ||||
-----BEGIN RSA PUBLIC KEY----- | -----BEGIN RSA PUBLIC KEY----- | |||
MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | |||
WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | |||
MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | |||
kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | |||
uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | |||
PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | |||
-----END RSA PUBLIC KEY----- | -----END RSA PUBLIC KEY----- | |||
skipping to change at page 64, line 45 ¶ | skipping to change at page 67, 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. This key is PCKS#8 | |||
encoded in PEM format, with no encryption. | ||||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 | |||
+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | +QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ | |||
oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq | |||
gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W | |||
Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 | |||
aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI | |||
2wIDAQAB | 2wIDAQAB | |||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
skipping to change at page 65, line 46 ¶ | skipping to change at page 68, line 46 ¶ | |||
NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ | NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ | |||
3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | 3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE | |||
t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND | |||
dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF | |||
S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR | |||
rOjr9w349JooGXhOxbu8nOxX | rOjr9w349JooGXhOxbu8nOxX | |||
-----END PRIVATE KEY----- | -----END PRIVATE KEY----- | |||
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 a public and private elliptical curve key pair | |||
referred to in this document as test-key-ecc-p256. | over the curve P-256, referred to in this document as `test-key-ecc- | |||
p256. This key is encoded in PEM format, with no encryption. | ||||
-----BEGIN PUBLIC KEY----- | ||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | ||||
w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | ||||
-----END PUBLIC KEY----- | ||||
-----BEGIN EC PRIVATE KEY----- | -----BEGIN EC PRIVATE KEY----- | |||
MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 | |||
AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM | |||
4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | 4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | |||
-----END EC PRIVATE KEY----- | -----END EC PRIVATE KEY----- | |||
B.1.4. Example Ed25519 Test Key | ||||
The following key is an elliptical curve key over the Edwards curve | ||||
ed25519, referred to in this document as test-key-ed25519. This key | ||||
is PCKS#8 encoded in PEM format, with no encryption. | ||||
-----BEGIN PUBLIC KEY----- | -----BEGIN PUBLIC KEY----- | |||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf | MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= | |||
w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== | ||||
-----END PUBLIC KEY----- | -----END PUBLIC KEY----- | |||
B.1.4. Example Shared Secret | -----BEGIN PRIVATE KEY----- | |||
MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF | ||||
-----END PRIVATE KEY----- | ||||
B.1.5. Example Shared Secret | ||||
The following shared secret is 64 randomly-generated bytes encoded in | The following shared secret is 64 randomly-generated bytes encoded in | |||
Base64, referred to in this document as test-shared-secret. | Base64, referred to in this document as test-shared-secret. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | |||
bmHhIDi6pcl8jsasjlTMtDQ== | bmHhIDi6pcl8jsasjlTMtDQ== | |||
B.1.5. Example Ed25519 Test Key | ||||
The following key is an elliptical curve key over the Edwards curve | ||||
ed25519, referred to in this document as test-key-edd25519. | ||||
-----BEGIN PRIVATE KEY----- | ||||
MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF | ||||
-----END PRIVATE KEY----- | ||||
-----BEGIN PUBLIC KEY----- | ||||
MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= | ||||
-----END PUBLIC KEY----- | ||||
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 | |||
skipping to change at page 67, line 33 ¶ | skipping to change at page 70, line 33 ¶ | |||
{"message": "good dog"} | {"message": "good dog"} | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 | B.2.1. Minimal Signature Using rsa-pss-sha512 | |||
This example presents a minimal signature using the rsa-pss-sha512 | This example presents a minimal signature using the rsa-pss-sha512 | |||
algorithm over test-request, covering none of the components of the | algorithm over test-request, covering none of the components of the | |||
HTTP message, but providing a timestamped signature proof of | HTTP message, but providing a timestamped signature proof of | |||
possession of the key with a signer-provided nonce. | possession of the key with a signer-provided nonce. | |||
The corresponding signature input is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ | "@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ | |||
;nonce="b3k2pp5k7z-50gnwp.yemd" | ;nonce="b3k2pp5k7z-50gnwp.yemd" | |||
This results in the following Signature-Input and Signature headers | This results in the following Signature-Input and Signature headers | |||
being added to the message under the signature label sig-b21: | being added to the message under the signature label sig-b21: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
skipping to change at page 68, line 25 ¶ | skipping to change at page 71, line 25 ¶ | |||
meaning a different signature value will be created every time the | meaning a different signature value will be created every time the | |||
algorithm is run. The signature value provided here can be validated | algorithm is run. The signature value provided here can be validated | |||
against the given keys, but newly-generated signature values are not | against the given keys, but newly-generated signature values are not | |||
expected to match the example. See Section 7.19. | expected to match the example. See Section 7.19. | |||
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 base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@authority": example.com | "@authority": example.com | |||
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"@signature-params": ("@authority" "content-digest")\ | "@signature-params": ("@authority" "content-digest")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
This results in the following Signature-Input and Signature headers | This results in the following Signature-Input and Signature headers | |||
skipping to change at page 69, line 18 ¶ | skipping to change at page 72, line 18 ¶ | |||
against the given keys, but newly-generated signature values are not | against the given keys, but newly-generated signature values are not | |||
expected to match the example. See Section 7.19. | expected to match the example. See Section 7.19. | |||
B.2.3. Full Coverage using rsa-pss-sha512 | B.2.3. Full Coverage using rsa-pss-sha512 | |||
This example covers all applicable in test-request (including the | This example covers all applicable in test-request (including the | |||
content type and length) plus many derived components, again using | content type and length) plus many derived components, again using | |||
the rsa-pss-sha512 algorithm. Note that the Host header field is not | the rsa-pss-sha512 algorithm. Note that the Host header field is not | |||
covered because the @authority derived component is included instead. | covered because the @authority derived component is included instead. | |||
The corresponding signature input is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:55 GMT | |||
"@method": POST | "@method": POST | |||
"@path": /foo | "@path": /foo | |||
"@query": param=Value&Pet=dog | "@query": ?param=Value&Pet=dog | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"content-length": 18 | "content-length": 18 | |||
"@signature-params": ("date" "@method" "@path" "@query" \ | "@signature-params": ("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "content-digest" "content-length")\ | "@authority" "content-type" "content-digest" "content-length")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
This results in the following Signature-Input and Signature headers | This results in the following Signature-Input and Signature headers | |||
being added to the message under the label sig-b23: | being added to the message under the label sig-b23: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ | Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "content-digest" "content-length")\ | "@authority" "content-type" "content-digest" "content-length")\ | |||
;created=1618884473;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Signature: sig-b23=:f9nOGJSjCdQ/t+/Mp7gpAHU7Kn1LpnWJE6W2081yRFITJob\ | Signature: sig-b23=:bbN8oArOxYoyylQQUU6QYwrTuaxLwjAC9fbY2F6SVWvh0yB\ | |||
BDODwQNxnjiIdAGstfGKuM2vlc5SyN16//K5dBLGoiaboMco4J6R0zS+8oXqD7o6K\ | iMIRGOnMYwZ/5MR6fb0Kh1rIRASVxFkeGt683+qRpRRU5p2voTp768ZrCUb38K0fU\ | |||
RpIZR/qMrFc5Bu6f6UxuoWZPfCxhs3vxL/60JbF8dcdul1b77mWyC07ZjZ9VkelBy\ | xN0O0iC59DzYx8DFll5GmydPxSmme9v6ULbMFkl+V5B1TP/yPViV7KsLNmvKiLJH1\ | |||
eF5+zN7v6Al/vnBzMS3H1NLz9dI2sw5Vb7kxQQ6CvEI9v3R30aFgWz4rCuyT0Kt3y\ | pFkh/aYA2HXXZzNBXmIkoQoLd7YfW91kE9o/CCoC1xMy7JA1ipwvKvfrs65ldmlu9\ | |||
tQvTHOBsadF66eDe641Sd6O/DgbdFibsE/+ToYopL9NlAuva42NlcFemrozvOKvGI\ | bpG6A9BmzhuzF8Eim5f8ui9eH8LZH896+QIF61ka39VBrohr9iyMUJpvRX2Zbhl5Z\ | |||
PXdAPqmng/bePoSR6DIaFbWp5aDlNSbWlcA==: | JzSRxpJyoEZAFL2FUo5fTIztsDZKEgM4cUA==: | |||
Note in this example that the value of the Date header and the value | Note in this example that the value of the Date header and the value | |||
of the created signature parameter need not be the same. This is due | of the created signature parameter need not be the same. This is due | |||
to the fact that the Date header is added when creating the HTTP | to the fact that the Date header is added when creating the HTTP | |||
Message and the created parameter is populated when creating the | Message and the created parameter is populated when creating the | |||
signature over that message, and these two times could vary. If the | signature over that message, and these two times could vary. If the | |||
Date header is covered by the signature, it is up to the verifier to | Date header is covered by the signature, it is up to the verifier to | |||
determine whether its value has to match that of the created | determine whether its value has to match that of the created | |||
parameter or not. | parameter or not. See Section 7.20 for more discussion. | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | Note that the RSA PSS algorithm in use here is non-deterministic, | |||
meaning a different signature value will be created every time the | meaning a different signature value will be created every time the | |||
algorithm is run. The signature value provided here can be validated | algorithm is run. The signature value provided here can be validated | |||
against the given keys, but newly-generated signature values are not | against the given keys, but newly-generated signature values are not | |||
expected to match the example. See Section 7.19. | expected to match the example. See Section 7.19. | |||
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-p256. | using the ecdsa-p256-sha256 algorithm and the key test-key-ecc-p256. | |||
The corresponding signature input is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 200 | "@status": 200 | |||
"content-type": application/json | "content-type": application/json | |||
"content-digest": sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6\ | "content-digest": sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6\ | |||
sNHpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==: | sNHpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==: | |||
"content-length": 23 | "content-length": 23 | |||
"@signature-params": ("@status" "content-type" "content-digest" \ | "@signature-params": ("@status" "content-type" "content-digest" \ | |||
"content-length");created=1618884473;keyid="test-key-ecc-p256" | "content-length");created=1618884473;keyid="test-key-ecc-p256" | |||
skipping to change at page 71, line 10 ¶ | skipping to change at page 74, line 10 ¶ | |||
meaning a different signature value will be created every time the | meaning a different signature value will be created every time the | |||
algorithm is run. The signature value provided here can be validated | algorithm is run. The signature value provided here can be validated | |||
against the given keys, but newly-generated signature values are not | against the given keys, but newly-generated signature values are not | |||
expected to match the example. See Section 7.19. | expected to match the example. See Section 7.19. | |||
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 base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:55 GMT | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("date" "@authority" "content-type")\ | "@signature-params": ("date" "@authority" "content-type")\ | |||
;created=1618884473;keyid="test-shared-secret" | ;created=1618884473;keyid="test-shared-secret" | |||
This results in the following Signature-Input and Signature headers | This results in the following Signature-Input and Signature headers | |||
skipping to change at page 71, line 37 ¶ | skipping to change at page 74, line 37 ¶ | |||
Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: | Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: | |||
Before using symmetric signatures in practice, see the discussion of | Before using symmetric signatures in practice, see the discussion of | |||
the security tradeoffs in Section 7.11. | the security tradeoffs in Section 7.11. | |||
B.2.6. Signing a Request using ed25519 | B.2.6. Signing a Request using ed25519 | |||
This example covers portions of the test-request using the ed25519 | This example covers portions of the test-request using the ed25519 | |||
algorithm and the key test-key-ed25519. | algorithm and the key test-key-ed25519. | |||
The corresponding signature input is: | The corresponding signature base is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | "date": Tue, 20 Apr 2021 02:07:55 GMT | |||
"@method": POST | "@method": POST | |||
"@path": /foo | "@path": /foo | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-type": application/json | |||
"content-length": 18 | "content-length": 18 | |||
"@signature-params": ("date" "@method" "@path" "@authority" \ | "@signature-params": ("date" "@method" "@path" "@authority" \ | |||
skipping to change at page 72, line 28 ¶ | skipping to change at page 75, line 28 ¶ | |||
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], and then applies a signature | to [I-D.ietf-httpbis-client-cert-field], and then applies a signature | |||
to this field. By signing this header field, a reverse proxy can not | to this field. By signing this header field, a reverse proxy can not | |||
only attest to its own validation of the initial request's TLS | only attest to its own validation of the initial request's TLS | |||
parameters but also authenticate itself to the backend system | parameters but also authenticate itself to the backend system | |||
independently of the client's actions. | independently of the client's actions. | |||
The client makes the following request to the TLS terminating proxy | The client makes the following request to the TLS terminating proxy | |||
using mutual TLS: | using mutual TLS: | |||
POST /foo?Param=value&pet=Dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
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 the | certificate to a Client-Cert header field and passes it along to the | |||
internal service hosted at service.internal.example. This results in | internal service hosted at service.internal.example. This results in | |||
skipping to change at page 73, line 29 ¶ | skipping to change at page 76, line 29 ¶ | |||
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 base consists of the following: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@path": /foo | "@path": /foo | |||
"@query": param=Value&Pet=dog | "@query": ?param=Value&Pet=dog | |||
"@method": POST | "@method": POST | |||
"@authority": service.internal.example | "@authority": service.internal.example | |||
"client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ | "client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ | |||
KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ | KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ | |||
QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ | QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ | |||
FkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXm\ | FkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXm\ | |||
ckC8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQY\ | ckC8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQY\ | |||
DVR0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8B\ | DVR0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8B\ | |||
Af8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQ\ | Af8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQ\ | |||
GV4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0\ | GV4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0\ | |||
Q6bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | Q6bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | |||
"@signature-params": ("@path" "@query" "@method" "@authority" \ | "@signature-params": ("@path" "@query" "@method" "@authority" \ | |||
"client-cert");created=1618884473;keyid="test-key-ecc-p256" | "client-cert");created=1618884473;keyid="test-key-ecc-p256" | |||
This results in the following signature: | This results in the following signature: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
aLFj9LxKArG+6IY9mfdR3e6K1zfoDJKw71fAkWROXZh34FIiWKAgshFIfBjmiU2X01u\ | xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6Mce9315T6xoklyy0y\ | |||
6YbDkRgzwyg5L9tky0w== | zhD9ah4JHRwMLOgmizw== | |||
Which results in the following signed request sent from the proxy to | Which results in the following signed request sent from the proxy to | |||
the internal service with the proxy's signature under the label ttrp: | the internal service with the proxy's signature under the label ttrp: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: service.internal.example | Host: service.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
skipping to change at page 74, line 31 ¶ | skipping to change at page 77, line 31 ¶ | |||
BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | |||
AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | |||
wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | |||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | |||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | |||
8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ | |||
4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ | |||
bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: | |||
Signature-Input: ttrp=("@path" "@query" "@method" "@authority" \ | Signature-Input: ttrp=("@path" "@query" "@method" "@authority" \ | |||
"client-cert");created=1618884473;keyid="test-key-ecc-p256" | "client-cert");created=1618884473;keyid="test-key-ecc-p256" | |||
Signature: ttrp=:aLFj9LxKArG+6IY9mfdR3e6K1zfoDJKw71fAkWROXZh34FIiWK\ | Signature: ttrp=:xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6\ | |||
AgshFIfBjmiU2X01u6YbDkRgzwyg5L9tky0w==: | Mce9315T6xoklyy0yzhD9ah4JHRwMLOgmizw==: | |||
{"hello": "world"} | {"hello": "world"} | |||
The internal service can validate the proxy's signature and therefore | The internal service can validate the proxy's signature and therefore | |||
be able to trust that the client's certificate has been appropriately | be able to trust that the client's certificate has been appropriately | |||
processed. | processed. | |||
Acknowledgements | Acknowledgements | |||
This specification was initially based on the draft-cavage-http- | This specification was initially based on the draft-cavage-http- | |||
skipping to change at page 75, line 8 ¶ | skipping to change at page 78, line 8 ¶ | |||
internet draft and other similar efforts. | 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 Böhlmark, Stéphane Bortzmeyer, Sarven Capadisli, Liam | Annesley, Karl Böhlmark, Stéphane Bortzmeyer, Sarven Capadisli, Liam | |||
Dennehy, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, Andrey | Dennehy, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, Andrey | |||
Kislyuk, Adam Knight, Dave Lehn, Dave Longley, Ilari Liusvaara, James | Kislyuk, Adam Knight, Dave Lehn, Dave Longley, Ilari Liusvaara, James | |||
H. Manger, Kathleen Moriarty, Mark Nottingham, Yoav Nir, Adrian | H. Manger, Kathleen Moriarty, Mark Nottingham, Yoav Nir, Adrian | |||
Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, Michael | Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, Michael | |||
Richardson, Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk | Richardson, Wojciech Rygielski, Rich Salz, Adam Scarr, Cory J. Slep, | |||
Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey Yasskin. | Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey | |||
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 | |||
- -09 | ||||
o Explained key formats better. | ||||
o Removed "host" and "date" from most examples. | ||||
o Fixed query component generation. | ||||
o Renamed "signature input" and "signature input string" to | ||||
"signature base". | ||||
o Added consideration for semantically equivalent field | ||||
values. | ||||
- -08 | - -08 | |||
o Editorial fixes. | o Editorial fixes. | |||
o Changed "specialty component" to "derived component". | o Changed "specialty component" to "derived component". | |||
o Expanded signature input generation and ABNF rules. | o Expanded signature input generation and ABNF rules. | |||
o Added Ed25519 algorithm. | o Added Ed25519 algorithm. | |||
End of changes. 121 change blocks. | ||||
341 lines changed or deleted | 490 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/ |