Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language for signer inheritance #377

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions cddl/cmw-corim-bundle.cddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
corim-cbor-collection = {
"__cmwc_t" => "tag:{{&SELF}}:bundle",
+ cmw-label => [10572, bytes .cbor tagged-corim-map]
}
cmw-label = text / int
1 change: 1 addition & 0 deletions cddl/corim-role-type-choice.cddl
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
$corim-role-type-choice /= &(manifest-creator: 1)
$corim-role-type-choice /= &(manifest-signer: 2)
42 changes: 42 additions & 0 deletions cddl/examples/cmw-corim-bundle.diag
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/ cbor-collection / {
"__cmwc_t": "tag:{{&SELF}}:bundle",
"adee8cd4-4e47-461f-b341-2aba3ae4cbda":
/ cbor-cmw / [10572, << / tagged-corim-map / 501({
/ id / 0: h'adee8cd44e47461fb3412aba3ae4cbda',
/ tags / 1: [/ tagged-concise-mid-tag / 506(<<{
/ tag-identity / 1: {
/ tag-id / 0: h'315cfc0208d548ee9c89906df96e7fb8'
},
/ triples / 4: {
/ reference-triples / 0: [[
/ ref-env / {/ class / 0: {/ class-id / 0: 560(h'c0de')}},
/ ref-claims / {
/ mval / 1: {
/ profile-foo / -404:
h'6094685f8bb9b67daaf35707bd2c391f536a1df2ce5152c3cc'
}}]],
/ coswid-triples / 6: [[
{/ class / 0: {/ class-id / 0: 560(h'c0de')}},
[h'369a6688451240b9b74905b1dd5fae9f']]]}}>>)],
/ profile / 3: "tag:example.com,2025/example-profile",
/ dependent-rims / 2: [{
/ href / 0: [
"urn:uuid:51a5f633-71c0-45f5-855e-43e8254c1806",
"https://example.com/369a6688451240b9b74905b1dd5fae9f.corim"
]}]}) >>],
"51a5f633-71c0-45f5-855e-43e8254c1806":
/ cbor-cmw / [10572, << / tagged-corim-map / 501({
/ id: / 0: h'51a5f63371c045f5855e43e8254c1806',
/ tags / 1: [/ tagged-concise-swid-tag / 505(<<{
/ tag-id / 0: h'369a6688451240b9b74905b1dd5fae9f',
/ tag-version / 12: 2,
/ software-name / 1: "Gadget Firmware",
/ entity / 2: {
/ entity-name / 31: "ACME Firmware",
/ role / 33: / software-creator / 2
},
/ profile-bar / 4294967295: {
/ profile-baz / 0: 5,
/ profile-qux / 1: h'f76e41f3462a62e8'}}>>)],
/ profile / 3: "tag:example.com,2025/software-profile"})>>]
}
42 changes: 42 additions & 0 deletions cddl/examples/corim-roles.diag
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/ tagged-corim-map / 501({
/ corim.id / 0 : h'284e6c3e5d9f4f6b851f5a4247f243a7',
/ corim.entities / 5 : [
{
/ corim.entity-name / 0 : "OEM-A",
/ corim.reg-id / 1 : 32("https://oem-a.example"),
/ corim.role / 2 : [ 2 ] / manifest-signer /
}
],
/ corim.tags / 1 : [
/ concise-mid-tag / 506( <<
/ concise-mid-tag / {
/ comid.tag-identity / 1 : {
/ comid.tag-id / 0 : h'3f06af63a93c11e4979700505690773f'
},
/ comid.triples / 4 : {
/ comid.reference-triples / 0 : [ [
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 :
/ tagged-uuid-type / 37(
h'67b28b6c34cc40a19117ab5b05911e37'
)
}
},
[
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.ver / 0 : {
/ comid.version / 0 : "1.0.0",
/ comid.version-scheme / 1 : 16384 / semver /
}
}
}
]
] ]
}
}
>> )
]
}
)
37 changes: 36 additions & 1 deletion draft-ietf-rats-corim.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ normative:

