Skip to content

Commit 97ba35b

Browse files
Make the HID channel safer (fix #103) (#109)
Fixes #103. Also protect against mutex poisoning.
1 parent e11bd71 commit 97ba35b

4 files changed

Lines changed: 23 additions & 9 deletions

File tree

libwebauthn/src/transport/ble/channel.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ use crate::proto::ctap1::apdu::{ApduRequest, ApduResponse};
77
use crate::proto::ctap2::cbor::{CborRequest, CborResponse};
88
use crate::proto::CtapError;
99
use crate::transport::ble::btleplug;
10-
use crate::transport::channel::{
11-
AuthTokenData, Channel, ChannelStatus, Ctap2AuthTokenStore,
12-
};
10+
use crate::transport::channel::{AuthTokenData, Channel, ChannelStatus, Ctap2AuthTokenStore};
1311
use crate::transport::device::SupportedProtocols;
1412
use crate::transport::error::{Error, TransportError};
1513
use crate::UxUpdate;
@@ -129,7 +127,9 @@ impl<'a> Channel for BleChannel<'a> {
129127
debug!("Sending CBOR request");
130128
trace!(?request);
131129

132-
let cbor_request = request.raw_long().or(Err(TransportError::InvalidFraming))?;
130+
let cbor_request = request
131+
.raw_long()
132+
.map_err(|e| TransportError::IoError(e.kind()))?;
133133
let request_frame = BleFrame::new(BleCommand::Msg, &cbor_request);
134134
self.connection
135135
.frame_send(&request_frame)

libwebauthn/src/transport/cable/tunnel.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,9 @@ async fn connection_send(
453453
debug!("Sending CBOR request");
454454
trace!(?request);
455455

456-
let cbor_request = request.raw_long().or(Err(TransportError::InvalidFraming))?;
456+
let cbor_request = request
457+
.raw_long()
458+
.map_err(|e| TransportError::IoError(e.kind()))?;
457459
if cbor_request.len() > MAX_CBOR_SIZE {
458460
error!(
459461
cbor_request_len = cbor_request.len(),

libwebauthn/src/transport/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub enum TransportError {
4040
InvalidKey,
4141
#[error("invalid signature")]
4242
InvalidSignature,
43+
#[error("input/output error: {0}")]
44+
IoError(std::io::ErrorKind),
4345
}
4446

4547
#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq)]

libwebauthn/src/transport/hid/channel.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,10 @@ impl<'d> HidChannel<'d> {
246246
pub async fn hid_send(&self, msg: &HidMessage) -> Result<(), Error> {
247247
match &self.open_device {
248248
OpenHidDevice::HidApiDevice(hidapi_device) => {
249-
let guard = hidapi_device.lock().unwrap();
249+
let Ok(guard) = hidapi_device.lock() else {
250+
warn!("Poisoned lock on HID API device");
251+
return Err(Error::Transport(TransportError::ConnectionLost));
252+
};
250253
Self::hid_send_hidapi(guard.deref(), msg)
251254
}
252255
#[cfg(feature = "virtual-hid-device")]
@@ -264,7 +267,9 @@ impl<'d> HidChannel<'d> {
264267
report.extend(vec![0; PACKET_SIZE - packet.len()]);
265268
debug!({ packet = i, len = report.len() }, "Sending packet as HID report",);
266269
trace!(?report);
267-
device.write(&report).unwrap();
270+
device
271+
.write(&report)
272+
.or(Err(Error::Transport(TransportError::ConnectionLost)))?;
268273
}
269274
Ok(())
270275
}
@@ -307,7 +312,10 @@ impl<'d> HidChannel<'d> {
307312
loop {
308313
let response = match &self.open_device {
309314
OpenHidDevice::HidApiDevice(hidapi_device) => {
310-
let guard = hidapi_device.lock().unwrap();
315+
let Ok(guard) = hidapi_device.lock() else {
316+
warn!("Poisoned lock on HID API device");
317+
return Err(Error::Transport(TransportError::ConnectionLost));
318+
};
311319
Self::hid_recv_hidapi(guard.deref(), timeout)
312320
}
313321
#[cfg(feature = "virtual-hid-device")]
@@ -440,7 +448,9 @@ impl Channel for HidChannel<'_> {
440448
let cid = self.init.cid;
441449
debug!({ cid }, "Sending APDU request");
442450
trace!(?request);
443-
let apdu_raw = request.raw_long().unwrap();
451+
let apdu_raw = request
452+
.raw_long()
453+
.map_err(|e| TransportError::IoError(e.kind()))?;
444454
self.hid_send(&HidMessage::new(cid, HidCommand::Msg, &apdu_raw))
445455
.await?;
446456
Ok(())

0 commit comments

Comments
 (0)