From 49703cd770fd0522beae2dc53d1f882c9143c64e Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 18 Feb 2019 21:08:32 +0000 Subject: 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. --- src/device.rs | 80 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 38 deletions(-) (limited to 'src') 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) } -- cgit v1.2.1