Skip to content

Commit

Permalink
e2ee: add unit tests
Browse files Browse the repository at this point in the history
Both for just encode function as well as an end-to-end test.
  • Loading branch information
fippo committed Oct 2, 2020
1 parent 687a82e commit 6343419
Showing 1 changed file with 174 additions and 0 deletions.
174 changes: 174 additions & 0 deletions modules/e2ee/Context.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { Context } from './Context';
import { ratchet, importKey } from './crypto-utils';

/*
function hexdump(buffer) {
const a = new Uint8Array(buffer);
let s = '';
for (let i = 0; i < a.byteLength; i++) {
s += '0x';
s += a[i].toString(16);
s += ' ';
}
return s.trim();
}
*/

/* TODO: more tests
* - delta frames
* - frame header is not encrypted
* - different sendCounts
* - different key length
* - ratcheting in decodeFunction
* etc
*/
const audioBytes = [ 0xde, 0xad, 0xbe, 0xef ];
const videoBytes = [ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef ];

describe('E2EE Context', () => {
let sender;
let receiver;
const key = new Uint8Array([
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]);

beforeEach(() => {
sender = new Context('sender');
receiver = new Context('receiver');
});

describe('encode function', () => {
it('with an audio frame', async done => {
const sendController = {
enqueue: encodedFrame => {
const data = new Uint8Array(encodedFrame.data);

// An audio frame will have an overhead of 6 bytes with this counter and key size:
// 4 bytes truncated signature, counter (1 byte) and 1 byte trailer.
expect(data.byteLength).toEqual(audioBytes.length + 6);

// TODO: provide test vector and matcher.
done();
}
};
const frame = {
data: new Uint8Array(audioBytes).buffer,
type: undefined // type is undefined for audio frames.
};

await sender.setKey(key, 0);
await receiver.setKey(key, 0);
await sender.encodeFunction(frame, sendController);
});

it('with a video frame', async done => {
const sendController = {
enqueue: encodedFrame => {
const data = new Uint8Array(encodedFrame.data);

// A video frame will have an overhead of 12 bytes with this counter and key size:
// 10 bytes signature, counter (1 byte) and 1 byte trailer.

expect(data.byteLength).toEqual(videoBytes.length + 12);

// TODO: provide test vector and matcher.
done();
}
};
const frame = {
data: new Uint8Array(videoBytes).buffer,
type: 'key'
};

await sender.setKey(key, 0);
await receiver.setKey(key, 0);
await sender.encodeFunction(frame, sendController);
});
});

describe('end-to-end test', () => {
it('with an audio frame', async done => {
await sender.setKey(key, 0);
await receiver.setKey(key, 0);
const receiveController = {
enqueue: encodedFrame => {
const data = new Uint8Array(encodedFrame.data);

expect(data.byteLength).toEqual(audioBytes.length);
expect(Array.from(data)).toEqual(audioBytes);
done();
}
};
const sendController = {
enqueue: encodedFrame => {
receiver.decodeFunction(encodedFrame, receiveController);
}
};
const frame = {
data: new Uint8Array(audioBytes).buffer,
type: undefined // type is undefined for audio frames.
};

await sender.encodeFunction(frame, sendController);
});

it('with a video frame', async done => {
await sender.setKey(key, 0);
await receiver.setKey(key, 0);
const receiveController = {
enqueue: encodedFrame => {
const data = new Uint8Array(encodedFrame.data);

expect(data.byteLength).toEqual(videoBytes.length);
expect(Array.from(data)).toEqual(videoBytes);
done();
}
};
const sendController = {
enqueue: encodedFrame => {
receiver.decodeFunction(encodedFrame, receiveController);
}
};
const frame = {
data: new Uint8Array(videoBytes).buffer,
type: 'key'
};

await sender.encodeFunction(frame, sendController);
});

it('the receiver ratchets forward', async done => {
await sender.setKey(key, 0);
await receiver.setKey(key, 0);

// Ratchet the key. We reimport from the raw bytes.
const material = await importKey(key);

await sender.setKey(await ratchet(material), 0);

const receiveController = {
enqueue: encodedFrame => {
const data = new Uint8Array(encodedFrame.data);

expect(data.byteLength).toEqual(audioBytes.length);
expect(Array.from(data)).toEqual(audioBytes);
done();
}
};
const sendController = {
enqueue: encodedFrame => {
receiver.decodeFunction(encodedFrame, receiveController);
}
};
const frame = {
data: new Uint8Array(audioBytes).buffer,
type: undefined
};

await sender.encodeFunction(frame, sendController);
});
});
});

0 comments on commit 6343419

Please sign in to comment.