informative:
RFC7942:
RFC9277:
I-D.fdb-rats-psa-endorsements: psa-endorsements
I-D.tschofenig-rats-psa-token: psa-token
I-D.ietf-rats-endorsements: rats-endorsements
I-D.ietf-rats-msg-wrap: cmw
DICE.Layer:
title: DICE Layering Architecture
author:
Expand Down Expand Up @@ -266,7 +268,7 @@ For more detail, see {{sec-corim-profile-types}}.

A CoRIM can be signed ({{sec-corim-signed}}) using COSE Sign1 to provide end-to-end security to the CoRIM contents.
When CoRIM is signed, the protected header carries further identifying information about the CoRIM signer.
Alternatively, CoRIM can be encoded as a #6.501 CBOR-tagged payload ({{sec-corim-map}}) and transported over a secure channel.
Alternatively, an unsigned CoRIM can be encoded as a #6.501 CBOR-tagged payload ({{sec-corim-map}}) and transported over a secure channel and maintain a notion of a CoRIM signer ({{sec-conveyed-signer}}).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Alternatively, an unsigned CoRIM can be encoded as a #6.501 CBOR-tagged payload ({{sec-corim-map}}) and transported over a secure channel and maintain a notion of a CoRIM signer ({{sec-conveyed-signer}}).
Alternatively, an unsigned CoRIM can be encoded as a #6.501 CBOR-tagged payload ({{sec-corim-map}}) and transported over a secure channel where the CoRIM signer authority is inherited from the secure channel credential. (See {{sec-conveyed-signer}}).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the parentheses necessary for the pointer?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not certain of the convention. It appears that if a capital "See" is used then there are not parens, but if a lower case "see" is used it is inside of parens. Probably correct to remove the parens.


The following CDDL describes the top-level CoRIM.

Expand Down Expand Up @@ -481,6 +483,39 @@ Described in {{sec-common-validity}}.
{::include cddl/unprotected-corim-header-map.cddl}
~~~

## Signer authority of securely conveyed unsigned CoRIM {#sec-conveyed-signer}

