@blockcast/mmt-manifest-verify 0.1.1 → 0.3.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/dist/verifier.d.ts +19 -1
- package/dist/verifier.d.ts.map +1 -1
- package/dist/verifier.js +54 -11
- package/dist/verifier.js.map +1 -1
- package/package.json +7 -2
- package/src/verifier.ts +64 -10
- package/src/verifier.test.ts +0 -509
package/dist/verifier.d.ts
CHANGED
|
@@ -45,7 +45,16 @@ export interface ManifestTrackContext {
|
|
|
45
45
|
}
|
|
46
46
|
export interface ManifestVerificationStats {
|
|
47
47
|
verified: number;
|
|
48
|
+
/** Terminal outcomes only: an object counted here will never be verified. */
|
|
48
49
|
failures: Record<ManifestFailureReason, number>;
|
|
50
|
+
/**
|
|
51
|
+
* Objects currently held in quarantine awaiting a manifest — pending, NOT
|
|
52
|
+
* failed, and deliberately disjoint from `failures`. An enforce-mode stall is
|
|
53
|
+
* accounted here first and moves into `failures` only once the verifier gives
|
|
54
|
+
* up on it, so a reason breakdown that ignores this gauge under-reports live
|
|
55
|
+
* stalls by whatever is still in flight (BLO-30007).
|
|
56
|
+
*/
|
|
57
|
+
quarantined: number;
|
|
49
58
|
quarantinedBytes: number;
|
|
50
59
|
}
|
|
51
60
|
export interface ManifestFailure {
|
|
@@ -75,7 +84,16 @@ export declare class ManifestVerifier {
|
|
|
75
84
|
setMode(mode: ManifestAuthMode): void;
|
|
76
85
|
registerTrack(context: ManifestTrackContext): void;
|
|
77
86
|
ingestManifestFrame(bindingId: string, frameBytes: Uint8Array): void;
|
|
78
|
-
admitObject(identity: ManifestObjectIdentity, data: Uint8Array, release: () => void
|
|
87
|
+
admitObject(identity: ManifestObjectIdentity, data: Uint8Array, release: () => void,
|
|
88
|
+
/**
|
|
89
|
+
* Called instead of `release` when a stalled object is terminally rejected
|
|
90
|
+
* rather than played. A caller that drives a sequence off `release` (the FEC
|
|
91
|
+
* symbol loop in `mmtp-router` does) must pass this, or an enforce-mode
|
|
92
|
+
* discard leaves the sequence waiting on a callback that will never fire.
|
|
93
|
+
* A `drop` returned from this call is the synchronous form of the same
|
|
94
|
+
* outcome and does NOT also invoke `discard`.
|
|
95
|
+
*/
|
|
96
|
+
discard?: () => void): ManifestAdmission;
|
|
79
97
|
dispose(): void;
|
|
80
98
|
}
|
|
81
99
|
//# sourceMappingURL=verifier.d.ts.map
|
package/dist/verifier.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAA;AAC3D,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,iBAAiB,CAAA;AAC/D,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,eAAe,CAAA;AAEnB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAA;IACtB,iBAAiB,EAAE,qBAAqB,CAAA;CACzC;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5D;AAED,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,qBAAqB,EAAE,MAAM,CAAA;IAC7B;kEAC8D;IAC9D,SAAS,EAAE,UAAU,CAAA;IACrB,SAAS,EAAE,UAAU,CAAA;IACrB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,sBAAsB,CAAA;IAC9B,4BAA4B,EAAE,OAAO,CAAA;CACtC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IAC/C,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,qBAAqB,CAAA;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;IACjC,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAC/B;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,KAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/B,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,GAAE,YAAuC,GAC9C,iBAAiB,CAQnB;
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/verifier.js
CHANGED
|
@@ -47,9 +47,13 @@ export class ManifestVerifier {
|
|
|
47
47
|
return this.#config;
|
|
48
48
|
}
|
|
49
49
|
get stats() {
|
|
50
|
+
let quarantined = 0;
|
|
51
|
+
for (const track of this.#tracks.values())
|
|
52
|
+
quarantined += track.quarantine.length;
|
|
50
53
|
return {
|
|
51
54
|
verified: this.#stats.verified,
|
|
52
55
|
failures: { ...this.#stats.failures },
|
|
56
|
+
quarantined,
|
|
53
57
|
quarantinedBytes: this.#stats.quarantinedBytes,
|
|
54
58
|
};
|
|
55
59
|
}
|
|
@@ -137,7 +141,16 @@ export class ManifestVerifier {
|
|
|
137
141
|
this.#failure({ trackName: track.context.trackName, bindingId, groupId: 0, objectId: 0 }, 'verifierError');
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
|
-
admitObject(identity, data, release
|
|
144
|
+
admitObject(identity, data, release,
|
|
145
|
+
/**
|
|
146
|
+
* Called instead of `release` when a stalled object is terminally rejected
|
|
147
|
+
* rather than played. A caller that drives a sequence off `release` (the FEC
|
|
148
|
+
* symbol loop in `mmtp-router` does) must pass this, or an enforce-mode
|
|
149
|
+
* discard leaves the sequence waiting on a callback that will never fire.
|
|
150
|
+
* A `drop` returned from this call is the synchronous form of the same
|
|
151
|
+
* outcome and does NOT also invoke `discard`.
|
|
152
|
+
*/
|
|
153
|
+
discard) {
|
|
141
154
|
if (this.#config.mode === 'off') {
|
|
142
155
|
release();
|
|
143
156
|
return { action: 'play', verified: false };
|
|
@@ -158,13 +171,13 @@ export class ManifestVerifier {
|
|
|
158
171
|
}
|
|
159
172
|
const entry = group.entries.get(identity.objectId);
|
|
160
173
|
if (entry)
|
|
161
|
-
return this.#admitAgainstEntry(track, group, identity, data, release, entry);
|
|
174
|
+
return this.#admitAgainstEntry(track, group, identity, data, release, entry, discard);
|
|
162
175
|
if (this.#config.mode === 'shadow' || this.#config.onMissingManifest === 'fallback-shadow') {
|
|
163
176
|
release();
|
|
164
177
|
this.#failure(identity, 'manifestAbsent');
|
|
165
178
|
return { action: 'play', verified: false, reason: 'manifestAbsent' };
|
|
166
179
|
}
|
|
167
|
-
if (!this.#quarantine(track, group, { identity, data, release, bytes: data.byteLength })) {
|
|
180
|
+
if (!this.#quarantine(track, group, { identity, data, release, discard, bytes: data.byteLength })) {
|
|
168
181
|
return { action: 'drop', verified: false };
|
|
169
182
|
}
|
|
170
183
|
return { action: 'stall', verified: false };
|
|
@@ -200,8 +213,13 @@ export class ManifestVerifier {
|
|
|
200
213
|
const [oldestId, oldestGroup] = oldest;
|
|
201
214
|
for (const pending of [...oldestGroup.pending.values()]) {
|
|
202
215
|
this.#removePending(track, oldestGroup, pending);
|
|
203
|
-
pending
|
|
204
|
-
|
|
216
|
+
this.#giveUpOnPending(pending);
|
|
217
|
+
// The group aged out with objects still waiting on a manifest that
|
|
218
|
+
// never arrived. That is an absent manifest, not a verifier fault:
|
|
219
|
+
// `verifierError` is reserved for an exception/crash in the verifier
|
|
220
|
+
// itself, so mislabelling here reads on the graduation dashboard as a
|
|
221
|
+
// software bug and hides a benign absent-manifest stall (BLO-30007).
|
|
222
|
+
this.#failure(pending.identity, 'manifestAbsent');
|
|
205
223
|
}
|
|
206
224
|
track.manifestEntries -= oldestGroup.entries.size;
|
|
207
225
|
track.groups.delete(oldestId);
|
|
@@ -213,7 +231,7 @@ export class ManifestVerifier {
|
|
|
213
231
|
const coordinates = track.context.mapper.derive(Number(identity.groupId), identity.objectId);
|
|
214
232
|
return identity.ssId === undefined || coordinates.ssId === identity.ssId;
|
|
215
233
|
}
|
|
216
|
-
#admitAgainstEntry(track, group, identity, data, release, entry) {
|
|
234
|
+
#admitAgainstEntry(track, group, identity, data, release, entry, discard) {
|
|
217
235
|
if (entry.trueLength !== data.byteLength) {
|
|
218
236
|
return this.#rejectOrShadow(identity, release, 'digestMismatch');
|
|
219
237
|
}
|
|
@@ -225,7 +243,7 @@ export class ManifestVerifier {
|
|
|
225
243
|
release();
|
|
226
244
|
return { action: 'play', verified: false };
|
|
227
245
|
}
|
|
228
|
-
if (!this.#quarantine(track, group, { identity, data, release, bytes: data.byteLength })) {
|
|
246
|
+
if (!this.#quarantine(track, group, { identity, data, release, discard, bytes: data.byteLength })) {
|
|
229
247
|
return { action: 'drop', verified: false };
|
|
230
248
|
}
|
|
231
249
|
return { action: 'stall', verified: false };
|
|
@@ -245,7 +263,7 @@ export class ManifestVerifier {
|
|
|
245
263
|
}
|
|
246
264
|
#resolvePending(track, group, pending, entry) {
|
|
247
265
|
this.#removePending(track, group, pending);
|
|
248
|
-
this.#admitAgainstEntry(track, group, pending.identity, pending.data, pending.release, entry);
|
|
266
|
+
this.#admitAgainstEntry(track, group, pending.identity, pending.data, pending.release, entry, pending.discard);
|
|
249
267
|
}
|
|
250
268
|
#closeGroup(track, groupId, group, close) {
|
|
251
269
|
if (group.close || group.signaturePending)
|
|
@@ -366,7 +384,12 @@ export class ManifestVerifier {
|
|
|
366
384
|
}
|
|
367
385
|
for (const pending of [...group.pending.values()]) {
|
|
368
386
|
this.#removePending(track, group, pending);
|
|
369
|
-
|
|
387
|
+
// Same contract as an eviction: a quarantined object that is rejected
|
|
388
|
+
// rather than played must still tell the caller it is finished, or a
|
|
389
|
+
// caller sequencing off `release` waits forever (BLO-30095).
|
|
390
|
+
if (this.#rejectOrShadow(pending.identity, pending.release, reason).action === 'drop') {
|
|
391
|
+
pending.discard?.();
|
|
392
|
+
}
|
|
370
393
|
}
|
|
371
394
|
}
|
|
372
395
|
#removePending(track, group, pending) {
|
|
@@ -397,10 +420,30 @@ export class ManifestVerifier {
|
|
|
397
420
|
group.pending.delete(pending.identity.objectId);
|
|
398
421
|
track.quarantinedBytes -= pending.bytes;
|
|
399
422
|
this.#stats.quarantinedBytes -= pending.bytes;
|
|
423
|
+
this.#giveUpOnPending(pending);
|
|
424
|
+
// Quarantine budget ran out while the object was still waiting on a
|
|
425
|
+
// manifest. The manifest was absent when we gave up; the verifier did not
|
|
426
|
+
// fault. Same reason in shadow and enforce so the dashboard reads one
|
|
427
|
+
// taxonomy across modes (BLO-30007).
|
|
428
|
+
this.#failure(pending.identity, 'manifestAbsent');
|
|
429
|
+
console.warn(`[ManifestVerifier] quarantine cap eviction track=${pending.identity.trackName} group=${pending.identity.groupId} object=${pending.identity.objectId} disposition=${this.#config.mode === 'enforce' ? 'drop' : 'fail-open'}`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Stop waiting for a manifest that never arrived. In `enforce` the object is
|
|
434
|
+
* discarded: an eviction is a rejection, not a deferred play, so unverified
|
|
435
|
+
* media never reaches the player two groups after the stall was recorded
|
|
436
|
+
* (BLO-30095, CTO disposition on the issue thread).
|
|
437
|
+
*
|
|
438
|
+
* Deliberately NOT used by `#failOpenGroup`/`#failOpenTrack` — failing open on
|
|
439
|
+
* a genuine verifier fault is correct and stays untouched.
|
|
440
|
+
*/
|
|
441
|
+
#giveUpOnPending(pending) {
|
|
442
|
+
if (this.#config.mode !== 'enforce') {
|
|
400
443
|
pending.release();
|
|
401
|
-
|
|
402
|
-
console.warn(`[ManifestVerifier] quarantine cap eviction fail-open track=${pending.identity.trackName} group=${pending.identity.groupId} object=${pending.identity.objectId}`);
|
|
444
|
+
return;
|
|
403
445
|
}
|
|
446
|
+
pending.discard?.();
|
|
404
447
|
}
|
|
405
448
|
#failOpenTrack(track, reason) {
|
|
406
449
|
for (const pending of [...track.quarantine]) {
|
package/dist/verifier.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockcast/mmt-manifest-verify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Canonical live MMT source-auth manifest verifier",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"src"
|
|
16
|
+
"src",
|
|
17
|
+
"!src/**/*.test.ts",
|
|
18
|
+
"!src/**/*.spec.ts",
|
|
19
|
+
"!src/**/__tests__",
|
|
20
|
+
"!dist/**/*.test.*",
|
|
21
|
+
"!dist/**/*.spec.*"
|
|
17
22
|
],
|
|
18
23
|
"scripts": {
|
|
19
24
|
"build": "tsc",
|
package/src/verifier.ts
CHANGED
|
@@ -62,7 +62,16 @@ export interface ManifestTrackContext {
|
|
|
62
62
|
|
|
63
63
|
export interface ManifestVerificationStats {
|
|
64
64
|
verified: number
|
|
65
|
+
/** Terminal outcomes only: an object counted here will never be verified. */
|
|
65
66
|
failures: Record<ManifestFailureReason, number>
|
|
67
|
+
/**
|
|
68
|
+
* Objects currently held in quarantine awaiting a manifest — pending, NOT
|
|
69
|
+
* failed, and deliberately disjoint from `failures`. An enforce-mode stall is
|
|
70
|
+
* accounted here first and moves into `failures` only once the verifier gives
|
|
71
|
+
* up on it, so a reason breakdown that ignores this gauge under-reports live
|
|
72
|
+
* stalls by whatever is still in flight (BLO-30007).
|
|
73
|
+
*/
|
|
74
|
+
quarantined: number
|
|
66
75
|
quarantinedBytes: number
|
|
67
76
|
}
|
|
68
77
|
|
|
@@ -106,6 +115,7 @@ interface PendingObject {
|
|
|
106
115
|
identity: ManifestObjectIdentity
|
|
107
116
|
data: Uint8Array
|
|
108
117
|
release: () => void
|
|
118
|
+
discard?: () => void
|
|
109
119
|
bytes: number
|
|
110
120
|
}
|
|
111
121
|
|
|
@@ -155,7 +165,7 @@ export class ManifestVerifier {
|
|
|
155
165
|
readonly #verifySignature: SignatureVerifier
|
|
156
166
|
readonly #onFailure?: (failure: ManifestFailure) => void
|
|
157
167
|
readonly #tracks = new Map<string, TrackState>()
|
|
158
|
-
readonly #stats: ManifestVerificationStats = {
|
|
168
|
+
readonly #stats: Omit<ManifestVerificationStats, 'quarantined'> = {
|
|
159
169
|
verified: 0,
|
|
160
170
|
failures: Object.fromEntries(FAILURE_REASONS.map((reason) => [reason, 0])) as Record<ManifestFailureReason, number>,
|
|
161
171
|
quarantinedBytes: 0,
|
|
@@ -177,9 +187,12 @@ export class ManifestVerifier {
|
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
get stats(): ManifestVerificationStats {
|
|
190
|
+
let quarantined = 0
|
|
191
|
+
for (const track of this.#tracks.values()) quarantined += track.quarantine.length
|
|
180
192
|
return {
|
|
181
193
|
verified: this.#stats.verified,
|
|
182
194
|
failures: { ...this.#stats.failures },
|
|
195
|
+
quarantined,
|
|
183
196
|
quarantinedBytes: this.#stats.quarantinedBytes,
|
|
184
197
|
}
|
|
185
198
|
}
|
|
@@ -269,6 +282,15 @@ export class ManifestVerifier {
|
|
|
269
282
|
identity: ManifestObjectIdentity,
|
|
270
283
|
data: Uint8Array,
|
|
271
284
|
release: () => void,
|
|
285
|
+
/**
|
|
286
|
+
* Called instead of `release` when a stalled object is terminally rejected
|
|
287
|
+
* rather than played. A caller that drives a sequence off `release` (the FEC
|
|
288
|
+
* symbol loop in `mmtp-router` does) must pass this, or an enforce-mode
|
|
289
|
+
* discard leaves the sequence waiting on a callback that will never fire.
|
|
290
|
+
* A `drop` returned from this call is the synchronous form of the same
|
|
291
|
+
* outcome and does NOT also invoke `discard`.
|
|
292
|
+
*/
|
|
293
|
+
discard?: () => void,
|
|
272
294
|
): ManifestAdmission {
|
|
273
295
|
if (this.#config.mode === 'off') {
|
|
274
296
|
release()
|
|
@@ -289,13 +311,13 @@ export class ManifestVerifier {
|
|
|
289
311
|
return this.#rejectOrShadow(identity, release, group.failed)
|
|
290
312
|
}
|
|
291
313
|
const entry = group.entries.get(identity.objectId)
|
|
292
|
-
if (entry) return this.#admitAgainstEntry(track, group, identity, data, release, entry)
|
|
314
|
+
if (entry) return this.#admitAgainstEntry(track, group, identity, data, release, entry, discard)
|
|
293
315
|
if (this.#config.mode === 'shadow' || this.#config.onMissingManifest === 'fallback-shadow') {
|
|
294
316
|
release()
|
|
295
317
|
this.#failure(identity, 'manifestAbsent')
|
|
296
318
|
return { action: 'play', verified: false, reason: 'manifestAbsent' }
|
|
297
319
|
}
|
|
298
|
-
if (!this.#quarantine(track, group, { identity, data, release, bytes: data.byteLength })) {
|
|
320
|
+
if (!this.#quarantine(track, group, { identity, data, release, discard, bytes: data.byteLength })) {
|
|
299
321
|
return { action: 'drop', verified: false }
|
|
300
322
|
}
|
|
301
323
|
return { action: 'stall', verified: false }
|
|
@@ -330,8 +352,13 @@ export class ManifestVerifier {
|
|
|
330
352
|
const [oldestId, oldestGroup] = oldest
|
|
331
353
|
for (const pending of [...oldestGroup.pending.values()]) {
|
|
332
354
|
this.#removePending(track, oldestGroup, pending)
|
|
333
|
-
pending
|
|
334
|
-
|
|
355
|
+
this.#giveUpOnPending(pending)
|
|
356
|
+
// The group aged out with objects still waiting on a manifest that
|
|
357
|
+
// never arrived. That is an absent manifest, not a verifier fault:
|
|
358
|
+
// `verifierError` is reserved for an exception/crash in the verifier
|
|
359
|
+
// itself, so mislabelling here reads on the graduation dashboard as a
|
|
360
|
+
// software bug and hides a benign absent-manifest stall (BLO-30007).
|
|
361
|
+
this.#failure(pending.identity, 'manifestAbsent')
|
|
335
362
|
}
|
|
336
363
|
track.manifestEntries -= oldestGroup.entries.size
|
|
337
364
|
track.groups.delete(oldestId)
|
|
@@ -352,6 +379,7 @@ export class ManifestVerifier {
|
|
|
352
379
|
data: Uint8Array,
|
|
353
380
|
release: () => void,
|
|
354
381
|
entry: SourceAuthObjectEntry,
|
|
382
|
+
discard?: () => void,
|
|
355
383
|
): ManifestAdmission {
|
|
356
384
|
if (entry.trueLength !== data.byteLength) {
|
|
357
385
|
return this.#rejectOrShadow(identity, release, 'digestMismatch')
|
|
@@ -363,7 +391,7 @@ export class ManifestVerifier {
|
|
|
363
391
|
release()
|
|
364
392
|
return { action: 'play', verified: false }
|
|
365
393
|
}
|
|
366
|
-
if (!this.#quarantine(track, group, { identity, data, release, bytes: data.byteLength })) {
|
|
394
|
+
if (!this.#quarantine(track, group, { identity, data, release, discard, bytes: data.byteLength })) {
|
|
367
395
|
return { action: 'drop', verified: false }
|
|
368
396
|
}
|
|
369
397
|
return { action: 'stall', verified: false }
|
|
@@ -394,7 +422,7 @@ export class ManifestVerifier {
|
|
|
394
422
|
entry: SourceAuthObjectEntry,
|
|
395
423
|
): void {
|
|
396
424
|
this.#removePending(track, group, pending)
|
|
397
|
-
this.#admitAgainstEntry(track, group, pending.identity, pending.data, pending.release, entry)
|
|
425
|
+
this.#admitAgainstEntry(track, group, pending.identity, pending.data, pending.release, entry, pending.discard)
|
|
398
426
|
}
|
|
399
427
|
|
|
400
428
|
#closeGroup(
|
|
@@ -532,7 +560,12 @@ export class ManifestVerifier {
|
|
|
532
560
|
}
|
|
533
561
|
for (const pending of [...group.pending.values()]) {
|
|
534
562
|
this.#removePending(track, group, pending)
|
|
535
|
-
|
|
563
|
+
// Same contract as an eviction: a quarantined object that is rejected
|
|
564
|
+
// rather than played must still tell the caller it is finished, or a
|
|
565
|
+
// caller sequencing off `release` waits forever (BLO-30095).
|
|
566
|
+
if (this.#rejectOrShadow(pending.identity, pending.release, reason).action === 'drop') {
|
|
567
|
+
pending.discard?.()
|
|
568
|
+
}
|
|
536
569
|
}
|
|
537
570
|
}
|
|
538
571
|
|
|
@@ -563,10 +596,31 @@ export class ManifestVerifier {
|
|
|
563
596
|
if (group) group.pending.delete(pending.identity.objectId)
|
|
564
597
|
track.quarantinedBytes -= pending.bytes
|
|
565
598
|
this.#stats.quarantinedBytes -= pending.bytes
|
|
599
|
+
this.#giveUpOnPending(pending)
|
|
600
|
+
// Quarantine budget ran out while the object was still waiting on a
|
|
601
|
+
// manifest. The manifest was absent when we gave up; the verifier did not
|
|
602
|
+
// fault. Same reason in shadow and enforce so the dashboard reads one
|
|
603
|
+
// taxonomy across modes (BLO-30007).
|
|
604
|
+
this.#failure(pending.identity, 'manifestAbsent')
|
|
605
|
+
console.warn(`[ManifestVerifier] quarantine cap eviction track=${pending.identity.trackName} group=${pending.identity.groupId} object=${pending.identity.objectId} disposition=${this.#config.mode === 'enforce' ? 'drop' : 'fail-open'}`)
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Stop waiting for a manifest that never arrived. In `enforce` the object is
|
|
611
|
+
* discarded: an eviction is a rejection, not a deferred play, so unverified
|
|
612
|
+
* media never reaches the player two groups after the stall was recorded
|
|
613
|
+
* (BLO-30095, CTO disposition on the issue thread).
|
|
614
|
+
*
|
|
615
|
+
* Deliberately NOT used by `#failOpenGroup`/`#failOpenTrack` — failing open on
|
|
616
|
+
* a genuine verifier fault is correct and stays untouched.
|
|
617
|
+
*/
|
|
618
|
+
#giveUpOnPending(pending: PendingObject): void {
|
|
619
|
+
if (this.#config.mode !== 'enforce') {
|
|
566
620
|
pending.release()
|
|
567
|
-
|
|
568
|
-
console.warn(`[ManifestVerifier] quarantine cap eviction fail-open track=${pending.identity.trackName} group=${pending.identity.groupId} object=${pending.identity.objectId}`)
|
|
621
|
+
return
|
|
569
622
|
}
|
|
623
|
+
pending.discard?.()
|
|
570
624
|
}
|
|
571
625
|
|
|
572
626
|
#failOpenTrack(track: TrackState, reason: 'verifierError'): void {
|
package/src/verifier.test.ts
DELETED
|
@@ -1,509 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
encodeSourceAuthGroupClose,
|
|
4
|
-
encodeSourceAuthObjectEntry,
|
|
5
|
-
ManifestVerifier,
|
|
6
|
-
createWebCryptoEd25519Verifier,
|
|
7
|
-
manifestBindingId,
|
|
8
|
-
sourceAuthMerkleRoot,
|
|
9
|
-
sourceAuthObjectDigest,
|
|
10
|
-
sourceAuthSignaturePreimage,
|
|
11
|
-
} from './index.js'
|
|
12
|
-
|
|
13
|
-
const mapper = {
|
|
14
|
-
d: 1,
|
|
15
|
-
derive(groupId: number, objectId: number) {
|
|
16
|
-
return { ssId: groupId * 4 + objectId }
|
|
17
|
-
},
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function createVerifier(options?: {
|
|
21
|
-
mode?: 'off' | 'shadow' | 'enforce'
|
|
22
|
-
onMissingManifest?: 'stall' | 'fallback-shadow'
|
|
23
|
-
signatureValid?: boolean
|
|
24
|
-
bitrate?: number
|
|
25
|
-
authenticated?: boolean
|
|
26
|
-
}) {
|
|
27
|
-
const failures = vi.fn()
|
|
28
|
-
const verifier = new ManifestVerifier({
|
|
29
|
-
manifestAuth: {
|
|
30
|
-
mode: options?.mode ?? 'enforce',
|
|
31
|
-
onMissingManifest: options?.onMissingManifest ?? 'stall',
|
|
32
|
-
},
|
|
33
|
-
verifySignature: () => options?.signatureValid ?? true,
|
|
34
|
-
onFailure: failures,
|
|
35
|
-
})
|
|
36
|
-
verifier.registerTrack({
|
|
37
|
-
broadcastNamespaceId: 'broadcast-1',
|
|
38
|
-
trackName: 'video',
|
|
39
|
-
keyEpoch: 7,
|
|
40
|
-
codec: 'avc1.640033',
|
|
41
|
-
timing: '30/1',
|
|
42
|
-
fecGeometry: 'K=4,T=1200,D=1',
|
|
43
|
-
manifestFormatVersion: 1,
|
|
44
|
-
authScope: new Uint8Array(32).fill(1),
|
|
45
|
-
publicKey: new Uint8Array(32).fill(2),
|
|
46
|
-
bitrate: options?.bitrate ?? 80_000,
|
|
47
|
-
groupDurationMs: 1000,
|
|
48
|
-
mapper,
|
|
49
|
-
manifestChannelAuthenticated: options?.authenticated ?? true,
|
|
50
|
-
})
|
|
51
|
-
return { verifier, failures }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function entry(groupId: number, objectId: number, data: Uint8Array) {
|
|
55
|
-
return {
|
|
56
|
-
groupId: BigInt(groupId),
|
|
57
|
-
objectId,
|
|
58
|
-
trueLength: data.byteLength,
|
|
59
|
-
digest: sourceAuthObjectDigest(data),
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function ingestEntry(verifier: ManifestVerifier, value: ReturnType<typeof entry>): void {
|
|
64
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthObjectEntry(value))
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function closeGroup(
|
|
68
|
-
verifier: ManifestVerifier,
|
|
69
|
-
groupId: number,
|
|
70
|
-
entries: ReturnType<typeof entry>[],
|
|
71
|
-
): void {
|
|
72
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthGroupClose({
|
|
73
|
-
groupId: BigInt(groupId),
|
|
74
|
-
objectCount: entries.length,
|
|
75
|
-
root: sourceAuthMerkleRoot(entries),
|
|
76
|
-
signature: new Uint8Array(64).fill(3),
|
|
77
|
-
}))
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
describe('ManifestVerifier', () => {
|
|
81
|
-
test('supports async WebCrypto Ed25519 verification', async () => {
|
|
82
|
-
const verify = createWebCryptoEd25519Verifier()
|
|
83
|
-
const publicKey = Uint8Array.from(Buffer.from(
|
|
84
|
-
'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
|
|
85
|
-
'hex',
|
|
86
|
-
))
|
|
87
|
-
const signature = Uint8Array.from(Buffer.from(
|
|
88
|
-
'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155' +
|
|
89
|
-
'5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b',
|
|
90
|
-
'hex',
|
|
91
|
-
))
|
|
92
|
-
|
|
93
|
-
await expect(verify(publicKey, new Uint8Array(), signature)).resolves.toBe(true)
|
|
94
|
-
signature[0] ^= 1
|
|
95
|
-
await expect(verify(publicKey, new Uint8Array(), signature)).resolves.toBe(false)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
test('reports exact failures for a mutated root, signature, and wrong WebCrypto key', async () => {
|
|
99
|
-
const subtle = globalThis.crypto.subtle
|
|
100
|
-
const publicKey = Uint8Array.from(Buffer.from(
|
|
101
|
-
'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
|
|
102
|
-
'hex',
|
|
103
|
-
))
|
|
104
|
-
const privateKey = await subtle.importKey(
|
|
105
|
-
'pkcs8',
|
|
106
|
-
Uint8Array.from(Buffer.from(
|
|
107
|
-
'302e020100300506032b657004220420' +
|
|
108
|
-
'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
|
|
109
|
-
'hex',
|
|
110
|
-
)).buffer,
|
|
111
|
-
'Ed25519',
|
|
112
|
-
false,
|
|
113
|
-
['sign'],
|
|
114
|
-
)
|
|
115
|
-
const authScope = new Uint8Array(32).fill(1)
|
|
116
|
-
const data = new Uint8Array([1, 2, 3])
|
|
117
|
-
const manifestEntry = entry(12, 0, data)
|
|
118
|
-
const root = sourceAuthMerkleRoot([manifestEntry])
|
|
119
|
-
const signature = new Uint8Array(await subtle.sign(
|
|
120
|
-
'Ed25519',
|
|
121
|
-
privateKey,
|
|
122
|
-
sourceAuthSignaturePreimage(authScope, 12n, 1, root),
|
|
123
|
-
))
|
|
124
|
-
|
|
125
|
-
const failureFor = async (options: {
|
|
126
|
-
root?: Uint8Array
|
|
127
|
-
signature?: Uint8Array
|
|
128
|
-
publicKey?: Uint8Array
|
|
129
|
-
}): Promise<string | undefined> => {
|
|
130
|
-
const failures = vi.fn()
|
|
131
|
-
const verifier = new ManifestVerifier({
|
|
132
|
-
manifestAuth: { mode: 'enforce', onMissingManifest: 'stall' },
|
|
133
|
-
verifySignature: createWebCryptoEd25519Verifier(subtle),
|
|
134
|
-
onFailure: failures,
|
|
135
|
-
})
|
|
136
|
-
verifier.registerTrack({
|
|
137
|
-
broadcastNamespaceId: 'broadcast-1', trackName: 'video', keyEpoch: 1,
|
|
138
|
-
codec: 'avc1', timing: '30/1', fecGeometry: 'K=4', manifestFormatVersion: 1,
|
|
139
|
-
authScope, publicKey: options.publicKey ?? publicKey, bitrate: 80_000,
|
|
140
|
-
groupDurationMs: 1000, mapper, manifestChannelAuthenticated: false,
|
|
141
|
-
})
|
|
142
|
-
ingestEntry(verifier, manifestEntry)
|
|
143
|
-
verifier.admitObject(
|
|
144
|
-
{ trackName: 'video', groupId: 12, objectId: 0, ssId: 48 },
|
|
145
|
-
data,
|
|
146
|
-
vi.fn(),
|
|
147
|
-
)
|
|
148
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthGroupClose({
|
|
149
|
-
groupId: 12n,
|
|
150
|
-
objectCount: 1,
|
|
151
|
-
root: options.root ?? root,
|
|
152
|
-
signature: options.signature ?? signature,
|
|
153
|
-
}))
|
|
154
|
-
for (let attempt = 0; attempt < 20 && failures.mock.calls.length === 0; attempt++) {
|
|
155
|
-
await new Promise((resolve) => setTimeout(resolve, 5))
|
|
156
|
-
}
|
|
157
|
-
return failures.mock.calls.at(-1)?.[0]?.reason as string | undefined
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const mutatedRoot = root.slice()
|
|
161
|
-
mutatedRoot[0] ^= 1
|
|
162
|
-
await expect(failureFor({ root: mutatedRoot })).resolves.toBe('digestMismatch')
|
|
163
|
-
const mutatedSignature = signature.slice()
|
|
164
|
-
mutatedSignature[0] ^= 1
|
|
165
|
-
await expect(failureFor({ signature: mutatedSignature })).resolves.toBe('sigInvalid')
|
|
166
|
-
const wrongKey = Uint8Array.from(Buffer.from(
|
|
167
|
-
'3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c',
|
|
168
|
-
'hex',
|
|
169
|
-
))
|
|
170
|
-
await expect(failureFor({ publicKey: wrongKey })).resolves.toBe('sigInvalid')
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
test('accepts a previous rotation key only while it is advertised', async () => {
|
|
174
|
-
const previousKey = new Uint8Array(32).fill(7)
|
|
175
|
-
const currentKey = new Uint8Array(32).fill(8)
|
|
176
|
-
const verifySignature = (key: Uint8Array): boolean => key[0] === 7
|
|
177
|
-
|
|
178
|
-
const verifyWith = async (acceptedPublicKeys: readonly Uint8Array[]): Promise<string> => {
|
|
179
|
-
const verifier = new ManifestVerifier({
|
|
180
|
-
manifestAuth: { mode: 'enforce', onMissingManifest: 'stall' },
|
|
181
|
-
verifySignature,
|
|
182
|
-
})
|
|
183
|
-
verifier.registerTrack({
|
|
184
|
-
broadcastNamespaceId: 'broadcast-1', trackName: 'video', keyEpoch: 1,
|
|
185
|
-
codec: 'avc1', timing: '30/1', fecGeometry: 'K=4', manifestFormatVersion: 1,
|
|
186
|
-
authScope: new Uint8Array(32), publicKey: currentKey, acceptedPublicKeys,
|
|
187
|
-
bitrate: 80_000, groupDurationMs: 1000, mapper, manifestChannelAuthenticated: false,
|
|
188
|
-
})
|
|
189
|
-
const data = new Uint8Array([4])
|
|
190
|
-
const manifestEntry = entry(13, 0, data)
|
|
191
|
-
ingestEntry(verifier, manifestEntry)
|
|
192
|
-
const release = vi.fn()
|
|
193
|
-
verifier.admitObject(
|
|
194
|
-
{ trackName: 'video', groupId: 13, objectId: 0, ssId: 52 },
|
|
195
|
-
data,
|
|
196
|
-
release,
|
|
197
|
-
)
|
|
198
|
-
closeGroup(verifier, 13, [manifestEntry])
|
|
199
|
-
await Promise.resolve()
|
|
200
|
-
return release.mock.calls.length === 1 ? 'accepted' : 'rejected'
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
await expect(verifyWith([currentKey, previousKey])).resolves.toBe('accepted')
|
|
204
|
-
await expect(verifyWith([currentKey])).resolves.toBe('rejected')
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
test('keeps source-symbol bindings independent for one media track', () => {
|
|
208
|
-
const verifier = new ManifestVerifier({
|
|
209
|
-
manifestAuth: { mode: 'enforce', onMissingManifest: 'stall' },
|
|
210
|
-
verifySignature: () => true,
|
|
211
|
-
})
|
|
212
|
-
for (const sourceSymbolFormat of ['full-mmtp-packet', 'fec-padded-recovery']) {
|
|
213
|
-
verifier.registerTrack({
|
|
214
|
-
broadcastNamespaceId: 'broadcast-1',
|
|
215
|
-
trackName: 'video',
|
|
216
|
-
bindingId: manifestBindingId('video', sourceSymbolFormat),
|
|
217
|
-
sourceSymbolFormat,
|
|
218
|
-
keyEpoch: 1,
|
|
219
|
-
codec: 'avc1',
|
|
220
|
-
timing: '30/1',
|
|
221
|
-
fecGeometry: 'K=4',
|
|
222
|
-
manifestFormatVersion: 1,
|
|
223
|
-
authScope: new Uint8Array(32),
|
|
224
|
-
publicKey: new Uint8Array(32),
|
|
225
|
-
bitrate: 80_000,
|
|
226
|
-
groupDurationMs: 1000,
|
|
227
|
-
mapper,
|
|
228
|
-
manifestChannelAuthenticated: true,
|
|
229
|
-
})
|
|
230
|
-
}
|
|
231
|
-
const direct = new Uint8Array([1])
|
|
232
|
-
const recovered = new Uint8Array([2])
|
|
233
|
-
const directBinding = manifestBindingId('video', 'full-mmtp-packet')
|
|
234
|
-
const recoveredBinding = manifestBindingId('video', 'fec-padded-recovery')
|
|
235
|
-
verifier.ingestManifestFrame(directBinding, encodeSourceAuthObjectEntry(entry(0, 0, direct)))
|
|
236
|
-
verifier.ingestManifestFrame(recoveredBinding, encodeSourceAuthObjectEntry(entry(0, 0, recovered)))
|
|
237
|
-
|
|
238
|
-
expect(verifier.admitObject(
|
|
239
|
-
{ trackName: 'video', bindingId: directBinding, groupId: 0, objectId: 0, ssId: 0 },
|
|
240
|
-
direct,
|
|
241
|
-
vi.fn(),
|
|
242
|
-
)).toMatchObject({ action: 'play', verified: true })
|
|
243
|
-
expect(verifier.admitObject(
|
|
244
|
-
{ trackName: 'video', bindingId: recoveredBinding, groupId: 0, objectId: 0, ssId: 0 },
|
|
245
|
-
recovered,
|
|
246
|
-
vi.fn(),
|
|
247
|
-
)).toMatchObject({ action: 'play', verified: true })
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
test('holds quarantine until an async signature result resolves', async () => {
|
|
251
|
-
let resolveSignature!: (valid: boolean) => void
|
|
252
|
-
const verifier = new ManifestVerifier({
|
|
253
|
-
manifestAuth: { mode: 'enforce', onMissingManifest: 'stall' },
|
|
254
|
-
verifySignature: () => new Promise<boolean>((resolve) => { resolveSignature = resolve }),
|
|
255
|
-
})
|
|
256
|
-
verifier.registerTrack({
|
|
257
|
-
broadcastNamespaceId: 'broadcast-1', trackName: 'video', keyEpoch: 1,
|
|
258
|
-
codec: 'avc1', timing: '30/1', fecGeometry: 'K=4', manifestFormatVersion: 1,
|
|
259
|
-
authScope: new Uint8Array(32), publicKey: new Uint8Array(32), bitrate: 80_000,
|
|
260
|
-
groupDurationMs: 1000, mapper, manifestChannelAuthenticated: false,
|
|
261
|
-
})
|
|
262
|
-
const data = new Uint8Array([1])
|
|
263
|
-
const manifestEntry = entry(0, 0, data)
|
|
264
|
-
ingestEntry(verifier, manifestEntry)
|
|
265
|
-
const release = vi.fn()
|
|
266
|
-
verifier.admitObject({ trackName: 'video', groupId: 0, objectId: 0, ssId: 0 }, data, release)
|
|
267
|
-
closeGroup(verifier, 0, [manifestEntry])
|
|
268
|
-
expect(release).not.toHaveBeenCalled()
|
|
269
|
-
|
|
270
|
-
resolveSignature(true)
|
|
271
|
-
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
272
|
-
expect(release).toHaveBeenCalledOnce()
|
|
273
|
-
expect(verifier.stats.verified).toBe(1)
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
test('supports off, shadow, and enforce modes', () => {
|
|
277
|
-
const data = new Uint8Array([1, 2, 3])
|
|
278
|
-
const identity = { trackName: 'video', groupId: 1, objectId: 0, ssId: 4 }
|
|
279
|
-
|
|
280
|
-
const off = createVerifier({ mode: 'off' }).verifier
|
|
281
|
-
const offRelease = vi.fn()
|
|
282
|
-
expect(off.admitObject(identity, data, offRelease)).toMatchObject({ action: 'play' })
|
|
283
|
-
expect(offRelease).toHaveBeenCalledOnce()
|
|
284
|
-
|
|
285
|
-
const shadow = createVerifier({ mode: 'shadow' }).verifier
|
|
286
|
-
const shadowRelease = vi.fn()
|
|
287
|
-
expect(shadow.admitObject(identity, data, shadowRelease)).toMatchObject({
|
|
288
|
-
action: 'play',
|
|
289
|
-
reason: 'manifestAbsent',
|
|
290
|
-
})
|
|
291
|
-
expect(shadowRelease).toHaveBeenCalledOnce()
|
|
292
|
-
|
|
293
|
-
const enforce = createVerifier().verifier
|
|
294
|
-
const enforceRelease = vi.fn()
|
|
295
|
-
expect(enforce.admitObject(identity, data, enforceRelease)).toMatchObject({ action: 'stall' })
|
|
296
|
-
expect(enforceRelease).not.toHaveBeenCalled()
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
test('releases a late matching entry and drops only a digest mismatch', () => {
|
|
300
|
-
const { verifier, failures } = createVerifier()
|
|
301
|
-
const data = new Uint8Array([4, 5, 6])
|
|
302
|
-
const release = vi.fn()
|
|
303
|
-
verifier.admitObject({ trackName: 'video', groupId: 2, objectId: 1, ssId: 9 }, data, release)
|
|
304
|
-
ingestEntry(verifier, entry(2, 1, data))
|
|
305
|
-
expect(release).toHaveBeenCalledOnce()
|
|
306
|
-
expect(verifier.stats.verified).toBe(1)
|
|
307
|
-
expect(failures).toHaveBeenCalledWith(expect.objectContaining({ reason: 'manifestLate' }))
|
|
308
|
-
|
|
309
|
-
const badRelease = vi.fn()
|
|
310
|
-
ingestEntry(verifier, entry(2, 2, new Uint8Array([9])))
|
|
311
|
-
expect(verifier.admitObject(
|
|
312
|
-
{ trackName: 'video', groupId: 2, objectId: 2, ssId: 10 },
|
|
313
|
-
new Uint8Array([8]),
|
|
314
|
-
badRelease,
|
|
315
|
-
)).toMatchObject({ action: 'drop', reason: 'digestMismatch' })
|
|
316
|
-
expect(badRelease).not.toHaveBeenCalled()
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
test('verifies one close per group and rejects quarantined media on a bad signature', () => {
|
|
320
|
-
const { verifier } = createVerifier({ authenticated: false, signatureValid: false })
|
|
321
|
-
const data = new Uint8Array([7, 8])
|
|
322
|
-
const manifestEntry = entry(3, 0, data)
|
|
323
|
-
ingestEntry(verifier, manifestEntry)
|
|
324
|
-
const release = vi.fn()
|
|
325
|
-
expect(verifier.admitObject(
|
|
326
|
-
{ trackName: 'video', groupId: 3, objectId: 0, ssId: 12 },
|
|
327
|
-
data,
|
|
328
|
-
release,
|
|
329
|
-
).action).toBe('stall')
|
|
330
|
-
closeGroup(verifier, 3, [manifestEntry])
|
|
331
|
-
expect(release).not.toHaveBeenCalled()
|
|
332
|
-
expect(verifier.stats.failures.sigInvalid).toBe(1)
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
test('fails open on quarantine cap eviction and verifier exceptions', () => {
|
|
336
|
-
const capped = createVerifier({ bitrate: 8 }).verifier
|
|
337
|
-
const capRelease = vi.fn()
|
|
338
|
-
capped.admitObject(
|
|
339
|
-
{ trackName: 'video', groupId: 4, objectId: 0, ssId: 16 },
|
|
340
|
-
new Uint8Array(2),
|
|
341
|
-
capRelease,
|
|
342
|
-
)
|
|
343
|
-
expect(capRelease).toHaveBeenCalledOnce()
|
|
344
|
-
expect(capped.stats.failures.verifierError).toBe(1)
|
|
345
|
-
|
|
346
|
-
const release = vi.fn()
|
|
347
|
-
const verifier = new ManifestVerifier({
|
|
348
|
-
manifestAuth: { mode: 'enforce', onMissingManifest: 'stall' },
|
|
349
|
-
verifySignature: () => { throw new Error('WASM unavailable') },
|
|
350
|
-
})
|
|
351
|
-
verifier.registerTrack({
|
|
352
|
-
broadcastNamespaceId: 'broadcast-1', trackName: 'video', keyEpoch: 1,
|
|
353
|
-
codec: 'avc1', timing: '30/1', fecGeometry: 'K=4', manifestFormatVersion: 1,
|
|
354
|
-
authScope: new Uint8Array(32), publicKey: new Uint8Array(32), bitrate: 80_000,
|
|
355
|
-
groupDurationMs: 1000, mapper, manifestChannelAuthenticated: false,
|
|
356
|
-
})
|
|
357
|
-
const data = new Uint8Array([1])
|
|
358
|
-
const manifestEntry = entry(5, 0, data)
|
|
359
|
-
ingestEntry(verifier, manifestEntry)
|
|
360
|
-
verifier.admitObject({ trackName: 'video', groupId: 5, objectId: 0, ssId: 20 }, data, release)
|
|
361
|
-
closeGroup(verifier, 5, [manifestEntry])
|
|
362
|
-
expect(release).toHaveBeenCalledOnce()
|
|
363
|
-
expect(verifier.stats.failures.verifierError).toBe(1)
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
test('switches enforce to shadow live and releases quarantine', () => {
|
|
367
|
-
const { verifier } = createVerifier()
|
|
368
|
-
const release = vi.fn()
|
|
369
|
-
verifier.admitObject(
|
|
370
|
-
{ trackName: 'video', groupId: 6, objectId: 0, ssId: 24 },
|
|
371
|
-
new Uint8Array([1]),
|
|
372
|
-
release,
|
|
373
|
-
)
|
|
374
|
-
verifier.setMode('shadow')
|
|
375
|
-
expect(release).toHaveBeenCalledOnce()
|
|
376
|
-
expect(verifier.config.mode).toBe('shadow')
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
test('does not release quarantine for malformed or incomplete manifest frames', () => {
|
|
380
|
-
const { verifier } = createVerifier()
|
|
381
|
-
const release = vi.fn()
|
|
382
|
-
verifier.admitObject(
|
|
383
|
-
{ trackName: 'video', groupId: 7, objectId: 0, ssId: 28 },
|
|
384
|
-
new Uint8Array([1]),
|
|
385
|
-
release,
|
|
386
|
-
)
|
|
387
|
-
verifier.ingestManifestFrame('video', new Uint8Array([0xff]))
|
|
388
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthGroupClose({
|
|
389
|
-
groupId: 7n,
|
|
390
|
-
objectCount: 1,
|
|
391
|
-
root: new Uint8Array(32),
|
|
392
|
-
signature: new Uint8Array(64),
|
|
393
|
-
}))
|
|
394
|
-
expect(release).not.toHaveBeenCalled()
|
|
395
|
-
expect(verifier.stats.failures.verifierError).toBe(1)
|
|
396
|
-
expect(verifier.stats.failures.manifestAbsent).toBe(1)
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
test('rejects entries appended after a verified close', () => {
|
|
400
|
-
const { verifier } = createVerifier({ authenticated: false })
|
|
401
|
-
const first = entry(8, 0, new Uint8Array([1]))
|
|
402
|
-
ingestEntry(verifier, first)
|
|
403
|
-
closeGroup(verifier, 8, [first])
|
|
404
|
-
|
|
405
|
-
ingestEntry(verifier, entry(8, 1, new Uint8Array([2])))
|
|
406
|
-
const release = vi.fn()
|
|
407
|
-
expect(verifier.admitObject(
|
|
408
|
-
{ trackName: 'video', groupId: 8, objectId: 1, ssId: 33 },
|
|
409
|
-
new Uint8Array([2]),
|
|
410
|
-
release,
|
|
411
|
-
).action).toBe('stall')
|
|
412
|
-
expect(release).not.toHaveBeenCalled()
|
|
413
|
-
expect(verifier.stats.failures.verifierError).toBe(1)
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
test('requires exact authenticated object length', () => {
|
|
417
|
-
const { verifier } = createVerifier()
|
|
418
|
-
ingestEntry(verifier, entry(9, 0, new Uint8Array([1])))
|
|
419
|
-
const release = vi.fn()
|
|
420
|
-
expect(verifier.admitObject(
|
|
421
|
-
{ trackName: 'video', groupId: 9, objectId: 0, ssId: 36 },
|
|
422
|
-
new Uint8Array([1, 2]),
|
|
423
|
-
release,
|
|
424
|
-
)).toMatchObject({ action: 'drop', reason: 'digestMismatch' })
|
|
425
|
-
expect(release).not.toHaveBeenCalled()
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
test('keeps first arrival on duplicate pending object identity', () => {
|
|
429
|
-
const { verifier } = createVerifier()
|
|
430
|
-
const firstRelease = vi.fn()
|
|
431
|
-
const duplicateRelease = vi.fn()
|
|
432
|
-
const identity = { trackName: 'video', groupId: 10, objectId: 0, ssId: 40 }
|
|
433
|
-
verifier.admitObject(identity, new Uint8Array([1]), firstRelease)
|
|
434
|
-
verifier.admitObject(identity, new Uint8Array([1]), duplicateRelease)
|
|
435
|
-
expect(verifier.stats.quarantinedBytes).toBe(1)
|
|
436
|
-
ingestEntry(verifier, entry(10, 0, new Uint8Array([1])))
|
|
437
|
-
expect(firstRelease).toHaveBeenCalledOnce()
|
|
438
|
-
expect(duplicateRelease).not.toHaveBeenCalled()
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
test('re-attempts group close when entries complete after a reordered close frame', () => {
|
|
442
|
-
const { verifier } = createVerifier({ authenticated: false })
|
|
443
|
-
const dataA = new Uint8Array([1, 2])
|
|
444
|
-
const dataB = new Uint8Array([3])
|
|
445
|
-
const entryA = entry(11, 0, dataA)
|
|
446
|
-
const entryB = entry(11, 1, dataB)
|
|
447
|
-
|
|
448
|
-
// Manifest-channel reorder: the close frame beats every object entry.
|
|
449
|
-
closeGroup(verifier, 11, [entryA, entryB])
|
|
450
|
-
expect(verifier.stats.failures.manifestAbsent).toBe(1)
|
|
451
|
-
|
|
452
|
-
const release = vi.fn()
|
|
453
|
-
expect(verifier.admitObject(
|
|
454
|
-
{ trackName: 'video', groupId: 11, objectId: 0, ssId: 44 },
|
|
455
|
-
dataA,
|
|
456
|
-
release,
|
|
457
|
-
).action).toBe('stall')
|
|
458
|
-
|
|
459
|
-
// Before the last entry arrives the object stays quarantined, not played.
|
|
460
|
-
ingestEntry(verifier, entryA)
|
|
461
|
-
expect(release).not.toHaveBeenCalled()
|
|
462
|
-
expect(verifier.stats.verified).toBe(0)
|
|
463
|
-
|
|
464
|
-
// Final entry completes the group: the stashed close is re-attempted and
|
|
465
|
-
// the quarantined object is released verified.
|
|
466
|
-
ingestEntry(verifier, entryB)
|
|
467
|
-
expect(release).toHaveBeenCalledOnce()
|
|
468
|
-
expect(verifier.stats.verified).toBe(1)
|
|
469
|
-
|
|
470
|
-
const directRelease = vi.fn()
|
|
471
|
-
expect(verifier.admitObject(
|
|
472
|
-
{ trackName: 'video', groupId: 11, objectId: 1, ssId: 45 },
|
|
473
|
-
dataB,
|
|
474
|
-
directRelease,
|
|
475
|
-
)).toMatchObject({ action: 'play', verified: true })
|
|
476
|
-
expect(directRelease).toHaveBeenCalledOnce()
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
test('verifies a group whose id exceeds Number.MAX_SAFE_INTEGER (u62 group ids)', () => {
|
|
480
|
-
const { verifier, failures } = createVerifier()
|
|
481
|
-
const groupId = 72623859790382856n
|
|
482
|
-
expect(Number.isSafeInteger(Number(groupId))).toBe(false)
|
|
483
|
-
|
|
484
|
-
const data = new Uint8Array([9, 8, 7])
|
|
485
|
-
const bigEntry = {
|
|
486
|
-
groupId,
|
|
487
|
-
objectId: 0,
|
|
488
|
-
trueLength: data.byteLength,
|
|
489
|
-
digest: sourceAuthObjectDigest(data),
|
|
490
|
-
}
|
|
491
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthObjectEntry(bigEntry))
|
|
492
|
-
verifier.ingestManifestFrame('video', encodeSourceAuthGroupClose({
|
|
493
|
-
groupId,
|
|
494
|
-
objectCount: 1,
|
|
495
|
-
root: sourceAuthMerkleRoot([bigEntry]),
|
|
496
|
-
signature: new Uint8Array(64).fill(3),
|
|
497
|
-
}))
|
|
498
|
-
|
|
499
|
-
const release = vi.fn()
|
|
500
|
-
expect(verifier.admitObject(
|
|
501
|
-
{ trackName: 'video', groupId, objectId: 0 },
|
|
502
|
-
data,
|
|
503
|
-
release,
|
|
504
|
-
)).toMatchObject({ action: 'play', verified: true })
|
|
505
|
-
expect(release).toHaveBeenCalledOnce()
|
|
506
|
-
expect(verifier.stats.verified).toBe(1)
|
|
507
|
-
expect(failures).not.toHaveBeenCalled()
|
|
508
|
-
})
|
|
509
|
-
})
|