1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +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

@@ -5,6 +5,7 @@ import { CsprngArray } from "../../types/csprng";
import { CryptoFunctionService } from "../abstractions/crypto-function.service";
import { LogService } from "../abstractions/log.service";
import { EncryptionType } from "../enums";
import { Utils } from "../misc/utils";
import { EncArrayBuffer } from "../models/domain/enc-array-buffer";
import { EncString } from "../models/domain/enc-string";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
@@ -163,6 +164,79 @@ describe("EncryptService", () => {
});
});
describe("rsa", () => {
const data = makeStaticByteArray(10, 100);
const encryptedData = makeStaticByteArray(10, 150);
const publicKey = makeStaticByteArray(10, 200);
const privateKey = makeStaticByteArray(10, 250);
const encString = makeEncString(encryptedData);
function makeEncString(data: Uint8Array): EncString {
return new EncString(EncryptionType.Rsa2048_OaepSha1_B64, Utils.fromBufferToB64(data));
}
describe("rsaEncrypt", () => {
it("throws if no data is provided", () => {
return expect(encryptService.rsaEncrypt(null, publicKey)).rejects.toThrow("No data");
});
it("throws if no public key is provided", () => {
return expect(encryptService.rsaEncrypt(data, null)).rejects.toThrow("No public key");
});
it("encrypts data with provided key", async () => {
cryptoFunctionService.rsaEncrypt.mockResolvedValue(encryptedData);
const actual = await encryptService.rsaEncrypt(data, publicKey);
expect(cryptoFunctionService.rsaEncrypt).toBeCalledWith(
expect.toEqualBuffer(data),
expect.toEqualBuffer(publicKey),
"sha1",
);
expect(actual).toEqual(encString);
expect(actual.dataBytes).toEqualBuffer(encryptedData);
});
});
describe("rsaDecrypt", () => {
it("throws if no data is provided", () => {
return expect(encryptService.rsaDecrypt(null, privateKey)).rejects.toThrow("No data");
});
it("throws if no private key is provided", () => {
return expect(encryptService.rsaDecrypt(encString, null)).rejects.toThrow("No private key");
});
it.each([
EncryptionType.AesCbc256_B64,
EncryptionType.AesCbc128_HmacSha256_B64,
EncryptionType.AesCbc256_HmacSha256_B64,
])("throws if encryption type is %s", async (encType) => {
encString.encryptionType = encType;
await expect(encryptService.rsaDecrypt(encString, privateKey)).rejects.toThrow(
"Invalid encryption type",
);
});
it("decrypts data with provided key", async () => {
cryptoFunctionService.rsaDecrypt.mockResolvedValue(data);
const actual = await encryptService.rsaDecrypt(makeEncString(data), privateKey);
expect(cryptoFunctionService.rsaDecrypt).toBeCalledWith(
expect.toEqualBuffer(data),
expect.toEqualBuffer(privateKey),
"sha1",
);
expect(actual).toEqualBuffer(data);
});
});
});
describe("resolveLegacyKey", () => {
it("creates a legacy key if required", async () => {
const key = new SymmetricCryptoKey(makeStaticByteArray(32), EncryptionType.AesCbc256_B64);