Comments (10)
I haven't disassembled the responses from your ledger, so I can't give a full breakdown of what happened. See my answer to your question 2, so we can get a more detailed log.
But one step or rather one question at a time:
- Using this tracking-bug https://bugzilla.mozilla.org/show_bug.cgi?id=1828974 you should be able to find which version was going into which milestone.
- You can start Firefox from the commandline with
RUST_LOG=authenticator=debug
to get the logs for auth-rs. - "make.me.blink"-requests are sent in two scenarios: First, if multiple devices are plugged in and the user has to select which to use. For this, we make all devices blink and let the user touch the one that should be used. Second, in cases where a
register()
call was made, but the credential was already registered previously. The spec mandates that the device has to blink anyways, even if we have the opportunity to determine this without user interaction. Or asign()
call was made, and an allow-list was provided that contained no valid credential. Again, we have to blink anyways and collect a user interaction. If the call succeeds or fails with e.g. 'no pin set' should make no difference here. - Not really relevant, see 3.
- There is only one implementation of authenticator-rs, the only OS-dependent part of the code is how to discover and interact with the raw USB-devices, which obviously differs for each OS. The business-logic is the same for all. However on newer Windows-machines "Windows Hello" is used instead of authenticator-rs. And I think the same is true for MacOS. But given that your logs show the
"make.me.blink"
-request, it's pretty obvious that in your case auth-rs is used. So, I'm also not sure what the difference is. Hopefully more detailed logs will help.
Hope that helps!
from authenticator-rs.
Hello @msirringhaus ,
First thanks for your help!
1/
Using this tracking-bug https://bugzilla.mozilla.org/show_bug.cgi?id=1828974 you should be able to find which version was going into which milestone.
If I get it correctly, this shows that v0.4.0-alpha.22
is included in firefox119
while this show that v0.4.0-alpha.23
will be included in firefox120
?
2/
You can start Firefox from the commandline with RUST_LOG=authenticator=debug to get the logs for auth-rs.
I gave it a try with both export RUST_LOG=authenticator=debug
and then launching Firefox with /Applications/Firefox.app/Contents/MacOS/firefox
but I didn't see any additional logging, even in the developer console. I'm sorry I have never debugged anything on Firefox and or Mac, and will therefore require a bit more indication here :/ Maybe I need a Firefox debug build? Or I should look somewhere else for logs?
3/
"make.me.blink"-requests are sent in two scenarios: First, if multiple devices are plugged in and the user has to select which to use. For this, we make all devices blink and let the user touch the one that should be used.
I was wondering how other browser do that, and therefore gave it a try on Google Chrome. It appears it sends the request to every authenticator, and once authenticator respond with a success it cancel the other request. I found that more intuitive and maybe more spec compliant, is there any reason not to do that?
Second, in cases where a register() call was made, but the credential was already registered previously. The spec mandates that the device has to blink anyways, even if we have the opportunity to determine this without user interaction.
I'm not sure to understand which part of the spec you are referring? In the FIDO2.1 spec I found this but this specify the behavior of the authenticator which should be done without any "make.me.blink"-requests. Are you referring to another part of the spec, or another spec maybe?
Or a sign() call was made, and an allow-list was provided that contained no valid credential. Again, we have to blink anyways and collect a user interaction.
In both FIDO2.0 and FIDO2.1 spec I can see requirements for authenticators to collect user presence or user verification before responding to a sign call with an allow-list without valid credential, but again, that should be done on authenticator side, without any "make.me.blink"-requests. Are you referring to another part of the spec, or another spec maybe?
Thanks!
Xavier
from authenticator-rs.
Hi,
no problem.
\1. Yes, I think thats correct.
\2. Hm, this is weird. I don't have a Mac, so I can't reproduce this. I just asked somebody else and it worked for them (although, AFAIK for released versions the log-levels are capped at "INFO", and "DEBUG" can't be chosen any more). Maybe the problem is the selector for authenticator=
. Please try with RUST_LOG=trace /Applications/Firefox\ Beta.app/Contents/MacOS/firefox
, although this will print a lot.
On the other hand, you could also just download this repository and run RUST_LOG=debug cargo run --example ctap2
. This will cut out the middle-man (Firefox), and make debugging easier.
\3.1.
It appears it sends the request to every authenticator, and once authenticator respond with a success it cancel the other request.
We have to be careful here, as there are multiple different variations, that all have a different outcome. E.g. Chrome checks, if the device also speaks the old CTAP1 protocol and then downgrades the request to that. This is to get around the PIN-stuff. Then it can send the actual request to all devices instead of selection-requests, followed by the actual request. We currently don't do this (and I'm still not 100% convinced we should be). But Chrome does also use dummy requests to select devices in certain cases, see #155 .
\3.2.
In both FIDO2.0 and FIDO2.1 spec I can see requirements for authenticators to collect user presence or user verification before responding to a sign call with an allow-list without valid credential, but again, that should be done on authenticator side, without any "make.me.blink"-requests.
As mentioned Chrome does this, too: https://github.com/chromium/chromium/blob/6aaa00ad13642255e207e1c4893463f31c5ecf68/device/fido/make_credential_task.cc#L126-L156
and
https://github.com/chromium/chromium/blob/6aaa00ad13642255e207e1c4893463f31c5ecf68/device/fido/get_assertion_task.cc#L366-L381
There may be some constellations were we could use the actual request instead of the dummy to make the device fail, but it doesn't really matter what we send, if all we want to do is collect a user-interaction and fail.
As far as I remember, the spec doesn't explicitly mention this, except for the old CTAP1-compatibility section:
If the excludeList is not empty, the platform MUST send signing request with check-only control byte to the CTAP1/U2F authenticator using each of the credential ids (key handles) in the excludeList. If any of them does not result in an error, that means that this is a known device. Afterwards, the platform MUST still send a dummy registration request (with a dummy appid and invalid challenge) to CTAP1/U2F authenticators that it believes are excluded. This makes it so the user still needs to touch the CTAP1/U2F authenticator before the RP gets told that the token is already registered.
from authenticator-rs.
Hello :)
\2. Hm, this is weird. I don't have a Mac, so I can't reproduce this. I just asked somebody else and it worked for them (although, AFAIK for released versions the log-levels are capped at "INFO", and "DEBUG" can't be chosen any more). Maybe the problem is the selector for authenticator=. Please try with RUST_LOG=trace /Applications/Firefox\ Beta.app/Contents/MacOS/firefox, although this will print a lot.
Using Firefox Beta, I managed to get some logs, but it was really noisy, and didn't contains interesting logs as far as I know.
On the other hand, you could also just download this repository and run RUST_LOG=debug cargo run --example ctap2. This will cut out the middle-man (Firefox), and make debugging easier.
I therefore went this path, but what a nightmare. I went from one issue to another during the installation of nss
.
I eventually managed to make it works by switching to openssl
in the cargo.toml
with this diff:
diff --git a/Cargo.toml b/Cargo.toml
index 554ea1c..8e60540 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@ travis-ci = { repository = "mozilla/authenticator-rs", branch = "master" }
maintenance = { status = "actively-developed" }
[features]
-default = ["crypto_nss"]
+default = ["crypto_openssl"]
binding-recompile = ["bindgen"]
# Crypto backends
# NOTE: These are mutually exclusive, but cargo does not support that.
@@ -22,8 +22,8 @@ binding-recompile = ["bindgen"]
# Default: NSS
crypto_dummy = []
crypto_openssl = ["openssl", "openssl-sys"]
-crypto_nss = ["nss-gk-api", "pkcs11-bindings"]
-gecko = ["nss-gk-api/gecko"]
+#crypto_nss = ["nss-gk-api", "pkcs11-bindings"]
+#gecko = ["nss-gk-api/gecko"]
[target.'cfg(target_os = "linux")'.dependencies]
libudev = "^0.2"
@@ -67,7 +67,7 @@ cfg-if = "1.0"
# Crypto backends
openssl-sys = { version = "0.9", optional = true}
openssl = { version = "0.10", optional = true}
-nss-gk-api = { version = "0.3.0", optional = true }
+#nss-gk-api = { version = "0.3.0", optional = true }
pkcs11-bindings = { version = "0.1.4", optional = true }
[dev-dependencies]
I've attached the log below, I hope this help understanding the issue.
ledger_authenticator_ctap2_failure.txt
Regarding dummy request, first thanks for the links on Google Chrome code, that's interesting.
I guess I should look at implementing the FIDO2.1 spec, this might improve some behavior as it seems implemented (and even expected) in browser.
There may be some constellations were we could use the actual request instead of the dummy to make the device fail, but it doesn't really matter what we send, if all we want to do is collect a user-interaction and fail.
I still don't get why you want a user-interaction at that point. From my point of view, if the authenticator respond to the request with a failure without requesting UV or UP it's already an issue, as one could then design a rogue client which could then try to get information on known credentials. that's why the authenticator has to do this, and this is specified in both FIDO2 and FIDO2.1 spec:
- FIDO2: The step 7 (collecting UV or UP) should be done before step 8 (responding if no credential is present): "Collect user consent if required. This step MUST happen before the following steps due to privacy reasons (i.e., authenticator cannot disclose existence of a credential until the user interacted with the device):"
- FIDO2.1 : UV verification should be done in step 6 before maybe responding in step 7 and credentials can be protected to request UV for access.
Thanks,
Xavier
from authenticator-rs.
Hello @msirringhaus I found a way to work around the problem.
I think it is because in the getAssertion response, the authenticator doesn't add the credential (0x01)
member.
This is allowed by the FIDO2 spec in some situation, which this one is:
Optional PublicKeyCredentialDescriptor structure containing the credential identifier whose private key was used to generate the assertion. May be omitted if the allowList has exactly one Credential.
However, it's seems that your implementation enforces it, I try adding it in my authenticator response, and after that, the ctap2 example run successfully.
Do you think this is something you could change to be compatible with more devices that respect the FIDO2 spec?
I guess this should require some changes around here: https://github.com/mozilla/authenticator-rs/blob/ctap2-2021/src/ctap2/mod.rs#L661-L673
I still don't get why it works on Firefox on Linux and on Windows, but not on Firefox on Mac nor when directly using authenticator-rs (on Mac or Linux), do you know?
Edit: looking at the FIDO2.1 spec, this credential (0x01)
member is required, so I guess I will change the authenticator behavior to always include it.
Also, I now see that in such situation, your authenticator code make a first silent getAssertion request (with up=false and uv=false) and then a second requiring user presence and verifiation. So now behaving mainly as I expected it in working cases.
So if it's ok for you, I'm going to change the title of this issue to:
Wrongly enforces getAssertion credential (0x01)
member presence in the authenticator response, which is optional in FIDO2
Thanks
Xavier
from authenticator-rs.
Ok, this makes no sense to me. We do not enforce user
to be present anywhere, as far as I can tell.
What I've noticed, though, is that you do not send the credentialID in your GetAssertion response. This is fine for CTAP2.0 devices (although not allowed anymore for 2.1), but it looks to me that our code may have a bug there, and disregard your token because this is missing.
The only situation the omission is allowed for CTAP2.0 is, if the allowList has length 1. This may explain why it sometimes works, and sometimes doesn't. You could try to add a dummy credential to the allowList in examples/ctap2.rs
, and see if it works then?
from authenticator-rs.
Ok sorry, I was editing my response. Indeed, the issue is due to the absence of credential (0x01) member in the response.
from authenticator-rs.
Here is what I have added in my response:
looking at the FIDO2.1 spec, this
credential (0x01)
member is required, so I guess I will change the authenticator behavior to always include it.Also, I now see that in such situation, your authenticator code make a first silent getAssertion request (with up=false and uv=false) and then a second requiring user presence and verifiation. So now behaving mainly as I expected it in working cases.
So if it's ok for you, I'm going to change the title of this issue to: Wrongly enforces getAssertion
credential (0x01)
member presence in the authenticator response, which is optional in FIDO2
from authenticator-rs.
Ah, mid-air collision :) Yes, now it makes sense to me.
The problem is in our pre-flighting code here: https://github.com/mozilla/authenticator-rs/blob/ctap2-2021/src/ctap2/preflight.rs#L168-L171
I'll see, if I can come up with a fix (that doesn't introduce 10 additional bugs).
from authenticator-rs.
Resolved by #320
from authenticator-rs.
Related Issues (20)
- Get rid of nom? HOT 1
- Pre-flighting breaks AppID support HOT 1
- Select a reasonable default pin protocol when `pinUvAuthProtocols` is absent from GetInfo response HOT 1
- Access Raw Auth Data HOT 2
- FIDO_2_0 devices with no pin set - experiencing unexpected make credential behavior HOT 7
- Rewrite tests that use mock devices
- Consider only blinking useful tokens from DeviceSelector
- Add AuthenticatorData::to_writer
- Get rid of bitflags
- Avoid clippy randomly breaking the CI HOT 1
- Add a status update to tell the user to connect a device HOT 1
- Inconsistent Serialization/Deserialization Behavior with Empty Extension Data in attestation.rs HOT 1
- Support Hybrid Transport / caBLE
- Dependency serde_cbor is unmaintained HOT 2
- USB transport isn't working and always showing passkey as the first option HOT 2
- AppId Extension is broken again for FIDO2 security keys in Firefox 122 HOT 10
- Broken since last April with SoloKeys (v1) HOT 5
- [Bug] Registration fails when device is full and discoverable credentials is only preferred.
- Review use of GetVersion with CTAP1 devices HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from authenticator-rs.