diff options
author | Matthew Miller <matthew@millerti.me> | 2023-09-23 08:13:42 -0700 |
---|---|---|
committer | Matthew Miller <matthew@millerti.me> | 2023-09-23 08:13:42 -0700 |
commit | 48e88e120710e7b2c785e1b59cc715140a645be0 (patch) | |
tree | 34d9d60760f20d04c01b63e27791bd380e4344fb /packages/server/src/helpers/parseAuthenticatorData.ts | |
parent | 0b3e442fe353efb104aa7f8cdf7e86cb4f6a0a28 (diff) |
Detect and fix bad bytes
Diffstat (limited to 'packages/server/src/helpers/parseAuthenticatorData.ts')
-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), |