From 23d12ba40c3d2644ea744442d12617a29728ab14 Mon Sep 17 00:00:00 2001 From: kralonur Date: Thu, 14 May 2026 19:48:49 +0300 Subject: [PATCH] refactor(fido): split raw HID and CBOR response handling --- src/device/fido/hid.rs | 61 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/device/fido/hid.rs b/src/device/fido/hid.rs index 092a503..c9987b6 100644 --- a/src/device/fido/hid.rs +++ b/src/device/fido/hid.rs @@ -168,6 +168,11 @@ impl HidTransport { self.read_cbor_response(cmd) } + pub fn send_raw(&self, cmd: u8, payload: &[u8]) -> Result, PFError> { + self.write_cbor_request(cmd, payload)?; + self.read_hid_response(cmd) + } + fn write_cbor_request(&self, cmd: u8, payload: &[u8]) -> Result<(), PFError> { log::debug!( "Sending CBOR Command: 0x{:02X}, Payload Size: {} bytes", @@ -235,6 +240,32 @@ impl HidTransport { } fn read_cbor_response(&self, cmd: u8) -> Result, PFError> { + let response_data = self.read_hid_response(cmd)?; + + // Check CTAP Status Byte (First byte of payload) + if response_data.is_empty() { + log::error!("Device sent empty payload response."); + return Err(PFError::Device("Empty response".into())); + } + let status = response_data[0]; + if status != 0x00 { + log::error!("FIDO Operation returned failure status: 0x{:02X}", status); + return Err(PFError::Device(format!( + "FIDO Operation Failed with Status: 0x{:02X}", + status + ))); + } + + log::debug!( + "Command 0x{:02X} successful. Response payload len: {}", + cmd, + response_data.len() - 1 + ); + // Return payload without status byte + Ok(response_data[1..].to_vec()) + } + + fn read_hid_response(&self, cmd: u8) -> Result, PFError> { log::debug!("Waiting for response..."); let mut buf = [0u8; HID_REPORT_SIZE]; @@ -347,27 +378,7 @@ impl HidTransport { read_len += in_pkt; } - // 3. Check CTAP Status Byte (First byte of payload) - if response_data.is_empty() { - log::error!("Device sent empty payload response."); - return Err(PFError::Device("Empty response".into())); - } - let status = response_data[0]; - if status != 0x00 { - log::error!("FIDO Operation returned failure status: 0x{:02X}", status); - return Err(PFError::Device(format!( - "FIDO Operation Failed with Status: 0x{:02X}", - status - ))); - } - - log::debug!( - "Command 0x{:02X} successful. Response payload len: {}", - cmd, - response_data.len() - 1 - ); - // Return payload without status byte - Ok(response_data[1..].to_vec()) + Ok(response_data) } pub fn send_vendor_config( @@ -518,7 +529,7 @@ impl HidTransport { sub_params: Option, ) -> Result, PFError> { let mut sub_params_bytes: Vec = Vec::new(); - + if let Some(ref params) = sub_params { sub_params_bytes = to_vec(¶ms).map_err(|e| PFError::Io(e.to_string()))?; } @@ -599,7 +610,11 @@ impl HidTransport { Value::Integer(new_min_pin_length as i128), ); let sub_params = Value::Map(sub_params_map); - match self.send_config(ConfigSubCommand::SetMinPinLength, pin_token, Some(sub_params)) { + match self.send_config( + ConfigSubCommand::SetMinPinLength, + pin_token, + Some(sub_params), + ) { Ok(_) => { log::info!( "Successfully set minimum PIN length to {}",