diff --git a/apps/browser/src/webauthn/content/page-script.ts b/apps/browser/src/webauthn/content/page-script.ts index eda3d15d48..02a8e5e2ef 100644 --- a/apps/browser/src/webauthn/content/page-script.ts +++ b/apps/browser/src/webauthn/content/page-script.ts @@ -32,7 +32,19 @@ navigator.credentials.create = async ( throw new Error("Something went wrong."); } - return WebauthnUtils.mapCredentialRegistrationResult(response.result); + console.log(response.result); + + let mappedResult; + try { + mappedResult = WebauthnUtils.mapCredentialRegistrationResult(response.result); + } catch (e) { + console.error(e); + throw e; + } + + console.log(mappedResult); + + return mappedResult; } catch (error) { if (error && error.fallbackRequested) { return await browserCredentials.create(options); @@ -60,6 +72,8 @@ navigator.credentials.get = async ( throw new Error("Something went wrong."); } + console.log(response.result); + return WebauthnUtils.mapCredentialAssertResult(response.result); } catch (error) { if (error && error.fallbackRequested) { diff --git a/libs/common/src/vault/models/request/cipher.request.ts b/libs/common/src/vault/models/request/cipher.request.ts index 3d189930d6..26c9663dbd 100644 --- a/libs/common/src/vault/models/request/cipher.request.ts +++ b/libs/common/src/vault/models/request/cipher.request.ts @@ -125,7 +125,10 @@ export class CipherRequest { break; case CipherType.Fido2Key: this.fido2Key = new Fido2KeyApi(); - this.fido2Key.nonDiscoverableId = cipher.fido2Key.nonDiscoverableId.encryptedString; + this.fido2Key.nonDiscoverableId = + cipher.fido2Key.nonDiscoverableId != null + ? cipher.fido2Key.nonDiscoverableId.encryptedString + : null; this.fido2Key.keyType = cipher.fido2Key.keyType != null ? (cipher.fido2Key.keyType.encryptedString as "public-key") diff --git a/libs/common/src/webauthn/abstractions/fido2-authenticator.service.abstraction.ts b/libs/common/src/webauthn/abstractions/fido2-authenticator.service.abstraction.ts index fc5f4a184c..74fc073a05 100644 --- a/libs/common/src/webauthn/abstractions/fido2-authenticator.service.abstraction.ts +++ b/libs/common/src/webauthn/abstractions/fido2-authenticator.service.abstraction.ts @@ -110,7 +110,7 @@ export interface Fido2AuthenticatorGetAssertionParams { export interface Fido2AuthenticatorGetAssertionResult { selectedCredential: { - id: string; + id: Uint8Array; userHandle?: Uint8Array; }; authenticatorData: Uint8Array; 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 fbff20f13c..28bbde5c80 100644 --- a/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts +++ b/libs/common/src/webauthn/services/fido2-authenticator.service.spec.ts @@ -446,10 +446,10 @@ describe("FidoAuthenticatorService", () => { const aaguid = encAuthData.slice(37, 53); const credentialIdLength = encAuthData.slice(53, 55); const credentialId = encAuthData.slice(55, 71); - // Public key format is not tested here since it will be tested - // by the assertion tests. + // Unsure how to test public key // const publicKey = encAuthData.slice(87); + expect(encAuthData.length).toBe(71 + 77); expect(attestationObject.fmt).toBe("none"); expect(attestationObject.attStmt).toEqual({}); expect(rpIdHash).toEqual( @@ -710,7 +710,7 @@ describe("FidoAuthenticatorService", () => { const flags = encAuthData.slice(32, 33); const counter = encAuthData.slice(33, 37); - expect(result.selectedCredential.id).toBe(selectedCredentialId); + expect(result.selectedCredential.id).toEqual(Utils.guidToRawFormat(selectedCredentialId)); expect(result.selectedCredential.userHandle).toEqual( Fido2Utils.stringToBuffer(ciphers[0].fido2Key.userHandle) ); diff --git a/libs/common/src/webauthn/services/fido2-authenticator.service.ts b/libs/common/src/webauthn/services/fido2-authenticator.service.ts index 6b23c55ee7..166bede78c 100644 --- a/libs/common/src/webauthn/services/fido2-authenticator.service.ts +++ b/libs/common/src/webauthn/services/fido2-authenticator.service.ts @@ -212,7 +212,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr return { authenticatorData, selectedCredential: { - id: selectedCredentialId, + id: Utils.guidToRawFormat(selectedCredentialId), userHandle: Fido2Utils.stringToBuffer(selectedCipher.fido2Key.userHandle), }, signature, diff --git a/libs/common/src/webauthn/services/fido2-client.service.spec.ts b/libs/common/src/webauthn/services/fido2-client.service.spec.ts index c719650366..5eab8e8768 100644 --- a/libs/common/src/webauthn/services/fido2-client.service.spec.ts +++ b/libs/common/src/webauthn/services/fido2-client.service.spec.ts @@ -318,8 +318,12 @@ describe("FidoAuthenticatorService", () => { }); describe("assert non-discoverable credential", () => { - it("should call authenticator.makeCredential", async () => { - const allowedCredentialIds = [Utils.newGuid(), Utils.newGuid(), "not-a-guid"]; + it("should call authenticator.assertCredential", async () => { + const allowedCredentialIds = [ + Fido2Utils.bufferToString(Utils.guidToRawFormat(Utils.newGuid())), + Fido2Utils.bufferToString(Utils.guidToRawFormat(Utils.newGuid())), + Fido2Utils.bufferToString(Utils.fromByteStringToArray("not-a-guid")), + ]; const params = createParams({ userVerification: "required", allowedCredentialIds, @@ -334,10 +338,13 @@ describe("FidoAuthenticatorService", () => { rpId: RpId, allowCredentialDescriptorList: [ expect.objectContaining({ - id: Utils.guidToRawFormat(allowedCredentialIds[0]), + id: Fido2Utils.stringToBuffer(allowedCredentialIds[0]), }), expect.objectContaining({ - id: Utils.guidToRawFormat(allowedCredentialIds[1]), + id: Fido2Utils.stringToBuffer(allowedCredentialIds[1]), + }), + expect.objectContaining({ + id: Fido2Utils.stringToBuffer(allowedCredentialIds[2]), }), ], }), @@ -347,7 +354,7 @@ describe("FidoAuthenticatorService", () => { }); describe("assert discoverable credential", () => { - it("should call authenticator.makeCredential", async () => { + it("should call authenticator.assertCredential", async () => { const params = createParams({ userVerification: "required", allowedCredentialIds: [], diff --git a/libs/common/src/webauthn/services/fido2-client.service.ts b/libs/common/src/webauthn/services/fido2-client.service.ts index 3244fd2b58..8d4eae9c06 100644 --- a/libs/common/src/webauthn/services/fido2-client.service.ts +++ b/libs/common/src/webauthn/services/fido2-client.service.ts @@ -83,19 +83,13 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction { params.authenticatorSelection?.userVerification, params.timeout ); - const excludeCredentialDescriptorList: PublicKeyCredentialDescriptor[] = []; - if (params.excludeCredentials !== undefined) { - for (const credential of params.excludeCredentials) { - try { - excludeCredentialDescriptorList.push({ - id: Fido2Utils.stringToBuffer(credential.id), - transports: credential.transports, - type: credential.type, - }); - // eslint-disable-next-line no-empty - } catch {} - } - } + const excludeCredentialDescriptorList: PublicKeyCredentialDescriptor[] = + params.excludeCredentials?.map((credential) => ({ + id: Fido2Utils.stringToBuffer(credential.id), + transports: credential.transports, + type: credential.type, + })) ?? []; + const makeCredentialParams: Fido2AuthenticatorMakeCredentialsParams = { requireResidentKey: params.authenticatorSelection?.residentKey === "required" || @@ -138,9 +132,9 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction { credentialId: Fido2Utils.bufferToString(makeCredentialResult.credentialId), attestationObject: Fido2Utils.bufferToString(makeCredentialResult.attestationObject), authData: Fido2Utils.bufferToString(makeCredentialResult.authData), + clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes), publicKeyAlgorithm: makeCredentialResult.publicKeyAlgorithm, - clientDataJSON, - transports: ["web-extension"], + transports: ["hybrid"], }; } @@ -181,16 +175,11 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction { const timeout = setAbortTimeout(abortController, params.userVerification, params.timeout); - const allowCredentialDescriptorList: PublicKeyCredentialDescriptor[] = []; - for (const id of params.allowedCredentialIds) { - try { - allowCredentialDescriptorList.push({ - id: Utils.guidToRawFormat(id), - type: "public-key", - }); - // eslint-disable-next-line no-empty - } catch {} - } + const allowCredentialDescriptorList: PublicKeyCredentialDescriptor[] = + params.allowedCredentialIds.map((id) => ({ + id: Fido2Utils.stringToBuffer(id), + type: "public-key", + })); const getAssertionParams: Fido2AuthenticatorGetAssertionParams = { rpId, @@ -223,8 +212,8 @@ export class Fido2ClientService implements Fido2ClientServiceAbstraction { return { authenticatorData: Fido2Utils.bufferToString(getAssertionResult.authenticatorData), - clientDataJSON, - credentialId: getAssertionResult.selectedCredential.id, + clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes), + credentialId: Fido2Utils.bufferToString(getAssertionResult.selectedCredential.id), userHandle: getAssertionResult.selectedCredential.userHandle !== undefined ? Fido2Utils.bufferToString(getAssertionResult.selectedCredential.userHandle)