diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-02-19 13:51:10 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-02-19 14:54:29 +0100 |
commit | dbae67d6fbb1f8a310b8de820fcda34c31eed39f (patch) | |
tree | 21ff0a6646ae12dc8e8578a1955516c4f39f1b6f /src | |
parent | 55d3369d9e7f68bb0c836c8143778b2918f01ba5 (diff) | |
download | ntw-dbae67d6fbb1f8a310b8de820fcda34c31eed39f.tar.gz ntw-dbae67d6fbb1f8a310b8de820fcda34c31eed39f.tar.bz2 |
Use ssmarshal to deserialize the request data
Previously, we directly accessed the request data by indexing the buffer
containing the data. This patch introduces the Request struct which can
be deserialized from raw bytes using ssmarshal.
Diffstat (limited to 'src')
-rw-r--r-- | src/device.rs | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/src/device.rs b/src/device.rs index 5fd0aed..0df14ae 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,7 +1,7 @@ // Copyright 2019 Robin Krahl <robin.krahl@ireas.org> // SPDX-License-Identifier: GPL-3.0-or-later -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_big_array::big_array; use usb_device::bus::{UsbBus, UsbBusAllocator}; use usb_device::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid}; @@ -14,6 +14,7 @@ const VID_CLAY_LOGIC: u16 = 0x20a0; const PID_NITROKEY_PRO: u16 = 0x4108; const REPORT_LEN: usize = 64; +const REQUEST_DATA_LEN: usize = REPORT_LEN - 5; const REPORT_DESCRIPTOR: &[u8] = &[ 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x95, 0x05, 0x75, 0x01, @@ -22,7 +23,7 @@ const REPORT_DESCRIPTOR: &[u8] = &[ 0x75, 0x08, 0x95, 0x40, 0xB1, 0x02, 0xC0, ]; -big_array! { BigArray; COMMAND_LEN, } +big_array! { BigArray; COMMAND_LEN, REQUEST_DATA_LEN, } enum_u8! { #[derive(Clone, Copy, Debug, PartialEq)] @@ -51,11 +52,19 @@ enum_u8! { } } +#[derive(Deserialize)] +struct Request { + pub command_id: u8, + #[serde(with = "BigArray")] + pub data: [u8; REQUEST_DATA_LEN], + pub crc: u32, +} + #[derive(Serialize)] struct Response { pub device_status: DeviceStatus, pub command_id: u8, - pub last_crc: [u8; 4], + pub last_crc: u32, pub command_status: CommandStatus, #[serde(with = "BigArray")] pub data: [u8; COMMAND_LEN], @@ -63,11 +72,11 @@ struct Response { } impl Response { - fn new(device_status: DeviceStatus, command_id: u8) -> Response { + fn new(device_status: DeviceStatus, command_id: u8, last_crc: u32) -> Response { Response { device_status, command_id, - last_crc: [0; 4], + last_crc, command_status: CommandStatus::NotSupported, data: [0; COMMAND_LEN], crc: 0, @@ -76,12 +85,14 @@ impl Response { } pub struct Nitrokey { + request: Option<Request>, buf: [u8; REPORT_LEN], } impl Nitrokey { pub fn new() -> Self { Nitrokey { + request: None, buf: [0; REPORT_LEN], } } @@ -105,19 +116,23 @@ impl HidDevice for Nitrokey { return Err(()); } - let mut response = Response::new(DeviceStatus::Ok, self.buf[0]); - response.last_crc = [self.buf[60], self.buf[61], self.buf[62], self.buf[63]]; - response.command_status = if let Ok(command_id) = CommandId::try_from(response.command_id) { - command_id.execute(&self.buf[1..60], &mut response.data) + if let Some(ref request) = self.request { + let mut response = Response::new(DeviceStatus::Ok, request.command_id, request.crc); + response.command_status = + if let Ok(command_id) = CommandId::try_from(request.command_id) { + command_id.execute(&request.data, &mut response.data) + } else { + CommandStatus::UnknownCommand + }; + // TODO: calculate actual CRC + response.crc = 1; // libnitrokey accepts any non-zero value + + let len = ssmarshal::serialize(&mut self.buf, &response).map_err(|_| ())?; + assert!(len == REPORT_LEN); + Ok(&self.buf) } else { - CommandStatus::UnknownCommand - }; - // TODO: calculate actual CRC - response.crc = 1; // libnitrokey accepts any non-zero value - - let len = ssmarshal::serialize(&mut self.buf, &response).map_err(|_| ())?; - assert!(len == REPORT_LEN); - Ok(&self.buf) + Err(()) + } } fn set_report( @@ -129,7 +144,9 @@ impl HidDevice for Nitrokey { if report_type != ReportType::Feature || report_id != 0 || data.len() != REPORT_LEN { Err(()) } else { - self.buf.copy_from_slice(data); + let (request, len) = ssmarshal::deserialize(data).map_err(|_| ())?; + assert!(len == REPORT_LEN); + self.request = Some(request); Ok(()) } } |