Skip to content

Commit

Permalink
Tests for ParticipantKeyHandler.ratchetKey() (#1288)
Browse files Browse the repository at this point in the history
* Tests for ParticipantKeyHandler.ratchetKey()

* Lint

* Format

* Create thirty-crabs-mate.md

---------

Co-authored-by: lukasIO <mail@lukasseiler.de>
  • Loading branch information
hughns and lukasIO authored Oct 11, 2024
1 parent 0f90c36 commit f0ad7e5
Show file tree
Hide file tree
Showing 4 changed files with 422 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-crabs-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"livekit-client": patch
---

[e2ee] await key update before emitting key ratchet event
62 changes: 60 additions & 2 deletions src/e2ee/worker/ParticipantKeyHandler.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest';
import { KEY_PROVIDER_DEFAULTS } from '../constants';
import { describe, expect, it, vitest } from 'vitest';
import { ENCRYPTION_ALGORITHM, KEY_PROVIDER_DEFAULTS } from '../constants';
import { KeyHandlerEvent } from '../events';
import { createKeyMaterialFromString } from '../utils';
import { ParticipantKeyHandler } from './ParticipantKeyHandler';

Expand Down Expand Up @@ -157,4 +158,61 @@ describe('ParticipantKeyHandler', () => {
expect(keyHandler.hasValidKey).toBe(true);
}
});

describe('ratchetKey', () => {
it('emits event', async () => {
const keyHandler = new ParticipantKeyHandler(participantIdentity, KEY_PROVIDER_DEFAULTS);

const material = await createKeyMaterialFromString('password');

const keyRatched = vitest.fn();

keyHandler.on(KeyHandlerEvent.KeyRatcheted, keyRatched);

await keyHandler.setKey(material);

await keyHandler.ratchetKey();

const newMaterial = keyHandler.getKeySet()?.material;

expect(keyRatched).toHaveBeenCalledWith(newMaterial, participantIdentity, 0);
});

it('ratchets keys predictably', async () => {
// we can't extract the keys directly, so we instead use them to encrypt a known plaintext
const keyHandler = new ParticipantKeyHandler(participantIdentity, KEY_PROVIDER_DEFAULTS);

const originalMaterial = await createKeyMaterialFromString('password');

await keyHandler.setKey(originalMaterial);

const ciphertexts: Uint8Array[] = [];

const plaintext = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

const iv = new Uint8Array(12);
const additionalData = new Uint8Array(0);

for (let i = 0; i < 10; i++) {
const { encryptionKey } = keyHandler.getKeySet()!;

const ciphertext = await crypto.subtle.encrypt(
{
name: ENCRYPTION_ALGORITHM,
iv,
additionalData,
},
encryptionKey,
plaintext,
);
ciphertexts.push(new Uint8Array(ciphertext));
await keyHandler.ratchetKey();
}
// check that all ciphertexts are unique
expect(new Set(ciphertexts.map((x) => new TextDecoder().decode(x))).size).toEqual(
ciphertexts.length,
);
expect(ciphertexts).matchSnapshot('ciphertexts');
});
});
});
2 changes: 1 addition & 1 deletion src/e2ee/worker/ParticipantKeyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class ParticipantKeyHandler extends (EventEmitter as new () => TypedEvent
);

if (setKey) {
this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
await this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
this.emit(
KeyHandlerEvent.KeyRatcheted,
newMaterial,
Expand Down
Loading

0 comments on commit f0ad7e5

Please sign in to comment.