element-web/test/unit-tests/utils/MegolmExportEncryption-test.ts

155 lines
5.7 KiB
TypeScript
Raw Normal View History

/*
Copyright 2024 New Vector Ltd.
Copyright 2017 Vector Creations Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
2021-06-29 14:11:58 +02:00
import { TextEncoder } from "util";
2019-12-17 12:24:37 +01:00
import nodeCrypto from "crypto";
import { Crypto } from "@peculiar/webcrypto";
import type * as MegolmExportEncryptionExport from "../../../src/utils/MegolmExportEncryption";
2019-12-17 12:24:37 +01:00
const webCrypto = new Crypto();
2019-12-16 12:55:01 +01:00
function getRandomValues<T extends ArrayBufferView | null>(buf: T): T {
Test typescriptification continued (#8327) * test/utils/MegolmExportEncryption-test.js -> test/utils/MegolmExportEncryption-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * test/utils/ShieldUtils-test.js - test/utils/ShieldUtils-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * type fixes for ShieldUtils-test Signed-off-by: Kerry Archibald <kerrya@element.io> * test/DecryptionFailureTracker-test.js -> test/DecryptionFailureTracker-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * remove unsupported assertion failure messages Signed-off-by: Kerry Archibald <kerrya@element.io> * fix ts issues in DecryptionFailureTracker Signed-off-by: Kerry Archibald <kerrya@element.io> * add mock restores Signed-off-by: Kerry Archibald <kerrya@element.io> * newline Signed-off-by: Kerry Archibald <kerrya@element.io> * remove commented decriptionfailuretracker code and test Signed-off-by: Kerry Archibald <kerrya@element.io> * make should aggregate error codes correctly pass Signed-off-by: Kerry Archibald <kerrya@element.io> * cheaters types in MegolmExportEncryption Signed-off-by: Kerry Archibald <kerrya@element.io> * lint Signed-off-by: Kerry Archibald <kerrya@element.io> * Revert "fix ts issues in DecryptionFailureTracker" This reverts commit 1ae748cc51088d60722320dbefae04a62310e2e1. Signed-off-by: Kerry Archibald <kerrya@element.io> * Revert "remove unsupported assertion failure messages" This reverts commit 7bd93d075c4d8d45befcbfd59c889782c9a44b48. * Revert "test/DecryptionFailureTracker-test.js -> test/DecryptionFailureTracker-test.ts" This reverts commit 1670025bd2af9a355c2761998202f602d61f242e. * revert change to DecryptionFailureTracker Signed-off-by: Kerry Archibald <kerrya@element.io>
2022-05-02 09:57:35 +02:00
// @ts-ignore fussy generics
2019-12-17 12:24:37 +01:00
return nodeCrypto.randomFillSync(buf);
2019-12-16 12:55:01 +01:00
}
2022-12-12 12:24:14 +01:00
const TEST_VECTORS = [
[
"plain",
"password",
2017-06-08 14:12:27 +02:00
"-----BEGIN MEGOLM SESSION DATA-----\n" +
2022-12-12 12:24:14 +01:00
"AXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" +
"cissyYBxjsfsAndErh065A8=\n" +
"-----END MEGOLM SESSION DATA-----",
],
[
"Hello, World",
"betterpassword",
2017-06-08 14:12:27 +02:00
"-----BEGIN MEGOLM SESSION DATA-----\n" +
2022-12-12 12:24:14 +01:00
"AW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" +
"KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n" +
"-----END MEGOLM SESSION DATA-----",
],
[
"alphanumericallyalphanumericallyalphanumericallyalphanumerically",
"SWORDFISH",
2017-06-08 14:12:27 +02:00
"-----BEGIN MEGOLM SESSION DATA-----\n" +
2022-12-12 12:24:14 +01:00
"AXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" +
"MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\n" +
"Pgg29363BGR+/Ripq/VCLKGNbw==\n" +
"-----END MEGOLM SESSION DATA-----",
],
[
"alphanumericallyalphanumericallyalphanumericallyalphanumerically",
2017-06-08 14:12:27 +02:00
"passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" +
2022-12-12 12:24:14 +01:00
"passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpassword",
2017-06-08 14:12:27 +02:00
"-----BEGIN MEGOLM SESSION DATA-----\n" +
2022-12-12 12:24:14 +01:00
"Af//////////////////////////////////////////AAAD6IAZJy7IQ7Y0idqSw/bmpngEEVVh\n" +
"gsH+8ptgqxw6ZVWQnohr8JsuwH9SwGtiebZuBu5smPCO+RFVWH2cQYslZijXv/BEH/txvhUrrtCd\n" +
"bWnSXS9oymiqwUIGs08sXI33ZA==\n" +
"-----END MEGOLM SESSION DATA-----",
2017-06-08 14:12:27 +02:00
],
2019-12-16 12:12:48 +01:00
];
Test typescriptification continued (#8327) * test/utils/MegolmExportEncryption-test.js -> test/utils/MegolmExportEncryption-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * test/utils/ShieldUtils-test.js - test/utils/ShieldUtils-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * type fixes for ShieldUtils-test Signed-off-by: Kerry Archibald <kerrya@element.io> * test/DecryptionFailureTracker-test.js -> test/DecryptionFailureTracker-test.ts Signed-off-by: Kerry Archibald <kerrya@element.io> * remove unsupported assertion failure messages Signed-off-by: Kerry Archibald <kerrya@element.io> * fix ts issues in DecryptionFailureTracker Signed-off-by: Kerry Archibald <kerrya@element.io> * add mock restores Signed-off-by: Kerry Archibald <kerrya@element.io> * newline Signed-off-by: Kerry Archibald <kerrya@element.io> * remove commented decriptionfailuretracker code and test Signed-off-by: Kerry Archibald <kerrya@element.io> * make should aggregate error codes correctly pass Signed-off-by: Kerry Archibald <kerrya@element.io> * cheaters types in MegolmExportEncryption Signed-off-by: Kerry Archibald <kerrya@element.io> * lint Signed-off-by: Kerry Archibald <kerrya@element.io> * Revert "fix ts issues in DecryptionFailureTracker" This reverts commit 1ae748cc51088d60722320dbefae04a62310e2e1. Signed-off-by: Kerry Archibald <kerrya@element.io> * Revert "remove unsupported assertion failure messages" This reverts commit 7bd93d075c4d8d45befcbfd59c889782c9a44b48. * Revert "test/DecryptionFailureTracker-test.js -> test/DecryptionFailureTracker-test.ts" This reverts commit 1670025bd2af9a355c2761998202f602d61f242e. * revert change to DecryptionFailureTracker Signed-off-by: Kerry Archibald <kerrya@element.io>
2022-05-02 09:57:35 +02:00
function stringToArray(s: string): ArrayBufferLike {
return new TextEncoder().encode(s).buffer;
}
2022-12-12 12:24:14 +01:00
describe("MegolmExportEncryption", function () {
let MegolmExportEncryption: typeof MegolmExportEncryptionExport;
2019-12-16 12:12:48 +01:00
2022-11-04 11:48:08 +01:00
beforeEach(() => {
Object.defineProperty(window, "crypto", {
value: {
getRandomValues,
randomUUID: jest.fn().mockReturnValue("not-random-uuid"),
subtle: webCrypto.subtle,
},
});
MegolmExportEncryption = require("../../../src/utils/MegolmExportEncryption");
2019-12-16 12:12:48 +01:00
});
2022-12-12 12:24:14 +01:00
describe("decrypt", function () {
it("should handle missing header", function () {
const input = stringToArray(`-----`);
return MegolmExportEncryption.decryptMegolmKeyFile(input, "").then(
(res) => {
throw new Error("expected to throw");
},
(error) => {
expect(error.message).toEqual("Header line not found");
},
);
});
2022-12-12 12:24:14 +01:00
it("should handle missing trailer", function () {
const input = stringToArray(`-----BEGIN MEGOLM SESSION DATA-----
-----`);
2022-12-12 12:24:14 +01:00
return MegolmExportEncryption.decryptMegolmKeyFile(input, "").then(
(res) => {
throw new Error("expected to throw");
},
(error) => {
expect(error.message).toEqual("Trailer line not found");
},
);
});
2022-12-12 12:24:14 +01:00
it("should handle a too-short body", function () {
const input = stringToArray(`-----BEGIN MEGOLM SESSION DATA-----
AXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx
cissyYBxjsfsAn
-----END MEGOLM SESSION DATA-----
`);
2022-12-12 12:24:14 +01:00
return MegolmExportEncryption.decryptMegolmKeyFile(input, "").then(
(res) => {
throw new Error("expected to throw");
},
(error) => {
expect(error.message).toEqual("Invalid file: too short");
},
);
});
2019-12-17 12:24:37 +01:00
// TODO find a subtlecrypto shim which doesn't break this test
2022-12-12 12:24:14 +01:00
it.skip("should decrypt a range of inputs", function () {
function next(i: number): Promise<string | undefined> | undefined {
if (i >= TEST_VECTORS.length) {
return;
}
const [plain, password, input] = TEST_VECTORS[i];
2022-12-12 12:24:14 +01:00
return MegolmExportEncryption.decryptMegolmKeyFile(stringToArray(input), password).then((decrypted) => {
expect(decrypted).toEqual(plain);
2022-12-12 12:24:14 +01:00
return next(i + 1);
2017-06-08 14:12:27 +02:00
});
}
next(0);
});
});
2022-12-12 12:24:14 +01:00
describe("encrypt", function () {
it("should round-trip", function () {
const input = "words words many words in plain text here".repeat(100);
const password = "my super secret passphrase";
return MegolmExportEncryption.encryptMegolmKeyFile(input, password, { kdf_rounds: 1000 })
.then((ciphertext) => {
return MegolmExportEncryption.decryptMegolmKeyFile(ciphertext, password);
})
.then((plaintext) => {
expect(plaintext).toEqual(input);
});
});
});
});