livekit-client 1.13.0 → 1.13.2
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/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +122 -105
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +172 -109
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts +4 -3
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/KeyProvider.d.ts +7 -6
- package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
- package/dist/src/e2ee/events.d.ts +34 -0
- package/dist/src/e2ee/events.d.ts.map +1 -0
- package/dist/src/e2ee/index.d.ts +1 -0
- package/dist/src/e2ee/index.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +17 -33
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +15 -12
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +2 -1
- package/dist/src/room/track/processor/types.d.ts.map +1 -1
- package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +4 -3
- package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +7 -6
- package/dist/ts4.2/src/e2ee/events.d.ts +34 -0
- package/dist/ts4.2/src/e2ee/index.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/types.d.ts +17 -33
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +15 -12
- package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/ts4.2/src/room/track/processor/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/e2ee/E2eeManager.ts +105 -77
- package/src/e2ee/KeyProvider.ts +23 -13
- package/src/e2ee/events.ts +48 -0
- package/src/e2ee/index.ts +1 -0
- package/src/e2ee/types.ts +19 -41
- package/src/e2ee/worker/FrameCryptor.ts +51 -43
- package/src/e2ee/worker/ParticipantKeyHandler.ts +25 -27
- package/src/e2ee/worker/e2ee.worker.ts +61 -68
- package/src/room/PCTransport.ts +12 -2
- package/src/room/RTCEngine.ts +0 -1
- package/src/room/Room.ts +20 -15
- package/src/room/participant/LocalParticipant.ts +5 -1
- package/src/room/track/LocalTrack.ts +18 -10
- package/src/room/track/facingMode.ts +1 -1
- package/src/room/track/processor/types.ts +2 -1
@@ -392,6 +392,26 @@ class CryptorError extends LivekitError {
|
|
392
392
|
}
|
393
393
|
}
|
394
394
|
|
395
|
+
var KeyProviderEvent;
|
396
|
+
(function (KeyProviderEvent) {
|
397
|
+
KeyProviderEvent["SetKey"] = "setKey";
|
398
|
+
KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
|
399
|
+
KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
|
400
|
+
})(KeyProviderEvent || (KeyProviderEvent = {}));
|
401
|
+
var KeyHandlerEvent;
|
402
|
+
(function (KeyHandlerEvent) {
|
403
|
+
KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
|
404
|
+
})(KeyHandlerEvent || (KeyHandlerEvent = {}));
|
405
|
+
var EncryptionEvent;
|
406
|
+
(function (EncryptionEvent) {
|
407
|
+
EncryptionEvent["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
|
408
|
+
EncryptionEvent["EncryptionError"] = "encryptionError";
|
409
|
+
})(EncryptionEvent || (EncryptionEvent = {}));
|
410
|
+
var CryptorEvent;
|
411
|
+
(function (CryptorEvent) {
|
412
|
+
CryptorEvent["Error"] = "cryptorError";
|
413
|
+
})(CryptorEvent || (CryptorEvent = {}));
|
414
|
+
|
395
415
|
var events = {exports: {}};
|
396
416
|
|
397
417
|
var R = typeof Reflect === 'object' ? Reflect : null;
|
@@ -773,10 +793,6 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
|
773
793
|
}
|
774
794
|
var eventsExports = events.exports;
|
775
795
|
|
776
|
-
const CryptorEvent = {
|
777
|
-
Error: 'cryptorError'
|
778
|
-
};
|
779
|
-
|
780
796
|
var AudioPresets;
|
781
797
|
(function (AudioPresets) {
|
782
798
|
AudioPresets.telephone = {
|
@@ -903,6 +919,7 @@ class SifGuard {
|
|
903
919
|
}
|
904
920
|
}
|
905
921
|
|
922
|
+
const encryptionEnabledMap = new Map();
|
906
923
|
class BaseFrameCryptor extends eventsExports.EventEmitter {
|
907
924
|
encodeFunction(encodedFrame, controller) {
|
908
925
|
throw Error('not implemented for subclass');
|
@@ -921,7 +938,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
921
938
|
super();
|
922
939
|
this.sendCounts = new Map();
|
923
940
|
this.keys = opts.keys;
|
924
|
-
this.
|
941
|
+
this.participantIdentity = opts.participantIdentity;
|
925
942
|
this.rtpMap = new Map();
|
926
943
|
this.keyProviderOptions = opts.keyProviderOptions;
|
927
944
|
this.sifTrailer = (_a = opts.sifTrailer) !== null && _a !== void 0 ? _a : Uint8Array.from([]);
|
@@ -934,15 +951,22 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
934
951
|
* @param keys
|
935
952
|
*/
|
936
953
|
setParticipant(id, keys) {
|
937
|
-
this.
|
954
|
+
this.participantIdentity = id;
|
938
955
|
this.keys = keys;
|
939
956
|
this.sifGuard.reset();
|
940
957
|
}
|
941
958
|
unsetParticipant() {
|
942
|
-
this.
|
959
|
+
this.participantIdentity = undefined;
|
960
|
+
}
|
961
|
+
isEnabled() {
|
962
|
+
if (this.participantIdentity) {
|
963
|
+
return encryptionEnabledMap.get(this.participantIdentity);
|
964
|
+
} else {
|
965
|
+
return undefined;
|
966
|
+
}
|
943
967
|
}
|
944
|
-
|
945
|
-
return this.
|
968
|
+
getParticipantIdentity() {
|
969
|
+
return this.participantIdentity;
|
946
970
|
}
|
947
971
|
getTrackId() {
|
948
972
|
return this.trackId;
|
@@ -974,10 +998,13 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
974
998
|
});
|
975
999
|
readable.pipeThrough(transformStream).pipeTo(writable).catch(e => {
|
976
1000
|
workerLogger.warn(e);
|
977
|
-
this.emit(
|
1001
|
+
this.emit(CryptorEvent.Error, e instanceof CryptorError ? e : new CryptorError(e.message));
|
978
1002
|
});
|
979
1003
|
this.trackId = trackId;
|
980
1004
|
}
|
1005
|
+
setSifTrailer(trailer) {
|
1006
|
+
this.sifTrailer = trailer;
|
1007
|
+
}
|
981
1008
|
/**
|
982
1009
|
* Function that will be injected in a stream and will encrypt the given encoded frames.
|
983
1010
|
*
|
@@ -1003,14 +1030,18 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1003
1030
|
encodeFunction(encodedFrame, controller) {
|
1004
1031
|
var _a;
|
1005
1032
|
return __awaiter(this, void 0, void 0, function* () {
|
1006
|
-
if (!this.
|
1033
|
+
if (!this.isEnabled() ||
|
1007
1034
|
// skip for encryption for empty dtx frames
|
1008
1035
|
encodedFrame.data.byteLength === 0) {
|
1009
1036
|
return controller.enqueue(encodedFrame);
|
1010
1037
|
}
|
1038
|
+
const keySet = this.keys.getKeySet();
|
1039
|
+
if (!keySet) {
|
1040
|
+
throw new TypeError("key set not found for ".concat(this.participantIdentity, " at index ").concat(this.keys.getCurrentKeyIndex()));
|
1041
|
+
}
|
1011
1042
|
const {
|
1012
1043
|
encryptionKey
|
1013
|
-
} =
|
1044
|
+
} = keySet;
|
1014
1045
|
const keyIndex = this.keys.getCurrentKeyIndex();
|
1015
1046
|
if (encryptionKey) {
|
1016
1047
|
const iv = this.makeIV((_a = encodedFrame.getMetadata().synchronizationSource) !== null && _a !== void 0 ? _a : -1, encodedFrame.timestamp);
|
@@ -1058,7 +1089,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1058
1089
|
*/
|
1059
1090
|
decodeFunction(encodedFrame, controller) {
|
1060
1091
|
return __awaiter(this, void 0, void 0, function* () {
|
1061
|
-
if (!this.
|
1092
|
+
if (!this.isEnabled() ||
|
1062
1093
|
// skip for decryption for empty dtx frames
|
1063
1094
|
encodedFrame.data.byteLength === 0) {
|
1064
1095
|
this.sifGuard.recordUserFrame();
|
@@ -1087,8 +1118,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1087
1118
|
} catch (error) {
|
1088
1119
|
if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {
|
1089
1120
|
if (this.keys.hasValidKey) {
|
1090
|
-
|
1091
|
-
this.emit(CryptorEvent.Error, new CryptorError("invalid key for participant ".concat(this.participantId), CryptorErrorReason.InvalidKey));
|
1121
|
+
this.emit(CryptorEvent.Error, error);
|
1092
1122
|
this.keys.decryptionFailure();
|
1093
1123
|
}
|
1094
1124
|
} else {
|
@@ -1100,7 +1130,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1100
1130
|
} else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
|
1101
1131
|
// emit an error in case the key index is out of bounds but the key handler thinks we still have a valid key
|
1102
1132
|
workerLogger.warn('skipping decryption due to missing key at index');
|
1103
|
-
this.emit(CryptorEvent.Error, new CryptorError("missing key at index for participant ".concat(this.
|
1133
|
+
this.emit(CryptorEvent.Error, new CryptorError("missing key at index for participant ".concat(this.participantIdentity), CryptorErrorReason.MissingKey));
|
1104
1134
|
}
|
1105
1135
|
});
|
1106
1136
|
}
|
@@ -1116,6 +1146,9 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1116
1146
|
var _a;
|
1117
1147
|
return __awaiter(this, void 0, void 0, function* () {
|
1118
1148
|
const keySet = this.keys.getKeySet(keyIndex);
|
1149
|
+
if (!ratchetOpts.encryptionKey && !keySet) {
|
1150
|
+
throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));
|
1151
|
+
}
|
1119
1152
|
// Construct frame trailer. Similar to the frame header described in
|
1120
1153
|
// https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
|
1121
1154
|
// but we put it at the end.
|
@@ -1173,11 +1206,11 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1173
1206
|
workerLogger.debug('resetting to initial material');
|
1174
1207
|
this.keys.setKeyFromMaterial(initialMaterial.material, keyIndex);
|
1175
1208
|
}
|
1176
|
-
workerLogger.warn('maximum ratchet attempts exceeded
|
1177
|
-
throw new CryptorError("valid key missing for participant ".concat(this.
|
1209
|
+
workerLogger.warn('maximum ratchet attempts exceeded');
|
1210
|
+
throw new CryptorError("valid key missing for participant ".concat(this.participantIdentity), CryptorErrorReason.InvalidKey);
|
1178
1211
|
}
|
1179
1212
|
} else {
|
1180
|
-
throw new CryptorError(
|
1213
|
+
throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
|
1181
1214
|
}
|
1182
1215
|
}
|
1183
1216
|
});
|
@@ -1265,9 +1298,6 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1265
1298
|
const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
|
1266
1299
|
return codec;
|
1267
1300
|
}
|
1268
|
-
setSifTrailer(trailer) {
|
1269
|
-
this.sifTrailer = trailer;
|
1270
|
-
}
|
1271
1301
|
}
|
1272
1302
|
/**
|
1273
1303
|
* Slice the NALUs present in the supplied buffer, assuming it is already byte-aligned
|
@@ -1370,28 +1400,24 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1370
1400
|
get hasValidKey() {
|
1371
1401
|
return this._hasValidKey;
|
1372
1402
|
}
|
1373
|
-
constructor(
|
1403
|
+
constructor(participantIdentity, keyProviderOptions) {
|
1374
1404
|
super();
|
1375
1405
|
this.decryptionFailureCount = 0;
|
1376
1406
|
this._hasValidKey = true;
|
1377
1407
|
this.currentKeyIndex = 0;
|
1378
|
-
this.cryptoKeyRing = new Array(KEYRING_SIZE);
|
1379
|
-
this.enabled = isEnabled;
|
1408
|
+
this.cryptoKeyRing = new Array(KEYRING_SIZE).fill(undefined);
|
1380
1409
|
this.keyProviderOptions = keyProviderOptions;
|
1381
1410
|
this.ratchetPromiseMap = new Map();
|
1382
|
-
this.
|
1411
|
+
this.participantIdentity = participantIdentity;
|
1383
1412
|
this.resetKeyStatus();
|
1384
1413
|
}
|
1385
|
-
setEnabled(enabled) {
|
1386
|
-
this.enabled = enabled;
|
1387
|
-
}
|
1388
1414
|
decryptionFailure() {
|
1389
1415
|
if (this.keyProviderOptions.failureTolerance < 0) {
|
1390
1416
|
return;
|
1391
1417
|
}
|
1392
1418
|
this.decryptionFailureCount += 1;
|
1393
1419
|
if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {
|
1394
|
-
workerLogger.warn("key for ".concat(this.
|
1420
|
+
workerLogger.warn("key for ".concat(this.participantIdentity, " is being marked as invalid"));
|
1395
1421
|
this._hasValidKey = false;
|
1396
1422
|
}
|
1397
1423
|
}
|
@@ -1415,19 +1441,23 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1415
1441
|
*/
|
1416
1442
|
ratchetKey(keyIndex) {
|
1417
1443
|
let setKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
1418
|
-
const currentKeyIndex = keyIndex !== null && keyIndex !== void 0 ? keyIndex :
|
1444
|
+
const currentKeyIndex = keyIndex !== null && keyIndex !== void 0 ? keyIndex : this.getCurrentKeyIndex();
|
1419
1445
|
const existingPromise = this.ratchetPromiseMap.get(currentKeyIndex);
|
1420
1446
|
if (typeof existingPromise !== 'undefined') {
|
1421
1447
|
return existingPromise;
|
1422
1448
|
}
|
1423
1449
|
const ratchetPromise = new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
1424
1450
|
try {
|
1425
|
-
const
|
1451
|
+
const keySet = this.getKeySet(currentKeyIndex);
|
1452
|
+
if (!keySet) {
|
1453
|
+
throw new TypeError("Cannot ratchet key without a valid keyset of participant ".concat(this.participantIdentity));
|
1454
|
+
}
|
1455
|
+
const currentMaterial = keySet.material;
|
1426
1456
|
const newMaterial = yield importKey(yield ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt), currentMaterial.algorithm.name, 'derive');
|
1427
1457
|
if (setKey) {
|
1428
1458
|
this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
|
1459
|
+
this.emit(KeyHandlerEvent.KeyRatcheted, newMaterial, this.participantIdentity, currentKeyIndex);
|
1429
1460
|
}
|
1430
|
-
this.emit('keyRatcheted', newMaterial, keyIndex, this.participantId);
|
1431
1461
|
resolve(newMaterial);
|
1432
1462
|
} catch (e) {
|
1433
1463
|
reject(e);
|
@@ -1471,12 +1501,10 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1471
1501
|
}
|
1472
1502
|
setKeySet(keySet, keyIndex) {
|
1473
1503
|
let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
}
|
1479
|
-
});
|
1504
|
+
this.cryptoKeyRing[keyIndex % this.cryptoKeyRing.length] = keySet;
|
1505
|
+
if (emitRatchetEvent) {
|
1506
|
+
this.emit(KeyHandlerEvent.KeyRatcheted, keySet.material, this.participantIdentity, keyIndex);
|
1507
|
+
}
|
1480
1508
|
}
|
1481
1509
|
setCurrentKeyIndex(index) {
|
1482
1510
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -1484,9 +1512,6 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1484
1512
|
this.resetKeyStatus();
|
1485
1513
|
});
|
1486
1514
|
}
|
1487
|
-
isEnabled() {
|
1488
|
-
return this.enabled;
|
1489
|
-
}
|
1490
1515
|
getCurrentKeyIndex() {
|
1491
1516
|
return this.currentKeyIndex;
|
1492
1517
|
}
|
@@ -1502,8 +1527,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1502
1527
|
|
1503
1528
|
const participantCryptors = [];
|
1504
1529
|
const participantKeys = new Map();
|
1505
|
-
let
|
1506
|
-
let publisherKeys;
|
1530
|
+
let sharedKeyHandler;
|
1507
1531
|
let isEncryptionEnabled = false;
|
1508
1532
|
let useSharedKey = false;
|
1509
1533
|
let sharedKey;
|
@@ -1521,36 +1545,35 @@ onmessage = ev => {
|
|
1521
1545
|
keyProviderOptions = data.keyProviderOptions;
|
1522
1546
|
useSharedKey = !!data.keyProviderOptions.sharedKey;
|
1523
1547
|
// acknowledge init successful
|
1524
|
-
const
|
1525
|
-
kind: '
|
1548
|
+
const ackMsg = {
|
1549
|
+
kind: 'initAck',
|
1526
1550
|
data: {
|
1527
1551
|
enabled: isEncryptionEnabled
|
1528
1552
|
}
|
1529
1553
|
};
|
1530
|
-
|
1531
|
-
publisherKeys.on('keyRatcheted', emitRatchetedKeys);
|
1532
|
-
postMessage(enableMsg);
|
1554
|
+
postMessage(ackMsg);
|
1533
1555
|
break;
|
1534
1556
|
case 'enable':
|
1535
|
-
setEncryptionEnabled(data.enabled, data.
|
1557
|
+
setEncryptionEnabled(data.enabled, data.participantIdentity);
|
1536
1558
|
workerLogger.info('updated e2ee enabled status');
|
1537
1559
|
// acknowledge enable call successful
|
1538
1560
|
postMessage(ev.data);
|
1539
1561
|
break;
|
1540
1562
|
case 'decode':
|
1541
|
-
let cryptor = getTrackCryptor(data.
|
1563
|
+
let cryptor = getTrackCryptor(data.participantIdentity, data.trackId);
|
1542
1564
|
cryptor.setupTransform(kind, data.readableStream, data.writableStream, data.trackId, data.codec);
|
1543
1565
|
break;
|
1544
1566
|
case 'encode':
|
1545
|
-
let pubCryptor =
|
1567
|
+
let pubCryptor = getTrackCryptor(data.participantIdentity, data.trackId);
|
1546
1568
|
pubCryptor.setupTransform(kind, data.readableStream, data.writableStream, data.trackId, data.codec);
|
1547
1569
|
break;
|
1548
1570
|
case 'setKey':
|
1549
1571
|
if (useSharedKey) {
|
1550
|
-
workerLogger.
|
1572
|
+
workerLogger.warn('set shared key');
|
1551
1573
|
setSharedKey(data.key, data.keyIndex);
|
1552
|
-
} else if (data.
|
1553
|
-
|
1574
|
+
} else if (data.participantIdentity) {
|
1575
|
+
workerLogger.warn("set participant sender key ".concat(data.participantIdentity));
|
1576
|
+
getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);
|
1554
1577
|
} else {
|
1555
1578
|
workerLogger.error('no participant Id was provided and shared key usage is disabled');
|
1556
1579
|
}
|
@@ -1559,11 +1582,14 @@ onmessage = ev => {
|
|
1559
1582
|
unsetCryptorParticipant(data.trackId);
|
1560
1583
|
break;
|
1561
1584
|
case 'updateCodec':
|
1562
|
-
getTrackCryptor(data.
|
1585
|
+
getTrackCryptor(data.participantIdentity, data.trackId).setVideoCodec(data.codec);
|
1563
1586
|
break;
|
1564
1587
|
case 'setRTPMap':
|
1565
|
-
|
1566
|
-
|
1588
|
+
// this is only used for the local participant
|
1589
|
+
participantCryptors.forEach(cr => {
|
1590
|
+
if (cr.getParticipantIdentity() === data.participantIdentity) {
|
1591
|
+
cr.setRtpMap(data.map);
|
1592
|
+
}
|
1567
1593
|
});
|
1568
1594
|
break;
|
1569
1595
|
case 'ratchetRequest':
|
@@ -1576,86 +1602,77 @@ onmessage = ev => {
|
|
1576
1602
|
};
|
1577
1603
|
function handleRatchetRequest(data) {
|
1578
1604
|
return __awaiter(this, void 0, void 0, function* () {
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1605
|
+
if (useSharedKey) {
|
1606
|
+
const keyHandler = getSharedKeyHandler();
|
1607
|
+
yield keyHandler.ratchetKey(data.keyIndex);
|
1608
|
+
keyHandler.resetKeyStatus();
|
1609
|
+
} else if (data.participantIdentity) {
|
1610
|
+
const keyHandler = getParticipantKeyHandler(data.participantIdentity);
|
1611
|
+
yield keyHandler.ratchetKey(data.keyIndex);
|
1612
|
+
keyHandler.resetKeyStatus();
|
1613
|
+
} else {
|
1614
|
+
workerLogger.error('no participant Id was provided for ratchet request and shared key usage is disabled');
|
1615
|
+
}
|
1582
1616
|
});
|
1583
1617
|
}
|
1584
|
-
function getTrackCryptor(
|
1618
|
+
function getTrackCryptor(participantIdentity, trackId) {
|
1585
1619
|
let cryptor = participantCryptors.find(c => c.getTrackId() === trackId);
|
1586
1620
|
if (!cryptor) {
|
1587
1621
|
workerLogger.info('creating new cryptor for', {
|
1588
|
-
|
1622
|
+
participantIdentity
|
1589
1623
|
});
|
1590
1624
|
if (!keyProviderOptions) {
|
1591
1625
|
throw Error('Missing keyProvider options');
|
1592
1626
|
}
|
1593
1627
|
cryptor = new FrameCryptor({
|
1594
|
-
|
1595
|
-
keys: getParticipantKeyHandler(
|
1628
|
+
participantIdentity,
|
1629
|
+
keys: getParticipantKeyHandler(participantIdentity),
|
1596
1630
|
keyProviderOptions,
|
1597
1631
|
sifTrailer
|
1598
1632
|
});
|
1599
1633
|
setupCryptorErrorEvents(cryptor);
|
1600
1634
|
participantCryptors.push(cryptor);
|
1601
|
-
} else if (
|
1635
|
+
} else if (participantIdentity !== cryptor.getParticipantIdentity()) {
|
1602
1636
|
// assign new participant id to track cryptor and pass in correct key handler
|
1603
|
-
cryptor.setParticipant(
|
1637
|
+
cryptor.setParticipant(participantIdentity, getParticipantKeyHandler(participantIdentity));
|
1604
1638
|
}
|
1605
1639
|
return cryptor;
|
1606
1640
|
}
|
1607
|
-
function getParticipantKeyHandler(
|
1608
|
-
if (
|
1609
|
-
return
|
1641
|
+
function getParticipantKeyHandler(participantIdentity) {
|
1642
|
+
if (useSharedKey) {
|
1643
|
+
return getSharedKeyHandler();
|
1610
1644
|
}
|
1611
|
-
let keys = participantKeys.get(
|
1645
|
+
let keys = participantKeys.get(participantIdentity);
|
1612
1646
|
if (!keys) {
|
1613
|
-
keys = new ParticipantKeyHandler(
|
1647
|
+
keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);
|
1614
1648
|
if (sharedKey) {
|
1615
1649
|
keys.setKey(sharedKey);
|
1616
1650
|
}
|
1617
|
-
|
1651
|
+
keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);
|
1652
|
+
participantKeys.set(participantIdentity, keys);
|
1618
1653
|
}
|
1619
1654
|
return keys;
|
1620
1655
|
}
|
1656
|
+
function getSharedKeyHandler() {
|
1657
|
+
if (!sharedKeyHandler) {
|
1658
|
+
sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);
|
1659
|
+
}
|
1660
|
+
return sharedKeyHandler;
|
1661
|
+
}
|
1621
1662
|
function unsetCryptorParticipant(trackId) {
|
1622
1663
|
var _a;
|
1623
1664
|
(_a = participantCryptors.find(c => c.getTrackId() === trackId)) === null || _a === void 0 ? void 0 : _a.unsetParticipant();
|
1624
1665
|
}
|
1625
|
-
function
|
1626
|
-
|
1627
|
-
if (!publishCryptor) {
|
1628
|
-
if (!keyProviderOptions) {
|
1629
|
-
throw new TypeError('Missing keyProvider options');
|
1630
|
-
}
|
1631
|
-
publishCryptor = new FrameCryptor({
|
1632
|
-
keys: publisherKeys,
|
1633
|
-
participantId: 'publisher',
|
1634
|
-
keyProviderOptions
|
1635
|
-
});
|
1636
|
-
setupCryptorErrorEvents(publishCryptor);
|
1637
|
-
publishCryptors.push(publishCryptor);
|
1638
|
-
}
|
1639
|
-
return publishCryptor;
|
1640
|
-
}
|
1641
|
-
function setEncryptionEnabled(enable, participantId) {
|
1642
|
-
if (!participantId) {
|
1643
|
-
isEncryptionEnabled = enable;
|
1644
|
-
publisherKeys.setEnabled(enable);
|
1645
|
-
} else {
|
1646
|
-
getParticipantKeyHandler(participantId).setEnabled(enable);
|
1647
|
-
}
|
1666
|
+
function setEncryptionEnabled(enable, participantIdentity) {
|
1667
|
+
encryptionEnabledMap.set(participantIdentity, enable);
|
1648
1668
|
}
|
1649
1669
|
function setSharedKey(key, index) {
|
1650
1670
|
workerLogger.debug('setting shared key');
|
1651
1671
|
sharedKey = key;
|
1652
|
-
|
1653
|
-
for (const [, keyHandler] of participantKeys) {
|
1654
|
-
keyHandler.setKey(key, index);
|
1655
|
-
}
|
1672
|
+
getSharedKeyHandler().setKey(key, index);
|
1656
1673
|
}
|
1657
1674
|
function setupCryptorErrorEvents(cryptor) {
|
1658
|
-
cryptor.on(
|
1675
|
+
cryptor.on(CryptorEvent.Error, error => {
|
1659
1676
|
const msg = {
|
1660
1677
|
kind: 'error',
|
1661
1678
|
data: {
|
@@ -1665,11 +1682,11 @@ function setupCryptorErrorEvents(cryptor) {
|
|
1665
1682
|
postMessage(msg);
|
1666
1683
|
});
|
1667
1684
|
}
|
1668
|
-
function emitRatchetedKeys(material, keyIndex) {
|
1685
|
+
function emitRatchetedKeys(material, participantIdentity, keyIndex) {
|
1669
1686
|
const msg = {
|
1670
1687
|
kind: "ratchetKey",
|
1671
1688
|
data: {
|
1672
|
-
|
1689
|
+
participantIdentity,
|
1673
1690
|
keyIndex,
|
1674
1691
|
material
|
1675
1692
|
}
|
@@ -1693,11 +1710,11 @@ if (self.RTCTransformEvent) {
|
|
1693
1710
|
transformer.handled = true;
|
1694
1711
|
const {
|
1695
1712
|
kind,
|
1696
|
-
|
1713
|
+
participantIdentity,
|
1697
1714
|
trackId,
|
1698
1715
|
codec
|
1699
1716
|
} = transformer.options;
|
1700
|
-
const cryptor =
|
1717
|
+
const cryptor = getTrackCryptor(participantIdentity, trackId);
|
1701
1718
|
workerLogger.debug('transform', {
|
1702
1719
|
codec
|
1703
1720
|
});
|