Skip to content

Commit cde693e

Browse files
Fix ClientPayload serialization; Add ClientPayloadHint
1 parent 625fd50 commit cde693e

File tree

4 files changed

+33
-37
lines changed

4 files changed

+33
-37
lines changed

libwebauthn/examples/webauthn_cable.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::Duration;
55

66
use libwebauthn::pin::PinRequestReason;
77
use libwebauthn::transport::cable::known_devices::{
8-
self, CableKnownDevice, CableKnownDeviceId, CableKnownDeviceInfoStore, EphemeralDeviceInfoStore,
8+
CableKnownDevice, ClientPayloadHint, EphemeralDeviceInfoStore,
99
};
1010
use libwebauthn::transport::cable::qr_code_device::{CableQrCodeDevice, QrCodeOperationHint};
1111
use libwebauthn::UxUpdate;
@@ -142,8 +142,8 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
142142
(&response.authenticator_data).try_into().unwrap()
143143
};
144144

145-
println!("Waiting for 10 seconds before contacting the device...");
146-
sleep(Duration::from_secs(30)).await;
145+
println!("Waiting for 5 seconds before contacting the device...");
146+
sleep(Duration::from_secs(5)).await;
147147

148148
let get_assertion = GetAssertionRequest {
149149
relying_party_id: "example.org".to_owned(),
@@ -158,10 +158,13 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
158158
let (_known_device_id, known_device_info) =
159159
all_devices.first().expect("No known devices found");
160160

161-
let mut known_device: CableKnownDevice =
162-
CableKnownDevice::new(known_device_info, device_info_store.clone())
163-
.await
164-
.unwrap();
161+
let mut known_device: CableKnownDevice = CableKnownDevice::new(
162+
ClientPayloadHint::GetAssertion,
163+
known_device_info,
164+
device_info_store.clone(),
165+
)
166+
.await
167+
.unwrap();
165168

166169
// Connect to a known device
167170
let (mut channel, state_recv) = known_device.channel().await.unwrap();

libwebauthn/src/transport/cable/known_devices.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::UxUpdate;
1212
use async_trait::async_trait;
1313
use futures::lock::Mutex;
1414
use serde::Serialize;
15+
use serde_bytes::ByteBuf;
1516
use serde_indexed::SerializeIndexed;
1617
use tokio::sync::mpsc;
1718
use tracing::{debug, trace};
@@ -119,6 +120,7 @@ impl CableKnownDeviceInfo {
119120

120121
#[derive(Debug)]
121122
pub struct CableKnownDevice {
123+
pub hint: ClientPayloadHint,
122124
pub device_info: CableKnownDeviceInfo,
123125
pub(crate) store: Arc<dyn CableKnownDeviceInfoStore>,
124126
}
@@ -139,10 +141,12 @@ unsafe impl Sync for CableKnownDevice {}
139141

140142
impl CableKnownDevice {
141143
pub async fn new(
144+
hint: ClientPayloadHint,
142145
device_info: &CableKnownDeviceInfo,
143146
store: Arc<dyn CableKnownDeviceInfoStore>,
144147
) -> Result<CableKnownDevice, Error> {
145148
let device = CableKnownDevice {
149+
hint,
146150
device_info: device_info.clone(),
147151
store: store,
148152
};
@@ -155,7 +159,8 @@ impl<'d> Device<'d, Cable, CableChannel> for CableKnownDevice {
155159
async fn channel(&'d mut self) -> Result<(CableChannel, mpsc::Receiver<UxUpdate>), Error> {
156160
debug!(?self.device_info.tunnel_domain, "Creating channel to tunnel server");
157161

158-
let (client_nonce, client_payload) = construct_client_payload(self.device_info.link_id);
162+
let (client_nonce, client_payload) =
163+
construct_client_payload(self.hint, self.device_info.link_id);
159164
let contact_id = base64_url::encode(&self.device_info.contact_id);
160165

161166
let connection_type = tunnel::CableTunnelConnectionType::KnownDevice {
@@ -193,11 +198,6 @@ impl<'d> Device<'d, Cable, CableChannel> for CableKnownDevice {
193198
)
194199
.await
195200
}
196-
197-
// #[instrument(skip_all)]
198-
// async fn supported_protocols(&mut self) -> Result<SupportedProtocols, Error> {
199-
// todo!()
200-
// }
201201
}
202202

203203
type ClientNonce = [u8; 16];
@@ -206,27 +206,29 @@ type ClientNonce = [u8; 16];
206206
#[derive(Debug, SerializeIndexed)]
207207
#[serde(offset = 1)]
208208
pub struct ClientPayload {
209-
pub link_id: [u8; 8],
210-
pub client_nonce: ClientNonce,
209+
pub link_id: ByteBuf,
210+
pub client_nonce: ByteBuf,
211211
pub hint: ClientPayloadHint,
212212
}
213213

214-
#[derive(Debug, Serialize, PartialEq)]
214+
#[derive(Debug, Copy, Clone, Serialize, PartialEq)]
215215
pub enum ClientPayloadHint {
216216
#[serde(rename = "ga")]
217217
GetAssertion,
218218
#[serde(rename = "mc")]
219219
MakeCredential,
220220
}
221221

222-
fn construct_client_payload(link_id: [u8; 8]) -> (ClientNonce, ClientPayload) {
222+
fn construct_client_payload(
223+
hint: ClientPayloadHint,
224+
link_id: [u8; 8],
225+
) -> (ClientNonce, ClientPayload) {
223226
let client_nonce = rand::random::<ClientNonce>();
224227
let client_payload = {
225228
ClientPayload {
226-
link_id,
227-
client_nonce,
228-
// TODO: add hint
229-
hint: ClientPayloadHint::MakeCredential,
229+
link_id: ByteBuf::from(link_id),
230+
client_nonce: ByteBuf::from(client_nonce),
231+
hint,
230232
}
231233
};
232234
(client_nonce, client_payload)

libwebauthn/src/transport/cable/qr_code_device.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,14 @@ use crate::transport::Device;
2424
use crate::webauthn::TransportError;
2525
use crate::UxUpdate;
2626

27-
#[derive(Debug, Clone, Copy)]
27+
#[derive(Debug, Clone, Copy, Serialize, PartialEq)]
2828
pub enum QrCodeOperationHint {
29+
#[serde(rename = "ga")]
2930
GetAssertionRequest,
31+
#[serde(rename = "mc")]
3032
MakeCredential,
3133
}
3234

33-
impl Serialize for QrCodeOperationHint {
34-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35-
where
36-
S: serde::Serializer,
37-
{
38-
match self {
39-
QrCodeOperationHint::GetAssertionRequest => serializer.serialize_str("ga"),
40-
QrCodeOperationHint::MakeCredential => serializer.serialize_str("mc"),
41-
}
42-
}
43-
}
44-
4535
#[derive(Debug, SerializeIndexed)]
4636
pub struct CableQrCode {
4737
// Key 0: a 33-byte, P-256, X9.62, compressed public key.

libwebauthn/src/transport/cable/tunnel.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::collections::BTreeMap;
22
use std::sync::Arc;
33

44
use ctap_types::serde::cbor_deserialize;
5-
use ctap_types::serde::cbor_serialize;
65
use futures::{SinkExt, StreamExt};
76
use p256::NonZeroScalar;
87
use serde::Deserialize;
@@ -13,7 +12,7 @@ use sha2::{Digest, Sha256};
1312
use snow::{Builder, TransportState};
1413
use tokio::net::TcpStream;
1514
use tokio::sync::mpsc::{self, Receiver, Sender};
16-
use tokio::task::{self, JoinHandle};
15+
use tokio::task;
1716
use tokio_tungstenite::tungstenite::http::StatusCode;
1817
use tokio_tungstenite::tungstenite::Message;
1918
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
@@ -202,7 +201,9 @@ pub(crate) async fn connect<'d>(
202201
.or(Err(Error::Transport(TransportError::InvalidEndpoint)))?,
203202
);
204203
}
205-
let (mut ws_stream, response) = match connect_async(request).await {
204+
trace!(?request);
205+
206+
let (ws_stream, response) = match connect_async(request).await {
206207
Ok((ws_stream, response)) => (ws_stream, response),
207208
Err(e) => {
208209
error!(?e, "Failed to connect to tunnel server");

0 commit comments

Comments
 (0)