Closed OR13 closed 3 months ago
The main reasons is integrity protection, and being able to swap detached payload of hash of content for detached payload of content, in protocol messages that require COSE Sign 1.
If ? 4 : any # object containing other details and things can be any object, then its totally possible we could simply put a cose sign 1 with detached payload there, but the structure of the signed statement would then become an OR type of special kinds of COSE_Hash_V and special kinds of COSE Sign 1.
I do think its awkward that we can't directly use COSE_Hash_V in COSE sign 1 headers, perhaps registering a single header that is a COSE_Hash_V or set of COSE_Hash_V is a better approach?
I wanted to continue this discussion here.
I get the use case for indirect identification of content for COSE vrs direct identification of content. Unfortunately, COSE was authored in such a way that indirect identification of content is considered an application layer concept and not a core concept within COSE explicitly.
Given the only way to validate a COSE message is to provide the content as part of the verification structure, we're left with needing application layer logic to manage expectations of indirect identification. If we need application layer logic, then I'm not quite seeing how moving everything but the hash value into COSE protected headers solve this problem differently vrs using a COSE_Hash_V
structure as the COSE message content for indirect identification of content and processing it as such via content-type of COSE_Hash_V identification.
It is also possible that there is another problem that moving fields into the COSE protected header is intended to solve, which may not have been fully articulated yet, beyond integrity protection?
A hash of content is just another app layer concern.
In https://github.com/cose-wg/draft-ietf-cose-merkle-tree-proofs
We have COSE Sign 1 payload that are merkle tree roots for a specific type of application cose sign 1 called a "receipt".
We discover the semantics necessary to process this payload, from the protected headers.
The approach taken here is essentially the same, except it is for "signed statements"
( these terms, "signed statements, and receipts" come from SCITT, see https://datatracker.ietf.org/doc/html/draft-ietf-scitt-architecture-04#section-5 )
The reason it is desirable to have a signed hash and meta data, that is also a COSE Sign 1, is that a Verifier will have a policy that says:
Then the "Issuer" can register a tiny message, and the Verifier / TS can simply check to see if they trust they key... because the payload is a hash, there is nothing else to check.
I'm guessing the issue lies in the use of "detached" vrs indirect.
When working with this in the past, it was found that a COSE Sign 1 cannot be validated without access to what COSE calls the payload in bstr form.
When looking at RFC 9052: CBOR Object Signing and Encryption (COSE): Structures and Process (rfc-editor.org)https://www.rfc-editor.org/rfc/rfc9052#name-signing-and-verification-pr, specifically 4.4's Sig_structure:
Sig_structure = [ context : "Signature" / "Signature1", body_protected : empty_or_serialized_map, ? sign_protected : empty_or_serialized_map, external_aad : bstr, payload : bstr ]
As I understand it and have experienced thus far, the COSE payload must always be provided to perform verification (even in a detached COSE message). Without the payload, the COSE message cannot be verified and/or processed. This means that anything wanting to process a COSE message must always have access to the payload which was used to generate the COSE message. The issue with SCITT, along with other verifier scenarios, is they want to be able to verify the COSE message (and read headers etc) without needing access to the payload. However to validate that COSE message hasn't been tampered with, they still must process a payload to satisfy the Sig_structure.
Unless I am missing something major, it doesn't seem possible for a verifier to allow a detached COSE signature without the payload also being accessible. In the case where the hash is the COSE payload, an embedded COSE signature makes far more sense given the complexity of managing and dealing with the various pieces of a detached COSE signature for such a small payload provides little value.
In other words, I'm not sure there is a ton of value for a detached COSE signature to be used in the verifier use case of hashes. Once a verifier needs to support a detached COSE signature, they then must support the entity posting the COSE message to it, to also provide the payload and the choice of how large that payload can/should be is a function of the verifiers policy.
I think the confusion may be stemming from the use of "detached payloads" which I'm interpreting as "detached COSE signatures" where it's quite possible others may be interpreting it as "indirect content identification".
My summary is as follows:
Those payloads provided for COSE verification could either be the raw content (of whatever size limits imposed by the verifier), or a hash of content, but that payload must still be provided to the verifier.
I'm just not sure how one handles trying to support detached payloads as a verifier and still not want access to payloads. Access to payloads is simply a requirement of COSE.
From: Orie Steele @.>
Sent: Friday, January 12, 2024 12:59 PM
To: OR13/draft-steele-cose-hash-envelope @.>
Cc: Comment @.***>
Subject: Re: [OR13/draft-steele-cose-hash-envelope] Use COSE_Hash_V
(Issue #9)
A hash of content is just another app layer concern.
In https://github.com/cose-wg/draft-ietf-cose-merkle-tree-proofs
We have COSE Sign 1 payload that are merkle tree roots for a specific type of application cose sign 1 called a "receipt".
We discover the semantics necessary to process this payload, from the protected headers.
The approach taken here is essentially the same, except it is for "signed statements"
( these terms, "signed statements, and receipts" come from SCITT, see https://datatracker.ietf.org/doc/html/draft-ietf-scitt-architecture-04#section-5 )
The reason it is desirable to have a signed hash and meta data, that is also a COSE Sign 1, is that a Verifier will have a policy that says:
Then the "Issuer" can register a tiny message, and the Verifier / TS can simply check to see if they trust they key... because the payload is a hash, there is nothing else to check.
— Reply to this email directly, view it on GitHubhttps://github.com/OR13/draft-steele-cose-hash-envelope/issues/9#issuecomment-1889942444 or unsubscribehttps://github.com/notifications/unsubscribe-auth/AC7XYFMUD5NCWCNKTSPSKUTYOGP47BFKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLLDTOVRGUZLDORPXI6LQMWWES43TOVSUG33NNVSW45FGORXXA2LDOOJIFJDUPFYGLKTSMVYG643JORXXE6NFOZQWY5LFVE3TCNJTGAZTONBZQKSHI6LQMWSWS43TOVS2K5TBNR2WLKRSGA3TANRQHA4TQOFHORZGSZ3HMVZKMY3SMVQXIZI. You are receiving this email because you commented on the thread.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
I agree with Jeromy that, in the context of indirect signatures where the payload is a hash, it's confusing to discuss detached payloads. A primary benefit of an indirect signature is that a hash is small, so a verifier does not need access to a potentially large payload to verify the envelope's signature. Detached payloads are of course "allowed" and can be supported if the hash/payload is provided to a verifier out of band, but I don't see a strong use case.
I also agree that it seems more straightforward to use the COSE_Hash_V
structure as the payload, rather than in a new header (especially because the latter implies duplication of the hash bstr as both the payload and a required field in the header value). With this approach, the existing content type: 3
header could be used to accurately describe the payload content as a COSE_Hash_V
structure, and the application can process it accordingly. I'm not sure that the new typ
header describing the type of the envelope is even necessary in this scenario.
I actually think there's an opportunity to avoid needing to register any new header parameters at all, leveraging content type
. Rather than using the new payload_preimage_content_type
header parameter, we could register a +cose-hash-v
media type suffix. This would concisely signal to an application that the payload is a COSE_Hash_V
structure representing a preimage of the specified type, e.g. application/json+cose-hash-v
, while requiring no special handling of the envelope or new semantics. It's also consistent with the principle Jeromy highlighted, that indirection is an application layer concept.
Are there scenarios that this approach would be incompatible with?
Are there scenarios that this approach would be incompatible with?
Honestly (and maybe unsurprisingly so), I am having a hard time to envision usage scenarios where this would pose a problem. I'd even would go as far as to say that the "indirection is dealt with by application layer" approach was my preferred choice when the topic came up (sans the now solidifying details of +cose-hash-v
and the corresponding COSE_Hash_V
, which I totally can get behind at). I'd happily step up as contributor, if this proposal becomes the new direction,
Anyone have any other input here? We're going to put a working implementation and can come back to this group to share and discuss more as needed.
@ianjmcm, have you made any progress on this? We're going to bring this draft to the COSE working group in Vancouver. More input would be really helpful.
I don't think we can use this approach, because of how we are handling the hash algorithm in the header, and the hash value in the payload.
Hash_Envelope_Protected_Header = {
; Signature algorithm to use
? &(alg: 1) => int,
; Hash algorithm used to produce the payload from content
&(payload_hash_alg: TBD_1) => int
; Content type of the preimage
&(payload_preimage_content_type: TBD_2) => int
; Location the content of the hashed payload is stored
? &(payload_location: TBD_3) => tstr
* int => any
}
Hash_Envelope_as_COSE_Sign1 = [
protected : bstr .cbor Hash_Envelope_Protected_Header,
unprotected : Hash_Envelope_Unprotected_Header,
payload: bstr / nil,
signature : bstr
]
We do not want to tell people they have to parse label 3 (content_type) to understand the media type of the content that was hashed.
We discussed this with @cabo and other at IETF Prague, and it lead to the current structure.
Discussion at IETF 120 circled around avoiding content-types from representing these more complex structures. The adoption of RFC 9596 was the direction the COSE WG felt made the most sense. Closing based on the updates, including #18
Add a single header for an instance or set of
COSE_Hash_V
, instead of multiple headers... as discussed in https://github.com/OR13/draft-steele-cose-hash-envelope/pull/7#issuecomment-1879407221