aboutsummaryrefslogtreecommitdiff
path: root/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/device.rs')
-rw-r--r--src/device.rs16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/device.rs b/src/device.rs
index 0df14ae..fc119d5 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -7,6 +7,7 @@ use usb_device::bus::{UsbBus, UsbBusAllocator};
use usb_device::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid};
use crate::commands::{CommandId, COMMAND_LEN};
+use crate::crc::Crc;
use crate::hid::{HidDevice, Protocol, ReportType, Subclass};
use crate::util::TryFrom;
@@ -85,14 +86,18 @@ impl Response {
}
pub struct Nitrokey {
+ crc: Crc,
request: Option<Request>,
+ request_crc: u32,
buf: [u8; REPORT_LEN],
}
impl Nitrokey {
- pub fn new() -> Self {
+ pub fn new(crc: Crc) -> Self {
Nitrokey {
+ crc,
request: None,
+ request_crc: 0,
buf: [0; REPORT_LEN],
}
}
@@ -118,12 +123,15 @@ impl HidDevice for Nitrokey {
if let Some(ref request) = self.request {
let mut response = Response::new(DeviceStatus::Ok, request.command_id, request.crc);
- response.command_status =
+ response.command_status = if self.request_crc == request.crc {
if let Ok(command_id) = CommandId::try_from(request.command_id) {
command_id.execute(&request.data, &mut response.data)
} else {
CommandStatus::UnknownCommand
- };
+ }
+ } else {
+ CommandStatus::WrongCrc
+ };
// TODO: calculate actual CRC
response.crc = 1; // libnitrokey accepts any non-zero value
@@ -146,6 +154,8 @@ impl HidDevice for Nitrokey {
} else {
let (request, len) = ssmarshal::deserialize(data).map_err(|_| ())?;
assert!(len == REPORT_LEN);
+ // the last four bytes are ignored as they contain the CRC
+ self.request_crc = self.crc.get(&data[..REPORT_LEN - 4]);
self.request = Some(request);
Ok(())
}