Skip to content
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

WIP: Implement U2F TwoFactor Authorization (on Android) #662

Closed
wants to merge 0 commits into from

Conversation

mastacheata
Copy link

NOTE: This is a work in progress, just opened the pull request in order to properly share the idea and ask for help,

I started working on FIDO-U2F 2nd Factor stuff yesterday, but only got to a point where it will immediately return from the intent without even trying to ask for a token. Instead I get an ErrorResponse with ERROR_OTHER as the Response Code.

I've so far identified 2 possible causes, but am not sure about that as there is no more information in the error than "Other".

Cause 1 woud be that I have the appId wrong. I tried to get that from the challenge issued by the Bitwarden server, but that might be a mistake as a JSON URL is not actually an appId. Instead I should probably pick one of the IDs from that JSON file (in this case, the Android App identifier).
If that is the case, should I just hardcode the ID, grab the one from the remote JSON or is there a way for the Android part of the app to know it's own ID?

The other thing that might be wrong is how I deserialize and then convert to the requested byte array for the keys from a string. In the debugger the string representation of the keys list changes multiple times between the string from the JSON response, the byte array and the "RegisteredKeys" object.

In the end I somehow need to retry the login with the signed challenge / the response from the U2F key. I have no idea how to do that, All the other 2-factor challenges work without sending a challenge to the 3rd party and are either time or account based as it seems.

I guess I'll figure that out as soon as I got the correct signed challenge / the response from the U2F token.