An unsigned (#6.501-tagged) CoRIM may be a payload in an enveloping signed document.
An unsigned CoRIM may be a payload within a secure channel.
In both cases, there is a method of integrity protection that relies on some authentication.
The role of "the CoRIM signer" MUST be specified in both cases, with the same constraint on the signed CoRIM that there is a single signer.
Comment on lines +490 to +491
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In both cases, there is a method of integrity protection that relies on some authentication.
The role of "the CoRIM signer" MUST be specified in both cases, with the same constraint on the signed CoRIM that there is a single signer.
The CoRIM signer authority is taken from the authenticated credential of the same entity that originates the CoRIM.
A CoRIM role entry that contains the `manifest-signer` role MUST be added to `corim-entity-map`.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role MUST be added? By the sender or receiver? This will be hard to enforce. Anyone transmitting a CoRIM has to transform it first?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role MUST be added? By the sender or receiver? This will be hard to enforce. Anyone transmitting a CoRIM has to transform it first?

I'm trying to reflect the normative that applies to corim-signer-map which is not optional when COSE-sign1-corim is used. The corim author (typically is also the signer). If "sender" means author, then those are the semantics I was envisioning. The corim author can modify the corim.entities normally. Originally, only corim.entities contained manifest-signer property but was removed when we defined COSE-sign1-corim. Given we're supporting other signature formats, it makes sense to put it back in. However, the CDDL doesn't make it mandatory so we need normative prose. It wouldn't be incorrect if manifest signer role info was always populated, even if COSE-sign1-corim was used. But it would be in two places at that point. A COSE-sign1-corim signer could remove manifest-signer from corim.entities if an upstream process supplied it (to remove unnecessary bytes).

If the manifest-creator knows who the manifest-signer is supposed to be then the manifest creator can populate corim.entities. If the signer is a COSE-sign1-corim entity, then they can choose to remove the rundundant bytes or just layer on the corim-meta-map as part of the COSE header.

If the manifest creator doesn't know the manifest signer yet, then I don't see an alternative other than for the signer to modify the image. Possibly, the implementation has to define a template structure that pre-allocates space for the fix up?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have multiple builders all authenticated to an orchestrator and builders send unsigned reference values over a secure channel to the orchestrator, then the orchestrator sends the collection of reference values in a CMW to a signer, then it seems like I'm breaking your MUST rule because of the two hops. Is that an intentional restriction?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that an intentional restriction?

I don't think so. The first hop sounds more like authoring activity, in which case there might be multiple role entities added before it gets to the orchestrator. Since the orchestrator is the last to touch it before it goes to the Verifier that seems closest to original intent. The original discussions assumed COSE signing and stopped short of trying to capture deep suppy chain workflow use cases. Basically, if the orchestrator is the last stop before handing it over to a Verfier, then any of the other entities that may have been involved can be listed as entities but the signer is trusted to assemble the list of entities. Doing supply chain provenance (aka in-toto) was a non-goal).

BTW: I'm interpreting your use of "CMW to a signer" as meaning to a Verifier. If you meant "signer" to be part of the supply chain before the CMW arrives at a Verifier, then the "signer" fills in the entities list based on the defined roles reserving the manifest-signer role for itself.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the requirement to modify the internals of the map. It's unnecessary in the case of my bundle use, where the signature must be a COSE envelope and must use the corim-meta statement.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The primary objective is that the ACS ECT authority is populated correctly. If the information isn't inside the corim then the downstream network has to maintain state across parsing layers that strip off various layers. I think it is easier to talk about how to construct the message than how to maintain ancillary state post parsing.


It is out of scope of this document to specify a method of delegating the signer role in the case that an unsigned CoRIM is conveyed through multiple secured links with different notions of authenticity without end-to-end integrity protection.

### CoRIM bundles

A method of signing a bundle of CoRIMs together is through a signed RATS Conceptual Message Wrapper (CMW) {{-cmw}}.
Let `tag:{{&SELF}}:bundle` name a collection type that when signed MUST include the `corim-meta` protected header.
Copy link
Collaborator

@nedmsmith nedmsmith Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Let `tag:{{&SELF}}:bundle` name a collection type that when signed MUST include the `corim-meta` protected header.
The COSE_Sign1 signature format can be used with a CMW collection. The COSE protected header can include a CMW collection type name.
The collection type name SHALL be of the form: `tag:{{&SELF}}:bundle`.
The signing operation MUST include the `corim-meta` in the COSE_Sign1 `protected-header` parameter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The CMW collection signature structure" sounds strange to me, since it's the COSE signing structure.

The `corim-meta` statement ensures that each CoRIM in the bundle has an identified signer.

~~~ cddl
{::include cddl/cmw-corim-bundle.cddl}
~~~

The CMW MAY use any label for its CoRIMs.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following section seems too terse to follow. Possibly, more of the CDDL context is needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

If there is a hierarchical structure to the CoRIM bundle, the base entry point SHOULD be labeled `0` in CBOR or `"base"` in JSON.
It is RECOMMENDED to use to label a CoRIM with its tag-id in string format, where `uuid-type` string format is specified by [RFC4122].
CoRIMs distributed in a bundle MAY declare their interdependence `dependent-rims` with local resource indicators.
It is RECOMMENDED that a CoRIM with a `uuid-type` tag-id be referenced with URI `urn:uuid:`_tag-id-uuid-string_.
It is RECOMMENDED that a CoRIM with a `tstr` tag-id be referenced with `tag:{{&SELF}}:local,`_tag-id-tstr_.
It is RECOMMENDED for a `corim-locator-map` containing local URI to afterwards list a nonzero amount of reachable URLs as remote references.

<!-- TODO: replace "supposes" when the number is allocated. -->
The following example supposes the CoAP Content-Format ID for `application/rim+cbor` to be 10572.

~~~cbor-diag
{::include cddl/examples/cmw-corim-bundle.diag}
~~~

# Concise Module Identifier (CoMID) {#sec-comid}

Expand Down