2020-10-30 20:34:04 +00:00
|
|
|
// Copyright 2015-2020 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2021-04-16 23:13:13 +00:00
|
|
|
/* global textsecure */
|
2018-11-02 18:02:53 +00:00
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
describe('encrypting and decrypting profile data', () => {
|
2020-01-13 22:28:28 +00:00
|
|
|
const NAME_PADDED_LENGTH = 53;
|
2018-07-21 21:51:20 +00:00
|
|
|
describe('encrypting and decrypting profile names', () => {
|
|
|
|
it('pads, encrypts, decrypts, and unpads a short string', () => {
|
|
|
|
const name = 'Alice';
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(name).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2017-09-11 16:50:35 +00:00
|
|
|
|
2018-05-02 16:51:22 +00:00
|
|
|
return textsecure.crypto
|
|
|
|
.encryptProfileName(buffer, key)
|
2018-07-21 21:51:20 +00:00
|
|
|
.then(encrypted => {
|
2018-05-02 16:51:22 +00:00
|
|
|
assert(encrypted.byteLength === NAME_PADDED_LENGTH + 16 + 12);
|
|
|
|
return textsecure.crypto
|
|
|
|
.decryptProfileName(encrypted, key)
|
2020-01-13 22:28:28 +00:00
|
|
|
.then(({ given, family }) => {
|
|
|
|
assert.strictEqual(family, null);
|
2018-05-02 16:51:22 +00:00
|
|
|
assert.strictEqual(
|
2020-01-13 22:28:28 +00:00
|
|
|
dcodeIO.ByteBuffer.wrap(given).toString('utf8'),
|
|
|
|
name
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('handles a given name of the max, 53 characters', () => {
|
|
|
|
const name = '01234567890123456789012345678901234567890123456789123';
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(name).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2020-01-13 22:28:28 +00:00
|
|
|
|
|
|
|
return textsecure.crypto
|
|
|
|
.encryptProfileName(buffer, key)
|
|
|
|
.then(encrypted => {
|
|
|
|
assert(encrypted.byteLength === NAME_PADDED_LENGTH + 16 + 12);
|
|
|
|
return textsecure.crypto
|
|
|
|
.decryptProfileName(encrypted, key)
|
|
|
|
.then(({ given, family }) => {
|
|
|
|
assert.strictEqual(
|
|
|
|
dcodeIO.ByteBuffer.wrap(given).toString('utf8'),
|
|
|
|
name
|
|
|
|
);
|
|
|
|
assert.strictEqual(family, null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('handles family/given name of the max, 53 characters', () => {
|
|
|
|
const name = '01234567890123456789\u000001234567890123456789012345678912';
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(name).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2020-01-13 22:28:28 +00:00
|
|
|
|
|
|
|
return textsecure.crypto
|
|
|
|
.encryptProfileName(buffer, key)
|
|
|
|
.then(encrypted => {
|
|
|
|
assert(encrypted.byteLength === NAME_PADDED_LENGTH + 16 + 12);
|
|
|
|
return textsecure.crypto
|
|
|
|
.decryptProfileName(encrypted, key)
|
|
|
|
.then(({ given, family }) => {
|
|
|
|
assert.strictEqual(
|
|
|
|
dcodeIO.ByteBuffer.wrap(given).toString('utf8'),
|
|
|
|
'01234567890123456789'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
dcodeIO.ByteBuffer.wrap(family).toString('utf8'),
|
|
|
|
'01234567890123456789012345678912'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
it('handles a string with family/given name', () => {
|
|
|
|
const name = 'Alice\0Jones';
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(name).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2020-01-13 22:28:28 +00:00
|
|
|
|
|
|
|
return textsecure.crypto
|
|
|
|
.encryptProfileName(buffer, key)
|
|
|
|
.then(encrypted => {
|
|
|
|
assert(encrypted.byteLength === NAME_PADDED_LENGTH + 16 + 12);
|
|
|
|
return textsecure.crypto
|
|
|
|
.decryptProfileName(encrypted, key)
|
|
|
|
.then(({ given, family }) => {
|
|
|
|
assert.strictEqual(
|
|
|
|
dcodeIO.ByteBuffer.wrap(given).toString('utf8'),
|
2018-05-02 16:51:22 +00:00
|
|
|
'Alice'
|
|
|
|
);
|
2020-01-13 22:28:28 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
dcodeIO.ByteBuffer.wrap(family).toString('utf8'),
|
|
|
|
'Jones'
|
|
|
|
);
|
2018-05-02 16:51:22 +00:00
|
|
|
});
|
2017-09-11 16:50:35 +00:00
|
|
|
});
|
|
|
|
});
|
2021-04-16 23:13:13 +00:00
|
|
|
it('works for empty string', async () => {
|
2018-07-21 21:51:20 +00:00
|
|
|
const name = dcodeIO.ByteBuffer.wrap('').toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2017-09-11 16:50:35 +00:00
|
|
|
|
2021-04-16 23:13:13 +00:00
|
|
|
const encrypted = await textsecure.crypto.encryptProfileName(name, key);
|
|
|
|
assert(encrypted.byteLength === NAME_PADDED_LENGTH + 16 + 12);
|
|
|
|
|
|
|
|
const { given, family } = await textsecure.crypto.decryptProfileName(
|
|
|
|
encrypted,
|
|
|
|
key
|
|
|
|
);
|
|
|
|
assert.strictEqual(family, null);
|
|
|
|
assert.strictEqual(given.byteLength, 0);
|
|
|
|
assert.strictEqual(dcodeIO.ByteBuffer.wrap(given).toString('utf8'), '');
|
2017-09-11 16:50:35 +00:00
|
|
|
});
|
|
|
|
});
|
2018-07-21 21:51:20 +00:00
|
|
|
describe('encrypting and decrypting profile avatars', () => {
|
|
|
|
it('encrypts and decrypts', () => {
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(
|
|
|
|
'This is an avatar'
|
|
|
|
).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
2017-09-11 16:50:35 +00:00
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
return textsecure.crypto.encryptProfile(buffer, key).then(encrypted => {
|
|
|
|
assert(encrypted.byteLength === buffer.byteLength + 16 + 12);
|
|
|
|
return textsecure.crypto
|
|
|
|
.decryptProfile(encrypted, key)
|
|
|
|
.then(decrypted => {
|
|
|
|
assertEqualArrayBuffers(buffer, decrypted);
|
|
|
|
});
|
|
|
|
});
|
2017-09-11 16:50:35 +00:00
|
|
|
});
|
2018-07-21 21:51:20 +00:00
|
|
|
it('throws when decrypting with the wrong key', () => {
|
|
|
|
const buffer = dcodeIO.ByteBuffer.wrap(
|
|
|
|
'This is an avatar'
|
|
|
|
).toArrayBuffer();
|
2021-04-16 23:13:13 +00:00
|
|
|
const key = window.Signal.Crypto.getRandomBytes(32);
|
|
|
|
const badKey = window.Signal.Crypto.getRandomBytes(32);
|
2017-09-11 16:50:35 +00:00
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
return textsecure.crypto.encryptProfile(buffer, key).then(encrypted => {
|
|
|
|
assert(encrypted.byteLength === buffer.byteLength + 16 + 12);
|
|
|
|
return textsecure.crypto
|
2018-11-02 18:02:53 +00:00
|
|
|
.decryptProfile(encrypted, badKey)
|
2018-07-21 21:51:20 +00:00
|
|
|
.catch(error => {
|
|
|
|
assert.strictEqual(error.name, 'ProfileDecryptError');
|
|
|
|
});
|
|
|
|
});
|
2017-09-11 16:50:35 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|