diff --git a/lib/src/e2ee.worker/e2ee.cryptor.dart b/lib/src/e2ee.worker/e2ee.cryptor.dart index e731f2f..e871317 100644 --- a/lib/src/e2ee.worker/e2ee.cryptor.dart +++ b/lib/src/e2ee.worker/e2ee.cryptor.dart @@ -301,6 +301,9 @@ class FrameCryptor { if (!enabled || // skip for encryption for empty dtx frames buffer.isEmpty) { + if (keyOptions.discardFrameWhenCryptorNotReady) { + return; + } controller.enqueue(frame); return; } @@ -405,6 +408,9 @@ class FrameCryptor { // skip for encryption for empty dtx frames buffer.isEmpty) { sifGuard.recordUserFrame(); + if (keyOptions.discardFrameWhenCryptorNotReady) { + return; + } controller.enqueue(frame); return; } diff --git a/lib/src/e2ee.worker/e2ee.keyhandler.dart b/lib/src/e2ee.worker/e2ee.keyhandler.dart index 84f9c2a..e7feae6 100644 --- a/lib/src/e2ee.worker/e2ee.keyhandler.dart +++ b/lib/src/e2ee.worker/e2ee.keyhandler.dart @@ -8,6 +8,8 @@ import 'crypto.dart' as crypto; import 'e2ee.logger.dart'; import 'e2ee.utils.dart'; +const KEYRING_SIZE = 16; + class KeyOptions { KeyOptions({ required this.sharedKey, @@ -15,12 +17,16 @@ class KeyOptions { required this.ratchetWindowSize, this.uncryptedMagicBytes, this.failureTolerance = -1, + this.keyRingSze = KEYRING_SIZE, + this.discardFrameWhenCryptorNotReady = false, }); bool sharedKey; Uint8List ratchetSalt; int ratchetWindowSize = 0; int failureTolerance; Uint8List? uncryptedMagicBytes; + int keyRingSze; + bool discardFrameWhenCryptorNotReady; @override String toString() { @@ -77,8 +83,6 @@ class KeyProvider { } } -const KEYRING_SIZE = 16; - class KeySet { KeySet(this.material, this.encryptionKey); web.CryptoKey material; @@ -90,10 +94,15 @@ class ParticipantKeyHandler { required this.worker, required this.keyOptions, required this.participantIdentity, - }); + }) { + if (keyOptions.keyRingSze <= 0 || keyOptions.keyRingSze > 255) { + throw Exception('Invalid key ring size'); + } + cryptoKeyRing = List.filled(keyOptions.keyRingSze, null); + } int currentKeyIndex = 0; - List cryptoKeyRing = List.filled(KEYRING_SIZE, null); + late List cryptoKeyRing; bool _hasValidKey = false; diff --git a/lib/src/e2ee.worker/e2ee.worker.dart b/lib/src/e2ee.worker/e2ee.worker.dart index 17d555a..fac64b0 100644 --- a/lib/src/e2ee.worker/e2ee.worker.dart +++ b/lib/src/e2ee.worker/e2ee.worker.dart @@ -118,7 +118,10 @@ void main() async { uncryptedMagicBytes: options['uncryptedMagicBytes'] != null ? Uint8List.fromList( base64Decode(options['uncryptedMagicBytes'] as String)) - : null); + : null, + keyRingSze: options['keyRingSize'] ?? KEYRING_SIZE, + discardFrameWhenCryptorNotReady: + options['discardFrameWhenCryptorNotReady'] ?? false); logger.config( 'Init with keyProviderOptions:\n ${keyProviderOptions.toString()}'); diff --git a/lib/src/frame_cryptor_impl.dart b/lib/src/frame_cryptor_impl.dart index 9e16bf4..db66d52 100644 --- a/lib/src/frame_cryptor_impl.dart +++ b/lib/src/frame_cryptor_impl.dart @@ -193,6 +193,9 @@ class KeyProviderImpl implements KeyProvider { 'ratchetWindowSize': options.ratchetWindowSize, if (options.uncryptedMagicBytes != null) 'uncryptedMagicBytes': base64Encode(options.uncryptedMagicBytes!), + 'keyRingSize': options.keyRingSize, + 'discardFrameWhenCryptorNotReady': + options.discardFrameWhenCryptorNotReady, }, }) ]); diff --git a/pubspec.yaml b/pubspec.yaml index 5682271..925629e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: platform_detect: ^2.0.7 synchronized: ^3.0.0+3 web: ^0.5.1 - webrtc_interface: ^1.1.2 + webrtc_interface: ^1.2.0 dev_dependencies: build_runner: ^2.3.3 diff --git a/web/main.dart b/web/main.dart index 8dd8300..4bbed71 100644 --- a/web/main.dart +++ b/web/main.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:typed_data'; import 'package:dart_webrtc/dart_webrtc.dart'; @@ -49,7 +50,8 @@ void loopBackTest() async { sharedKey: false, ratchetWindowSize: 16, failureTolerance: -1, - ratchetSalt: Uint8List.fromList('testSalt'.codeUnits)); + ratchetSalt: Uint8List.fromList('testSalt'.codeUnits), + discardFrameWhenCryptorNotReady: true); var keyProvider = await frameCryptorFactory.createDefaultKeyProvider(keyProviderOptions); @@ -73,7 +75,14 @@ void loopBackTest() async { receiver: event.receiver!, algorithm: Algorithm.kAesGcm, keyProvider: keyProvider); - await fc.setEnabled(true); + if (keyProviderOptions.discardFrameWhenCryptorNotReady) { + Timer(Duration(seconds: 2), () { + fc.setEnabled(true); + }); + } else { + await fc.setEnabled(true); + } + await fc.setKeyIndex(0); await fc.updateCodec('vp8'); pc2FrameCryptors.add(fc);