Repository navigation
Description
Describe the issue
Nothing in verifyRegistrationResponse() communicates the fact that a response may contain an attestation statement, but that the attestation statement wasn't actually confirmed to chain to a specified trust anchor. This would typically be because A) no trust anchors were specified for the attestation format (e.g. MDS isn't being used), or B) it's "packed" self attestation that doesn't verify anything but proof of possession of the new credential's private key.
Additionally, some attestation statements, like "android-key", "android-safetynet", and "apple" will always chain to a trust anchor because they have default trust anchors registered with SettingsService. Others, like "packed" and "tpm", won't actually be verified unless the RP explicitly defines trust anchors for them or opts into using FIDO MDS (and even then only when MDS contains trust anchors for the given AAGUID.)
Right now in all these cases responses containing attestations will return as "verified: true" even if the statement couldn't actually be verified. But if I add something like "registrationInfo.fmtVerified" to the output of verifyRegistrationResponse() then I could signal to RPs, "this response contained an attestation statement, and the statement was fully chained to a trust anchor."
Proposed Examples
"packed" attestation was verified to chain to a trust anchor:
const verified = await verifyRegistrationResponse({...});
console.log(verified.registrationInfo.fmt); // "packed"
console.log(verified.registrationInfo.fmtVerified); // "packed:x5c""packed" attestation contained self attestation (signed using the passkey private key):
const verified = await verifyRegistrationResponse({...});
console.log(verified.registrationInfo.fmt); // "packed"
console.log(verified.registrationInfo.fmtVerified); // "packed:self"No trust anchors were specified so "tpm" attestation had a valid signature but x5c[0] used to verify the signature wasn't chained to a trust anchor:
const verified = await verifyRegistrationResponse({...});
console.log(verified.registrationInfo.fmt); // "tpm"
console.log(verified.registrationInfo.fmtVerified); // undefined"android-key" attestation was verified to chain to a trust anchor:
const verified = await verifyRegistrationResponse({...});
console.log(verified.registrationInfo.fmt); // "android-key"
console.log(verified.registrationInfo.fmtVerified); // "android-key""none" attestation would I guess return "none" for both because it's technically true?
const verified = await verifyRegistrationResponse({...});
console.log(verified.registrationInfo.fmt); // "none"
console.log(verified.registrationInfo.fmtVerified); // "none"
Activity
[-]Communicate that an attestation statement was fully verified[/-][+]Communicate that an attestation statement was fully chained to a trust anchor[/+]