Skip to content

Commit

Permalink
improve for framecryptor.
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwebrtc committed Sep 15, 2023
1 parent 9aaec7d commit e53e06d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 73 deletions.
2 changes: 1 addition & 1 deletion example/lib/pages/connect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class _ConnectPageState extends State<ConnectPage> {
final keyProvider = await BaseKeyProvider.create();
e2eeOptions = E2EEOptions(keyProvider: keyProvider);
var sharedKey = _sharedKeyCtrl.text;
await keyProvider.setKey(sharedKey);
await keyProvider.setSharedKey(sharedKey);
}

String preferredCodec = 'VP8';
Expand Down
2 changes: 1 addition & 1 deletion ios/livekit_client.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ Pod::Spec.new do |s|
s.static_framework = true

s.dependency 'Flutter'
s.dependency 'WebRTC-SDK', '114.5735.02'
s.dependency 'WebRTC-SDK', '114.5735.06'
end
5 changes: 5 additions & 0 deletions lib/src/core/room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
_getOrCreateRemoteParticipant(info.sid, info);
}

if (e2eeManager != null && event.response.sifTrailer.isNotEmpty) {
e2eeManager!.keyProvider
.setSifTrailer(Uint8List.fromList(event.response.sifTrailer));
}

logger.fine('Room Connect completed');
})
..on<SignalParticipantUpdateEvent>(
Expand Down
99 changes: 49 additions & 50 deletions lib/src/e2ee/e2ee_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import 'key_provider.dart';

class E2EEManager {
Room? _room;
final Map<String, FrameCryptor> _frameCryptors = {};
final List<FrameCryptor> _senderFrameCryptors = [];
final Map<Map<String, String>, FrameCryptor> _frameCryptors = {};
final BaseKeyProvider _keyProvider;
final Algorithm _algorithm = Algorithm.kAesGcm;
bool _enabled = true;
Expand All @@ -40,13 +39,10 @@ class E2EEManager {
_listener = _room!.createListener();
_listener!
..on<LocalTrackPublishedEvent>((event) async {
var trackId = event.publication.sid;
var participantId = event.participant.sid;
var frameCryptor = await _addRtpSender(
event.publication.track!.sender!,
participantId,
trackId,
event.publication.track!.kind.name.toLowerCase());
sender: event.publication.track!.sender!,
identity: event.participant.identity,
sid: event.publication.sid);
if (kIsWeb && event.publication.track!.codec != null) {
await frameCryptor.updateCodec(event.publication.track!.codec!);
}
Expand All @@ -63,19 +59,23 @@ class E2EEManager {
state: _e2eeStateFromFrameCryptoState(state),
));
};
_senderFrameCryptors.add(frameCryptor);
})
..on<LocalTrackUnpublishedEvent>((event) async {
var trackId = event.publication.sid;
var frameCryptor = _frameCryptors.remove(trackId);
_senderFrameCryptors.remove(frameCryptor);
await frameCryptor?.dispose();
for (var key in _frameCryptors.keys.toList()) {
if (key.keys.first == event.participant.identity &&
key.values.first == event.publication.sid) {
var frameCryptor = _frameCryptors.remove(key);
await frameCryptor?.setEnabled(false);
await frameCryptor?.dispose();
}
}
})
..on<TrackSubscribedEvent>((event) async {
var trackId = event.publication.sid;
var participantId = event.participant.sid;
var frameCryptor = await _addRtpReceiver(event.track.receiver!,
participantId, trackId, event.track.kind.name.toLowerCase());
var frameCryptor = await _addRtpReceiver(
receiver: event.track.receiver!,
identity: event.participant.identity,
sid: event.publication.sid,
);
if (kIsWeb) {
var codec = event.publication.mimeType.split('/')[1];
await frameCryptor.updateCodec(codec.toLowerCase());
Expand All @@ -95,16 +95,28 @@ class E2EEManager {
};
})
..on<TrackUnsubscribedEvent>((event) async {
var trackId = event.publication.sid;
var frameCryptor = _frameCryptors.remove(trackId);
await frameCryptor?.dispose();
for (var key in _frameCryptors.keys.toList()) {
if (key.keys.first == event.participant.identity &&
key.values.first == event.publication.sid) {
var frameCryptor = _frameCryptors.remove(key);
await frameCryptor?.setEnabled(false);
await frameCryptor?.dispose();
}
}
});
}
}

