From 42f50c05b465f6b7ec3795854222e9cc2b258fdc Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Wed, 24 Apr 2024 19:59:15 -0700 Subject: [PATCH 1/6] Substantial rewrite, introducing the terms endorser and endorsee, and clarifying the workflow for each role --- docs/antora.yml | 2 +- docs/modules/ROOT/pages/index.adoc | 199 ++++++++++++++---- .../schemas/cddl/endorsement-target.cddl | 8 +- .../ROOT/partials/version-history.adoc | 4 + 4 files changed, 169 insertions(+), 44 deletions(-) diff --git a/docs/antora.yml b/docs/antora.yml index 46db0ce..6f90407 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -1,4 +1,4 @@ name: endorsement -version: 1.0-draft +version: 1.0-draft2 title: Endorsement Assertion start_page: index.adoc diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index f9635c6..00af98f 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -4,9 +4,9 @@ :sectanchors: :sectnums: -An endorsement is a way of indicating approval for specific actions made on content after it has had a link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[C2PA Manifest] attached. (See xref:_generating_an_endorsement[xrefstyle=full].) The *endorsement assertion* is where an endorsement from the signer of an ingredient asset is stored. These endorsements are typically provided (out-of-band of this specification) by ingredient asset signers to actors those signers trust to perform the actions listed in the assertion. They are used by a validator when assessing whether the actions of the active manifest are “endorsed” or not. (See xref:_validation[xrefstyle=full].) +An _<<_endorsement,endorsement>>_ is a way of indicating approval for specific actions made on content after it has had a _<>_ attached. (See xref:_generating_an_endorsement[xrefstyle=full].) The *endorsement assertion* is where an _<<_endorsement,endorsement>>_ from the signer of an ingredient _<>_ (known here as an _<<_endorser,endorser>>_) is stored. These _<<_endorsement,endorsements>>_ are typically provided (out-of-band of this specification) by ingredient _<>_ signers to actors those signers trust to perform the actions listed in the assertion (known here as _<<_endorsee,endorsees>>_). They are used by a validator when assessing whether the actions of the active _<>_ are “endorsed” or not. (See xref:_validation[xrefstyle=full].) -Version 1.0 *Draft 04 March 2024* · xref:_version_history[] +Version 1.0 *Draft 24 April 2024* · xref:_version_history[] [#maintainers] *Maintainers:* @@ -28,39 +28,162 @@ IMPORTANT: For purposes of the Community Specification License, the link:https:/ === Overview -Endorsements are a way of indicating approval of three possible actions (see xref:_permitted_actions[xrefstyle=full]) that could be applied to an asset in a link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[C2PA Manifest] in which the asset is used as an ingredient. +_<<_endorsement,Endorsements>>_ are a way of indicating approval of three possible actions (see xref:_permitted_actions[xrefstyle=full]) that could be applied to an _<>_ described by a _<>_ in which the _<>_ is used as an ingredient. -For example, the signer of a link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[C2PA Manifest] may want to endorse another party who wishes to transcode its asset. The signer creates an endorsement that identifies the transcoder, and conveys the endorsement to them (in some method that is out-of-band from this specification). When the transcoder creates their asset containing the ingredient, they include the endorsement as an *endorsement assertion,* which lets the manifest consumer know that the actions they performed have been endorsed. +_<<_endorsement,Endorsements>>_ endorse the specific actions (described in xref:_permitted_actions[xrefstyle=full]) that MAY be taken by the _<<_endorsee,endorsee>>_, and are therefore valid for _<<_c2pa_manifest,C2PA Manifests>>_ that use only the specified actions. Actions are only endorsed by the signer of that action’s referenced ingredient (known here as the _<<_endorser,endorser>>_); they cannot be endorsed across more than multiple _<<_c2pa_manifest,C2PA Manifests>>_ in the _<<_c2pa_asset,C2PA asset’s>>_ provenance. -Endorsements are made by signers, and describe the actor they are endorsing through the use of their signing credentials and a validity period. These endorsements are conveyed out-of-band from the endorser to the endorsee. When the endorsee is using an asset created by the endorser as an ingredient in their own asset, they shall include the endorsement in its link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[C2PA Manifest]. +=== Use case -Endorsements endorse the specific actions (described in xref:_permitted_actions[xrefstyle=full]) that may be taken by the endorsee, and are therefore valid for asset manifests that use only the specified actions. Actions are only endorsed by the signer of that action’s referenced ingredient; they cannot be endorsed across more than multiple link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[C2PA Manifests] in the asset’s provenance. +As one example, an _<<_endorser,endorser>>_ may want to endorse another party, such as a content-distribution network, who will transcode its _<>_ as part of a publication workflow. The _<<_endorser,endorser>>_ creates an _<<_endorsement,endorsement>>_ that identifies the transcoder, and conveys the _<<_endorsement,endorsement>>_ to them in some method that is out-of-band from this specification. When the transcoder creates their _<>_ containing the ingredient, they include the _<<_endorsement,endorsement>>_ as an *endorsement assertion,* which lets the _<>_ consumer know that the actions they performed have been endorsed. == Normative references * https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html[C2PA technical specification, version 2.0] * https://tools.ietf.org/html/rfc5280[Internet X.509 public key infrastructure certificate] (RFC 5280) +== Terms and definitions + +=== Actor + +A human or non-human (hardware or software) that is participating in the C2PA ecosystem. For example: a camera (capture device), image editing software, cloud service, or the person using such tools. + +NOTE: An organization or group of _actors_ may also be considered an _actor._ + +=== C2PA asset + +A file or stream of data containing _digital content,_ _asset metadata,_ and a _<>_. + +For the purposes of this definition, we will extend the typical definition of “file” to include cloud-native and dynamically-generated data. + +IMPORTANT: The definition of “C2PA asset” in this specification differs from the definition of “asset” given in the C2PA technical specification. A “C2PA asset” as defined in _this_ specification MUST contain a _<>._ + +=== C2PA Manifest + +The set of information about the _provenance_ of a _<>_ based on the combination of one or more assertions, a single C2PA claim, and a claim signature. + +See link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_manifests++[Section 11, “Manifests,”] of the C2PA technical specification. + +=== Endorsee + +An _<<_actor,actor>>_ who receives an _<<_endorsement,endorsement>>_ to perform a limited set of actions. + +=== Endorsement + +A signed credential intended to convey approval from an _<<_endorser,endorser>>_ to perform a limited set of actions on _<<_c2pa_asset,C2PA assets>>_ on their behalf. Endorsements are not constrained to specific _<<_c2pa_asset,C2PA assets>>._ + +=== Endorser + +An _<<_actor,actor>>_ who provides an _<<_endorsement,endorsement>>_ authorizing an _<<_endorsee,endorsee>>_ to perform a limited set of actions on any _<>_ signed by the _endorser._ + == Generating an endorsement -=== Endorsement storage +=== Endorser workflow + +Any _<<_actor,actor>>_ MAY choose to become an _<<_endorser,endorser>>_ by producing the following outputs: + +* a _<>_ and a corresponding _<>_ (which MAY be embedded in the _<<_c2pa_asset,C2PA asset>>_) +* an _<<_endorsement,endorsement>>,_ as defined in xref:_endorsement_cose_payload[xrefstyle=full] + +IMPORTANT: An _<<_endorsement,endorsement>>_ does not convey permission to perform these actions on any specific _<>._ Therefore, an _<<_endorsement,endorsement>>_ MUST NOT be included in any _<>_ or _<>_ created by the _<<_endorser,endorser>>._ It SHOULD be provided separately to the _<<_endorsee,endorsee>>._ + +The relationship among _<<_endorser,endorser>>_, _<<_endorsee,endorsee>>_, and the _<<_endorser,endorser’s>>_ _<>_ is represented by the following diagram, which is non-normative: + +[mermaid,width=100%] +.... +erDiagram + er["Endorser"] { + x509-cert signingCredential + } + em["Endorser’s C2PA manifest"] { + assertions anyAssertions + cose-sig claimSignature + } + oa["Endorser’s C2PA asset"] { + c2pa-manifest manifest + } + e["Endorsement"] { + der endorseeCredential + date notValidBefore + date notValidAfter + cose-sig endorsementSignature + } + ee["Endorsee"] { + x509-cert signingCredential + } -If the active manifest signer possesses an endorsement that it wishes to use to endorse an action performed by an actor, it can choose to embed the endorsement in the manifest it is generating. An endorsement is added as an *endorsement assertion* in the active manifest’s assertion store. + er ||--|| em: "creates and signs" + er ||--|| e: "creates and signs" + em ||--|| oa: "describes" + e ||--|| ee: "identifies" +.... -Before generating an *endorsement action,* the claim generator MUST ensure that: +=== Endorsee workflow -* exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[`c2pa.actions` assertion] exists in the manifest, +An _<<_endorsee,endorsee>>,_ once in possession of a _<>_ and an _<<_endorsement,endorsement>>_ signed by the same _<<_actor,actor>>_ that signed the _<<_c2pa_asset,C2PA asset’s>>_ _<>,_ MAY choose to perform one or more of the actions permitted in xref:_permitted_actions[xrefstyle=full], and describe those actions in a new _<>._ + +The _<<_endorseee,endorsee>>_ MAY include the _<<_endorsement,endorsement>>_ by adding an *endorsement assertion* in the new _<>’s_ assertion store. + +Before generating an *endorsement assertion,* the _<<_endorsee,endorsee>>_ MUST ensure that: + +* exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[`c2pa.actions` assertion] exists in the _<>,_ * only the actions listed under xref:_permitted_actions[xrefstyle=full] are present in the actions assertion, * exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_ingredient++[ingredient assertion] is present in the assertion store, and, * that ingredient is the one referenced by the actions assertion’s `parameters.ingredient` field. -The *endorsement assertion* MUST have a label of `cawg.endorsement` and there SHALL be at most one *endorsement assertion* per manifest. The assertion contents MUST be a `COSE_Sign1_Tagged` structure that is created as defined in xref:_cose_payload_details[xrefstyle=full]. - -IMPORTANT: C2PA 1.4 description of endorsement assertion was unclear as to whether there could be one or more than one endorsement assertion per claim. Resolve. +The *endorsement assertion* MUST have a label of `cawg.endorsement`. The assertion contents MUST be a `COSE_Sign1_Tagged` structure that is created as defined in xref:_endorsement_cose_payload[xrefstyle=full]. + +There MUST NOT be more than one *endorsement assertion* in any _<>._ + +The relationship between the _<<_endorser,endorser’s>>_ _<>_ and the _<<_endorsee,endorsee’s>>_ _<>_ is illustrated by the following diagram, which is non-normative: + +[mermaid,width=100%] +.... +erDiagram + oa["Endorser’s C2PA asset"] { + c2pa-manifest manifest + } + aa["Actions assertion"] { + list actionsPerformed + } + ia["Ingredient assertion"] { + ref endorsersAsset + } + e["Endorsement"] { + any endorseeCredential + date notValidBefore + date notValidAfter + cose-sig endorsementSignature + } + ea["Endorsement assertion"] { + ref endorsement + } + ee["Endorsee"] { + x509-cert signingCredential + } + eas["Endorsee’s C2PA asset"] { + c2pa-manifest manifest + } + eem["Endorsee’s C2PA manifest"] { + assertion ingredients + assertion actions + assertion endorsement + cose-sig claimSignature + } + + oa ||--|| ia: "referenced by" + ee ||--|| eem: "creates and signs" + ee ||--|| aa: "creates" + e ||--|| ea: "included in" + aa ||--|| eem: "included in" + ia ||--|| eem: "included in" + ea ||--|| eem: "included in" + eem ||--|| eas: "describes" + +.... === Permitted actions -The link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[`c2pa.actions` assertion] in a C2PA Manifest containing an *endorsement assertion* MAY contain any of the following action codes: +The link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[`c2pa.actions` assertion] in a _<>_ containing an *endorsement assertion* MAY contain any of the following action codes: * `c2pa.published` * `c2pa.transcoded` @@ -68,9 +191,9 @@ The link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specifi The actions assertion MUST NOT contain any other action codes. -=== COSE payload details +=== Endorsement COSE payload -Endorsements are COSE objects (see link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_digital_signatures++[Section 13.2, “Digital Signatures,” of the C2PA 2.0 Technical Specification]), where the COSE payload is an “endorsement target” data structure encoded as CBOR, as shown below. The `endorseeCredential` field is an object with a single field, labelled according to the type of credential used to sign the endorsement. The label of this field indicates to validators the type of the credential present, so that they know how to decode, parse and validate the credential correctly. The following table details the format of each of the currently specified credential types: +_<<_endorsement,Endorsements>>_ are COSE objects (see link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_digital_signatures++[Section 13.2, “Digital Signatures,” of the C2PA 2.0 Technical Specification]), where the COSE payload is an “endorsement target” data structure encoded as CBOR, as shown below. The `endorseeCredential` field is an object with a single field, labelled according to the type of credential used to sign the _<<_endorsement,endorsement>>._ The label of this field indicates to validators the type of the credential present, so that they know how to decode, parse and validate the credential correctly. The following table details the format of each of the currently specified credential types: ==== Endorsement credential types @@ -85,11 +208,11 @@ Endorsements are COSE objects (see link:++https://c2pa.org/specifications/specif |X.509 SubjectPublicKeyInfo |1 -|A https://datatracker.ietf.org/doc/html/rfc5280#section-4.1[DER-encoded ASN.1 SubjectPublicKeyInfo] structure (as a CBOR `bstr`), from the _endorsee’s_ X.509 certificate that will be used for signing the claims of assets that this endorsement is expected to be used with. -|The value of the credential shall be compared (bitwise identical) to the SubjectPublicKeyInfo structure of the certificate located in the `x5chain` or `33` (integer) COSE header of the active manifest Claim Signature. (See link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates++[Section 14.6, “X.509 Certificates,” of the C2PA 2.0 Technical Specification].) +|A https://datatracker.ietf.org/doc/html/rfc5280#section-4.1[DER-encoded ASN.1 SubjectPublicKeyInfo] structure (as a CBOR `bstr`), from the _endorsee’s_ X.509 certificate that will be used for signing the claims of _<<_c2pa_asset,C2PA assets>>_ that this _<<_endorsement,endorsement>>_ is expected to be used with. +|The value of the credential shall be compared (bitwise identical) to the SubjectPublicKeyInfo structure of the certificate located in the `x5chain` or `33` (integer) COSE header of the active _<>_ claim signature. (See link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates++[Section 14.6, “X.509 Certificates,” of the C2PA 2.0 Technical Specification].) |=== -Endorsers SHALL place the credential of the signer they are endorsing and its type in the `endorseeCredential`. To limit the length of time that an endorser is lending their endorsement to another signer, the `notValidBefore` and `notValidAfter` fields contain ISO 8601 date times. +_<<_endorser,Endorsers>>_ SHALL place the credential of the signer they are endorsing (the _<<_endorsee,endorsee>>_) and its type in the `endorseeCredential`. To limit the length of time that an _<<_endorser,endorser>>_ is lending their _<<_endorsement,endorsement>>_ to the _<<_endorsee,endorsee>>,_ the `notValidBefore` and `notValidAfter` fields MUST contain ISO 8601 date times. The schema for the endorsement target type is defined by the `endorsement-target-map` rule in the following https://datatracker.ietf.org/doc/html/rfc8610[CDDL Definition]: @@ -105,33 +228,31 @@ An example endorsement target is shown below: include::partial$schemas/cddl/examples/endorsement-target.cbordiag[] ---- -To sign an endorsement, follow the procedure specified in link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_digital_signatures++[Section 13.2, “Digital Signatures,” of the C2PA 2.0 Technical Specification], using the serialised CBOR `endorsement-target` object as the contents of the payload field. A signer SHALL NOT include a `x5chain` header and value, as endorsements are validated in the context of their use as an ingredient, and therefore use the signing credential of that ingredient manifest. (See xref:_validation[xrefstyle=full].) The serialized `COSE_Sign1_Tagged` structure resulting from the digital signature procedure is the endorsement that may be conveyed to the signer identified in the `endorsement-target`, but the process for conveying it is out of scope of this specification. +To sign an _<<_endorsement,endorsement>>,_ follow the procedure specified in link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_digital_signatures++[Section 13.2, “Digital Signatures,” of the C2PA 2.0 Technical Specification], using the serialised CBOR `endorsement-target` object as the contents of the payload field. An _<<_endorser,endorser>>_ SHALL NOT include a `x5chain` header and value, as _<<_endorsement,endorsements>>_ are validated in the context of their use as an ingredient, and therefore use the signing credential of that ingredient _<>._ (See xref:_validation[xrefstyle=full].) -== Validation - -Endorsement validation SHALL only be attempted if the active manifest first meets a number of conditions: +The serialized `COSE_Sign1_Tagged` structure resulting from the digital signature procedure is the _<<_endorsement,endorsement>>_ that MAY be conveyed to the _<<_endorsee,endorsee>>_ identified in the `endorsement-target`, but the process for conveying it is out of scope of this specification. -* There is exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[actions assertion] present in the assertion store -* There is exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_ingredient++[ingredient assertion] +== Validation -IMPORTANT: Are more than one endorsement assertion permitted? If not, the following paragraph becomes irrelevant. +Validation of an *endorsement assertion* SHALL only be attempted if the active _<>_ first meets a number of conditions: -Retrieve the *endorsement assertion* in the active manifest, as described in xref:_endorsement_storage[xrefstyle=full]. In order to provide resilience in the case of a claim generator unexpectedly adding multiple *endorsement assertions* to an assertion store, a validator may iterate through the validation process below with each endorsement, stopping the iteration immediately if an endorsement validates successfully. +* There is exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[actions assertion] present in the assertion store. +* There is exactly one link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_ingredient++[ingredient assertion]. +* There is exactly one *endorsement assertion.* -For each `action` object in the link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[actions assertion] : +For each `action` object in the link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_actions++[actions assertion]: -. Check that the `action` field is set to `c2pa.published`, `c2pa.transcoded` or `c2pa.repackaged`. If any other action is present, fail the endorsement process for this manifest and do not proceed with further validation. -. Check the `ingredient` field that is a member of the `parameters` object for the presence of a JUMBF URI. If the JUMBF URI is not present, or cannot be resolved to the related ingredient assertion, skip endorsement for this action. -. Follow the JUMBF URI link in the `ingredient` field to the ingredient assertion. Check that the URI link resolves to an assertion in the active manifest. If it does not, skip endorsement for this action. Check that the `relationship` field is `parentOf`. If it is not, skip endorsement for this action. -. Check the `c2pa_manifest` field in the ingredient assertion for the presence of a hashed URI. If the hashed URI is not present, or cannot be resolved to a manifest, skip endorsement for this action. -. Follow the JUMBF URI link in the `c2pa_manifest` field to the ingredient’s manifest. Ensure that this _ingredient_ manifest has been validated according to link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.8, “Recursively validating integrity of ingredients,” of the C2PA 2.0 Technical Specification], but do not skip the establishing of signer credential trust. If it does not validate, skip endorsement for this action. -. Validate the endorsement as described in link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.4, “Validate the signature,” of the C2PA Technical Specification], using the credential of the ingredient manifest signer. If a signing credential is present in the endorsement’s signature’s headers, it shall not be used for validation. If validation fails, skip this action. +. Check that the `action` field is set to `c2pa.published`, `c2pa.transcoded`, or `c2pa.repackaged`. If any other action is present, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +. Check the `ingredient` field that is a member of the `parameters` object for the presence of a JUMBF URI. If the JUMBF URI is not present, or cannot be resolved to the related ingredient assertion, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +. Follow the JUMBF URI link in the `ingredient` field to the ingredient assertion. Check that the URI link resolves to the single ingredient assertion in the active _<>._ If it does not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. Check that the `relationship` field is `parentOf`. If it is not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +. Check the `c2pa_manifest` field in the ingredient assertion for the presence of a hashed URI. If the hashed URI is not present, or cannot be resolved to a _<>,_ fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +. Follow the JUMBF URI link in the `c2pa_manifest` field to the ingredient’s _<>._ Ensure that this _ingredient_ _<>_ has been validated according to link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.8, “Recursively validating integrity of ingredients,” of the C2PA 2.0 Technical Specification], but do not skip the establishing of signer credential trust. If it does not validate, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +. Validate the endorsement as described in link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.4, “Validate the signature,” of the C2PA Technical Specification], using the credential of the ingredient _<>_ signer. If a signing credential is present in the endorsement’s signature’s headers, it shall not be used for validation. If validation fails, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. . Validate the `endorsement-target` payload itself, following the steps below: -.. Compare the `endorseeCredential` to the credential of the active manifest signer, according to the table found in xref:_endorsement_credential_types[xrefstyle=full]. If the comparison fails, skip this endorsement. -.. If the active manifest is timestamped, then the _time-stamp_ must fall within the endorsement’s validity time range. If it does not, skip this endorsement. -.. If the active manifest is not timestamped, then the _time of validation_ must fall within the endorsement’s validity time range. If it does not, skip this endorsement. -.. If validation fails, skip this endorsement. If validation succeeds, mark that action as __endorsed__. +.. Compare the `endorseeCredential` to the credential of the active _<>_ signer, according to the table found in xref:_endorsement_credential_types[xrefstyle=full]. If the comparison fails, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +.. If the active _<>_ is timestamped, then the _time-stamp_ must fall within the endorsement’s validity time range. If it does not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +.. If the active _<>_ is not timestamped, then the _time of validation_ must fall within the endorsement’s validity time range. If it does not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. -When endorsement validation has completed, for each actions assertion in the active manifest where all actions are marked as __endorsed__, the actions assertion itself shall be marked as __endorsed__ in the validation results returned by the validator. +If all steps above have been completed without failure, the *endorsement assertion* SHOULD be considered valid. include::partial$version-history.adoc[] diff --git a/docs/modules/ROOT/partials/schemas/cddl/endorsement-target.cddl b/docs/modules/ROOT/partials/schemas/cddl/endorsement-target.cddl index 38c3fc7..a198be2 100644 --- a/docs/modules/ROOT/partials/schemas/cddl/endorsement-target.cddl +++ b/docs/modules/ROOT/partials/schemas/cddl/endorsement-target.cddl @@ -1,7 +1,7 @@ endorsement-target-map = { - "endorseeCredential" : public-credential, ; A DER-encoded SubjectPublicKeyInfo containing the public key - "notValidBefore": tdate, ; The date-time that this endorsement valid from, before this time it is not valid - "notValidAfter": tdate ; The date-time that this endorsement expires and is no longer valid + "endorseeCredential" : public-credential, ; a DER-encoded SubjectPublicKeyInfo containing the public key + "notValidBefore": tdate, ; the date-time that this endorsement valid from; before this time it is not valid + "notValidAfter": tdate ; the date-time that this endorsement expires and is no longer valid ? "metadata": $assertion-metadata-map, ; additional information about the assertion } @@ -9,4 +9,4 @@ public-credential = { $credential-type: any ; an extensible field allowing the specification of the credential payload } -$credential-type /= 1 ; credentials with this type are a DER-encoded ASN.1 SubjectPublicKeyInfo structure, as a bstr (specification text for usage) \ No newline at end of file +$credential-type /= 1 ; credentials with this type are a DER-encoded ASN.1 SubjectPublicKeyInfo structure, as a bstr (specification text for usage) diff --git a/docs/modules/ROOT/partials/version-history.adoc b/docs/modules/ROOT/partials/version-history.adoc index f7f735c..0ff616c 100644 --- a/docs/modules/ROOT/partials/version-history.adoc +++ b/docs/modules/ROOT/partials/version-history.adoc @@ -10,3 +10,7 @@ _This section is non-normative._ *04 March 2024* * Promoted from pre-draft to draft status. + +*Pending merge* + +* Substantial rewrite, introducing the terms _<<_endorser,endorser>>_ and _<<_endorsee,endorsee>>,_ and clarifying the workflow for each role. From 82322706dcea4e9a7b489ec2a346d54d5bca7b18 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Mon, 29 Apr 2024 12:47:49 -0700 Subject: [PATCH 2/6] Incorporate suggestion from @chalford: https://github.com/creator-assertions/endorsement-assertion/pull/6#discussion_r1583258628 --- docs/modules/ROOT/pages/index.adoc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 00af98f..ee136b4 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -206,10 +206,15 @@ _<<_endorsement,Endorsements>>_ are COSE objects (see link:++https://c2pa.org/sp | | -|X.509 SubjectPublicKeyInfo +|Reserved _(deprecated)_ |1 -|A https://datatracker.ietf.org/doc/html/rfc5280#section-4.1[DER-encoded ASN.1 SubjectPublicKeyInfo] structure (as a CBOR `bstr`), from the _endorsee’s_ X.509 certificate that will be used for signing the claims of _<<_c2pa_asset,C2PA assets>>_ that this _<<_endorsement,endorsement>>_ is expected to be used with. -|The value of the credential shall be compared (bitwise identical) to the SubjectPublicKeyInfo structure of the certificate located in the `x5chain` or `33` (integer) COSE header of the active _<>_ claim signature. (See link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates++[Section 14.6, “X.509 Certificates,” of the C2PA 2.0 Technical Specification].) +|This CBOR label was used in link:https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_endorsement_credential_types[a prior version of the endorsement assertion specification] and should no longer be used. +|n/a + +|X.509 Certificate Hash +|2 +|A SHA-256 hash of the _endorsee’s_ X.509 certificate chain that will be used for signing the claims of _<<_c2pa_asset,C2PA assets>>_ that this _<<_endorsement,endorsement>>_ is expected to be used with. +|The value of the credential shall be compared (bitwise identical) to a SHA-256 hash of the entire certificate chain located in the `x5chain` or `33` (integer) COSE header of the active _<>_ claim signature. (See link:++https://c2pfa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#x509_certificates++[Section 14.6, “X.509 Certificates,” of the C2PA 2.0 Technical Specification].) |=== _<<_endorser,Endorsers>>_ SHALL place the credential of the signer they are endorsing (the _<<_endorsee,endorsee>>_) and its type in the `endorseeCredential`. To limit the length of time that an _<<_endorser,endorser>>_ is lending their _<<_endorsement,endorsement>>_ to the _<<_endorsee,endorsee>>,_ the `notValidBefore` and `notValidAfter` fields MUST contain ISO 8601 date times. From cdfcc6c70ba8a09e9101a2a8913bfac3b84642b1 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Mon, 29 Apr 2024 12:54:30 -0700 Subject: [PATCH 3/6] Update example for new label and data type --- .../partials/schemas/cddl/examples/endorsement-target.cbordiag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/partials/schemas/cddl/examples/endorsement-target.cbordiag b/docs/modules/ROOT/partials/schemas/cddl/examples/endorsement-target.cbordiag index e9ac617..3eab61d 100644 --- a/docs/modules/ROOT/partials/schemas/cddl/examples/endorsement-target.cbordiag +++ b/docs/modules/ROOT/partials/schemas/cddl/examples/endorsement-target.cbordiag @@ -1,6 +1,6 @@ { "endorseeCredential": { - 1: 'A DER-encoded SubjectPublicKeyInfo containing the public key of the signer to be endorsed' + 2: 'A SHA-256 hash of endorsee’s X.509 certificate chain' }, "notValidBefore": 0("2021-03-21T20:04:00Z"), "notValidAfter": 0("2022-03-21T20:04:00Z") From 8bfddb461656be3696d1c3b862d129d178c45d81 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Sun, 5 May 2024 07:49:24 -0700 Subject: [PATCH 4/6] Update validation section --- docs/modules/ROOT/pages/index.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index ee136b4..0274962 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -254,7 +254,7 @@ For each `action` object in the link:++https://c2pa.org/specifications/specifica . Follow the JUMBF URI link in the `c2pa_manifest` field to the ingredient’s _<>._ Ensure that this _ingredient_ _<>_ has been validated according to link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.8, “Recursively validating integrity of ingredients,” of the C2PA 2.0 Technical Specification], but do not skip the establishing of signer credential trust. If it does not validate, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. . Validate the endorsement as described in link:++https://c2pa.org/specifications/specifications/2.0/specs/C2PA_Specification.html#_recursively_validating_integrity_of_ingredients++[Section 15.4, “Validate the signature,” of the C2PA Technical Specification], using the credential of the ingredient _<>_ signer. If a signing credential is present in the endorsement’s signature’s headers, it shall not be used for validation. If validation fails, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. . Validate the `endorsement-target` payload itself, following the steps below: -.. Compare the `endorseeCredential` to the credential of the active _<>_ signer, according to the table found in xref:_endorsement_credential_types[xrefstyle=full]. If the comparison fails, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. +.. Compare the `endorseeCredential` to the SHA-256 hash of the credential of the active _<>_ signer, according to the table found in xref:_endorsement_credential_types[xrefstyle=full]. If the comparison fails, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. .. If the active _<>_ is timestamped, then the _time-stamp_ must fall within the endorsement’s validity time range. If it does not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. .. If the active _<>_ is not timestamped, then the _time of validation_ must fall within the endorsement’s validity time range. If it does not, fail the *endorsement assertion* validation process for this _<>_ and do not proceed with further validation. From 5a856f3fc3bbd3f81f5c3458eb04f6f61aa0ea3b Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Sun, 5 May 2024 07:52:03 -0700 Subject: [PATCH 5/6] Merge prep --- docs/modules/ROOT/pages/index.adoc | 2 +- docs/modules/ROOT/partials/version-history.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 0274962..ec0f0c5 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -6,7 +6,7 @@ An _<<_endorsement,endorsement>>_ is a way of indicating approval for specific actions made on content after it has had a _<>_ attached. (See xref:_generating_an_endorsement[xrefstyle=full].) The *endorsement assertion* is where an _<<_endorsement,endorsement>>_ from the signer of an ingredient _<>_ (known here as an _<<_endorser,endorser>>_) is stored. These _<<_endorsement,endorsements>>_ are typically provided (out-of-band of this specification) by ingredient _<>_ signers to actors those signers trust to perform the actions listed in the assertion (known here as _<<_endorsee,endorsees>>_). They are used by a validator when assessing whether the actions of the active _<>_ are “endorsed” or not. (See xref:_validation[xrefstyle=full].) -Version 1.0 *Draft 24 April 2024* · xref:_version_history[] +Version 1.0 *Draft 05 May 2024* · xref:_version_history[] [#maintainers] *Maintainers:* diff --git a/docs/modules/ROOT/partials/version-history.adoc b/docs/modules/ROOT/partials/version-history.adoc index 0ff616c..c4f6888 100644 --- a/docs/modules/ROOT/partials/version-history.adoc +++ b/docs/modules/ROOT/partials/version-history.adoc @@ -11,6 +11,6 @@ _This section is non-normative._ * Promoted from pre-draft to draft status. -*Pending merge* +*05 May 2024* * Substantial rewrite, introducing the terms _<<_endorser,endorser>>_ and _<<_endorsee,endorsee>>,_ and clarifying the workflow for each role. From 882b1ede472aa61cc18159bc04c21df7821672a2 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Sun, 5 May 2024 07:52:39 -0700 Subject: [PATCH 6/6] Merge prep --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index 6f90407..46db0ce 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -1,4 +1,4 @@ name: endorsement -version: 1.0-draft2 +version: 1.0-draft title: Endorsement Assertion start_page: index.adoc