Skip to content

Commit 6990ea8

Browse files
committed
fix e2ee.
1 parent 8049a42 commit 6990ea8

File tree

6 files changed

+369
-428
lines changed

6 files changed

+369
-428
lines changed

lib/src/e2ee.worker/crypto.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
/*
21
import 'dart:async';
32
import 'dart:js_util' as jsutil;
43
import 'dart:typed_data';
54

65
import 'package:js/js.dart';
76
import 'package:web/web.dart' as web;
87

9-
108
@JS('Promise')
119
class Promise<T> {
1210
external factory Promise._();
@@ -94,5 +92,3 @@ Future<web.CryptoKey> impportKeyFromRawData(List<int> secretKeyData,
9492
keyUsages,
9593
));
9694
}
97-
98-
*/

lib/src/e2ee.worker/e2ee.cryptor.dart

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
import 'dart:async';
2-
32
import 'dart:js';
43
import 'dart:js_interop';
4+
import 'dart:js_util' as jsutil;
55
import 'dart:math';
66
import 'dart:typed_data';
77

88
import 'package:dart_webrtc/src/rtc_transform_stream.dart';
9-
import 'package:js/js_util.dart' as jsutil;
109
import 'package:web/web.dart' as web;
1110

11+
import 'crypto.dart' as crypto;
1212
import 'e2ee.keyhandler.dart';
1313
import 'e2ee.logger.dart';
1414
import 'e2ee.sfi_guard.dart';
1515

16-
final crypto = web.window.crypto.subtle;
17-
1816
const IV_LENGTH = 12;
1917

2018
const kNaluTypeMask = 0x1f;
@@ -223,7 +221,7 @@ class FrameCryptor {
223221
}
224222

225223
void postMessage(Object message) {
226-
worker.postMessage(jsutil.jsify(message));
224+
worker.postMessage(message.jsify());
227225
}
228226

