2020-10-30 20:34:04 +00:00
|
|
|
// Copyright 2017-2020 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
import { assert } from 'chai';
|
2021-09-10 02:38:11 +00:00
|
|
|
import { v4 as getGuid } from 'uuid';
|
2021-08-03 22:26:00 +00:00
|
|
|
|
|
|
|
import { getRandomBytes } from '../../Crypto';
|
|
|
|
import AccountManager from '../../textsecure/AccountManager';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { OuterSignedPrekeyType } from '../../textsecure/Types.d';
|
2021-09-10 02:38:11 +00:00
|
|
|
import { UUID } from '../../types/UUID';
|
2021-08-03 22:26:00 +00:00
|
|
|
|
|
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
describe('AccountManager', () => {
|
2021-08-03 22:26:00 +00:00
|
|
|
let accountManager: AccountManager;
|
2017-12-01 21:35:39 +00:00
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
beforeEach(() => {
|
2021-08-03 22:26:00 +00:00
|
|
|
const server: any = {};
|
|
|
|
accountManager = new AccountManager(server);
|
2017-12-01 21:35:39 +00:00
|
|
|
});
|
|
|
|
|
2018-07-21 21:51:20 +00:00
|
|
|
describe('#cleanSignedPreKeys', () => {
|
2021-08-03 22:26:00 +00:00
|
|
|
let originalGetIdentityKeyPair: any;
|
|
|
|
let originalLoadSignedPreKeys: any;
|
|
|
|
let originalRemoveSignedPreKey: any;
|
2021-09-10 02:38:11 +00:00
|
|
|
let originalGetUuid: any;
|
2021-08-03 22:26:00 +00:00
|
|
|
let signedPreKeys: Array<OuterSignedPrekeyType>;
|
2017-12-01 21:35:39 +00:00
|
|
|
const DAY = 1000 * 60 * 60 * 24;
|
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
const pubKey = getRandomBytes(33);
|
|
|
|
const privKey = getRandomBytes(32);
|
2021-09-10 02:38:11 +00:00
|
|
|
const identityKey = window.Signal.Curve.generateKeyPair();
|
2021-08-03 22:26:00 +00:00
|
|
|
|
2018-12-13 19:12:33 +00:00
|
|
|
beforeEach(async () => {
|
2021-09-10 02:38:11 +00:00
|
|
|
const ourUuid = new UUID(getGuid());
|
2018-12-13 19:12:33 +00:00
|
|
|
|
2021-09-10 02:38:11 +00:00
|
|
|
originalGetUuid = window.textsecure.storage.user.getUuid;
|
2021-08-03 22:26:00 +00:00
|
|
|
originalGetIdentityKeyPair =
|
|
|
|
window.textsecure.storage.protocol.getIdentityKeyPair;
|
|
|
|
originalLoadSignedPreKeys =
|
|
|
|
window.textsecure.storage.protocol.loadSignedPreKeys;
|
|
|
|
originalRemoveSignedPreKey =
|
|
|
|
window.textsecure.storage.protocol.removeSignedPreKey;
|
|
|
|
|
2021-09-10 02:38:11 +00:00
|
|
|
window.textsecure.storage.user.getUuid = () => ourUuid;
|
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
window.textsecure.storage.protocol.getIdentityKeyPair = async () =>
|
|
|
|
identityKey;
|
|
|
|
window.textsecure.storage.protocol.loadSignedPreKeys = async () =>
|
|
|
|
signedPreKeys;
|
2017-12-01 21:35:39 +00:00
|
|
|
});
|
2018-07-21 21:51:20 +00:00
|
|
|
afterEach(() => {
|
2021-09-10 02:38:11 +00:00
|
|
|
window.textsecure.storage.user.getUuid = originalGetUuid;
|
2021-11-11 22:43:05 +00:00
|
|
|
window.textsecure.storage.protocol.getIdentityKeyPair =
|
|
|
|
originalGetIdentityKeyPair;
|
|
|
|
window.textsecure.storage.protocol.loadSignedPreKeys =
|
|
|
|
originalLoadSignedPreKeys;
|
|
|
|
window.textsecure.storage.protocol.removeSignedPreKey =
|
|
|
|
originalRemoveSignedPreKey;
|
2017-12-01 21:35:39 +00:00
|
|
|
});
|
|
|
|
|
2018-12-13 19:12:33 +00:00
|
|
|
describe('encrypted device name', () => {
|
|
|
|
it('roundtrips', async () => {
|
|
|
|
const deviceName = 'v2.5.0 on Ubunto 20.04';
|
2021-09-24 00:49:05 +00:00
|
|
|
const encrypted = accountManager.encryptDeviceName(
|
2021-09-10 02:38:11 +00:00
|
|
|
deviceName,
|
|
|
|
identityKey
|
|
|
|
);
|
2021-08-03 22:26:00 +00:00
|
|
|
if (!encrypted) {
|
|
|
|
throw new Error('failed to encrypt!');
|
|
|
|
}
|
2018-12-13 19:12:33 +00:00
|
|
|
assert.strictEqual(typeof encrypted, 'string');
|
|
|
|
const decrypted = await accountManager.decryptDeviceName(encrypted);
|
|
|
|
|
|
|
|
assert.strictEqual(decrypted, deviceName);
|
|
|
|
});
|
2019-01-29 17:39:55 +00:00
|
|
|
|
2021-09-24 00:49:05 +00:00
|
|
|
it('handles falsey deviceName', () => {
|
|
|
|
const encrypted = accountManager.encryptDeviceName('', identityKey);
|
2019-01-29 17:39:55 +00:00
|
|
|
assert.strictEqual(encrypted, null);
|
|
|
|
});
|
2018-12-13 19:12:33 +00:00
|
|
|
});
|
|
|
|
|
2020-12-17 23:29:20 +00:00
|
|
|
it('keeps three confirmed keys even if over a month old', () => {
|
2017-12-01 21:35:39 +00:00
|
|
|
const now = Date.now();
|
2018-05-02 16:51:22 +00:00
|
|
|
signedPreKeys = [
|
|
|
|
{
|
|
|
|
keyId: 1,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 32,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 2,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 34,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 3,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 38,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
];
|
2017-12-01 21:35:39 +00:00
|
|
|
|
|
|
|
// should be no calls to store.removeSignedPreKey, would cause crash
|
|
|
|
return accountManager.cleanSignedPreKeys();
|
|
|
|
});
|
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
it('eliminates oldest keys, even if recent key is unconfirmed', async () => {
|
2017-12-01 21:35:39 +00:00
|
|
|
const now = Date.now();
|
2018-05-02 16:51:22 +00:00
|
|
|
signedPreKeys = [
|
|
|
|
{
|
|
|
|
keyId: 1,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 32,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 2,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 31,
|
2021-08-03 22:26:00 +00:00
|
|
|
confirmed: false,
|
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 3,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 24,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
2021-08-03 22:26:00 +00:00
|
|
|
// Oldest, should be dropped
|
2018-05-02 16:51:22 +00:00
|
|
|
keyId: 4,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 38,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 5,
|
|
|
|
created_at: now - DAY,
|
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
2021-08-03 22:26:00 +00:00
|
|
|
keyId: 6,
|
|
|
|
created_at: now - DAY * 5,
|
|
|
|
confirmed: true,
|
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
];
|
2017-12-01 21:35:39 +00:00
|
|
|
|
|
|
|
let count = 0;
|
2021-09-10 02:38:11 +00:00
|
|
|
window.textsecure.storage.protocol.removeSignedPreKey = async (
|
|
|
|
_,
|
|
|
|
keyId
|
|
|
|
) => {
|
2021-08-03 22:26:00 +00:00
|
|
|
if (keyId !== 4) {
|
2018-07-21 21:51:20 +00:00
|
|
|
throw new Error(`Wrong keys were eliminated! ${keyId}`);
|
2017-12-01 21:35:39 +00:00
|
|
|
}
|
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
count += 1;
|
2017-12-01 21:35:39 +00:00
|
|
|
};
|
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
await accountManager.cleanSignedPreKeys();
|
|
|
|
assert.strictEqual(count, 1);
|
2017-12-01 21:35:39 +00:00
|
|
|
});
|
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
it('Removes no keys if less than five', async () => {
|
2017-12-01 21:35:39 +00:00
|
|
|
const now = Date.now();
|
2018-05-02 16:51:22 +00:00
|
|
|
signedPreKeys = [
|
|
|
|
{
|
|
|
|
keyId: 1,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 32,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 2,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 44,
|
2018-05-02 16:51:22 +00:00
|
|
|
confirmed: true,
|
2021-08-03 22:26:00 +00:00
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 3,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 36,
|
2021-08-03 22:26:00 +00:00
|
|
|
confirmed: false,
|
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
keyId: 4,
|
2020-12-17 23:29:20 +00:00
|
|
|
created_at: now - DAY * 20,
|
2021-08-03 22:26:00 +00:00
|
|
|
confirmed: false,
|
|
|
|
pubKey,
|
|
|
|
privKey,
|
2018-05-02 16:51:22 +00:00
|
|
|
},
|
|
|
|
];
|
2017-12-01 21:35:39 +00:00
|
|
|
|
2021-08-03 22:26:00 +00:00
|
|
|
window.textsecure.storage.protocol.removeSignedPreKey = async () => {
|
|
|
|
throw new Error('None should be removed!');
|
2017-12-01 21:35:39 +00:00
|
|
|
};
|
|
|
|
|
2018-11-02 18:02:53 +00:00
|
|
|
await accountManager.cleanSignedPreKeys();
|
2017-12-01 21:35:39 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|