private async Task<bool> ListenU2F(Dictionary<string, object> data)
{
var appId = Uri.Parse((string)data["appId"]);
var challenge = Encoding.ASCII.GetBytes((string) data["challenge"]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that challenge is a "url safe" base 64 encoded string. See here for a method that can decode that: https://github.com/bitwarden/mobile/blob/master/src/Core/Services/TokenService.cs#L203

Might want to mvoe that method into a static core helper.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint, will try that in the next few days.

I'll clean that up once I got everything up and running. I just noticed that I'll need at least 2 entrypoints to the U2F functionality when I started and before that I just picked up where you left comments about implementing U2F sometime in the future.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you by any chance know how the U2F appId must be formatted? I fear that this is my actual problem here. The Bitwarden Server returns a link to the https://vault.bitwarden.com/app-id.json and from the documentation of U2F I read, that's not a valid app identifier. Instead it seems like this just tells me which appIds will be accepted by the server when I open that reference.

I think I might need to insert the Android App ID in the appId field, but I'm not sure how to obtain that yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app id should be https://vault.bitwarden.com/app-id.json.

If that doesn't work, then maybe try android:apk-key-hash:dUGFzUzf3lmHSLBDBIv+WaFyZMI, which is defined in that JSON file for the Bitwarden android app.

foreach (var key in keys)
{
var keyHandle = new KeyHandle(
Encoding.ASCII.GetBytes(key["keyHandle"]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be the same, a "url safe" base 64 encoded string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any updates?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I haven't found any documentation on how the Original Android API is supposed to work with other providers than Google itself. There's also no Open Source projects using either the Xamarin Library or the original Android Java classes to access third-party U2F/FIDO2 providers. I'm pretty much stuck not knowing what I might do wrong/what format the Android API expects.

Copy link

@nerrixde nerrixde Feb 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not really in this topic, but why https://github.com/android/security-samples/tree/master/Fido not helps / is not an option?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mastacheata
Copy link
Author

mastacheata commented Feb 21, 2020 via email

@CLAassistant
Copy link

CLAassistant commented Mar 7, 2020

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@mKoonrad
Copy link

mKoonrad commented Mar 9, 2020

@mastacheata 1Password recently released their Android app (version 7.4) with security key support. It looks like they've found any solution.

@mastacheata
Copy link
Author

@mastacheata 1Password recently released their Android app (version 7.4) with security key support. It looks like they've found any solution.

1password isn't open source and most likely not written in Xamarin.
The "easy" solution is to hand over the authentication to a web browser / web view. On Android webauthn is supported by Firefox and Chrome. That would even work on ios as long as the brave browser is installed.

@nerrixde
Copy link

nerrixde commented Mar 9, 2020

Not having U2F support on android is a major issue for me and makes me really consider switching to 1password away from Bitwarden.
It is definitly possible to implement and well, it might require a bit more work than just implementing a library by adding 10 lines of code.
But I really wish I don't have to wait for this until the next standard is released....

@mastacheata
Copy link
Author

I'm fine with the biometric authentication on my phone, but would definitely like to have U2F/FIDO2 as well, but I'm a web developer by trade and have close to zero knowledge of mobile development.
The Xamarin library is basically just a wrapper around the native Google Android APIs, but even those have barely any documentation.

Pretty much all the documentation you can find on both U2F and FIDO2 are strongly linked to Web Authentication through the browser. On Android you can easily get both to work in Chrome and Firefox and it even works on iOS if you use the Brave browser (no idea how they managed to include that feature as it's just like all other browsers only a wrapper around the included Safari on iOS).

If you find any documentation/examples about how to do FIDO2/U2F/Webauthn on Android in a native application and NOT using the Google account, please let me know and I'll try to pick up my work on this feature again. Otherwise, we'll have to wait and see if Kyle (the author/lead developer of Bitwarden) can find some time to look into that or find someone with more knowledge...

@rdslw
Copy link

rdslw commented Mar 12, 2020

For all waiting: 1password currently supports 2FA on android.

@mastacheata
Copy link
Author

For all waiting: 1password currently supports 2FA on android.

mKonrad already noticed that 3 posts above.
It's not gonna help with this issue, though, as 1password is not open source and we can't learn from how they did it. (And even if we could, it's probably a native Java Application and not taking the detour through Xamarin like Bitwarden does)

@nerrixde
Copy link

@Bitwarden-Staff How is the priority? You really should prioritize it, as consumers want it. Some consider switching.

@schlomie
Copy link

I have not dug into the code, so I have absolutely no idea if this would prove helpful, but the OnlyKey guys have done some work with communicating with their usb token over U2F on android.

https://github.com/trustcrypto/Android-OnlyKey-U2F

@arianvp
Copy link

arianvp commented Mar 18, 2020

Is it really important for it to be U2f?

FIDO2 is backwards-compatible wit U2F and the android APIs for FIDO2 Closely model the welldocumented webauthn spec for browsers. I'm currently experimenting with a minimal app to get things working on kotlin.

However this might require changes on bitwarden server. Is that realistic?

@arianvp
Copy link

arianvp commented Mar 18, 2020

I started working on FIDO-U2F 2nd Factor stuff yesterday, but only got to a point where it will immediately return from the intent without even trying to ask for a token

@mastacheata was this in the emulator by any chance? I have the same issue when trying out the FIDO2 API using Google's own examples. I think FIDO2 stuff in the emulator is just bugged

@mastacheata
Copy link
Author

mastacheata commented Mar 18, 2020

I started working on FIDO-U2F 2nd Factor stuff yesterday, but only got to a point where it will immediately return from the intent without even trying to ask for a token

@mastacheata was this in the emulator by any chance? I have the same issue when trying out the FIDO2 API using Google's own examples. I think FIDO2 stuff in the emulator is just bugged

Sadly, no. This was debugging on a physical device. (Pixel 3 and HTC10)

Maybe it's an option to ditch the native approach and instead use a WebView? Both Chrome and Firefox (only the stable version, not the Preview yet) work perfectly fine with WebAuthn / FIDO2 / FIDO-U2F.

FIDO2 is backwards-compatible wit U2F

That's optional and up to the server to decide that.

Is it really important for it to be U2f?

There are by far more U2F tokens than there are FIDO2 ones around. (At least if you exclude the Android software-token where your device can act as security token for your PC or another phone)
That's why I think U2F-support is important.

Whether you do that via the Webauthn/FIDO2 API or the U2F API doesn't matter, I think.

Copy link

@nerrixde nerrixde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any updates?

@Ceveos
Copy link

Ceveos commented Sep 14, 2020

Any update on this? This would be a major feature that would help convert a few to Bitwarden Premium

@kibartas
Copy link

kibartas commented Dec 8, 2020

Updates? Is there still the same issue with this?

@mastacheata
Copy link
Author

mastacheata commented Dec 8, 2020

Yeah, I haven't done any work on this as you can see and only opened this PR to look for support from other developers. Sadly Bitwarden doesn't seem to attract many developers and is pretty much developed solely by the company itself.

In the Bitwarden forum one of their devs announced U2F being pretty high on their roadmap. That's it however. No news or timeframe after that.

@kibartas
Copy link

kibartas commented Dec 8, 2020

That's unfortunate then. It'd be interesting to have a crack at it, still. Some time has passed maybe it'd be more clear how to implement FIDO U2F now than back when you did it.

EDIT: okay. So the development is ongoing but nothing else is known. Alright... that's quite demotivating. Guess we'll just have to wait

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.

None yet

10 participants