Skip to content

Commit f5fbced

Browse files
committed
Adapt nfc transport to API changes
1 parent 31e147a commit f5fbced

File tree

5 files changed

+53
-34
lines changed

5 files changed

+53
-34
lines changed

libwebauthn/src/transport/nfc/channel.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ use async_trait::async_trait;
55
use std::fmt;
66
use std::fmt::{Debug, Display, Formatter};
77
use std::time::Duration;
8-
use tokio::sync::mpsc;
8+
use tokio::sync::broadcast;
9+
use tokio::sync::mpsc::{self, Sender};
910
#[allow(unused_imports)]
1011
use tracing::{Level, debug, instrument, trace, warn};
1112

12-
use crate::UxUpdate;
13+
use crate::webauthn::error::Error;
14+
use crate::UvUpdate;
1315
use crate::proto::ctap1::apdu::{ApduRequest, ApduResponse};
1416
use crate::proto::ctap2::cbor::{CborRequest, CborResponse};
1517
use crate::transport::channel::{AuthTokenData, Channel, ChannelStatus, Ctap2AuthTokenStore};
1618
use crate::transport::device::SupportedProtocols;
17-
use crate::transport::error::{Error, TransportError};
19+
use crate::transport::error::TransportError;
1820

1921
use super::commands::{command_ctap_msg, command_get_response};
2022

@@ -23,6 +25,8 @@ const SELECT_P2: u8 = 0x00;
2325
const APDU_FIDO: &[u8; 8] = b"\xa0\x00\x00\x06\x47\x2f\x00\x01";
2426
const SW1_MORE_DATA: u8 = 0x61;
2527

