draft-ietf-httpbis-message-signatures-01.txt | draft-ietf-httpbis-message-signatures-02.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: 21 May 2021 Bespoke Engineering | Expires: 16 September 2021 Bespoke Engineering | |||
M. Sporny | M. Sporny | |||
Digital Bazaar | Digital Bazaar | |||
17 November 2020 | 15 March 2021 | |||
Signing HTTP Messages | Signing HTTP Messages | |||
draft-ietf-httpbis-message-signatures-01 | draft-ietf-httpbis-message-signatures-02 | |||
Abstract | Abstract | |||
This document describes a mechanism for creating, encoding, and | This document describes a mechanism for creating, encoding, and | |||
verifying digital signatures or message authentication codes over | verifying digital signatures or message authentication codes over | |||
content within an HTTP message. This mechanism supports use cases | content within an HTTP message. This mechanism supports use cases | |||
where the full HTTP message may not be known to the signer, and where | where the full HTTP message may not be known to the signer, and where | |||
the message may be transformed (e.g., by intermediaries) before | the message may be transformed (e.g., by intermediaries) before | |||
reaching the verifier. | reaching the verifier. | |||
Note to Readers | Note to Readers | |||
_RFC EDITOR: please remove this section before publication_ | _RFC EDITOR: please remove this section before publication_ | |||
This work was originally based on draft-cavage-http-signatures-12, | Discussion of this draft takes place on the HTTP working group | |||
but has since diverged from it, to reflect discussion since adoption | mailing list (ietf-http-wg@w3.org), which is archived at | |||
by the HTTP Working Group. In particular, it addresses issues that | https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
have been identified, and adds features to support new use cases. It | (https://lists.w3.org/Archives/Public/ietf-http-wg/). | |||
is a work-in-progress and not yet suitable for deployment. | ||||
Working Group information can be found at https://httpwg.org/ | ||||
(https://httpwg.org/); source code and issues list for this draft can | ||||
be found at https://github.com/httpwg/http-extensions/labels/ | ||||
signatures (https://github.com/httpwg/http-extensions/labels/ | ||||
signatures). | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on 21 May 2021. | This Internet-Draft will expire on 16 September 2021. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2021 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents (https://trustee.ietf.org/ | |||
license-info) in effect on the date of publication of this document. | license-info) in effect on the date of publication of this document. | |||
Please review these documents carefully, as they describe your rights | Please review these documents carefully, as they describe your rights | |||
and restrictions with respect to this document. Code Components | and restrictions with respect to this document. Code Components | |||
extracted from this document must include Simplified BSD License text | extracted from this document must include Simplified BSD License text | |||
as described in Section 4.e of the Trust Legal Provisions and are | as described in Section 4.e of the Trust Legal Provisions and are | |||
provided without warranty as described in the Simplified BSD License. | provided without warranty as described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 5 | 1.1. Requirements Discussion . . . . . . . . . . . . . . . . . 4 | |||
1.2. HTTP Message Transformations . . . . . . . . . . . . . . 5 | 1.2. HTTP Message Transformations . . . . . . . . . . . . . . 5 | |||
1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 6 | 1.3. Safe Transformations . . . . . . . . . . . . . . . . . . 5 | |||
1.4. Conventions and Terminology . . . . . . . . . . . . . . . 7 | 1.4. Conventions and Terminology . . . . . . . . . . . . . . . 6 | |||
1.5. Application of HTTP Message Signatures . . . . . . . . . 7 | ||||
2. Identifying and Canonicalizing Content . . . . . . . . . . . 8 | 2. Identifying and Canonicalizing Content . . . . . . . . . . . 8 | |||
2.1. HTTP Header Fields . . . . . . . . . . . . . . . . . . . 8 | 2.1. HTTP Headers . . . . . . . . . . . . . . . . . . . . . . 8 | |||
2.1.1. Canonicalization Examples . . . . . . . . . . . . . . 9 | 2.1.1. Canonicalized Structured HTTP Headers . . . . . . . . 9 | |||
2.2. Dictionary Structured Field Members . . . . . . . . . . . 9 | 2.1.2. Canonicalization Examples . . . . . . . . . . . . . . 9 | |||
2.2. Dictionary Structured Field Members . . . . . . . . . . . 10 | ||||
2.2.1. Canonicalization Examples . . . . . . . . . . . . . . 10 | 2.2.1. Canonicalization Examples . . . . . . . . . . . . . . 10 | |||
2.3. List Prefixes . . . . . . . . . . . . . . . . . . . . . . 10 | 2.3. List Prefixes . . . . . . . . . . . . . . . . . . . . . . 11 | |||
2.3.1. Canonicalization Examples . . . . . . . . . . . . . . 10 | 2.3.1. Canonicalization Examples . . . . . . . . . . . . . . 11 | |||
2.4. Signature Creation Time . . . . . . . . . . . . . . . . . 11 | 2.4. Specialty Content Fields . . . . . . . . . . . . . . . . 12 | |||
2.5. Signature Expiration Time . . . . . . . . . . . . . . . . 11 | 2.4.1. Request Target . . . . . . . . . . . . . . . . . . . 12 | |||
2.6. Target Endpoint . . . . . . . . . . . . . . . . . . . . . 11 | 2.4.2. Signature Parameters . . . . . . . . . . . . . . . . 13 | |||
2.6.1. Canonicalization Examples . . . . . . . . . . . . . . 12 | 3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 14 | |||
3. HTTP Message Signatures . . . . . . . . . . . . . . . . . . . 12 | 3.1. Signature Metadata . . . . . . . . . . . . . . . . . . . 14 | |||
3.1. Signature Metadata . . . . . . . . . . . . . . . . . . . 13 | 3.2. Creating a Signature . . . . . . . . . . . . . . . . . . 16 | |||
3.2. Creating a Signature . . . . . . . . . . . . . . . . . . 13 | 3.2.1. Choose and Set Signature Metadata Properties . . . . 16 | |||
3.2.1. Choose and Set Signature Metadata Properties . . . . 14 | 3.2.2. Create the Signature Input . . . . . . . . . . . . . 18 | |||
3.2.2. Create the Signature Input . . . . . . . . . . . . . 16 | 3.2.3. Sign the Signature Input . . . . . . . . . . . . . . 19 | |||
3.2.3. Sign the Signature Input . . . . . . . . . . . . . . 17 | 3.3. Verifying a Signature . . . . . . . . . . . . . . . . . . 19 | |||
3.3. Verifying a Signature . . . . . . . . . . . . . . . . . . 17 | 3.3.1. Enforcing Application Requirements . . . . . . . . . 20 | |||
3.3.1. Enforcing Application Requirements . . . . . . . . . 18 | ||||
4. Including a Message Signature in a Message . . . . . . . . . 19 | ||||
4.1. The 'Signature-Input' HTTP Header . . . . . . . . . . . . 19 | ||||
4.1.1. Metadata Parameters . . . . . . . . . . . . . . . . . 19 | ||||
4.2. The 'Signature' HTTP Header . . . . . . . . . . . . . . . 20 | ||||
4.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . 20 | ||||
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21 | ||||
5.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 21 | ||||
5.1.1. Registration Template . . . . . . . . . . . . . . . . 21 | ||||
5.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 22 | ||||
5.2. HTTP Signature Metadata Parameters Registry . . . . . . . 24 | ||||
5.2.1. Registration Template . . . . . . . . . . . . . . . . 24 | ||||
5.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 24 | ||||
6. Security Considerations . . . . . . . . . . . . . . . . . . . 25 | ||||
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 25 | ||||
7.1. Normative References . . . . . . . . . . . . . . . . . . 25 | ||||
7.2. Informative References . . . . . . . . . . . . . . . . . 26 | ||||
Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . 27 | ||||
A.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 27 | ||||
A.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 27 | ||||
A.2. Example keyId Values . . . . . . . . . . . . . . . . . . 28 | ||||
A.3. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 29 | ||||
A.3.1. Signature Generation . . . . . . . . . . . . . . . . 29 | ||||
A.3.2. Signature Verification . . . . . . . . . . . . . . . 32 | ||||
Appendix B. Topics for Working Group Discussion . . . . . . . . 34 | ||||
B.1. Issues . . . . . . . . . . . . . . . . . . . . . . . . . 34 | ||||
B.1.1. Confusing guidance on algorithm and key | ||||
identification . . . . . . . . . . . . . . . . . . . 35 | ||||
B.1.2. Lack of definition of keyId hurts interoperability . 35 | ||||
B.1.3. Algorithm Registry duplicates work of JWA . . . . . . 35 | ||||
B.1.4. Algorithm Registry should not be initialized with | ||||
deprecated entries . . . . . . . . . . . . . . . . . 36 | ||||
B.1.5. No percent-encoding normalization of path/query . . . 36 | ||||
B.1.6. Misleading name for headers parameter . . . . . . . . 36 | ||||
B.1.7. Changes to whitespace in header field values break | ||||
verification . . . . . . . . . . . . . . . . . . . . 36 | ||||
B.1.8. Multiple Set-Cookie headers are not well supported . 36 | ||||
B.1.9. Covered Content list is not signed . . . . . . . . . 37 | ||||
B.1.10. Algorithm is not signed . . . . . . . . . . . . . . . 37 | ||||
B.1.11. Verification key identifier is not signed . . . . . . 37 | ||||
B.1.12. Max values, precision for Integer String and Decimal | ||||
String not defined . . . . . . . . . . . . . . . . . 37 | ||||
B.1.13. keyId parameter value could break list syntax . . . . 37 | ||||
B.1.14. Creation Time and Expiration Time do not allow for | ||||
clock skew . . . . . . . . . . . . . . . . . . . . . 37 | ||||
B.1.15. Should require lowercased header field names as | ||||
identifiers . . . . . . . . . . . . . . . . . . . . . 37 | ||||
B.1.16. Reconcile Date header and Creation Time . . . . . . . 38 | ||||
B.1.17. Remove algorithm-specific rules for content | ||||
identifiers . . . . . . . . . . . . . . . . . . . . . 38 | ||||
B.1.18. Add guidance for signing compressed headers . . . . . 38 | ||||
B.1.19. Transformations to Via header field value break | ||||
verification . . . . . . . . . . . . . . . . . . . . 38 | ||||
B.1.20. Case changes to case-insensitive header field values | ||||
break verification . . . . . . . . . . . . . . . . . 38 | ||||
B.1.21. Need more examples for Signature header . . . . . . . 38 | ||||
B.1.22. Expiration not needed . . . . . . . . . . . . . . . . 39 | ||||
B.2. Features . . . . . . . . . . . . . . . . . . . . . . . . 39 | 4. Including a Message Signature in a Message . . . . . . . . . 21 | |||
B.2.1. Define more content identifiers . . . . . . . . . . . 39 | 4.1. The 'Signature-Input' HTTP Header . . . . . . . . . . . . 21 | |||
B.2.2. Multiple signature support . . . . . . . . . . . . . 39 | 4.2. The 'Signature' HTTP Header . . . . . . . . . . . . . . . 21 | |||
B.2.3. Support for incremental signing of header field value | 4.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . 22 | |||
list items . . . . . . . . . . . . . . . . . . . . . 40 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23 | |||
B.2.4. Support expected authority changes . . . . . . . . . 40 | 5.1. HTTP Signature Algorithms Registry . . . . . . . . . . . 23 | |||
B.2.5. Support for signing specific cookies . . . . . . . . 40 | 5.1.1. Registration Template . . . . . . . . . . . . . . . . 23 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 41 | 5.1.2. Initial Contents . . . . . . . . . . . . . . . . . . 24 | |||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 41 | 5.2. HTTP Signature Metadata Parameters Registry . . . . . . . 25 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 43 | 5.2.1. Registration Template . . . . . . . . . . . . . . . . 25 | |||
5.2.2. Initial Contents . . . . . . . . . . . . . . . . . . 25 | ||||
5.3. HTTP Signature Specialty Content Identifiers Registry . . 26 | ||||
5.3.1. Registration Template . . . . . . . . . . . . . . . . 26 | ||||
5.3.2. Initial Contents . . . . . . . . . . . . . . . . . . 26 | ||||
6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 | ||||
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | ||||
7.1. Normative References . . . . . . . . . . . . . . . . . . 27 | ||||
7.2. Informative References . . . . . . . . . . . . . . . . . 28 | ||||
Appendix A. Detecting HTTP Message Signatures . . . . . . . . . 29 | ||||
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 29 | ||||
B.1. Example Keys . . . . . . . . . . . . . . . . . . . . . . 29 | ||||
B.1.1. Example Key RSA test . . . . . . . . . . . . . . . . 29 | ||||
B.2. Example keyid Values . . . . . . . . . . . . . . . . . . 30 | ||||
B.3. Test Cases . . . . . . . . . . . . . . . . . . . . . . . 31 | ||||
B.3.1. Signature Generation . . . . . . . . . . . . . . . . 31 | ||||
B.3.2. Signature Verification . . . . . . . . . . . . . . . 34 | ||||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 36 | ||||
Document History . . . . . . . . . . . . . . . . . . . . . . . . 37 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 39 | ||||
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 7, line 31 ¶ | skipping to change at page 6, line 50 ¶ | |||
For brevity, the term "signature" on its own is used in this document | For brevity, the term "signature" on its own is used in this document | |||
to refer to both digital signatures and keyed MACs. Similarly, the | to refer to both digital signatures and keyed MACs. Similarly, the | |||
verb "sign" refers to the generation of either a digital signature or | verb "sign" refers to the generation of either a digital signature or | |||
keyed MAC over a given input string. The qualified term "digital | keyed MAC over a given input string. The qualified term "digital | |||
signature" refers specifically to the output of an asymmetric | signature" refers specifically to the output of an asymmetric | |||
cryptographic signing operation. | cryptographic signing operation. | |||
In addition to those listed above, this document uses the following | In addition to those listed above, this document uses the following | |||
terms: | terms: | |||
Decimal String | Signer: | |||
An Integer String optionally concatenated with a period "." | ||||
followed by a second Integer String, representing a positive real | ||||
number expressed in base 10. The first Integer String represents | ||||
the integral portion of the number, while the optional second | ||||
Integer String represents the fractional portion of the number. | ||||
(( Editor's note: There's got to be a definition for this that we | ||||
can reference. )) | ||||
Integer String | ||||
A US-ASCII string of one or more digits "0-9", representing a | ||||
positive integer in base 10. (( Editor's note: There's got to be a | ||||
definition for this that we can reference. )) | ||||
Signer | ||||
The entity that is generating or has generated an HTTP Message | The entity that is generating or has generated an HTTP Message | |||
Signature. | Signature. | |||
Verifier | Verifier: | |||
An entity that is verifying or has verified an HTTP Message | An entity that is verifying or has verified an HTTP Message | |||
Signature against an HTTP Message. Note that an HTTP Message | Signature against an HTTP Message. Note that an HTTP Message | |||
Signature may be verified multiple times, potentially by different | Signature may be verified multiple times, potentially by different | |||
entities. | entities. | |||
The term "Unix time" is defined by [POSIX.1] section 4.16 | ||||
(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ | ||||
V1_chap04.html#tag_04_16). | ||||
This document contains non-normative examples of partial and complete | This document contains non-normative examples of partial and complete | |||
HTTP messages. To improve readability, header fields may be split | HTTP messages. To improve readability, header fields may be split | |||
into multiple lines, using the "obs-fold" syntax. This syntax is | into multiple lines, using the "obs-fold" syntax. This syntax is | |||
deprecated in [MESSAGING], and senders MUST NOT generate messages | deprecated in [MESSAGING], and senders MUST NOT generate messages | |||
that include it. | that include it. | |||
Additionally, some examples use '\' line wrapping for long values | ||||
that contain no whitespace, as per [RFC8792]. | ||||
1.5. Application of HTTP Message Signatures | ||||
HTTP Message Signatures are designed to be a general-purpose security | ||||
mechanism applicable in a wide variety of circumstances and | ||||
applications. In order to properly and safely apply HTTP Message | ||||
Signatures, an application or profile of this specification MUST | ||||
specify all of the following items: | ||||
* The set of content identifiers (Section 2) that are expected and | ||||
required. For example, an authorization protocol would mandate | ||||
that the "Authorization" header be covered to protect the | ||||
authorization credentials, as well as a "*created" field to allow | ||||
replay detection. | ||||
* A means of retrieving the key material used to verify the | ||||
signature. An application will usually use the "keyid" field of | ||||
the "Signature-Input" header value and define rules for resolving | ||||
a key from there. | ||||
* A means of determining the signature algorithm used to verify the | ||||
signature content is appropriate for the key material. | ||||
* A means of determining that a given key and algorithm presented in | ||||
the request are appropriate for the request being made. For | ||||
example, a server expecting only ECDSA signatures should know to | ||||
reject any RSA signatures; or a server expecting asymmetric | ||||
cryptography should know to reject any symmetric cryptography. | ||||
The details of this kind of profiling are the purview of the | ||||
application and outside the scope of this specification. | ||||
2. Identifying and Canonicalizing Content | 2. Identifying and Canonicalizing Content | |||
In order to allow signers and verifiers to establish which content is | In order to allow signers and verifiers to establish which content is | |||
covered by a signature, this document defines content identifiers for | covered by a signature, this document defines content identifiers for | |||
signature metadata and discrete pieces of message content that may be | data items covered by an HTTP Message Signature. | |||
covered by an HTTP Message Signature. | ||||
Some content within HTTP messages may undergo transformations that | Some content within HTTP messages can undergo transformations that | |||
change the bitwise value without altering meaning of the content (for | change the bitwise value without altering meaning of the content (for | |||
example, the merging together of header fields with the same name). | example, the merging together of header fields with the same name). | |||
Message content must therefore be canonicalized before it is signed, | Message content must therefore be canonicalized before it is signed, | |||
to ensure that a signature can be verified despite such innocuous | to ensure that a signature can be verified despite such intermediary | |||
transformations. This document defines rules for each content | transformations. This document defines rules for each content | |||
identifier that transform the identifier's associated content into | identifier that transform the identifier's associated content into | |||
such a canonical form. | such a canonical form. | |||
The following sections define content identifiers, their associated | Content identifiers are defined using production grammar defined by | |||
content, and their canonicalization rules. | [RFC8941] section 4. The content identifier is an "sf-string" value. | |||
The content identifier type MAY define parameters which are included | ||||
using the "parameters" rule. | ||||
2.1. HTTP Header Fields | content-identifier = sf-string parameters | |||
An HTTP header field is identified by its header field name. While | Note that this means the value of the identifier itself is encased in | |||
HTTP header field names are case-insensitive, implementations MUST | double quotes, with parameters following as a semicolon-separated | |||
use lowercased field names (e.g., "content-type", "date", "etag") | list, such as ""cache-control"", ""date"", or ""@signature-params"". | |||
when using them as content identifiers. | ||||
An HTTP header field value is canonicalized as follows: | The following sections define content identifier types, their | |||
parameters, their associated content, and their canonicalization | ||||
rules. | ||||
2.1. HTTP Headers | ||||
The content identifier for an HTTP header is the lowercased form of | ||||
its header field name. While HTTP header field names are case- | ||||
insensitive, implementations MUST use lowercased field names (e.g., | ||||
"content-type", "date", "etag") when using them as content | ||||
identifiers. | ||||
Unless overridden by additional parameters and rules, the HTTP header | ||||
field value MUST be canonicalized with the following steps: | ||||
1. Create an ordered list of the field values of each instance of | 1. Create an ordered list of the field values of each instance of | |||
the header field in the message, in the order that they occur (or | the header field in the message, in the order that they occur (or | |||
will occur) in the message. | will occur) in the message. | |||
2. Strip leading and trailing whitespace from each item in the list. | 2. Strip leading and trailing whitespace from each item in the list. | |||
3. Concatenate the list items together, with a comma "," and space " | 3. Concatenate the list items together, with a comma "," and space " | |||
" between each item. The resulting string is the canonicalized | " between each item. | |||
value. | ||||
2.1.1. Canonicalization Examples | The resulting string is the canonicalized value. | |||
2.1.1. Canonicalized Structured HTTP Headers | ||||
If value of the the HTTP header in question is a structured field | ||||
[RFC8941], the content identifier MAY include the "sf" parameter. If | ||||
this parameter is included, the HTTP header value MUST be | ||||
canonicalized using the rules specified in [RFC8941] section 4. Note | ||||
that this process will replace any optional whitespace with a single | ||||
space. | ||||
The resulting string is used as the field value input in Section 2.1. | ||||
2.1.2. Canonicalization Examples | ||||
This section contains non-normative examples of canonicalized values | This section contains non-normative examples of canonicalized values | |||
for header fields, given the following example HTTP message: | for header fields, given the following example HTTP message: | |||
HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
Server: www.example.com | Server: www.example.com | |||
Date: Tue, 07 Jun 2014 20:51:35 GMT | Date: Tue, 07 Jun 2014 20:51:35 GMT | |||
X-OWS-Header: Leading and trailing whitespace. | X-OWS-Header: Leading and trailing whitespace. | |||
X-Obs-Fold-Header: Obsolete | X-Obs-Fold-Header: Obsolete | |||
line folding. | line folding. | |||
X-Empty-Header: | X-Empty-Header: | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
The following table shows example canonicalized values for header | The following table shows example canonicalized values for header | |||
fields, given that message: | fields, given that message: | |||
+===================+==================================+ | +=====================+==================================+ | |||
| Header Field | Canonicalized Value | | | Header Field | Canonicalized Value | | |||
+===================+==================================+ | +=====================+==================================+ | |||
| cache-control | max-age=60, must-revalidate | | | "cache-control" | max-age=60, must-revalidate | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| date | Tue, 07 Jun 2014 20:51:35 GMT | | | "date" | Tue, 07 Jun 2014 20:51:35 GMT | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| server | www.example.com | | | "server" | www.example.com | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| x-empty-header | | | | "x-empty-header" | | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| x-obs-fold-header | Obsolete line folding. | | | "x-obs-fold-header" | Obsolete line folding. | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
| x-ows-header | Leading and trailing whitespace. | | | "x-ows-header" | Leading and trailing whitespace. | | |||
+-------------------+----------------------------------+ | +---------------------+----------------------------------+ | |||
Table 1: Non-normative examples of header field | Table 1: Non-normative examples of header field | |||
canonicalization. | canonicalization. | |||
2.2. Dictionary Structured Field Members | 2.2. Dictionary Structured Field Members | |||
An individual member in the value of a Dictionary Structured Field is | An individual member in the value of a Dictionary Structured Field is | |||
identified by the lowercased field name, followed by a semicolon | identified by using the parameter "key" on the content identifier for | |||
"":"", followed by the member name. An individual member in the | the header. The value of this parameter is a the key being | |||
value of a Dictionary Structured Field is canonicalized by applying | identified, without any parameters present on that key in the | |||
the serialization algorithm described in Section 4.1.2 of | original dictionary. | |||
[StructuredFields] on a Dictionary containing only that member. | ||||
An individual member in the value of a Dictionary Structured Field is | ||||
canonicalized by applying the serialization algorithm described in | ||||
Section 4.1.2 of [RFC8941] on a Dictionary containing only that | ||||
member. | ||||
2.2.1. Canonicalization Examples | 2.2.1. Canonicalization Examples | |||
This section contains non-normative examples of canonicalized values | This section contains non-normative examples of canonicalized values | |||
for Dictionary Structured Field Members given the following example | for Dictionary Structured Field Members given the following example | |||
header field, whose value is assumed to be a Dictionary: | header field, whose value is assumed to be a Dictionary: | |||
X-Dictionary: a=1, b=2;x=1;y=2, c=(a, b, c) | X-Dictionary: a=1, b=2;x=1;y=2, c=(a b c) | |||
The following table shows example canonicalized values for different | The following table shows example canonicalized values for different | |||
content identifiers, given that field: | content identifiers, given that field: | |||
+====================+=====================+ | +======================+=====================+ | |||
| Content Identifier | Canonicalized Value | | | Content Identifier | Canonicalized Value | | |||
+====================+=====================+ | +======================+=====================+ | |||
| x-dictionary:a | 1 | | | "x-dictionary";key=a | 1 | | |||
+--------------------+---------------------+ | +----------------------+---------------------+ | |||
| x-dictionary:b | 2;x=1;y=2 | | | "x-dictionary";key=b | 2;x=1;y=2 | | |||
+--------------------+---------------------+ | +----------------------+---------------------+ | |||
| x-dictionary:c | (a, b, c) | | | "x-dictionary";key=c | (a, b, c) | | |||
+--------------------+---------------------+ | +----------------------+---------------------+ | |||
Table 2: Non-normative examples of | Table 2: Non-normative examples of | |||
Dictionary member canonicalization. | Dictionary member canonicalization. | |||
2.3. List Prefixes | 2.3. List Prefixes | |||
A prefix of a List Structured Field consisting of the first N members | A prefix of a List Structured Field consisting of the first N members | |||
in the field's value (where N is an integer greater than 0 and less | in the field's value (where N is an integer greater than 0 and less | |||
than or equal to the number of members in the List) is identified by | than or equal to the number of members in the List) is identified by | |||
the lowercased field name, followed by a semicolon "":"", followed by | the parameter "prefix" with the value of N as an integer. | |||
N expressed as an Integer String. A list prefix is canonicalized by | ||||
applying the serialization algorithm described in Section 4.1.1 of | A list prefix value is canonicalized by applying the serialization | |||
[StructuredFields] on a List containing only the first N members as | algorithm described in Section 4.1.1 of [RFC8941] on a List | |||
specified in the list prefix, in the order they appear in the | containing only the first N members as specified in the list prefix, | |||
original List. | in the order they appear in the original List. | |||
2.3.1. Canonicalization Examples | 2.3.1. Canonicalization Examples | |||
This section contains non-normative examples of canonicalized values | This section contains non-normative examples of canonicalized values | |||
for list prefixes given the following example header fields, whose | for list prefixes given the following example header fields, whose | |||
values are assumed to be Dictionaries: | values are assumed to be Dictionaries: | |||
X-List-A: (a, b, c, d, e, f) | X-List-A: (a b c d e f) | |||
X-List-B: () | X-List-B: () | |||
The following table shows example canonicalized values for different | The following table shows example canonicalized values for different | |||
content identifiers, given those fields: | content identifiers, given those fields: | |||
+====================+=====================+ | +=====================+=====================+ | |||
| Content Identifier | Canonicalized Value | | | Content Identifier | Canonicalized Value | | |||
+====================+=====================+ | +=====================+=====================+ | |||
| x-list-a:0 | () | | | "x-list-a";prefix=0 | () | | |||
+--------------------+---------------------+ | +---------------------+---------------------+ | |||
| x-list-a:1 | (a) | | | "x-list-a";prefix=1 | (a) | | |||
+--------------------+---------------------+ | +---------------------+---------------------+ | |||
| x-list-a:3 | (a, b, c) | | | "x-list-a";prefix=3 | (a, b, c) | | |||
+--------------------+---------------------+ | +---------------------+---------------------+ | |||
| x-list-a:6 | (a, b, c, d, e, f) | | | "x-list-a";prefix=6 | (a, b, c, d, e, f) | | |||
+--------------------+---------------------+ | +---------------------+---------------------+ | |||
| x-list-b:0 | () | | | "x-list-b";prefix=0 | () | | |||
+--------------------+---------------------+ | +---------------------+---------------------+ | |||
Table 3: Non-normative examples of list | ||||
prefix canonicalization. | ||||
2.4. Signature Creation Time | Table 3: Non-normative examples of list | |||
prefix canonicalization. | ||||
The signature's Creation Time (Section 3.1) is identified by the | 2.4. Specialty Content Fields | |||
"*created" identifier. | ||||
Its canonicalized value is an Integer String containing the | Content not found in an HTTP header can be included in the signature | |||
signature's Creation Time expressed as the number of seconds since | base string by defining a content identifier and the canonicalization | |||
the Epoch, as defined in Section 4.16 | method for its content. | |||
(https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ | ||||
V1_chap04.html#tag_04_16) of [POSIX.1]. | ||||
The use of seconds since the Epoch to canonicalize a timestamp | To differentiate speciality content identifiers from HTTP headers, | |||
simplifies processing and avoids timezone management required by | specialty content identifiers MUST start with the "at" "@" character. | |||
specifications such as [RFC3339]. | This specification defines the following specialty content | |||
identifiers: | ||||
2.5. Signature Expiration Time | @request-target The target request endpoint. Section 2.4.1 | |||
The signature's Expiration Time (Section 3.1) is identified by the | @signature-params The signature metadata parameters for this | |||
"*expires" identifier. | signature. Section 2.4.2 | |||
Its canonicalized value is a Decimal String containing the | Additional specialty content identifiers MAY be defined and | |||
signature's Expiration Time expressed as the number of seconds since | registered in the HTTP Signatures Specialty Content Identifier | |||
the Epoch, as defined in Section 4.16 | Registry. Section 5.3 | |||
(https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ | ||||
V1_chap04.html#tag_04_16) of [POSIX.1]. | ||||
2.6. Target Endpoint | 2.4.1. Request Target | |||
The request target endpoint, consisting of the request method and the | The request target endpoint, consisting of the request method and the | |||
path and query of the effective request URI, is identified by the | path and query of the effective request URI, is identified by the | |||
"*request-target" identifier. | "@request-target" identifier. | |||
Its value is canonicalized as follows: | Its value is canonicalized as follows: | |||
1. Take the lowercased HTTP method of the message. | 1. Take the lowercased HTTP method of the message. | |||
2. Append a space " ". | 2. Append a space " ". | |||
3. Append the path and query of the request target of the message, | 3. Append the path and query of the request target of the message, | |||
formatted according to the rules defined for the :path pseudo- | formatted according to the rules defined for the :path pseudo- | |||
header in [HTTP2], Section 8.1.2.3. The resulting string is the | header in [HTTP2], Section 8.1.2.3. The resulting string is the | |||
canonicalized value. | canonicalized value. | |||
2.6.1. Canonicalization Examples | 2.4.1.1. Canonicalization Examples | |||
The following table contains non-normative example HTTP messages and | The following table contains non-normative example HTTP messages and | |||
their canonicalized "*request-target" values. | their canonicalized "@request-target" values. | |||
+=========================+=================+ | +=========================+=================+ | |||
|HTTP Message | *request-target | | |HTTP Message | @request-target | | |||
+=========================+=================+ | +=========================+=================+ | |||
| POST /?param=value HTTP/1.1| post | | | POST /?param=value HTTP/1.1| post | | |||
| Host: www.example.com | /?param=value | | | Host: www.example.com | /?param=value | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
| POST /a/b HTTP/1.1 | post /a/b | | | POST /a/b HTTP/1.1 | post /a/b | | |||
| Host: www.example.com | | | | Host: www.example.com | | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
| GET http://www.example.com/a/ HTTP/1.1| get /a/ | | | GET http://www.example.com/a/ HTTP/1.1| get /a/ | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
| GET http://www.example.com HTTP/1.1| get / | | | GET http://www.example.com HTTP/1.1| get / | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
| CONNECT server.example.com:80 HTTP/1.1| connect / | | | CONNECT server.example.com:80 HTTP/1.1| connect / | | |||
| Host: server.example.com| | | | Host: server.example.com| | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
| OPTIONS * HTTP/1.1 | options * | | | OPTIONS * HTTP/1.1 | options * | | |||
| Host: server.example.com| | | | Host: server.example.com| | | |||
+-------------------------+-----------------+ | +-------------------------+-----------------+ | |||
Table 4: Non-normative examples of "*request-target" | Table 4: Non-normative examples of "@request-target" | |||
canonicalization. | canonicalization. | |||
2.4.2. Signature Parameters | ||||
The signature parameters special content is identified by the | ||||
"@signature-params" identifier. | ||||
Its canonicalized value is the serialization of the signature | ||||
parameters for this signature, including the covered content list | ||||
with all associated parameters. Section 3.1 | ||||
Note that an HTTP message could contain multiple signatures, but only | ||||
the signature parameters used for the current signature are included. | ||||
2.4.2.1. Canonicalization Examples | ||||
Given the following signature parameters: | ||||
+==============+=========================================+ | ||||
| Property | Value | | ||||
+==============+=========================================+ | ||||
| Algorithm | hs2019 | | ||||
+--------------+-----------------------------------------+ | ||||
| Covered | "@request-target", "host", "date", | | ||||
| Content | "cache-control", "x-emptyheader", | | ||||
| | "x-example", "x-dictionary;key=b", | | ||||
| | "x-dictionary;key=a", "x-list;prefix=3" | | ||||
+--------------+-----------------------------------------+ | ||||
| Creation | 1402174295 | | ||||
| Time | | | ||||
+--------------+-----------------------------------------+ | ||||
| Expiration | 1402174595 | | ||||
| Time | | | ||||
+--------------+-----------------------------------------+ | ||||
| Verification | The public key provided in | | ||||
| Key Material | Appendix B.1.1 and identified by the | | ||||
| | "keyid" value "test-key-a". | | ||||
+--------------+-----------------------------------------+ | ||||
Table 5 | ||||
The signature parameter value is defined as: | ||||
"@signature-params": ("@request-target" "host" "date" "cache-control" "x-empty-header" "x-example" "x-dictionary";key=b "x-dictionary";key=a "x-list";prefix=3); keyid="test-key-a"; alg="hs2019"; created=1402170695; expires=1402170995 | ||||
3. HTTP Message Signatures | 3. HTTP Message Signatures | |||
An HTTP Message Signature is a signature over a string generated from | An HTTP Message Signature is a signature over a string generated from | |||
a subset of the content in an HTTP message and metadata about the | a subset of the content in an HTTP message and metadata about the | |||
signature itself. When successfully verified against an HTTP | signature itself. When successfully verified against an HTTP | |||
message, it provides cryptographic proof that with respect to the | message, it provides cryptographic proof that with respect to the | |||
subset of content that was signed, the message is semantically | subset of content that was signed, the message is semantically | |||
equivalent to the message for which the signature was generated. | equivalent to the message for which the signature was generated. | |||
3.1. Signature Metadata | 3.1. Signature Metadata | |||
HTTP Message Signatures have metadata properties that provide | HTTP Message Signatures have metadata properties that provide | |||
information regarding the signature's generation and/or verification. | information regarding the signature's generation and/or verification. | |||
The following metadata properties are defined: | The following metadata properties are defined: | |||
Algorithm | Algorithm: | |||
An HTTP Signature Algorithm defined in the HTTP Signature | An HTTP Signature Algorithm defined in the HTTP Signature | |||
Algorithms Registry defined in this document. It describes the | Algorithms Registry defined in this document, represented as a | |||
signing and verification algorithms for the signature. | string. It describes the signing and verification algorithms for | |||
the signature. | ||||
Creation Time | ||||
Creation Time: | ||||
A timestamp representing the point in time that the signature was | A timestamp representing the point in time that the signature was | |||
generated. Sub-second precision is not supported. A signature's | generated, represented as an integer. Sub-second precision is not | |||
Creation Time MAY be undefined, indicating that it is unknown. | supported. A signature's Creation Time MAY be undefined, | |||
indicating that it is unknown. | ||||
Covered Content | Expiration Time: | |||
A timestamp representing the point in time at which the signature | ||||
expires, represented as an integer. An expired signature always | ||||
fails verification. A signature's Expiration Time MAY be | ||||
undefined, indicating that the signature does not expire. | ||||
Verification Key Material: | ||||
The key material required to verify the signature. | ||||
Covered Content: | ||||
An ordered list of content identifiers (Section 2) that indicates | An ordered list of content identifiers (Section 2) that indicates | |||
the metadata and message content that is covered by the signature. | the metadata and message content that is covered by the signature. | |||
The order of identifiers in this list affects signature generation | This list MUST NOT include the "@signature-params" content | |||
and verification, and therefore MUST be preserved. | identifier. | |||
Expiration Time | The signature metadata is serialized using the rules in [RFC8941] | |||
section 4 as follows: | ||||
A timestamp representing the point in time at which the signature | 1. Let the output be an empty string. | |||
expires. An expired signature always fails verification. A | ||||
signature's Expiration Time MAY be undefined, indicating that the | ||||
signature does not expire. | ||||
Verification Key Material | 2. Serialize the content identifiers as an ordered "inner-list" | |||
according to [RFC8941] section 4.1.1.1 and append this to the | ||||
output. | ||||
The key material required to verify the signature. | 3. Append the signature metadata as parameters according to | |||
[RFC8941] section 4.1.1.2 in the any order, skipping fields that | ||||
are not available: | ||||
* "alg": Algorithm as an "sf-string" value. | ||||
* "keyid": Verification Key Material as an "sf-string" value. | ||||
* "created": Creation Time as an "sf-integer" timestamp value. | ||||
* "expires": Expiration Time as an "sf-integer" timestamp value. | ||||
Note that the "inner-list" serialization is used instead of the "sf- | ||||
list" serialization in order to facilitate this value's inclusion in | ||||
the "Signature-Input" header's dictionary, as discussed in | ||||
Section 4.1. | ||||
The Table 6 values would be serialized as follows: | ||||
("@request-target" "host" "date" "cache-control" "x-empty-header" "x-example"); keyid="test-key-a"; alg="hs2019"; created=1402170695; expires=1402170995 | ||||
3.2. Creating a Signature | 3.2. Creating a Signature | |||
In order to create a signature, a signer completes the following | In order to create a signature, a signer completes the following | |||
process: | process: | |||
1. Choose key material and algorithm, and set metadata properties | 1. Choose key material and algorithm, and set metadata properties | |||
Section 3.2.1 | Section 3.2.1 | |||
2. Create the Signature Input Section 3.2.2 | 2. Create the Signature Input Section 3.2.2 | |||
skipping to change at page 14, line 41 ¶ | skipping to change at page 17, line 15 ¶ | |||
5. The signer creates an ordered list of content identifiers | 5. The signer creates an ordered list of content identifiers | |||
representing the message content and signature metadata to be | representing the message content and signature metadata to be | |||
covered by the signature, and assigns this list as the | covered by the signature, and assigns this list as the | |||
signature's Covered Content. | signature's Covered Content. | |||
* Each identifier MUST be one of those defined in Section 2. | * Each identifier MUST be one of those defined in Section 2. | |||
* This list MUST NOT be empty, as this would result in creating | * This list MUST NOT be empty, as this would result in creating | |||
a signature over the empty string. | a signature over the empty string. | |||
* If the signature's Algorithm name does not start with rsa, | * Signers SHOULD include "@request-target" in the list. | |||
hmac, or ecdsa, signers SHOULD include "*created" and | ||||
"*request-target" in the list. | ||||
* If the signature's Algorithm starts with rsa, hmac, or ecdsa, | * Signers SHOULD include a date stamp, such as the "date" | |||
signers SHOULD include "date" and "*request-target" in the | header. Alternatively, the "created" signature metadata | |||
list. | parameter can fulfil this role. | |||
* Further guidance on what to include in this list and in what | * Further guidance on what to include in this list and in what | |||
order is out of scope for this document. However, the list | order is out of scope for this document. However, the list | |||
order is significant and once established for a given | order is significant and once established for a given | |||
signature it MUST be preserved for that signature. | signature it MUST be preserved for that signature. | |||
* Note that the signature metadata is not included in the | ||||
explicit list of covered content identifiers since its value | ||||
is always covered. | ||||
For example, given the following HTTP message: | For example, given the following HTTP message: | |||
GET /foo HTTP/1.1 | GET /foo HTTP/1.1 | |||
Host: example.org | Host: example.org | |||
Date: Sat, 07 Jun 2014 20:51:35 GMT | Date: Sat, 07 Jun 2014 20:51:35 GMT | |||
X-Example: Example header | X-Example: Example header | |||
with some whitespace. | with some whitespace. | |||
X-EmptyHeader: | X-EmptyHeader: | |||
X-Dictionary: a=1, b=2 | X-Dictionary: a=1, b=2 | |||
X-List: (a, b, c, d) | X-List: (a b c d) | |||
Cache-Control: max-age=60 | Cache-Control: max-age=60 | |||
Cache-Control: must-revalidate | Cache-Control: must-revalidate | |||
The following table presents a non-normative example of metadata | The following table presents a non-normative example of metadata | |||
values that a signer may choose: | values that a signer may choose: | |||
+==============+================================================+ | +==============+=========================================+ | |||
| Property | Value | | | Property | Value | | |||
+==============+================================================+ | +==============+=========================================+ | |||
| Algorithm | hs2019 | | | Algorithm | hs2019 | | |||
+--------------+------------------------------------------------+ | +--------------+-----------------------------------------+ | |||
| Covered | "*request-target", "*created", "host", "date", | | | Covered | "@request-target", "host", "date", | | |||
| Content | "cache-contol", "x-emptyheader", "x-example", | | | Content | "cache-control", "x-emptyheader", | | |||
| | "x-dictionary:b", "x-dictionary:a", "x-list:3" | | | | "x-example", "x-dictionary;key=b", | | |||
+--------------+------------------------------------------------+ | | | "x-dictionary;key=a", "x-list;prefix=3" | | |||
| Creation | 1402174295 | | +--------------+-----------------------------------------+ | |||
| Time | | | | Creation | 1402174295 | | |||
+--------------+------------------------------------------------+ | | Time | | | |||
| Expiration | 1402174595 | | +--------------+-----------------------------------------+ | |||
| Time | | | | Expiration | 1402174595 | | |||
+--------------+------------------------------------------------+ | | Time | | | |||
| Verification | The public key provided in Appendix A.1.1 and | | +--------------+-----------------------------------------+ | |||
| Key Material | identified by the "keyId" value "test-key-a". | | | Verification | The public key provided in | | |||
+--------------+------------------------------------------------+ | | Key Material | Appendix B.1.1 and identified by the | | |||
| | "keyid" value "test-key-a". | | ||||
+--------------+-----------------------------------------+ | ||||
Table 5: Non-normative example metadata values | Table 6: Non-normative example metadata values | |||
3.2.2. Create the Signature Input | 3.2.2. Create the Signature Input | |||
The Signature Input is a US-ASCII string containing the content that | The Signature Input is a US-ASCII string containing the content that | |||
will be signed. To create it, the signer concatenates together | will be signed. To create it, the signer or verifier concatenates | |||
entries for each identifier in the signature's Covered Content in the | together entries for each identifier in the signature's Covered | |||
order it occurs in the list, with each entry separated by a newline | Content in the order it occurs in the list, with each entry separated | |||
""\n"". An identifier's entry is a US-ASCII string consisting of the | by a newline ""\n"". An identifier's entry is a "sf-string" followed | |||
lowercased identifier followed with a colon "":"", a space "" "", and | with a colon "":"", a space "" "", and the identifier's canonicalized | |||
the identifier's canonicalized value (described below). | value. | |||
If Covered Content contains "*created" and the signature's Creation | ||||
Time is undefined or the signature's Algorithm name starts with | ||||
"rsa", "hmac", or "ecdsa" an implementation MUST produce an error. | ||||
If Covered Content contains "*expires" and the signature does not | The signer or verifier then includes the signature metadata specialty | |||
have an Expiration Time or the signature's Algorithm name starts with | field "@signature-params" as the last entry in the covered content, | |||
"rsa", "hmac", or "ecdsa" an implementation MUST produce an error. | separated by a newline ""\n"". Section 2.4.2 | |||
If Covered Content contains an identifier for a header field that is | If Covered Content contains an identifier for a header field that is | |||
not present or malformed in the message, the implementation MUST | malformed or is not present in the message, the implementation MUST | |||
produce an error. | produce an error. | |||
If Covered Content contains an identifier for a Dictionary member | If Covered Content contains an identifier for a Dictionary member | |||
that references a header field that is not present, is malformed in | that references a header field using the "key" parameter that is not | |||
the message, or is not a Dictionary Structured Field, the | present, is malformed in the message, or is not a Dictionary | |||
implementation MUST produce an error. If the header field value does | Structured Field, the implementation MUST produce an error. If the | |||
not contain the specified member, the implementation MUST produce an | header field value does not contain the specified member, the | |||
error. | implementation MUST produce an error. | |||
If Covered Content contains an identifier for a List Prefix that | If Covered Content contains an identifier for a List Prefix that | |||
references a header field that is not present, is malformed in the | references a header field using the "prefix" parameter that is not | |||
message, or is not a List Structured Field, the implementation MUST | present, is malformed in the message, or is not a List Structured | |||
produce an error. If the header field value contains fewer than the | Field, the implementation MUST produce an error. If the header field | |||
specified number of members, the implementation MUST produce an | value contains fewer than the specified number of members, the | |||
error. | implementation MUST produce an error. | |||
For the non-normative example Signature metadata in Table 5, the | For the non-normative example Signature metadata in Table 6, the | |||
corresponding Signature Input is: | corresponding Signature Input is: | |||
*request-target: get /foo | "@request-target": get /foo | |||
*created: 1402170695 | "host": example.org | |||
host: example.org | "date": Tue, 07 Jun 2014 20:51:35 GMT | |||
date: Tue, 07 Jun 2014 20:51:35 GMT | "cache-control": max-age=60, must-revalidate | |||
cache-control: max-age=60, must-revalidate | "x-emptyheader": | |||
x-emptyheader: | "x-example": Example header with some whitespace. | |||
x-example: Example header with some whitespace. | "x-dictionary";key=b: 2 | |||
x-dictionary: b=2 | "x-dictionary";key=a: 1 | |||
x-dictionary: a=1 | "x-list";prefix=3: (a, b, c) | |||
x-list: (a, b, c) | "@signature-params": ("@request-target" "host" "date" "cache-control" "x-empty-header" "x-example" "x-dictionary";key=b "x-dictionary";key=b "x-list";prefix=3); keyid="test-key-a"; alg="hs2019"; created=1402170695; expires=1402170995 | |||
Figure 1: Non-normative example Signature Input | Figure 1: Non-normative example Signature Input | |||
3.2.3. Sign the Signature Input | 3.2.3. Sign the Signature Input | |||
The signer signs the Signature Input using the signing algorithm | The signer signs the Signature Input using the signing algorithm | |||
described by the signature's Algorithm property, and the key material | described by the signature's Algorithm property, and the key material | |||
chosen by the signer. The signer then encodes the result of that | chosen by the signer. The signer then encodes the result of that | |||
operation as a base 64-encoded string [RFC4648]. This string is the | operation as a base 64-encoded string [RFC4648]. This string is the | |||
signature value. | signature value. | |||
For the non-normative example Signature metadata in Section 3.2.1 and | For the non-normative example Signature metadata in Section 3.2.1 and | |||
skipping to change at page 17, line 49 ¶ | skipping to change at page 20, line 13 ¶ | |||
In order to verify a signature, a verifier MUST: | In order to verify a signature, a verifier MUST: | |||
1. Examine the signature's metadata to confirm that the signature | 1. Examine the signature's metadata to confirm that the signature | |||
meets the requirements described in this document, as well as any | meets the requirements described in this document, as well as any | |||
additional requirements defined by the application such as which | additional requirements defined by the application such as which | |||
header fields or other content are required to be covered by the | header fields or other content are required to be covered by the | |||
signature. | signature. | |||
2. Use the received HTTP message and the signature's metadata to | 2. Use the received HTTP message and the signature's metadata to | |||
recreate the Signature Input, using the process described in | recreate the Signature Input, using the process described in | |||
Section 3.2.2. | Section 3.2.2. The value of the "@signature-params" input is the | |||
value of the signature input header field for this signature, not | ||||
including the signature's label. | ||||
3. Use the signature's Algorithm and Verification Key Material with | 3. Use the signature's Algorithm and Verification Key Material with | |||
the recreated Signing Input to verify the signature value. | the recreated Signing Input to verify the signature value. | |||
A signature with a Creation Time that is in the future or an | A signature with a Creation Time that is in the future or an | |||
Expiration Time that is in the past MUST NOT be processed. | Expiration Time that is in the past MUST NOT be processed. | |||
The verifier MUST ensure that a signature's Algorithm is appropriate | The verifier MUST ensure that a signature's Algorithm is appropriate | |||
for the key material the verifier will use to verify the signature. | for the key material the verifier will use to verify the signature. | |||
If the Algorithm is not appropriate for the key material (for | If the Algorithm is not appropriate for the key material (for | |||
skipping to change at page 19, line 17 ¶ | skipping to change at page 21, line 27 ¶ | |||
Message signatures can be included within an HTTP message via the | Message signatures can be included within an HTTP message via the | |||
"Signature-Input" and "Signature" HTTP header fields, both defined | "Signature-Input" and "Signature" HTTP header fields, both defined | |||
within this specification. The "Signature" HTTP header field | within this specification. The "Signature" HTTP header field | |||
contains signature values, while the "Signature-Input" HTTP header | contains signature values, while the "Signature-Input" HTTP header | |||
field identifies the Covered Content and metadata that describe how | field identifies the Covered Content and metadata that describe how | |||
each signature was generated. | each signature was generated. | |||
4.1. The 'Signature-Input' HTTP Header | 4.1. The 'Signature-Input' HTTP Header | |||
The "Signature-Input" HTTP header field is a Dictionary Structured | The "Signature-Input" HTTP header field is a Dictionary Structured | |||
Header [StructuredFields] containing the metadata for zero or more | Header [RFC8941] containing the metadata for zero or more message | |||
message signatures generated from content within the HTTP message. | signatures generated from content within the HTTP message. Each | |||
Each member describes a single message signature. The member's name | member describes a single message signature. The member's name is an | |||
is an identifier that uniquely identifies the message signature | identifier that uniquely identifies the message signature within the | |||
within the context of the HTTP message. The member's value is the | context of the HTTP message. The member's value is the serialization | |||
message signature's Covered Content, expressed as a List of Tokens. | of the covered content including all signature metadata parameters, | |||
Further signature metadata is expressed in parameters on the member | described in Section 3.1. | |||
value, as described below. | ||||
4.1.1. Metadata Parameters | ||||
The parameters on each "Signature-Input" member value contain | ||||
metadata about the signature. Each parameter name MUST be a | ||||
parameter name registered in the IANA HTTP Signatures Metadata | ||||
Parameters Registry defined in Section 5.2 of this document. This | ||||
document defines the following parameters, and registers them as the | ||||
initial contents of the registry: | ||||
alg | ||||
RECOMMENDED. The "alg" parameter is a Token containing the name | ||||
of the signature's Algorithm, as registered in the HTTP Signature | ||||
Algorithms Registry defined by this document. Verifiers MUST | ||||
determine the signature's Algorithm from the "keyId" parameter | ||||
rather than from "alg". If "alg" is provided and differs from or | ||||
is incompatible with the algorithm or key material identified by | ||||
"keyId" (for example, "alg" has a value of "rsa-sha256" but | ||||
"keyId" identifies an EdDSA key), then implementations MUST | ||||
produce an error. | ||||
created | ||||
RECOMMENDED. The "created" parameter is a Decimal containing the | ||||
signature's Creation Time, expressed as the canonicalized value of | ||||
the "*created" content identifier, as defined in Section 2. If | ||||
not specified, the signature's Creation Time is undefined. This | ||||
parameter is useful when signers are not capable of controlling | ||||
the Date HTTP Header such as when operating in certain web browser | ||||
environments. | ||||
expires | ||||
OPTIONAL. The "expires" parameter is a Decimal containing the | ||||
signature's Expiration Time, expressed as the canonicalized value | ||||
of the "*expires" content identifier, as defined in Section 2. If | ||||
the signature does not have an Expiration Time, this parameter | ||||
MUST be omitted. If not specified, the signature's Expiration | ||||
Time is undefined. | ||||
keyId | Signature-Input: sig1=("@request-target" "host" "date" | |||
"cache-control" "x-empty-header" "x-example"); keyid="test-key-a"; | ||||
alg="hs2019"; created=1402170695; expires=1402170995 | ||||
REQUIRED. The "keyId" parameter is a String whose value can be | To facilitate signature validation, the "Signature-Input" header MUST | |||
used by a verifier to identify and/or obtain the signature's | contain the same serialization value used in generating the signature | |||
Verification Key Material. Further format and semantics of this | input. | |||
value are out of scope for this document. | ||||
4.2. The 'Signature' HTTP Header | 4.2. The 'Signature' HTTP Header | |||
The "Signature" HTTP header field is a Dictionary Structured Header | The "Signature" HTTP header field is a Dictionary Structured Header | |||
[StructuredFields] containing zero or more message signatures | [RFC8941] containing zero or more message signatures generated from | |||
generated from content within the HTTP message. Each member's name | content within the HTTP message. Each member's name is a signature | |||
is a signature identifier that is present as a member name in the | identifier that is present as a member name in the "Signature-Input" | |||
"Signature-Input" Structured Header within the HTTP message. Each | Structured Header within the HTTP message. Each member's value is a | |||
member's value is a Byte Sequence containing the signature value for | Byte Sequence containing the signature value for the message | |||
the message signature identified by the member name. Any member in | signature identified by the member name. Any member in the | |||
the "Signature" HTTP header field that does not have a corresponding | "Signature" HTTP header field that does not have a corresponding | |||
member in the HTTP message's "Signature-Input" HTTP header field MUST | member in the HTTP message's "Signature-Input" HTTP header field MUST | |||
be ignored. | be ignored. | |||
Signature: sig1=:K2qGT5srn2OGbOIDzQ6kYT+ruaycnDAAUpKv+ePFfD0RAxn/1BUe\ | ||||
Zx/Kdrq32DrfakQ6bPsvB9aqZqognNT6be4olHROIkeV879RrsrObury8L9SCEibe\ | ||||
oHyqU/yCjphSmEdd7WD+zrchK57quskKwRefy2iEC5S2uAH0EPyOZKWlvbKmKu5q4\ | ||||
CaB8X/I5/+HLZLGvDiezqi6/7p2Gngf5hwZ0lSdy39vyNMaaAT0tKo6nuVw0S1MVg\ | ||||
1Q7MpWYZs0soHjttq0uLIA3DIbQfLiIvK6/l0BdWTU7+2uQj7lBkQAsFZHoA96ZZg\ | ||||
FquQrXRlmYOh+Hx5D9fJkXcXe5tmAg==: | ||||
4.3. Examples | 4.3. Examples | |||
The following is a non-normative example of "Signature-Input" and | The following is a non-normative example of "Signature-Input" and | |||
"Signature" HTTP header fields representing the signature in | "Signature" HTTP header fields representing the signature in | |||
Figure 2: | Figure 2: | |||
Signature-Input: sig1=(*request-target, *created, host, date, | # NOTE: '\' line wrapping per RFC 8792 | |||
cache-control, x-empty-header, x-example); keyId="test-key-a"; | ||||
alg=hs2019; created=1402170695; expires=1402170995 | Signature-Input: sig1=("@request-target" "host" "date" | |||
Signature: sig1=:K2qGT5srn2OGbOIDzQ6kYT+ruaycnDAAUpKv+ePFfD0RAxn/1BUe | "cache-control" "x-empty-header" "x-example"); keyid="test-key-a"; | |||
Zx/Kdrq32DrfakQ6bPsvB9aqZqognNT6be4olHROIkeV879RrsrObury8L9SCEibe | alg="hs2019"; created=1402170695; expires=1402170995 | |||
oHyqU/yCjphSmEdd7WD+zrchK57quskKwRefy2iEC5S2uAH0EPyOZKWlvbKmKu5q4 | Signature: sig1=:K2qGT5srn2OGbOIDzQ6kYT+ruaycnDAAUpKv+ePFfD0RAxn/1BUe\ | |||
CaB8X/I5/+HLZLGvDiezqi6/7p2Gngf5hwZ0lSdy39vyNMaaAT0tKo6nuVw0S1MVg | Zx/Kdrq32DrfakQ6bPsvB9aqZqognNT6be4olHROIkeV879RrsrObury8L9SCEibe\ | |||
1Q7MpWYZs0soHjttq0uLIA3DIbQfLiIvK6/l0BdWTU7+2uQj7lBkQAsFZHoA96ZZg | oHyqU/yCjphSmEdd7WD+zrchK57quskKwRefy2iEC5S2uAH0EPyOZKWlvbKmKu5q4\ | |||
CaB8X/I5/+HLZLGvDiezqi6/7p2Gngf5hwZ0lSdy39vyNMaaAT0tKo6nuVw0S1MVg\ | ||||
1Q7MpWYZs0soHjttq0uLIA3DIbQfLiIvK6/l0BdWTU7+2uQj7lBkQAsFZHoA96ZZg\ | ||||
FquQrXRlmYOh+Hx5D9fJkXcXe5tmAg==: | FquQrXRlmYOh+Hx5D9fJkXcXe5tmAg==: | |||
Since "Signature-Input" and "Signature" are both defined as | Since "Signature-Input" and "Signature" are both defined as | |||
Dictionary Structured Headers, they can be used to easily include | Dictionary Structured Headers, they can be used to easily include | |||
multiple signatures within the same HTTP message. For example, a | multiple signatures within the same HTTP message. For example, a | |||
signer may include multiple signatures signing the same content with | signer may include multiple signatures signing the same content with | |||
different keys and/or algorithms to support verifiers with different | different keys and/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 header fields when forwarding the request to a service | client in header fields when forwarding the request to a service | |||
host, and may also include a signature over those fields and the | host, and may also include a signature over those fields and the | |||
client's signature. The following is a non-normative example of | client's signature. The following is a non-normative example of | |||
header fields a reverse proxy might add to a forwarded request that | header fields a reverse proxy might add to a forwarded request that | |||
contains the signature in the above example: | contains the signature in the above example: | |||
# NOTE: '\' line wrapping per RFC 8792 | ||||
X-Forwarded-For: 192.0.2.123 | X-Forwarded-For: 192.0.2.123 | |||
Signature-Input: reverse_proxy_sig=(*created, host, date, | Signature-Input: reverse_proxy_sig=("host" "date" | |||
signature:sig1, x-forwarded-for); keyId="test-key-a"; | "signature";key=sig1 "x-forwarded-for"); keyid="test-key-a"; | |||
alg=hs2019; created=1402170695; expires=1402170695.25 | alg="hs2019"; created=1402170695; expires=1402170695 | |||
Signature: reverse_proxy_sig=:ON3HsnvuoTlX41xfcGWaOEVo1M3bJDRBOp0Pc/O | Signature: reverse_proxy_sig=:ON3HsnvuoTlX41xfcGWaOEVo1M3bJDRBOp0Pc/O\ | |||
jAOWKQn0VMY0SvMMWXS7xG+xYVa152rRVAo6nMV7FS3rv0rR5MzXL8FCQ2A35DCEN | jAOWKQn0VMY0SvMMWXS7xG+xYVa152rRVAo6nMV7FS3rv0rR5MzXL8FCQ2A35DCEN\ | |||
LOhEgj/S1IstEAEFsKmE9Bs7McBsCtJwQ3hMqdtFenkDffSoHOZOInkTYGafkoy78 | LOhEgj/S1IstEAEFsKmE9Bs7McBsCtJwQ3hMqdtFenkDffSoHOZOInkTYGafkoy78\ | |||
l1VZvmb3Y4yf7McJwAvk2R3gwKRWiiRCw448Nt7JTWzhvEwbh7bN2swc/v3NJbg/w | l1VZvmb3Y4yf7McJwAvk2R3gwKRWiiRCw448Nt7JTWzhvEwbh7bN2swc/v3NJbg/w\ | |||
JYyYVbelZx4IywuZnYFxgPl/qvqbAjeEVvaLKLgSMr11y+uzxCHoMnDUnTYhMrmOT | JYyYVbelZx4IywuZnYFxgPl/qvqbAjeEVvaLKLgSMr11y+uzxCHoMnDUnTYhMrmOT\ | |||
4O8lBLfRFOcoJPKBdoKg9U0a96U2mUug1bFOozEVYFg==: | 4O8lBLfRFOcoJPKBdoKg9U0a96U2mUug1bFOozEVYFg==: | |||
5. IANA Considerations | 5. IANA Considerations | |||
5.1. HTTP Signature Algorithms Registry | 5.1. HTTP Signature Algorithms Registry | |||
This document defines HTTP Signature Algorithms, for which IANA is | This document defines HTTP Signature Algorithms, for which IANA is | |||
asked to create and maintain a new registry titled "HTTP Signature | asked to create and maintain a new registry titled "HTTP Signature | |||
Algorithms". Initial values for this registry are given in | Algorithms". Initial values for this registry are given in | |||
Section 5.1.2. Future assignments and modifications to existing | Section 5.1.2. Future assignments and modifications to existing | |||
assignment are to be made through the Expert Review registration | assignment are to be made through the Expert Review registration | |||
policy [RFC8126] and shall follow the template presented in | policy [RFC8126] and shall follow the template presented in | |||
Section 5.1.1. | Section 5.1.1. | |||
5.1.1. Registration Template | 5.1.1. Registration Template | |||
Algorithm Name | Algorithm Name: | |||
An identifier for the HTTP Signature Algorithm. The name MUST be | An identifier for the HTTP Signature Algorithm. The name MUST be | |||
an ASCII string consisting only of lower-case characters (""a"" - | an ASCII string consisting only of lower-case characters (""a"" - | |||
""z""), digits (""0"" - ""9""), and hyphens (""-""), and SHOULD | ""z""), digits (""0"" - ""9""), and hyphens (""-""), and SHOULD | |||
NOT exceed 20 characters in length. The identifier MUST be unique | NOT exceed 20 characters in length. The identifier MUST be unique | |||
within the context of the registry. | within the context of the registry. | |||
Status | Status: | |||
A brief text description of the status of the algorithm. The | A brief text description of the status of the algorithm. The | |||
description MUST begin with one of "Active" or "Deprecated", and | description MUST begin with one of "Active" or "Deprecated", and | |||
MAY provide further context or explanation as to the reason for | MAY provide further context or explanation as to the reason for | |||
the status. | the status. | |||
Description | Description: | |||
A description of the algorithm used to sign the signing string | A description of the algorithm used to sign the signing string | |||
when generating an HTTP Message Signature, or instructions on how | when generating an HTTP Message Signature, or instructions on how | |||
to determine that algorithm. When the description specifies an | to determine that algorithm. When the description specifies an | |||
algorithm, it MUST include a reference to the document or | algorithm, it MUST include a reference to the document or | |||
documents that define the algorithm. | documents that define the algorithm. | |||
5.1.2. Initial Contents | 5.1.2. Initial Contents | |||
(( MS: The references in this section are problematic as many of the | (( MS: The references in this section are problematic as many of the | |||
specifications that they refer to are too implementation specific, | specifications that they refer to are too implementation specific, | |||
rather than just pointing to the proper signature and hashing | rather than just pointing to the proper signature and hashing | |||
specifications. A better approach might be just specifying the | specifications. A better approach might be just specifying the | |||
signature and hashing function specifications, leaving implementers | signature and hashing function specifications, leaving implementers | |||
to connect the dots (which are not that hard to connect). )) | to connect the dots (which are not that hard to connect). )) | |||
5.1.2.1. hs2019 | 5.1.2.1. hs2019 | |||
Algorithm Name | Algorithm Name: | |||
"hs2019" | "hs2019" | |||
Status | Status: | |||
active | active | |||
Description | Description: | |||
Derived from metadata associated with keyid. Recommend support | ||||
Derived from metadata associated with keyId. Recommend support | ||||
for: | for: | |||
* RSASSA-PSS [RFC8017] using SHA-512 [RFC6234] | * RSASSA-PSS [RFC8017] using SHA-512 [RFC6234] | |||
* HMAC [RFC2104] using SHA-512 [RFC6234] | * HMAC [RFC2104] using SHA-512 [RFC6234] | |||
* ECDSA using curve P-256 DSS [FIPS186-4] and SHA-512 [RFC6234] | * ECDSA using curve P-256 DSS [FIPS186-4] and SHA-512 [RFC6234] | |||
* Ed25519ph, Ed25519ctx, and Ed25519 [RFC8032] | * Ed25519ph, Ed25519ctx, and Ed25519 [RFC8032] | |||
5.1.2.2. rsa-sha1 | 5.1.2.2. rsa-sha1 | |||
Algorithm Name | Algorithm Name: | |||
"rsa-sha1" | "rsa-sha1" | |||
Status | Status: | |||
Deprecated; SHA-1 not secure. | Deprecated; SHA-1 not secure. | |||
Description | Description: | |||
RSASSA-PKCS1-v1_5 [RFC8017] using SHA-1 [RFC6234] | RSASSA-PKCS1-v1_5 [RFC8017] using SHA-1 [RFC6234] | |||
5.1.2.3. rsa-sha256 | 5.1.2.3. rsa-sha256 | |||
Algorithm Name | Algorithm Name: | |||
"rsa-sha256" | "rsa-sha256" | |||
Status | Status: | |||
Deprecated; specifying signature algorithm enables attack vector. | Deprecated; specifying signature algorithm enables attack vector. | |||
Description | Description: | |||
RSASSA-PKCS1-v1_5 [RFC8017] using SHA-256 [RFC6234] | RSASSA-PKCS1-v1_5 [RFC8017] using SHA-256 [RFC6234] | |||
5.1.2.4. hmac-sha256 | 5.1.2.4. hmac-sha256 | |||
Algorithm Name | Algorithm Name: | |||
"hmac-sha256" | "hmac-sha256" | |||
Status | Status: | |||
Deprecated; specifying signature algorithm enables attack vector. | Deprecated; specifying signature algorithm enables attack vector. | |||
Description | Description: | |||
HMAC [RFC2104] using SHA-256 [RFC6234] | HMAC [RFC2104] using SHA-256 [RFC6234] | |||
5.1.2.5. ecdsa-sha256 | 5.1.2.5. ecdsa-sha256 | |||
Algorithm Name | Algorithm Name: | |||
"ecdsa-sha256" | "ecdsa-sha256" | |||
Status | Status: | |||
Deprecated; specifying signature algorithm enables attack vector. | Deprecated; specifying signature algorithm enables attack vector. | |||
Description | Description: | |||
ECDSA using curve P-256 DSS [FIPS186-4] and SHA-256 [RFC6234] | ECDSA using curve P-256 DSS [FIPS186-4] and SHA-256 [RFC6234] | |||
5.2. HTTP Signature Metadata Parameters Registry | 5.2. HTTP Signature Metadata Parameters Registry | |||
This document defines the "Signature-Input" Structured Header, whose | This document defines the "Signature-Input" Structured Header, whose | |||
member values may have parameters containing metadata about a message | member values may have parameters containing metadata about a message | |||
signature. IANA is asked to create and maintain a new registry | signature. IANA is asked to create and maintain a new registry | |||
titled "HTTP Signature Metadata Parameters" to record and maintain | titled "HTTP Signature Metadata Parameters" to record and maintain | |||
the set of parameters defined for use with member values in the | the set of parameters defined for use with member values in the | |||
"Signature-Input" Structured Header. Initial values for this | "Signature-Input" Structured Header. Initial values for this | |||
skipping to change at page 24, line 34 ¶ | skipping to change at page 26, line 5 ¶ | |||
template presented in Section 5.2.1. | template presented in Section 5.2.1. | |||
5.2.1. Registration Template | 5.2.1. Registration Template | |||
5.2.2. Initial Contents | 5.2.2. Initial Contents | |||
The table below contains the initial contents of the HTTP Signature | The table below contains the initial contents of the HTTP Signature | |||
Metadata Parameters Registry. Each row in the table represents a | Metadata Parameters Registry. Each row in the table represents a | |||
distinct entry in the registry. | distinct entry in the registry. | |||
+=========+========+================================+ | +=========+========+==============================+ | |||
| Name | Status | Reference(s) | | | Name | Status | Reference(s) | | |||
+=========+========+================================+ | +=========+========+==============================+ | |||
| alg | Active | Section 4.1.1 of this document | | | alg | Active | Section 3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+------------------------------+ | |||
| created | Active | Section 4.1.1 of this document | | | created | Active | Section 3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+------------------------------+ | |||
| expires | Active | Section 4.1.1 of this document | | | expires | Active | Section 3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+------------------------------+ | |||
| keyId | Active | Section 4.1.1 of this document | | | keyid | Active | Section 3.1 of this document | | |||
+---------+--------+--------------------------------+ | +---------+--------+------------------------------+ | |||
Table 6: Initial contents of the HTTP Signature | Table 7: Initial contents of the HTTP Signature | |||
Metadata Parameters Registry. | Metadata Parameters Registry. | |||
5.3. HTTP Signature Specialty Content Identifiers Registry | ||||
This document defines a method for canonicalizing HTTP message | ||||
content, including content that can be generated from the context of | ||||
the HTTP message outside of the HTTP headers. This content is | ||||
identified by a unique key. IANA is asked to create and maintain a | ||||
new registry typed "HTTP Signature Specialty Content Identifiers" to | ||||
record and maintain the set of non-header content identifiers and | ||||
their canonicalization method. Initial values for this registry are | ||||
given in Section 5.3.2. Future assignments and modifications to | ||||
existing assignments are to be made through the Expert Review | ||||
registration policy [RFC8126] and shall follow the template presented | ||||
in Section 5.3.1. | ||||
5.3.1. Registration Template | ||||
5.3.2. Initial Contents | ||||
The table below contains the initial contents of the HTTP Signature | ||||
Specialty Content Identifiers Registry. | ||||
+===================+========+================================+ | ||||
| Name | Status | Reference(s) | | ||||
+===================+========+================================+ | ||||
| @request-target | Active | Section 2.4.1 of this document | | ||||
+-------------------+--------+--------------------------------+ | ||||
| @signature-params | Active | Section 2.4.2 of this document | | ||||
+-------------------+--------+--------------------------------+ | ||||
Table 8: Initial contents of the HTTP Signature Specialty | ||||
Content Identifiers Registry. | ||||
6. Security Considerations | 6. Security Considerations | |||
(( TODO: need to dive deeper on this section; not sure how much of | (( TODO: need to dive deeper on this section; not sure how much of | |||
what's referenced below is actually applicable, or if it covers | what's referenced below is actually applicable, or if it covers | |||
everything we need to worry about. )) | everything we need to worry about. )) | |||
(( TODO: Should provide some recommendations on how to determine what | (( TODO: Should provide some recommendations on how to determine what | |||
content needs to be signed for a given use case. )) | content needs to be signed for a given use case. )) | |||
There are a number of security considerations to take into account | There are a number of security considerations to take into account | |||
skipping to change at page 25, line 31 ¶ | skipping to change at page 27, line 31 ¶ | |||
7.1. Normative References | 7.1. Normative References | |||
[FIPS186-4] | [FIPS186-4] | |||
"Digital Signature Standard (DSS)", 2013, | "Digital Signature Standard (DSS)", 2013, | |||
<https://csrc.nist.gov/publications/detail/fips/186/4/ | <https://csrc.nist.gov/publications/detail/fips/186/4/ | |||
final>. | final>. | |||
[HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | |||
Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | |||
DOI 10.17487/RFC7540, May 2015, | DOI 10.17487/RFC7540, May 2015, | |||
<https://www.rfc-editor.org/info/rfc7540>. | <https://www.rfc-editor.org/rfc/rfc7540>. | |||
[MESSAGING] | [MESSAGING] | |||
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
Protocol (HTTP/1.1): Message Syntax and Routing", | Protocol (HTTP/1.1): Message Syntax and Routing", | |||
RFC 7230, DOI 10.17487/RFC7230, June 2014, | RFC 7230, DOI 10.17487/RFC7230, June 2014, | |||
<https://www.rfc-editor.org/info/rfc7230>. | <https://www.rfc-editor.org/rfc/rfc7230>. | |||
[POSIX.1] "The Open Group Base Specifications Issue 7, 2018 | [POSIX.1] "The Open Group Base Specifications Issue 7, 2018 | |||
edition", 2018, | edition", 2018, | |||
<https://pubs.opengroup.org/onlinepubs/9699919799/>. | <https://pubs.opengroup.org/onlinepubs/9699919799/>. | |||
[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | |||
Hashing for Message Authentication", RFC 2104, | Hashing for Message Authentication", RFC 2104, | |||
DOI 10.17487/RFC2104, February 1997, | DOI 10.17487/RFC2104, February 1997, | |||
<https://www.rfc-editor.org/info/rfc2104>. | <https://www.rfc-editor.org/rfc/rfc2104>. | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/rfc/rfc2119>. | |||
[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/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | |||
[RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, | ||||
"Handling Long Lines in Content of Internet-Drafts and | ||||
RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, | ||||
<https://www.rfc-editor.org/rfc/rfc8792>. | ||||
[RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for | ||||
HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, | ||||
<https://www.rfc-editor.org/rfc/rfc8941>. | ||||
[SEMANTICS] | [SEMANTICS] | |||
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | |||
DOI 10.17487/RFC7231, June 2014, | DOI 10.17487/RFC7231, June 2014, | |||
<https://www.rfc-editor.org/info/rfc7231>. | <https://www.rfc-editor.org/rfc/rfc7231>. | |||
[StructuredFields] | ||||
"Structured Field Vaues for HTTP", 2020, | ||||
<https://datatracker.ietf.org/doc/draft-ietf-httpbis- | ||||
header-structure>. | ||||
7.2. Informative References | 7.2. Informative References | |||
[RFC3230] Mogul, J. and A. Van Hoff, "Instance Digests in HTTP", | ||||
RFC 3230, DOI 10.17487/RFC3230, January 2002, | ||||
<https://www.rfc-editor.org/info/rfc3230>. | ||||
[RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: | ||||
Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, | ||||
<https://www.rfc-editor.org/info/rfc3339>. | ||||
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | ||||
Resource Identifier (URI): Generic Syntax", STD 66, | ||||
RFC 3986, DOI 10.17487/RFC3986, January 2005, | ||||
<https://www.rfc-editor.org/info/rfc3986>. | ||||
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data | [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data | |||
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, | Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, | |||
<https://www.rfc-editor.org/info/rfc4648>. | <https://www.rfc-editor.org/rfc/rfc4648>. | |||
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms | |||
(SHA and SHA-based HMAC and HKDF)", RFC 6234, | (SHA and SHA-based HMAC and HKDF)", RFC 6234, | |||
DOI 10.17487/RFC6234, May 2011, | DOI 10.17487/RFC6234, May 2011, | |||
<https://www.rfc-editor.org/info/rfc6234>. | <https://www.rfc-editor.org/rfc/rfc6234>. | |||
[RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | [RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", | |||
RFC 7239, DOI 10.17487/RFC7239, June 2014, | RFC 7239, DOI 10.17487/RFC7239, June 2014, | |||
<https://www.rfc-editor.org/info/rfc7239>. | <https://www.rfc-editor.org/rfc/rfc7239>. | |||
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, | ||||
DOI 10.17487/RFC7518, May 2015, | ||||
<https://www.rfc-editor.org/info/rfc7518>. | ||||
[RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | ||||
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | ||||
<https://www.rfc-editor.org/info/rfc7541>. | ||||
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | [RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, | |||
"PKCS #1: RSA Cryptography Specifications Version 2.2", | "PKCS #1: RSA Cryptography Specifications Version 2.2", | |||
RFC 8017, DOI 10.17487/RFC8017, November 2016, | RFC 8017, DOI 10.17487/RFC8017, November 2016, | |||
<https://www.rfc-editor.org/info/rfc8017>. | <https://www.rfc-editor.org/rfc/rfc8017>. | |||
[RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital | [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital | |||
Signature Algorithm (EdDSA)", RFC 8032, | Signature Algorithm (EdDSA)", RFC 8032, | |||
DOI 10.17487/RFC8032, January 2017, | DOI 10.17487/RFC8032, January 2017, | |||
<https://www.rfc-editor.org/info/rfc8032>. | <https://www.rfc-editor.org/rfc/rfc8032>. | |||
[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/info/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/info/rfc8446>. | <https://www.rfc-editor.org/rfc/rfc8446>. | |||
[WP-HTTP-Sig-Audit] | [WP-HTTP-Sig-Audit] | |||
"Security Considerations for HTTP Signatures", 2013, | "Security Considerations for HTTP Signatures", 2013, | |||
<https://web-payments.org/specs/source/http-signatures- | <https://web-payments.org/specs/source/http-signatures- | |||
audit/>. | audit/>. | |||
Appendix A. Examples | Appendix A. Detecting HTTP Message Signatures | |||
A.1. Example Keys | There have been many attempts to create signed HTTP messages in the | |||
past, including other non-standard definitions of the "Signature" | ||||
header used within this specification. It is recommended that | ||||
developers wishing to support both this specification and other | ||||
historial drafts do so carefully and deliberately, as | ||||
incompatibilities between this specification and various versions of | ||||
other drafts could lead to problems. | ||||
It is recommended that implementers first detect and validate the | ||||
"Signature-Input" header defined in this specification to detect that | ||||
this standard is in use and not an alternative. If the "Signature- | ||||
Input" header is present, all "Signature" headers can be parsed and | ||||
interpreted in the context of this draft. | ||||
Appendix B. Examples | ||||
B.1. Example Keys | ||||
This section provides cryptographic keys that are referenced in | This section provides cryptographic keys that are referenced in | |||
example signatures throughout this document. These keys MUST NOT be | example signatures throughout this document. These keys MUST NOT be | |||
used for any purpose other than testing. | used for any purpose other than testing. | |||
A.1.1. Example Key RSA test | B.1.1. Example Key RSA test | |||
The following key is a 2048-bit RSA public and private key pair: | The following key is a 2048-bit RSA public and private key pair: | |||
-----BEGIN RSA PUBLIC KEY----- | -----BEGIN RSA PUBLIC KEY----- | |||
MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw | |||
WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq | |||
MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg | |||
kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P | |||
uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ | |||
PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB | |||
skipping to change at page 28, line 42 ¶ | skipping to change at page 30, line 42 ¶ | |||
9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn | 9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn | |||
f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo | f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo | |||
81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa | 81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa | |||
/2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | /2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG | |||
IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m | |||
qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P | |||
WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ | |||
EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= | |||
-----END RSA PRIVATE KEY----- | -----END RSA PRIVATE KEY----- | |||
A.2. Example keyId Values | B.2. Example keyid Values | |||
The table below maps example "keyId" values to associated algorithms | The table below maps example "keyid" values to associated algorithms | |||
and/or keys. These are example mappings that are valid only within | and/or keys. These are example mappings that are valid only within | |||
the context of examples in examples within this and future documents | the context of examples in examples within this and future documents | |||
that reference this section. Unless otherwise specified, within the | that reference this section. Unless otherwise specified, within the | |||
context of examples it should be assumed that the signer and verifier | context of examples it should be assumed that the signer and verifier | |||
understand these "keyId" mappings. These "keyId" values are not | understand these "keyid" mappings. These "keyid" values are not | |||
reserved, and deployments are free to use them, with these | reserved, and deployments are free to use them, with these | |||
associations or others. | associations or others. | |||
+============+=================================+================+ | +============+=================================+================+ | |||
| keyId | Algorithm | Verification | | | keyid | Algorithm | Verification | | |||
| | | Key | | | | | Key | | |||
+============+=================================+================+ | +============+=================================+================+ | |||
| test-key-a | "hs2019", using RSASSA-PSS | The public key | | | test-key-a | "hs2019", using RSASSA-PSS | The public key | | |||
| | [RFC8017] and SHA-512 [RFC6234] | specified in | | | | [RFC8017] and SHA-512 [RFC6234] | specified in | | |||
| | | Appendix A.1.1 | | | | | Appendix B.1.1 | | |||
+------------+---------------------------------+----------------+ | +------------+---------------------------------+----------------+ | |||
| test-key-b | rsa-sha256 | The public key | | | test-key-b | rsa-sha256 | The public key | | |||
| | | specified in | | | | | specified in | | |||
| | | Appendix A.1.1 | | | | | Appendix B.1.1 | | |||
+------------+---------------------------------+----------------+ | +------------+---------------------------------+----------------+ | |||
Table 7 | Table 9 | |||
A.3. Test Cases | B.3. 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 message: | based on the following HTTP message: | |||
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, 07 Jun 2014 20:51:35 GMT | Date: Tue, 07 Jun 2014 20:51:35 GMT | |||
Content-Type: application/json | Content-Type: application/json | |||
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
Content-Length: 18 | Content-Length: 18 | |||
{"hello": "world"} | {"hello": "world"} | |||
A.3.1. Signature Generation | B.3.1. Signature Generation | |||
A.3.1.1. hs2019 signature over minimal recommended content | B.3.1.1. hs2019 signature over minimal recommended content | |||
This presents metadata for a Signature using "hs2019", over minimum | This presents metadata for a Signature using "hs2019", over minimum | |||
recommended data to sign: | recommended data to sign: | |||
+==============+===================================+ | +==============+===================================+ | |||
| Property | Value | | | Property | Value | | |||
+==============+===================================+ | +==============+===================================+ | |||
| Algorithm | "hs2019", using RSASSA-PSS | | | Algorithm | "hs2019", using RSASSA-PSS | | |||
| | [RFC8017] using SHA-512 [RFC6234] | | | | [RFC8017] using SHA-512 [RFC6234] | | |||
+--------------+-----------------------------------+ | +--------------+-----------------------------------+ | |||
| Covered | *created, *request-target | | | Covered | @request-target | | |||
| Content | | | | Content | | | |||
+--------------+-----------------------------------+ | +--------------+-----------------------------------+ | |||
| Creation | 8:51:35 PM GMT, June 7th, 2014 | | | Creation | 8:51:35 PM GMT, June 7th, 2014 | | |||
| Time | | | | Time | | | |||
+--------------+-----------------------------------+ | +--------------+-----------------------------------+ | |||
| Expiration | Undefined | | | Expiration | Undefined | | |||
| Time | | | | Time | | | |||
+--------------+-----------------------------------+ | +--------------+-----------------------------------+ | |||
| Verification | The public key specified in | | | Verification | The public key specified in | | |||
| Key Material | Appendix A.1.1. | | | Key Material | Appendix B.1.1. | | |||
+--------------+-----------------------------------+ | +--------------+-----------------------------------+ | |||
Table 8 | Table 10 | |||
The Signature Input is: | The Signature Input is: | |||
*created: 1402170695 | "@request-target": post /foo?param=value&pet=dog | |||
*request-target: post /foo?param=value&pet=dog | "@signature-params": ("@request-target"); keyid="test-key-a"; created=1402170695 | |||
The signature value is: | The signature value is: | |||
QaVaWYfF2da6tG66Xtd0GrVFChJ0fOWUe/C6kaYESPiYYwnMH9egOgyKqgLLY9NQJFk7b | QaVaWYfF2da6tG66Xtd0GrVFChJ0fOWUe/C6kaYESPiYYwnMH9egOgyKqgLLY9NQJFk7b | |||
QY834sHEUwjS5ByEBaO3QNwIvqEY1qAAU/2MX14tc9Yn7ELBnaaNHaHkV3xVO9KIuLT7V | QY834sHEUwjS5ByEBaO3QNwIvqEY1qAAU/2MX14tc9Yn7ELBnaaNHaHkV3xVO9KIuLT7V | |||
6e4OUuGb1axfbXpMgPEql6CEFrn6K95CLuuKP5/gOEcBtmJp5L58gN4VvZrk2OVA6U971 | 6e4OUuGb1axfbXpMgPEql6CEFrn6K95CLuuKP5/gOEcBtmJp5L58gN4VvZrk2OVA6U971 | |||
YiEDNuDa4CwMcQMvcGssbc/L3OULTUffD/1VcPtdGImP2uvVQntpT8b2lBeBpfh8MuaV2 | YiEDNuDa4CwMcQMvcGssbc/L3OULTUffD/1VcPtdGImP2uvVQntpT8b2lBeBpfh8MuaV2 | |||
vtzidyBYFtAUoYhRWO8+ntqA1q2OK4LMjM2XgDScSVWvGdVd459A0wI9lRlnPap3zg== | vtzidyBYFtAUoYhRWO8+ntqA1q2OK4LMjM2XgDScSVWvGdVd459A0wI9lRlnPap3zg== | |||
A possible "Signature-Input" and "Signature" header containing this | A possible "Signature-Input" and "Signature" header containing this | |||
signature is: | signature is: | |||
Signature-Input: sig1=(*created, *request-target); | # NOTE: '\' line wrapping per RFC 8792 | |||
keyId="test-key-a"; created=1402170695 | ||||
Signature: sig1=:QaVaWYfF2da6tG66Xtd0GrVFChJ0fOWUe/C6kaYESPiYYwnMH9eg | Signature-Input: sig1=("@request-target"); | |||
OgyKqgLLY9NQJFk7bQY834sHEUwjS5ByEBaO3QNwIvqEY1qAAU/2MX14tc9Yn7ELB | keyid="test-key-a"; created=1402170695 | |||
naaNHaHkV3xVO9KIuLT7V6e4OUuGb1axfbXpMgPEql6CEFrn6K95CLuuKP5/gOEcB | Signature: sig1=:QaVaWYfF2da6tG66Xtd0GrVFChJ0fOWUe/C6kaYESPiYYwnMH9eg\ | |||
tmJp5L58gN4VvZrk2OVA6U971YiEDNuDa4CwMcQMvcGssbc/L3OULTUffD/1VcPtd | OgyKqgLLY9NQJFk7bQY834sHEUwjS5ByEBaO3QNwIvqEY1qAAU/2MX14tc9Yn7ELB\ | |||
GImP2uvVQntpT8b2lBeBpfh8MuaV2vtzidyBYFtAUoYhRWO8+ntqA1q2OK4LMjM2X | naaNHaHkV3xVO9KIuLT7V6e4OUuGb1axfbXpMgPEql6CEFrn6K95CLuuKP5/gOEcB\ | |||
tmJp5L58gN4VvZrk2OVA6U971YiEDNuDa4CwMcQMvcGssbc/L3OULTUffD/1VcPtd\ | ||||
GImP2uvVQntpT8b2lBeBpfh8MuaV2vtzidyBYFtAUoYhRWO8+ntqA1q2OK4LMjM2X\ | ||||
gDScSVWvGdVd459A0wI9lRlnPap3zg==: | gDScSVWvGdVd459A0wI9lRlnPap3zg==: | |||
A.3.1.2. hs2019 signature covering all header fields | B.3.1.2. hs2019 signature covering all header fields | |||
This presents metadata for a Signature using "hs2019" that covers all | This presents metadata for a Signature using "hs2019" that covers all | |||
header fields in the request: | header fields in the request: | |||
+==============+========================================+ | +==============+============================================+ | |||
| Property | Value | | | Property | Value | | |||
+==============+========================================+ | +==============+============================================+ | |||
| Algorithm | "hs2019", using RSASSA-PSS [RFC8017] | | | Algorithm | "hs2019", using RSASSA-PSS [RFC8017] using | | |||
| | using SHA-512 [RFC6234] | | | | SHA-512 [RFC6234] | | |||
+--------------+----------------------------------------+ | +--------------+--------------------------------------------+ | |||
| Covered | *created, *request-target, host, date, | | | Covered | "@request-target", "host", "date", | | |||
| Content | content-type, digest, content-length | | | Content | "content-type", "digest", "content-length" | | |||
+--------------+----------------------------------------+ | +--------------+--------------------------------------------+ | |||
| Creation | 8:51:35 PM GMT, June 7th, 2014 | | | Creation | 8:51:35 PM GMT, June 7th, 2014 | | |||
| Time | | | | Time | | | |||
+--------------+----------------------------------------+ | +--------------+--------------------------------------------+ | |||
| Expiration | Undefined | | | Expiration | Undefined | | |||
| Time | | | | Time | | | |||
+--------------+----------------------------------------+ | +--------------+--------------------------------------------+ | |||
| Verification | The public key specified in | | | Verification | The public key specified in | | |||
| Key Material | Appendix A.1.1. | | | Key Material | Appendix B.1.1. | | |||
+--------------+----------------------------------------+ | +--------------+--------------------------------------------+ | |||
Table 9 | Table 11 | |||
The Signature Input is: | The Signature Input is: | |||
*created: 1402170695 | "@request-target": post /foo?param=value&pet=dog | |||
*request-target: post /foo?param=value&pet=dog | "host": example.com | |||
host: example.com | "date": Tue, 07 Jun 2014 20:51:35 GMT | |||
date: Tue, 07 Jun 2014 20:51:35 GMT | "content-type": application/json | |||
content-type: application/json | "digest": SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | |||
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= | "content-length": 18 | |||
content-length: 18 | "@signature-params": ("@request-target" "host" "date" "content-type" "digest" "content-length"); keyid="test-key-a"; alg="hs2019"; created=1402170695 | |||
The signature value is: | The signature value is: | |||
B24UG4FaiE2kSXBNKV4DA91J+mElAhS3mncrgyteAye1GKMpmzt8jkHNjoudtqw3GngGY | B24UG4FaiE2kSXBNKV4DA91J+mElAhS3mncrgyteAye1GKMpmzt8jkHNjoudtqw3GngGY | |||
3n0mmwjdfn1eA6nAjgeHwl0WXced5tONcCPNzLswqPOiobGeA5y4WE8iBveel30OKYVel | 3n0mmwjdfn1eA6nAjgeHwl0WXced5tONcCPNzLswqPOiobGeA5y4WE8iBveel30OKYVel | |||
0lZ1OnXOmN5TIEIIPo9LrE+LzZis6A0HA1FRMtKgKGhT3N965pkqfhKbq/V48kpJKT8+c | 0lZ1OnXOmN5TIEIIPo9LrE+LzZis6A0HA1FRMtKgKGhT3N965pkqfhKbq/V48kpJKT8+c | |||
Zs0TOn4HFMG+OIy6c9ofSBrXD68yxP6QYTz6xH0GMWawLyPLYR52j3I05fK1ylAb6K0ox | Zs0TOn4HFMG+OIy6c9ofSBrXD68yxP6QYTz6xH0GMWawLyPLYR52j3I05fK1ylAb6K0ox | |||
PxzQ5nwrLD+mUVPZ9rDs1En6fmOX9xfkZTblG/5D+s1fHHs9dDXCOVkT5dLS8DjdIA== | PxzQ5nwrLD+mUVPZ9rDs1En6fmOX9xfkZTblG/5D+s1fHHs9dDXCOVkT5dLS8DjdIA== | |||
A possible "Signature-Input" and "Signature" header containing this | A possible "Signature-Input" and "Signature" header containing this | |||
signature is: | signature is: | |||
Signature-Input: sig1=(*request-target, *created, host, date, | # NOTE: '\' line wrapping per RFC 8792 | |||
content-type, digest, content-length); keyId="test-key-a"; | ||||
alg=hs2019; created=1402170695 | Signature-Input: sig1=("@request-target" "host" "date" | |||
Signature: sig1=:B24UG4FaiE2kSXBNKV4DA91J+mElAhS3mncrgyteAye1GKMpmzt8 | "content-type" "digest" "content-length"); keyid="test-key-a"; | |||
jkHNjoudtqw3GngGY3n0mmwjdfn1eA6nAjgeHwl0WXced5tONcCPNzLswqPOiobGe | alg="hs2019"; created=1402170695 | |||
A5y4WE8iBveel30OKYVel0lZ1OnXOmN5TIEIIPo9LrE+LzZis6A0HA1FRMtKgKGhT | Signature: sig1=:B24UG4FaiE2kSXBNKV4DA91J+mElAhS3mncrgyteAye1GKMpmzt8\ | |||
3N965pkqfhKbq/V48kpJKT8+cZs0TOn4HFMG+OIy6c9ofSBrXD68yxP6QYTz6xH0G | jkHNjoudtqw3GngGY3n0mmwjdfn1eA6nAjgeHwl0WXced5tONcCPNzLswqPOiobGe\ | |||
MWawLyPLYR52j3I05fK1ylAb6K0oxPxzQ5nwrLD+mUVPZ9rDs1En6fmOX9xfkZTbl | A5y4WE8iBveel30OKYVel0lZ1OnXOmN5TIEIIPo9LrE+LzZis6A0HA1FRMtKgKGhT\ | |||
3N965pkqfhKbq/V48kpJKT8+cZs0TOn4HFMG+OIy6c9ofSBrXD68yxP6QYTz6xH0G\ | ||||
MWawLyPLYR52j3I05fK1ylAb6K0oxPxzQ5nwrLD+mUVPZ9rDs1En6fmOX9xfkZTbl\ | ||||
G/5D+s1fHHs9dDXCOVkT5dLS8DjdIA==: | G/5D+s1fHHs9dDXCOVkT5dLS8DjdIA==: | |||
A.3.2. Signature Verification | B.3.2. Signature Verification | |||
A.3.2.1. Minimal Required Signature Header | B.3.2.1. Minimal Required Signature Header | |||
This presents a "Signature-Input" and "Signature" header containing | This presents a "Signature-Input" and "Signature" header containing | |||
only the minimal required parameters: | only the minimal required parameters: | |||
Signature-Input: sig1=(); keyId="test-key-a"; created=1402170695 | # NOTE: '\' line wrapping per RFC 8792 | |||
Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSzR9TYFV | ||||
vwUjeU6CTYUdbOByGMCee5q1eWWUOM8BIH04Si6VndEHjQVdHqshAtNJk2Quzs6WC | Signature-Input: sig1=(); keyid="test-key-a"; created=1402170695 | |||
2DkV0vysOhBSvFZuLZvtCmXRQfYGTGhZqGwq/AAmFbt5WNLQtDrEe0ErveEKBfaz+ | Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSzR9TYFV\ | |||
IJ35zhaj+dun71YZ82b/CRfO6fSSt8VXeJuvdqUuVPWqjgJD4n9mgZpZFGBaDdPiw | vwUjeU6CTYUdbOByGMCee5q1eWWUOM8BIH04Si6VndEHjQVdHqshAtNJk2Quzs6WC\ | |||
pfbVZHzcHrumFJeFHWXH64a+c5GN+TWlP8NPg2zFdEc/joMymBiRelq236WGm5VvV | 2DkV0vysOhBSvFZuLZvtCmXRQfYGTGhZqGwq/AAmFbt5WNLQtDrEe0ErveEKBfaz+\ | |||
IJ35zhaj+dun71YZ82b/CRfO6fSSt8VXeJuvdqUuVPWqjgJD4n9mgZpZFGBaDdPiw\ | ||||
pfbVZHzcHrumFJeFHWXH64a+c5GN+TWlP8NPg2zFdEc/joMymBiRelq236WGm5VvV\ | ||||
9a22RW2/yLmaU/uwf9v40yGR/I1NRA==: | 9a22RW2/yLmaU/uwf9v40yGR/I1NRA==: | |||
The corresponding signature metadata derived from this header field | The corresponding signature metadata derived from this header field | |||
is: | is: | |||
+=================+==========================================+ | +=================+==========================================+ | |||
| Property | Value | | | Property | Value | | |||
+=================+==========================================+ | +=================+==========================================+ | |||
| Algorithm | "hs2019", using RSASSA-PSS using SHA-256 | | | Algorithm | "hs2019", using RSASSA-PSS using SHA-256 | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Covered Content | *created | | | Covered Content | `` | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Creation Time | 8:51:35 PM GMT, June 7th, 2014 | | | Creation Time | 8:51:35 PM GMT, June 7th, 2014 | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Expiration Time | Undefined | | | Expiration Time | Undefined | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Verification | The public key specified in | | | Verification | The public key specified in | | |||
| Key Material | Appendix A.1.1. | | | Key Material | Appendix B.1.1. | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
Table 10 | Table 12 | |||
The corresponding Signature Input is: | The corresponding Signature Input is: | |||
*created: 1402170695 | "@signature-params": sig1=(); alg="hs2019"; keyid="test-key-a"; created=1402170695 | |||
A.3.2.2. Minimal Recommended Signature Header | B.3.2.2. Minimal Recommended Signature Header | |||
This presents a "Signature-Input" and "Signature" header containing | This presents a "Signature-Input" and "Signature" header containing | |||
only the minimal required and recommended parameters: | only the minimal required and recommended parameters: | |||
Signature-Input: sig1=(); alg=hs2019; keyId="test-key-a"; | # NOTE: '\' line wrapping per RFC 8792 | |||
Signature-Input: sig1=(); alg="hs2019"; keyid="test-key-a"; | ||||
created=1402170695 | created=1402170695 | |||
Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSzR9TYFV | Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSzR9TYFV\ | |||
vwUjeU6CTYUdbOByGMCee5q1eWWUOM8BIH04Si6VndEHjQVdHqshAtNJk2Quzs6WC | vwUjeU6CTYUdbOByGMCee5q1eWWUOM8BIH04Si6VndEHjQVdHqshAtNJk2Quzs6WC\ | |||
2DkV0vysOhBSvFZuLZvtCmXRQfYGTGhZqGwq/AAmFbt5WNLQtDrEe0ErveEKBfaz+ | 2DkV0vysOhBSvFZuLZvtCmXRQfYGTGhZqGwq/AAmFbt5WNLQtDrEe0ErveEKBfaz+\ | |||
IJ35zhaj+dun71YZ82b/CRfO6fSSt8VXeJuvdqUuVPWqjgJD4n9mgZpZFGBaDdPiw | IJ35zhaj+dun71YZ82b/CRfO6fSSt8VXeJuvdqUuVPWqjgJD4n9mgZpZFGBaDdPiw\ | |||
pfbVZHzcHrumFJeFHWXH64a+c5GN+TWlP8NPg2zFdEc/joMymBiRelq236WGm5VvV | pfbVZHzcHrumFJeFHWXH64a+c5GN+TWlP8NPg2zFdEc/joMymBiRelq236WGm5VvV\ | |||
9a22RW2/yLmaU/uwf9v40yGR/I1NRA==: | 9a22RW2/yLmaU/uwf9v40yGR/I1NRA==: | |||
The corresponding signature metadata derived from this header field | The corresponding signature metadata derived from this header field | |||
is: | is: | |||
+=================+==========================================+ | +=================+==========================================+ | |||
| Property | Value | | | Property | Value | | |||
+=================+==========================================+ | +=================+==========================================+ | |||
| Algorithm | "hs2019", using RSASSA-PSS using SHA-512 | | | Algorithm | "hs2019", using RSASSA-PSS using SHA-512 | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Covered Content | *created | | | Covered Content | `` | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Creation Time | 8:51:35 PM GMT, June 7th, 2014 | | | Creation Time | 8:51:35 PM GMT, June 7th, 2014 | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Expiration Time | Undefined | | | Expiration Time | Undefined | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
| Verification | The public key specified in | | | Verification | The public key specified in | | |||
| Key Material | Appendix A.1.1. | | | Key Material | Appendix B.1.1. | | |||
+-----------------+------------------------------------------+ | +-----------------+------------------------------------------+ | |||
Table 11 | Table 13 | |||
The corresponding Signature Input is: | The corresponding Signature Input is: | |||
*created: 1402170695 | "@signature-params": sig1=(); alg="rsa-sha256"; keyid="test-key-b" | |||
A.3.2.3. Minimal Signature Header using rsa-sha256 | B.3.2.3. Minimal Signature Header using rsa-sha256 | |||
This presents a minimal "Signature-Input" and "Signature" header for | This presents a minimal "Signature-Input" and "Signature" header for | |||
a signature using the "rsa-sha256" algorithm: | a signature using the "rsa-sha256" algorithm: | |||
Signature: sig1=(date); alg=rsa-sha256; keyId="test-key-b" | # NOTE: '\' line wrapping per RFC 8792 | |||
Signature: sig1=:HtXycCl97RBVkZi66ADKnC9c5eSSlb57GnQ4KFqNZplOpNfxqk62 | ||||
JzZ484jXgLvoOTRaKfR4hwyxlcyb+BWkVasApQovBSdit9Ml/YmN2IvJDPncrlhPD | Signature: sig1=("date"); alg=rsa-sha256; keyid="test-key-b" | |||
VDv36Z9/DiSO+RNHD7iLXugdXo1+MGRimW1RmYdenl/ITeb7rjfLZ4b9VNnLFtVWw | Signature: sig1=:HtXycCl97RBVkZi66ADKnC9c5eSSlb57GnQ4KFqNZplOpNfxqk62\ | |||
rjhAiwIqeLjodVImzVc5srrk19HMZNuUejK6I3/MyN3+3U8tIRW4LWzx6ZgGZUaEE | JzZ484jXgLvoOTRaKfR4hwyxlcyb+BWkVasApQovBSdit9Ml/YmN2IvJDPncrlhPD\ | |||
P0aBlBkt7Fj0Tt5/P5HNW/Sa/m8smxbOHnwzAJDa10PyjzdIbywlnWIIWtZKPPsoV | VDv36Z9/DiSO+RNHD7iLXugdXo1+MGRimW1RmYdenl/ITeb7rjfLZ4b9VNnLFtVWw\ | |||
rjhAiwIqeLjodVImzVc5srrk19HMZNuUejK6I3/MyN3+3U8tIRW4LWzx6ZgGZUaEE\ | ||||
P0aBlBkt7Fj0Tt5/P5HNW/Sa/m8smxbOHnwzAJDa10PyjzdIbywlnWIIWtZKPPsoV\ | ||||
oKVopUWEU3TNhpWmaVhFrUL/O6SN3w==: | oKVopUWEU3TNhpWmaVhFrUL/O6SN3w==: | |||
The corresponding signature metadata derived from this header field | The corresponding signature metadata derived from this header field | |||
is: | is: | |||
+===========================+==========================+ | +===========================+==========================+ | |||
| Property | Value | | | Property | Value | | |||
+===========================+==========================+ | +===========================+==========================+ | |||
| Algorithm | rsa-sha256 | | | Algorithm | rsa-sha256 | | |||
+---------------------------+--------------------------+ | +---------------------------+--------------------------+ | |||
| Covered Content | date | | | Covered Content | date | | |||
+---------------------------+--------------------------+ | +---------------------------+--------------------------+ | |||
| Creation Time | Undefined | | | Creation Time | Undefined | | |||
+---------------------------+--------------------------+ | +---------------------------+--------------------------+ | |||
| Expiration Time | Undefined | | | Expiration Time | Undefined | | |||
+---------------------------+--------------------------+ | +---------------------------+--------------------------+ | |||
| Verification Key Material | The public key specified | | | Verification Key Material | The public key specified | | |||
| | in Appendix A.1.1. | | | | in Appendix B.1.1. | | |||
+---------------------------+--------------------------+ | +---------------------------+--------------------------+ | |||
Table 12 | Table 14 | |||
The corresponding Signature Input is: | The corresponding Signature Input is: | |||
date: Tue, 07 Jun 2014 20:51:35 GMT | "date": Tue, 07 Jun 2014 20:51:35 GMT | |||
"@signature-params": ("date"); alg=rsa-sha256; keyid="test-key-b" | ||||
Appendix B. Topics for Working Group Discussion | ||||
_RFC EDITOR: please remove this section before publication_ | ||||
The draft has known issues that will need to be addressed during | ||||
development, and these issues have been enumerated but not addressed | ||||
in this version. Topics are not listed in any particular order. | ||||
B.1. Issues | ||||
B.1.1. Confusing guidance on algorithm and key identification | ||||
The current draft encourages determining the Algorithm metadata | ||||
property from the "keyId" field, both in the guidance for the use of | ||||
"algorithm" and "keyId", and the definition for the "hs2019" | ||||
algorithm and deprecation of the other algorithms in the registry. | ||||
The current state arose from concern that a malicious party could | ||||
change the value of the "algorithm" parameter, potentially tricking | ||||
the verifier into accepting a signature that would not have been | ||||
verified under the actual parameter. | ||||
Punting algorithm identification into "keyId" hurts interoperability, | ||||
since we aren't defining the syntax or semantics of "keyId". It | ||||
actually goes against that claim, as we are dictating that the | ||||
signing algorithm must be specified by "keyId" or derivable from it. | ||||
It also renders the algorithm registry essentially useless. Instead | ||||
of this approach, we can protect against manipulation of the | ||||
Signature header field by adding support for (and possibly mandating) | ||||
including Signature metadata within the Signature Input. | ||||
B.1.2. Lack of definition of keyId hurts interoperability | ||||
The current text leaves the format and semantics of "keyId" | ||||
completely up to the implementation. This is primarily due to the | ||||
fact that most implementers of Cavage have extensive investment in | ||||
key distribution and management, and just need to plug an identifier | ||||
into the header. We should support those cases, but we also need to | ||||
provide guidance for the developer that doesn't have that and just | ||||
wants to know how to identify a key. It may be enough to punt this | ||||
to profiling specs, but this needs to be explored more. | ||||
B.1.3. Algorithm Registry duplicates work of JWA | ||||
[RFC7518] already defines an IANA registry for cryptographic | ||||
algorithms. This wasn't used by Cavage out of concerns about | ||||
complexity of JOSE, and issues with JWE and JWS being too flexible, | ||||
leading to insecure combinations of options. Using JWA's definitions | ||||
does not need to mean we're using JOSE, however. We should look at | ||||
if/how we can leverage JWA's work without introducing too many sharp | ||||
edges for implementers. | ||||
In any use of JWS algorithms, this spec would define a way to create | ||||
the JWS Signing Input string to be applied to the algorithm. It | ||||
should be noted that this is incompatible with JWS itself, which | ||||
requires the inclusion of a structured header in the signature input. | ||||
A possible approach is to incorporate all elements of the JWA | ||||
signature algorithm registry into this spec using a prefix or other | ||||
marker, such as "jws-RS256" for the RSA 256 JSON Web Signature | ||||
algorithm. | ||||
B.1.4. Algorithm Registry should not be initialized with deprecated | ||||
entries | ||||
The initial entries in this document reflect those in Cavage. The | ||||
ones that are marked deprecated were done so because of the issue | ||||
explained in Appendix B.1.1, with the possible exception of "rsa- | ||||
sha1". We should probably just remove that one. | ||||
B.1.5. No percent-encoding normalization of path/query | ||||
See: issue #26 (https://github.com/w3c-dvcg/http-signatures/ | ||||
issues/26) | ||||
The canonicalization rules for "*request-target" do not perform | ||||
handle minor, semantically meaningless differences in percent- | ||||
encoding, such that verification could fail if an intermediary | ||||
normalizes the effective request URI prior to forwarding the message. | ||||
At a minimum, they should be case and percent-encoding normalized as | ||||
described in sections 6.2.2.1 and 6.2.2.2 of [RFC3986]. | ||||
B.1.6. Misleading name for headers parameter | ||||
The Covered Content list contains identifiers for more than just | ||||
headers, so the "header" parameter name is no longer appropriate. | ||||
Some alternatives: "content", "signed-content", "covered-content". | ||||
B.1.7. Changes to whitespace in header field values break verification | ||||
Some header field values contain RWS, OWS, and/or BWS. Since the | ||||
header field value canonicalization rules do not address whitespace, | ||||
changes to it (e.g., removing OWS or BWS or replacing strings of RWS | ||||
with a single space) can cause verification to fail. | ||||
B.1.8. Multiple Set-Cookie headers are not well supported | ||||
The Set-Cookie header can occur multiple times but does not adhere to | ||||
the list syntax, and thus is not well supported by the header field | ||||
value concatenation rules. | ||||
B.1.9. Covered Content list is not signed | ||||
The Covered Content list should be part of the Signature Input, to | ||||
protect against malicious changes. | ||||
B.1.10. Algorithm is not signed | ||||
The Algorithm should be part of the Signature Input, to protect | ||||
against malicious changes. | ||||
B.1.11. Verification key identifier is not signed | ||||
The Verification key identifier (e.g., the value used for the "keyId" | ||||
parameter) should be part of the Signature Input, to protect against | ||||
malicious changes. | ||||
B.1.12. Max values, precision for Integer String and Decimal String not | ||||
defined | ||||
The definitions for Integer String and Decimal String do not specify | ||||
a maximum value. The definition for Decimal String (used to provide | ||||
sub-second precision for Expiration Time) does not define minimum or | ||||
maximum precision requirements. It should set a sane requirement | ||||
here (e.g., MUST support up to 3 decimal places and no more). | ||||
B.1.13. keyId parameter value could break list syntax | ||||
The "keyId" parameter value needs to be constrained so as to not | ||||
break list syntax (e.g., by containing a comma). | ||||
B.1.14. Creation Time and Expiration Time do not allow for clock skew | ||||
The processing instructions for Creation Time and Expiration Time | ||||
imply that verifiers are not permitted to account for clock skew | ||||
during signature verification. | ||||
B.1.15. Should require lowercased header field names as identifiers | ||||
The current text allows mixed-case header field names when they are | ||||
being used as content identifiers. This is unnecessary, as header | ||||
field names are case-insensitive, and creates opportunity for | ||||
incompatibility. Instead, content identifiers should always be | ||||
lowercase. | ||||
B.1.16. Reconcile Date header and Creation Time | ||||
The draft is missing guidance on if/how the Date header relates to | ||||
signature Creation Time. There are cases where they may be | ||||
different, such as if a signature was pre-created. Should Creation | ||||
Time default to the value in the Date header if the "created" | ||||
parameter is not specified? | ||||
B.1.17. Remove algorithm-specific rules for content identifiers | ||||
The rules that restrict when the signer can or must include certain | ||||
identifiers appear to be related to the pseudo-revving of the Cavage | ||||
draft that happened when the "hs2019" algorithm was introduced. We | ||||
should drop these rules, as it can be expected that anyone | ||||
implementing this draft will support all content identifiers. | ||||
B.1.18. Add guidance for signing compressed headers | ||||
The draft should provide guidance on how to sign headers when | ||||
[RFC7541] is used. This guidance might be as simple as "sign the | ||||
uncompressed header field value." | ||||
B.1.19. Transformations to Via header field value break verification | ||||
Intermediaries are permitted to strip comments from the "Via" header | ||||
field value, and consolidate related sequences of entries. The | ||||
canonicalization rules do not account for these changes, and thus | ||||
they cause signature verification to fail if the "Via" header is | ||||
signed. At the very least, guidance on signing or not signing "Via" | ||||
headers needs to be included. | ||||
B.1.20. Case changes to case-insensitive header field values break | ||||
verification | ||||
Some header field values are case-insensitive, in whole or in part. | ||||
The canonicalization rules do not account for this, thus a case | ||||
change to a covered header field value causes verification to fail. | ||||
B.1.21. Need more examples for Signature header | ||||
Add more examples showing different cases e.g, where "created" or | ||||
"expires" are not present. | ||||
B.1.22. Expiration not needed | ||||
In many cases, putting the expiration of the signature into the hands | ||||
of the signer opens up more options for failures than necessary. | ||||
Instead of the "expires", any verifier can use the "created" field | ||||
and an internal lifetime or offset to calculate expiration. We | ||||
should consider dropping the "expires" field. | ||||
B.2. Features | ||||
B.2.1. Define more content identifiers | ||||
It should be possible to independently include the following content | ||||
and metadata properties in Covered Content: | ||||
* The signature's Algorithm | ||||
* The signature's Covered Content | ||||
* The value used for the "keyId" parameter | ||||
* Request method | ||||
* Individual components of the effective request URI: scheme, | ||||
authority, path, query | ||||
* Status code | ||||
* Request body (currently supported via Digest header [RFC3230] ) | ||||
B.2.2. Multiple signature support | ||||
(( Editor's note: I believe this use case is theoretical. Please let | ||||
me know if this is a use case you have. )) | ||||
There may be scenarios where attaching multiple signatures to a | ||||
single message is useful: | ||||
* A gateway attaches a signature over headers it adds (e.g., | ||||
"Forwarded") to messages already signed by the user agent. | ||||
* A signer attaches two signatures signed by different keys, to be | ||||
verified by different entities. | ||||
This could be addressed by changing the Signature header syntax to | ||||
accept a list of parameter sets for a single signature, e.g., by | ||||
separating parameters with "";"" instead of "","". It may also be | ||||
necessary to include a signature identifier parameter. | ||||
B.2.3. Support for incremental signing of header field value list items | ||||
(( Editor's note: I believe this use case is theoretical. Please let | ||||
me know if this is a use case you have. )) | ||||
Currently, signing a header field value is all-or-nothing: either the | ||||
entire value is signed, or none of it is. For header fields that use | ||||
list syntax, it would be useful to be able to specify which items in | ||||
the list are signed. | ||||
A simple approach that allowed the signer to indicate the list size | ||||
at signing time would allow a signer to sign header fields that are | ||||
may be appended to by intermediaries as the message makes its way to | ||||
the recipient. Specifying list size in terms of number of items | ||||
could introduce risks of list syntax is not strictly adhered to | ||||
(e.g., a malicious party crafts a value that gets parsed by the | ||||
application as 5 items, but by the verifier as 4). Specifying list | ||||
size in number of octets might address this, but more exploration is | ||||
required. | ||||
B.2.4. Support expected authority changes | ||||
In some cases, the authority of the effective request URI may be | ||||
expected to change, for example from "public-service- | ||||
name.example.com" to "service-host-1.public-service- | ||||
name.example.com". This is commonly the case for services that are | ||||
hosted behind a load-balancing gateway, where the client sends | ||||
requests to a publicly known domain name for the service, and these | ||||
requests are transformed by the gateway into requests to specific | ||||
hosts in the service fleet. | ||||
One possible way to handle this would be to special-case the Host | ||||
header field to allow verifier to substitute a known expected value, | ||||
or a value provided in another header field (e.g., "Via") when | ||||
generating the Signature Input, provided that the verifier also | ||||
recognizes the real value in the "Host" header. Alternatively, this | ||||
logic could apply to an "(audience)" content identifier. | ||||
B.2.5. Support for signing specific cookies | ||||
A signer may only wish to sign one or a few cookies, for example if | ||||
the website requires its authentication state cookie to be signed, | ||||
but also sets other cookies (e.g., for analytics, ad tracking, etc.) | ||||
Acknowledgements | Acknowledgements | |||
This specification is based on the draft-cavage-http-signatures | This specification was initially based on the draft-cavage-http- | |||
draft. The editor would like to thank the authors of that draft, | signatures internet draft. The editors would like to thank the | |||
Mark Cavage and Manu Sporny, for their work on that draft and their | authors of that draft, Mark Cavage and Manu Sporny, for their work on | |||
continuing contributions. | that draft and their continuing contributions. | |||
The editor would also like to thank the following individuals for | The editor would also like to thank the following individuals for | |||
feedback on and implementations of the draft-cavage-http-signatures | feedback on and implementations of the draft-cavage-http-signatures | |||
draft (in alphabetical order): Mark Adamcin, Mark Allen, Paul | draft (in alphabetical order): Mark Adamcin, Mark Allen, Paul | |||
Annesley, Karl Boehlmark, Stephane Bortzmeyer, Sarven Capadisli, Liam | Annesley, Karl Boehlmark, Stephane Bortzmeyer, Sarven Capadisli, Liam | |||
Dennehy, ductm54, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, | Dennehy, ductm54, Stephen Farrell, Phillip Hallam-Baker, Eric Holmes, | |||
Andrey Kislyuk, Adam Knight, Dave Lehn, Dave Longley, James H. | Andrey Kislyuk, Adam Knight, Dave Lehn, Dave Longley, James H. | |||
Manger, Ilari Liusvaara, Mark Nottingham, Yoav Nir, Adrian Palmer, | Manger, Ilari Liusvaara, Mark Nottingham, Yoav Nir, Adrian Palmer, | |||
Lucas Pardue, Roberto Polli, Julian Reschke, Michael Richardson, | Lucas Pardue, Roberto Polli, Julian Reschke, Michael Richardson, | |||
Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk Stein, Henry | Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk Stein, Henry | |||
Story, Lukasz Szewc, Chris Webber, and Jeffrey Yasskin | 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 | |||
skipping to change at page 41, line 29 ¶ | skipping to change at page 37, line 16 ¶ | |||
Lucas Pardue, Roberto Polli, Julian Reschke, Michael Richardson, | Lucas Pardue, Roberto Polli, Julian Reschke, Michael Richardson, | |||
Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk Stein, Henry | Wojciech Rygielski, Adam Scarr, Cory J. Slep, Dirk Stein, Henry | |||
Story, Lukasz Szewc, Chris Webber, and Jeffrey Yasskin | 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 | |||
- Since -01 | - Since -02 | |||
- -02 | ||||
o Removed editorial comments on document sources. | ||||
o Removed in-document issues list in favor of tracked issues. | ||||
o Replaced unstructured "Signature" header with "Signature- | o Replaced unstructured "Signature" header with "Signature- | |||
Input" and "Signature" Dictionary Structured Header Fields. | Input" and "Signature" Dictionary Structured Header Fields. | |||
o Defined content identifiers for individual Dictionary | o Defined content identifiers for individual Dictionary | |||
members, e.g., "x-dictionary-field:member-name". | members, e.g., ""x-dictionary-field";key=member-name". | |||
o Defined content identifiers for first N members of a List, | o Defined content identifiers for first N members of a List, | |||
e.g., "x-list-field:4". | e.g., ""x-list-field":prefix=4". | |||
o Fixed up examples. | o Fixed up examples. | |||
o Updated introduction now that it's adopted. | o Updated introduction now that it's adopted. | |||
o Defined specialty content identifiers and a means to extend | ||||
them. | ||||
o Required signature parameters to be included in signature. | ||||
o Added guidance on backwards compatibility, detection, and | ||||
use of signature methods. | ||||
- -01 | - -01 | |||
o Strengthened requirement for content identifiers for header | o Strengthened requirement for content identifiers for header | |||
fields to be lower-case (changed from SHOULD to MUST). | fields to be lower-case (changed from SHOULD to MUST). | |||
o Added real example values for Creation Time and Expiration | o Added real example values for Creation Time and Expiration | |||
Time. | Time. | |||
o Minor editorial corrections and readability improvements. | o Minor editorial corrections and readability improvements. | |||
End of changes. 162 change blocks. | ||||
833 lines changed or deleted | 649 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/ |