@blockcast/mmt-manifest-verify 0.1.0 → 0.1.1
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 +12 -3
- package/dist/verifier.d.ts.map +1 -1
- package/dist/verifier.js +90 -17
- package/dist/verifier.js.map +1 -1
- package/package.json +1 -1
- package/src/verifier.test.ts +204 -2
- package/src/verifier.ts +115 -20
package/dist/verifier.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export interface ManifestAuthConfig {
|
|
|
7
7
|
}
|
|
8
8
|
export interface ManifestObjectIdentity {
|
|
9
9
|
trackName: string;
|
|
10
|
+
/** Stable v2 auth binding. Defaults to trackName for legacy single-format callers. */
|
|
11
|
+
bindingId?: string;
|
|
10
12
|
/** MoQ group ids are u62; values above 2^53 must be passed as bigint. */
|
|
11
13
|
groupId: number | bigint;
|
|
12
14
|
objectId: number;
|
|
@@ -22,6 +24,9 @@ export interface ManifestFecBlockMapper {
|
|
|
22
24
|
export interface ManifestTrackContext {
|
|
23
25
|
broadcastNamespaceId: string;
|
|
24
26
|
trackName: string;
|
|
27
|
+
/** Stable v2 auth binding. Defaults to trackName for legacy single-format callers. */
|
|
28
|
+
bindingId?: string;
|
|
29
|
+
sourceSymbolFormat?: string;
|
|
25
30
|
keyEpoch: number;
|
|
26
31
|
codec: string;
|
|
27
32
|
timing: string;
|
|
@@ -31,6 +36,8 @@ export interface ManifestTrackContext {
|
|
|
31
36
|
* timing, FEC geometry, and manifest version fields above. */
|
|
32
37
|
authScope: Uint8Array;
|
|
33
38
|
publicKey: Uint8Array;
|
|
39
|
+
/** Current key first, followed by any catalog-advertised overlap keys. */
|
|
40
|
+
acceptedPublicKeys?: readonly Uint8Array[];
|
|
34
41
|
bitrate: number;
|
|
35
42
|
groupDurationMs: number;
|
|
36
43
|
mapper: ManifestFecBlockMapper;
|
|
@@ -43,6 +50,7 @@ export interface ManifestVerificationStats {
|
|
|
43
50
|
}
|
|
44
51
|
export interface ManifestFailure {
|
|
45
52
|
trackName: string;
|
|
53
|
+
bindingId?: string;
|
|
46
54
|
groupId: number | bigint;
|
|
47
55
|
objectId: number;
|
|
48
56
|
reason: ManifestFailureReason;
|
|
@@ -52,7 +60,9 @@ export interface ManifestAdmission {
|
|
|
52
60
|
verified: boolean;
|
|
53
61
|
reason?: ManifestFailureReason;
|
|
54
62
|
}
|
|
55
|
-
type SignatureVerifier = (publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => boolean
|
|
63
|
+
export type SignatureVerifier = (publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => boolean | Promise<boolean>;
|
|
64
|
+
export declare function manifestBindingId(trackName: string, sourceSymbolFormat: string): string;
|
|
65
|
+
export declare function createWebCryptoEd25519Verifier(subtle?: SubtleCrypto): SignatureVerifier;
|
|
56
66
|
export declare class ManifestVerifier {
|
|
57
67
|
#private;
|
|
58
68
|
constructor(options: {
|
|
@@ -64,9 +74,8 @@ export declare class ManifestVerifier {
|
|
|
64
74
|
get stats(): ManifestVerificationStats;
|
|
65
75
|
setMode(mode: ManifestAuthMode): void;
|
|
66
76
|
registerTrack(context: ManifestTrackContext): void;
|
|
67
|
-
ingestManifestFrame(
|
|
77
|
+
ingestManifestFrame(bindingId: string, frameBytes: Uint8Array): void;
|
|
68
78
|
admitObject(identity: ManifestObjectIdentity, data: Uint8Array, release: () => void): ManifestAdmission;
|
|
69
79
|
dispose(): void;
|
|
70
80
|
}
|
|
71
|
-
export {};
|
|
72
81
|
//# 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,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,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,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,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,
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/verifier.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { decodeSourceAuthManifestFrame, sourceAuthMerkleRoot, sourceAuthObjectDigest, sourceAuthSignaturePreimage, } from './source-auth.js';
|
|
2
|
+
export function manifestBindingId(trackName, sourceSymbolFormat) {
|
|
3
|
+
return JSON.stringify([trackName, sourceSymbolFormat]);
|
|
4
|
+
}
|
|
5
|
+
export function createWebCryptoEd25519Verifier(subtle = globalThis.crypto.subtle) {
|
|
6
|
+
return async (publicKey, message, signature) => {
|
|
7
|
+
const keyBytes = Uint8Array.from(publicKey);
|
|
8
|
+
const messageBytes = Uint8Array.from(message);
|
|
9
|
+
const signatureBytes = Uint8Array.from(signature);
|
|
10
|
+
const key = await subtle.importKey('raw', keyBytes.buffer, 'Ed25519', false, ['verify']);
|
|
11
|
+
return subtle.verify('Ed25519', key, signatureBytes.buffer, messageBytes.buffer);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
2
14
|
const FAILURE_REASONS = [
|
|
3
15
|
'sigInvalid',
|
|
4
16
|
'digestMismatch',
|
|
@@ -14,6 +26,7 @@ const equalBytes = (left, right) => {
|
|
|
14
26
|
diff |= left[index] ^ right[index];
|
|
15
27
|
return diff === 0;
|
|
16
28
|
};
|
|
29
|
+
const isPromiseLike = (value) => typeof value === 'object' && value !== null && typeof value.then === 'function';
|
|
17
30
|
export class ManifestVerifier {
|
|
18
31
|
#config;
|
|
19
32
|
#verifySignature;
|
|
@@ -24,6 +37,7 @@ export class ManifestVerifier {
|
|
|
24
37
|
failures: Object.fromEntries(FAILURE_REASONS.map((reason) => [reason, 0])),
|
|
25
38
|
quarantinedBytes: 0,
|
|
26
39
|
};
|
|
40
|
+
#disposed = false;
|
|
27
41
|
constructor(options) {
|
|
28
42
|
this.#config = { ...options.manifestAuth };
|
|
29
43
|
this.#verifySignature = options.verifySignature;
|
|
@@ -45,8 +59,9 @@ export class ManifestVerifier {
|
|
|
45
59
|
this.#releaseAllQuarantine(false);
|
|
46
60
|
}
|
|
47
61
|
registerTrack(context) {
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
const bindingId = context.bindingId ?? context.trackName;
|
|
63
|
+
if (this.#tracks.has(bindingId)) {
|
|
64
|
+
throw new Error(`manifest binding ${bindingId} is already registered`);
|
|
50
65
|
}
|
|
51
66
|
if (!Number.isFinite(context.bitrate) || context.bitrate <= 0) {
|
|
52
67
|
throw new Error('manifest track bitrate must be > 0');
|
|
@@ -58,6 +73,10 @@ export class ManifestVerifier {
|
|
|
58
73
|
throw new Error('manifest authScope must be 32 bytes');
|
|
59
74
|
if (context.publicKey.byteLength !== 32)
|
|
60
75
|
throw new Error('manifest publicKey must be 32 bytes');
|
|
76
|
+
for (const key of context.acceptedPublicKeys ?? []) {
|
|
77
|
+
if (key.byteLength !== 32)
|
|
78
|
+
throw new Error('manifest acceptedPublicKeys must contain 32-byte keys');
|
|
79
|
+
}
|
|
61
80
|
for (const [name, value] of Object.entries({
|
|
62
81
|
broadcastNamespaceId: context.broadcastNamespaceId,
|
|
63
82
|
trackName: context.trackName,
|
|
@@ -68,8 +87,8 @@ export class ManifestVerifier {
|
|
|
68
87
|
if (value.length === 0)
|
|
69
88
|
throw new Error(`manifest ${name} must not be empty`);
|
|
70
89
|
}
|
|
71
|
-
this.#tracks.set(
|
|
72
|
-
context,
|
|
90
|
+
this.#tracks.set(bindingId, {
|
|
91
|
+
context: { ...context, bindingId },
|
|
73
92
|
groups: new Map(),
|
|
74
93
|
quarantine: [],
|
|
75
94
|
quarantinedBytes: 0,
|
|
@@ -79,23 +98,23 @@ export class ManifestVerifier {
|
|
|
79
98
|
maxGroups: context.mapper.d + 1,
|
|
80
99
|
});
|
|
81
100
|
}
|
|
82
|
-
ingestManifestFrame(
|
|
83
|
-
const track = this.#requireTrack(
|
|
101
|
+
ingestManifestFrame(bindingId, frameBytes) {
|
|
102
|
+
const track = this.#requireTrack(bindingId);
|
|
84
103
|
try {
|
|
85
104
|
const frame = decodeSourceAuthManifestFrame(frameBytes);
|
|
86
105
|
const groupId = frame.groupId;
|
|
87
106
|
const group = this.#group(track, groupId);
|
|
88
107
|
if (frame.kind === 'object') {
|
|
89
|
-
if (group.close || group.failed) {
|
|
90
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError');
|
|
108
|
+
if (group.close || group.signaturePending || group.failed) {
|
|
109
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError');
|
|
91
110
|
return;
|
|
92
111
|
}
|
|
93
112
|
if (group.entries.has(frame.objectId)) {
|
|
94
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError');
|
|
113
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError');
|
|
95
114
|
return;
|
|
96
115
|
}
|
|
97
116
|
if (group.entries.size >= 4096 || track.manifestEntries >= track.maxManifestEntries) {
|
|
98
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError');
|
|
117
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError');
|
|
99
118
|
return;
|
|
100
119
|
}
|
|
101
120
|
group.entries.set(frame.objectId, frame);
|
|
@@ -115,7 +134,7 @@ export class ManifestVerifier {
|
|
|
115
134
|
this.#closeGroup(track, groupId, group, frame);
|
|
116
135
|
}
|
|
117
136
|
catch {
|
|
118
|
-
this.#failure({ trackName, groupId: 0, objectId: 0 }, 'verifierError');
|
|
137
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId: 0, objectId: 0 }, 'verifierError');
|
|
119
138
|
}
|
|
120
139
|
}
|
|
121
140
|
admitObject(identity, data, release) {
|
|
@@ -123,7 +142,7 @@ export class ManifestVerifier {
|
|
|
123
142
|
release();
|
|
124
143
|
return { action: 'play', verified: false };
|
|
125
144
|
}
|
|
126
|
-
const track = this.#tracks.get(identity.trackName);
|
|
145
|
+
const track = this.#tracks.get(identity.bindingId ?? identity.trackName);
|
|
127
146
|
if (!track) {
|
|
128
147
|
release();
|
|
129
148
|
this.#failure(identity, 'verifierError');
|
|
@@ -157,13 +176,16 @@ export class ManifestVerifier {
|
|
|
157
176
|
}
|
|
158
177
|
}
|
|
159
178
|
dispose() {
|
|
179
|
+
if (this.#disposed)
|
|
180
|
+
return;
|
|
181
|
+
this.#disposed = true;
|
|
160
182
|
this.#releaseAllQuarantine(false);
|
|
161
183
|
this.#tracks.clear();
|
|
162
184
|
}
|
|
163
|
-
#requireTrack(
|
|
164
|
-
const track = this.#tracks.get(
|
|
185
|
+
#requireTrack(bindingId) {
|
|
186
|
+
const track = this.#tracks.get(bindingId);
|
|
165
187
|
if (!track)
|
|
166
|
-
throw new Error(`unknown manifest
|
|
188
|
+
throw new Error(`unknown manifest binding ${bindingId}`);
|
|
167
189
|
return track;
|
|
168
190
|
}
|
|
169
191
|
#group(track, groupId) {
|
|
@@ -226,7 +248,7 @@ export class ManifestVerifier {
|
|
|
226
248
|
this.#admitAgainstEntry(track, group, pending.identity, pending.data, pending.release, entry);
|
|
227
249
|
}
|
|
228
250
|
#closeGroup(track, groupId, group, close) {
|
|
229
|
-
if (group.close)
|
|
251
|
+
if (group.close || group.signaturePending)
|
|
230
252
|
return;
|
|
231
253
|
const entries = [...group.entries.values()];
|
|
232
254
|
if (entries.length !== close.objectCount) {
|
|
@@ -261,12 +283,30 @@ export class ManifestVerifier {
|
|
|
261
283
|
const preimage = sourceAuthSignaturePreimage(track.context.authScope, close.groupId, close.objectCount, close.root);
|
|
262
284
|
let signatureValid;
|
|
263
285
|
try {
|
|
264
|
-
signatureValid = this.#
|
|
286
|
+
signatureValid = this.#verifyAcceptedSignature(track, preimage, close.signature);
|
|
265
287
|
}
|
|
266
288
|
catch {
|
|
267
289
|
this.#failOpenGroup(track, groupId, group);
|
|
268
290
|
return;
|
|
269
291
|
}
|
|
292
|
+
if (isPromiseLike(signatureValid)) {
|
|
293
|
+
group.signaturePending = true;
|
|
294
|
+
void signatureValid.then((valid) => {
|
|
295
|
+
if (this.#disposed)
|
|
296
|
+
return;
|
|
297
|
+
group.signaturePending = false;
|
|
298
|
+
this.#finishGroupSignature(track, groupId, group, close, valid);
|
|
299
|
+
}, () => {
|
|
300
|
+
if (this.#disposed)
|
|
301
|
+
return;
|
|
302
|
+
group.signaturePending = false;
|
|
303
|
+
this.#failOpenGroup(track, groupId, group);
|
|
304
|
+
});
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
this.#finishGroupSignature(track, groupId, group, close, signatureValid);
|
|
308
|
+
}
|
|
309
|
+
#finishGroupSignature(track, groupId, group, close, signatureValid) {
|
|
270
310
|
if (!signatureValid) {
|
|
271
311
|
group.failed = 'sigInvalid';
|
|
272
312
|
this.#failGroup(track, groupId, group, 'sigInvalid');
|
|
@@ -287,6 +327,38 @@ export class ManifestVerifier {
|
|
|
287
327
|
}
|
|
288
328
|
}
|
|
289
329
|
}
|
|
330
|
+
#verifyAcceptedSignature(track, message, signature) {
|
|
331
|
+
const keys = track.context.acceptedPublicKeys ?? [track.context.publicKey];
|
|
332
|
+
const pending = [];
|
|
333
|
+
let hadSynchronousError = false;
|
|
334
|
+
for (const key of keys) {
|
|
335
|
+
try {
|
|
336
|
+
const result = this.#verifySignature(key, message, signature);
|
|
337
|
+
if (isPromiseLike(result)) {
|
|
338
|
+
pending.push(Promise.resolve(result).then((valid) => valid, () => 'error'));
|
|
339
|
+
}
|
|
340
|
+
else if (result) {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
hadSynchronousError = true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (pending.length === 0) {
|
|
349
|
+
if (hadSynchronousError)
|
|
350
|
+
throw new Error('manifest signature verifier unavailable');
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
return Promise.all(pending).then((results) => {
|
|
354
|
+
if (results.some((valid) => valid === true))
|
|
355
|
+
return true;
|
|
356
|
+
if (hadSynchronousError || results.some((valid) => valid === 'error')) {
|
|
357
|
+
throw new Error('manifest signature verifier unavailable');
|
|
358
|
+
}
|
|
359
|
+
return false;
|
|
360
|
+
});
|
|
361
|
+
}
|
|
290
362
|
#failGroup(track, groupId, group, reason) {
|
|
291
363
|
if (group.pending.size === 0) {
|
|
292
364
|
this.#failure({ trackName: track.context.trackName, groupId, objectId: 0 }, reason);
|
|
@@ -367,6 +439,7 @@ export class ManifestVerifier {
|
|
|
367
439
|
this.#stats.failures[reason]++;
|
|
368
440
|
this.#onFailure?.({
|
|
369
441
|
trackName: identity.trackName,
|
|
442
|
+
...(identity.bindingId === undefined ? {} : { bindingId: identity.bindingId }),
|
|
370
443
|
groupId: identity.groupId,
|
|
371
444
|
objectId: identity.objectId,
|
|
372
445
|
reason,
|
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
package/src/verifier.test.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { describe, expect, test, vi } from 'vitest'
|
|
2
|
-
import { FecBlockMapper } from '@blockcast/mmt-fec'
|
|
3
2
|
import {
|
|
4
3
|
encodeSourceAuthGroupClose,
|
|
5
4
|
encodeSourceAuthObjectEntry,
|
|
6
5
|
ManifestVerifier,
|
|
6
|
+
createWebCryptoEd25519Verifier,
|
|
7
|
+
manifestBindingId,
|
|
7
8
|
sourceAuthMerkleRoot,
|
|
8
9
|
sourceAuthObjectDigest,
|
|
10
|
+
sourceAuthSignaturePreimage,
|
|
9
11
|
} from './index.js'
|
|
10
12
|
|
|
11
|
-
const mapper =
|
|
13
|
+
const mapper = {
|
|
14
|
+
d: 1,
|
|
15
|
+
derive(groupId: number, objectId: number) {
|
|
16
|
+
return { ssId: groupId * 4 + objectId }
|
|
17
|
+
},
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
function createVerifier(options?: {
|
|
14
21
|
mode?: 'off' | 'shadow' | 'enforce'
|
|
@@ -71,6 +78,201 @@ function closeGroup(
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
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
|
+
|
|
74
276
|
test('supports off, shadow, and enforce modes', () => {
|
|
75
277
|
const data = new Uint8Array([1, 2, 3])
|
|
76
278
|
const identity = { trackName: 'video', groupId: 1, objectId: 0, ssId: 4 }
|
package/src/verifier.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface ManifestAuthConfig {
|
|
|
23
23
|
|
|
24
24
|
export interface ManifestObjectIdentity {
|
|
25
25
|
trackName: string
|
|
26
|
+
/** Stable v2 auth binding. Defaults to trackName for legacy single-format callers. */
|
|
27
|
+
bindingId?: string
|
|
26
28
|
/** MoQ group ids are u62; values above 2^53 must be passed as bigint. */
|
|
27
29
|
groupId: number | bigint
|
|
28
30
|
objectId: number
|
|
@@ -38,6 +40,9 @@ export interface ManifestFecBlockMapper {
|
|
|
38
40
|
export interface ManifestTrackContext {
|
|
39
41
|
broadcastNamespaceId: string
|
|
40
42
|
trackName: string
|
|
43
|
+
/** Stable v2 auth binding. Defaults to trackName for legacy single-format callers. */
|
|
44
|
+
bindingId?: string
|
|
45
|
+
sourceSymbolFormat?: string
|
|
41
46
|
keyEpoch: number
|
|
42
47
|
codec: string
|
|
43
48
|
timing: string
|
|
@@ -47,6 +52,8 @@ export interface ManifestTrackContext {
|
|
|
47
52
|
* timing, FEC geometry, and manifest version fields above. */
|
|
48
53
|
authScope: Uint8Array
|
|
49
54
|
publicKey: Uint8Array
|
|
55
|
+
/** Current key first, followed by any catalog-advertised overlap keys. */
|
|
56
|
+
acceptedPublicKeys?: readonly Uint8Array[]
|
|
50
57
|
bitrate: number
|
|
51
58
|
groupDurationMs: number
|
|
52
59
|
mapper: ManifestFecBlockMapper
|
|
@@ -61,6 +68,7 @@ export interface ManifestVerificationStats {
|
|
|
61
68
|
|
|
62
69
|
export interface ManifestFailure {
|
|
63
70
|
trackName: string
|
|
71
|
+
bindingId?: string
|
|
64
72
|
groupId: number | bigint
|
|
65
73
|
objectId: number
|
|
66
74
|
reason: ManifestFailureReason
|
|
@@ -72,11 +80,27 @@ export interface ManifestAdmission {
|
|
|
72
80
|
reason?: ManifestFailureReason
|
|
73
81
|
}
|
|
74
82
|
|
|
75
|
-
type SignatureVerifier = (
|
|
83
|
+
export type SignatureVerifier = (
|
|
76
84
|
publicKey: Uint8Array,
|
|
77
85
|
message: Uint8Array,
|
|
78
86
|
signature: Uint8Array,
|
|
79
|
-
) => boolean
|
|
87
|
+
) => boolean | Promise<boolean>
|
|
88
|
+
|
|
89
|
+
export function manifestBindingId(trackName: string, sourceSymbolFormat: string): string {
|
|
90
|
+
return JSON.stringify([trackName, sourceSymbolFormat])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function createWebCryptoEd25519Verifier(
|
|
94
|
+
subtle: SubtleCrypto = globalThis.crypto.subtle,
|
|
95
|
+
): SignatureVerifier {
|
|
96
|
+
return async (publicKey, message, signature) => {
|
|
97
|
+
const keyBytes = Uint8Array.from(publicKey)
|
|
98
|
+
const messageBytes = Uint8Array.from(message)
|
|
99
|
+
const signatureBytes = Uint8Array.from(signature)
|
|
100
|
+
const key = await subtle.importKey('raw', keyBytes.buffer, 'Ed25519', false, ['verify'])
|
|
101
|
+
return subtle.verify('Ed25519', key, signatureBytes.buffer, messageBytes.buffer)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
80
104
|
|
|
81
105
|
interface PendingObject {
|
|
82
106
|
identity: ManifestObjectIdentity
|
|
@@ -93,6 +117,7 @@ interface GroupState {
|
|
|
93
117
|
* reordering); retried once the entry count matches. */
|
|
94
118
|
pendingClose?: SourceAuthGroupClose
|
|
95
119
|
rootVerified: boolean
|
|
120
|
+
signaturePending?: boolean
|
|
96
121
|
failed?: ManifestFailureReason
|
|
97
122
|
}
|
|
98
123
|
|
|
@@ -122,6 +147,9 @@ const equalBytes = (left: Uint8Array, right: Uint8Array): boolean => {
|
|
|
122
147
|
return diff === 0
|
|
123
148
|
}
|
|
124
149
|
|
|
150
|
+
const isPromiseLike = (value: boolean | Promise<boolean>): value is Promise<boolean> =>
|
|
151
|
+
typeof value === 'object' && value !== null && typeof value.then === 'function'
|
|
152
|
+
|
|
125
153
|
export class ManifestVerifier {
|
|
126
154
|
#config: ManifestAuthConfig
|
|
127
155
|
readonly #verifySignature: SignatureVerifier
|
|
@@ -132,6 +160,7 @@ export class ManifestVerifier {
|
|
|
132
160
|
failures: Object.fromEntries(FAILURE_REASONS.map((reason) => [reason, 0])) as Record<ManifestFailureReason, number>,
|
|
133
161
|
quarantinedBytes: 0,
|
|
134
162
|
}
|
|
163
|
+
#disposed = false
|
|
135
164
|
|
|
136
165
|
constructor(options: {
|
|
137
166
|
manifestAuth: ManifestAuthConfig
|
|
@@ -161,8 +190,9 @@ export class ManifestVerifier {
|
|
|
161
190
|
}
|
|
162
191
|
|
|
163
192
|
registerTrack(context: ManifestTrackContext): void {
|
|
164
|
-
|
|
165
|
-
|
|
193
|
+
const bindingId = context.bindingId ?? context.trackName
|
|
194
|
+
if (this.#tracks.has(bindingId)) {
|
|
195
|
+
throw new Error(`manifest binding ${bindingId} is already registered`)
|
|
166
196
|
}
|
|
167
197
|
if (!Number.isFinite(context.bitrate) || context.bitrate <= 0) {
|
|
168
198
|
throw new Error('manifest track bitrate must be > 0')
|
|
@@ -172,6 +202,9 @@ export class ManifestVerifier {
|
|
|
172
202
|
}
|
|
173
203
|
if (context.authScope.byteLength !== 32) throw new Error('manifest authScope must be 32 bytes')
|
|
174
204
|
if (context.publicKey.byteLength !== 32) throw new Error('manifest publicKey must be 32 bytes')
|
|
205
|
+
for (const key of context.acceptedPublicKeys ?? []) {
|
|
206
|
+
if (key.byteLength !== 32) throw new Error('manifest acceptedPublicKeys must contain 32-byte keys')
|
|
207
|
+
}
|
|
175
208
|
for (const [name, value] of Object.entries({
|
|
176
209
|
broadcastNamespaceId: context.broadcastNamespaceId,
|
|
177
210
|
trackName: context.trackName,
|
|
@@ -181,8 +214,8 @@ export class ManifestVerifier {
|
|
|
181
214
|
})) {
|
|
182
215
|
if (value.length === 0) throw new Error(`manifest ${name} must not be empty`)
|
|
183
216
|
}
|
|
184
|
-
this.#tracks.set(
|
|
185
|
-
context,
|
|
217
|
+
this.#tracks.set(bindingId, {
|
|
218
|
+
context: { ...context, bindingId },
|
|
186
219
|
groups: new Map(),
|
|
187
220
|
quarantine: [],
|
|
188
221
|
quarantinedBytes: 0,
|
|
@@ -193,23 +226,23 @@ export class ManifestVerifier {
|
|
|
193
226
|
})
|
|
194
227
|
}
|
|
195
228
|
|
|
196
|
-
ingestManifestFrame(
|
|
197
|
-
const track = this.#requireTrack(
|
|
229
|
+
ingestManifestFrame(bindingId: string, frameBytes: Uint8Array): void {
|
|
230
|
+
const track = this.#requireTrack(bindingId)
|
|
198
231
|
try {
|
|
199
232
|
const frame = decodeSourceAuthManifestFrame(frameBytes)
|
|
200
233
|
const groupId = frame.groupId
|
|
201
234
|
const group = this.#group(track, groupId)
|
|
202
235
|
if (frame.kind === 'object') {
|
|
203
|
-
if (group.close || group.failed) {
|
|
204
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError')
|
|
236
|
+
if (group.close || group.signaturePending || group.failed) {
|
|
237
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError')
|
|
205
238
|
return
|
|
206
239
|
}
|
|
207
240
|
if (group.entries.has(frame.objectId)) {
|
|
208
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError')
|
|
241
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError')
|
|
209
242
|
return
|
|
210
243
|
}
|
|
211
244
|
if (group.entries.size >= 4096 || track.manifestEntries >= track.maxManifestEntries) {
|
|
212
|
-
this.#failure({ trackName, groupId, objectId: frame.objectId }, 'verifierError')
|
|
245
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId, objectId: frame.objectId }, 'verifierError')
|
|
213
246
|
return
|
|
214
247
|
}
|
|
215
248
|
group.entries.set(frame.objectId, frame)
|
|
@@ -228,7 +261,7 @@ export class ManifestVerifier {
|
|
|
228
261
|
}
|
|
229
262
|
this.#closeGroup(track, groupId, group, frame)
|
|
230
263
|
} catch {
|
|
231
|
-
this.#failure({ trackName, groupId: 0, objectId: 0 }, 'verifierError')
|
|
264
|
+
this.#failure({ trackName: track.context.trackName, bindingId, groupId: 0, objectId: 0 }, 'verifierError')
|
|
232
265
|
}
|
|
233
266
|
}
|
|
234
267
|
|
|
@@ -241,7 +274,7 @@ export class ManifestVerifier {
|
|
|
241
274
|
release()
|
|
242
275
|
return { action: 'play', verified: false }
|
|
243
276
|
}
|
|
244
|
-
const track = this.#tracks.get(identity.trackName)
|
|
277
|
+
const track = this.#tracks.get(identity.bindingId ?? identity.trackName)
|
|
245
278
|
if (!track) {
|
|
246
279
|
release()
|
|
247
280
|
this.#failure(identity, 'verifierError')
|
|
@@ -274,13 +307,15 @@ export class ManifestVerifier {
|
|
|
274
307
|
}
|
|
275
308
|
|
|
276
309
|
dispose(): void {
|
|
310
|
+
if (this.#disposed) return
|
|
311
|
+
this.#disposed = true
|
|
277
312
|
this.#releaseAllQuarantine(false)
|
|
278
313
|
this.#tracks.clear()
|
|
279
314
|
}
|
|
280
315
|
|
|
281
|
-
#requireTrack(
|
|
282
|
-
const track = this.#tracks.get(
|
|
283
|
-
if (!track) throw new Error(`unknown manifest
|
|
316
|
+
#requireTrack(bindingId: string): TrackState {
|
|
317
|
+
const track = this.#tracks.get(bindingId)
|
|
318
|
+
if (!track) throw new Error(`unknown manifest binding ${bindingId}`)
|
|
284
319
|
return track
|
|
285
320
|
}
|
|
286
321
|
|
|
@@ -368,7 +403,7 @@ export class ManifestVerifier {
|
|
|
368
403
|
group: GroupState,
|
|
369
404
|
close: SourceAuthGroupClose,
|
|
370
405
|
): void {
|
|
371
|
-
if (group.close) return
|
|
406
|
+
if (group.close || group.signaturePending) return
|
|
372
407
|
const entries = [...group.entries.values()]
|
|
373
408
|
if (entries.length !== close.objectCount) {
|
|
374
409
|
// Manifest-channel reordering: the close frame beat some object entries.
|
|
@@ -399,13 +434,39 @@ export class ManifestVerifier {
|
|
|
399
434
|
return
|
|
400
435
|
}
|
|
401
436
|
const preimage = sourceAuthSignaturePreimage(track.context.authScope, close.groupId, close.objectCount, close.root)
|
|
402
|
-
let signatureValid: boolean
|
|
437
|
+
let signatureValid: boolean | Promise<boolean>
|
|
403
438
|
try {
|
|
404
|
-
signatureValid = this.#
|
|
439
|
+
signatureValid = this.#verifyAcceptedSignature(track, preimage, close.signature)
|
|
405
440
|
} catch {
|
|
406
441
|
this.#failOpenGroup(track, groupId, group)
|
|
407
442
|
return
|
|
408
443
|
}
|
|
444
|
+
if (isPromiseLike(signatureValid)) {
|
|
445
|
+
group.signaturePending = true
|
|
446
|
+
void signatureValid.then(
|
|
447
|
+
(valid) => {
|
|
448
|
+
if (this.#disposed) return
|
|
449
|
+
group.signaturePending = false
|
|
450
|
+
this.#finishGroupSignature(track, groupId, group, close, valid)
|
|
451
|
+
},
|
|
452
|
+
() => {
|
|
453
|
+
if (this.#disposed) return
|
|
454
|
+
group.signaturePending = false
|
|
455
|
+
this.#failOpenGroup(track, groupId, group)
|
|
456
|
+
},
|
|
457
|
+
)
|
|
458
|
+
return
|
|
459
|
+
}
|
|
460
|
+
this.#finishGroupSignature(track, groupId, group, close, signatureValid)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
#finishGroupSignature(
|
|
464
|
+
track: TrackState,
|
|
465
|
+
groupId: bigint,
|
|
466
|
+
group: GroupState,
|
|
467
|
+
close: SourceAuthGroupClose,
|
|
468
|
+
signatureValid: boolean,
|
|
469
|
+
): void {
|
|
409
470
|
if (!signatureValid) {
|
|
410
471
|
group.failed = 'sigInvalid'
|
|
411
472
|
this.#failGroup(track, groupId, group, 'sigInvalid')
|
|
@@ -426,6 +487,39 @@ export class ManifestVerifier {
|
|
|
426
487
|
}
|
|
427
488
|
}
|
|
428
489
|
|
|
490
|
+
#verifyAcceptedSignature(
|
|
491
|
+
track: TrackState,
|
|
492
|
+
message: Uint8Array,
|
|
493
|
+
signature: Uint8Array,
|
|
494
|
+
): boolean | Promise<boolean> {
|
|
495
|
+
const keys = track.context.acceptedPublicKeys ?? [track.context.publicKey]
|
|
496
|
+
const pending: Promise<boolean | 'error'>[] = []
|
|
497
|
+
let hadSynchronousError = false
|
|
498
|
+
for (const key of keys) {
|
|
499
|
+
try {
|
|
500
|
+
const result = this.#verifySignature(key, message, signature)
|
|
501
|
+
if (isPromiseLike(result)) {
|
|
502
|
+
pending.push(Promise.resolve(result).then((valid) => valid, () => 'error' as const))
|
|
503
|
+
} else if (result) {
|
|
504
|
+
return true
|
|
505
|
+
}
|
|
506
|
+
} catch {
|
|
507
|
+
hadSynchronousError = true
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (pending.length === 0) {
|
|
511
|
+
if (hadSynchronousError) throw new Error('manifest signature verifier unavailable')
|
|
512
|
+
return false
|
|
513
|
+
}
|
|
514
|
+
return Promise.all(pending).then((results) => {
|
|
515
|
+
if (results.some((valid) => valid === true)) return true
|
|
516
|
+
if (hadSynchronousError || results.some((valid) => valid === 'error')) {
|
|
517
|
+
throw new Error('manifest signature verifier unavailable')
|
|
518
|
+
}
|
|
519
|
+
return false
|
|
520
|
+
})
|
|
521
|
+
}
|
|
522
|
+
|
|
429
523
|
#failGroup(
|
|
430
524
|
track: TrackState,
|
|
431
525
|
groupId: bigint,
|
|
@@ -512,6 +606,7 @@ export class ManifestVerifier {
|
|
|
512
606
|
this.#stats.failures[reason]++
|
|
513
607
|
this.#onFailure?.({
|
|
514
608
|
trackName: identity.trackName,
|
|
609
|
+
...(identity.bindingId === undefined ? {} : { bindingId: identity.bindingId }),
|
|
515
610
|
groupId: identity.groupId,
|
|
516
611
|
objectId: identity.objectId,
|
|
517
612
|
reason,
|