diff options
Diffstat (limited to 'packages/server/src')
-rw-r--r-- | packages/server/src/helpers/parseAuthenticatorData.ts | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/packages/server/src/helpers/parseAuthenticatorData.ts b/packages/server/src/helpers/parseAuthenticatorData.ts index 497f2d4..2307e44 100644 --- a/packages/server/src/helpers/parseAuthenticatorData.ts +++ b/packages/server/src/helpers/parseAuthenticatorData.ts @@ -53,6 +53,19 @@ export function parseAuthenticatorData( credentialID = authData.slice(pointer, pointer += credIDLen); + /** + * Firefox 117 incorrectly CBOR-encodes authData when EdDSA (-8) is used for the public key. + * A CBOR "Map of 3 items" (0xa3) should be "Map of 4 items" (0xa4), and if we manually adjust + * the single byte there's a good chance the authData can be correctly parsed. + */ + // Bytes decode to `{ 1: "OKP", 3: -8, -1: "Ed25519" }` (it's missing key -2 a.k.a. COSEKEYS.x) + const badEdDSACBOR = isoUint8Array.fromHex('a301634f4b500327206745643235353139'); + const bytesAtCurrentPosition = authData.slice(pointer, pointer + badEdDSACBOR.byteLength); + if (isoUint8Array.areEqual(badEdDSACBOR, bytesAtCurrentPosition)) { + // Change the bad CBOR 0xa3 to 0xa4 so that the credential public key can be recognized + authData[pointer] = 0xa4; + } + // Decode the next CBOR item in the buffer, then re-encode it back to a Buffer const firstDecoded = isoCBOR.decodeFirst<COSEPublicKey>( authData.slice(pointer), |