in fido.js [319:375]
function parseAuthenticatorData(authData) {
try {
const rpIdHash = authData.slice(0, 32);
const flags = authData[32];
const signCount = (authData[33] << 24) | (authData[34] << 16) | (authData[35] << 8) | (authData[36]);
/** @type {AuthenticatorData} */
const authenticatorData = {
rpIdHash,
flags,
signCount,
attestedCredentialData: undefined,
extensionDataHex: undefined
};
if (flags & 64) {
//has attestation data
const aaguid = uuid.unparse(authData.slice(37, 53)).toUpperCase();
const credentialIdLength = (authData[53] << 8) | authData[54];
const credentialId = authData.slice(55, 55 + credentialIdLength);
const publicKeyBuffer = authData.slice(55 + credentialIdLength, authData.length);
const publicKeyHex = coseToHex(publicKeyBuffer);
//convert public key to JWK for storage
const publicKey = coseToJwk(publicKeyBuffer);
authenticatorData.attestedCredentialData = {
aaguid,
credentialId,
credentialIdLength,
publicKeyHex,
publicKey
};
}
if (flags & 128) {
//has extension data
let extensionDataCbor;
if (authenticatorData.attestedCredentialData) {
extensionDataCbor = cbor.decodeAllSync(authData.slice(55 + authenticatorData.attestedCredentialData.credentialIdLength, authData.length));
extensionDataCbor = extensionDataCbor[1]; //second element
} else {
extensionDataCbor = cbor.decodeFirstSync(authData.slice(37, authData.length));
}
authenticatorData.extensionDataHex = cbor.encode(extensionDataCbor).toString('hex').toUpperCase();
}
else
{
authenticatorData.extensionDataHex = "No extension data";
}
return authenticatorData;
} catch (e) {
throw new Error("Authenticator Data could not be parsed")
}
}