Don't use a protocol version that a device doesn't support (#367) - #370
Draft
micolous wants to merge 9 commits into
Draft
Don't use a protocol version that a device doesn't support (#367)#370micolous wants to merge 9 commits into
micolous wants to merge 9 commits into
Conversation
micolous
force-pushed
the
ctap2/issue-367
branch
2 times, most recently
from
August 18, 2026 05:23
df6098b to
e1f96c1
Compare
micolous
added a commit
to micolous/firefox
that referenced
this pull request
Aug 18, 2026
* Implement `CtapVersionSupport` trait for `TestToken`: mozilla/authenticator-rs#370 * Remove local version of `memoffset v0.8.999`, dependency removed in mozilla/authenticator-rs#361 Differential Revision: https://phabricator.services.mozilla.com/D318670
micolous
added a commit
to micolous/firefox
that referenced
this pull request
Aug 19, 2026
* Implement `CtapVersionSupport` trait for `TestToken`: mozilla/authenticator-rs#370 * Make `TestToken` explicitly treat a version parameter as "this version and lower". * Remove local version of `memoffset v0.8.999`, dependency removed in mozilla/authenticator-rs#361 Differential Revision: https://phabricator.services.mozilla.com/D318670
micolous
added a commit
to micolous/firefox
that referenced
this pull request
Aug 20, 2026
* Implement `CtapVersionSupport` trait for `TestToken`: mozilla/authenticator-rs#370 * `TestToken` now treats a version parameter as "this version and lower". * Remove local version of `memoffset v0.8.999`, dependency removed in mozilla/authenticator-rs#361 Differential Revision: https://phabricator.services.mozilla.com/D318670
* Update `AuthenticatorOptions::user_verification` docs to use the CTAP 2.3 description, and note some caveats. * Add `AuthenticatorOptions::supports_uv()` helper.
…uraged and 'possible'.
* Don't skip UV when `uv = required` * Don't skip UV when `uv != discouraged` and UV is "possible" but unconfigured This is rewritten to be closer to the CTAP 2.3 spec's steps.
…pport, fixup tests with that call path
micolous
force-pushed
the
ctap2/issue-367
branch
from
August 21, 2026 02:37
b48eab6 to
b763463
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft PR, needs #374
This makes
authenticator-rsnever try to use CTAP1 / U2F on devices that won't support it (#367), and also never try to use CTAP2 on devices that won't support it (#371, repeat of #72).API changes:
FidoDevicenow requires (new)CtapVersionSupporttrait. There is an impl forT: HIDDevice.Replaced, with alias:
FidoDevice::should_try_ctap2()is moved and renamed toCtapVersionSupport::supports_ctap2(). There is an alias for the old name. This replaces the duplicated definition of the function for each platform.Added:
CtapVersionSupport::supports_ctap1(), which checks forCAPABILITY_NMSGbeing unset.Changed:
FidoDevice::downgrade_to_ctap1()is now a fallible operation (returnsResult), based onCtapVersionSupport::supports_ctap1().Using
supports_ctap1()fixes some incorrect behaviour:CTAP2-only1
register()orsign()requests withuse_ctap1_fallback = true(security.webauthn.ctap2 = false):The request will now immediately error out with
UnsupportedOption(...)(orNotAllowedErrorin Firefox), rather than attempting device selection and then erroring out (with the same error).CTAP2-only1
register()orsign()requests:CTAP1-only devices will now be completely ignored, rather than trying device selection and then erroring out if the CTAP1-only device is selected 2.
This also excludes CTAP1-only devices that don't enforce user presence checks (like U2F NitroKeys that don't have a button), which would otherwise "capture" the request and then prevent use of a CTAP2 authenticator.
CTAP1-compatible
register()orsign()requests withuse_ctap1_fallback = true(security.webauthn.ctap2 = false):CTAP2-only devices will now be completely ignored, rather than trying device selection and then sending them an invalid command (which would probably error out) if selected 2.
When a device is ignored, it won't blink or respond to button press. This may lead a user to believe some of their devices are not working. Immediately erroring for impossible requests may lead a user to believe there is a browser bug.
However, prompting for a button press on a device that definitely won't work will just return an error anyway, and doesn't give the user clues about which of their authenticators would actually work.
There may be better ways to handle that (eg: "there are 2 devices connected, but none of them can handle this request"), but it'd require significant API and UI changes to support it, and risks being annoying (eg: corporate-issued devices that have an always-present nano-key that only supports CTAP1).
While here, I've added some more documentation, and fixed some incorrect comments.
Fixes #367, which is required to implement caBLE support in Firefox.
Fixes #371.
TODO (for me)
supports_ctap2()guard tosend_cbor_cancellable. There are a bunch of CTAP2 tests that use the device without initialising first, causingmock::HIDDevice::get_device_infoto panic.supports_ctap1()guard tosend_ctap1_cancellable.HidDevice::get_device_inforeturn an optional, rather than panicing.authrs_bridge::TestToken(which usesFidoDevicebut notHIDDevice)Footnotes
eg:
uv = required,rk = required, not supporting ES256, etc. ↩ ↩2selected implicitly, as the only device, or selected explicitly among multiple devices with a button press ↩ ↩2