Future<void> ratchetKey() async {
for (var frameCryptor in _senderFrameCryptors) {
var newKey = await _keyProvider.ratchetKey(frameCryptor.participantId, 0);
BaseKeyProvider get keyProvider => _keyProvider;

Future<void> ratchetKey({String? participantId, int? keyIndex}) async {
if (participantId != null) {
var newKey = await _keyProvider.ratchetKey(participantId, keyIndex);
if (kDebugMode) {
print('newKey: $newKey');
}
} else {
var newKey = await _keyProvider.ratchetSharedKey(keyIndex: keyIndex);
if (kDebugMode) {
print('newKey: $newKey');
}
Expand All @@ -121,54 +133,41 @@ class E2EEManager {
_frameCryptors.clear();
}

Future<FrameCryptor> _addRtpSender(RTCRtpSender sender, String participantId,
String trackId, String kind) async {
var pid = '$kind-sender-$participantId-$trackId';
Future<FrameCryptor> _addRtpSender(
{required RTCRtpSender sender,
required String identity,
required String sid}) async {
var frameCryptor = await frameCryptorFactory.createFrameCryptorForRtpSender(
participantId: pid,
participantId: identity,
sender: sender,
algorithm: _algorithm,
keyProvider: _keyProvider.keyProvider);
_frameCryptors[trackId] = frameCryptor;
_frameCryptors[{identity: sid}] = frameCryptor;
await frameCryptor.setEnabled(_enabled);
if (_keyProvider.options.sharedKey) {
await _keyProvider.keyProvider
.setKey(participantId: pid, index: 0, key: _keyProvider.sharedKey!);
await frameCryptor.setKeyIndex(0);
}
await frameCryptor.setKeyIndex(0);
return frameCryptor;
}

Future<FrameCryptor> _addRtpReceiver(RTCRtpReceiver receiver,
String participantId, String trackId, String kind) async {
var pid = '$kind-receiver-$participantId-$trackId';
Future<FrameCryptor> _addRtpReceiver(
{required RTCRtpReceiver receiver,
required String identity,
required String sid}) async {
var frameCryptor =
await frameCryptorFactory.createFrameCryptorForRtpReceiver(
participantId: pid,
participantId: identity,
receiver: receiver,
algorithm: _algorithm,
keyProvider: _keyProvider.keyProvider);
_frameCryptors[trackId] = frameCryptor;
_frameCryptors[{identity: sid}] = frameCryptor;
await frameCryptor.setEnabled(_enabled);
if (_keyProvider.options.sharedKey) {
await _keyProvider.keyProvider
.setKey(participantId: pid, index: 0, key: _keyProvider.sharedKey!);
await frameCryptor.setKeyIndex(0);
}
await frameCryptor.setKeyIndex(0);
return frameCryptor;
}

Future<void> setEnabled(bool enabled) async {
_enabled = enabled;
for (var frameCryptor in _frameCryptors.entries) {
await frameCryptor.value.setEnabled(enabled);
if (_keyProvider.options.sharedKey) {
await _keyProvider.keyProvider.setKey(
participantId: frameCryptor.key,
index: 0,
key: _keyProvider.sharedKey!);
await frameCryptor.value.setKeyIndex(0);
}
}
}

Expand Down
53 changes: 47 additions & 6 deletions lib/src/e2ee/key_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ class KeyInfo {
}

abstract class KeyProvider {
Future<void> setKey(String key, {String? participantId, int keyIndex = 0});
Future<Uint8List> ratchetKey(String participantId, int index);
Future<void> setSharedKey(String key, {int? keyIndex});
Future<Uint8List> ratchetSharedKey({int? keyIndex});
Future<Uint8List> exportSharedKey({int? keyIndex});
Future<void> setKey(String key, {String? participantId, int? keyIndex});
Future<Uint8List> ratchetKey(String participantId, int? keyIndex);
Future<Uint8List> exportKey(String participantId, int? keyIndex);
Future<void> setSifTrailer(Uint8List trailer);
rtc.KeyProvider get keyProvider;
}

Expand All @@ -54,6 +59,7 @@ class BaseKeyProvider implements KeyProvider {
String? ratchetSalt,
String? uncryptedMagicBytes,
int? ratchetWindowSize,
int? failureTolerance,
}) async {
rtc.KeyProviderOptions options = rtc.KeyProviderOptions(
sharedKey: sharedKey,
Expand All @@ -62,26 +68,56 @@ class BaseKeyProvider implements KeyProvider {
ratchetWindowSize: ratchetWindowSize ?? defaultRatchetWindowSize,
uncryptedMagicBytes: Uint8List.fromList(
(uncryptedMagicBytes ?? defaultMagicBytes).codeUnits),
failureTolerance: failureTolerance ?? -1,
);
final keyProvider =
await rtc.frameCryptorFactory.createDefaultKeyProvider(options);
return BaseKeyProvider(keyProvider, options);
}

@override
Future<Uint8List> ratchetKey(String participantId, int index) =>
_keyProvider.ratchetKey(participantId: participantId, index: index);
Future<void> setSharedKey(String key, {int? keyIndex}) async {
_sharedKey = Uint8List.fromList(key.codeUnits);
return _keyProvider.setSharedKey(key: _sharedKey!, index: keyIndex ?? 0);
}

@override
Future<Uint8List> ratchetSharedKey({int? keyIndex}) async {
if (_sharedKey == null) {
throw Exception('shared key not set');
}
_sharedKey = await _keyProvider.ratchetSharedKey(index: keyIndex ?? 0);
return _sharedKey!;
}

@override
Future<Uint8List> exportSharedKey({int? keyIndex}) async {
if (_sharedKey == null) {
throw Exception('shared key not set');
}
return _keyProvider.exportSharedKey(index: keyIndex ?? 0);
}

@override
Future<Uint8List> ratchetKey(String participantId, int? keyIndex) =>
_keyProvider.ratchetKey(
participantId: participantId, index: keyIndex ?? 0);

@override
Future<Uint8List> exportKey(String participantId, int? keyIndex) =>
_keyProvider.exportKey(
participantId: participantId, index: keyIndex ?? 0);

@override
Future<void> setKey(String key,
{String? participantId, int keyIndex = 0}) async {
{String? participantId, int? keyIndex}) async {
if (options.sharedKey) {
_sharedKey = Uint8List.fromList(key.codeUnits);
return;
}
final keyInfo = KeyInfo(
participantId: participantId ?? '',
keyIndex: keyIndex,
keyIndex: keyIndex ?? 0,
key: Uint8List.fromList(key.codeUnits),
);
return _setKey(keyInfo);
Expand All @@ -98,4 +134,9 @@ class BaseKeyProvider implements KeyProvider {
key: keyInfo.key,
);
}

@override
Future<void> setSifTrailer(Uint8List trailer) async {
return _keyProvider.setSifTrailer(trailer: trailer);
}
}
24 changes: 12 additions & 12 deletions lib/src/participant/local.dart
Original file line number Diff line number Diff line change
Expand Up @@ -199,20 +199,20 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
publishOptions.backupCodec!.codec != publishOptions.videoCodec) {
simulcastCodecs = <lk_rtc.SimulcastCodec>[
lk_rtc.SimulcastCodec(
codec: publishOptions.videoCodec,
cid: track.getCid(),
enableSimulcastLayers: true),
codec: publishOptions.videoCodec,
cid: track.getCid(),
),
lk_rtc.SimulcastCodec(
codec: publishOptions.backupCodec!.codec.toLowerCase(),
cid: '',
enableSimulcastLayers: publishOptions.backupCodec!.simulcast),
codec: publishOptions.backupCodec!.codec.toLowerCase(),
cid: '',
),
];
} else {
simulcastCodecs = <lk_rtc.SimulcastCodec>[
lk_rtc.SimulcastCodec(
codec: publishOptions.videoCodec,
cid: track.getCid(),
enableSimulcastLayers: publishOptions.simulcast),
codec: publishOptions.videoCodec,
cid: track.getCid(),
),
];
}

Expand Down Expand Up @@ -618,9 +618,9 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
sid: publication.sid,
simulcastCodecs: <lk_rtc.SimulcastCodec>[
lk_rtc.SimulcastCodec(
codec: backupCodec.toLowerCase(),
cid: cid,
enableSimulcastLayers: backupCodecOpts.simulcast),
codec: backupCodec.toLowerCase(),
cid: cid,
),
]);

await room.engine.negotiate();
Expand Down
2 changes: 1 addition & 1 deletion macos/livekit_client.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ Pod::Spec.new do |s|
s.static_framework = true

s.dependency 'FlutterMacOS'
s.dependency 'WebRTC-SDK', '114.5735.02'
s.dependency 'WebRTC-SDK', '114.5735.06'
end
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ dependencies:
uuid: ^3.0.6
synchronized: ^3.0.0+3
protobuf: ^3.0.0
flutter_webrtc: 0.9.41
flutter_webrtc: 0.9.42
flutter_window_close: ^0.2.2
device_info_plus: ^9.0.0
js: ^0.6.4
platform_detect: ^2.0.7
dart_webrtc: 1.1.2
dart_webrtc: 1.1.3

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit e53e06d

Please sign in to comment.