diff options
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | src/lib.rs | 66 | ||||
| -rw-r--r-- | src/tests/pro.rs | 44 | 
3 files changed, 110 insertions, 2 deletions
| @@ -5,8 +5,6 @@    - `NK_factory_reset`    - `NK_build_aes_key`    - `NK_unlock_user_password` -  - `NK_erase_hotp_slot` -  - `NK_erase_totp_slot`    - `NK_change_admin_PIN`    - `NK_change_user_PIN`    - `NK_enable_password_safe` @@ -1310,6 +1310,72 @@ impl AdminAuthenticatedDevice {              )          });      } + +    /// Erase an HOTP slot. +    /// +    /// # Errors +    /// +    /// - [`InvalidSlot`][] if there is no slot with the given number +    /// +    /// # Example +    /// +    /// ```no_run +    /// use nitrokey::{CommandStatus, Device, OtpMode, OtpSlotData}; +    /// # use nitrokey::CommandError; +    /// +    /// # fn try_main() -> Result<(), (CommandError)> { +    /// let device = nitrokey::connect()?; +    /// match device.authenticate_admin("12345678") { +    ///     Ok(admin) => { +    ///         match admin.erase_hotp_slot(1) { +    ///             CommandStatus::Success => println!("Successfully erased slot."), +    ///             CommandStatus::Error(err) => println!("Could not erase slot: {:?}", err), +    ///         } +    ///     }, +    ///     Err((_, err)) => println!("Could not authenticate as admin: {:?}", err), +    /// } +    /// #     Ok(()) +    /// # } +    /// ``` +    /// +    /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot +    pub fn erase_hotp_slot(&self, slot: u8) -> CommandStatus { +        let temp_password_ptr = self.temp_password.as_ptr() as *const i8; +        unsafe { CommandStatus::from(nitrokey_sys::NK_erase_hotp_slot(slot, temp_password_ptr)) } +    } + +    /// Erase a TOTP slot. +    /// +    /// # Errors +    /// +    /// - [`InvalidSlot`][] if there is no slot with the given number +    /// +    /// # Example +    /// +    /// ```no_run +    /// use nitrokey::{CommandStatus, Device, OtpMode, OtpSlotData}; +    /// # use nitrokey::CommandError; +    /// +    /// # fn try_main() -> Result<(), (CommandError)> { +    /// let device = nitrokey::connect()?; +    /// match device.authenticate_admin("12345678") { +    ///     Ok(admin) => { +    ///         match admin.erase_totp_slot(1) { +    ///             CommandStatus::Success => println!("Successfully erased slot."), +    ///             CommandStatus::Error(err) => println!("Could not erase slot: {:?}", err), +    ///         } +    ///     }, +    ///     Err((_, err)) => println!("Could not authenticate as admin: {:?}", err), +    /// } +    /// #     Ok(()) +    /// # } +    /// ``` +    /// +    /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot +    pub fn erase_totp_slot(&self, slot: u8) -> CommandStatus { +        let temp_password_ptr = self.temp_password.as_ptr() as *const i8; +        unsafe { CommandStatus::from(nitrokey_sys::NK_erase_totp_slot(slot, temp_password_ptr)) } +    }  }  impl Device for AdminAuthenticatedDevice {} diff --git a/src/tests/pro.rs b/src/tests/pro.rs index a508801..a23d42a 100644 --- a/src/tests/pro.rs +++ b/src/tests/pro.rs @@ -136,6 +136,28 @@ fn hotp_error() {      assert_eq!(CommandError::InvalidSlot, code.unwrap_err());  } +#[test] +#[cfg_attr(not(feature = "test-pro"), ignore)] +fn hotp_erase() { +    let admin = get_admin_test_device(); +    let config = Config::new(None, None, None, false); +    assert_eq!(CommandStatus::Success, admin.write_config(config)); +    let slot_data = OtpSlotData::new(1, "test1", HOTP_SECRET, OtpMode::SixDigits); +    assert_eq!(CommandStatus::Success, admin.write_hotp_slot(slot_data, 0)); +    let slot_data = OtpSlotData::new(2, "test2", HOTP_SECRET, OtpMode::SixDigits); +    assert_eq!(CommandStatus::Success, admin.write_hotp_slot(slot_data, 0)); + +    assert_eq!(CommandStatus::Success, admin.erase_hotp_slot(1)); + +    let device = admin.device(); +    let result = device.get_hotp_slot_name(1); +    assert_eq!(CommandError::SlotNotProgrammed, result.unwrap_err()); +    let result = device.get_hotp_code(1); +    assert_eq!(CommandError::SlotNotProgrammed, result.unwrap_err()); + +    assert_eq!("test2", device.get_hotp_slot_name(2).unwrap()); +} +  fn configure_totp(admin: &AdminAuthenticatedDevice) {      let slot_data = OtpSlotData::new(1, "test-totp", TOTP_SECRET, OtpMode::EightDigits);      assert_eq!(CommandStatus::Success, admin.write_totp_slot(slot_data, 30)); @@ -218,6 +240,28 @@ fn totp_error() {  #[test]  #[cfg_attr(not(feature = "test-pro"), ignore)] +fn totp_erase() { +    let admin = get_admin_test_device(); +    let config = Config::new(None, None, None, false); +    assert_eq!(CommandStatus::Success, admin.write_config(config)); +    let slot_data = OtpSlotData::new(1, "test1", TOTP_SECRET, OtpMode::SixDigits); +    assert_eq!(CommandStatus::Success, admin.write_totp_slot(slot_data, 0)); +    let slot_data = OtpSlotData::new(2, "test2", TOTP_SECRET, OtpMode::SixDigits); +    assert_eq!(CommandStatus::Success, admin.write_totp_slot(slot_data, 0)); + +    assert_eq!(CommandStatus::Success, admin.erase_totp_slot(1)); + +    let device = admin.device(); +    let result = device.get_totp_slot_name(1); +    assert_eq!(CommandError::SlotNotProgrammed, result.unwrap_err()); +    let result = device.get_totp_code(1); +    assert_eq!(CommandError::SlotNotProgrammed, result.unwrap_err()); + +    assert_eq!("test2", device.get_totp_slot_name(2).unwrap()); +} + +#[test] +#[cfg_attr(not(feature = "test-pro"), ignore)]  fn get_firmware_version() {      let device = get_test_device();      assert_eq!(0, device.get_major_firmware_version()); | 