28+
pub type CancelNfcOperation = ();
29+
2630
#[derive(thiserror::Error)]
2731
pub enum NfcError {
2832
/// APDU error returned by the card.
@@ -68,15 +72,27 @@ pub trait HandlerInCtx<Ctx> {
6872

6973
pub trait NfcBackend<Ctx>: HandlerInCtx<Ctx> + Display {}
7074

75+
#[derive(Debug, Clone)]
76+
pub struct NfcChannelHandle {
77+
tx: Sender<CancelNfcOperation>,
78+
}
79+
80+
impl NfcChannelHandle {
81+
pub async fn cancel_ongoing_operation(&self) {
82+
let _ = self.tx.send(()).await;
83+
}
84+
}
85+
7186
pub struct NfcChannel<Ctx>
7287
where
7388
Ctx: Copy + Sync,
7489
{
7590
delegate: Box<dyn NfcBackend<Ctx> + Send + Sync>,
7691
auth_token_data: Option<AuthTokenData>,
77-
tx: mpsc::Sender<UxUpdate>,
92+
ux_update_sender: broadcast::Sender<UvUpdate>,
93+
handle: NfcChannelHandle,
7894
ctx: Ctx,
79-
apdu_response: Option<ApduResponse>,
95+
_apdu_response: Option<ApduResponse>,
8096
cbor_response: Option<CborResponse>,
8197
supported: SupportedProtocols,
8298
status: ChannelStatus,
@@ -98,14 +114,17 @@ where
98114
pub fn new(
99115
delegate: Box<dyn NfcBackend<Ctx> + Send + Sync>,
100116
ctx: Ctx,
101-
tx: mpsc::Sender<UxUpdate>,
102117
) -> Self {
118+
let (ux_update_sender, _) = broadcast::channel(16);
119+
let (handle_tx, _handle_rx) = mpsc::channel(1);
120+
let handle = NfcChannelHandle { tx: handle_tx };
103121
NfcChannel {
104122
delegate,
105123
auth_token_data: None,
106-
tx,
124+
ux_update_sender,
125+
handle,
107126
ctx,
108-
apdu_response: None,
127+
_apdu_response: None,
109128
cbor_response: None,
110129
supported: SupportedProtocols {
111130
fido2: false,
@@ -115,6 +134,10 @@ where
115134
}
116135
}
117136

137+
pub fn get_handle(&self) -> NfcChannelHandle {
138+
self.handle.clone()
139+
}
140+
118141
#[instrument(skip_all)]
119142
pub async fn wink(&mut self, _timeout: Duration) -> Result<bool, Error> {
120143
warn!("WINK capability is not supported");
@@ -192,6 +215,8 @@ impl<'a, Ctx> Channel for NfcChannel<Ctx>
192215
where
193216
Ctx: Copy + Send + Sync + fmt::Debug + Display,
194217
{
218+
type UxUpdate = UvUpdate;
219+
195220
async fn supported_protocols(&self) -> Result<SupportedProtocols, Error> {
196221
Ok(self.supported)
197222
}
@@ -205,7 +230,7 @@ where
205230
}
206231

207232
#[instrument(level = Level::DEBUG, skip_all)]
208-
async fn apdu_send(&self, request: &ApduRequest, _timeout: Duration) -> Result<(), Error> {
233+
async fn apdu_send(&self, _request: &ApduRequest, _timeout: Duration) -> Result<(), Error> {
209234
todo!("apdu_send")
210235
}
211236

@@ -272,8 +297,8 @@ where
272297
.ok_or(Error::Transport(TransportError::InvalidFraming))
273298
}
274299

275-
fn get_state_sender(&self) -> &mpsc::Sender<UxUpdate> {
276-
&self.tx
300+
fn get_ux_update_sender(&self) -> &broadcast::Sender<UvUpdate> {
301+
&self.ux_update_sender
277302
}
278303
}
279304

libwebauthn/src/transport/nfc/commands.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn command_get_response(p1: u8, p2: u8, le: u8) -> GetResponseCommand {
4646

4747
const CLA_HAS_MORE: u8 = 0x10;
4848
const INS_CTAP_MSG: u8 = 0x10;
49-
const CTAP_P1_SUPP_GET_RESP: u8 = 0x80;
49+
const _CTAP_P1_SUPP_GET_RESP: u8 = 0x80;
5050
const CTAP_P2: u8 = 0x00;
5151

5252
/// `CTAP MSG` (0x10) command.

libwebauthn/src/transport/nfc/device.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
use async_trait::async_trait;
22
use std::fmt;
3-
use tokio::sync::mpsc;
43
#[allow(unused_imports)]
54
use tracing::{debug, info, instrument, trace};
65

7-
use crate::UxUpdate;
6+
use crate::webauthn::error::Error;
87
use crate::transport::device::Device;
9-
use crate::transport::error::Error;
108

119
use super::channel::NfcChannel;
1210
#[cfg(feature = "libnfc")]
@@ -62,9 +60,9 @@ impl NfcDevice {
6260

6361
fn channel_sync<'d>(
6462
&'d self,
65-
) -> Result<(NfcChannel<Context>, mpsc::Receiver<UxUpdate>), Error> {
63+
) -> Result<NfcChannel<Context>, Error> {
6664
trace!("nfc channel {:?}", self);
67-
let (mut channel, recv): (NfcChannel<Context>, mpsc::Receiver<UxUpdate>) = match &self.info
65+
let mut channel: NfcChannel<Context> = match &self.info
6866
{
6967
#[cfg(feature = "libnfc")]
7068
DeviceInfo::LibNfc(info) => info.channel(),
@@ -74,15 +72,15 @@ impl NfcDevice {
7472

7573
channel.select_fido2()?;
7674

77-
Ok((channel, recv))
75+
Ok(channel)
7876
}
7977
}
8078

8179
#[async_trait]
8280
impl<'d> Device<'d, Nfc, NfcChannel<Context>> for NfcDevice {
8381
async fn channel(
8482
&'d mut self,
85-
) -> Result<(NfcChannel<Context>, mpsc::Receiver<UxUpdate>), Error> {
83+
) -> Result<NfcChannel<Context>, Error> {
8684
self.channel_sync()
8785
}
8886
}
@@ -95,7 +93,7 @@ where
9593
where
9694
Ctx: fmt::Debug + fmt::Display + Copy + Send + Sync,
9795
{
98-
let (mut chan, _send) = device.channel_sync()?;
96+
let mut chan = device.channel_sync()?;
9997
let _ = chan.select_fido2()?;
10098
Ok(true)
10199
}

libwebauthn/src/transport/nfc/libnfc/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::Context;
22
use super::channel::{HandlerInCtx, NfcBackend, NfcChannel};
33
use super::device::NfcDevice;
4-
use crate::UxUpdate;
5-
use crate::transport::error::{Error, TransportError};
4+
use crate::webauthn::error::Error;
5+
use crate::transport::error::TransportError;
66
use apdu::core::HandleError;
77
use apdu_core;
88
use std::fmt;
@@ -11,7 +11,6 @@ use std::io::Write;
1111
use std::sync::{Arc, Mutex};
1212
use std::thread;
1313
use std::time::Duration;
14-
use tokio::sync::mpsc;
1514
#[allow(unused_imports)]
1615
use tracing::{debug, info, instrument, trace};
1716

@@ -70,8 +69,7 @@ impl Info {
7069
}
7170
}
7271

73-
pub fn channel(&self) -> Result<(NfcChannel<Context>, mpsc::Receiver<UxUpdate>), Error> {
74-
let (send, recv) = mpsc::channel(1);
72+
pub fn channel(&self) -> Result<NfcChannel<Context>, Error> {
7573
let context = nfc1::Context::new().map_err(|e| map_error(e))?;
7674

7775
let mut chan = Channel::new(self, context);
@@ -89,8 +87,8 @@ impl Info {
8987
debug!("Selected: {:?}", target);
9088

9189
let ctx = Context {};
92-
let channel = NfcChannel::new(Box::new(chan), ctx, send);
93-
Ok((channel, recv))
90+
let channel = NfcChannel::new(Box::new(chan), ctx);
91+
Ok(channel)
9492
}
9593
}
9694

libwebauthn/src/transport/nfc/pcsc/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
use super::Context;
22
use super::channel::{HandlerInCtx, NfcBackend, NfcChannel};
33
use super::device::NfcDevice;
4-
use crate::UxUpdate;
5-
use crate::transport::error::{Error, TransportError};
4+
use crate::webauthn::error::Error;
5+
use crate::transport::error::TransportError;
66
use apdu::core::HandleError;
77
use pcsc;
88
use std::ffi::{CStr, CString};
99
use std::fmt;
1010
use std::fmt::Debug;
1111
use std::ops::Deref;
1212
use std::sync::{Arc, Mutex};
13-
use tokio::sync::mpsc;
1413
#[allow(unused_imports)]
1514
use tracing::{debug, info, instrument, trace};
1615

@@ -92,14 +91,13 @@ impl Info {
9291
}
9392
}
9493

95-
pub fn channel(&self) -> Result<(NfcChannel<Context>, mpsc::Receiver<UxUpdate>), Error> {
96-
let (send, recv) = mpsc::channel(1);
94+
pub fn channel(&self) -> Result<NfcChannel<Context>, Error> {
9795
let context = pcsc::Context::establish(pcsc::Scope::User)?;
9896
let chan = Channel::new(self, context)?;
9997

10098
let ctx = Context {};
101-
let channel = NfcChannel::new(Box::new(chan), ctx, send);
102-
Ok((channel, recv))
99+
let channel = NfcChannel::new(Box::new(chan), ctx);
100+
Ok(channel)
103101
}
104102
}
105103

0 commit comments

Comments
 (0)