livekit-client 2.5.8 → 2.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -5941,10 +5941,14 @@ class FrameCryptor extends BaseFrameCryptor {
5941
5941
  }
5942
5942
  const data = new Uint8Array(encodedFrame.data);
5943
5943
  const keyIndex = data[encodedFrame.data.byteLength - 1];
5944
- if (this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
5944
+ if (this.keys.hasInvalidKeyAtIndex(keyIndex)) {
5945
+ // drop frame
5946
+ return;
5947
+ }
5948
+ if (this.keys.getKeySet(keyIndex)) {
5945
5949
  try {
5946
5950
  const decodedFrame = yield this.decryptFrame(encodedFrame, keyIndex);
5947
- this.keys.decryptionSuccess();
5951
+ this.keys.decryptionSuccess(keyIndex);
5948
5952
  if (decodedFrame) {
5949
5953
  return controller.enqueue(decodedFrame);
5950
5954
  }
@@ -5953,7 +5957,7 @@ class FrameCryptor extends BaseFrameCryptor {
5953
5957
  // emit an error if the key handler thinks we have a valid key
5954
5958
  if (this.keys.hasValidKey) {
5955
5959
  this.emit(CryptorEvent.Error, error);
5956
- this.keys.decryptionFailure();
5960
+ this.keys.decryptionFailure(keyIndex);
5957
5961
  }
5958
5962
  } else {
5959
5963
  workerLogger.warn('decoding frame failed', {
@@ -5961,11 +5965,11 @@ class FrameCryptor extends BaseFrameCryptor {
5961
5965
  });
5962
5966
  }
5963
5967
  }
5964
- } else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
5968
+ } else {
5965
5969
  // emit an error if the key index is out of bounds but the key handler thinks we still have a valid key
5966
5970
  workerLogger.warn("skipping decryption due to missing key at index ".concat(keyIndex));
5967
5971
  this.emit(CryptorEvent.Error, new CryptorError("missing key at index ".concat(keyIndex, " for participant ").concat(this.participantIdentity), CryptorErrorReason.MissingKey, this.participantIdentity));
5968
- this.keys.decryptionFailure();
5972
+ this.keys.decryptionFailure(keyIndex);
5969
5973
  }
5970
5974
  });
5971
5975
  }
@@ -6259,43 +6263,68 @@ function isFrameServerInjected(frameData, trailerBytes) {
6259
6263
  *
6260
6264
  */
6261
6265
  class ParticipantKeyHandler extends eventsExports.EventEmitter {
6266
+ /**
6267
+ * true if the current key has not been marked as invalid
6268
+ */
6262
6269
  get hasValidKey() {
6263
- return this._hasValidKey;
6270
+ return !this.hasInvalidKeyAtIndex(this.currentKeyIndex);
6264
6271
  }
6265
6272
  constructor(participantIdentity, keyProviderOptions) {
6266
6273
  super();
6267
- this.decryptionFailureCount = 0;
6268
- this._hasValidKey = true;
6269
6274
  this.currentKeyIndex = 0;
6270
6275
  if (keyProviderOptions.keyringSize < 1 || keyProviderOptions.keyringSize > 256) {
6271
6276
  throw new TypeError('Keyring size needs to be between 1 and 256');
6272
6277
  }
6273
6278
  this.cryptoKeyRing = new Array(keyProviderOptions.keyringSize).fill(undefined);
6279
+ this.decryptionFailureCounts = new Array(keyProviderOptions.keyringSize).fill(0);
6274
6280
  this.keyProviderOptions = keyProviderOptions;
6275
6281
  this.ratchetPromiseMap = new Map();
6276
6282
  this.participantIdentity = participantIdentity;
6277
- this.resetKeyStatus();
6278
6283
  }
6284
+ /**
6285
+ * Returns true if the key at the given index is marked as invalid.
6286
+ *
6287
+ * @param keyIndex the index of the key
6288
+ */
6289
+ hasInvalidKeyAtIndex(keyIndex) {
6290
+ return this.keyProviderOptions.failureTolerance >= 0 && this.decryptionFailureCounts[keyIndex] > this.keyProviderOptions.failureTolerance;
6291
+ }
6292
+ /**
6293
+ * Informs the key handler that a decryption failure occurred for an encryption key.
6294
+ * @internal
6295
+ * @param keyIndex the key index for which the failure occurred. Defaults to the current key index.
6296
+ */
6279
6297
  decryptionFailure() {
6298
+ let keyIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentKeyIndex;
6280
6299
  if (this.keyProviderOptions.failureTolerance < 0) {
6281
6300
  return;
6282
6301
  }
6283
- this.decryptionFailureCount += 1;
6284
- if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {
6285
- workerLogger.warn("key for ".concat(this.participantIdentity, " is being marked as invalid"));
6286
- this._hasValidKey = false;
6302
+ this.decryptionFailureCounts[keyIndex] += 1;
6303
+ if (this.decryptionFailureCounts[keyIndex] > this.keyProviderOptions.failureTolerance) {
6304
+ workerLogger.warn("key for ".concat(this.participantIdentity, " at index ").concat(keyIndex, " is being marked as invalid"));
6287
6305
  }
6288
6306
  }
6307
+ /**
6308
+ * Informs the key handler that a frame was successfully decrypted using an encryption key.
6309
+ * @internal
6310
+ * @param keyIndex the key index for which the success occurred. Defaults to the current key index.
6311
+ */
6289
6312
  decryptionSuccess() {
6290
- this.resetKeyStatus();
6313
+ let keyIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentKeyIndex;
6314
+ this.resetKeyStatus(keyIndex);
6291
6315
  }
6292
6316
  /**
6293
6317
  * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially
6294
6318
  * invalid keys as valid again
6319
+ *
6320
+ * @param keyIndex the index of the key. Defaults to the current key index.
6295
6321
  */
6296
- resetKeyStatus() {
6297
- this.decryptionFailureCount = 0;
6298
- this._hasValidKey = true;
6322
+ resetKeyStatus(keyIndex) {
6323
+ if (keyIndex === undefined) {
6324
+ this.decryptionFailureCounts.fill(0);
6325
+ } else {
6326
+ this.decryptionFailureCounts[keyIndex] = 0;
6327
+ }
6299
6328
  }
6300
6329
  /**
6301
6330
  * Ratchets the current key (or the one at keyIndex if provided) and
@@ -6320,7 +6349,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
6320
6349
  const currentMaterial = keySet.material;
6321
6350
  const newMaterial = yield importKey(yield ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt), currentMaterial.algorithm.name, 'derive');
6322
6351
  if (setKey) {
6323
- this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
6352
+ yield this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
6324
6353
  this.emit(KeyHandlerEvent.KeyRatcheted, newMaterial, this.participantIdentity, currentKeyIndex);
6325
6354
  }
6326
6355
  resolve(newMaterial);
@@ -6345,7 +6374,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
6345
6374
  let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
6346
6375
  return function* () {
6347
6376
  yield _this.setKeyFromMaterial(material, keyIndex);
6348
- _this.resetKeyStatus();
6377
+ _this.resetKeyStatus(keyIndex);
6349
6378
  }();
6350
6379
  });
6351
6380
  }
@@ -6382,7 +6411,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
6382
6411
  setCurrentKeyIndex(index) {
6383
6412
  return __awaiter(this, void 0, void 0, function* () {
6384
6413
  this.currentKeyIndex = index % this.cryptoKeyRing.length;
6385
- this.resetKeyStatus();
6414
+ this.resetKeyStatus(index);
6386
6415
  });
6387
6416
  }
6388
6417
  getCurrentKeyIndex() {