|
@@ -1,5 +1,4 @@
|
1
|
1
|
/* eslint-disable no-bitwise */
|
2
|
|
-/* global BigInt */
|
3
|
2
|
|
4
|
3
|
import { deriveKeys, importKey, ratchet } from './crypto-utils';
|
5
|
4
|
|
|
@@ -49,6 +48,16 @@ export class Context {
|
49
|
48
|
this._sendCounts = new Map();
|
50
|
49
|
|
51
|
50
|
this._sharedKey = sharedKey;
|
|
51
|
+
|
|
52
|
+ this._enabled = false;
|
|
53
|
+ }
|
|
54
|
+
|
|
55
|
+ /**
|
|
56
|
+ * Enables or disables the E2EE context. When disabled packets are passed through.
|
|
57
|
+ * @param {boolean} enabled True if E2EE is enabled, false otherwise.
|
|
58
|
+ */
|
|
59
|
+ setEnabled(enabled) {
|
|
60
|
+ this._enabled = enabled;
|
52
|
61
|
}
|
53
|
62
|
|
54
|
63
|
/**
|
|
@@ -86,8 +95,6 @@ export class Context {
|
86
|
95
|
}
|
87
|
96
|
|
88
|
97
|
this._cryptoKeyRing[this._currentKeyIndex] = keys;
|
89
|
|
-
|
90
|
|
- this._sendCount = BigInt(0); // eslint-disable-line new-cap
|
91
|
98
|
}
|
92
|
99
|
|
93
|
100
|
/**
|
|
@@ -113,12 +120,17 @@ export class Context {
|
113
|
120
|
* 9) Enqueue the encrypted frame for sending.
|
114
|
121
|
*/
|
115
|
122
|
encodeFunction(encodedFrame, controller) {
|
|
123
|
+ if (!this._enabled) {
|
|
124
|
+ return controller.enqueue(encodedFrame);
|
|
125
|
+ }
|
|
126
|
+
|
116
|
127
|
const keyIndex = this._currentKeyIndex;
|
|
128
|
+ const currentKey = this._cryptoKeyRing[keyIndex];
|
117
|
129
|
|
118
|
|
- if (this._cryptoKeyRing[keyIndex]) {
|
|
130
|
+ if (currentKey) {
|
119
|
131
|
const iv = this._makeIV(encodedFrame.getMetadata().synchronizationSource, encodedFrame.timestamp);
|
120
|
132
|
|
121
|
|
- // Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.
|
|
133
|
+ // This is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.
|
122
|
134
|
const frameHeader = new Uint8Array(encodedFrame.data, 0, UNENCRYPTED_BYTES[encodedFrame.type]);
|
123
|
135
|
|
124
|
136
|
// Frame trailer contains the R|IV_LENGTH and key index
|
|
@@ -139,7 +151,7 @@ export class Context {
|
139
|
151
|
name: ENCRYPTION_ALGORITHM,
|
140
|
152
|
iv,
|
141
|
153
|
additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength)
|
142
|
|
- }, this._cryptoKeyRing[keyIndex].encryptionKey, new Uint8Array(encodedFrame.data,
|
|
154
|
+ }, currentKey.encryptionKey, new Uint8Array(encodedFrame.data,
|
143
|
155
|
UNENCRYPTED_BYTES[encodedFrame.type]))
|
144
|
156
|
.then(cipherText => {
|
145
|
157
|
const newData = new ArrayBuffer(frameHeader.byteLength + cipherText.byteLength
|
|
@@ -165,12 +177,6 @@ export class Context {
|
165
|
177
|
// We are not enqueuing the frame here on purpose.
|
166
|
178
|
});
|
167
|
179
|
}
|
168
|
|
-
|
169
|
|
- /* NOTE WELL:
|
170
|
|
- * This will send unencrypted data (only protected by DTLS transport encryption) when no key is configured.
|
171
|
|
- * This is ok for demo purposes but should not be done once this becomes more relied upon.
|
172
|
|
- */
|
173
|
|
- controller.enqueue(encodedFrame);
|
174
|
180
|
}
|
175
|
181
|
|
176
|
182
|
/**
|
|
@@ -180,11 +186,14 @@ export class Context {
|
180
|
186
|
* @param {TransformStreamDefaultController} controller - TransportStreamController.
|
181
|
187
|
*/
|
182
|
188
|
async decodeFunction(encodedFrame, controller) {
|
|
189
|
+ if (!this._enabled) {
|
|
190
|
+ return controller.enqueue(encodedFrame);
|
|
191
|
+ }
|
|
192
|
+
|
183
|
193
|
const data = new Uint8Array(encodedFrame.data);
|
184
|
194
|
const keyIndex = data[encodedFrame.data.byteLength - 1];
|
185
|
195
|
|
186
|
196
|
if (this._cryptoKeyRing[keyIndex]) {
|
187
|
|
-
|
188
|
197
|
const decodedFrame = await this._decryptFrame(
|
189
|
198
|
encodedFrame,
|
190
|
199
|
keyIndex);
|