diff options
| -rw-r--r-- | src/device.rs | 80 | 
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)      } | 
