Skip to content

fix(conformance): load the metadata the tools ship, echo only requested extensions - #253

Merged
Bccorb merged 1 commit into
mainfrom
fix/fido-conformance-metadata-and-extensions
Sep 3, 2026
Merged

fix(conformance): load the metadata the tools ship, echo only requested extensions#253
Bccorb merged 1 commit into
mainfrom
fix/fido-conformance-metadata-and-extensions

Conversation

@Bccorb

@Bccorb Bccorb commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Closes #172.

The FIDO2 conformance test tools were run against a local instance for the first
time. The first run reported 15 failures. This fixes the three defects behind
them, and a run now reports zero failures.

All three are confined to FIDO_CONFORMANCE_MODE, which is refused under a
production NODE_ENV, so no deployed behaviour changes.

Metadata statements were never loaded

The tools' "DOWNLOAD SERVER METADATA" archive unzips to a nested
metadataStatements/ directory, and the loader only read JSON files at the top
level of FIDO_CONFORMANCE_METADATA_DIR. It silently found none.

With requireKnownAuthenticator set, the metadata service runs in strict mode,
so every conformance authenticator was refused as unlisted and every
registration failed. That cascaded into the tests which depend on a registration
having already succeeded, so the failures pointed away from the actual cause.
Confirmed directly against the library before and after:

before: REFUSE packed Secp256R1 -> No metadata statement found for aaguid "326adcf0-..."
after:  OK     packed Secp256R1 -> Virtual Secp256R1 FIDO2 Conformance Testing CTAP2 Authenticator

The directory is now read recursively, so the archive can be dropped in unedited
as the documentation already promised.

Vendor attestation roots blocked their own tests

The tools sign their Apple, Android Key and SafetyNet statements with their own
test roots, so validating those against the real vendor roots could never
succeed. Those preset roots are now cleared in conformance mode, which lets the
roots carried in the metadata statement apply instead. Android Key attestation
verifies for the first time as a result.

Registration options advertised an extension nobody asked for

generateRegistrationOptions always appends its own credProps, and the tools
compare the echoed extensions against the requested set for exact equality:

AssertionError: Response.extensions MUST be set to the requested extensions!
Expected "{"example.extension.bool":true,"credProps":true}"
to equal "{"example.extension.bool":true}"

The requested set is now echoed verbatim over the library's answer. The
authentication options path was already correct, since the library passes
extensions through there unchanged.

Verification

Three conformance runs, 347 captured requests in the last one. Every options
call answered ok, no ceremony was lost, and every remaining refusal is a
negative test the tools intend to fail: corrupted attestation internals, bad
origins, unsupported formats.

Attestation formats verified end to end during a run: packed, tpm, fido-u2f,
android-key and none. Android SafetyNet is never exercised by the tools even
with every test group selected, which is worth confirming before closing #210.

Full suite green: 1219 passed, 1 skipped. Lint, typecheck, format and coverage
thresholds all clean.

…ed extensions

The first real FIDO2 conformance runs surfaced three defects, all confined to
FIDO_CONFORMANCE_MODE, which is refused under a production NODE_ENV.

The tools' metadata archive unzips to a nested metadataStatements/ directory and
the loader only read the top level, so it silently loaded nothing. With
requireKnownAuthenticator set the metadata service runs strict, so every
conformance authenticator was refused as unlisted and every registration failed.
That cascaded into the tests which depend on a registration having succeeded,
rather than showing up as a metadata failure. The directory is now read
recursively, so the archive can be dropped in unedited as the docs already said.

The tools sign their Apple, Android Key and SafetyNet statements with their own
test roots, so validating those against the real vendor roots could never
succeed. Those preset roots are now cleared in conformance mode, which lets the
roots carried in the metadata statement apply instead. Android Key attestation
verifies for the first time as a result.

generateRegistrationOptions always appends its own credProps, and the tools
compare the echoed extensions against the requested set for exact equality, so
every options request carrying extensions failed. The requested set is now
echoed verbatim over the library's answer. The authentication options path was
already correct, since the library passes extensions through there unchanged.

A conformance run now reports zero failures.
@Bccorb
Bccorb merged commit 5efcf5c into main Sep 3, 2026
5 checks passed
@Bccorb
Bccorb deleted the fix/fido-conformance-metadata-and-extensions branch September 3, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run FIDO2 conformance self-validation and remediate findings

1 participant