AlfioEmanueleFresta / xdg-credentials-portal

FIDO2 (WebAuthn) and FIDO U2F platform library for Linux written in Rust; includes a proposal for a new D-Bus Portal interface for FIDO2, accessible from Flatpak apps and Snaps 🔑
GNU Lesser General Public License v2.1
366 stars 13 forks source link

FIDO2 over BLE #27

Open tgagneret-embedded opened 2 years ago

tgagneret-embedded commented 2 years ago

Hi,

Is it possible to have an example code for webauthn/FIDO2 over BLE ?

Thanks

AlfioEmanueleFresta commented 2 years ago

Thanks for your interest! Each transport has its own methods to list devices, and get a channel to the authenticator; but all channels expose the same APIs for U2F and WebAuthn. There is no single working example for this, but here are some relevant examples from libwebauthn/examples:

  1. u2f_ble.rs shows how to fetch a list of BLE devices; then
  2. webauthn_hid.rs shows how to use WebAuthn's MakeCredential and GetAssertion operations.

Unfortunately this will currently result in a panic, because the following methods are not implemented (see #3):

BleChannel::cbor_send
BleChannel::cbor_recv

These should be trivial to implement, however sadly I have been unable to get my hands on any FIDO2 BLE devices, which I would need to test this. @tgagneret-embedded do you happen to know any such devices?

tgagneret-embedded commented 2 years ago

Hi @AlfioEmanueleFresta,

I'm not using a certified device, but I've managed to have something working with my device, I guess it's a start :) This is the associated PR: https://github.com/AlfioEmanueleFresta/xdg-credentials-portal/pull/28

I'll try to add an example in a PR if I have some time.

AlfioEmanueleFresta commented 2 years ago

Awesome! Thank you :)

tgagneret-embedded commented 2 years ago

Hi,

When trying to add an example I ran into a problem. The code force U2F protocol when using BLE (https://github.com/AlfioEmanueleFresta/xdg-credentials-portal/blob/daf4e48653f2c996f97d0ed245441f44dadc7e4a/libwebauthn/src/transport/ble/channel.rs#L36), but I need to use FIDO protocol.

The "channel" method from "Device" trait is an interface for HID and BLE. In HID the use of U2F or FIDO is included in the protocol but in BLE you need to specify it before sending any frame.

When using BLE, I guess it would be ideal to give the protocol you will use when calliing "channel" but it would break the interface (since it's not needed for HID devices).

Do you have any idea/input to help me solve this issue ?

Thanks

AlfioEmanueleFresta commented 2 years ago

Thanks for looking into this @tgagneret-embedded.

Passing the protocol when creating the channel would work. However, it would also effectively move the responsibility of negotiating the appropriate protocol onto the client. I don't think this is ideal, mainly because this is just the underlying protocol, and may not be meaningful to the client. For example, the client may be trying to perform a WebAuthn's authenticatorMakeCredential operation. This doesn't necessarily need the FIDO2 protocol: the platform client can detect a device only supporting U2F, and safely downgrade the WebAuthn request to a U2F register command. I believe this behaviour is well suited for the platform library to take care of, rather than its client.

Currently, for BLE, we select a protocol at connection time (ie. when the channel is created). I'm wondering if a better option is to do this lazily - only selecting a protocol before sending CBOR or APDU payloads, as part of the {cbor,apdu}_{send,recv} methods. A simple initial implementation would be to always select FIDO2 before sending CBOR payloads, and U2F before sending APDUs.

Note that by the time we are calling one of these Channel methods, protocol negotiation will have already taken place, preventing unsupported protocol methods from being invoked.

What do you think?

I'm mostly off the grid until tomorrow, sorry for any delays.

AlfioEmanueleFresta commented 2 years ago

Adding help-wanted label. If you have a FIDO2 BLE device that could be used for testing, please reach out!