summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Miller <matthew@millerti.me>2023-10-25 21:41:36 -0700
committerGitHub <noreply@github.com>2023-10-25 21:41:36 -0700
commite9926f8964bc1781c5ec9ee86b123ca03e1714dc (patch)
tree9227635fa4bfdf7f94470cb0f8e627bb16c13412
parent499aec93a57d845c2c5c5f9523a16167ee31d8e4 (diff)
parent187f1da979c2aa285495ce46ed1a7d009457f060 (diff)
Merge pull request #465 from MasterKale/fix/463-restore-authdata-after-bad-cbor-fix
fix/463-restore-authdata-after-bad-cbor-fix
-rw-r--r--packages/server/src/helpers/parseAuthenticatorData.test.ts10
-rw-r--r--packages/server/src/helpers/parseAuthenticatorData.ts8
2 files changed, 16 insertions, 2 deletions
diff --git a/packages/server/src/helpers/parseAuthenticatorData.test.ts b/packages/server/src/helpers/parseAuthenticatorData.test.ts
index e1f5be2..d794bbc 100644
--- a/packages/server/src/helpers/parseAuthenticatorData.test.ts
+++ b/packages/server/src/helpers/parseAuthenticatorData.test.ts
@@ -74,11 +74,17 @@ Deno.test('should parse malformed authenticator data from Firefox 117', () => {
* - https://github.com/duo-labs/py_webauthn/issues/175
* - https://github.com/mozilla/authenticator-rs/pull/292
*/
- const authDataBadKty =
+ const authDataBadKtyHex =
'b40499b0271a68957267de4ec40056a74c8758c6582e1e01fcf357d73101e7ba450000000400000000000000000000000000000000008072d3a1a3fa7cf32f44367df847585ff0850c7bd62c338ab45be1fda6fdb79982f96c20efc0bb6ed9347e8c1e77690e67b225b485a098f6f46fde3f2a85acd0177a04d6bb5c7566fb89881dfe48ea7abc361f7acaf86a5966adef557930fa5c045c636f50cf938e508a81b845134eb2988dc3af0ab6f98cfc615532684b4a6363a301634f4b50032720674564323535313921982018d51858187318e6188918eb18ab187e18fd18fd185d184b08184b187318e818e118f818c71518ff18f5183a18fd18a3186b185f1109183e183b14';
+ const authData = isoUint8Array.fromHex(authDataBadKtyHex);
- const parsed = parseAuthenticatorData(isoUint8Array.fromHex(authDataBadKty));
+ const parsed = parseAuthenticatorData(authData);
+
+ const authDataAfterHex = isoUint8Array.toHex(authData);
// If we can assert this then it means we could parse the bad auth data above
assertEquals(parsed.flags.at, true);
+ // Let's make sure we didn't fundamentally change authData as it would break signature
+ // verification if we did.
+ assertEquals(authDataBadKtyHex, authDataAfterHex);
});
diff --git a/packages/server/src/helpers/parseAuthenticatorData.ts b/packages/server/src/helpers/parseAuthenticatorData.ts
index 28bd469..18ce93d 100644
--- a/packages/server/src/helpers/parseAuthenticatorData.ts
+++ b/packages/server/src/helpers/parseAuthenticatorData.ts
@@ -65,8 +65,10 @@ export function parseAuthenticatorData(
// 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);
+ let foundBadCBOR = false;
if (isoUint8Array.areEqual(badEdDSACBOR, bytesAtCurrentPosition)) {
// Change the bad CBOR 0xa3 to 0xa4 so that the credential public key can be recognized
+ foundBadCBOR = true;
authData[pointer] = 0xa4;
}
@@ -76,6 +78,12 @@ export function parseAuthenticatorData(
);
const firstEncoded = Uint8Array.from(isoCBOR.encode(firstDecoded));
+ if (foundBadCBOR) {
+ // Restore the bit we changed so that `authData` is the same as it came in and won't break
+ // signature verification.
+ authData[pointer] = 0xa3;
+ }
+
credentialPublicKey = firstEncoded;
pointer += firstEncoded.byteLength;
}