@trylimbo/sdk-verifier-wasm 0.2.24 → 0.2.25-canary.37
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/gen/wasm/trylimbo_sdk_verifier.d.ts +284 -317
- package/gen/wasm/trylimbo_sdk_verifier.js +223 -288
- package/gen/wasm/trylimbo_sdk_verifier_bg.wasm +0 -0
- package/gen/wasm/trylimbo_sdk_verifier_bg.wasm.d.ts +13 -19
- package/gen/wasm/worker-thread.js +194 -301
- package/gen/wasm/worker.d.ts +309 -306
- package/package.json +1 -1
package/gen/wasm/worker.d.ts
CHANGED
|
@@ -163,141 +163,61 @@ interface RangeSource {
|
|
|
163
163
|
readAt: (offset: number, length: number) => Uint8Array;
|
|
164
164
|
}
|
|
165
165
|
/**
|
|
166
|
-
* A
|
|
167
|
-
* list, e.g. `io.iscc.v0`) plus its algorithm-specific value (the `ISCC:…` code,
|
|
168
|
-
* a watermark token, …). The signer embeds it as a `c2pa.soft-binding` assertion
|
|
169
|
-
* and indexes it, so a transcoded copy whose exact content hash no longer
|
|
170
|
-
* matches still recovers the manifest from the repository.
|
|
166
|
+
* A `soft-binding-block-map`. No scope is the whole content.
|
|
171
167
|
*/
|
|
172
|
-
interface
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
*/
|
|
176
|
-
alg: string;
|
|
177
|
-
/**
|
|
178
|
-
* Algorithm-specific binding value: the canonical string the algorithm
|
|
179
|
-
* produces (an `ISCC:…` code, a watermark token). Its UTF-8 bytes are what
|
|
180
|
-
* the repository lookup base64-encodes.
|
|
181
|
-
*/
|
|
182
|
-
value: string;
|
|
168
|
+
interface Block {
|
|
169
|
+
value: Uint8Array;
|
|
170
|
+
scope?: Scope;
|
|
183
171
|
}
|
|
184
172
|
/**
|
|
185
|
-
* A
|
|
186
|
-
* SDK\'s own two. A browser has no host binder: a detector runs repository-side.
|
|
173
|
+
* A `soft-binding-scope-map`.
|
|
187
174
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
175
|
+
interface Scope {
|
|
176
|
+
timespan?: Timespan;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* A `soft-binding-timespan-map`: where the range starts in the media and how long it lasts, in
|
|
180
|
+
* milliseconds.
|
|
181
|
+
*/
|
|
182
|
+
interface Timespan {
|
|
183
|
+
start: number;
|
|
184
|
+
duration: number;
|
|
185
|
+
}
|
|
194
186
|
/**
|
|
195
187
|
* A session signing key from the init manifest\'s roster (spec §19.4.4).
|
|
196
188
|
*/
|
|
197
|
-
interface
|
|
189
|
+
interface SessionKey {
|
|
198
190
|
/**
|
|
199
191
|
* Identifier of the session signing key.
|
|
200
192
|
*/
|
|
201
|
-
|
|
193
|
+
kid: Uint8Array;
|
|
202
194
|
/**
|
|
203
195
|
* The session key\'s public half (SEC1-encoded bytes).
|
|
204
196
|
*/
|
|
205
197
|
publicKey: Uint8Array;
|
|
206
198
|
}
|
|
207
199
|
/**
|
|
208
|
-
*
|
|
209
|
-
*/
|
|
210
|
-
type ValidationState = "Invalid" | "Valid" | "Trusted";
|
|
211
|
-
/**
|
|
212
|
-
* Construction options for [`AssetVerifier::new`] (and the `AssetVerifier.create` JS
|
|
213
|
-
* binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
|
|
214
|
-
*
|
|
215
|
-
* One definition, all lanes: `#[binding]` derives the shapes directly here:
|
|
216
|
-
* tsify (camelCase) on wasm, a `uniffi::Record` on the native `ffi` build, so there is no
|
|
217
|
-
* per-lane DTO copy. Off both lanes it is a plain struct.
|
|
200
|
+
* An asset a repository downloads, as the `byReference` request body names it.
|
|
218
201
|
*/
|
|
219
|
-
interface
|
|
220
|
-
/**
|
|
221
|
-
* The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
|
|
222
|
-
* for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
|
|
223
|
-
* `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
|
|
224
|
-
* asked of this verifier.
|
|
225
|
-
*/
|
|
226
|
-
repositories: Repository[];
|
|
227
|
-
/**
|
|
228
|
-
* PEM trust anchors for the manifest signers the caller trusts.
|
|
229
|
-
*/
|
|
230
|
-
trustAnchors: string[];
|
|
202
|
+
interface Reference {
|
|
231
203
|
/**
|
|
232
|
-
*
|
|
204
|
+
* A short-lived https URL without credentials.
|
|
233
205
|
*/
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
|
|
237
|
-
* caller\'s. `false` trusts the caller\'s lists alone.
|
|
238
|
-
*/
|
|
239
|
-
trustC2paAnchors: boolean;
|
|
240
|
-
/**
|
|
241
|
-
* Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
|
|
242
|
-
* exactly against the credential issuer. Empty trusts no issuer: every identity assertion
|
|
243
|
-
* then reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`,
|
|
244
|
-
* which leaves the manifest\'s own validity untouched.
|
|
245
|
-
*/
|
|
246
|
-
trustedIcaIssuers: string[];
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Construction options for [`StreamVerifier::new`] (and the `StreamVerifier.create`
|
|
250
|
-
* JS binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
|
|
251
|
-
*
|
|
252
|
-
* `#[binding]` derives the wasm shape (`trustC2paAnchors` camelCase) and,
|
|
253
|
-
* with `ffi`, a `uniffi::Record` for the native `StreamVerifier.create` binding, so there
|
|
254
|
-
* is no per-lane DTO copy. Off both lanes it is a plain struct.
|
|
255
|
-
*/
|
|
256
|
-
interface StreamVerifierOptions {
|
|
257
|
-
/**
|
|
258
|
-
* PEM trust anchors for the manifest signers the caller trusts.
|
|
259
|
-
*/
|
|
260
|
-
trustAnchors: string[];
|
|
261
|
-
/**
|
|
262
|
-
* PEM trust anchors for the time-stamping authorities the caller trusts.
|
|
263
|
-
*/
|
|
264
|
-
tsaTrustAnchors: string[];
|
|
265
|
-
/**
|
|
266
|
-
* Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
|
|
267
|
-
* caller\'s. `false` trusts the caller\'s lists alone.
|
|
268
|
-
*/
|
|
269
|
-
trustC2paAnchors: boolean;
|
|
206
|
+
url: string;
|
|
270
207
|
/**
|
|
271
|
-
*
|
|
272
|
-
* exactly against the credential issuer. Empty trusts no issuer: an identity assertion
|
|
273
|
-
* on the init segment\'s manifest then reports `cawg.ica.untrusted_issuer` and withholds
|
|
274
|
-
* `cawg.ica.credential_valid`.
|
|
208
|
+
* The asset\'s size in bytes.
|
|
275
209
|
*/
|
|
276
|
-
|
|
210
|
+
length: number;
|
|
277
211
|
/**
|
|
278
|
-
*
|
|
279
|
-
* skewed, in seconds: the deployment\'s own encoder-clock allowance, stated rather than
|
|
280
|
-
* assumed.
|
|
212
|
+
* The asset\'s media type.
|
|
281
213
|
*/
|
|
282
|
-
|
|
214
|
+
format?: string;
|
|
215
|
+
ranges?: import('@contentauth/c2pa-types').Range[];
|
|
283
216
|
}
|
|
284
217
|
/**
|
|
285
|
-
*
|
|
286
|
-
* the native lane\'s `DeriveOptions` is, spelled as data.
|
|
287
|
-
*/
|
|
288
|
-
interface DeriveOptions {
|
|
289
|
-
format: AssetFormat;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* How a call knows the asset\'s format: stated by the caller, or read from the leading bytes.
|
|
293
|
-
* Stated, never defaulted: sniffing is a choice made by name.
|
|
218
|
+
* C2PA validation state of a manifest (spec §14.3).
|
|
294
219
|
*/
|
|
295
|
-
type
|
|
296
|
-
kind: "sniff";
|
|
297
|
-
} | {
|
|
298
|
-
kind: "declared";
|
|
299
|
-
mediaType: string;
|
|
300
|
-
};
|
|
220
|
+
type ValidationState = "Invalid" | "Valid" | "Trusted";
|
|
301
221
|
/**
|
|
302
222
|
* One C2PA manifest repository, as the Soft Binding Resolution API spec lets a client find it.
|
|
303
223
|
*/
|
|
@@ -306,8 +226,8 @@ type Repository = {
|
|
|
306
226
|
url: string;
|
|
307
227
|
algorithms: string[];
|
|
308
228
|
} | {
|
|
309
|
-
kind: "
|
|
310
|
-
|
|
229
|
+
kind: "registered";
|
|
230
|
+
alg: string;
|
|
311
231
|
};
|
|
312
232
|
/**
|
|
313
233
|
* One C2PA validation status entry (spec §15.3): the registered code, its kind, and the
|
|
@@ -331,13 +251,7 @@ interface ValidationCode {
|
|
|
331
251
|
*/
|
|
332
252
|
interface Credential {
|
|
333
253
|
/**
|
|
334
|
-
*
|
|
335
|
-
* `identifier`: each manifest\'s claim thumbnail and each ingredient\'s. The manifests state
|
|
336
|
-
* identifiers and no images, so this is what a chain draws from.
|
|
337
|
-
*/
|
|
338
|
-
thumbnails: Record<string, Uint8Array>;
|
|
339
|
-
/**
|
|
340
|
-
* Where this credential came from. See [`CredentialOrigin`].
|
|
254
|
+
* Where this credential came from.
|
|
341
255
|
*/
|
|
342
256
|
origin: CredentialOrigin;
|
|
343
257
|
manifest: import('@contentauth/c2pa-types').ManifestStore;
|
|
@@ -346,17 +260,38 @@ interface Credential {
|
|
|
346
260
|
*/
|
|
347
261
|
hardBinding: HardBinding;
|
|
348
262
|
/**
|
|
349
|
-
* Where this credential sits among the others returned.
|
|
263
|
+
* Where this credential sits among the others returned.
|
|
350
264
|
*/
|
|
351
265
|
lineage: Lineage;
|
|
352
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* One query that located a recovered credential: how it was asked, under which algorithm, and
|
|
269
|
+
* where the manifest came from.
|
|
270
|
+
*/
|
|
271
|
+
interface Discovery {
|
|
272
|
+
via: DiscoveryVia;
|
|
273
|
+
alg: string;
|
|
274
|
+
type: SoftBindingType;
|
|
275
|
+
/**
|
|
276
|
+
* 0-100, the repository\'s `similarityScore`.
|
|
277
|
+
*/
|
|
278
|
+
score?: number;
|
|
279
|
+
repository: string;
|
|
280
|
+
/**
|
|
281
|
+
* The resolution API the manifest was fetched from, when not `repository`.
|
|
282
|
+
*/
|
|
283
|
+
endpoint?: string;
|
|
284
|
+
}
|
|
353
285
|
/**
|
|
354
286
|
* Outcome of validating a media segment against its stream\'s init.
|
|
355
287
|
*/
|
|
356
288
|
interface MediaValidation {
|
|
357
|
-
|
|
289
|
+
/**
|
|
290
|
+
* `invalid` on any failure, else the state of the init manifest the segment\'s key came from.
|
|
291
|
+
*/
|
|
292
|
+
state: ValidationState;
|
|
358
293
|
codes: ValidationCode[];
|
|
359
|
-
|
|
294
|
+
kid: Uint8Array;
|
|
360
295
|
timing: SegmentTiming;
|
|
361
296
|
manifestId: string;
|
|
362
297
|
}
|
|
@@ -367,7 +302,7 @@ interface InitValidation {
|
|
|
367
302
|
state: ValidationState;
|
|
368
303
|
codes: ValidationCode[];
|
|
369
304
|
manifest: import('@contentauth/c2pa-types').ManifestStore;
|
|
370
|
-
sessionKeys:
|
|
305
|
+
sessionKeys: SessionKey[];
|
|
371
306
|
}
|
|
372
307
|
/**
|
|
373
308
|
* Result of `StreamSession.validate`, discriminated by `kind`.
|
|
@@ -380,80 +315,214 @@ type SegmentValidation = ({
|
|
|
380
315
|
kind: "unknown";
|
|
381
316
|
};
|
|
382
317
|
/**
|
|
383
|
-
*
|
|
318
|
+
* The C2PA 2.4 golden-flow comparison of the embedded manifest against what the repository holds.
|
|
319
|
+
*/
|
|
320
|
+
type Golden = {
|
|
321
|
+
kind: "matches";
|
|
322
|
+
index: number;
|
|
323
|
+
} | {
|
|
324
|
+
kind: "differs";
|
|
325
|
+
index: number;
|
|
326
|
+
} | {
|
|
327
|
+
kind: "noneMatches";
|
|
328
|
+
candidates: number[];
|
|
329
|
+
} | {
|
|
330
|
+
kind: "unreadable";
|
|
331
|
+
index: number;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* The C2PA list\'s `type` of a soft binding algorithm.
|
|
335
|
+
*/
|
|
336
|
+
type SoftBindingType = "fingerprint" | "watermark";
|
|
337
|
+
/**
|
|
338
|
+
* The Soft Binding Resolution API route a discovery came through.
|
|
339
|
+
*/
|
|
340
|
+
type DiscoveryVia = {
|
|
341
|
+
kind: "byBinding";
|
|
342
|
+
value: Uint8Array;
|
|
343
|
+
} | {
|
|
344
|
+
kind: "byContent";
|
|
345
|
+
hint?: Hint;
|
|
346
|
+
} | {
|
|
347
|
+
kind: "byReference";
|
|
348
|
+
hint?: Hint;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* The evidence that singled a recovered verdict out.
|
|
352
|
+
*/
|
|
353
|
+
type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
|
|
354
|
+
/**
|
|
355
|
+
* The query a repository answers from the content: `matches/byReference` when `reference` is
|
|
356
|
+
* stated, so nothing is uploaded, else `matches/byContent` with the asset in the request.
|
|
357
|
+
*/
|
|
358
|
+
interface Content {
|
|
359
|
+
when: ContentWhen;
|
|
360
|
+
/**
|
|
361
|
+
* Where each repository downloads the asset from.
|
|
362
|
+
*/
|
|
363
|
+
reference?: Reference;
|
|
364
|
+
/**
|
|
365
|
+
* The largest asset an upload sends, in bytes; a larger one is reported `tooLarge`. Absent,
|
|
366
|
+
* 64 MiB.
|
|
367
|
+
*/
|
|
368
|
+
maxUploadBytes?: number;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* The re-sign chain between the returned credentials, by manifest label.
|
|
372
|
+
*/
|
|
373
|
+
interface Lineage {
|
|
374
|
+
supersedes: string[];
|
|
375
|
+
supersededBy: string[];
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The value a content query was hinted with, under its own algorithm.
|
|
379
|
+
*/
|
|
380
|
+
interface Hint {
|
|
381
|
+
alg: string;
|
|
382
|
+
value: Uint8Array;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Timing a media segment\'s container carries.
|
|
384
386
|
*/
|
|
385
387
|
interface SegmentTiming {
|
|
386
388
|
/**
|
|
387
|
-
*
|
|
389
|
+
* The segment\'s `sequenceNumber` (exact below 2^53).
|
|
388
390
|
*/
|
|
389
|
-
|
|
391
|
+
sequence: number;
|
|
390
392
|
/**
|
|
391
|
-
*
|
|
393
|
+
* The span its C2PA `emsg` covers, in milliseconds.
|
|
392
394
|
*/
|
|
393
|
-
|
|
395
|
+
duration?: number;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* What a stream verifier trusts, and how far a segment\'s clock may drift.
|
|
399
|
+
*/
|
|
400
|
+
interface StreamVerifierOptions {
|
|
401
|
+
trust: Trust;
|
|
394
402
|
/**
|
|
395
|
-
*
|
|
403
|
+
* How far a segment\'s presentation time may sit outside its session key\'s validity period,
|
|
404
|
+
* in milliseconds. Absent, 5 minutes.
|
|
396
405
|
*/
|
|
397
|
-
|
|
406
|
+
skewTolerance?: number;
|
|
398
407
|
}
|
|
399
408
|
/**
|
|
400
|
-
* What
|
|
401
|
-
* itself, decided into `matches/byBinding`, and one field per content operation, absent when
|
|
402
|
-
* not to be called. It needs a configured repository and at least one query.
|
|
409
|
+
* What a verifier trusts. An omitted list trusts nothing.
|
|
403
410
|
*/
|
|
404
|
-
interface
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
411
|
+
interface Trust {
|
|
412
|
+
/**
|
|
413
|
+
* PEM anchors for the manifest signers the caller trusts.
|
|
414
|
+
*/
|
|
415
|
+
anchors?: string[];
|
|
416
|
+
/**
|
|
417
|
+
* PEM anchors for the time-stamping authorities the caller trusts.
|
|
418
|
+
*/
|
|
419
|
+
tsaAnchors?: string[];
|
|
420
|
+
/**
|
|
421
|
+
* Also trust the bundled official C2PA manifest and TSA lists, beside the caller\'s.
|
|
422
|
+
*/
|
|
423
|
+
c2pa: boolean;
|
|
424
|
+
/**
|
|
425
|
+
* Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched exactly
|
|
426
|
+
* against the credential issuer. Empty trusts no issuer: every identity assertion then
|
|
427
|
+
* reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`, which leaves
|
|
428
|
+
* the manifest\'s own validity untouched.
|
|
429
|
+
*/
|
|
430
|
+
icaIssuers?: string[];
|
|
409
431
|
}
|
|
410
432
|
/**
|
|
411
|
-
*
|
|
433
|
+
* What an asset verifier trusts and which repositories it may ask. An omitted list trusts or
|
|
434
|
+
* asks nothing.
|
|
412
435
|
*/
|
|
413
|
-
|
|
436
|
+
interface AssetVerifierOptions {
|
|
437
|
+
/**
|
|
438
|
+
* The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
|
|
439
|
+
* for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
|
|
440
|
+
* `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
|
|
441
|
+
* asked of this verifier.
|
|
442
|
+
*/
|
|
443
|
+
repositories?: Repository[];
|
|
444
|
+
trust: Trust;
|
|
445
|
+
}
|
|
414
446
|
/**
|
|
415
|
-
*
|
|
447
|
+
* What one verify may do to recover a manifest, as data: the soft bindings this client looks up
|
|
448
|
+
* itself through `matches/byBinding`, and the content query, absent when not to be asked. It
|
|
449
|
+
* needs a configured repository and at least one query.
|
|
416
450
|
*/
|
|
417
|
-
|
|
451
|
+
interface Recovery {
|
|
452
|
+
when: RecoveryTrigger;
|
|
453
|
+
softBindings?: SoftBindingSource[];
|
|
454
|
+
content?: Content;
|
|
455
|
+
/**
|
|
456
|
+
* The whole recovery\'s budget in milliseconds, every repository together, each request
|
|
457
|
+
* bounded by what remains. Absent, 10 minutes; at most 2147483647.
|
|
458
|
+
*/
|
|
459
|
+
timeout?: number;
|
|
460
|
+
}
|
|
418
461
|
/**
|
|
419
|
-
*
|
|
462
|
+
* What this verify concludes about the asset, from signed evidence alone.
|
|
420
463
|
*/
|
|
421
|
-
type
|
|
464
|
+
type Verdict = {
|
|
465
|
+
kind: "unsigned";
|
|
466
|
+
} | {
|
|
467
|
+
kind: "inconclusive";
|
|
468
|
+
} | {
|
|
469
|
+
kind: "embedded";
|
|
470
|
+
} | {
|
|
471
|
+
kind: "recovered";
|
|
472
|
+
index: number;
|
|
473
|
+
decidedBy: VerdictRule;
|
|
474
|
+
} | {
|
|
475
|
+
kind: "recoveredDerivative";
|
|
476
|
+
index: number;
|
|
477
|
+
decidedBy: VerdictRule;
|
|
478
|
+
} | {
|
|
479
|
+
kind: "ambiguous";
|
|
480
|
+
candidates: number[];
|
|
481
|
+
};
|
|
422
482
|
/**
|
|
423
|
-
*
|
|
424
|
-
* `@contentauth/c2pa-types`, the shape a credential\'s actions carry.
|
|
483
|
+
* When a verify asks the repositories.
|
|
425
484
|
*/
|
|
426
|
-
|
|
427
|
-
after: ContentTrigger;
|
|
428
|
-
url: string;
|
|
429
|
-
length: number;
|
|
430
|
-
mediaType?: string;
|
|
431
|
-
region: import('@contentauth/c2pa-types').Range[];
|
|
432
|
-
}
|
|
485
|
+
type RecoveryTrigger = "manifestMissing" | "always";
|
|
433
486
|
/**
|
|
434
|
-
*
|
|
435
|
-
* credential carries different evidence. Lane-local for the same reason [`FingerprintCheck`] is: a
|
|
436
|
-
* tag layout is what `#[binding(wasm)]` declines to express.
|
|
487
|
+
* Where a credential came from: embedded in the asset, or recovered from a repository.
|
|
437
488
|
*/
|
|
438
489
|
type CredentialOrigin = {
|
|
439
490
|
kind: "embedded";
|
|
440
491
|
} | {
|
|
441
492
|
kind: "recovered";
|
|
442
|
-
discoveries:
|
|
493
|
+
discoveries: Discovery[];
|
|
443
494
|
fingerprintCheck: FingerprintCheck;
|
|
444
495
|
};
|
|
445
496
|
/**
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
|
|
497
|
+
* Where one byBinding query\'s value comes from. A browser has no host engine: a vendor\'s
|
|
498
|
+
* detector runs repository-side, through `byContent`.
|
|
499
|
+
*/
|
|
500
|
+
type SoftBindingSource = {
|
|
501
|
+
kind: "builtin";
|
|
502
|
+
alg: string;
|
|
503
|
+
} | {
|
|
504
|
+
kind: "held";
|
|
505
|
+
alg: string;
|
|
506
|
+
value: Uint8Array;
|
|
507
|
+
};
|
|
508
|
+
/**
|
|
509
|
+
* Whether a code is a success, an informational note, or a failure.
|
|
510
|
+
*/
|
|
511
|
+
type ValidationCodeKind = "success" | "informational" | "failure";
|
|
512
|
+
/**
|
|
513
|
+
* Whether a content form runs on this verify. Judged against the byBinding results alone.
|
|
514
|
+
*/
|
|
515
|
+
type ContentWhen = "bindingMisses" | "always";
|
|
516
|
+
/**
|
|
517
|
+
* Whether the asset\'s own fingerprint backs up a manifest that a watermark led to.
|
|
449
518
|
*/
|
|
450
519
|
type FingerprintCheck = {
|
|
451
520
|
kind: "notNeeded";
|
|
452
521
|
} | {
|
|
453
|
-
kind: "
|
|
522
|
+
kind: "missing";
|
|
454
523
|
} | {
|
|
455
524
|
kind: "unsupported";
|
|
456
|
-
|
|
525
|
+
alg: string;
|
|
457
526
|
} | {
|
|
458
527
|
kind: "indeterminate";
|
|
459
528
|
} | {
|
|
@@ -461,59 +530,40 @@ type FingerprintCheck = {
|
|
|
461
530
|
score: number;
|
|
462
531
|
};
|
|
463
532
|
/**
|
|
464
|
-
*
|
|
533
|
+
* Whether the manifest\'s hard binding holds over the bytes this verify read.
|
|
465
534
|
*/
|
|
466
535
|
type HardBinding = "match" | "mismatch";
|
|
467
536
|
/**
|
|
468
|
-
*
|
|
469
|
-
*/
|
|
470
|
-
interface Lineage {
|
|
471
|
-
supersedes: string[];
|
|
472
|
-
supersededBy: string[];
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* [`crate::asset::RecoveryIssue`] as JS sees it: a tagged union, each kind with its own data.
|
|
537
|
+
* Why repository recovery did not complete cleanly, or why one candidate was omitted.
|
|
476
538
|
*/
|
|
477
539
|
type RecoveryIssue = {
|
|
478
|
-
kind: "
|
|
479
|
-
|
|
540
|
+
kind: "computeFailed";
|
|
541
|
+
alg: string;
|
|
480
542
|
message: string;
|
|
481
543
|
} | {
|
|
482
|
-
kind: "
|
|
483
|
-
algorithm: string;
|
|
484
|
-
} | {
|
|
485
|
-
kind: "bindingUndeclared";
|
|
486
|
-
binderIndex: number;
|
|
487
|
-
algorithm: string;
|
|
488
|
-
} | {
|
|
489
|
-
kind: "bindingQueryFailed";
|
|
544
|
+
kind: "bindingFailed";
|
|
490
545
|
repository: string;
|
|
491
|
-
|
|
492
|
-
algorithm: string;
|
|
546
|
+
alg: string;
|
|
493
547
|
message: string;
|
|
494
548
|
} | {
|
|
495
549
|
kind: "queryRefused";
|
|
496
550
|
repository: string;
|
|
497
|
-
|
|
498
|
-
message: string;
|
|
499
|
-
} | {
|
|
500
|
-
kind: "contentFormUnsupported";
|
|
501
|
-
repository: string;
|
|
551
|
+
alg: string;
|
|
502
552
|
message: string;
|
|
503
553
|
} | {
|
|
504
|
-
kind: "
|
|
554
|
+
kind: "contentFailed";
|
|
505
555
|
repository: string;
|
|
506
|
-
|
|
556
|
+
alg: string;
|
|
507
557
|
message: string;
|
|
508
558
|
} | {
|
|
509
559
|
kind: "capabilitiesUnavailable";
|
|
510
560
|
repository: string;
|
|
511
561
|
message: string;
|
|
512
562
|
} | {
|
|
513
|
-
kind: "
|
|
514
|
-
|
|
563
|
+
kind: "tooLarge";
|
|
564
|
+
maxUploadBytes: number;
|
|
515
565
|
} | {
|
|
516
|
-
kind: "
|
|
566
|
+
kind: "fetchFailed";
|
|
517
567
|
repository: string;
|
|
518
568
|
manifestId: string;
|
|
519
569
|
message: string;
|
|
@@ -527,98 +577,22 @@ type RecoveryIssue = {
|
|
|
527
577
|
manifestId: string;
|
|
528
578
|
endpoint: string;
|
|
529
579
|
} | {
|
|
530
|
-
kind: "
|
|
580
|
+
kind: "limitReached";
|
|
531
581
|
message: string;
|
|
532
582
|
};
|
|
533
|
-
/**
|
|
534
|
-
* [`crate::asset::VerdictRule`] as JS sees it.
|
|
535
|
-
*/
|
|
536
|
-
type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
|
|
537
|
-
/**
|
|
538
|
-
* [`crate::asset::Verdict`] as JS sees it.
|
|
539
|
-
*/
|
|
540
|
-
type Verdict = {
|
|
541
|
-
kind: "unsigned";
|
|
542
|
-
} | {
|
|
543
|
-
kind: "inconclusive";
|
|
544
|
-
} | {
|
|
545
|
-
kind: "embedded";
|
|
546
|
-
} | {
|
|
547
|
-
kind: "recovered";
|
|
548
|
-
index: number;
|
|
549
|
-
decidedBy: VerdictRule;
|
|
550
|
-
} | {
|
|
551
|
-
kind: "recoveredDerivative";
|
|
552
|
-
index: number;
|
|
553
|
-
decidedBy: VerdictRule;
|
|
554
|
-
} | {
|
|
555
|
-
kind: "ambiguous";
|
|
556
|
-
candidates: number[];
|
|
557
|
-
};
|
|
558
|
-
/**
|
|
559
|
-
* `matches/byContent`: the asset is uploaded to each repository, one request per algorithm that
|
|
560
|
-
* repository is declared for.
|
|
561
|
-
*/
|
|
562
|
-
interface ByContent {
|
|
563
|
-
after: ContentTrigger;
|
|
564
|
-
}
|
|
565
583
|
interface AssetVerification {
|
|
566
584
|
credentials: Credential[];
|
|
567
585
|
recovery: RecoverySummary;
|
|
568
|
-
|
|
586
|
+
/**
|
|
587
|
+
* Absent when there was nothing to compare.
|
|
588
|
+
*/
|
|
589
|
+
golden?: Golden;
|
|
569
590
|
verdict: Verdict;
|
|
570
591
|
}
|
|
571
592
|
interface RecoverySummary {
|
|
572
593
|
status: RecoveryStatus;
|
|
573
594
|
issues: RecoveryIssue[];
|
|
574
595
|
}
|
|
575
|
-
type ContentBindingClass = "fingerprint" | "watermark";
|
|
576
|
-
type GoldenComparison = {
|
|
577
|
-
kind: "notRequested";
|
|
578
|
-
} | {
|
|
579
|
-
kind: "noEmbeddedManifest";
|
|
580
|
-
} | {
|
|
581
|
-
kind: "noRecoveredManifest";
|
|
582
|
-
} | {
|
|
583
|
-
kind: "recoveryIncomplete";
|
|
584
|
-
} | {
|
|
585
|
-
kind: "matches";
|
|
586
|
-
recoveredIndex: number;
|
|
587
|
-
} | {
|
|
588
|
-
kind: "differs";
|
|
589
|
-
recoveredIndex: number;
|
|
590
|
-
} | {
|
|
591
|
-
kind: "noneMatches";
|
|
592
|
-
candidates: number[];
|
|
593
|
-
} | {
|
|
594
|
-
kind: "unreadable";
|
|
595
|
-
recoveredIndex: number;
|
|
596
|
-
};
|
|
597
|
-
type RecoveryDiscovery = {
|
|
598
|
-
kind: "byBinding";
|
|
599
|
-
class: ContentBindingClass;
|
|
600
|
-
binding: SoftBinding;
|
|
601
|
-
binderIndex: number;
|
|
602
|
-
repositoryScore: number | undefined;
|
|
603
|
-
repository: string;
|
|
604
|
-
fetchedFrom: string;
|
|
605
|
-
} | {
|
|
606
|
-
kind: "byContent";
|
|
607
|
-
hint: SoftBinding | undefined;
|
|
608
|
-
class: ContentBindingClass;
|
|
609
|
-
algorithm: string;
|
|
610
|
-
repositoryScore: number | undefined;
|
|
611
|
-
repository: string;
|
|
612
|
-
fetchedFrom: string;
|
|
613
|
-
} | {
|
|
614
|
-
kind: "byReference";
|
|
615
|
-
hint: SoftBinding | undefined;
|
|
616
|
-
class: ContentBindingClass;
|
|
617
|
-
algorithm: string;
|
|
618
|
-
repositoryScore: number | undefined;
|
|
619
|
-
repository: string;
|
|
620
|
-
fetchedFrom: string;
|
|
621
|
-
};
|
|
622
596
|
type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
|
|
623
597
|
declare class AssetVerifier {
|
|
624
598
|
private constructor();
|
|
@@ -638,14 +612,11 @@ declare class AssetVerifier {
|
|
|
638
612
|
*
|
|
639
613
|
* # Errors
|
|
640
614
|
*
|
|
641
|
-
* Throws on a malformed `
|
|
615
|
+
* Throws on a malformed `source`, a repository (or engine) failure, or a validation
|
|
642
616
|
* failure.
|
|
643
617
|
*/
|
|
644
|
-
verify(
|
|
618
|
+
verify(source: RangeSource, recovery?: Recovery | null): Promise<Verification>;
|
|
645
619
|
}
|
|
646
|
-
declare function C2PA_TRUST_LIST(): string;
|
|
647
|
-
declare function C2PA_TSA_TRUST_LIST(): string;
|
|
648
|
-
declare function DEV_CA(): string;
|
|
649
620
|
/**
|
|
650
621
|
* One stream being validated. It owns the session keys and manifest ids its init segments
|
|
651
622
|
* advertised, so releasing the stream is dropping this object.
|
|
@@ -655,8 +626,8 @@ declare class StreamSession {
|
|
|
655
626
|
free(): void;
|
|
656
627
|
[Symbol.dispose](): void;
|
|
657
628
|
/**
|
|
658
|
-
*
|
|
659
|
-
* `StreamVerifier.resume` from.
|
|
629
|
+
* This stream's id and everything its init segments have registered, as CBOR for another
|
|
630
|
+
* node to `StreamVerifier.resume` from.
|
|
660
631
|
*
|
|
661
632
|
* The one piece of stream state that leaves the SDK, and only because a clustered
|
|
662
633
|
* verifier needs it: the init URL is overwritten on rotation, so a node joining during
|
|
@@ -677,7 +648,7 @@ declare class StreamSession {
|
|
|
677
648
|
* Throws an `SdkError` on parse or signature failure, or when a media segment arrives
|
|
678
649
|
* before any init was processed for the stream.
|
|
679
650
|
*/
|
|
680
|
-
validate(
|
|
651
|
+
validate(source: RangeSource): Promise<SegmentValidation>;
|
|
681
652
|
}
|
|
682
653
|
declare class StreamVerifier {
|
|
683
654
|
private constructor();
|
|
@@ -692,25 +663,57 @@ declare class StreamVerifier {
|
|
|
692
663
|
*/
|
|
693
664
|
static create(options: StreamVerifierOptions): StreamVerifier;
|
|
694
665
|
/**
|
|
695
|
-
* Open `
|
|
666
|
+
* Open the stream `id` for validation, handing back a `StreamSession` to feed segments to.
|
|
696
667
|
*
|
|
697
668
|
* No I/O: the handle carries the id so it cannot be mistyped or confused with another
|
|
698
669
|
* stream's, and classification still happens per segment. Opening one id twice hands
|
|
699
670
|
* back the same live session, so a component that remounts keeps the state its earlier
|
|
700
671
|
* handle accumulated.
|
|
701
672
|
*/
|
|
702
|
-
open(
|
|
673
|
+
open(id: string): StreamSession;
|
|
703
674
|
/**
|
|
704
|
-
* Open
|
|
705
|
-
*
|
|
675
|
+
* Open the stream another node exported, its state merged into whatever this one holds
|
|
676
|
+
* for that stream already.
|
|
706
677
|
*
|
|
707
678
|
* # Errors
|
|
708
679
|
*
|
|
709
|
-
* Throws an `SdkError`
|
|
710
|
-
* `StreamSession.export` produced, or
|
|
680
|
+
* Throws an `SdkError` with a field violation at `state` when it is not a value
|
|
681
|
+
* `StreamSession.export` produced (`state.malformed`), or one of another export version
|
|
682
|
+
* (`state.version`).
|
|
711
683
|
*/
|
|
712
|
-
resume(
|
|
684
|
+
resume(state: Uint8Array): StreamSession;
|
|
713
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* One `verify` result held with the stores it read: `report` is the data, and `resource` reads a
|
|
688
|
+
* thumbnail from credential `credential` (its position in `report.credentials`) by the
|
|
689
|
+
* `identifier` of a resource reference in its manifest. A class rather than a field of the
|
|
690
|
+
* report because a store cannot be serialized, and one handle per verify is what a worker can
|
|
691
|
+
* proxy (a class nested in the report cannot cross a thread).
|
|
692
|
+
*/
|
|
693
|
+
declare class Verification {
|
|
694
|
+
private constructor();
|
|
695
|
+
free(): void;
|
|
696
|
+
[Symbol.dispose](): void;
|
|
697
|
+
/**
|
|
698
|
+
* The bytes of one resource credential `credential` holds, or `undefined`.
|
|
699
|
+
*
|
|
700
|
+
* # Errors
|
|
701
|
+
*
|
|
702
|
+
* Throws `READER_INVALID` when the store holds the resource but cannot produce it, and
|
|
703
|
+
* `undefined` for a `credential` out of range.
|
|
704
|
+
*/
|
|
705
|
+
resource(credential: number, uri: string): Uint8Array | undefined;
|
|
706
|
+
/**
|
|
707
|
+
* The report: credentials, recovery, golden flow and verdict.
|
|
708
|
+
*/
|
|
709
|
+
readonly report: AssetVerification;
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* PEM trust anchor for the Limbo Integrity development signing environment, **development
|
|
713
|
+
* only**, no security guarantees: put it in `trust.anchors` for a development build, never in a
|
|
714
|
+
* release.
|
|
715
|
+
*/
|
|
716
|
+
declare function devCa(): string;
|
|
714
717
|
//#endregion
|
|
715
718
|
//#region src/worker-thread.d.ts
|
|
716
719
|
/**
|
|
@@ -737,9 +740,18 @@ declare abstract class Handle<T extends {
|
|
|
737
740
|
constructor(inner: T);
|
|
738
741
|
[finalizer](): void;
|
|
739
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* One verify result. A wasm class cannot cross the thread, so the report and the stores behind it
|
|
745
|
+
* stay here and the caller holds this: `report()` is the data, `resource()` reads a thumbnail from
|
|
746
|
+
* a credential by its position in `report().credentials`.
|
|
747
|
+
*/
|
|
748
|
+
declare class VerificationHandle extends Handle<Verification> {
|
|
749
|
+
report(): AssetVerification;
|
|
750
|
+
resource(credential: number, uri: string): Uint8Array | undefined;
|
|
751
|
+
}
|
|
740
752
|
declare class AssetVerifierHandle extends Handle<AssetVerifier> {
|
|
741
753
|
/** `recovery` is what this verify may do to recover a manifest, as the direct import takes it. */
|
|
742
|
-
verify(asset: Asset, recovery: Recovery | undefined): Promise<
|
|
754
|
+
verify(asset: Asset, recovery: Recovery | undefined): Promise<VerificationHandle & ProxyMarked>;
|
|
743
755
|
}
|
|
744
756
|
/** One stream being validated. Dropping the handle releases the session it accumulated. */
|
|
745
757
|
declare class StreamSessionHandle extends Handle<StreamSession> {
|
|
@@ -747,8 +759,8 @@ declare class StreamSessionHandle extends Handle<StreamSession> {
|
|
|
747
759
|
export(): Uint8Array;
|
|
748
760
|
}
|
|
749
761
|
declare class StreamVerifierHandle extends Handle<StreamVerifier> {
|
|
750
|
-
open(
|
|
751
|
-
resume(
|
|
762
|
+
open(id: string): StreamSessionHandle & ProxyMarked;
|
|
763
|
+
resume(state: Uint8Array): StreamSessionHandle & ProxyMarked;
|
|
752
764
|
}
|
|
753
765
|
/** The module's own surface, name for name with the direct import. */
|
|
754
766
|
declare const sdk: {
|
|
@@ -763,13 +775,11 @@ declare const sdk: {
|
|
|
763
775
|
StreamVerifier: {
|
|
764
776
|
create: (options: StreamVerifierOptions) => StreamVerifierHandle & ProxyMarked;
|
|
765
777
|
} & ProxyMarked;
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
derive: (spec: BinderSpec, content: Asset, options: DeriveOptions) => Promise<SoftBinding | undefined>;
|
|
772
|
-
} & ProxyMarked;
|
|
778
|
+
/**
|
|
779
|
+
* The values this SDK computes for `alg` over the asset, `[]` when it finds none. `format` is the
|
|
780
|
+
* asset's media type; omitted, the bytes name it.
|
|
781
|
+
*/
|
|
782
|
+
computeSoftBinding(alg: string, asset: Asset, format?: string): Promise<Block[]>;
|
|
773
783
|
/**
|
|
774
784
|
* Read a detached manifest store. Contents, not a verdict: with no asset there is no hard binding
|
|
775
785
|
* to check, so the store's validation fields state nothing this established.
|
|
@@ -780,14 +790,7 @@ declare const sdk: {
|
|
|
780
790
|
* manifest's claim thumbnail, and any ingredient's.
|
|
781
791
|
*/
|
|
782
792
|
resource(manifest: Asset, uri: string): Promise<Uint8Array<ArrayBufferLike> | undefined>;
|
|
783
|
-
|
|
784
|
-
* Every thumbnail the store references, by the identifier it references them under. One parse
|
|
785
|
-
* and one thread hop for the whole set, where `resource` pays both per call.
|
|
786
|
-
*/
|
|
787
|
-
thumbnails(manifest: Asset): Promise<Record<string, Uint8Array<ArrayBufferLike>>>;
|
|
788
|
-
C2PA_TRUST_LIST: typeof C2PA_TRUST_LIST;
|
|
789
|
-
C2PA_TSA_TRUST_LIST: typeof C2PA_TSA_TRUST_LIST;
|
|
790
|
-
DEV_CA: typeof DEV_CA;
|
|
793
|
+
devCa: typeof devCa;
|
|
791
794
|
close(): void;
|
|
792
795
|
};
|
|
793
796
|
/** What the caller's thread holds a `Comlink.Remote` of. */
|