83 lines
5.9 KiB
Markdown
83 lines
5.9 KiB
Markdown
# live-conformance/c2pa-live — live provenance
|
|
|
|
The corpus of [`extensions/live-provenance.md`](../../extensions/live-provenance.md) §13: C2PA
|
|
2.4 §19 live video streams, each an initialization segment and its segments in the order a
|
|
verifier receives them, with, for a room track, the JWP group and object receipts of its
|
|
groups; the trust anchor every vector is verified under; and what a verifier states of each.
|
|
|
|
**Files.** `vectors.json` lists the vectors, each its `name`, `kind` (`track` or `take`),
|
|
`init`, `segments` (each a `file` and, for a track, the `group` it came in), `receipts` (a JSON
|
|
file of `groups` and `objects` in jwp-receipts §2.4's forms, or `null` for a take) and
|
|
`expect`. A file whose bytes another vector already wrote is named by that vector's path, so a
|
|
negative that changes one segment holds one file of its own. `anchor.der` is the trust anchor
|
|
for `c2pa-kp-claimSigning`, and `time` the instant *T* (§11.1).
|
|
|
|
**Equivalence.** A conforming verifier given a vector's files, the anchor and *T* reaches the
|
|
outcome `expect` states (§11):
|
|
|
|
- `refuse`: the `reason` of §12, `at` (`init`, `segment k` counting received segments from 0,
|
|
or `group g`), and the two C2PA codes §12 gives the reason, `c2pa` (§15's) and `livevideo`
|
|
(§19.7's), each `null` where §12 gives none;
|
|
- `accept`: the `streamId`, the `sourceType`, the `registration` (the `repository`, the
|
|
`treeSize` and the `leafIndex` of the receipt of inclusion) or `null`, and for each segment
|
|
(§11.6) its
|
|
`sequenceNumber`, its `group` (a track) or `chunk` (a take), its `methods` (`manifest`,
|
|
`vsi` or `manifest+vsi`), the active `manifestId`, its number of `chunks`, and its group's
|
|
`root` or its take chunk's `chunkHash`, in lowercase hexadecimal.
|
|
|
|
**The vectors.**
|
|
|
|
- Good: `camera-manifests` (the per-segment method), `camera-vsi` (the Verifiable Segment
|
|
Info method from group 10, the session key rotated at the third segment by a manifest in
|
|
it, the receipts' chain restarting under the new key), `avatar-manifests` (a track labelled
|
|
machine-made, with its AI disclosure), `composite-manifests` (a compositor's output of the
|
|
camera and the avatar: `compositeSynthetic` and the avatar's disclosure), `take-both` (a
|
|
take under both methods at once, the device's key as its session key), `camera-failover`
|
|
(the camera track, a second packager under its own claim signer taking over at the third
|
|
segment, the continuity chain holding across it because the identifiers are derived) and
|
|
`camera-registered` (the camera track's initialization segment with its update manifest
|
|
and repository receipt; `repositories` in `vectors.json` names the repository and its key).
|
|
- One negative for each reason of §12, and for some reasons more than one; each name says its
|
|
defect.
|
|
|
|
**Provenance.** `wai_live_provenance_vectors gen` writes every file but this one from fixed
|
|
seeds: every key is SHA-256 of a label and no key is one anyone holds; the certificates are
|
|
issued under the corpus's own test anchor; the media are the AV1 floor of
|
|
`pack-conformance/packs/video-base-01`, its samples cut into chunks of at most 15 frames, each
|
|
group one of the floor's pieces, renumbered and retimed across the stream.
|
|
|
|
**Checked by.** `wai_live_provenance_vectors verify` and `tests/live_provenance.rs` in
|
|
`wai-rs` (every file regenerates byte for byte and no other is here; every vector gets its
|
|
outcome; every reason refuses one; §12 lists the reference's codes), and
|
|
`../c2pa_live_verify.py`, the second implementation, written from the extension's text, which
|
|
also requires every mutated copy of a good vector to be refused.
|
|
|
|
**An independent C2PA validator.** The corpus's files were also read with the C2PA
|
|
command-line tool, version 0.27.22, given `anchor.der` as its trust anchor, on 2026-10-21:
|
|
|
|
- every good vector's initialization segment validates: state `Trusted`, with
|
|
`assertion.bmffHash.match`, `assertion.hashedURI.match`, `claimSignature.validated`,
|
|
`claimSignature.insideValidity` and `signingCredential.trusted`. The manifest store, the
|
|
claim, its signature, the certificate chain and the BMFF hash over the `moov` are therefore
|
|
read the same way by an implementation that shares nothing with this one;
|
|
- `camera-registered/init.mp4` validates too, state `Trusted`, its active manifest the update
|
|
manifest: the tool reads the ingredient (`ingredient.manifest.validated`) and its validation
|
|
results. Before the ingredient carried them it reported `assertion.ingredient.malformed`,
|
|
which C2PA 2.4 §18.16.12.4.3 requires; `update-ingredient/init.mp4` is reported
|
|
`ingredient.manifest.mismatch`, where this corpus states `update_manifest_invalid`;
|
|
`repository-receipt-forged/init.mp4` is reported `Trusted`: the receipt's proof is the
|
|
repository's form (§18.27), which the tool does not check;
|
|
- `cert-untrusted/init.mp4` is reported `signingCredential.untrusted`, as here;
|
|
- `cert-expired/init.mp4` is reported `signingCredential.expired`, a code C2PA 2.4 does not
|
|
list; §15.8 names this failure `claimSignature.outsideValidity`, which this corpus states;
|
|
- `cert-wrong-eku/init.mp4`, whose end entity is valid for `id-kp-timeStamping` alone, is
|
|
reported `Trusted`: the tool's default list of accepted extended key usages includes
|
|
time-stamping and OCSP signing. C2PA 2.4 §14.5.1.1 makes a certificate valid for either of
|
|
those purposes valid for no other, and §14.5.1.2 requires a claim signer's to hold an EKU of
|
|
the validator's configuration, so this corpus refuses it `credential_invalid`;
|
|
- the tool reads no media segment: a file that does not begin with `ftyp` is not one it
|
|
opens, so it does not verify §19 per-segment manifests, segment-info maps or session keys.
|
|
The segments are checked by the two implementations above alone.
|
|
|
|
The tool reports a claim signature as failed when the end-entity certificate's subject holds
|
|
no organization name, which C2PA does not require; the corpus's names all hold one (§4.4).
|