1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 17:23:37 +00:00

[PM-23627] Require publicKey for keyService getFingerprint (#15933)

* require public key on keyService getFingerprint

* Update consumers and add error handling & logging
This commit is contained in:
Thomas Avery
2025-08-21 15:49:19 -05:00
committed by GitHub
parent 805b6fe7aa
commit a6e7efddeb
9 changed files with 119 additions and 36 deletions

View File

@@ -1227,6 +1227,63 @@ describe("keyService", () => {
});
});
describe("getFingerprint", () => {
const mockFingerprintMaterial = "test@example.com";
const mockPublicKey = new Uint8Array(256);
const mockKeyFingerprint = Utils.fromB64ToArray("nfG2jTrJilBEsSrg7ffe9exE9PlClem4P2bxlQ6rNbs=");
const mockUserFingerprint = Utils.fromB64ToArray(
"V5AQSk83YXd6kZqCncC6d9J72R7UZ60Xl1eIoDoWgTc=",
);
const expectedFingerprint = ["predefine", "hunting", "pastime", "enrich", "unhearing"];
beforeEach(() => {
cryptoFunctionService.hash.mockResolvedValue(mockKeyFingerprint);
cryptoFunctionService.hkdfExpand.mockResolvedValue(mockUserFingerprint);
});
test.each([null as unknown as Uint8Array, undefined as unknown as Uint8Array])(
"throws when publicKey is %s",
async (publicKey) => {
await expect(keyService.getFingerprint(mockFingerprintMaterial, publicKey)).rejects.toThrow(
"Public key is required to generate a fingerprint.",
);
expect(cryptoFunctionService.hash).not.toHaveBeenCalled();
expect(cryptoFunctionService.hkdfExpand).not.toHaveBeenCalled();
},
);
it("generates fingerprint successfully", async () => {
const result = await keyService.getFingerprint(mockFingerprintMaterial, mockPublicKey);
expect(result).toEqual(expectedFingerprint);
expect(cryptoFunctionService.hash).toHaveBeenCalledWith(mockPublicKey, "sha256");
expect(cryptoFunctionService.hkdfExpand).toHaveBeenCalledWith(
mockKeyFingerprint,
mockFingerprintMaterial,
32,
"sha256",
);
});
it("throws when entropy of hash function is too small", async () => {
const keyFingerprint = new Uint8Array(3);
cryptoFunctionService.hash.mockResolvedValue(keyFingerprint);
cryptoFunctionService.hkdfExpand.mockResolvedValue(new Uint8Array(3));
await expect(
keyService.getFingerprint(mockFingerprintMaterial, mockPublicKey),
).rejects.toThrow("Output entropy of hash function is too small");
expect(cryptoFunctionService.hash).toHaveBeenCalledWith(mockPublicKey, "sha256");
expect(cryptoFunctionService.hkdfExpand).toHaveBeenCalledWith(
keyFingerprint,
mockFingerprintMaterial,
32,
"sha256",
);
});
});
describe("makeKeyPair", () => {
test.each([null as unknown as SymmetricCryptoKey, undefined as unknown as SymmetricCryptoKey])(
"throws when the provided key is %s",