From 0ce8cc0b246995c6894467f03a7dcfd30cd42708 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 12 Apr 2023 10:55:40 +0200 Subject: [PATCH] [EC-598] feat: test unique signatures --- .../fido2-authenticator.service.spec.ts | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts b/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts index 70635817f90..de9798853c0 100644 --- a/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts +++ b/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts @@ -663,7 +663,7 @@ describe("FidoAuthenticatorService", () => { let fido2Keys: Fido2KeyView[]; let params: Fido2AuthenticatorGetAssertionParams; - beforeEach(async () => { + const init = async () => { keyPair = await createKeyPair(); credentialIds = [Utils.newGuid(), Utils.newGuid()]; const keyValue = Fido2Utils.bufferToString( @@ -701,7 +701,8 @@ describe("FidoAuthenticatorService", () => { } cipherService.getAllDecrypted.mockResolvedValue(ciphers); userInterfaceSession.pickCredential.mockResolvedValue(ciphers[0].id); - }); + }; + beforeEach(init); /** Spec: Increment the credential associated signature counter */ it("should increment counter", async () => { @@ -771,6 +772,24 @@ describe("FidoAuthenticatorService", () => { // expect(isValidSignature).toBe(true); }); + it("should always generate unique signatures even if the input is the same", async () => { + const signatures = new Set(); + + for (let i = 0; i < 100; ++i) { + await init(); // Reset inputs + const result = await authenticator.getAssertion(params); + + const counter = result.authenticatorData.slice(33, 37); + expect(counter).toEqual(new Uint8Array([0, 0, 0x23, 0x29])); // double check that the counter doesn't change + + const signature = Fido2Utils.bufferToString(result.signature); + if (signatures.has(signature)) { + throw new Error("Found duplicate signature"); + } + signatures.add(signature); + } + }); + /** Spec: If any error occurred while generating the assertion signature, return an error code equivalent to "UnknownError" and terminate the operation. */ it("should throw unkown error if creation fails", async () => { cipherService.updateWithServer.mockRejectedValue(new Error("Internal error"));