2018-11-02 18:02:53 +00:00
|
|
|
/* global Signal, textsecure */
|
|
|
|
|
2018-03-19 19:42:12 +00:00
|
|
|
'use strict';
|
|
|
|
|
2018-10-18 01:01:21 +00:00
|
|
|
describe('Crypto', () => {
|
|
|
|
describe('accessKey/profileKey', () => {
|
|
|
|
it('verification roundtrips', async () => {
|
|
|
|
const profileKey = await Signal.Crypto.getRandomBytes(32);
|
|
|
|
const accessKey = await Signal.Crypto.deriveAccessKey(profileKey);
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-10-18 01:01:21 +00:00
|
|
|
const verifier = await Signal.Crypto.getAccessKeyVerifier(accessKey);
|
|
|
|
|
|
|
|
const correct = await Signal.Crypto.verifyAccessKey(accessKey, verifier);
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-10-18 01:01:21 +00:00
|
|
|
assert.strictEqual(correct, true);
|
|
|
|
});
|
2018-03-19 19:42:12 +00:00
|
|
|
});
|
|
|
|
|
2018-10-18 01:01:21 +00:00
|
|
|
describe('symmetric encryption', () => {
|
|
|
|
it('roundtrips', async () => {
|
2018-11-02 18:02:53 +00:00
|
|
|
const message = 'this is my message';
|
|
|
|
const plaintext = dcodeIO.ByteBuffer.wrap(
|
2018-10-18 01:01:21 +00:00
|
|
|
message,
|
|
|
|
'binary'
|
|
|
|
).toArrayBuffer();
|
2018-11-02 18:02:53 +00:00
|
|
|
const key = textsecure.crypto.getRandomBytes(32);
|
2018-10-18 01:01:21 +00:00
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
const encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
|
|
|
|
const decrypted = await Signal.Crypto.decryptSymmetric(key, encrypted);
|
2018-10-18 01:01:21 +00:00
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
const equal = Signal.Crypto.constantTimeEqual(plaintext, decrypted);
|
2018-10-18 01:01:21 +00:00
|
|
|
if (!equal) {
|
|
|
|
throw new Error('The output and input did not match!');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it('roundtrip fails if nonce is modified', async () => {
|
2018-11-02 18:02:53 +00:00
|
|
|
const message = 'this is my message';
|
|
|
|
const plaintext = dcodeIO.ByteBuffer.wrap(
|
2018-10-18 01:01:21 +00:00
|
|
|
message,
|
|
|
|
'binary'
|
|
|
|
).toArrayBuffer();
|
2018-11-02 18:02:53 +00:00
|
|
|
const key = textsecure.crypto.getRandomBytes(32);
|
2018-10-18 01:01:21 +00:00
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
const encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
|
|
|
|
const uintArray = new Uint8Array(encrypted);
|
2018-10-18 01:01:21 +00:00
|
|
|
uintArray[2] = 9;
|
|
|
|
|
|
|
|
try {
|
2018-11-02 18:02:53 +00:00
|
|
|
await Signal.Crypto.decryptSymmetric(key, uintArray.buffer);
|
2018-10-18 01:01:21 +00:00
|
|
|
} catch (error) {
|
|
|
|
assert.strictEqual(
|
|
|
|
error.message,
|
|
|
|
'decryptSymmetric: Failed to decrypt; MAC verification failed'
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Expected error to be thrown');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('roundtrip fails if mac is modified', async () => {
|
2018-11-02 18:02:53 +00:00
|
|
|
const message = 'this is my message';
|
|
|
|
const plaintext = dcodeIO.ByteBuffer.wrap(
|
2018-10-18 01:01:21 +00:00
|
|
|
message,
|
|
|
|
'binary'
|
|
|
|
).toArrayBuffer();
|
2018-11-02 18:02:53 +00:00
|
|
|
const key = textsecure.crypto.getRandomBytes(32);
|
2018-10-18 01:01:21 +00:00
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
const encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
|
|
|
|
const uintArray = new Uint8Array(encrypted);
|
2018-10-18 01:01:21 +00:00
|
|
|
uintArray[uintArray.length - 3] = 9;
|
|
|
|
|
|
|
|
try {
|
2018-11-02 18:02:53 +00:00
|
|
|
await Signal.Crypto.decryptSymmetric(key, uintArray.buffer);
|
2018-10-18 01:01:21 +00:00
|
|
|
} catch (error) {
|
|
|
|
assert.strictEqual(
|
|
|
|
error.message,
|
|
|
|
'decryptSymmetric: Failed to decrypt; MAC verification failed'
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Expected error to be thrown');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('roundtrip fails if encrypted contents are modified', async () => {
|
2018-11-02 18:02:53 +00:00
|
|
|
const message = 'this is my message';
|
|
|
|
const plaintext = dcodeIO.ByteBuffer.wrap(
|
2018-10-18 01:01:21 +00:00
|
|
|
message,
|
|
|
|
'binary'
|
|
|
|
).toArrayBuffer();
|
2018-11-02 18:02:53 +00:00
|
|
|
const key = textsecure.crypto.getRandomBytes(32);
|
2018-10-18 01:01:21 +00:00
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
const encrypted = await Signal.Crypto.encryptSymmetric(key, plaintext);
|
|
|
|
const uintArray = new Uint8Array(encrypted);
|
2018-10-18 01:01:21 +00:00
|
|
|
uintArray[35] = 9;
|
|
|
|
|
|
|
|
try {
|
2018-11-02 18:02:53 +00:00
|
|
|
await Signal.Crypto.decryptSymmetric(key, uintArray.buffer);
|
2018-10-18 01:01:21 +00:00
|
|
|
} catch (error) {
|
|
|
|
assert.strictEqual(
|
|
|
|
error.message,
|
|
|
|
'decryptSymmetric: Failed to decrypt; MAC verification failed'
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Expected error to be thrown');
|
|
|
|
});
|
2018-03-19 19:42:12 +00:00
|
|
|
});
|
|
|
|
});
|