@@ -21,6 +21,7 @@ import {
21
21
EncryptionEvent ,
22
22
type DecryptDataResponseMessage ,
23
23
type EncryptDataResponseMessage ,
24
+ Mutex ,
24
25
} from 'livekit-client' ;
25
26
import type RNKeyProvider from './RNKeyProvider' ;
26
27
import type RTCEngine from 'livekit-client/dist/src/room/RTCEngine' ;
@@ -37,13 +38,14 @@ export default class RNE2EEManager
37
38
private room ?: Room ;
38
39
private frameCryptors : Map < string , RTCFrameCryptor > = new Map ( ) ;
39
40
private keyProvider : RNKeyProvider ;
40
- private dataPacketCryptor : RTCDataPacketCryptor ;
41
41
private algorithm : RTCFrameCryptorAlgorithm =
42
42
RTCFrameCryptorAlgorithm . kAesGcm ;
43
43
44
44
private encryptionEnabled : boolean = false ;
45
45
private dataChannelEncryptionEnabled : boolean = false ;
46
46
47
+ private dataPacketCryptorLock = new Mutex ( ) ;
48
+ private dataPacketCryptor : RTCDataPacketCryptor | undefined = undefined ;
47
49
constructor (
48
50
keyProvider : RNKeyProvider ,
49
51
dcEncryptionEnabled : boolean = false
@@ -52,17 +54,19 @@ export default class RNE2EEManager
52
54
this . keyProvider = keyProvider ;
53
55
this . encryptionEnabled = false ;
54
56
this . dataChannelEncryptionEnabled = dcEncryptionEnabled ;
55
- this . dataPacketCryptor =
56
- RTCDataPacketCryptorFactory . createDataPacketCryptor (
57
- this . algorithm ,
58
- this . keyProvider . rtcKeyProvider
59
- ) ;
60
57
}
61
58
62
59
get isEnabled ( ) : boolean {
63
60
return this . encryptionEnabled ;
64
61
}
65
62
get isDataChannelEncryptionEnabled ( ) : boolean {
63
+ console . log (
64
+ 'isDataChannelEncryptionEnabled?' ,
65
+ this . isEnabled ,
66
+ this . encryptionEnabled ,
67
+ this . dataChannelEncryptionEnabled ,
68
+ this . isEnabled && this . dataChannelEncryptionEnabled
69
+ ) ;
66
70
return this . isEnabled && this . dataChannelEncryptionEnabled ;
67
71
}
68
72
@@ -101,7 +105,16 @@ export default class RNE2EEManager
101
105
await frameCryptor . dispose ( ) ;
102
106
}
103
107
}
104
- ) ;
108
+ )
109
+ . on ( RoomEvent . SignalConnected , ( ) => {
110
+ if ( ! this . room ) {
111
+ throw new TypeError ( `expected room to be present on signal connect` ) ;
112
+ }
113
+ this . setParticipantCryptorEnabled (
114
+ this . room . localParticipant . isE2EEEnabled ,
115
+ this . room . localParticipant . identity
116
+ ) ;
117
+ } ) ;
105
118
}
106
119
107
120
private async setupE2EESender (
@@ -156,6 +169,32 @@ export default class RNE2EEManager
156
169
this . keyProvider . setSifTrailer ( trailer ) ;
157
170
}
158
171
172
+ private async getDataPacketCryptor ( ) : Promise < RTCDataPacketCryptor > {
173
+ let dataPacketCryptor = this . dataPacketCryptor ;
174
+ if ( dataPacketCryptor ) {
175
+ return dataPacketCryptor ;
176
+ }
177
+
178
+ let unlock = await this . dataPacketCryptorLock . lock ( ) ;
179
+
180
+ try {
181
+ dataPacketCryptor = this . dataPacketCryptor ;
182
+ if ( dataPacketCryptor ) {
183
+ return dataPacketCryptor ;
184
+ }
185
+
186
+ dataPacketCryptor =
187
+ await RTCDataPacketCryptorFactory . createDataPacketCryptor (
188
+ this . algorithm ,
189
+ this . keyProvider . rtcKeyProvider
190
+ ) ;
191
+
192
+ this . dataPacketCryptor = dataPacketCryptor ;
193
+ return dataPacketCryptor ;
194
+ } finally {
195
+ unlock ( ) ;
196
+ }
197
+ }
159
198
async encryptData (
160
199
data : Uint8Array
161
200
) : Promise < EncryptDataResponseMessage [ 'data' ] > {
@@ -165,7 +204,10 @@ export default class RNE2EEManager
165
204
}
166
205
167
206
let participantId = room . localParticipant . identity ;
168
- let encryptedPacket = await this . dataPacketCryptor . encrypt (
207
+
208
+ let dataPacketCryptor = await this . getDataPacketCryptor ( ) ;
209
+
210
+ let encryptedPacket = await dataPacketCryptor . encrypt (
169
211
participantId ,
170
212
this . keyProvider . getLatestKeyIndex ( participantId ) ,
171
213
data
@@ -196,7 +238,8 @@ export default class RNE2EEManager
196
238
keyIndex,
197
239
} satisfies RTCEncryptedPacket ;
198
240
199
- let decryptedData = await this . dataPacketCryptor . decrypt (
241
+ let dataPacketCryptor = await this . getDataPacketCryptor ( ) ;
242
+ let decryptedData = await dataPacketCryptor . decrypt (
200
243
participantIdentity ,
201
244
packet
202
245
) ;
@@ -249,11 +292,13 @@ export default class RNE2EEManager
249
292
enabled : boolean ,
250
293
participantIdentity : string
251
294
) : void {
295
+ console . log ( 'setParticipantCryptorEnabled' , enabled , participantIdentity ) ;
252
296
if (
253
297
this . encryptionEnabled !== enabled &&
254
298
participantIdentity === this . room ?. localParticipant . identity
255
299
) {
256
300
this . encryptionEnabled = enabled ;
301
+ console . log ( 'setting encryption enabled to ' , enabled ) ;
257
302
this . emit (
258
303
EncryptionEvent . ParticipantEncryptionStatusChanged ,
259
304
enabled ,
0 commit comments