1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

[PM-5533] migrate provider keys (#7649)

* Provide RSA encryption in encrypt service

* Define state for provider keys

* Require cryptoService

This is temporary until cryptoService has an observable active user private key. We don't want promise-based values in derive functions

* Update crypto service provider keys to observables

* Remove provider keys from state service

* Migrate provider keys out of state account object

* Correct Provider key state types

* Prefix migration with current version number
This commit is contained in:
Matt Gibson
2024-01-29 16:53:01 -05:00
committed by GitHub
parent c199f02d44
commit 3a9dead640
16 changed files with 485 additions and 118 deletions

View File

@@ -0,0 +1,83 @@
import { mock } from "jest-mock-extended";
import { makeStaticByteArray } from "../../../../spec";
import { ProviderId } from "../../../types/guid";
import { ProviderKey, UserPrivateKey } from "../../../types/key";
import { EncryptService } from "../../abstractions/encrypt.service";
import { EncryptionType } from "../../enums";
import { Utils } from "../../misc/utils";
import { EncString, EncryptedString } from "../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
import { CryptoService } from "../crypto.service";
import { USER_ENCRYPTED_PROVIDER_KEYS, USER_PROVIDER_KEYS } from "./provider-keys.state";
function makeEncString(data?: string) {
data ??= Utils.newGuid();
return new EncString(EncryptionType.AesCbc256_HmacSha256_B64, data, "test", "test");
}
describe("encrypted provider keys", () => {
const sut = USER_ENCRYPTED_PROVIDER_KEYS;
it("should deserialize encrypted provider keys", () => {
const encryptedProviderKeys = {
"provider-id-1": makeEncString().encryptedString,
"provider-id-2": makeEncString().encryptedString,
};
const result = sut.deserializer(JSON.parse(JSON.stringify(encryptedProviderKeys)));
expect(result).toEqual(encryptedProviderKeys);
});
});
describe("derived decrypted provider keys", () => {
const encryptService = mock<EncryptService>();
const cryptoService = mock<CryptoService>();
const userPrivateKey = makeStaticByteArray(64, 0) as UserPrivateKey;
const sut = USER_PROVIDER_KEYS;
afterEach(() => {
jest.resetAllMocks();
});
it("should deserialize provider keys", async () => {
const decryptedProviderKeys = {
"provider-id-1": new SymmetricCryptoKey(makeStaticByteArray(64, 1)) as ProviderKey,
"provider-id-2": new SymmetricCryptoKey(makeStaticByteArray(64, 2)) as ProviderKey,
};
const result = sut.deserialize(JSON.parse(JSON.stringify(decryptedProviderKeys)));
expect(result).toEqual(decryptedProviderKeys);
});
it("should derive provider keys", async () => {
const encryptedProviderKeys = {
"provider-id-1": makeEncString().encryptedString,
"provider-id-2": makeEncString().encryptedString,
};
const decryptedProviderKeys = {
"provider-id-1": new SymmetricCryptoKey(makeStaticByteArray(64, 1)) as ProviderKey,
"provider-id-2": new SymmetricCryptoKey(makeStaticByteArray(64, 2)) as ProviderKey,
};
encryptService.rsaDecrypt.mockResolvedValueOnce(decryptedProviderKeys["provider-id-1"].key);
encryptService.rsaDecrypt.mockResolvedValueOnce(decryptedProviderKeys["provider-id-2"].key);
cryptoService.getPrivateKey.mockResolvedValueOnce(userPrivateKey);
const result = await sut.derive(encryptedProviderKeys, { encryptService, cryptoService });
expect(result).toEqual(decryptedProviderKeys);
});
it("should handle null input values", async () => {
const encryptedProviderKeys: Record<ProviderId, EncryptedString> = null;
const result = await sut.derive(encryptedProviderKeys, { encryptService, cryptoService });
expect(result).toEqual({});
});
});