Skip to content

Commit 82f87b5

Browse files
feat(ble): support FIDO2 for BLE transport, chooses best protocol available (fix #27) (#175)
Fixes #27, adding support for FIDO over BLE. No reason not to prefer FIDO2 when available.
1 parent 6567b9c commit 82f87b5

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

libwebauthn/src/transport/ble/btleplug/manager.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ impl SupportedRevisions {
4949
}
5050
}
5151
}
52+
53+
pub fn select_best(&self) -> Option<FidoRevision> {
54+
self.select_protocol(FidoProtocol::FIDO2)
55+
.or_else(|| self.select_protocol(FidoProtocol::U2F))
56+
}
5257
}
5358

5459
async fn on_peripheral_service_data(
@@ -244,3 +249,59 @@ async fn discover_services(peripheral: &Peripheral) -> Result<FidoEndpoints, Err
244249
service_revision_bitfield,
245250
})
246251
}
252+
253+
#[cfg(test)]
254+
mod tests {
255+
use super::*;
256+
use crate::fido::FidoRevision;
257+
258+
#[test]
259+
fn select_best_prefers_fido2() {
260+
let revisions = SupportedRevisions {
261+
u2fv11: true,
262+
u2fv12: true,
263+
v2: true,
264+
};
265+
assert_eq!(revisions.select_best(), Some(FidoRevision::V2));
266+
}
267+
268+
#[test]
269+
fn select_best_falls_back_to_u2f() {
270+
let revisions = SupportedRevisions {
271+
u2fv11: true,
272+
u2fv12: true,
273+
v2: false,
274+
};
275+
assert_eq!(revisions.select_best(), Some(FidoRevision::U2fv12));
276+
}
277+
278+
#[test]
279+
fn select_best_falls_back_to_u2fv11() {
280+
let revisions = SupportedRevisions {
281+
u2fv11: true,
282+
u2fv12: false,
283+
v2: false,
284+
};
285+
assert_eq!(revisions.select_best(), Some(FidoRevision::U2fv11));
286+
}
287+
288+
#[test]
289+
fn select_best_fido2_only() {
290+
let revisions = SupportedRevisions {
291+
u2fv11: false,
292+
u2fv12: false,
293+
v2: true,
294+
};
295+
assert_eq!(revisions.select_best(), Some(FidoRevision::V2));
296+
}
297+
298+
#[test]
299+
fn select_best_none_supported() {
300+
let revisions = SupportedRevisions {
301+
u2fv11: false,
302+
u2fv12: false,
303+
v2: false,
304+
};
305+
assert_eq!(revisions.select_best(), None);
306+
}
307+
}

libwebauthn/src/transport/ble/channel.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::convert::TryInto;
22
use std::fmt::{Display, Formatter};
33
use std::time::Duration;
44

5-
use crate::fido::{FidoProtocol, FidoRevision};
5+
use crate::fido::FidoRevision;
66
use crate::proto::ctap1::apdu::{ApduRequest, ApduResponse};
77
use crate::proto::ctap2::cbor::{CborRequest, CborResponse};
88
use crate::proto::CtapError;
@@ -40,7 +40,7 @@ impl<'a> BleChannel<'a> {
4040
let (ux_update_sender, _) = broadcast::channel(16);
4141

4242
let revision = revisions
43-
.select_protocol(FidoProtocol::U2F)
43+
.select_best()
4444
.ok_or(Error::Transport(TransportError::NegotiationFailed))?;
4545
let connection = btleplug::connect(&device.btleplug_device.peripheral, &revision)
4646
.await

0 commit comments

Comments
 (0)