浏览代码

e2ee: sync ratchetted key with olm layer

dev1
Saúl Ibarra Corretgé 5 年前
父节点
当前提交
25f08f97c3
共有 4 个文件被更改,包括 33 次插入44 次删除
  1. 0
    11
      modules/e2ee/E2EEContext.js
  2. 19
    9
      modules/e2ee/E2EEncryption.js
  3. 14
    1
      modules/e2ee/OlmAdapter.js
  4. 0
    23
      modules/e2ee/Worker.js

+ 0
- 11
modules/e2ee/E2EEContext.js 查看文件

@@ -139,15 +139,4 @@ export default class E2EEcontext {
139 139
             keyIndex
140 140
         });
141 141
     }
142
-
143
-    /**
144
-     * Ratchet our own key.
145
-     * @param {string} participantId - the ID of the participant who's key we should ratchet.
146
-     */
147
-    ratchet(participantId) {
148
-        this._worker.postMessage({
149
-            operation: 'ratchet',
150
-            participantId
151
-        });
152
-    }
153 142
 }

+ 19
- 9
modules/e2ee/E2EEncryption.js 查看文件

@@ -30,6 +30,7 @@ export class E2EEncryption {
30 30
         this._conferenceJoined = false;
31 31
         this._enabled = false;
32 32
         this._initialized = false;
33
+        this._key = undefined;
33 34
 
34 35
         this._e2eeCtx = new E2EEContext();
35 36
         this._olmAdapter = new OlmAdapter(conference);
@@ -125,12 +126,12 @@ export class E2EEncryption {
125 126
         }
126 127
 
127 128
         // Generate a random key in case we are enabling.
128
-        const key = enabled ? this._generateKey() : false;
129
+        this._key = enabled ? this._generateKey() : false;
129 130
 
130 131
         // Send it to others using the E2EE olm channel.
131
-        this._olmAdapter.updateKey(key).then(index => {
132
+        this._olmAdapter.updateKey(this._key).then(index => {
132 133
             // Set our key so we begin encrypting.
133
-            this._e2eeCtx.setKey(this.conference.myUserId(), key, index);
134
+            this._e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
134 135
         });
135 136
     }
136 137
 
@@ -224,10 +225,19 @@ export class E2EEncryption {
224 225
     async _ratchetKeyImpl() {
225 226
         logger.debug('Ratchetting key');
226 227
 
227
-        this._e2eeCtx.ratchet(this.conference.myUserId());
228
+        const material = await crypto.subtle.importKey('raw', this._key, 'HKDF', false, [ 'deriveBits' ]);
229
+        const newKey = await crypto.subtle.deriveBits({
230
+            name: 'HKDF',
231
+            salt: new TextEncoder().encode('JFrameRatchetKey'),
232
+            hash: 'SHA-256',
233
+            info: new ArrayBuffer()
234
+        }, material, 256);
228 235
 
229
-        // TODO: how do we tell the olm adapter which might need to send the current ratchet key
230
-        //      to the other side?
236
+        this._key = new Uint8Array(newKey);
237
+
238
+        const index = await this._olmAdapter.updateCurrentKey(this._key);
239
+
240
+        this._e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
231 241
     }
232 242
 
233 243
     /**
@@ -239,10 +249,10 @@ export class E2EEncryption {
239 249
     async _rotateKeyImpl() {
240 250
         logger.debug('Rotating key');
241 251
 
242
-        const key = this._generateKey();
243
-        const index = await this._olmAdapter.updateKey(key);
252
+        this._key = this._generateKey();
253
+        const index = await this._olmAdapter.updateKey(this._key);
244 254
 
245
-        this._e2eeCtx.setKey(this.conference.myUserId(), key, index);
255
+        this._e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
246 256
     }
247 257
 
248 258
     /**

+ 14
- 1
modules/e2ee/OlmAdapter.js 查看文件

@@ -83,6 +83,19 @@ export class OlmAdapter extends Listenable {
83 83
         return typeof window.Olm !== 'undefined';
84 84
     }
85 85
 
86
+    /**
87
+     * Updates the current participant key and distributes it to all participants in the conference
88
+     * by sending a key-info message.
89
+     *
90
+     * @param {Uint8Array|boolean} key - The new key.
91
+     * @returns {number}
92
+     */
93
+    async updateCurrentKey(key) {
94
+        this._key = key;
95
+
96
+        return this._keyIndex;
97
+    }
98
+
86 99
     /**
87 100
      * Updates the current participant key and distributes it to all participants in the conference
88 101
      * by sending a key-info message.
@@ -95,9 +108,9 @@ export class OlmAdapter extends Listenable {
95 108
         this._key = key;
96 109
         this._keyIndex++;
97 110
 
111
+        // Broadcast it.
98 112
         const promises = [];
99 113
 
100
-        // Broadcast it.
101 114
         for (const participant of this._conf.getParticipants()) {
102 115
             const pId = participant.getId();
103 116
             const olmData = this._getParticipantOlmData(participant);

+ 0
- 23
modules/e2ee/Worker.js 查看文件

@@ -192,16 +192,6 @@ class Context {
192 192
         this._sendCount = 0n; // Reset the send count (bigint).
193 193
     }
194 194
 
195
-    /**
196
-     * Ratchets a key forward one step.
197
-     */
198
-    async ratchet() {
199
-        const keys = this._cryptoKeyRing[this._currentKeyIndex];
200
-        const material = await ratchet(keys.material);
201
-
202
-        this.setKey(material, this._currentKeyIndex);
203
-    }
204
-
205 195
     /**
206 196
      * Function that will be injected in a stream and will encrypt the given encoded frames.
207 197
      *
@@ -484,19 +474,6 @@ onmessage = async event => {
484 474
         } else {
485 475
             context.setKey(false, keyIndex);
486 476
         }
487
-    } else if (operation === 'ratchet') {
488
-        const { participantId } = event.data;
489
-
490
-        // TODO: can we ensure this is for our own sender key?
491
-
492
-        if (!contexts.has(participantId)) {
493
-            console.error('Could not find context for', participantId);
494
-
495
-            return;
496
-        }
497
-        const context = contexts.get(participantId);
498
-
499
-        context.ratchet();
500 477
     } else if (operation === 'cleanup') {
501 478
         const { participantId } = event.data;
502 479
 

正在加载...
取消
保存