229227
Future<void> setupTransform({
@@ -339,13 +337,14 @@ class FrameCryptor {
339337
frameTrailer.setInt8(1, keyIndex);
340338

341339
var cipherText = await jsutil.promiseToFuture<ByteBuffer>(crypto.encrypt(
342-
web.AesGcmParams(
343-
//name: 'AES-GCM',
344-
iv: iv.toJS,
345-
additionalData: buffer.sublist(0, headerLength).toJS,
340+
crypto.AesGcmParams(
341+
name: 'AES-GCM',
342+
iv: crypto.jsArrayBufferFrom(iv),
343+
additionalData:
344+
crypto.jsArrayBufferFrom(buffer.sublist(0, headerLength)),
346345
),
347346
secretKey,
348-
buffer.sublist(headerLength, buffer.length).toJS,
347+
crypto.jsArrayBufferFrom(buffer.sublist(headerLength, buffer.length)),
349348
));
350349

351350
logger.finer(
@@ -356,7 +355,7 @@ class FrameCryptor {
356355
finalBuffer.add(cipherText.asUint8List());
357356
finalBuffer.add(iv);
358357
finalBuffer.add(frameTrailer.buffer.asUint8List());
359-
frame.data = finalBuffer.toBytes().buffer;
358+
frame.data = crypto.jsArrayBufferFrom(finalBuffer.toBytes());
360359

361360
controller.enqueue(frame);
362361

@@ -425,7 +424,7 @@ class FrameCryptor {
425424
var finalBuffer = BytesBuilder();
426425
finalBuffer.add(Uint8List.fromList(
427426
buffer.sublist(0, buffer.length - (magicBytes.length + 1))));
428-
frame.data = finalBuffer.toBytes().buffer;
427+
frame.data = crypto.jsArrayBufferFrom(finalBuffer.toBytes());
429428
controller.enqueue(frame);
430429
} else {
431430
logger.finer('SIF limit reached, dropping frame');
@@ -471,17 +470,19 @@ class FrameCryptor {
471470
while (!endDecLoop) {
472471
try {
473472
decrypted = await jsutil.promiseToFuture<ByteBuffer>(crypto.decrypt(
474-
web.AesGcmParams(
475-
//name: 'AES-GCM',
476-
iv: iv.toJS,
477-
additionalData: buffer.sublist(0, headerLength).toJS,
473+
crypto.AesGcmParams(
474+
name: 'AES-GCM',
475+
iv: crypto.jsArrayBufferFrom(iv),
476+
additionalData:
477+
crypto.jsArrayBufferFrom(buffer.sublist(0, headerLength)),
478478
),
479479
currentkeySet.encryptionKey,
480-
buffer.sublist(headerLength, buffer.length - ivLength - 2).toJS,
480+
crypto.jsArrayBufferFrom(
481+
buffer.sublist(headerLength, buffer.length - ivLength - 2)),
481482
));
482483

483484
if (currentkeySet != initialKeySet) {
484-
logger.warning(
485+
logger.fine(
485486
'ratchetKey: decryption ok, reset state to kKeyRatcheted');
486487
await keyHandler.setKeySetFromMaterial(
487488
currentkeySet, initialKeyIndex);
@@ -515,10 +516,10 @@ class FrameCryptor {
515516
if (endDecLoop) {
516517
rethrow;
517518
}
518-
var newKeyBuffer = await keyHandler.ratchet(
519-
currentkeySet.material, keyOptions.ratchetSalt);
519+
var newKeyBuffer = crypto.jsArrayBufferFrom(await keyHandler.ratchet(
520+
currentkeySet.material, keyOptions.ratchetSalt));
520521
var newMaterial = await keyHandler.ratchetMaterial(
521-
currentkeySet.material, newKeyBuffer.buffer);
522+
currentkeySet.material, newKeyBuffer);
522523
currentkeySet =
523524
await keyHandler.deriveKeys(newMaterial, keyOptions.ratchetSalt);
524525
ratchetCount++;
@@ -531,7 +532,7 @@ class FrameCryptor {
531532

532533
finalBuffer.add(Uint8List.fromList(buffer.sublist(0, headerLength)));
533534
finalBuffer.add(decrypted!.asUint8List());
534-
frame.data = finalBuffer.toBytes().buffer;
535+
frame.data = crypto.jsArrayBufferFrom(finalBuffer.toBytes());
535536
controller.enqueue(frame);
536537

537538
if (lastError != CryptorError.kOk) {

lib/src/e2ee.worker/e2ee.keyhandler.dart

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import 'dart:async';
2-
import 'dart:js_interop';
32
import 'dart:js_util' as jsutil;
43
import 'dart:typed_data';
54

65
import 'package:web/web.dart' as web;
76

7+
import 'crypto.dart' as crypto;
88
import 'e2ee.logger.dart';
99
import 'e2ee.utils.dart';
1010

11-
final crypto = web.window.crypto.subtle;
12-
1311
class KeyOptions {
1412
KeyOptions({
1513
required this.sharedKey,
@@ -153,23 +151,22 @@ class ParticipantKeyHandler {
153151
return null;
154152
}
155153
var newKey = await ratchet(currentMaterial, keyOptions.ratchetSalt);
156-
var newMaterial = await ratchetMaterial(currentMaterial, newKey.buffer);
154+
var newMaterial = await ratchetMaterial(
155+
currentMaterial, crypto.jsArrayBufferFrom(newKey));
157156
var newKeySet = await deriveKeys(newMaterial, keyOptions.ratchetSalt);
158157
await setKeySetFromMaterial(newKeySet, keyIndex ?? currentKeyIndex);
159158
return newKey;
160159
}
161160

162161
Future<web.CryptoKey> ratchetMaterial(
163162
web.CryptoKey currentMaterial, ByteBuffer newKeyBuffer) async {
164-
var newMaterial = await crypto
165-
.importKey(
166-
'raw',
167-
newKeyBuffer.toJS,
168-
(currentMaterial.algorithm as web.Algorithm).name.toJS,
169-
false,
170-
<JSString>['deriveBits'.toJS, 'deriveKey'.toJS].toJS,
171-
)
172-
.toDart;
163+
var newMaterial = await jsutil.promiseToFuture(crypto.importKey(
164+
'raw',
165+
newKeyBuffer,
166+
(currentMaterial.algorithm as crypto.Algorithm).name,
167+
false,
168+
['deriveBits', 'deriveKey'],
169+
));
173170
return newMaterial;
174171
}
175172

@@ -178,11 +175,8 @@ class ParticipantKeyHandler {
178175
}
179176

180177
Future<void> setKey(Uint8List key, {int keyIndex = 0}) async {
181-
var keyMaterial = await crypto
182-
.importKey('raw', key.toJS, 'PBKDF2'.toJS, false,
183-
<JSString>['deriveBits'.toJS, 'deriveKey'.toJS].toJS)
184-
.toDart;
185-
178+
var keyMaterial = await crypto.impportKeyFromRawData(key,
179+
webCryptoAlgorithm: 'PBKDF2', keyUsages: ['deriveBits', 'deriveKey']);
186180
var keySet = await deriveKeys(
187181
keyMaterial,
188182
keyOptions.ratchetSalt,
@@ -203,7 +197,7 @@ class ParticipantKeyHandler {
203197
/// See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1
204198
Future<KeySet> deriveKeys(web.CryptoKey material, Uint8List salt) async {
205199
var algorithmOptions =
206-
getAlgoOptions((material.algorithm as web.Algorithm).name, salt);
200+
getAlgoOptions((material.algorithm as crypto.Algorithm).name, salt);
207201

208202
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF
209203
// https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams
@@ -213,7 +207,7 @@ class ParticipantKeyHandler {
213207
material,
214208
jsutil.jsify({'name': 'AES-GCM', 'length': 128}),
215209
false,
216-
<JSString>['encrypt'.toJS, 'decrypt'.toJS].toJS,
210+
['encrypt', 'decrypt'],
217211
));
218212

219213
return KeySet(material, encryptionKey);

lib/src/e2ee.worker/e2ee.utils.dart

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import 'dart:js' as js;
2-
import 'dart:js_interop';
3-
import 'dart:js_interop_unsafe';
42
import 'dart:typed_data';
53

64
import 'package:js/js_util.dart';
75
import 'package:web/web.dart' as web;
86

9-
final crypto = web.window.crypto.subtle;
7+
import 'crypto.dart' as crypto;
108

119
bool isE2EESupported() {
1210
return isInsertableStreamSupported() || isScriptTransformSupported();
@@ -24,29 +22,24 @@ bool isInsertableStreamSupported() {
2422
Future<web.CryptoKey> importKey(
2523
Uint8List keyBytes, String algorithm, String usage) {
2624
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
27-
28-
return crypto
29-
.importKey(
30-
'raw',
31-
keyBytes.toJS,
32-
newObject<JSObject>()..setProperty('name'.toJS, algorithm.toJS),
33-
false,
34-
usage == 'derive'
35-
? <JSString>['deriveBits'.toJS, 'deriveKey'.toJS].toJS
36-
: <JSString>['encrypt'.toJS, 'decrypt'.toJS].toJS,
37-
)
38-
.toDart;
25+
return promiseToFuture<web.CryptoKey>(crypto.importKey(
26+
'raw',
27+
crypto.jsArrayBufferFrom(keyBytes),
28+
js.JsObject.jsify({'name': algorithm}),
29+
false,
30+
usage == 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt'],
31+
));
3932
}
4033

4134
Future<web.CryptoKey> createKeyMaterialFromString(
4235
Uint8List keyBytes, String algorithm, String usage) {
4336
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
4437
return promiseToFuture<web.CryptoKey>(crypto.importKey(
4538
'raw',
46-
keyBytes.toJS,
47-
newObject<JSObject>()..setProperty('name'.toJS, 'PBKDF2'.toJS),
39+
crypto.jsArrayBufferFrom(keyBytes),
40+
js.JsObject.jsify({'name': 'PBKDF2'}),
4841
false,
49-
<JSString>['deriveBits'.toJS, 'deriveKey'.toJS].toJS,
42+
['deriveBits', 'deriveKey'],
5043
));
5144
}
5245

@@ -55,15 +48,15 @@ dynamic getAlgoOptions(String algorithmName, Uint8List salt) {
5548
case 'HKDF':
5649
return {
5750
'name': 'HKDF',
58-
'salt': salt.toJS,
51+
'salt': crypto.jsArrayBufferFrom(salt),
5952
'hash': 'SHA-256',
60-
'info': Uint8List(128).toJS,
53+
'info': crypto.jsArrayBufferFrom(Uint8List(128)),
6154
};
6255
case 'PBKDF2':
6356
{
6457
return {
6558
'name': 'PBKDF2',
66-
'salt': salt.toJS,
59+
'salt': crypto.jsArrayBufferFrom(salt),
6760
'hash': 'SHA-256',
6861
'iterations': 100000,
6962
};

0 commit comments

Comments
 (0)