diff options
-rw-r--r-- | packages/server/src/helpers/parseAuthenticatorData.test.ts | 18 | ||||
-rw-r--r-- | packages/server/src/helpers/parseAuthenticatorData.ts | 35 |
2 files changed, 27 insertions, 26 deletions
diff --git a/packages/server/src/helpers/parseAuthenticatorData.test.ts b/packages/server/src/helpers/parseAuthenticatorData.test.ts index a706718..e08d95b 100644 --- a/packages/server/src/helpers/parseAuthenticatorData.test.ts +++ b/packages/server/src/helpers/parseAuthenticatorData.test.ts @@ -1,12 +1,9 @@ -import cbor from 'cbor'; - import { parseAuthenticatorData } from './parseAuthenticatorData'; +import * as base64url from './base64url'; // Grabbed this from a Conformance test, contains attestation data -const authDataWithAT = Buffer.from( - 'SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAJch83ZdWwUm4niTLNjZU81AAIHa7Ksm5br3hAh3UjxP9+4rqu8BEsD+7SZ2xWe1/yHv6pAEDAzkBACBZAQDcxA7Ehs9goWB2Hbl6e9v+aUub9rvy2M7Hkvf+iCzMGE63e3sCEW5Ru33KNy4um46s9jalcBHtZgtEnyeRoQvszis+ws5o4Da0vQfuzlpBmjWT1dV6LuP+vs9wrfObW4jlA5bKEIhv63+jAxOtdXGVzo75PxBlqxrmrr5IR9n8Fw7clwRsDkjgRHaNcQVbwq/qdNwU5H3hZKu9szTwBS5NGRq01EaDF2014YSTFjwtAmZ3PU1tcO/QD2U2zg6eB5grfWDeAJtRE8cbndDWc8aLL0aeC37Q36+TVsGe6AhBgHEw6eO3I3NW5r9v/26CqMPBDwmEundeq1iGyKfMloobIUMBAAE=', - 'base64', -); +const authDataWithAT = base64url.toBuffer('SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAJch83ZdWwUm4niTLNjZU81AAIHa7Ksm5br3hAh3UjxP9+4rqu8BEsD+7SZ2xWe1/yHv6pAEDAzkBACBZAQDcxA7Ehs9goWB2Hbl6e9v+aUub9rvy2M7Hkvf+iCzMGE63e3sCEW5Ru33KNy4um46s9jalcBHtZgtEnyeRoQvszis+ws5o4Da0vQfuzlpBmjWT1dV6LuP+vs9wrfObW4jlA5bKEIhv63+jAxOtdXGVzo75PxBlqxrmrr5IR9n8Fw7clwRsDkjgRHaNcQVbwq/qdNwU5H3hZKu9szTwBS5NGRq01EaDF2014YSTFjwtAmZ3PU1tcO/QD2U2zg6eB5grfWDeAJtRE8cbndDWc8aLL0aeC37Q36+TVsGe6AhBgHEw6eO3I3NW5r9v/26CqMPBDwmEundeq1iGyKfMloobIUMBAAE=', 'base64'); + // Grabbed this from a Conformance test, contains extension data const authDataWithED = Buffer.from( 'SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2OBAAAAjaFxZXhhbXBsZS5leHRlbnNpb254dlRoaXMgaXMgYW4gZXhhbXBsZSBleHRlbnNpb24hIElmIHlvdSByZWFkIHRoaXMgbWVzc2FnZSwgeW91IHByb2JhYmx5IHN1Y2Nlc3NmdWxseSBwYXNzaW5nIGNvbmZvcm1hbmNlIHRlc3RzLiBHb29kIGpvYiE=', @@ -29,13 +26,14 @@ test('should parse flags', () => { test('should parse attestation data', () => { const parsed = parseAuthenticatorData(authDataWithAT); - const { credentialID, credentialPublicKey, aaguid } = parsed; + const { credentialID, credentialPublicKey, aaguid, counter } = parsed; - expect(credentialID?.toString('base64')).toEqual('drsqybluveECHdSPE/37iuq7wESwP7tJnbFZ7X/Ie/o='); - expect(credentialPublicKey?.toString('base64')).toEqual( + expect(base64url.fromBuffer(credentialID!)).toEqual('drsqybluveECHdSPE_37iuq7wESwP7tJnbFZ7X_Ie_o'); + expect(base64url.fromBuffer(credentialPublicKey!, 'base64')).toEqual( 'pAEDAzkBACBZAQDcxA7Ehs9goWB2Hbl6e9v+aUub9rvy2M7Hkvf+iCzMGE63e3sCEW5Ru33KNy4um46s9jalcBHtZgtEnyeRoQvszis+ws5o4Da0vQfuzlpBmjWT1dV6LuP+vs9wrfObW4jlA5bKEIhv63+jAxOtdXGVzo75PxBlqxrmrr5IR9n8Fw7clwRsDkjgRHaNcQVbwq/qdNwU5H3hZKu9szTwBS5NGRq01EaDF2014YSTFjwtAmZ3PU1tcO/QD2U2zg6eB5grfWDeAJtRE8cbndDWc8aLL0aeC37Q36+TVsGe6AhBgHEw6eO3I3NW5r9v/26CqMPBDwmEundeq1iGyKfMloobIUMBAAE=', ); - expect(aaguid?.toString('base64')).toEqual('yHzdl1bBSbieJMs2NlTzUA=='); + expect(base64url.fromBuffer(aaguid!, 'base64')).toEqual('yHzdl1bBSbieJMs2NlTzUA=='); + expect(counter).toEqual(37); }); test('should parse extension data', () => { diff --git a/packages/server/src/helpers/parseAuthenticatorData.ts b/packages/server/src/helpers/parseAuthenticatorData.ts index 9391135..03bfca0 100644 --- a/packages/server/src/helpers/parseAuthenticatorData.ts +++ b/packages/server/src/helpers/parseAuthenticatorData.ts @@ -1,9 +1,10 @@ -import cbor from 'cbor'; -import { decodeCborFirst } from './decodeCbor'; +import * as cbor from './cbor'; import { decodeAuthenticatorExtensions, AuthenticationExtensionsAuthenticatorOutputs, } from './decodeAuthenticatorExtensions'; +import * as uint8Array from './uint8Array'; +import { COSEPublicKey } from './convertCOSEtoPKCS'; /** * Make sense of the authData buffer contained in an Attestation @@ -16,6 +17,7 @@ export function parseAuthenticatorData(authData: Uint8Array): ParsedAuthenticato } let pointer = 0; + const dataView = uint8Array.toDataView(authData); const rpIdHash = authData.slice(pointer, (pointer += 32)); @@ -34,37 +36,38 @@ export function parseAuthenticatorData(authData: Uint8Array): ParsedAuthenticato flagsInt, }; - const counterBuf = authData.slice(pointer, (pointer += 4)); - const counter = counterBuf.readUInt32BE(0); + const counterBuf = authData.slice(pointer, pointer + 4); + const counter = dataView.getUint32(pointer, false); + pointer += 4; - let aaguid: Buffer | undefined = undefined; - let credentialID: Buffer | undefined = undefined; - let credentialPublicKey: Buffer | undefined = undefined; + let aaguid: Uint8Array | undefined = undefined; + let credentialID: Uint8Array | undefined = undefined; + let credentialPublicKey: Uint8Array | undefined = undefined; if (flags.at) { aaguid = authData.slice(pointer, (pointer += 16)); - const credIDLenBuf = authData.slice(pointer, (pointer += 2)); - const credIDLen = credIDLenBuf.readUInt16BE(0); + const credIDLen = dataView.getUint16(pointer); + pointer += 2; credentialID = authData.slice(pointer, (pointer += credIDLen)); // Decode the next CBOR item in the buffer, then re-encode it back to a Buffer - const firstDecoded = decodeCborFirst(authData.slice(pointer)); - const firstEncoded = Buffer.from(cbor.encode(firstDecoded) as ArrayBuffer); + const firstDecoded = cbor.decodeFirst<COSEPublicKey>(authData.slice(pointer)); + const firstEncoded = Uint8Array.from(cbor.encode(firstDecoded)); + credentialPublicKey = firstEncoded; pointer += firstEncoded.byteLength; } let extensionsData: AuthenticationExtensionsAuthenticatorOutputs | undefined = undefined; - let extensionsDataBuffer: Buffer | undefined = undefined; + let extensionsDataBuffer: Uint8Array | undefined = undefined; if (flags.ed) { - const firstDecoded = decodeCborFirst(authData.slice(pointer)); - const firstEncoded = Buffer.from(cbor.encode(firstDecoded) as ArrayBuffer); - extensionsDataBuffer = firstEncoded; + const firstDecoded = cbor.decodeFirst(authData.slice(pointer)); + extensionsDataBuffer = Uint8Array.from(cbor.encode(firstDecoded)); extensionsData = decodeAuthenticatorExtensions(extensionsDataBuffer); - pointer += firstEncoded.byteLength; + pointer += extensionsDataBuffer.byteLength; } // Pointer should be at the end of the authenticator data, otherwise too much data was sent |