From e7454501ea627903b8e5a90d26b63480b9f616a0 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Thu, 30 Mar 2023 10:59:19 +0200 Subject: [PATCH] [EC-598] feat: add general error handling for attestation --- .../fido2-authenticator.service.spec.ts | 9 +++ .../services/fido2-authenticator.service.ts | 60 ++++++++++--------- 2 files changed, 41 insertions(+), 28 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 f81545d395..babbf9cc12 100644 --- a/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts +++ b/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts @@ -724,6 +724,15 @@ describe("FidoAuthenticatorService", () => { // Signatures are non-deterministic, and webcrypto can't verify DER signature format // expect(result.signature).toMatchSnapshot(); }); + + /** 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")); + + const result = async () => await authenticator.getAssertion(params); + + await expect(result).rejects.toThrowError(Fido2AutenticatorErrorCode.Unknown); + }); }); } diff --git a/libs/common/src/webauthn/services/fido2-authenticator.service.ts b/libs/common/src/webauthn/services/fido2-authenticator.service.ts index f9be33981a..a974b795fc 100644 --- a/libs/common/src/webauthn/services/fido2-authenticator.service.ts +++ b/libs/common/src/webauthn/services/fido2-authenticator.service.ts @@ -173,38 +173,42 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotAllowed); } - const selectedCredentialId = - params.allowCredentialDescriptorList?.length > 0 - ? selectedCipher.fido2Key.nonDiscoverableId - : selectedCipher.id; + try { + const selectedCredentialId = + params.allowCredentialDescriptorList?.length > 0 + ? selectedCipher.fido2Key.nonDiscoverableId + : selectedCipher.id; - ++selectedCipher.fido2Key.counter; - selectedCipher.localData.lastUsedDate = new Date().getTime(); - const encrypted = await this.cipherService.encrypt(selectedCipher); - await this.cipherService.updateWithServer(encrypted); + ++selectedCipher.fido2Key.counter; + selectedCipher.localData.lastUsedDate = new Date().getTime(); + const encrypted = await this.cipherService.encrypt(selectedCipher); + await this.cipherService.updateWithServer(encrypted); - const authenticatorData = await generateAuthData({ - rpId: selectedCipher.fido2Key.rpId, - credentialId: selectedCredentialId, - counter: selectedCipher.fido2Key.counter, - userPresence: true, - userVerification: false, - }); + const authenticatorData = await generateAuthData({ + rpId: selectedCipher.fido2Key.rpId, + credentialId: selectedCredentialId, + counter: selectedCipher.fido2Key.counter, + userPresence: true, + userVerification: false, + }); - const signature = await generateSignature({ - authData: authenticatorData, - clientData: params.hash, - privateKey: await getPrivateKeyFromCipher(selectedCipher), - }); + const signature = await generateSignature({ + authData: authenticatorData, + clientData: params.hash, + privateKey: await getPrivateKeyFromCipher(selectedCipher), + }); - return { - authenticatorData, - selectedCredential: { - id: selectedCredentialId, - userHandle: Fido2Utils.stringToBuffer(selectedCipher.fido2Key.userHandle), - }, - signature, - }; + return { + authenticatorData, + selectedCredential: { + id: selectedCredentialId, + userHandle: Fido2Utils.stringToBuffer(selectedCipher.fido2Key.userHandle), + }, + signature, + }; + } catch { + throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown); + } } private async vaultContainsCredentials(