@svta/cml-c2pa 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  C2PA (Coalition for Content Provenance and Authenticity) live video validation for BMFF/MP4 containers.
4
4
 
5
- Supports both segment validation methods defined in the C2PA specification:
5
+ Supports the segment validation methods defined in the C2PA specification:
6
6
 
7
- - **§19.3 — Per-segment C2PA Manifest Box**: each segment embeds a full C2PA manifest with COSE signature
8
- - **§19.4 — Verifiable Segment Info (VSI/EMSG)**: the init segment carries the manifest and session keys; each media segment carries a lightweight signed EMSG box
7
+ - **§19.3 Per-segment C2PA Manifest Box**: each segment embeds a full C2PA manifest with COSE signature
8
+ - **§19.4 Verifiable Segment Info (VSI/EMSG)**: the init segment carries the manifest and session keys; each media segment carries a lightweight signed EMSG box
9
+ - **§15.12.2 / §18.6 VOD Merkle**: for on-demand fragmented MP4 assets, the init manifest stores one Merkle tree row per track, and each media segment carries its own leaf hash and proof
9
10
 
10
11
 
11
12
  ## Installation
@@ -55,11 +56,24 @@ const segmentBytes = new Uint8Array(await fetch(segmentUrl).then(r => r.arrayBuf
55
56
  const validated = await validateC2paSegment(segmentBytes, init.sessionKeys)
56
57
  ```
57
58
 
59
+ ### VOD Merkle method (init segment + media segments)
60
+
61
+ ```typescript
62
+ import { validateC2paInitSegment, validateC2paMerkleSegment } from '@svta/cml-c2pa'
63
+
64
+ const initBytes = new Uint8Array(await fetch(initUrl).then(r => r.arrayBuffer()))
65
+ const init = await validateC2paInitSegment(initBytes)
66
+
67
+ const segmentBytes = new Uint8Array(await fetch(segmentUrl).then(r => r.arrayBuffer()))
68
+ const { result } = await validateC2paMerkleSegment(segmentBytes, init.merkleMaps)
69
+ ```
70
+
58
71
  ## Docs
59
72
 
60
- - [VSI/EMSG Validation](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/vsi-validation.md) — Validate using Verifiable Segment Info (§19.4)
61
- - [Manifest Box Validation](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/manifest-box-validation.md) — Validate using per-segment manifests (§19.3)
62
- - [Results and Error Codes](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/results-and-error-codes.md) — Interpret results, error codes, and manifest data
73
+ - [VSI/EMSG Validation](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/vsi-validation.md): Validate using Verifiable Segment Info (§19.4)
74
+ - [Manifest Box Validation](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/manifest-box-validation.md): Validate using per-segment manifests (§19.3)
75
+ - [VOD Merkle Validation](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/merkle-validation.md): Validate on-demand fragmented MP4 assets using Merkle tree proofs (§15.12.2 / §18.6)
76
+ - [Results and Error Codes](https://github.com/streaming-video-technology-alliance/common-media-library/blob/main/libs/c2pa/docs/results-and-error-codes.md): Interpret results, error codes, and manifest data
63
77
 
64
78
  ## References
65
79
 
package/dist/index.d.ts CHANGED
@@ -57,6 +57,10 @@ declare const C2paStatusCode: {
57
57
  readonly ASSERTION_ACTION_INGREDIENT_MISMATCH: "assertion.action.ingredientMismatch";
58
58
  /** Claim signature verification failed (§15.7) */
59
59
  readonly CLAIM_SIGNATURE_MISMATCH: "claim.signature.mismatch";
60
+ /** BMFF hash assertion or Merkle structure is malformed (§15.2.2.3) */
61
+ readonly ASSERTION_BMFFHASH_MALFORMED: "assertion.bmffHash.malformed";
62
+ /** BMFF content hash does not match the committed value (§15.2.2.3) */
63
+ readonly ASSERTION_BMFFHASH_MISMATCH: "assertion.bmffHash.mismatch";
60
64
  };
61
65
  /**
62
66
  * Union type of all {@link (C2paStatusCode:variable)} values.
@@ -97,10 +101,16 @@ declare const LiveVideoStatusCode: {
97
101
  readonly MANIFEST_INVALID: "livevideo.manifest.invalid";
98
102
  /** Segment structure invalid: missing Manifest Box/emsg, signature/hash/key failure (§19.7) */
99
103
  readonly SEGMENT_INVALID: "livevideo.segment.invalid";
100
- /** Live video assertion field invalid: sequenceNumber or streamId mismatch (§19.7.2) */
104
+ /**
105
+ * Live video assertion field invalid: sequenceNumber or streamId mismatch
106
+ * (§19.7.2). Also reused for VOD Merkle per-track location discontinuity
107
+ * (§15.12.2), which has no dedicated code.
108
+ */
101
109
  readonly ASSERTION_INVALID: "livevideo.assertion.invalid";
102
110
  /** continuityMethod absent, unsupported, or companion fields incorrect (§19.7.2) */
103
111
  readonly CONTINUITY_METHOD_INVALID: "livevideo.continuityMethod.invalid";
112
+ /** Custom continuityMethod with no registered validator (§19.7.2) */
113
+ readonly CONTINUITY_METHOD_UNSUPPORTED: "livevideo.continuityMethod.unsupported";
104
114
  /** Session key invalid: signerBinding failed or required fields absent (§19.7.3) */
105
115
  readonly SESSIONKEY_INVALID: "livevideo.sessionkey.invalid";
106
116
  };
@@ -111,6 +121,73 @@ declare const LiveVideoStatusCode: {
111
121
  */
112
122
  type LiveVideoStatusCode = ValueOf<typeof LiveVideoStatusCode>;
113
123
  //#endregion
124
+ //#region src/bmff/BmffHashExclusion.d.ts
125
+ /**
126
+ * A byte-level constraint used to match specific BMFF box content
127
+ * within a C2PA BMFF hash exclusion.
128
+ *
129
+ * @public
130
+ */
131
+ type BmffHashConstraint = {
132
+ readonly offset: number;
133
+ readonly value: Uint8Array | readonly number[];
134
+ };
135
+ /**
136
+ * Identifies a BMFF box to exclude from the C2PA content hash (`c2pa.hash.bmff.v3`).
137
+ *
138
+ * The `xpath` uses C2PA path notation (e.g. `/emsg`, `/moof/traf`).
139
+ * Optional `data` constraints narrow the match to specific box content
140
+ * by byte offset within the box.
141
+ *
142
+ * @public
143
+ */
144
+ type BmffHashExclusion = {
145
+ readonly xpath: string;
146
+ readonly data?: readonly BmffHashConstraint[];
147
+ };
148
+ //#endregion
149
+ //#region src/merkle/MerkleSegmentValidation.d.ts
150
+ /**
151
+ * One merkle map from the `c2pa.hash.bmff.v3` assertion (§18.6).
152
+ *
153
+ * @public
154
+ */
155
+ type MerkleMap = {
156
+ readonly uniqueId: number;
157
+ readonly localId: number;
158
+ readonly count: number;
159
+ readonly hashes: readonly Uint8Array[];
160
+ readonly initHash: Uint8Array | null;
161
+ readonly alg: string | null;
162
+ readonly exclusions: readonly BmffHashExclusion[];
163
+ readonly offsetPrefixSize: number;
164
+ };
165
+ /**
166
+ * Continuity state carried between calls to `validateC2paMerkleSegment`.
167
+ * Reset (pass `undefined`) after a seek.
168
+ *
169
+ * `lastLocations` is keyed by `${uniqueId}:${localId}`, matching the
170
+ * `MerkleMap` fields of the track it tracks. The first location seen for a
171
+ * key is always accepted (no prior state to compare against), so a caller
172
+ * that needs strict start-at-zero enforcement must seed this map itself.
173
+ *
174
+ * @public
175
+ */
176
+ type MerkleSegmentState = {
177
+ readonly lastLocations: ReadonlyMap<string, number>;
178
+ };
179
+ /**
180
+ * Result of `validateC2paMerkleSegment` for one media segment.
181
+ *
182
+ * @public
183
+ */
184
+ type MerkleSegmentValidation = {
185
+ readonly location: number | null;
186
+ readonly bmffHashHex: string | null;
187
+ readonly isValid: boolean;
188
+ readonly errorCodes: readonly (LiveVideoStatusCode | C2paStatusCode)[];
189
+ };
190
+ //#endregion
114
191
  //#region src/init/InitSegmentValidation.d.ts
115
192
  /**
116
193
  * A session key extracted and verified from a C2PA `c2pa.session-keys` assertion.
@@ -139,6 +216,7 @@ type InitSegmentValidation = {
139
216
  readonly certificate: Uint8Array | null;
140
217
  readonly manifestId: string | null;
141
218
  readonly sessionKeys: readonly ValidatedSessionKey[];
219
+ readonly merkleMaps: readonly MerkleMap[];
142
220
  readonly isValid: boolean;
143
221
  readonly errorCodes: readonly (LiveVideoStatusCode | C2paStatusCode)[];
144
222
  };
@@ -294,6 +372,23 @@ type ManifestBoxValidationResult = {
294
372
  readonly errorCodes: readonly (LiveVideoStatusCode | C2paStatusCode)[];
295
373
  };
296
374
  /**
375
+ * Validates continuity for an implementer-defined continuity method (§19.3.2).
376
+ *
377
+ * @public
378
+ */
379
+ type ManifestBoxContinuityValidator = (liveVideoAssertion: Readonly<Record<string, unknown>>, manifest: C2paManifest) => boolean | Promise<boolean>;
380
+ /**
381
+ * Options for `validateC2paManifestBoxSegment`.
382
+ *
383
+ * @public
384
+ */
385
+ type ManifestBoxValidationOptions = {
386
+ readonly continuityValidator?: {
387
+ readonly method: string;
388
+ readonly validate: ManifestBoxContinuityValidator;
389
+ };
390
+ };
391
+ /**
297
392
  * State to carry between consecutive manifest-box segment validations.
298
393
  *
299
394
  * Pass the `nextState` returned by {@link validateC2paManifestBoxSegment}
@@ -314,6 +409,8 @@ type ManifestBoxValidationState = {
314
409
  * Recomputes the `c2pa.hash.bmff.v3` content hash from the raw segment bytes and compares
315
410
  * it against the expected hash in the manifest assertion. Checks live-video assertions
316
411
  * (sequenceNumber, streamId, continuityMethod) and manifest-ID chain continuity.
412
+ * A validator for an implementer-defined continuity method can be registered
413
+ * via {@link ManifestBoxValidationOptions}.
317
414
  *
318
415
  * This function is **pure** — it does not access any external state. The
319
416
  * caller is responsible for persisting `nextManifestId` and `nextState`
@@ -322,6 +419,7 @@ type ManifestBoxValidationState = {
322
419
  * @param bytes - Raw segment bytes
323
420
  * @param lastManifestId - Manifest ID from the previous segment, or null for the first segment
324
421
  * @param state - Optional state from the previous segment for streamId/sequenceNumber checks
422
+ * @param options - Optional custom continuity method validator
325
423
  * @returns Validation result, the manifest ID, and state to persist for the next call
326
424
  *
327
425
  * @example
@@ -329,11 +427,31 @@ type ManifestBoxValidationState = {
329
427
  *
330
428
  * @public
331
429
  */
332
- declare function validateC2paManifestBoxSegment(bytes: Uint8Array, lastManifestId: string | null, state?: ManifestBoxValidationState): Promise<{
430
+ declare function validateC2paManifestBoxSegment(bytes: Uint8Array, lastManifestId: string | null, state?: ManifestBoxValidationState, options?: ManifestBoxValidationOptions): Promise<{
333
431
  readonly result: ManifestBoxValidationResult;
334
432
  readonly nextManifestId: string | null;
335
433
  readonly nextState: ManifestBoxValidationState;
336
434
  }>;
337
435
  //#endregion
338
- export { C2paAssertion, C2paManifest, C2paSignatureInfo, C2paStatusCode, CoseKeyJwk, InitSegmentValidation, LiveVideoStatusCode, ManifestBoxValidationResult, ManifestBoxValidationState, SegmentValidationResult, type SequenceState, SequenceValidationReason, type SequenceValidationResult, ValidatedSessionKey, validateC2paInitSegment, validateC2paManifestBoxSegment, validateC2paSegment };
436
+ //#region src/merkle/validateC2paMerkleSegment.d.ts
437
+ /**
438
+ * Validates a fragmented MP4 VOD media segment against the init manifest's
439
+ * merkle maps (§15.12.2.2). Pure: the caller persists `nextState` and resets
440
+ * `state` after a seek.
441
+ *
442
+ * `merkleMaps` must be non-empty; the caller is responsible for only calling
443
+ * this in VOD Merkle mode (i.e. after `InitSegmentValidation.merkleMaps` came
444
+ * back non-empty).
445
+ *
446
+ * @example
447
+ * {@includeCode ../../test/merkle/validateC2paMerkleSegment.test.ts#example}
448
+ *
449
+ * @public
450
+ */
451
+ declare function validateC2paMerkleSegment(segmentBytes: Uint8Array, merkleMaps: readonly MerkleMap[], state?: MerkleSegmentState): Promise<{
452
+ readonly result: MerkleSegmentValidation;
453
+ readonly nextState: MerkleSegmentState;
454
+ }>;
455
+ //#endregion
456
+ export { BmffHashConstraint, BmffHashExclusion, C2paAssertion, C2paManifest, C2paSignatureInfo, C2paStatusCode, CoseKeyJwk, InitSegmentValidation, LiveVideoStatusCode, ManifestBoxContinuityValidator, ManifestBoxValidationOptions, ManifestBoxValidationResult, ManifestBoxValidationState, MerkleMap, MerkleSegmentState, MerkleSegmentValidation, SegmentValidationResult, type SequenceState, SequenceValidationReason, type SequenceValidationResult, ValidatedSessionKey, validateC2paInitSegment, validateC2paManifestBoxSegment, validateC2paMerkleSegment, validateC2paSegment };
339
457
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/C2paAssertion.ts","../src/C2paSignatureInfo.ts","../src/C2paManifest.ts","../src/C2paStatusCode.ts","../src/cose/CoseKeyJwk.ts","../src/LiveVideoStatusCode.ts","../src/init/InitSegmentValidation.ts","../src/init/validateC2paInitSegment.ts","../src/vsi/SequenceState.ts","../src/segment/SegmentValidation.ts","../src/segment/validateC2paSegment.ts","../src/manifestbox/ManifestBoxValidation.ts","../src/manifestbox/validateC2paManifestBoxSegment.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/C2paAssertion.ts","../src/C2paSignatureInfo.ts","../src/C2paManifest.ts","../src/C2paStatusCode.ts","../src/cose/CoseKeyJwk.ts","../src/LiveVideoStatusCode.ts","../src/bmff/BmffHashExclusion.ts","../src/merkle/MerkleSegmentValidation.ts","../src/init/InitSegmentValidation.ts","../src/init/validateC2paInitSegment.ts","../src/vsi/SequenceState.ts","../src/segment/SegmentValidation.ts","../src/segment/validateC2paSegment.ts","../src/manifestbox/ManifestBoxValidation.ts","../src/manifestbox/validateC2paManifestBoxSegment.ts","../src/merkle/validateC2paMerkleSegment.ts"],"sourcesContent":[],"mappings":"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"}