aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-02-18 21:08:32 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-02-18 23:27:29 +0100
commit49703cd770fd0522beae2dc53d1f882c9143c64e (patch)
tree774dde9adf872447646183d844fedb52194926a8
parentbaa0cd682aa219c4e16c6a7a8c3143931754ee01 (diff)
downloadntw-49703cd770fd0522beae2dc53d1f882c9143c64e.tar.gz
ntw-49703cd770fd0522beae2dc53d1f882c9143c64e.tar.bz2
Refactor Nitrokey::execute_command to write to a buffer
To avoid unnecessary allocations and to simplify the code, this patch refactors Nitrokey::execute_command to write the data to a slice instead of returning it as an array.
-rw-r--r--src/device.rs80
1 files changed, 42 insertions, 38 deletions
diff --git a/src/device.rs b/src/device.rs
index 9ffc39a..a6bf9bf 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -10,6 +10,7 @@ use crate::util::TryFrom;
const VID_CLAY_LOGIC: u16 = 0x20a0;
const PID_NITROKEY_PRO: u16 = 0x4108;
+const COMMAND_LEN: usize = 53;
const REPORT_LEN: usize = 64;
const REPORT_DESCRIPTOR: &[u8] = &[
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01,
@@ -65,41 +66,41 @@ impl Nitrokey {
}
}
- fn execute_command(
- &self,
- command_id: CommandId,
- data: &[u8],
- ) -> Result<[u8; 53], CommandStatus> {
- match command_id {
+ fn execute_command(&self, command_id: CommandId, data: &[u8], buf: &mut [u8]) -> CommandStatus {
+ let data: &[u8] = match command_id {
CommandId::GetStatus => {
- let mut data = [0u8; 53];
- data[0] = 1; // firmware_version_st.minor
- data[1] = 0; // firmware_version_st.major
- data[2] = 0; // card_serial[0]
- data[3] = 0; // card_serial[1]
- data[4] = 0; // card_serial[2]
- data[5] = 0; // card_serial[3]
- data[6] = 0; // numlock
- data[7] = 0; // capslock
- data[8] = 0; // enable_user_password
- data[9] = 0; // delete_user_password
- Ok(data)
+ &[
+ 1, // firmware_version_st.minor
+ 0, // firmware_version_st.major
+ 0, // card_serial[0]
+ 0, // card_serial[1]
+ 0, // card_serial[2]
+ 0, // card_serial[3]
+ 0, // numlock
+ 0, // capslock
+ 0, // enable_user_password
+ 0, // delete_user_password
+ ]
}
CommandId::ReadSlotName => {
assert!(data.len() > 1);
let slot_number = data[0];
if slot_number != 0x20 {
- Err(CommandStatus::SlotNotProgrammed)
- } else {
- let mut data = [0u8; 53];
- data[0] = 0x74; // t
- data[1] = 0x65; // e
- data[2] = 0x73; // s
- data[3] = 0x74; // t
- Ok(data)
+ return CommandStatus::SlotNotProgrammed;
}
+
+ &[
+ 0x74, // t
+ 0x65, // e
+ 0x73, // s
+ 0x74, // t
+ 0x00, // NULL
+ ]
}
- }
+ };
+ assert!(buf.len() >= data.len());
+ buf[..data.len()].copy_from_slice(data);
+ CommandStatus::Ok
}
}
@@ -121,18 +122,21 @@ impl HidDevice for Nitrokey {
return Err(());
}
+ const PREFIX_LEN: usize = 7;
+ const SUFFIX_LEN: usize = 4;
+ const PREFIX_END: usize = PREFIX_LEN;
+ const SUFFIX_START: usize = REPORT_LEN - SUFFIX_LEN;
+ let mut buf = [0; COMMAND_LEN];
+
let device_status = DeviceStatus::Ok;
let command_id = self.buf[0];
- let result = if let Ok(command_id) = CommandId::try_from(command_id) {
- self.execute_command(command_id, &self.buf[1..60])
+ let command_status = if let Ok(command_id) = CommandId::try_from(command_id) {
+ self.execute_command(command_id, &self.buf[1..60], &mut buf)
} else {
- Err(CommandStatus::UnknownCommand)
+ CommandStatus::UnknownCommand
};
- let (command_status, command_data) = result
- .map(|d| (CommandStatus::Ok, d))
- .unwrap_or_else(|status| (status, [0; 53]));
- let pre_data: [u8; 7] = [
+ let pre_data: [u8; PREFIX_LEN] = [
device_status.into(), // device status
command_id, // command_id
self.buf[60],
@@ -141,13 +145,13 @@ impl HidDevice for Nitrokey {
self.buf[63], // last_command_crc
command_status.into(), // last_command_status
];
- let post_data: [u8; 4] = [
+ let post_data: [u8; SUFFIX_LEN] = [
0x00, 0x00, 0x00, 0x01, // crc -- libnitrokey accepts any non-zero value
];
- self.buf[0..7].copy_from_slice(&pre_data);
- self.buf[7..7 + command_data.len()].copy_from_slice(&command_data);
- self.buf[60..64].copy_from_slice(&post_data);
+ self.buf[..PREFIX_END].copy_from_slice(&pre_data);
+ self.buf[PREFIX_END..SUFFIX_START].copy_from_slice(&buf);
+ self.buf[SUFFIX_START..].copy_from_slice(&post_data);
Ok(&self.buf)
}