draft-ietf-httpbis-message-signatures-07.txt | draft-ietf-httpbis-message-signatures-08.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: 23 June 2022 Bespoke Engineering | Expires: 1 August 2022 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
20 December 2021 | 28 January 2022 | |||
HTTP Message Signatures | HTTP Message Signatures | |||
draft-ietf-httpbis-message-signatures-07 | draft-ietf-httpbis-message-signatures-08 | |||
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 23 June 2022. | This Internet-Draft will expire on 1 August 2022. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2021 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. | |||
skipping to change at page 2, line 36 ¶ | skipping to change at page 2, line 36 ¶ | |||
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 . . . . . . . . . . . . . . . . . . 6 | |||
1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | 1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | |||
1.5. Application of HTTP Message Signatures . . . . . . . . . 9 | 1.5. Application of HTTP Message Signatures . . . . . . . . . 9 | |||
2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | 2. HTTP Message Components . . . . . . . . . . . . . . . . . . . 10 | |||
2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | 2.1. HTTP Fields . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 12 | 2.1.1. Canonicalized Structured HTTP Fields . . . . . . . . 13 | |||
2.1.2. HTTP Field Examples . . . . . . . . . . . . . . . . . 12 | 2.1.2. Dictionary Structured Field Members . . . . . . . . . 13 | |||
2.1.3. Dictionary Structured Field Members . . . . . . . . . 12 | 2.2. Derived Components . . . . . . . . . . . . . . . . . . . 14 | |||
2.2. Specialty Components . . . . . . . . . . . . . . . . . . 13 | 2.2.1. Signature Parameters . . . . . . . . . . . . . . . . 16 | |||
2.2.1. Signature Parameters . . . . . . . . . . . . . . . . 14 | 2.2.2. Method . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
2.2.2. Method . . . . . . . . . . . . . . . . . . . . . . . 16 | 2.2.3. Target URI . . . . . . . . . . . . . . . . . . . . . 18 | |||
2.2.3. Target URI . . . . . . . . . . . . . . . . . . . . . 16 | 2.2.4. Authority . . . . . . . . . . . . . . . . . . . . . . 18 | |||
2.2.4. Authority . . . . . . . . . . . . . . . . . . . . . . 17 | 2.2.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
2.2.5. Scheme . . . . . . . . . . . . . . . . . . . . . . . 17 | 2.2.6. Request Target . . . . . . . . . . . . . . . . . . . 19 | |||
2.2.6. Request Target . . . . . . . . . . . . . . . . . . . 18 | 2.2.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
2.2.7. Path . . . . . . . . . . . . . . . . . . . . . . . . 19 | 2.2.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 21 | |||
2.2.8. Query . . . . . . . . . . . . . . . . . . . . . . . . 20 | 2.2.9. Query Parameters . . . . . . . . . . . . . . . . . . 22 | |||
2.2.9. Query Parameters . . . . . . . . . . . . . . . . . . 20 | 2.2.10. Status Code . . . . . . . . . . . . . . . . . . . . . 23 | |||
2.2.10. Status Code . . . . . . . . . . . . . . . . . . . . . 21 | 2.2.11. Request-Response Signature Binding . . . . . . . . . 23 | |||
2.2.11. Request-Response Signature Binding . . . . . . . . . 22 | 2.3. Creating the Signature Input String . . . . . . . . . . . 26 | |||
2.3. Creating the Signature Input String . . . . . . . . . . . 23 | 3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 28 | |||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 26 | 3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 29 | |||
3.1. Creating a Signature . . . . . . . . . . . . . . . . . . 26 | 3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 31 | |||
3.2. Verifying a Signature . . . . . . . . . . . . . . . . . . 28 | 3.2.1. Enforcing Application Requirements . . . . . . . . . 33 | |||
3.2.1. Enforcing Application Requirements . . . . . . . . . 30 | 3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 34 | |||
3.3. Signature Algorithm Methods . . . . . . . . . . . . . . . 31 | 3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 35 | |||
3.3.1. RSASSA-PSS using SHA-512 . . . . . . . . . . . . . . 32 | 3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 35 | |||
3.3.2. RSASSA-PKCS1-v1_5 using SHA-256 . . . . . . . . . . . 32 | 3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 36 | |||
3.3.3. HMAC using SHA-256 . . . . . . . . . . . . . . . . . 33 | 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 . . . . . . . 33 | 3.3.5. EdDSA using curve edwards25519 . . . . . . . . . . . 37 | |||
3.3.5. JSON Web Signature (JWS) algorithms . . . . . . . . . 34 | 3.3.6. JSON Web Signature (JWS) algorithms . . . . . . . . . 38 | |||
4. Including a Message Signature in a Message . . . . . . . . . 34 | 4. Including a Message Signature in a Message . . . . . . . . . 38 | |||
4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 35 | 4.1. The 'Signature-Input' HTTP Field . . . . . . . . . . . . 38 | |||
4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 35 | 4.2. The 'Signature' HTTP Field . . . . . . . . . . . . . . . 39 | |||
4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 36 | 4.3. Multiple Signatures . . . . . . . . . . . . . . . . . . . 40 | |||
5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 38 | 5. Requesting Signatures . . . . . . . . . . . . . . . . . . . . 43 | |||
5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 39 | 5.1. The Accept-Signature Field . . . . . . . . . . . . . . . 44 | |||
5.2. Processing an Accept-Signature . . . . . . . . . . . . . 40 | 5.2. Processing an Accept-Signature . . . . . . . . . . . . . 45 | |||
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 | 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 45 | |||
6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 41 | 6.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 46 | |||
6.1.1. Registration Template . . . . . . . . . . . . . . . . 41 | 6.1.1. Registration Template . . . . . . . . . . . . . . . . 46 | |||
6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 42 | 6.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 47 | |||
6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 42 | 6.2. HTTP Signature Metadata Parameters Registry . . . . . . . 47 | |||
6.2.1. Registration Template . . . . . . . . . . . . . . . . 42 | 6.2.1. Registration Template . . . . . . . . . . . . . . . . 47 | |||
6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 43 | 6.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 48 | |||
6.3. HTTP Signature Specialty Component Identifiers | 6.3. HTTP Signature Derived Component Identifiers Registry . . 49 | |||
Registry . . . . . . . . . . . . . . . . . . . . . . . . 43 | 6.3.1. Registration Template . . . . . . . . . . . . . . . . 49 | |||
6.3.1. Registration Template . . . . . . . . . . . . . . . . 44 | 6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 50 | |||
6.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 44 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 51 | |||
7. Security Considerations . . . . . . . . . . . . . . . . . . . 45 | 7.1. Signature Verification Skipping . . . . . . . . . . . . . 51 | |||
7.1. Signature Verification Skipping . . . . . . . . . . . . . 46 | 7.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 51 | |||
7.2. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 46 | 7.3. Signature Replay . . . . . . . . . . . . . . . . . . . . 52 | |||
7.3. Signature Replay . . . . . . . . . . . . . . . . . . . . 47 | 7.4. Insufficient Coverage . . . . . . . . . . . . . . . . . . 52 | |||
7.4. Insufficient Coverage . . . . . . . . . . . . . . . . . . 47 | 7.5. Cryptography and Signature Collision . . . . . . . . . . 53 | |||
7.5. Cryptography and Signature Collision . . . . . . . . . . 48 | 7.6. Key Theft . . . . . . . . . . . . . . . . . . . . . . . . 53 | |||
7.6. Key Theft . . . . . . . . . . . . . . . . . . . . . . . . 48 | 7.7. Modification of Required Message Parameters . . . . . . . 54 | |||
7.7. Modification of Required Message Parameters . . . . . . . 49 | 7.8. Mismatch of Signature Parameters from Message . . . . . . 54 | |||
7.8. Mismatch of Signature Parameters from Message . . . . . . 49 | 7.9. Multiple Signature Confusion . . . . . . . . . . . . . . 54 | |||
7.9. Multiple Signature Confusion . . . . . . . . . . . . . . 49 | 7.10. Signature Labels . . . . . . . . . . . . . . . . . . . . 55 | |||
7.10. Signature Labels . . . . . . . . . . . . . . . . . . . . 50 | 7.11. Symmetric Cryptography . . . . . . . . . . . . . . . . . 55 | |||
7.11. Symmetric Cryptography . . . . . . . . . . . . . . . . . 50 | 7.12. Canonicalization Attacks . . . . . . . . . . . . . . . . 56 | |||
7.12. Canonicalization Attacks . . . . . . . . . . . . . . . . 50 | 7.13. Key Specification Mix-Up . . . . . . . . . . . . . . . . 56 | |||
7.13. Key Specification Mix-Up . . . . . . . . . . . . . . . . 51 | 7.14. HTTP Versions and Component Ambiguity . . . . . . . . . . 56 | |||
7.14. HTTP Versions and Component Ambiguity . . . . . . . . . . 51 | 7.15. Key and Algorithm Specification Downgrades . . . . . . . 57 | |||
7.15. Key and Algorithm Specification Downgrades . . . . . . . 52 | 7.16. Parsing Structured Field Values . . . . . . . . . . . . . 57 | |||
7.16. Parsing Structured Field Values . . . . . . . . . . . . . 52 | 7.17. Choosing Message Components . . . . . . . . . . . . . . . 58 | |||
7.17. Choosing Message Components . . . . . . . . . . . . . . . 53 | 7.18. Confusing HTTP Field Names for Derived Component | |||
8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 53 | Identifiers . . . . . . . . . . . . . . . . . . . . . . 58 | |||
8.1. Identification through Keys . . . . . . . . . . . . . . . 53 | 7.19. Non-deterministic Signature Primitives . . . . . . . . . 59 | |||
8.2. Signatures do not provide confidentiality . . . . . . . . 54 | 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 59 | |||
8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 54 | 8.1. Identification through Keys . . . . . . . . . . . . . . . 59 | |||
8.4. Required Content . . . . . . . . . . . . . . . . . . . . 54 | 8.2. Signatures do not provide confidentiality . . . . . . . . 59 | |||
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 54 | 8.3. Oracles . . . . . . . . . . . . . . . . . . . . . . . . . 60 | |||
9.1. Normative References . . . . . . . . . . . . . . . . . . 54 | 8.4. Required Content . . . . . . . . . . . . . . . . . . . . 60 | |||
9.2. Informative References . . . . . . . . . . . . . . . . . 56 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 60 | |||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 57 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 60 | |||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 57 | 9.2. Informative References . . . . . . . . . . . . . . . . . 62 | |||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 57 | Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 63 | |||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 57 | Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 63 | |||
B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 58 | B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 63 | |||
B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 59 | B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 63 | |||
B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 60 | B.1.2. Example RSA PSS Key . . . . . . . . . . . . . . . . . 64 | |||
B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 60 | B.1.3. Example ECC P-256 Test Key . . . . . . . . . . . . . 65 | |||
B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 61 | B.1.4. Example Shared Secret . . . . . . . . . . . . . . . . 66 | |||
B.2.2. Selective Covered Components using rsa-pss-sha512 . . 61 | B.1.5. Example Ed25519 Test Key . . . . . . . . . . . . . . 66 | |||
B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 62 | B.2. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 66 | |||
B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 63 | B.2.1. Minimal Signature Using rsa-pss-sha512 . . . . . . . 67 | |||
B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 63 | B.2.2. Selective Covered Components using rsa-pss-sha512 . . 68 | |||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 64 | B.2.3. Full Coverage using rsa-pss-sha512 . . . . . . . . . 69 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 66 | B.2.4. Signing a Response using ecdsa-p256-sha256 . . . . . 70 | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 67 | B.2.5. Signing a Request using hmac-sha256 . . . . . . . . . 71 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 70 | B.2.6. Signing a Request using ed25519 . . . . . . . . . . . 71 | |||
B.3. TLS-Terminating Proxies . . . . . . . . . . . . . . . . . 72 | ||||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 74 | ||||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 75 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 78 | ||||
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 8, line 37 ¶ | skipping to change at page 8, line 41 ¶ | |||
Message it applies to. | Message it applies to. | |||
HTTP Message Component Value: | HTTP Message Component Value: | |||
The value associated with a given component identifier within the | The value associated with a given component identifier within the | |||
context of a particular HTTP Message. Component values are | context of a particular HTTP Message. Component values are | |||
derived from the HTTP Message and are usually subject to a | derived from the HTTP Message and are usually subject to a | |||
canonicalization process. | canonicalization process. | |||
Covered Components: | Covered Components: | |||
An ordered set of HTTP message component identifiers for fields | An ordered set of HTTP message component identifiers for fields | |||
(Section 2.1) and specialty components (Section 2.2) that | (Section 2.1) and derived components (Section 2.2) that indicates | |||
indicates the set of message components covered by the signature, | the set of message components covered by the signature, never | |||
not including the @signature-params specialty identifier itself. | including the @signature-params identifier itself. The order of | |||
The order of this set is preserved and communicated between the | this set is preserved and communicated between the signer and | |||
signer and verifier to facilitate reconstruction of the signature | verifier to facilitate reconstruction of the signature input. | |||
input. | ||||
Signature Input: | Signature Input: | |||
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 input | |||
is generated by the signer and verifier using the covered | is generated by the signer and verifier using the covered | |||
components set and the HTTP Message. | components set and the HTTP Message. | |||
HTTP Message Signature Algorithm: | HTTP Message Signature Algorithm: | |||
A cryptographic algorithm that describes the signing and | A cryptographic algorithm that describes the signing and | |||
verification process for the signature, defined in terms of the | verification process for the signature, defined in terms of the | |||
HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | HTTP_SIGN and HTTP_VERIFY primitives described in Section 3.3. | |||
Key Material: | Key Material: | |||
The key material required to create or verify the signature. The | The key material required to create or verify the signature. The | |||
key material is often identified with an explicit key identifier, | key material is often identified with an explicit key identifier, | |||
allowing the signer to indicate to the verifier which key was | allowing the signer to indicate to the verifier which key was | |||
used. | used. | |||
skipping to change at page 11, line 21 ¶ | skipping to change at page 11, line 21 ¶ | |||
an sf-string value and MAY define parameters which are included using | an sf-string value and MAY define parameters which are included using | |||
the parameters rule. | the parameters rule. | |||
component-identifier = sf-string parameters | component-identifier = sf-string parameters | |||
Note that this means the serialization of the component identifier | Note that this means the serialization of the component identifier | |||
itself is encased in double quotes, with parameters following as a | itself is encased in double quotes, with parameters following as a | |||
semicolon-separated list, such as "cache-control", "date", or | semicolon-separated list, such as "cache-control", "date", or | |||
"@signature-params". | "@signature-params". | |||
Component identifiers including their parameters MUST NOT be repeated | Component identifiers, including component identifiers with | |||
within a single list of covered components. | parameters, MUST NOT be repeated within a single list of covered | |||
components. Component identifiers with different parameter values | ||||
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 input is defined in Section 2.3. | |||
2.1. HTTP Fields | 2.1. HTTP Fields | |||
The component identifier for an HTTP field is the lowercased form of | The component identifier for an HTTP field is the lowercased form of | |||
its field name. While HTTP field names are case-insensitive, | its field name. While HTTP field names are case-insensitive, | |||
implementations MUST use lowercased field names (e.g., content-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 with the following steps: | value MUST be canonicalized as a single combined value as defined in | |||
Section 5.2 of [SEMANTICS]. | ||||
If the combined value is not available for a given header, the | ||||
following algorithm will produce canonicalized results for an | ||||
implementation: | ||||
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 | ||||
leading and trailing whitespace, this will be a no-op in a | ||||
compliant implementation. | ||||
3. Concatenate the list items together, with a single comma "," and | 3. Remove any obsolete line-folding within the line and replace it | |||
space " " between each item. | with a single space (), as discussed in Section 5.2 of | |||
[MESSAGING]. Note that this behavior is specific to [MESSAGING] | ||||
The resulting string is the canonicalized component value. | and does not apply to other versions of the HTTP specification. | |||
2.1.1. Canonicalized Structured HTTP Fields | ||||
If value of the the HTTP field in question is a structured field | ||||
([RFC8941]), the component identifier MAY include the sf parameter. | ||||
If this parameter is included, the HTTP field value MUST be | ||||
canonicalized using the rules specified in Section 4 of [RFC8941]. | ||||
For example, this process will replace any optional internal | ||||
whitespace with a single space character. | ||||
The resulting string is used as the component value in Section 2.1. | 4. Concatenate the list of values together with a single comma (,) | |||
and a single space () between each item. | ||||
2.1.2. HTTP Field Examples | The resulting string is the canonicalized component value. | |||
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: | header fields, given the following example HTTP message fragment: | |||
Host: www.example.com | Host: www.example.com | |||
Date: Tue, 07 Jun 2014 20:51:35 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. | |||
X-Empty-Header: | ||||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dictionary: 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 input string format | |||
discussed in Section 2.3: | discussed in Section 2.3: | |||
"cache-control": max-age=60, must-revalidate| | "host": www.example.com | |||
"date": Tue, 07 Jun 2014 20:51:35 GMT| | "date": Tue, 20 Apr 2021 02:07:56 GMT | |||
"host": www.example.com| | "x-ows-header": Leading and trailing whitespace. | |||
"x-empty-header": | ||||
"x-obs-fold-header": Obsolete line folding. | "x-obs-fold-header": Obsolete line folding. | |||
"x-ows-header":Leading and trailing whitespace. | "cache-control": max-age=60, must-revalidate | |||
"x-dictionary": a=1, b=2;x=1;y=2, c=(a b c) | "Example-dictionary": a=1, b=2;x=1;y=2, c=(a b c) | |||
"x-dictionary";sf: a=1, b=2;x=1;y=2, c=(a b c) | ||||
2.1.3. Dictionary Structured Field Members | Since empty HTTP header fields are allowed, they are also able to be | |||
signed when present in a message. The canonicalized value is the | ||||
empty string. This means that the following empty header: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
X-Empty-Header: \ | ||||
Is serialized by the signature input generation algorithm | ||||
(Section 2.3) with an empty string value following the colon and | ||||
space added after the content identifier. | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
"x-empty-header": \ | ||||
Note: these are shown here using the line wrapping algorithm in | ||||
[RFC8792] due to limitations in the document format that strips | ||||
trailing spaces from diagrams. | ||||
2.1.1. Canonicalized Structured HTTP Fields | ||||
If value of the the HTTP field in question is a structured field | ||||
([RFC8941]), the component identifier MAY include the sf parameter to | ||||
indicate it is a known structured field. If this parameter is | ||||
included with a component identifier, the HTTP field value MUST be | ||||
serialized using the rules specified in Section 4 of [RFC8941] | ||||
applicable to the type of the HTTP field. Note that this process | ||||
will replace any optional internal whitespace with a single space | ||||
character, among other potential transformations of the value. | ||||
For example, the following dictionary field is a valid serialization: | ||||
Example-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | ||||
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) | ||||
However, if the sf parameter is added, the value is re-serialized as | ||||
follows: | ||||
"example-dictionary";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. | ||||
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 a Dictionary containing only that item. | Section 4.1.2 of [RFC8941] on the member value and its parameters, | |||
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 input. Parameterized keys MAY appear in any | |||
order. | order. | |||
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: | |||
X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | Example-Dictionary: 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: | input string format discussed in Section 2.3: | |||
"x-dictionary";key="a": 1 | "example-dictionary";key="a": 1 | |||
"x-dictionary";key="b": 2;x=1;y=2 | "example-dictionary";key="b": 2;x=1;y=2 | |||
"x-dictionary";key="c": (a, b, c) | "example-dictionary";key="c": (a b c) | |||
2.2. Specialty Components | Note that the value for key="c" has been re-serialized. | |||
Message components not found in an HTTP field can be included in the | 2.2. Derived Components | |||
signature input by defining a component identifier and the | ||||
canonicalization method for its component value. | ||||
To differentiate specialty component identifiers from HTTP fields, | In addition to HTTP fields, there are a number of different | |||
specialty component identifiers MUST start with the "at" @ character. | components that can be derived from the control data, processing | |||
This specification defines the following specialty component | context, or other aspects of the HTTP message being signed. Such | |||
derived components can be included in the signature input by defining | ||||
a component identifier and the derivation method for its component | ||||
value. | ||||
Derived component identifiers MUST start with the "at" @ character. | ||||
This differentiates derived component identifiers from HTTP field | ||||
names, which cannot contain the @ character as per Section 5.1 of | ||||
[SEMANTICS]. Processors of HTTP Message Signatures MUST treat | ||||
derived component identifiers separately from field names, as | ||||
discussed in Section 7.18. | ||||
This specification defines the following derived component | ||||
identifiers: | identifiers: | |||
@signature-params The signature metadata parameters for this | @signature-params The signature metadata parameters for this | |||
signature. (Section 2.2.1) | signature. (Section 2.2.1) | |||
@method The method used for a request. (Section 2.2.2) | @method The method used for a request. (Section 2.2.2) | |||
@target-uri The full target URI for a request. (Section 2.2.3) | @target-uri The full target URI for a request. (Section 2.2.3) | |||
@authority The authority of the target URI for a request. | @authority The authority of the target URI for a request. | |||
(Section 2.2.4) | (Section 2.2.4) | |||
@scheme The scheme of the target URI for a request. (Section 2.2.5) | @scheme The scheme of the target URI for a request. (Section 2.2.5) | |||
@request-target The request target. (Section 2.2.6) | @request-target The request target. (Section 2.2.6) | |||
@path The absolute path portion of the target URI for a request. | @path The absolute path portion of the target URI for a request. | |||
skipping to change at page 14, line 18 ¶ | skipping to change at page 15, line 27 ¶ | |||
(Section 2.2.8) | (Section 2.2.8) | |||
@query-params The parsed query parameters of the target URI for a | @query-params The parsed query parameters of the target URI for a | |||
request. (Section 2.2.9) | request. (Section 2.2.9) | |||
@status The status code for a response. (Section 2.2.10). | @status The status code for a response. (Section 2.2.10). | |||
@request-response A signature from a request message that resulted | @request-response A signature from a request message that resulted | |||
in this response message. (Section 2.2.11) | in this response message. (Section 2.2.11) | |||
Additional specialty component identifiers MAY be defined and | Additional derived component identifiers MAY be defined and | |||
registered in the HTTP Signatures Specialty Component Identifier | registered in the HTTP Signatures Derived Component Identifier | |||
Registry. (Section 6.3) | Registry. (Section 6.3) | |||
Specialty components can be applied in one or more of three targets: | Derived components can be applied in one or more of three targets: | |||
request: Values derived from and results applied to an HTTP request | request: Values derived from and results applied to an HTTP request | |||
message as described in {{Section 3.4 of SEMANTICS. | message as described in {{Section 3.4 of SEMANTICS. | |||
response: Values derived from and results applied to an HTTP | response: Values derived from and results applied to an HTTP | |||
response message as described in Section 3.4 of [SEMANTICS]. | response message as described in Section 3.4 of [SEMANTICS]. | |||
related-response: Values derived from an HTTP request message and | related-response: Values derived from an HTTP request message and | |||
results applied to the HTTP response message that is responding to | results applied to the HTTP response message that is responding to | |||
that specific request. | that specific request. | |||
A component identifier definition MUST define all targets to which it | A component identifier definition MUST define all targets to which it | |||
can be applied. | can be applied. | |||
The component value MUST be derived from the HTTP message being | ||||
signed or the context in which the derivation occurs. The derived | ||||
component value MUST be of the following form: | ||||
derived-component-value = *VCHAR | ||||
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 | input string (Section 2.3) but the component identifier MUST NOT be | |||
skipping to change at page 16, line 10 ¶ | skipping to change at page 17, line 28 ¶ | |||
Note that the inner-list serialization is used for the covered | Note that the inner-list serialization is used for the covered | |||
component value instead of the sf-list serialization in order to | component value instead of the sf-list serialization in order to | |||
facilitate this value's inclusion in message fields such as the | facilitate this value's inclusion in message fields such as the | |||
Signature-Input field's dictionary, as discussed in Section 4.1. | Signature-Input field's dictionary, as discussed in Section 4.1. | |||
This example shows a canonicalized value for the parameters of a | This example shows a canonicalized value for the parameters of a | |||
given signature: | given signature: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
("@target-uri" "@authority" "date" "cache-control" "x-empty-header" \ | ("@target-uri" "@authority" "date" "cache-control")\ | |||
"x-example");keyid="test-key-rsa-pss";alg="rsa-pss-sha512";\ | ;keyid="test-key-rsa-pss";alg="rsa-pss-sha512";\ | |||
created=1618884475;expires=1618884775 | created=1618884475;expires=1618884775 | |||
Note that an HTTP message could contain multiple signatures | Note that an HTTP message could contain multiple signatures | |||
(Section 4.3), but only the signature parameters used for a single | (Section 4.3), but only the signature parameters used for a single | |||
signature are included in an entry. | signature are included in an entry. | |||
2.2.2. Method | 2.2.2. Method | |||
The @method component identifier refers to the HTTP method of a | The @method component identifier refers to the HTTP method of a | |||
request message. The component value of is canonicalized by taking | request message. The component value of is canonicalized by taking | |||
skipping to change at page 22, line 24 ¶ | skipping to change at page 24, line 7 ¶ | |||
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: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=value&pet=dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.com | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | ||||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
Content-Length: 18 | Content-Length: 18 | |||
Signature-Input: sig1=("@authority" "content-type")\ | Signature-Input: sig1=("@method" "@authority" "@path" \ | |||
"content-digest" "content-length" "content-type")\ | ||||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
Signature: sig1=:KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu5rif3g7ckTbbX7C4\ | Signature: sig1=:LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8r5MW9S0\ | |||
Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79gBeqvHNUO4bhI27p\ | RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkBIS1M8Br\ | |||
4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7OjkfsHAm/enxf1fA\ | c8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpWINTEzpx\ | |||
wkk15xj0n6kmriwZfgUlOqyff0XLwuH4XFvZ+ZTyxYNoo2+EfFg4NVfqtSJch2WDY\ | jqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2Tr65+BXe\ | |||
7n/qmhZOzMfyHlggWYFnDpyP27VrzQCQg8rM1Crp6MrwGLa94v6qP8pq0sQVq2DLt\ | TG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZElYyUKaAI\ | |||
4NJSoRRqXTvqlWIRnexmcKXjQFVz6YSA==: | jZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | |||
{"hello": "world"} | {"hello": "world"} | |||
This would result in the following unsigned response message: | This would result in the following unsigned response message: | |||
HTTP/1.1 200 OK | HTTP/1.1 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"} | |||
The server signs the response with its own key and includes the | To cryptographically link the response to the request, the server | |||
signature of sig1 from the request in the covered components of the | signs the response with its own key and includes the signature of | |||
response. The signature input string for this example is: | sig1 from the request in the covered components of the response. The | |||
signature input string for this example is: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"content-type": application/json | "@status": 503 | |||
"content-length": 62 | "content-length": 62 | |||
"@status": 200 | "content-type": application/json | |||
"@request-response";key="sig1": :KuhJjsOKCiISnKHh2rln5ZNIrkRvue0DSu\ | "@request-response";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJR\ | |||
5rif3g7ckTbbX7C4Jp3bcGmi8zZsFRURSQTcjbHdJtN8ZXlRptLOPGHkUa/3Qov79\ | GziCLuD8r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVd\ | |||
gBeqvHNUO4bhI27p4WzD1bJDG9+6ml3gkrs7rOvMtROObPuc78A95fa4+skS/t2T7\ | wXyY/UkBIS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMT\ | |||
OjkfsHAm/enxf1fAwkk15xj0n6kmriwZfgUlOqyff0XLwuH4XFvZ+ZTyxYNoo2+Ef\ | e0QE3IpWINTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuT\ | |||
Fg4NVfqtSJch2WDY7n/qmhZOzMfyHlggWYFnDpyP27VrzQCQg8rM1Crp6MrwGLa94\ | Z9HdbD2Tr65+BXeTG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S\ | |||
v6qP8pq0sQVq2DLt4NJSoRRqXTvqlWIRnexmcKXjQFVz6YSA==: | 1ag3LZElYyUKaAIjZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | |||
"@signature-params": ("content-type" "content-length" "@status" \ | "@signature-params": ("@status" "content-length" "content-type" \ | |||
"@request-response";key="sig1");created=1618884475\ | "@request-response";key="sig1");created=1618884479\ | |||
;keyid="test-key-ecc-p256" | ;keyid="test-key-ecc-p256" | |||
The signed response message is: | The signed response message is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
HTTP/1.1 200 OK | 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 | |||
Signature-Input: sig1=("content-type" "content-length" "@status" \ | Signature-Input: reqres=("@status" "content-length" "content-type" \ | |||
"@request-response";key="sig1");created=1618884475\ | "@request-response";key="sig1");created=1618884479\ | |||
;keyid="test-key-ecc-p256" | ;keyid="test-key-ecc-p256" | |||
Signature: sig1=:crVqK54rxvdx0j7qnt2RL1oQSf+o21S/6Uk2hyFpoIfOT0q+Hv\ | Signature: reqres=:JqzXLIjNd6VWVg/M7enbjWkOgsPmIK9vcoFQEkLD0SXNbFjR\ | |||
msYAXUXzo0Wn8NFWh/OjWQOXHAQdVnTk87Pw==: | 6d+olsof1dv7xC7ygF1q0YKjVrbV2QlCpDxrHg==: | |||
{"busy": true, "message": "Your call is very important to us"} | {"busy": true, "message": "Your call is very important to us"} | |||
Since the request's signature value itself is not repeated in the | Since the request's signature value itself is not repeated in the | |||
response, the requester MUST keep the original signature value around | response, the requester MUST keep the original signature value around | |||
long enough to validate the signature of the response that uses this | long enough to validate the signature of the response that uses this | |||
component identifier. | component identifier. | |||
Note that the ECDSA algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
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 Input String | |||
The signature input is a US-ASCII string containing the canonicalized | The signature input is a US-ASCII string containing the canonicalized | |||
HTTP message components covered by the signature. The input to the | HTTP message components covered by the signature. The input to the | |||
signature creation algorithm is the list of covered component | signature input creation algorithm is the list of covered component | |||
identifiers and their associated values, along with an additional | identifiers and their associated values, along with any additional | |||
signature parameters. To create the signature input string, the | signature parameters. The output is the signature input string, | |||
signer or verifier concatenates together entries for each identifier | which has the following form: | |||
in the signature's covered components (including their parameters) | ||||
using the following algorithm: | signature-input = *( signature-input-line LF ) signature-params-line | |||
signature-input-line = component-identifier ":" SP ( derived-component-value / field-value ) | ||||
signature-params-line = DQUOTE "@signature-params" DQUOTE ":" SP inner-list | ||||
To create the signature input string, the signer or verifier | ||||
concatenates together entries for each identifier in the signature's | ||||
covered components (including their parameters) using the following | ||||
algorithm: | ||||
1. Let the output be an empty string. | 1. Let the output be an empty string. | |||
2. For each message component item in the covered components set (in | 2. For each message component item in the covered components set (in | |||
order): | order): | |||
1. Append the component identifier for the covered component | 1. Append the component identifier for the covered component | |||
serialized according to the component-identifier rule. | serialized according to the component-identifier rule. Note | |||
that this serialization places the component identifier in | ||||
double quotes and appends any parameters outside of the | ||||
quotes. | ||||
2. Append a single colon : | 2. Append a single colon : | |||
3. Append a single space " " | 3. Append a single space " " | |||
4. Append the covered component's canonicalized component value, | 4. Determine the component value for the component identifier. | |||
as defined by the HTTP message component type. (Section 2.1 | ||||
and Section 2.2) | ||||
5. Append a single newline \n | * If the component identifier starts with an "at" character | |||
(@), derive the component's value from the message | ||||
according to the specific rules defined for the derived | ||||
component identifier, as in Section 2.2. If the derived | ||||
component identifier is unknown or the value cannot be | ||||
derived, produce an error. | ||||
* If the component identifier does not start with an "at" | ||||
character (@), canonicalize the HTTP field value as | ||||
described in Section 2.1. If the value cannot be | ||||
calculated, produce an error. | ||||
5. Append the covered component's canonicalized component value. | ||||
6. Append a single newline \n | ||||
3. Append the signature parameters component (Section 2.2.1) as | 3. Append the signature parameters component (Section 2.2.1) as | |||
follows: | follows: | |||
1. Append the component identifier for the signature parameters | 1. Append the component identifier for the signature parameters | |||
serialized according to the component-identifier rule, i.e. | serialized according to the component-identifier rule, i.e. | |||
"@signature-params" | "@signature-params" | |||
2. Append a single colon : | 2. Append a single colon : | |||
3. Append a single space " " | 3. Append a single space " " | |||
4. Append the signature parameters' canonicalized component | 4. Append the signature parameters' canonicalized component | |||
value as defined in Section 2.2.1 | value as defined in Section 2.2.1 | |||
4. Return the output string. | 4. Return the output string. | |||
If covered components reference a component identifier that cannot be | If covered components reference a component identifier that cannot be | |||
resolved to a component value in the message, the implementation MUST | resolved to a component value in the message, the implementation MUST | |||
produce an error. Such situations are included but not limited to: | produce an error and not create an input string. Such situations are | |||
included but not limited to: | ||||
* The signer or verifier does not understand the component | * The signer or verifier does not understand the derived component | |||
identifier. | identifier. | |||
* The component identifier identifies a field that is not present in | * The component identifier identifies a field that is not present in | |||
the message or whose value is malformed. | the message or whose value is malformed. | |||
* The component identifier indicates that a structured field | * The component identifier indicates that a structured field | |||
serialization is used, but the field in question is known to not | serialization is used (via the sf parameter), but the field in | |||
be a structured field or the type of structured field is not known | question is known to not be a structured field or the type of | |||
to the verifier. | 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 "x-dictionary";key="c" and the value of | E.g., the identifier is "example-dictionary";key="c" and the value | |||
the x-dictionary header field is a=1, b=2 | of the Example-Dictionary header field is a=1, b=2, which does not | |||
have the c value. | ||||
In the following non-normative example, the HTTP message being signed | In the following non-normative example, the HTTP message being signed | |||
is the following request: | is the following request: | |||
GET /foo HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.org | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
X-Example: Example header | Content-Type: application/json | |||
with some whitespace. | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
X-Empty-Header: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Cache-Control: max-age=60 | Content-Length: 18 | |||
Cache-Control: must-revalidate | ||||
{"hello": "world"} | ||||
The covered components consist of the @method, @path, and @authority | The covered components consist of the @method, @path, and @authority | |||
specialty component identifiers followed by the Cache-Control, X- | derived component identifiers followed by the Content-Digest, | |||
Empty-Header, X-Example HTTP headers, in order. The signature | Content-Length, and Content-Type HTTP header fields, in order. The | |||
parameters consist of a creation timestamp is 1618884475 and the key | signature parameters consist of a creation timestamp of 1618884473 | |||
identifier is test-key-rsa-pss. The signature input string for this | and a key identifier of test-key-rsa-pss. Note that no explicit alg | |||
message with these parameters is: | parameter is given here since the verifier is assumed by the | |||
application to correctly use the RSA PSS algorithm based on the | ||||
identified key. The signature input string for this message with | ||||
these parameters is: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@method": GET | "@method": POST | |||
"@authority": example.com | ||||
"@path": /foo | "@path": /foo | |||
"@authority": example.org | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
"cache-control": max-age=60, must-revalidate | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
"x-empty-header": | "content-length": 18 | |||
"x-example": Example header with some whitespace. | "content-type": application/json | |||
"@signature-params": ("@method" "@path" "@authority" \ | "@signature-params": ("@method" "@authority" "@path" \ | |||
"cache-control" "x-empty-header" "x-example");created=1618884475\ | "content-digest" "content-length" "content-type")\ | |||
;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 Input | |||
Note that the example signature input here, or anywhere else within | ||||
this specification, does not include the final newline that ends the | ||||
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 26, line 51 ¶ | skipping to change at page 29, line 41 ¶ | |||
4. The signer creates an ordered set of component identifiers | 4. The signer creates an ordered set of component identifiers | |||
representing the message components to be covered by the | representing the message components to be covered by the | |||
signature, and attaches signature metadata parameters to this | signature, and attaches signature metadata parameters to this | |||
set. The serialized value of this is later used as the value of | set. The serialized value of this is later used as the value of | |||
the Signature-Input field as described in Section 4.1. | the Signature-Input field as described in Section 4.1. | |||
* Once an order of covered components is chosen, the order MUST | * Once an order of covered components is chosen, the order MUST | |||
NOT change for the life of the signature. | NOT change for the life of the signature. | |||
* Each covered component identifier MUST be either an HTTP field | * Each covered component identifier MUST be either an HTTP field | |||
in the message Section 2.1 or a specialty component identifier | in the message Section 2.1 or a derived component identifier | |||
listed in Section 2.2 or its associated registry. | listed in Section 2.2 or its associated registry. | |||
* Signers of a request SHOULD include some or all of the message | * Signers of a request SHOULD include some or all of the message | |||
control data in the covered components, such as the @method, | control data in the covered components, such as the @method, | |||
@authority, @target-uri, or some combination thereof. | @authority, @target-uri, or some combination thereof. | |||
* Signers SHOULD include the created signature metadata | * Signers SHOULD include the created signature metadata | |||
parameter to indicate when the signature was created. | parameter to indicate when the signature was created. | |||
* The @signature-params specialty component identifier is not | * The @signature-params 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 input. This ensures that a | |||
signature always covers its own metadata. | signature always covers its own metadata. | |||
* Further guidance on what to include in this set and in what | * Further guidance on what to include in this set and in what | |||
order is out of scope for this document. | order is out of scope for this document. | |||
5. The signer creates the signature input string based on these | 5. The signer creates the signature input string based on these | |||
signature parameters. (Section 2.3) | signature parameters. (Section 2.3) | |||
skipping to change at page 27, line 41 ¶ | skipping to change at page 30, line 34 ¶ | |||
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 input string is signed | |||
with the test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS | with the test-key-rsa-pss key in Appendix B.1.2 and the RSA PSS | |||
algorithm described in Section 3.3.1, giving the following message | algorithm described in Section 3.3.1, giving the following message | |||
signature output value, encoded in Base64: | signature output value, encoded in Base64: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1RSHi+oEF1FuX6O29\ | HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ | |||
d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC87qmSQjvu1CFyFuWSj\ | YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ | |||
dGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gyarxAiWI97mPXU+OVM64\ | +xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ | |||
+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix\ | VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ | |||
5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3r5S9IXf2fYJK+eyW4AiG\ | E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ | |||
VMvMcOg== | RalVc/g== | |||
Figure 2: Non-normative example signature value | Figure 2: Non-normative example signature value | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
expected to match the example. See Section 7.19. | ||||
3.2. Verifying a Signature | 3.2. Verifying a Signature | |||
Verification of an HTTP message signature is a process that takes as | Verification of an HTTP message signature is a process that takes as | |||
its input the message (including Signature and Signature-Input | its input the message (including Signature and Signature-Input | |||
fields) and the requirements for the application. The output of the | fields) and the requirements for the application. The output of the | |||
verification is either a positive verification or an error. | verification is either a positive verification or an error. | |||
In order to verify a signature, a verifier MUST follow the following | In order to verify a signature, a verifier MUST follow the following | |||
algorithm: | algorithm: | |||
skipping to change at page 30, line 7 ¶ | skipping to change at page 33, line 7 ¶ | |||
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 | |||
following message with the test-key-rsa-pss key in Appendix B.1.2 and | following message with the test-key-rsa-pss key in Appendix B.1.2 and | |||
the RSA PSS algorithm described in Section 3.3.1: | the RSA PSS algorithm described in Section 3.3.1: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
GET /foo HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: example.org | Host: example.com | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
X-Example: Example header | Content-Type: application/json | |||
with some whitespace. | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
X-Empty-Header: | aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
Cache-Control: max-age=60 | Content-Length: 18 | |||
Cache-Control: must-revalidate | Signature-Input: sig1=("@method" "@authority" "@path" \ | |||
Signature-Input: sig1=("@method" "@path" "@authority" \ | "content-digest" "content-length" "content-type")\ | |||
"cache-control" "x-empty-header" "x-example");created=1618884475\ | ;created=1618884473;keyid="test-key-rsa-pss" | |||
;keyid="test-key-rsa-pss" | Signature: sig1=:HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrl\ | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo1\ | FrCGUDih47vAxi4L2YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxH\ | |||
RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCiHzC8\ | LMCy8uqK488o+9jrptQ+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSf\ | |||
7qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW84jS8gya\ | SvzPuBCh+ARHBmWuNo1UzVVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y\ | |||
rxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53r58RmpZ+J9\ | 9TP5FsZYzHvDqbInkTNigBcE9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7\ | |||
eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCVRj05NrxABNFv3\ | aXq6Am6sfOrpIC49yXjj3ae6HRalVc/g==: | |||
r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | ||||
{"hello": "world"} | ||||
With the additional requirements that at least the method, path, | With the additional requirements that at least the method, path, | |||
authority, and cache-control be signed, and that the signature | authority, and cache-control be signed, and that the signature | |||
creation timestamp is recent enough at the time of verification, the | creation timestamp is recent enough at the time of verification, the | |||
verification passes. | verification passes. | |||
3.2.1. Enforcing Application Requirements | 3.2.1. Enforcing Application Requirements | |||
The verification requirements specified in this document are intended | The verification requirements specified in this document are intended | |||
as a baseline set of restrictions that are generally applicable to | as a baseline set of restrictions that are generally applicable to | |||
skipping to change at page 31, line 34 ¶ | skipping to change at page 34, line 34 ¶ | |||
requirements. | requirements. | |||
Applications MUST enforce the requirements defined in this document. | Applications MUST enforce the requirements defined in this document. | |||
Regardless of use case, applications MUST NOT accept signatures that | Regardless of use case, applications MUST NOT accept signatures that | |||
do not conform to these requirements. | do not conform to these requirements. | |||
3.3. Signature Algorithm Methods | 3.3. Signature Algorithm Methods | |||
HTTP Message signatures MAY use any cryptographic digital signature | HTTP Message signatures MAY use any cryptographic digital signature | |||
or MAC method that is appropriate for the key material, environment, | or MAC method that is appropriate for the key material, environment, | |||
and needs of the signer and verifier. All signatures are generated | and needs of the signer and verifier. | |||
from and verified against the byte values of the signature input | ||||
string defined in Section 2.3. | ||||
Each signature algorithm method takes as its input the signature | Each signature algorithm method takes as its input the signature | |||
input string as a set of byte values (I), the signing key material | input string defined in Section 2.3 as a byte array (M), the signing | |||
(Ks), and outputs the signature output as a set of byte values (S): | key material (Ks), and outputs the signature output as a byte array | |||
(S): | ||||
HTTP_SIGN (I, 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 as a set of byte values (I), the | recalculated signature input string defined in Section 2.3 as a byte | |||
verification key material (Kv), and the presented signature to be | array (M), the verification key material (Kv), and the presented | |||
verified as a set of byte values (S) and outputs the verification | signature to be verified as a byte array (S) and outputs the | |||
result (V) as a boolean: | verification result (V) as a boolean: | |||
HTTP_VERIFY (I, 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 algorithm signature parameter | |||
defined in Section 2.2.1, by reference to the key material, or | defined in Section 2.2.1, by reference to the key material, or | |||
through mutual agreement between the signer and verifier. | through mutual agreement between the signer and verifier. | |||
3.3.1. RSASSA-PSS using SHA-512 | 3.3.1. RSASSA-PSS using SHA-512 | |||
To sign using this algorithm, the signer applies the RSASSA-PSS-SIGN | To sign using this algorithm, the signer applies the RSASSA-PSS-SIGN | |||
(K, M) function [RFC8017] with the signer's private signing key (K) | (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 input string (M) (Section 2.3). The mask | |||
skipping to change at page 32, line 31 ¶ | skipping to change at page 35, line 31 ¶ | |||
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 input | |||
string (M) re-created as described in Section 3.2. The mask | string (M) re-created as described in Section 3.2. The mask | |||
generation function is MGF1 as specified in [RFC8017] with a hash | generation function is MGF1 as specified in [RFC8017] with a hash | |||
function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | function of SHA-512 [RFC6234]. The salt length (sLen) is 64 bytes. | |||
The hash function (Hash) SHA-512 [RFC6234] is applied to the | The hash function (Hash) SHA-512 [RFC6234] is applied to the | |||
signature input string to create the digest content to which the | signature input string to create the digest content to which the | |||
verification function is applied. The verifier extracts the HTTP | verification function is applied. The verifier extracts the HTTP | |||
message signature to be verified (S) as described in Section 3.2. | message signature to be verified (S) as described in Section 3.2. | |||
The results of the verification function are compared to the http | The results of the verification function indicate if the signature | |||
message signature to determine if the signature presented is valid. | presented is valid. | |||
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 | ||||
signature input and compare the results to an existing signature. | ||||
Instead, the verification algorithm defined here needs to be used. | ||||
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 input string (M) (Section 2.3). | |||
The hash SHA-256 [RFC6234] is applied to the signature input string | The hash SHA-256 [RFC6234] is applied to the signature input string | |||
skipping to change at page 33, line 40 ¶ | skipping to change at page 36, line 46 ¶ | |||
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 input string (Section 2.3). The hash SHA-256 | |||
[RFC6234] is applied to the signature input string to create the | [RFC6234] is applied to the signature input string to create the | |||
digest content to which the digital signature is applied. The | digest content to which the digital signature is applied, (M). The | |||
resulting signed content byte array is the HTTP message signature | signature algorithm returns two integer values, r and s. These are | |||
output used in Section 3.1. | both encoded in big-endian unsigned integers, zero-padded to | |||
32-octets each. These encoded values are concatenated into a single | ||||
64-octet array consisting of the encoded value of r followed by the | ||||
encoded value of s. The resulting concatenation of (r, s) is byte | ||||
array of the HTTP message signature output used in Section 3.1. | ||||
To verify using this algorithm, the verifier applies the ECDSA | To verify using this algorithm, the verifier applies the ECDSA | |||
algorithm [FIPS186-4] using the public key portion of the | algorithm [FIPS186-4] using the public key portion of the | |||
verification key material and the signature input string re-created | verification key material and the signature input string re-created | |||
as described in Section 3.2. The hash function SHA-256 [RFC6234] is | as described in Section 3.2. The hash function SHA-256 [RFC6234] is | |||
applied to the signature input string to create the digest content to | applied to the signature input string to create the digest content to | |||
which the verification function is applied. The verifier extracts | which the signature verification function is applied, (M). The | |||
the HTTP message signature to be verified (S) as described in | verifier extracts the HTTP message signature to be verified (S) as | |||
Section 3.2. The results of the verification function are compared | described in Section 3.2. This value is a 64-octet array consisting | |||
to the http message signature to determine if the signature presented | of the encoded values of r and s concatenated in order. These are | |||
is valid. | both encoded in big-endian unsigned integers, zero-padded to | |||
32-octets each. The resulting signature value (r, s) is used as | ||||
input to the signature verification function. The results of the | ||||
verification function indicate if the signature presented is valid. | ||||
Note that the output of ECDSA algorithms are non-deterministic, and | ||||
therefore it is not correct to re-calculate a new signature on the | ||||
signature input and compare the results to an existing signature. | ||||
Instead, the verification algorithm defined here needs to be used. | ||||
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. JSON Web Signature (JWS) algorithms | 3.3.5. EdDSA using curve edwards25519 | |||
To sign using this algorithm, the signer applies the Ed25519 | ||||
algorithm Section 5.1.6 of [RFC8032] with the signer's private | ||||
signing key and the signature input string (Section 2.3). The | ||||
signature input string is taken as the input message (M) with no pre- | ||||
hash function. The signature is a 64-octet concatenation of R and S | ||||
as specified in Section 5.1.6 of [RFC8032], and this is taken as a | ||||
byte array for the HTTP message signature output used in Section 3.1. | ||||
To verify using this algorithm, the signer applies the Ed25519 | ||||
algorithm Section 5.1.7 of [RFC8032] using the public key portion of | ||||
the verification key material (A) and the signature input string re- | ||||
created as described in Section 3.2. The signature input string is | ||||
taken as the input message (M) with no pre-hash function. The | ||||
signature to be verified is processed as the 64-octet concatenation | ||||
of R and S as specified in Section 5.1.7 of [RFC8032]. The results | ||||
of the verification function indicate if the signature presented is | ||||
valid. | ||||
Use of this algorithm can be indicated at runtime using the ed25519 | ||||
value for the alg signature parameter. | ||||
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 input | |||
string (Section 2.3) is used as the entire "JWS Signing Input". The | string (Section 2.3) is used as the entire "JWS Signing Input". The | |||
JOSE Header defined in [RFC7517] is not used, and the signature input | JOSE Header defined in [RFC7517] is not used, and the signature input | |||
string is not first encoded in Base64 before applying the algorithm. | string is not first encoded in Base64 before applying the algorithm. | |||
skipping to change at page 35, line 23 ¶ | skipping to change at page 39, line 9 ¶ | |||
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" "host" "date" \ | |||
"cache-control" "x-empty-header" "x-example");created=1618884475\ | "cache-control");created=1618884475\ | |||
;keyid="test-key-rsa-pss" | ;keyid="test-key-rsa-pss" | |||
To facilitate signature validation, the Signature-Input field value | To facilitate signature validation, the Signature-Input field value | |||
MUST contain the same serialized value used in generating the | MUST contain the same serialized value used in generating the | |||
signature input string's @signature-params value. | signature input string's @signature-params value. | |||
The signer MAY include the Signature-Input field as a trailer to | The signer MAY include the Signature-Input field as a trailer to | |||
facilitate signing a message after its content has been processed by | facilitate signing a message after its content has been processed by | |||
the signer. However, since intermediaries are allowed to drop | the signer. However, since intermediaries are allowed to drop | |||
trailers as per [SEMANTICS], it is RECOMMENDED that the Signature- | trailers as per [SEMANTICS], it is RECOMMENDED that the Signature- | |||
skipping to change at page 36, line 39 ¶ | skipping to change at page 40, line 30 ¶ | |||
they can be used to include multiple signatures within the same HTTP | they can be used to include multiple signatures within the same HTTP | |||
message by using distinct signature labels. These multiple | message by using distinct signature labels. These multiple | |||
signatures could be added all by the same signer or could come from | signatures could be added all by the same signer or could come from | |||
several different signers. For example, a signer may include | several different signers. For example, a signer may include | |||
multiple signatures signing the same message components with | multiple signatures signing the same message components with | |||
different keys or algorithms to support verifiers with different | different keys or algorithms to support verifiers with different | |||
capabilities, or a reverse proxy may include information about the | capabilities, or a reverse proxy may include information about the | |||
client in fields when forwarding the request to a service host, | client in fields when forwarding the request to a service host, | |||
including a signature over the client's original signature values. | including a signature over the client's original signature values. | |||
The following is a non-normative example of header fields a reverse | The following is a non-normative example starts with a signed request | |||
proxy sets in addition to the examples in the previous sections. | from the client. The proxy takes this request validates the client's | |||
signature. | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | ||||
Host: example.com | ||||
Date: Tue, 20 Apr 2021 02:07:55 GMT | ||||
Content-Type: application/json | ||||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | ||||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
Content-Length: 18 | ||||
Signature-Input: sig1=("@method" "@authority" "@path" \ | ||||
"content-digest" "content-length" "content-type")\ | ||||
;created=1618884475;keyid="test-key-rsa-pss" | ||||
Signature: sig1=:LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8r5MW9S0\ | ||||
RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkBIS1M8Br\ | ||||
c8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpWINTEzpx\ | ||||
jqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2Tr65+BXe\ | ||||
TG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZElYyUKaAI\ | ||||
jZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | ||||
{"hello": "world"} | ||||
The proxy then alters the message before forwarding it on to the | ||||
origin server, changing the target host and adding the Forwarded | ||||
header defined in [RFC7239]. | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
POST /foo?param=Value&Pet=dog HTTP/1.1 | ||||
Host: origin.host.internal.example | ||||
Date: Tue, 20 Apr 2021 02:07:56 GMT | ||||
Content-Type: application/json | ||||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | ||||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
Content-Length: 18 | ||||
Forwarded: for=192.0.2.123 | Forwarded: for=192.0.2.123 | |||
Signature-Input: sig1=("@method" "@path" "@authority" \ | Signature-Input: sig1=("@method" "@authority" "@path" \ | |||
"cache-control" "x-empty-header" "x-example")\ | "content-digest" "content-length" "content-type")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884475;keyid="test-key-rsa-pss" | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | Signature: sig1=:LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8r5MW9S0\ | |||
1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkBIS1M8Br\ | |||
HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | c8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpWINTEzpx\ | |||
4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | jqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2Tr65+BXe\ | |||
r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | TG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZElYyUKaAI\ | |||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | jZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | |||
The client's request includes a signature value under the label sig1, | {"hello": "world"} | |||
which the proxy signs in addition to the Forwarded header defined in | The proxy includes the client's signature value under the label sig1, | |||
[RFC7239]. Note that since the client's signature already covers the | which the proxy signs in addition to the Forwarded header. Note that | |||
client's Signature-Input value for sig1, this value is transitively | since the client's signature already covers the client's Signature- | |||
covered by the proxy's signature and need not be added explicitly. | Input value for sig1, this value is transitively covered by the | |||
This results in a signature input string of: | proxy's signature and need not be added explicitly. The proxy | |||
identifies its own key and algorithm and, in this example, includes | ||||
an expiration for the signature to indicate to downstream systems | ||||
that the proxy will not vouch for this signed message past this short | ||||
time window. This results in a signature input string of: | ||||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"signature";key="sig1": :P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP\ | "signature";key="sig1": :LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8\ | |||
4uKwxyJo1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9Gl\ | r5MW9S0RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkB\ | |||
yntiCiHzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyo\ | IS1M8Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpW\ | |||
yZW84jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg\ | INTEzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2T\ | |||
53r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | r65+BXeTG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZEl\ | |||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==: | YyUKaAIjZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==: | |||
"forwarded": for=192.0.2.123 | "forwarded": for=192.0.2.123 | |||
"@signature-params": ("signature";key="sig1" "forwarded")\ | "@signature-params": ("signature";key="sig1" "forwarded")\ | |||
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | ;created=1618884480;expires=1618884540;keyid="test-key-rsa"\ | |||
;alg="rsa-v1_5-sha256" | ||||
And a signature output value of: | And a signature output value of: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZxNiE+797dXK2cj\ | G1WLTL4/9PGSKEQbSAMypZNk+I2dpLJ6qvl2JISahlP31OO/QEUd8/HdO2O7vYLi5k3\ | |||
PPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8keB8xzFt4inv3J3zP0\ | JIiAK3UPK4U+kvJZyIUidsiXlzRI+Y2se3SGo0D8dLfhG95bKr6ukYXl60QHpsGRTfS\ | |||
k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1XSg03iUa0sju1yj6rcKbMA\ | iwdtvYKXGpKNrMlISJYd+oGrGRyI9gbCy0aFhc6I/okIMLeK4g9PgzpC3YTwhUQ98KI\ | |||
BBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hmcDHkNaavcokmq+3EBDCQTzgwL\ | BNLWHgREfBgJxjPbxFlsgJ9ykPviLj8GKJ81HwsK3XM9P7WaS7fMGOt8h1kSqgkZQB9\ | |||
qfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+j8kSydKoFg6EbVuGbrQijth6I0dDX\ | YqiIo+WhHvJa7iPy8QrYFKzx9BBEY6AwfStZAsXXz3LobZseyxsYcLJLs8rY0wVA9NP\ | |||
2/HYcJg== | sxKrHGA== | |||
These values are added to the HTTP request message by the proxy. The | These values are added to the HTTP request message by the proxy. The | |||
original signature is included under the identifier sig1, and the | original signature is included under the identifier sig1, and the | |||
reverse proxy's signature is included under the label proxy_sig. The | reverse proxy's signature is included under the label proxy_sig. The | |||
proxy uses the key test-key-rsa to create its signature using the | proxy uses the key test-key-rsa to create its signature using the | |||
rsa-v1_5-sha256 signature algorithm, while the client's original | rsa-v1_5-sha256 signature algorithm, while the client's original | |||
signature was made using the key id of test-key-rsa-pss and an RSA | signature was made using the key id of test-key-rsa-pss and an RSA | |||
PSS signature algorithm. | PSS signature algorithm. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?param=Value&Pet=dog HTTP/1.1 | ||||
Host: origin.host.internal.example | ||||
Date: Tue, 20 Apr 2021 02:07:56 GMT | ||||
Content-Type: application/json | ||||
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | ||||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
Content-Length: 18 | ||||
Forwarded: for=192.0.2.123 | Forwarded: for=192.0.2.123 | |||
Signature-Input: sig1=("@method" "@path" "@authority" \ | Signature-Input: sig1=("@method" "@authority" "@path" \ | |||
"cache-control" "x-empty-header" "x-example")\ | "content-digest" "content-length" "content-type")\ | |||
;created=1618884475;keyid="test-key-rsa-pss", \ | ;created=1618884475;keyid="test-key-rsa-pss", \ | |||
proxy_sig=("signature";key="sig1" "forwarded")\ | proxy_sig=("signature";key="sig1" "forwarded")\ | |||
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256" | ;created=1618884480;expires=1618884540;keyid="test-key-rsa"\ | |||
Signature: sig1=:P0wLUszWQjoi54udOtydf9IWTfNhy+r53jGFj9XZuP4uKwxyJo\ | ;alg="rsa-v1_5-sha256" | |||
1RSHi+oEF1FuX6O29d+lbxwwBao1BAgadijW+7O/PyezlTnqAOVPWx9GlyntiCi\ | Signature: sig1=:LAH8BjcfcOcLojiuOBFWn0P5keD3xAOuJRGziCLuD8r5MW9S0\ | |||
HzC87qmSQjvu1CFyFuWSjdGa3qLYYlNm7pVaJFalQiKWnUaqfT4LyttaXyoyZW8\ | RoXXLzLSRfGY/3SF8kVIkHjE13SEFdTo4Af/fJ/Pu9wheqoLVdwXyY/UkBIS1M8\ | |||
4jS8gyarxAiWI97mPXU+OVM64+HVBHmnEsS+lTeIsEQo36T3NFf2CujWARPQg53\ | Brc8IODsn5DFIrG0IrburbLi0uCc+E2ZIIb6HbUJ+o+jP58JelMTe0QE3IpWINT\ | |||
r58RmpZ+J9eKR2CD6IJQvacn5A4Ix5BUAVGqlyp8JYm+S/CWJi31PNUjRRCusCV\ | EzpxjqDf5/Df+InHCAkQCTuKsamjWXUpyOT1Wkxi7YPVNOjW4MfNuTZ9HdbD2Tr\ | |||
Rj05NrxABNFv3r5S9IXf2fYJK+eyW4AiGVMvMcOg==:, \ | 65+BXeTG9ZS/9SWuXAc+BZ8WyPz0QRz//ec3uWXd7bYYODSjRAxHqX+S1ag3LZE\ | |||
proxy_sig=:cjGvZwbsq9JwexP9TIvdLiivxqLINwp/ybAc19KOSQuLvtmMt3EnZx\ | lYyUKaAIjZ8MGOt4gXEwCSLDv/zqxZeWLj/PDkn6w==:, \ | |||
NiE+797dXK2cjPPUFqoZxO8WWx1SnKhAU9SiXBr99NTXRmA1qGBjqus/1Yxwr8k\ | proxy_sig=:G1WLTL4/9PGSKEQbSAMypZNk+I2dpLJ6qvl2JISahlP31OO/QEUd8/\ | |||
eB8xzFt4inv3J3zP0k6TlLkRJstkVnNjuhRIUA/ZQCo8jDYAl4zWJJjppy6Gd1X\ | HdO2O7vYLi5k3JIiAK3UPK4U+kvJZyIUidsiXlzRI+Y2se3SGo0D8dLfhG95bKr\ | |||
Sg03iUa0sju1yj6rcKbMABBuzhUz4G0u1hZkIGbQprCnk/FOsqZHpwaWvY8P3hm\ | 6ukYXl60QHpsGRTfSiwdtvYKXGpKNrMlISJYd+oGrGRyI9gbCy0aFhc6I/okIML\ | |||
cDHkNaavcokmq+3EBDCQTzgwLqfDmV0vLCXtDda6CNO2Zyum/pMGboCnQn/VkQ+\ | eK4g9PgzpC3YTwhUQ98KIBNLWHgREfBgJxjPbxFlsgJ9ykPviLj8GKJ81HwsK3X\ | |||
j8kSydKoFg6EbVuGbrQijth6I0dDX2/HYcJg==: | M9P7WaS7fMGOt8h1kSqgkZQB9YqiIo+WhHvJa7iPy8QrYFKzx9BBEY6AwfStZAs\ | |||
XXz3LobZseyxsYcLJLs8rY0wVA9NPsxKrHGA==: | ||||
{"hello": "world"} | ||||
The proxy's signature and the client's original signature can be | The proxy's signature and the client's original signature can be | |||
verified independently for the same message, based on the needs of | verified independently for the same message, based on the needs of | |||
the application. Since the proxy's signature covers the client | the application. Since the proxy's signature covers the client | |||
signature, the backend service fronted by the proxy can trust that | signature, the backend service fronted by the proxy can trust that | |||
the proxy has validated the incoming signature. | the proxy has validated the incoming signature. | |||
5. Requesting Signatures | 5. Requesting Signatures | |||
While a signer is free to attach a signature to a request or response | While a signer is free to attach a signature to a request or response | |||
skipping to change at page 39, line 41 ¶ | skipping to change at page 44, line 43 ¶ | |||
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" "host" "date" \ | |||
"cache-control" "x-empty-header" "x-example")\ | "cache-control")\ | |||
;keyid="test-key-rsa-pss" | ;keyid="test-key-rsa-pss" | |||
The requested signature MAY include parameters, such as a desired | The requested signature MAY include parameters, such as a desired | |||
algorithm or key identifier. These parameters MUST NOT include | algorithm or key identifier. These parameters MUST NOT include | |||
parameters that the signer is expected to generate, including the | parameters that the signer is expected to generate, including the | |||
created and nonce parameters. | created and nonce parameters. | |||
5.2. Processing an Accept-Signature | 5.2. Processing an Accept-Signature | |||
The receiver of an Accept-Signature field fulfills that header as | The receiver of an Accept-Signature field fulfills that header as | |||
skipping to change at page 42, line 27 ¶ | skipping to change at page 47, line 27 ¶ | |||
| | | | Section 3.3.2 | | | | | | Section 3.3.2 | | |||
+-------------------+--------+-------------------+---------------+ | +-------------------+--------+-------------------+---------------+ | |||
| hmac-sha256 | Active | HMAC using | [[This | | | hmac-sha256 | Active | HMAC using | [[This | | |||
| | | SHA-256 | document]], | | | | | SHA-256 | document]], | | |||
| | | | Section 3.3.3 | | | | | | Section 3.3.3 | | |||
+-------------------+--------+-------------------+---------------+ | +-------------------+--------+-------------------+---------------+ | |||
| ecdsa-p256-sha256 | Active | ECDSA using curve | [[This | | | ecdsa-p256-sha256 | Active | ECDSA using curve | [[This | | |||
| | | P-256 DSS and | document]], | | | | | P-256 DSS and | document]], | | |||
| | | SHA-256 | Section 3.3.4 | | | | | SHA-256 | Section 3.3.4 | | |||
+-------------------+--------+-------------------+---------------+ | +-------------------+--------+-------------------+---------------+ | |||
| ed25519 | Active | Edwards Curve DSA | [[This | | ||||
| | | using curve | document]], | | ||||
| | | edwards25519 | Section 3.3.5 | | ||||
+-------------------+--------+-------------------+---------------+ | ||||
Table 1 | Table 1 | |||
6.2. HTTP Signature Metadata Parameters Registry | 6.2. HTTP Signature Metadata Parameters Registry | |||
This document defines the signature parameters structure, the values | This document defines the signature parameters structure, the values | |||
of which may have parameters containing metadata about a message | of which may have parameters containing metadata about a message | |||
signature. IANA is asked to create and maintain a new registry | signature. IANA is asked to create and maintain a new registry | |||
titled "HTTP Signature Metadata Parameters" to record and maintain | titled "HTTP Signature Metadata Parameters" to record and maintain | |||
the set of parameters defined for use with member values in the | the set of parameters defined for use with member values in the | |||
skipping to change at page 43, line 44 ¶ | skipping to change at page 49, line 5 ¶ | |||
| | signing and verification keys | this document | | | | signing and verification keys | this document | | |||
| | used to create this signature | | | | | used to create this signature | | | |||
+---------+-------------------------------+------------------+ | +---------+-------------------------------+------------------+ | |||
| nonce | A single-use nonce value | Section 2.2.1 of | | | nonce | A single-use nonce value | Section 2.2.1 of | | |||
| | | this document | | | | | this document | | |||
+---------+-------------------------------+------------------+ | +---------+-------------------------------+------------------+ | |||
Table 2: Initial contents of the HTTP Signature Metadata | Table 2: Initial contents of the HTTP Signature Metadata | |||
Parameters Registry. | Parameters Registry. | |||
6.3. HTTP Signature Specialty Component Identifiers Registry | 6.3. HTTP Signature Derived Component Identifiers Registry | |||
This document defines a method for canonicalizing HTTP message | This document defines a method for canonicalizing HTTP message | |||
components, including components that can be derived from the context | components, including components that can be derived from the context | |||
of the HTTP message outside of the HTTP fields. These components are | of the HTTP message outside of the HTTP fields. These components are | |||
identified by a unique string, known as the component identifier. | identified by a unique string, known as the component identifier. | |||
Component identifiers for specialty components always start with the | Component identifiers for derived components always start with the | |||
"@" (at) symbol to distinguish them from HTTP header fields. IANA is | "@" (at) symbol to distinguish them from HTTP header fields. IANA is | |||
asked to create and maintain a new registry typed "HTTP Signature | asked to create and maintain a new registry typed "HTTP Signature | |||
Specialty Component Identifiers" to record and maintain the set of | Derived Component Identifiers" to record and maintain the set of non- | |||
non-field component identifiers and the methods to produce their | field component identifiers and the methods to produce their | |||
associated component values. Initial values for this registry are | associated component values. Initial values for this registry are | |||
given in Section 6.3.2. Future assignments and modifications to | given in Section 6.3.2. Future assignments and modifications to | |||
existing assignments are to be made through the Expert Review | existing assignments are to be made through the Expert Review | |||
registration policy [RFC8126] and shall follow the template presented | registration policy [RFC8126] and shall follow the template presented | |||
in Section 6.3.1. | in Section 6.3.1. | |||
6.3.1. Registration Template | 6.3.1. Registration Template | |||
Identifier: | Identifier: | |||
An identifier for the HTTP specialty component identifier. The | An identifier for the HTTP derived component identifier. The name | |||
name MUST begin with the "@" character followed by an ASCII string | MUST begin with the "@" character followed by an ASCII string | |||
consisting only of lower-case characters ("a" - "z"), digits ("0" | consisting only of lower-case characters ("a" - "z"), digits ("0" | |||
- "9"), and hyphens ("-"), and SHOULD NOT exceed 20 characters in | - "9"), and hyphens ("-"), and SHOULD NOT exceed 20 characters in | |||
length. The identifier MUST be unique within the context of the | length. The identifier MUST be unique within the context of the | |||
registry. | 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. | |||
Target: | Target: | |||
The valid message targets for the specialty parameter. MUST be | The valid message targets for the derived parameter. MUST be one | |||
one of the values "Request", "Request, Response", "Request, | of the values "Request", "Request, Response", "Request, Related- | |||
Related-Response", or "Related-Response". The semantics of these | Response", or "Related-Response". The semantics of these are | |||
are defined in Section 2.2. | defined in Section 2.2. | |||
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.3.2. Initial Contents | 6.3.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the HTTP Signature | |||
Specialty Component Identifiers Registry. | Derived Component Identifiers Registry. | |||
+===================+========+==================+==================+ | +===================+========+==================+==================+ | |||
| Identifier | Status | Target | Specification | | | Identifier | Status | Target | Specification | | |||
| | | | document(s) | | | | | | document(s) | | |||
+===================+========+==================+==================+ | +===================+========+==================+==================+ | |||
| @signature-params | Active | Request, | Section 2.2.1 of | | | @signature-params | Active | Request, | Section 2.2.1 of | | |||
| | | Response | this document | | | | | Response | this document | | |||
+-------------------+--------+------------------+------------------+ | +-------------------+--------+------------------+------------------+ | |||
| @method | Active | Request, | Section 2.2.2 of | | | @method | Active | Request, | Section 2.2.2 of | | |||
| | | Related-Response | this document | | | | | Related-Response | this document | | |||
skipping to change at page 45, line 43 ¶ | skipping to change at page 50, line 48 ¶ | |||
| @query-params | Active | Request, | Section 2.2.9 of | | | @query-params | Active | Request, | Section 2.2.9 of | | |||
| | | Related-Response | this document | | | | | Related-Response | this document | | |||
+-------------------+--------+------------------+------------------+ | +-------------------+--------+------------------+------------------+ | |||
| @status | Active | Response | Section 2.2.10 | | | @status | Active | Response | Section 2.2.10 | | |||
| | | | of this document | | | | | | of this document | | |||
+-------------------+--------+------------------+------------------+ | +-------------------+--------+------------------+------------------+ | |||
| @request-response | Active | Related-Response | Section 2.2.11 | | | @request-response | Active | Related-Response | Section 2.2.11 | | |||
| | | | of this document | | | | | | of this document | | |||
+-------------------+--------+------------------+------------------+ | +-------------------+--------+------------------+------------------+ | |||
Table 3: Initial contents of the HTTP Signature Specialty Component | Table 3: Initial contents of the HTTP Signature Derived | |||
Identifiers Registry. | Component Identifiers Registry. | |||
7. Security Considerations | 7. Security Considerations | |||
In order for an HTTP message to be considered covered by a signature, | In order for an HTTP message to be considered covered by a signature, | |||
all of the following conditions have to be true: | all of the following conditions have to be true: | |||
* a signature is expected or allowed on the message by the verifier | * a signature is expected or allowed on the message by the verifier | |||
* the signature exists on the message | * the signature exists on the message | |||
* the signature is verified against the identified key material and | * the signature is verified against the identified key material and | |||
algorithm | algorithm | |||
* the key material and algorithm are appropriate for the context of | * the key material and algorithm are appropriate for the context of | |||
the message | the message | |||
* the signature is within expected time boundaries | * the signature is within expected time boundaries | |||
skipping to change at page 51, line 43 ¶ | skipping to change at page 57, line 6 ¶ | |||
Some message components are expressed in different ways across HTTP | Some message components are expressed in different ways across HTTP | |||
versions. For example, the authority of the request target is sent | versions. For example, the authority of the request target is sent | |||
using the Host header field in HTTP 1.1 but with the :authority | using the Host header field in HTTP 1.1 but with the :authority | |||
pseudo-header in HTTP 2. If a signer sends an HTTP 1.1 message and | pseudo-header in HTTP 2. If a signer sends an HTTP 1.1 message and | |||
signs the Host field, but the message is translated to HTTP 2 before | signs the Host field, but the message is translated to HTTP 2 before | |||
it reaches the verifier, the signature will not validate as the Host | it reaches the verifier, the signature will not validate as the Host | |||
header field could be dropped. | header field could be dropped. | |||
It is for this reason that HTTP Message Signatures defines a set of | It is for this reason that HTTP Message Signatures defines a set of | |||
specialty components that define a single way to get value in | derived components that define a single way to get value in question, | |||
question, such as the @authority specialty component identifier | such as the @authority derived component identifier (Section 2.2.4) | |||
(Section 2.2.4). Applications should therefore prefer specialty | in lieu of the Host header field. Applications should therefore | |||
component identifiers for such options where possible. | prefer derived component identifiers for such options where possible. | |||
7.15. Key and Algorithm Specification Downgrades | 7.15. Key and Algorithm Specification Downgrades | |||
Applications of this specification need to protect against key | Applications of this specification need to protect against key | |||
specification downgrade attacks. For example, the same RSA key can | specification downgrade attacks. For example, the same RSA key can | |||
be used for both RSA-PSS and RSA v1.5 signatures. If an application | be used for both RSA-PSS and RSA v1.5 signatures. If an application | |||
expects a key to only be used with RSA-PSS, it needs to reject | expects a key to only be used with RSA-PSS, it needs to reject | |||
signatures for that key using the weaker RSA 1.5 specification. | signatures for that key using the weaker RSA 1.5 specification. | |||
Another example of a downgrade attack occurs when an asymmetric | Another example of a downgrade attack occurs when an asymmetric | |||
skipping to change at page 52, line 32 ¶ | skipping to change at page 57, line 38 ¶ | |||
specification does allow runtime specification of the algorithm using | specification does allow runtime specification of the algorithm using | |||
the alg signature parameter, applications are encouraged to use other | the alg signature parameter, applications are encouraged to use other | |||
mechanisms such as static configuration or higher protocol-level | mechanisms such as static configuration or higher protocol-level | |||
algorithm specification instead. | algorithm specification instead. | |||
7.16. Parsing Structured Field Values | 7.16. Parsing Structured Field Values | |||
Several parts of this specification rely on the parsing of structured | Several parts of this specification rely on the parsing of structured | |||
field values [RFC8941]. In particular, normalization of HTTP | field values [RFC8941]. In particular, normalization of HTTP | |||
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.3), 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 input string through | |||
manipulating the Signature-Input field value on a message. | manipulating the Signature-Input field value on a message. | |||
skipping to change at page 53, line 33 ¶ | skipping to change at page 58, line 33 ¶ | |||
Some components are expected to be changed by intermediaries and | Some components are expected to be changed by intermediaries and | |||
ought not to be signed under most circumstance. The Via and | ought not to be signed under most circumstance. The Via and | |||
Forwarded header fields, for example, are expected to be manipulated | Forwarded header fields, for example, are expected to be manipulated | |||
by proxies and other middle-boxes, including replacing or entirely | by proxies and other middle-boxes, including replacing or entirely | |||
dropping existing values. These fields should not be covered by the | dropping existing values. These fields should not be covered by the | |||
signature except in very limited and tightly-coupled scenarios. | signature except in very limited and tightly-coupled scenarios. | |||
Additional considerations for choosing signature aspects are | Additional considerations for choosing signature aspects are | |||
discussed in Section 1.5. | discussed in Section 1.5. | |||
7.18. Confusing HTTP Field Names for Derived Component Identifiers | ||||
The definition of HTTP field names does not allow for the use of the | ||||
@ character anywhere in the name. As such, since all derived | ||||
component identifiers start with the @ character, these namespaces | ||||
should be completely separate. However, some HTTP implementations | ||||
are not sufficiently strict about the characters accepted in HTTP | ||||
headers. In such implementations, a sender (or attacker) could | ||||
inject a header field starting with an @ character and have it passed | ||||
through to the application code. These invalid header fields could | ||||
be used to override a portion of the derived message content and | ||||
substitute an arbitrary value, providing a potential place for an | ||||
attacker to mount a signature collision (Section 7.5) attack. | ||||
To combat this, when selecting values for a message component, if the | ||||
component identifier starts with the @ character, it needs to be | ||||
processed as a derived component and never taken as a fields. Only | ||||
if the component identifier does not start with the @ character can | ||||
it be taken from the fields of the message. The algorithm discussed | ||||
in Section 2.3 provides a safe order of operations. | ||||
7.19. Non-deterministic Signature Primitives | ||||
Some cryptographic primitives such as RSA PSS and ECDSA have non- | ||||
deterministic outputs, which include some amount of entropy within | ||||
the algorithm. For such algorithms, multiple signatures generated in | ||||
succession will not match. A lazy implementation of a verifier could | ||||
ignore this distinction and simply check for the same value being | ||||
created by re-signing the signature input. Such an implementation | ||||
would work for deterministic algorithms such as HMAC and EdDSA but | ||||
fail to verify valid signatures made using non-deterministic | ||||
algorithms. It is therefore important that a verifier always use the | ||||
correctly-defined verification function for the algorithm in question | ||||
and not do a simple comparison. | ||||
8. Privacy Considerations | 8. Privacy Considerations | |||
8.1. Identification through Keys | 8.1. Identification through Keys | |||
If a signer uses the same key with multiple verifiers, or uses the | If a signer uses the same key with multiple verifiers, or uses the | |||
same key over time with a single verifier, the ongoing use of that | same key over time with a single verifier, the ongoing use of that | |||
key can be used to track the signer throughout the set of verifiers | key can be used to track the signer throughout the set of verifiers | |||
that messages are sent to. Since cryptographic keys are meant to be | that messages are sent to. Since cryptographic keys are meant to be | |||
functionally unique, the use of the same key over time is a strong | functionally unique, the use of the same key over time is a strong | |||
indicator that it is the same party signing multiple messages. | indicator that it is the same party signing multiple messages. | |||
skipping to change at page 55, line 39 ¶ | skipping to change at page 61, line 31 ¶ | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/rfc/rfc2119>. | <https://www.rfc-editor.org/rfc/rfc2119>. | |||
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | |||
Resource Identifier (URI): Generic Syntax", STD 66, | Resource Identifier (URI): Generic Syntax", STD 66, | |||
RFC 3986, DOI 10.17487/RFC3986, January 2005, | RFC 3986, DOI 10.17487/RFC3986, January 2005, | |||
<https://www.rfc-editor.org/rfc/rfc3986>. | <https://www.rfc-editor.org/rfc/rfc3986>. | |||
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | ||||
(SHA and SHA-based HMAC and HKDF)", RFC 6234, | ||||
DOI 10.17487/RFC6234, May 2011, | ||||
<https://www.rfc-editor.org/rfc/rfc6234>. | ||||
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, | ||||
DOI 10.17487/RFC7517, May 2015, | ||||
<https://www.rfc-editor.org/rfc/rfc7517>. | ||||
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, | ||||
DOI 10.17487/RFC7518, May 2015, | ||||
<https://www.rfc-editor.org/rfc/rfc7518>. | ||||
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | ||||
"PKCS #1: RSA Cryptography Specifications Version 2.2", | ||||
RFC 8017, DOI 10.17487/RFC8017, November 2016, | ||||
<https://www.rfc-editor.org/rfc/rfc8017>. | ||||
[RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital | ||||
Signature Algorithm (EdDSA)", RFC 8032, | ||||
DOI 10.17487/RFC8032, January 2017, | ||||
<https://www.rfc-editor.org/rfc/rfc8032>. | ||||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | |||
[RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, | [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, | |||
"Handling Long Lines in Content of Internet-Drafts and | "Handling Long Lines in Content of Internet-Drafts and | |||
RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, | RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, | |||
<https://www.rfc-editor.org/rfc/rfc8792>. | <https://www.rfc-editor.org/rfc/rfc8792>. | |||
[RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for | [RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for | |||
skipping to change at page 56, line 26 ¶ | skipping to change at page 62, line 39 ¶ | |||
Security (TLS) and Datagram Transport Layer Security | Security (TLS) and Datagram Transport Layer Security | |||
(DTLS)", BCP 195, RFC 7525, May 2015. | (DTLS)", BCP 195, RFC 7525, May 2015. | |||
Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS | Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS | |||
1.1", BCP 195, RFC 8996, March 2021. | 1.1", BCP 195, RFC 8996, March 2021. | |||
<https://www.rfc-editor.org/info/bcp195> | <https://www.rfc-editor.org/info/bcp195> | |||
[I-D.ietf-httpbis-client-cert-field] | [I-D.ietf-httpbis-client-cert-field] | |||
Campbell, B. and M. Bishop, "Client-Cert HTTP Header | Campbell, B. and M. Bishop, "Client-Cert HTTP Header | |||
Field: Conveying Client Certificate Information from TLS | Field", Work in Progress, Internet-Draft, draft-ietf- | |||
Terminating Reverse Proxies to Origin Server | httpbis-client-cert-field-01, 25 January 2022, | |||
Applications", Work in Progress, Internet-Draft, draft- | ||||
ietf-httpbis-client-cert-field-00, 8 June 2021, | ||||
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis- | |||
client-cert-field-00>. | client-cert-field-01>. | |||
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | ||||
(SHA and SHA-based HMAC and HKDF)", RFC 6234, | ||||
DOI 10.17487/RFC6234, May 2011, | ||||
<https://www.rfc-editor.org/rfc/rfc6234>. | ||||
[RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | [RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | |||
RFC 7239, DOI 10.17487/RFC7239, June 2014, | RFC 7239, DOI 10.17487/RFC7239, June 2014, | |||
<https://www.rfc-editor.org/rfc/rfc7239>. | <https://www.rfc-editor.org/rfc/rfc7239>. | |||
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, | ||||
DOI 10.17487/RFC7517, May 2015, | ||||
<https://www.rfc-editor.org/rfc/rfc7517>. | ||||
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, | ||||
DOI 10.17487/RFC7518, May 2015, | ||||
<https://www.rfc-editor.org/rfc/rfc7518>. | ||||
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | ||||
"PKCS #1: RSA Cryptography Specifications Version 2.2", | ||||
RFC 8017, DOI 10.17487/RFC8017, November 2016, | ||||
<https://www.rfc-editor.org/rfc/rfc8017>. | ||||
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/rfc/rfc8126>. | <https://www.rfc-editor.org/rfc/rfc8126>. | |||
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
<https://www.rfc-editor.org/rfc/rfc8446>. | <https://www.rfc-editor.org/rfc/rfc8446>. | |||
Appendix A. Detecting HTTP Message Signatures | Appendix A. Detecting HTTP Message Signatures | |||
skipping to change at page 60, line 26 ¶ | skipping to change at page 66, line 26 ¶ | |||
B.1.4. Example Shared Secret | B.1.4. Example Shared Secret | |||
The following shared secret is 64 randomly-generated bytes encoded in | The following shared secret is 64 randomly-generated bytes encoded in | |||
Base64, referred to in this document as test-shared-secret. | Base64, referred to in this document as test-shared-secret. | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ | |||
bmHhIDi6pcl8jsasjlTMtDQ== | bmHhIDi6pcl8jsasjlTMtDQ== | |||
B.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 | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ | |||
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
For responses, this test-response message is used: | For responses, this test-response message is used: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Date: Tue, 20 Apr 2021 02:07:56 GMT | Date: Tue, 20 Apr 2021 02:07:56 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | Content-Digest: sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6sN\ | |||
Content-Length: 18 | HpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==: | |||
Content-Length: 23 | ||||
{"hello": "world"} | {"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-Input and Signature header | This example presents a minimal signature using the rsa-pss-sha512 | |||
for a signature using the rsa-pss-sha512 algorithm over test-request, | algorithm over test-request, covering none of the components of the | |||
covering none of the components of the HTTP message request but | HTTP message, but providing a timestamped signature proof of | |||
providing a timestamped signature proof of possession of the key. | possession of the key with a signer-provided nonce. | |||
The corresponding signature input is: | The corresponding signature input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@signature-params": ();created=1618884475\ | "@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ | |||
;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | ;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: | being added to the message under the signature label sig-b21: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=();created=1618884475\ | Signature-Input: sig-b21=();created=1618884473\ | |||
;keyid="test-key-rsa-pss";alg="rsa-pss-sha512" | ;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd" | |||
Signature: sig1=:HWP69ZNiom9Obu1KIdqPPcu/C1a5ZUMBbqS/xwJECV8bhIQVmE\ | Signature: sig-b21=:d2pmTvmbncD3xQm8E9ZV2828BjQWGgiwAaw5bAkgibUopem\ | |||
AAAzz8LQPvtP1iFSxxluDO1KE9b8L+O64LEOvhwYdDctV5+E39Jy1eJiD7nYREBgx\ | LJcWDy/lkbbHAve4cRAtx31Iq786U7it++wgGxbtRxf8Udx7zFZsckzXaJMkA7ChG\ | |||
TpdUfzTO+Trath0vZdTylFlxK4H3l3s/cuFhnOCxmFYgEa+cw+StBRgY1JtafSFwN\ | 52eSkFxykJeNqsrWH5S+oxNFlD4dzVuwe8DhTSja8xxbR/Z2cOGdCbzR72rgFWhzx\ | |||
cZgLxVwialuH5VnqJS4JN8PHD91XLfkjMscTo4jmVMpFd3iLVe0hqVFl7MDt6TMkw\ | 2VjBqJzsPLMIQKhO4DGezXehhWwE56YCE+O6c0mKZsfxVrogUvA4HELjVKWmAvtl6\ | |||
IyVFnEZ7B/VIQofdShO+C/7MuupCSLVjQz5xA+Zs6Hw+W9ESD/6BuGs6LF1TcKLxW\ | UnCh8jYzuVG5WSb/QEVPnP5TmcAnLH1g+s++v6d4s8m0gCw1fV5/SITLq9mhho8K3\ | |||
+5K+2zvDY/Cia34HNpRW5io7Iv9/b7iQ==: | +7EPYTU8IU1bLhdxO5Nyt8C8ssinQ98Xw9Q==: | |||
Note that since the covered components list is empty, this signature | Note that since the covered components list is empty, this signature | |||
could be applied by an attacker to an unrelated HTTP message. | could be applied by an attacker to an unrelated HTTP message. In | |||
this example, the nonce parameter is included to prevent the same | ||||
signature from being replayed more than once, but if an attacker | ||||
intercepts the signature and prevents its delivery to the verifier, | ||||
the attacker could apply this signature to another message. | ||||
Therefore, use of an empty covered components set is discouraged. | Therefore, use of an empty covered components set is discouraged. | |||
See Section 7.4 for more discussion. | ||||
Note that the RSA PSS algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
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 input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
"@signature-params": ("@authority" "content-type")\ | +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | |||
;created=1618884475;keyid="test-key-rsa-pss" | "@signature-params": ("@authority" "content-digest")\ | |||
;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: | being added to the message under the label sig-b22: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "content-type")\ | Signature-Input: sig-b22=("@authority" "content-digest")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Signature: sig1=:ik+OtGmM/kFqENDf9Plm8AmPtqtC7C9a+zYSaxr58b/E6h81gh\ | Signature: sig-b22=:Fee1uy9YGZq5UUwwYU6vz4dZNvfw3GYrFl1L6YlVIyUMuWs\ | |||
JS3PcH+m1asiMp8yvccnO/RfaexnqanVB3C72WRNZN7skPTJmUVmoIeqZncdP2mlf\ | wWDNSvql4dVtSeidYjYZUm7SBCENIb5KYy2ByoC3bI+7gydd2i4OAT5lyDtmeapnA\ | |||
xlLP6UbkrgYsk91NS6nwkKC6RRgLhBFqzP42oq8D2336OiQPDAo/04SxZt4Wx9nDG\ | a8uP/b9xUpg+VSPElbBs6JWBIQsd+nMdHDe+ls/IwVMwXktC37SqsnbNyhNp6kcvc\ | |||
uy2SfZJUhsJqZyEWRk4204x7YEB3VxDAAlVgGt8ewilWbIKKTOKp3ymUeQIwptqYw\ | WpevjzFcD2VqdZleUz4jN7P+W5A3wHiMGfIjIWn36KXNB+RKyrlGnIS8yaBBrom5r\ | |||
v0l8mN404PPzRBTpB7+HpClyK4CNp+SVv46+6sHMfJU4taz10s/NoYRmYCGXyadzY\ | cZWLrLbtg6VlrH1+/07RV+kgTh/l10h8qgpl9zQHu7mWbDKTq0tJ8K4ywcPoC4s2I\ | |||
YDj0BYnFdERB6NblI/AOWFGl5Axhhmjg==: | 4rU88jzDKDGdTTQFZoTVZxZmuTM1FvHfzIw==: | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
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 headers in test-request (including the | This example covers all applicable in test-request (including the | |||
message body Digest) plus various elements of the control data, using | content type and length) plus many derived components, again using | |||
the rsa-pss-sha512 algorithm. | the rsa-pss-sha512 algorithm. Note that the Host header field is not | |||
covered because the @authority derived component is included instead. | ||||
The corresponding signature input is: | The corresponding signature input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:56 GMT | "date": Tue, 20 Apr 2021 02:07: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 | |||
"digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ | |||
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: | ||||
"content-length": 18 | "content-length": 18 | |||
"@signature-params": ("date" "@method" "@path" "@query" \ | "@signature-params": ("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "digest" "content-length")\ | "@authority" "content-type" "content-digest" "content-length")\ | |||
;created=1618884475;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: | being added to the message under the label sig-b23: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("date" "@method" "@path" "@query" \ | Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ | |||
"@authority" "content-type" "digest" "content-length")\ | "@authority" "content-type" "content-digest" "content-length")\ | |||
;created=1618884475;keyid="test-key-rsa-pss" | ;created=1618884473;keyid="test-key-rsa-pss" | |||
Signature: sig1=:JuJnJMFGD4HMysAGsfOY6N5ZTZUknsQUdClNG51VezDgPUOW03\ | Signature: sig-b23=:f9nOGJSjCdQ/t+/Mp7gpAHU7Kn1LpnWJE6W2081yRFITJob\ | |||
QMe74vbIdndKwW1BBrHOHR3NzKGYZJ7X3ur23FMCdANe4VmKb3Rc1Q/5YxOO8p7Ko\ | BDODwQNxnjiIdAGstfGKuM2vlc5SyN16//K5dBLGoiaboMco4J6R0zS+8oXqD7o6K\ | |||
yfVa4uUcMk5jB9KAn1M1MbgBnqwZkRWsbv8ocCqrnD85Kavr73lx51k1/gU8w673W\ | RpIZR/qMrFc5Bu6f6UxuoWZPfCxhs3vxL/60JbF8dcdul1b77mWyC07ZjZ9VkelBy\ | |||
T/oBtxPtAn1eFjUyIKyA+XD7kYph82I+ahvm0pSgDPagu917SlqUjeaQaNnlZzO03\ | eF5+zN7v6Al/vnBzMS3H1NLz9dI2sw5Vb7kxQQ6CvEI9v3R30aFgWz4rCuyT0Kt3y\ | |||
Iy1RZ5XpgbNeDLCqSLuZFVID80EohC2CQ1cL5svjslrlCNstd2JCLmhjL7xV3NYXe\ | tQvTHOBsadF66eDe641Sd6O/DgbdFibsE/+ToYopL9NlAuva42NlcFemrozvOKvGI\ | |||
rLim4bqUQGRgDwNJRnqobpS6C1NBns/Q==: | PXdAPqmng/bePoSR6DIaFbWp5aDlNSbWlcA==: | |||
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. | |||
Note that the RSA PSS algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
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 input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@status": 200 | ||||
"content-type": application/json | "content-type": application/json | |||
"digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | "content-digest": sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6\ | |||
"content-length": 18 | sNHpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==: | |||
"@signature-params": ("content-type" "digest" "content-length")\ | "content-length": 23 | |||
;created=1618884475;keyid="test-key-ecc-p256" | "@signature-params": ("@status" "content-type" "content-digest" \ | |||
"content-length");created=1618884473;keyid="test-key-ecc-p256" | ||||
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: | being added to the message under the label sig-b24: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("content-type" "digest" "content-length")\ | Signature-Input: sig-b24=("@status" "content-type" \ | |||
;created=1618884475;keyid="test-key-ecc-p256" | "content-digest" "content-length");created=1618884473\ | |||
Signature: sig1=:n8RKXkj0iseWDmC6PNSQ1GX2R9650v+lhbb6rTGoSrSSx18zmn\ | ;keyid="test-key-ecc-p256" | |||
6fPOtBx48/WffYLO0n1RHHf9scvNGAgGq52Q==: | Signature: sig-b24=:0Ry6HsvzS5VmA6HlfBYS/fYYeNs7fYuA7s0tAdxfUlPGv0C\ | |||
SVuwrrzBOjcCFHTxVRJ01wjvSzM2BetJauj8dsw==: | ||||
Note that the ECDSA algorithm in use here is non-deterministic, | ||||
meaning a different signature value will be created every time the | ||||
algorithm is run. The signature value provided here can be validated | ||||
against the given keys, but newly-generated signature values are not | ||||
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 input is: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"date": Tue, 20 Apr 2021 02:07:55 GMT | ||||
"@authority": example.com | "@authority": example.com | |||
"content-type": application/json | ||||
"@signature-params": ("date" "@authority" "content-type")\ | ||||
;created=1618884473;keyid="test-shared-secret" | ||||
This results in the following Signature-Input and Signature headers | ||||
being added to the message under the label sig-b25: | ||||
NOTE: '\' line wrapping per RFC 8792 | ||||
Signature-Input: sig-b25=("date" "@authority" "content-type")\ | ||||
;created=1618884473;keyid="test-shared-secret" | ||||
Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: | ||||
Before using symmetric signatures in practice, see the discussion of | ||||
the security tradeoffs in Section 7.11. | ||||
B.2.6. Signing a Request using ed25519 | ||||
This example covers portions of the test-request using the ed25519 | ||||
algorithm and the key test-key-ed25519. | ||||
The corresponding signature input is: | ||||
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 | ||||
"@path": /foo | ||||
"@authority": example.com | ||||
"content-type": application/json | "content-type": application/json | |||
"@signature-params": ("@authority" "date" "content-type")\ | "content-length": 18 | |||
;created=1618884475;keyid="test-shared-secret" | "@signature-params": ("date" "@method" "@path" "@authority" \ | |||
"content-type" "content-length");created=1618884473\ | ||||
;keyid="test-key-ed25519" | ||||
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: | being added to the message under the label sig-b26: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=("@authority" "date" "content-type")\ | Signature-Input: sig-b26=("date" "@method" "@path" "@authority" \ | |||
;created=1618884475;keyid="test-shared-secret" | "content-type" "content-length");created=1618884473\ | |||
Signature: sig1=:fN3AMNGbx0V/cIEKkZOvLOoC3InI+lM2+gTv22x3ia8=: | ;keyid="test-key-ed25519" | |||
Signature: sig-b26=:wqcAqbmYJ2ji2glfAMaRy4gruYYnx2nEFN2HN6jrnDnQCK1\ | ||||
u02Gb04v9EDgwUPiu4A0w6vuQv5lIp5WPpBKRCw==: | ||||
B.3. TLS-Terminating Proxies | B.3. TLS-Terminating Proxies | |||
In this example, there is a TLS-terminating reverse proxy sitting in | In this example, there is a TLS-terminating reverse proxy sitting in | |||
front of the resource. The client does not sign the request but | front of the resource. The client does not sign the request but | |||
instead uses mutual TLS to make its call. The terminating proxy | instead uses mutual TLS to make its call. The terminating proxy | |||
validates the TLS stream and injects a Client-Cert header according | validates the TLS stream and injects a Client-Cert header 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 | |||
skipping to change at page 65, line 7 ¶ | skipping to change at page 73, line 7 ¶ | |||
{"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 | |||
the following unsigned request: | the following unsigned request: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?Param=value&pet=Dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: service.internal.example | Host: service.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | |||
BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ | |||
AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ | |||
wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ | |||
C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ | |||
R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ | |||
skipping to change at page 65, line 34 ¶ | skipping to change at page 73, line 34 ¶ | |||
Without a signature, the internal service would need to trust that | Without a signature, the internal service would need to trust that | |||
the incoming connection has the right information. By signing the | the incoming connection has the right information. By signing the | |||
Client-Cert header and other portions of the internal request, the | Client-Cert header and other portions of the internal request, the | |||
internal service can be assured that the correct party, the trusted | internal service can be assured that the correct party, the trusted | |||
proxy, has processed the request and presented it to the correct | proxy, has processed the request and presented it to the correct | |||
service. The proxy's signature input consists of the following: | service. The proxy's signature input consists of the following: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
"@path": /foo | "@path": /foo | |||
"@query": Param=value&pet=Dog | "@query": param=Value&Pet=dog | |||
"@method": POST | "@method": POST | |||
"@authority": service.internal.example | "@authority": service.internal.example | |||
"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=1618884475;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 | |||
5gudRjXaHrAYbEaQUOoY9TuvqWOdPcspkp7YyKCB0XhyAG9cB715hucPPanEK0OVyiN\ | aLFj9LxKArG+6IY9mfdR3e6K1zfoDJKw71fAkWROXZh34FIiWKAgshFIfBjmiU2X01u\ | |||
LJqcoq2Yn1DPWQcnbog== | 6YbDkRgzwyg5L9tky0w== | |||
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: | the internal service with the proxy's signature under the label ttrp: | |||
NOTE: '\' line wrapping per RFC 8792 | NOTE: '\' line wrapping per RFC 8792 | |||
POST /foo?Param=value&pet=Dog HTTP/1.1 | POST /foo?param=Value&Pet=dog HTTP/1.1 | |||
Host: service.internal.example | Host: service.internal.example | |||
Date: Tue, 20 Apr 2021 02:07:55 GMT | Date: Tue, 20 Apr 2021 02:07:55 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Content-Length: 18 | Content-Length: 18 | |||
Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ | |||
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=1618884475;keyid="test-key-ecc-p256" | "client-cert");created=1618884473;keyid="test-key-ecc-p256" | |||
Signature: ttrp=:5gudRjXaHrAYbEaQUOoY9TuvqWOdPcspkp7YyKCB0XhyAG9cB7\ | Signature: ttrp=:aLFj9LxKArG+6IY9mfdR3e6K1zfoDJKw71fAkWROXZh34FIiWK\ | |||
15hucPPanEK0OVyiNLJqcoq2Yn1DPWQcnbog==: | AgshFIfBjmiU2X01u6YbDkRgzwyg5L9tky0w==: | |||
{"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 67, line 17 ¶ | skipping to change at page 75, line 17 ¶ | |||
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, Adam Scarr, Cory J. Slep, Dirk | |||
Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey Yasskin. | 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 | |||
- -08 | ||||
o Editorial fixes. | ||||
o Changed "specialty component" to "derived component". | ||||
o Expanded signature input generation and ABNF rules. | ||||
o Added Ed25519 algorithm. | ||||
o Clarified encoding of ECDSA signature. | ||||
o Clarified use of non-deterministic algorithms. | ||||
- -07 | - -07 | |||
o Added security and privacy considerations. | o Added security and privacy considerations. | |||
o Added pointers to algorithm values from definition sections. | o Added pointers to algorithm values from definition sections. | |||
o Expanded IANA registry sections. | o Expanded IANA registry sections. | |||
o Clarified that the signing and verification algorithms take | o Clarified that the signing and verification algorithms take | |||
application requirements as inputs. | application requirements as inputs. | |||
End of changes. 141 change blocks. | ||||
422 lines changed or deleted | 765 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/ |