1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 17:53:39 +00:00
Files
browser/libs/common/src/platform/services/key-generation.service.spec.ts
Ike 1e4158fd87 [PM-5735] Create kdf Service (#8715)
* key connector migration initial

* migrator complete

* fix dependencies

* finalized tests

* fix deps and sync main

* clean up definition file

* fixing tests

* fixed tests

* fixing CLI, Browser, Desktop builds

* fixed factory options

* reverting exports

* implemented UserKeyDefinition clearOn

* Initial Kdf Service Changes

* rename and account setting kdfconfig

* fixing tests and renaming migration

* fixed DI ordering for browser

* rename and fix DI

* Clean up Migrations

* fixing migrations

* begin data structure changes for kdf config

* Make KDF more type safe; co-author: jlf0dev

* fixing tests

* Fixed CLI login and comments

* set now accepts userId and test updates

---------

Co-authored-by: Jake Fink <jfink@bitwarden.com>
2024-04-25 11:26:01 -07:00

100 lines
3.2 KiB
TypeScript

import { mock } from "jest-mock-extended";
import { Argon2KdfConfig, PBKDF2KdfConfig } from "../../auth/models/domain/kdf-config";
import { CsprngArray } from "../../types/csprng";
import { CryptoFunctionService } from "../abstractions/crypto-function.service";
import { KeyGenerationService } from "./key-generation.service";
describe("KeyGenerationService", () => {
let sut: KeyGenerationService;
const cryptoFunctionService = mock<CryptoFunctionService>();
beforeEach(() => {
sut = new KeyGenerationService(cryptoFunctionService);
});
describe("createKey", () => {
test.each([256, 512])(
"it should delegate key creation to crypto function service",
async (bitLength: 256 | 512) => {
cryptoFunctionService.aesGenerateKey
.calledWith(bitLength)
.mockResolvedValue(new Uint8Array(bitLength / 8) as CsprngArray);
await sut.createKey(bitLength);
expect(cryptoFunctionService.aesGenerateKey).toHaveBeenCalledWith(bitLength);
},
);
});
describe("createMaterialAndKey", () => {
test.each([128, 192, 256, 512])(
"should create a 64 byte key from different material lengths",
async (bitLength: 128 | 192 | 256 | 512) => {
const inputMaterial = new Uint8Array(bitLength / 8) as CsprngArray;
const inputSalt = "salt";
const purpose = "purpose";
cryptoFunctionService.aesGenerateKey.calledWith(bitLength).mockResolvedValue(inputMaterial);
cryptoFunctionService.hkdf
.calledWith(inputMaterial, inputSalt, purpose, 64, "sha256")
.mockResolvedValue(new Uint8Array(64));
const { salt, material, derivedKey } = await sut.createKeyWithPurpose(
bitLength,
purpose,
inputSalt,
);
expect(salt).toEqual(inputSalt);
expect(material).toEqual(inputMaterial);
expect(derivedKey.key.length).toEqual(64);
},
);
});
describe("deriveKeyFromMaterial", () => {
it("should derive a 64 byte key from material", async () => {
const material = new Uint8Array(32) as CsprngArray;
const salt = "salt";
const purpose = "purpose";
cryptoFunctionService.hkdf.mockResolvedValue(new Uint8Array(64));
const key = await sut.deriveKeyFromMaterial(material, salt, purpose);
expect(key.key.length).toEqual(64);
});
});
describe("deriveKeyFromPassword", () => {
it("should derive a 32 byte key from a password using pbkdf2", async () => {
const password = "password";
const salt = "salt";
const kdfConfig = new PBKDF2KdfConfig(600_000);
cryptoFunctionService.pbkdf2.mockResolvedValue(new Uint8Array(32));
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
expect(key.key.length).toEqual(32);
});
it("should derive a 32 byte key from a password using argon2id", async () => {
const password = "password";
const salt = "salt";
const kdfConfig = new Argon2KdfConfig(3, 16, 4);
cryptoFunctionService.hash.mockResolvedValue(new Uint8Array(32));
cryptoFunctionService.argon2.mockResolvedValue(new Uint8Array(32));
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
expect(key.key.length).toEqual(32);
});
});
});