-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework CTAP2.0 GetPinToken-workflow #237
Conversation
Once #205 lands, this needs of course some rebasing, and then it should be hopefully rather straight forward to implement the CTAP2.1 auth-workflows. |
Nice! I can confirm that this code change does not break ThinC CTAP2.0 token. I wasn't able to build this change into Firefox due to a reason with a dependency with error
I would love to test UV = Discouraged, Preferred, Required once I can build this into Firefox. |
callback.call(Err(e)); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, let's add a helper function for the error cases. There's a lot of duplication with sign
, and right now they differ unnecessarily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly, they do NOT differ unnecessarily. They actually are different, because the spec (or at least how vendors interpret it) are different for GetAssertion and MakeCredential, in what they return in case of errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just handle the difference in repackage_pin_errors
? If not, I think we should avoid using repackage_pin_errors
entirely. A flat list of cases would be easier to follow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we need repackage_pin_errors
in other places as well, I've introduced a new function (which also uses it), that handles the differences, so we can move all of it out of statemachine.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Some minor comments below.
callback.call(Err(e)); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just handle the difference in repackage_pin_errors
? If not, I think we should avoid using repackage_pin_errors
entirely. A flat list of cases would be easier to follow.
I tested this PR with my mooltipass:
|
Thank you @andreydanil and @VincentVanlaer for testing. @VincentVanlaer: Could you open an issue for the failing |
Ok(PinUvAuthResult::SuccessGetPinToken) | ||
} | ||
|
||
fn handle_auth_command_errors<D: FidoDevice>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not really "unify the cases" as we're now just pushing the dependence on Self::command() into this function. I'm sorry to go back and forth on this minor point, but I think we should do the flat list of cases instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So reverting this change and doing what we did before? Or something else entirely?
"Avoiding duplicate code, if possible" and "having a flat list" unfortunately are at odds in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it will be easier for me to just submit a follow up patch with what I'm imagining. This is not as clear as I'd like it to be, but it does appear to be correct.
} | ||
|
||
let pin_auth = dev | ||
.get_pin_token(&self.client_data_hash(), self.pin()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will ultimately call set_shared_secret
on Device
. Where are we doing that in the UsingInternalUv
case?
Maybe we need to implement and integrate getPinUvAuthTokenUsingUvWithPermissions
before we can land this patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you are right. I was under the impression, that we do not need the shared_secret, if we don't use a PIN. But we may need it for the hmac-extension (which I'm currently not sure, if it works correctly anyways).
I'll add a dev.establish_shared_secret()?;
to the UsingInternalUv-case.
Waiting for getPinUvAuthTokenUsingUvWithPermissions
will (probably) not change anything here, since the plan is to do that in a separate function (hence the name determine_pin_uv_auth_ctap_2_0()
).
The InternalUv-case needs to work for CTAP2.0-only tokens as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, sounds good. I didn't realize that Internal UV did not require the shared secret in 2.0, but we do need it for the hmac extension (even though it's not currently working).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
} | ||
|
||
let pin_auth = dev | ||
.get_pin_token(&self.client_data_hash(), self.pin()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, sounds good. I didn't realize that Internal UV did not require the shared secret in 2.0, but we do need it for the hmac extension (even though it's not currently working).
Ok(PinUvAuthResult::SuccessGetPinToken) | ||
} | ||
|
||
fn handle_auth_command_errors<D: FidoDevice>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it will be easier for me to just submit a follow up patch with what I'm imagining. This is not as clear as I'd like it to be, but it does appear to be correct.
I did some digging in the meantime and it seems that the mooltipass is not returning the name field, even though it is set when the credential is created (and is stored as I can see it on the screen). There does seem to be a possibility in the spec to not send the name field back when the user is not verified, but I consider that a discussion to be had on the mooltipass side whether this applies or not (I'm assuming it doesn't really apply and the mooltipass should send the name field) |
Trying to rework the GetPinToken-workflow, in order to work for tokens with and without UV.
Tested this with Yubikey BIO.
Would be great to if @andreydanil and @VincentVanlaer could also test this with their ThinC and Mooltipass respectively.
To test, run examples
ctap2
andctap2_discoverable_credentials
with this patch and see if