From c43b63b70ee32f9fa8e980d89eff5383931f5c39 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 03:49:13 +0000 Subject: Add assert_cmd_err and assert_ok macros to tests These macros allow easier comparisions using the new error type. This patch fixes all tests and updates nitrokey-test to 0.2.0 so that it integrates with the new error structure. Some tests may still fail until CommunicationError::NotConnected is actually returned. --- tests/util/mod.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'tests/util') diff --git a/tests/util/mod.rs b/tests/util/mod.rs index cbf6b93..f0d0bb5 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -1,2 +1,69 @@ pub static ADMIN_PASSWORD: &str = "12345678"; pub static USER_PASSWORD: &str = "123456"; + +#[macro_export] +macro_rules! assert_ok { + ($left:expr, $right:expr) => {{ + match &$right { + Ok(right) => match &$left { + left => { + if !(*left == *right) { + panic!( + r#"assertion failed: `(left == right)` + left: `{:?}`, + right: `{:?}`"#, + left, right + ) + } + } + }, + Err(right_err) => panic!( + r#"assertion failed: `(left == right)` + left: `Ok({:?})`, + right: `Err({:?})`"#, + $left, right_err + ), + } + }}; +} + +#[macro_export] +macro_rules! assert_err { + ($err:path, $left:expr, $right:expr) => { + match &$right { + Err($err(ref right_err)) => match &$left { + left_err => { + if !(*left_err == *right_err) { + panic!( + r#"assertion failed: `(left == right)` + left: `{:?}`, + right: `{:?}`"#, + left_err, right_err + ) + } + } + }, + Err(ref right_err) => panic!( + r#"assertion failed: `(left == right)` + left: `{:?}`, + right: `{:?}`"#, + $err($left), + right_err + ), + Ok(right_ok) => panic!( + r#"assertion failed: `(left == right)` + left: `Err({:?})`, + right: `Ok({:?})`"#, + $err($left), + right_ok + ), + } + }; +} + +#[macro_export] +macro_rules! assert_cmd_err { + ($left:expr, $right:expr) => { + assert_err!(::nitrokey::Error::CommandError, $left, $right); + }; +} -- cgit v1.2.3 From 5e258d26b55af6bed7c316b1c7ac12e20946702d Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 12:47:52 +0000 Subject: Refactor library errors into LibraryError enum Previously, library errors were part of the CommandError enum. As command errors and library errors are two different error types, they should be split into two enums. --- CHANGELOG.md | 2 ++ src/auth.rs | 6 ++--- src/config.rs | 4 +-- src/device.rs | 22 ++++++++--------- src/error.rs | 74 +++++++++++++++++++++++++++++++++++++++---------------- src/lib.rs | 2 +- src/otp.rs | 20 +++++++-------- src/pws.rs | 14 +++++------ src/util.rs | 4 +-- tests/device.rs | 4 +-- tests/otp.rs | 28 ++++++++++----------- tests/pws.rs | 16 ++++++------ tests/util/mod.rs | 7 ++++++ 13 files changed, 123 insertions(+), 80 deletions(-) (limited to 'tests/util') diff --git a/CHANGELOG.md b/CHANGELOG.md index def5273..c34175e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Refactor the error handling code: - Implement `std::error::Error` for `CommandError`. - Add the `Error` enum and the `Result` typedef. + - Add the `LibraryError` enum and move the library error variants from + `CommandError` to `LibraryError`. - Return `Error` instead of `CommandError` in all public functions. - Move the `CommandError::RngError` variant to `Error::RandError` and the `CommandError::Unknown` variant to `Error::Unknown`. diff --git a/src/auth.rs b/src/auth.rs index e05f6b3..d1eb049 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -55,7 +55,7 @@ pub trait Authenticate { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn authenticate_user(self, password: &str) -> Result, (Self, Error)> @@ -101,7 +101,7 @@ pub trait Authenticate { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> @@ -287,7 +287,7 @@ impl Admin { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot pub fn write_config(&self, config: Config) -> Result<(), Error> { let raw_config = RawConfig::try_from(config)?; unsafe { diff --git a/src/config.rs b/src/config.rs index 741d67e..6aa6d10 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use crate::error::{CommandError, Error}; +use crate::error::{Error, LibraryError}; /// The configuration for a Nitrokey. #[derive(Clone, Copy, Debug, PartialEq)] @@ -41,7 +41,7 @@ fn option_to_config_otp_slot(value: Option) -> Result { if value < 3 { Ok(value) } else { - Err(CommandError::InvalidSlot.into()) + Err(LibraryError::InvalidSlot.into()) } } None => Ok(255), diff --git a/src/device.rs b/src/device.rs index ccd0597..5c4014b 100644 --- a/src/device.rs +++ b/src/device.rs @@ -461,7 +461,7 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn change_admin_pin(&self, current: &str, new: &str) -> Result<(), Error> { let current_string = get_cstring(current)?; @@ -497,7 +497,7 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn change_user_pin(&self, current: &str, new: &str) -> Result<(), Error> { let current_string = get_cstring(current)?; @@ -533,7 +533,7 @@ pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn unlock_user_pin(&self, admin_pin: &str, user_pin: &str) -> Result<(), Error> { let admin_pin_string = get_cstring(admin_pin)?; @@ -867,7 +867,7 @@ impl Storage { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn change_update_pin(&self, current: &str, new: &str) -> Result<(), Error> { let current_string = get_cstring(current)?; @@ -907,7 +907,7 @@ impl Storage { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn enable_firmware_update(&self, update_pin: &str) -> Result<(), Error> { let update_pin_string = get_cstring(update_pin)?; @@ -943,7 +943,7 @@ impl Storage { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn enable_encrypted_volume(&self, user_pin: &str) -> Result<(), Error> { let user_pin = get_cstring(user_pin)?; @@ -1021,7 +1021,7 @@ impl Storage { /// /// [`enable_encrypted_volume`]: #method.enable_encrypted_volume /// [`AesDecryptionFailed`]: enum.CommandError.html#variant.AesDecryptionFailed - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString pub fn enable_hidden_volume(&self, volume_password: &str) -> Result<(), Error> { let volume_password = get_cstring(volume_password)?; unsafe { @@ -1099,7 +1099,7 @@ impl Storage { /// ``` /// /// [`AesDecryptionFailed`]: enum.CommandError.html#variant.AesDecryptionFailed - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString pub fn create_hidden_volume( &self, slot: u8, @@ -1145,7 +1145,7 @@ impl Storage { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn set_unencrypted_volume_mode( &self, @@ -1276,7 +1276,7 @@ impl Storage { /// # } /// ``` /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn clear_new_sd_card_warning(&self, admin_pin: &str) -> Result<(), Error> { let admin_pin = get_cstring(admin_pin)?; @@ -1304,7 +1304,7 @@ impl Storage { /// - [`InvalidString`][] if one of the provided passwords contains a null byte /// - [`WrongPassword`][] if the admin password is wrong /// - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword pub fn export_firmware(&self, admin_pin: &str) -> Result<(), Error> { let admin_pin_string = get_cstring(admin_pin)?; diff --git a/src/error.rs b/src/error.rs index c5a975e..f40d07f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,6 +11,8 @@ pub enum Error { CommandError(CommandError), /// Placeholder for testing. CommunicationError(CommunicationError), + /// A library usage error. + LibraryError(LibraryError), /// An error that occured during random number generation. RandError(rand_core::Error), /// An unknown error returned by libnitrokey. @@ -21,6 +23,8 @@ impl From for Error { fn from(code: raw::c_int) -> Self { if let Some(err) = CommandError::try_from(code) { Error::CommandError(err) + } else if let Some(err) = LibraryError::try_from(code) { + Error::LibraryError(err) } else { Error::Unknown(code.into()) } @@ -33,6 +37,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: LibraryError) -> Self { + Error::LibraryError(err) + } +} + impl From for Error { fn from(error: rand_core::Error) -> Self { Error::RandError(error) @@ -44,6 +54,7 @@ impl error::Error for Error { match *self { Error::CommandError(ref err) => Some(err), Error::CommunicationError(_) => None, + Error::LibraryError(ref err) => Some(err), Error::RandError(ref err) => Some(err), Error::Unknown(_) => None, } @@ -55,6 +66,7 @@ impl fmt::Display for Error { match *self { Error::CommandError(ref err) => write!(f, "Command error: {}", err), Error::CommunicationError(_) => write!(f, "Placeholder"), + Error::LibraryError(ref err) => write!(f, "Library error: {}", err), Error::RandError(ref err) => write!(f, "RNG error: {}", err), Error::Unknown(ref err) => write!(f, "Unknown error: {}", err), } @@ -90,16 +102,6 @@ pub enum CommandError { AesDecryptionFailed, /// An unspecified error occurred. Undefined, - /// You passed a string containing a null byte. - InvalidString, - /// A supplied string exceeded a length limit. - StringTooLong, - /// You passed an invalid slot. - InvalidSlot, - /// The supplied string was not in hexadecimal format. - InvalidHexString, - /// The target buffer was smaller than the source. - TargetBufferTooSmall, } /// Placeholder for testing. @@ -122,10 +124,6 @@ impl CommandError { 8 => Some(CommandError::NotSupported), 9 => Some(CommandError::UnknownCommand), 10 => Some(CommandError::AesDecryptionFailed), - 200 => Some(CommandError::StringTooLong), - 201 => Some(CommandError::InvalidSlot), - 202 => Some(CommandError::InvalidHexString), - 203 => Some(CommandError::TargetBufferTooSmall), _ => None, } } @@ -149,13 +147,6 @@ impl CommandError { CommandError::UnknownCommand => "This command is unknown".into(), CommandError::AesDecryptionFailed => "AES decryption failed".into(), CommandError::Undefined => "An unspecified error occurred".into(), - CommandError::InvalidString => "You passed a string containing a null byte".into(), - CommandError::StringTooLong => "The supplied string is too long".into(), - CommandError::InvalidSlot => "The given slot is invalid".into(), - CommandError::InvalidHexString => { - "The supplied string is not in hexadecimal format".into() - } - CommandError::TargetBufferTooSmall => "The target buffer is too small".into(), } } } @@ -167,3 +158,44 @@ impl fmt::Display for CommandError { write!(f, "{}", self.as_str()) } } + +/// A library usage error. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum LibraryError { + /// A supplied string exceeded a length limit. + StringTooLong, + /// You passed an invalid slot. + InvalidSlot, + /// The supplied string was not in hexadecimal format. + InvalidHexString, + /// The target buffer was smaller than the source. + TargetBufferTooSmall, + /// You passed a string containing a null byte. + InvalidString, +} + +impl LibraryError { + fn try_from(value: raw::c_int) -> Option { + match value { + 200 => Some(LibraryError::StringTooLong), + 201 => Some(LibraryError::InvalidSlot), + 202 => Some(LibraryError::InvalidHexString), + 203 => Some(LibraryError::TargetBufferTooSmall), + _ => None, + } + } +} + +impl error::Error for LibraryError {} + +impl fmt::Display for LibraryError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + LibraryError::StringTooLong => "The supplied string is too long", + LibraryError::InvalidSlot => "The given slot is invalid", + LibraryError::InvalidHexString => "The supplied string is not in hexadecimal format", + LibraryError::TargetBufferTooSmall => "The target buffer is too small", + LibraryError::InvalidString => "You passed a string containing a null byte", + }) + } +} diff --git a/src/lib.rs b/src/lib.rs index 8522e83..993ec92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,7 +104,7 @@ pub use crate::device::{ connect, connect_model, Device, DeviceWrapper, Model, Pro, SdCardData, Storage, StorageProductionInfo, StorageStatus, VolumeMode, VolumeStatus, }; -pub use crate::error::{CommandError, CommunicationError, Error, Result}; +pub use crate::error::{CommandError, CommunicationError, Error, LibraryError, Result}; pub use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; pub use crate::pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; pub use crate::util::LogLevel; diff --git a/src/otp.rs b/src/otp.rs index 5dfe8b1..7535a77 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -47,8 +47,8 @@ pub trait ConfigureOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`NoName`]: enum.CommandError.html#variant.NoName fn write_hotp_slot(&self, data: OtpSlotData, counter: u64) -> Result<(), Error>; @@ -83,8 +83,8 @@ pub trait ConfigureOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`NoName`]: enum.CommandError.html#variant.NoName fn write_totp_slot(&self, data: OtpSlotData, time_window: u16) -> Result<(), Error>; @@ -115,7 +115,7 @@ pub trait ConfigureOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot fn erase_hotp_slot(&self, slot: u8) -> Result<(), Error>; /// Erases a TOTP slot. @@ -145,7 +145,7 @@ pub trait ConfigureOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot fn erase_totp_slot(&self, slot: u8) -> Result<(), Error>; } @@ -216,7 +216,7 @@ pub trait GenerateOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed fn get_hotp_slot_name(&self, slot: u8) -> Result { unsafe { result_from_string(nitrokey_sys::NK_get_hotp_slot_name(slot)) } @@ -245,7 +245,7 @@ pub trait GenerateOtp { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed fn get_totp_slot_name(&self, slot: u8) -> Result { unsafe { result_from_string(nitrokey_sys::NK_get_totp_slot_name(slot)) } @@ -275,7 +275,7 @@ pub trait GenerateOtp { /// ``` /// /// [`get_config`]: trait.Device.html#method.get_config - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`NotAuthorized`]: enum.CommandError.html#variant.NotAuthorized /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed fn get_hotp_code(&self, slot: u8) -> Result { @@ -320,7 +320,7 @@ pub trait GenerateOtp { /// /// [`set_time`]: #method.set_time /// [`get_config`]: trait.Device.html#method.get_config - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`NotAuthorized`]: enum.CommandError.html#variant.NotAuthorized /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed fn get_totp_code(&self, slot: u8) -> Result { diff --git a/src/pws.rs b/src/pws.rs index e974737..47965d7 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -109,7 +109,7 @@ pub trait GetPasswordSafe { /// [`lock`]: trait.Device.html#method.lock /// [`AesDecryptionFailed`]: enum.CommandError.html#variant.AesDecryptionFailed /// [`Device::build_aes_key`]: trait.Device.html#method.build_aes_key - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`Unknown`]: enum.CommandError.html#variant.Unknown /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword fn get_password_safe(&self, user_pin: &str) -> Result, Error>; @@ -207,7 +207,7 @@ impl<'a> PasswordSafe<'a> { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed pub fn get_slot_name(&self, slot: u8) -> Result { unsafe { result_from_string(nitrokey_sys::NK_get_password_safe_slot_name(slot)) } @@ -240,7 +240,7 @@ impl<'a> PasswordSafe<'a> { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed pub fn get_slot_login(&self, slot: u8) -> Result { unsafe { result_from_string(nitrokey_sys::NK_get_password_safe_slot_login(slot)) } @@ -273,7 +273,7 @@ impl<'a> PasswordSafe<'a> { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot /// [`SlotNotProgrammed`]: enum.CommandError.html#variant.SlotNotProgrammed pub fn get_slot_password(&self, slot: u8) -> Result { unsafe { result_from_string(nitrokey_sys::NK_get_password_safe_slot_password(slot)) } @@ -304,8 +304,8 @@ impl<'a> PasswordSafe<'a> { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot - /// [`InvalidString`]: enum.CommandError.html#variant.InvalidString + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot + /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString pub fn write_slot( &self, slot: u8, @@ -350,7 +350,7 @@ impl<'a> PasswordSafe<'a> { /// # } /// ``` /// - /// [`InvalidSlot`]: enum.CommandError.html#variant.InvalidSlot + /// [`InvalidSlot`]: enum.LibraryError.html#variant.InvalidSlot pub fn erase_slot(&self, slot: u8) -> Result<(), Error> { unsafe { get_command_result(nitrokey_sys::NK_erase_password_safe_slot(slot)) } } diff --git a/src/util.rs b/src/util.rs index 3b9904f..2738fce 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,7 @@ use libc::{c_void, free}; use rand_core::RngCore; use rand_os::OsRng; -use crate::error::{CommandError, Error}; +use crate::error::{CommandError, Error, LibraryError}; /// Log level for libnitrokey. /// @@ -78,7 +78,7 @@ pub fn generate_password(length: usize) -> Result, Error> { } pub fn get_cstring>>(s: T) -> Result { - CString::new(s).or(Err(CommandError::InvalidString.into())) + CString::new(s).or(Err(LibraryError::InvalidString.into())) } impl Into for LogLevel { diff --git a/tests/device.rs b/tests/device.rs index 174624f..ee5dae1 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -6,7 +6,7 @@ use std::{thread, time}; use nitrokey::{ Authenticate, CommandError, Config, ConfigureOtp, Device, Error, GenerateOtp, GetPasswordSafe, - OtpMode, OtpSlotData, Storage, VolumeMode, + LibraryError, OtpMode, OtpSlotData, Storage, VolumeMode, }; use nitrokey_test::test as test_device; @@ -130,7 +130,7 @@ fn config(device: DeviceWrapper) { assert_eq!(config, get_config); let config = Config::new(None, Some(9), None, true); - assert_cmd_err!(CommandError::InvalidSlot, admin.write_config(config)); + assert_lib_err!(LibraryError::InvalidSlot, admin.write_config(config)); let config = Config::new(Some(1), None, Some(0), false); assert_ok!((), admin.write_config(config)); diff --git a/tests/otp.rs b/tests/otp.rs index d328351..51a6539 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -4,8 +4,8 @@ use std::fmt::Debug; use std::ops::Deref; use nitrokey::{ - Admin, Authenticate, CommandError, Config, ConfigureOtp, Device, GenerateOtp, OtpMode, - OtpSlotData, + Admin, Authenticate, CommandError, Config, ConfigureOtp, Device, GenerateOtp, LibraryError, + OtpMode, OtpSlotData, }; use nitrokey_test::test as test_device; @@ -106,7 +106,7 @@ fn hotp_slot_name(device: DeviceWrapper) { let result = device.get_hotp_slot_name(1); assert_eq!("test-hotp", result.unwrap()); let result = device.get_hotp_slot_name(4); - assert_cmd_err!(CommandError::InvalidSlot, result); + assert_lib_err!(LibraryError::InvalidSlot, result); } #[test_device] @@ -115,17 +115,17 @@ fn hotp_error(device: DeviceWrapper) { let slot_data = OtpSlotData::new(1, "", HOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_hotp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(4, "test", HOTP_SECRET, OtpMode::SixDigits); - assert_cmd_err!( - CommandError::InvalidSlot, + assert_lib_err!( + LibraryError::InvalidSlot, admin.write_hotp_slot(slot_data, 0) ); let slot_data = OtpSlotData::new(1, "test", "foobar", OtpMode::SixDigits); - assert_cmd_err!( - CommandError::InvalidHexString, + assert_lib_err!( + LibraryError::InvalidHexString, admin.write_hotp_slot(slot_data, 0) ); let code = admin.get_hotp_code(4); - assert_cmd_err!(CommandError::InvalidSlot, code); + assert_lib_err!(LibraryError::InvalidSlot, code); } #[test_device] @@ -249,7 +249,7 @@ fn totp_slot_name(device: DeviceWrapper) { assert!(result.is_ok()); assert_eq!("test-totp", result.unwrap()); let result = device.get_totp_slot_name(16); - assert_cmd_err!(CommandError::InvalidSlot, result); + assert_lib_err!(LibraryError::InvalidSlot, result); } #[test_device] @@ -258,17 +258,17 @@ fn totp_error(device: DeviceWrapper) { let slot_data = OtpSlotData::new(1, "", TOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_totp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(20, "test", TOTP_SECRET, OtpMode::SixDigits); - assert_cmd_err!( - CommandError::InvalidSlot, + assert_lib_err!( + LibraryError::InvalidSlot, admin.write_totp_slot(slot_data, 0) ); let slot_data = OtpSlotData::new(4, "test", "foobar", OtpMode::SixDigits); - assert_cmd_err!( - CommandError::InvalidHexString, + assert_lib_err!( + LibraryError::InvalidHexString, admin.write_totp_slot(slot_data, 0) ); let code = admin.get_totp_code(20); - assert_cmd_err!(CommandError::InvalidSlot, code); + assert_lib_err!(LibraryError::InvalidSlot, code); } #[test_device] diff --git a/tests/pws.rs b/tests/pws.rs index a4647bd..51e6189 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -3,7 +3,9 @@ mod util; use std::ffi::CStr; use libc::{c_int, c_void, free}; -use nitrokey::{CommandError, Device, Error, GetPasswordSafe, PasswordSafe, SLOT_COUNT}; +use nitrokey::{ + CommandError, Device, Error, GetPasswordSafe, LibraryError, PasswordSafe, SLOT_COUNT, +}; use nitrokey_sys; use nitrokey_test::test as test_device; @@ -104,17 +106,17 @@ fn get_data(device: DeviceWrapper) { assert_eq!(login, pws.get_slot_login(1).unwrap()); assert_eq!(password, pws.get_slot_password(1).unwrap()); - assert_cmd_err!(CommandError::InvalidSlot, pws.get_slot_name(SLOT_COUNT)); - assert_cmd_err!(CommandError::InvalidSlot, pws.get_slot_login(SLOT_COUNT)); - assert_cmd_err!(CommandError::InvalidSlot, pws.get_slot_password(SLOT_COUNT)); + assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_name(SLOT_COUNT)); + assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_login(SLOT_COUNT)); + assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_password(SLOT_COUNT)); } #[test_device] fn write(device: DeviceWrapper) { let pws = get_pws(&device); - assert_cmd_err!( - CommandError::InvalidSlot, + assert_lib_err!( + LibraryError::InvalidSlot, pws.write_slot(SLOT_COUNT, "name", "login", "password") ); @@ -137,7 +139,7 @@ fn write(device: DeviceWrapper) { #[test_device] fn erase(device: DeviceWrapper) { let pws = get_pws(&device); - assert_cmd_err!(CommandError::InvalidSlot, pws.erase_slot(SLOT_COUNT)); + assert_lib_err!(LibraryError::InvalidSlot, pws.erase_slot(SLOT_COUNT)); assert_ok!((), pws.write_slot(0, "name", "login", "password")); assert_ok!((), pws.erase_slot(0)); diff --git a/tests/util/mod.rs b/tests/util/mod.rs index f0d0bb5..b1d3ea3 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -67,3 +67,10 @@ macro_rules! assert_cmd_err { assert_err!(::nitrokey::Error::CommandError, $left, $right); }; } + +#[macro_export] +macro_rules! assert_lib_err { + ($left:expr, $right:expr) => { + assert_err!(::nitrokey::Error::LibraryError, $left, $right); + }; +} -- cgit v1.2.3 From d87859975dc158919ecd5bf11a1111a2da5fcb30 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 17 Jan 2019 14:21:44 +0000 Subject: Check specific error codes in the tests If possible, check specific error codes instead of `is_err()`. This makes the code more readable and catches bugs resulting in the wrong error code. Also, using the assert_*_err and assert_ok macros yields error messages containing the expected and the actual value. To be able to use these macros with the `get_password_safe` method, we also have to implement `Debug` for `PasswordSafe` and `Device`. --- TODO.md | 1 - src/device.rs | 2 +- src/pws.rs | 1 + tests/device.rs | 46 +++++++++++++++------------------------------- tests/otp.rs | 20 ++++++-------------- tests/pws.rs | 6 ++---- tests/util/mod.rs | 7 +++++++ 7 files changed, 32 insertions(+), 51 deletions(-) (limited to 'tests/util') diff --git a/TODO.md b/TODO.md index 53de7e9..487f56d 100644 --- a/TODO.md +++ b/TODO.md @@ -9,7 +9,6 @@ - Clear passwords from memory. - Find a nicer syntax for the `write_config` test. - Prevent construction of internal types. -- More specific error checking in the tests. - Check integer conversions. - Consider implementing `Into` for `(Device, CommandError)` - Lock password safe in `PasswordSafe::drop()` (see [nitrokey-storage-firmware diff --git a/src/device.rs b/src/device.rs index 1cf9da9..16064c3 100644 --- a/src/device.rs +++ b/src/device.rs @@ -286,7 +286,7 @@ pub struct StorageStatus { /// /// This trait provides the commands that can be executed without authentication and that are /// present on all supported Nitrokey devices. -pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp { +pub trait Device: Authenticate + GetPasswordSafe + GenerateOtp + fmt::Debug { /// Returns the model of the connected Nitrokey device. /// /// # Example diff --git a/src/pws.rs b/src/pws.rs index 47965d7..a21527c 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -52,6 +52,7 @@ pub const SLOT_COUNT: u8 = 16; /// [`get_password_safe`]: trait.GetPasswordSafe.html#method.get_password_safe /// [`lock`]: trait.Device.html#method.lock /// [`GetPasswordSafe`]: trait.GetPasswordSafe.html +#[derive(Debug)] pub struct PasswordSafe<'a> { _device: &'a dyn Device, } diff --git a/tests/device.rs b/tests/device.rs index ee5dae1..c502945 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -5,8 +5,8 @@ use std::process::Command; use std::{thread, time}; use nitrokey::{ - Authenticate, CommandError, Config, ConfigureOtp, Device, Error, GenerateOtp, GetPasswordSafe, - LibraryError, OtpMode, OtpSlotData, Storage, VolumeMode, + Authenticate, CommandError, CommunicationError, Config, ConfigureOtp, Device, Error, + GenerateOtp, GetPasswordSafe, LibraryError, OtpMode, OtpSlotData, Storage, VolumeMode, }; use nitrokey_test::test as test_device; @@ -31,11 +31,11 @@ fn count_nitrokey_block_devices() -> usize { #[test_device] fn connect_no_device() { - assert!(nitrokey::connect().is_err()); - assert!(nitrokey::connect_model(nitrokey::Model::Pro).is_err()); - assert!(nitrokey::connect_model(nitrokey::Model::Storage).is_err()); - assert!(nitrokey::Pro::connect().is_err()); - assert!(nitrokey::Storage::connect().is_err()); + assert_cmu_err!(CommunicationError::NotConnected, nitrokey::connect()); + assert_cmu_err!(CommunicationError::NotConnected, nitrokey::connect_model(nitrokey::Model::Pro)); + assert_cmu_err!(CommunicationError::NotConnected, nitrokey::connect_model(nitrokey::Model::Storage)); + assert_cmu_err!(CommunicationError::NotConnected, nitrokey::Pro::connect()); + assert_cmu_err!(CommunicationError::NotConnected, nitrokey::Storage::connect()); } #[test_device] @@ -148,9 +148,7 @@ fn change_user_pin(device: DeviceWrapper) { let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; - assert!(device - .change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD) - .is_ok()); + assert_ok!((), device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD)); let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0; let device = device @@ -161,9 +159,7 @@ fn change_user_pin(device: DeviceWrapper) { let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); assert_cmd_err!(CommandError::WrongPassword, result); - assert!(device - .change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD) - .is_ok()); + assert_ok!((), device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD)); let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); assert!(device.authenticate_user(USER_NEW_PASSWORD).is_err()); @@ -174,9 +170,7 @@ fn change_admin_pin(device: DeviceWrapper) { let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; - assert!(device - .change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) - .is_ok()); + assert_ok!((), device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD)); let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0; let device = device @@ -189,9 +183,7 @@ fn change_admin_pin(device: DeviceWrapper) { device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD) ); - assert!(device - .change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD) - .is_ok()); + assert_ok!((), device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD)); let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); @@ -215,9 +207,7 @@ where #[test_device] fn unlock_user_pin(device: DeviceWrapper) { let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); - assert!(device - .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) - .is_ok()); + assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) @@ -235,9 +225,7 @@ fn unlock_user_pin(device: DeviceWrapper) { CommandError::WrongPassword, device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) ); - assert!(device - .unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD) - .is_ok()); + assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); // block user PIN @@ -251,14 +239,10 @@ fn unlock_user_pin(device: DeviceWrapper) { CommandError::WrongPassword, device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) ); - assert!(device - .unlock_user_pin(ADMIN_PASSWORD, USER_NEW_PASSWORD) - .is_ok()); + assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_NEW_PASSWORD)); // reset user PIN - assert!(device - .change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD) - .is_ok()); + assert_ok!((), device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD)); } #[test_device] diff --git a/tests/otp.rs b/tests/otp.rs index 51a6539..96da371 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -93,7 +93,7 @@ fn hotp_pin(device: DeviceWrapper) { let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); check_hotp_codes(&user, 0); - assert!(user.device().get_hotp_code(1).is_err()); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_hotp_code(1)); } #[test_device] @@ -156,7 +156,7 @@ fn configure_totp(admin: &ConfigureOtp, factor: u64) { } fn check_totp_codes(device: &GenerateOtp, factor: u64, timestamp_size: TotpTimestampSize) { - for (i, &(base_time, code)) in TOTP_CODES.iter().enumerate() { + for (base_time, code) in TOTP_CODES { let time = base_time.checked_mul(factor).unwrap(); let is_u64 = time > u32::max_value() as u64; if is_u64 != (timestamp_size == TotpTimestampSize::U64) { @@ -164,14 +164,7 @@ fn check_totp_codes(device: &GenerateOtp, factor: u64, timestamp_size: TotpTimes } assert_ok!((), device.set_time(time, true)); - let result = device.get_totp_code(1); - assert!(result.is_ok()); - let result_code = result.unwrap(); - assert_eq!( - code, result_code, - "TOTP code {} should be {} but is {}", - i, code, result_code - ); + assert_ok!(code.to_string(), device.get_totp_code(1)); } } @@ -221,7 +214,7 @@ fn totp_pin(device: DeviceWrapper) { let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); check_totp_codes(&user, 1, TotpTimestampSize::U32); - assert!(user.device().get_totp_code(1).is_err()); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); } #[test_device] @@ -235,7 +228,7 @@ fn totp_pin_64(device: Pro) { let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); check_totp_codes(&user, 1, TotpTimestampSize::U64); - assert!(user.device().get_totp_code(1).is_err()); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); } #[test_device] @@ -246,8 +239,7 @@ fn totp_slot_name(device: DeviceWrapper) { let device = admin.device(); let result = device.get_totp_slot_name(1); - assert!(result.is_ok()); - assert_eq!("test-totp", result.unwrap()); + assert_ok!("test-totp", result); let result = device.get_totp_slot_name(16); assert_lib_err!(LibraryError::InvalidSlot, result); } diff --git a/tests/pws.rs b/tests/pws.rs index b89d7f6..7a97983 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -39,11 +39,9 @@ where #[test_device] fn enable(device: DeviceWrapper) { - assert!(device - .get_password_safe(&(USER_PASSWORD.to_owned() + "123")) - .is_err()); + assert_cmd_err!(CommandError::WrongPassword, device.get_password_safe(&(USER_PASSWORD.to_owned() + "123"))); assert!(device.get_password_safe(USER_PASSWORD).is_ok()); - assert!(device.get_password_safe(ADMIN_PASSWORD).is_err()); + assert_cmd_err!(CommandError::WrongPassword, device.get_password_safe(ADMIN_PASSWORD)); assert!(device.get_password_safe(USER_PASSWORD).is_ok()); } diff --git a/tests/util/mod.rs b/tests/util/mod.rs index b1d3ea3..4a00a66 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -68,6 +68,13 @@ macro_rules! assert_cmd_err { }; } +#[macro_export] +macro_rules! assert_cmu_err { + ($left:expr, $right:expr) => { + assert_err!(::nitrokey::Error::CommunicationError, $left, $right); + }; +} + #[macro_export] macro_rules! assert_lib_err { ($left:expr, $right:expr) => { -- cgit v1.2.3 From fdb7bac3063e62776bfc13f184cf786da19f42d1 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Wed, 23 Jan 2019 16:33:26 +0100 Subject: Add license and copyright information This patch adds license and copyright information to all files to make nitrokey-rs compliant with the REUSE practices [0]. [0] https://reuse.software/practices/2.0/ --- .builds/archlinux-use-system-lib.yaml | 2 ++ .builds/archlinux.yml | 2 ++ CHANGELOG.md | 5 +++++ Cargo.toml | 3 +++ LICENSE | 3 +++ README.md | 8 ++++++++ TODO.md | 5 +++++ src/auth.rs | 3 +++ src/config.rs | 3 +++ src/device.rs | 3 +++ src/error.rs | 3 +++ src/lib.rs | 3 +++ src/otp.rs | 3 +++ src/pws.rs | 3 +++ src/util.rs | 3 +++ tests/device.rs | 3 +++ tests/lib.rs | 3 +++ tests/otp.rs | 3 +++ tests/pws.rs | 3 +++ tests/util/mod.rs | 3 +++ 20 files changed, 67 insertions(+) (limited to 'tests/util') diff --git a/.builds/archlinux-use-system-lib.yaml b/.builds/archlinux-use-system-lib.yaml index 6fba33a..13f7581 100644 --- a/.builds/archlinux-use-system-lib.yaml +++ b/.builds/archlinux-use-system-lib.yaml @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Robin Krahl +# SPDX-License-Identifier: MIT image: archlinux packages: - rust diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml index 9d45386..7dab954 100644 --- a/.builds/archlinux.yml +++ b/.builds/archlinux.yml @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Robin Krahl +# SPDX-License-Identifier: MIT image: archlinux packages: - rust diff --git a/CHANGELOG.md b/CHANGELOG.md index c28c228..49ff8fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ + + # Unreleased - Remove the `test-pro` and `test-storage` features. - Implement `Display` for `Version`. diff --git a/Cargo.toml b/Cargo.toml index ceaa57d..696adfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +# Copyright (C) 2019 Robin Krahl +# SPDX-License-Identifier: MIT + [package] name = "nitrokey" version = "0.3.4" diff --git a/LICENSE b/LICENSE index 1a3601d..6c67cd5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,6 @@ +Valid-License-Identifier: MIT +License-Text: + The MIT License (MIT) Copyright (c) 2018 Robin Krahl diff --git a/README.md b/README.md index 0819c9d..8e1d98e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ + + # nitrokey-rs A libnitrokey wrapper for Rust providing access to Nitrokey devices. @@ -73,6 +78,8 @@ mail to [nitrokey-rs-dev@ireas.org][]. This project is licensed under the [MIT License][]. `libnitrokey` is licensed under the [LGPL-3.0][]. +`nitrokey-rs` complies with [version 2.0 of the REUSE practices][reuse]. + [Documentation]: https://docs.rs/nitrokey [Nitrokey udev rules]: https://www.nitrokey.com/documentation/frequently-asked-questions-faq#openpgp-card-not-available [`libnitrokey`]: https://github.com/nitrokey/libnitrokey @@ -81,3 +88,4 @@ under the [LGPL-3.0][]. [pull request #114]: https://github.com/Nitrokey/libnitrokey/pull/114 [MIT license]: https://opensource.org/licenses/MIT [LGPL-3.0]: https://opensource.org/licenses/lgpl-3.0.html +[reuse]: https://reuse.software/practices/2.0/ diff --git a/TODO.md b/TODO.md index d3f0018..db45bb5 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,8 @@ + + - Add support for the currently unsupported commands: - `NK_send_startup` - `NK_fill_SD_card_with_random_data` diff --git a/src/auth.rs b/src/auth.rs index b97bee6..18b6572 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use std::ops::Deref; use std::os::raw::c_char; use std::os::raw::c_int; diff --git a/src/config.rs b/src/config.rs index 329f7a6..c273792 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use crate::error::{Error, LibraryError}; /// The configuration for a Nitrokey. diff --git a/src/device.rs b/src/device.rs index ad75a44..c4af8a8 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use std::fmt; use std::marker; diff --git a/src/error.rs b/src/error.rs index 551dd0f..9cdb932 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2019 Robin Krahl +// SPDX-License-Identifier: MIT + use std::error; use std::fmt; use std::os::raw; diff --git a/src/lib.rs b/src/lib.rs index a1edb6b..9d15d03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + //! Provides access to a Nitrokey device using the native libnitrokey API. //! //! # Usage diff --git a/src/otp.rs b/src/otp.rs index 430b127..6e0379b 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use std::ffi::CString; use nitrokey_sys; diff --git a/src/pws.rs b/src/pws.rs index c89b73f..fcf057b 100644 --- a/src/pws.rs +++ b/src/pws.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use libc; use nitrokey_sys; diff --git a/src/util.rs b/src/util.rs index 64dde39..5f25655 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_int}; diff --git a/tests/device.rs b/tests/device.rs index 59c9348..c790049 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + mod util; use std::ffi::CStr; diff --git a/tests/lib.rs b/tests/lib.rs index d298048..697024d 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2019 Robin Krahl +// SPDX-License-Identifier: MIT + #[test] fn get_library_version() { let version = nitrokey::get_library_version().unwrap(); diff --git a/tests/otp.rs b/tests/otp.rs index 96da371..fb20768 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + mod util; use std::fmt::Debug; diff --git a/tests/pws.rs b/tests/pws.rs index 8bdf532..df99e1c 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + mod util; use std::ffi::CStr; diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 4a00a66..49ec13e 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -1,3 +1,6 @@ +// Copyright (C) 2018-2019 Robin Krahl +// SPDX-License-Identifier: MIT + pub static ADMIN_PASSWORD: &str = "12345678"; pub static USER_PASSWORD: &str = "123456"; -- cgit v1.2.3 From 52df93249f27ae803bada0451d7380bc3d596007 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 19:40:49 +0000 Subject: Add unwrap_ok macro to replace unwrap in unit tests The unwrap error message is not very useful. This patch adds the unwrap_ok macro that is basically the same as unwrap but prints a more readable error message. --- tests/device.rs | 36 ++++++++++++++++-------------------- tests/lib.rs | 4 +++- tests/otp.rs | 21 +++++++++------------ tests/pws.rs | 23 +++++++++++------------ tests/util/mod.rs | 17 +++++++++++++++++ 5 files changed, 56 insertions(+), 45 deletions(-) (limited to 'tests/util') diff --git a/tests/device.rs b/tests/device.rs index cd37869..67c2713 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -87,15 +87,13 @@ fn disconnect(device: DeviceWrapper) { #[test_device] fn get_serial_number(device: DeviceWrapper) { - let result = device.get_serial_number(); - assert!(result.is_ok()); - let serial_number = result.unwrap(); + let serial_number = unwrap_ok!(device.get_serial_number()); assert!(serial_number.is_ascii()); assert!(serial_number.chars().all(|c| c.is_ascii_hexdigit())); } #[test_device] fn get_firmware_version(device: Pro) { - let version = device.get_firmware_version().unwrap(); + let version = unwrap_ok!(device.get_firmware_version()); assert_eq!(0, version.major); assert!(version.minor > 0); } @@ -135,7 +133,7 @@ fn get_retry_count(device: DeviceWrapper) { #[test_device] fn config(device: DeviceWrapper) { - let admin = device.authenticate_admin(ADMIN_PASSWORD).unwrap(); + let admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); @@ -274,12 +272,12 @@ fn assert_utf8_err_or_ne(left: &str, right: Result) { #[test_device] fn factory_reset(device: DeviceWrapper) { - let admin = device.authenticate_admin(ADMIN_PASSWORD).unwrap(); + let admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let otp_data = OtpSlotData::new(1, "test", "0123468790", OtpMode::SixDigits); assert_ok!((), admin.write_totp_slot(otp_data, 30)); let device = admin.device(); - let pws = device.get_password_safe(USER_PASSWORD).unwrap(); + let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); @@ -301,11 +299,11 @@ fn factory_reset(device: DeviceWrapper) { let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); - let user = device.authenticate_user(USER_PASSWORD).unwrap(); + let user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); assert_cmd_err!(CommandError::SlotNotProgrammed, user.get_totp_slot_name(1)); let device = user.device(); - let pws = device.get_password_safe(USER_PASSWORD).unwrap(); + let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); @@ -315,7 +313,7 @@ fn factory_reset(device: DeviceWrapper) { #[test_device] fn build_aes_key(device: DeviceWrapper) { - let pws = device.get_password_safe(USER_PASSWORD).unwrap(); + let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); @@ -327,7 +325,7 @@ fn build_aes_key(device: DeviceWrapper) { let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); - let pws = device.get_password_safe(USER_PASSWORD).unwrap(); + let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); @@ -406,10 +404,9 @@ fn lock(device: Storage) { #[test_device] fn set_unencrypted_volume_mode(device: Storage) { fn assert_mode(device: &Storage, mode: VolumeMode) { - let status = device.get_status(); - assert!(status.is_ok()); + let status = unwrap_ok!(device.get_status()); assert_eq!( - status.unwrap().unencrypted_volume.read_only, + status.unencrypted_volume.read_only, mode == VolumeMode::ReadOnly ); } @@ -434,15 +431,14 @@ fn set_unencrypted_volume_mode(device: Storage) { #[test_device] fn get_storage_status(device: Storage) { - let status = device.get_status().unwrap(); - + let status = unwrap_ok!(device.get_status()); assert!(status.serial_number_sd_card > 0); assert!(status.serial_number_smart_card > 0); } #[test_device] fn get_production_info(device: Storage) { - let info = device.get_production_info().unwrap(); + let info = unwrap_ok!(device.get_production_info()); assert_eq!(0, info.firmware_version.major); assert!(info.firmware_version.minor != 0); assert!(info.serial_number_cpu != 0); @@ -455,7 +451,7 @@ fn get_production_info(device: Storage) { assert!(info.sd_card.oem != 0); assert!(info.sd_card.manufacturer != 0); - let status = device.get_status().unwrap(); + let status = unwrap_ok!(device.get_status()); assert_eq!(status.firmware_version, info.firmware_version); assert_eq!(status.serial_number_sd_card, info.sd_card.serial_number); } @@ -469,12 +465,12 @@ fn clear_new_sd_card_warning(device: Storage) { // We have to perform an SD card operation to reset the new_sd_card_found field assert_ok!((), device.lock()); - let status = device.get_status().unwrap(); + let status = unwrap_ok!(device.get_status()); assert!(status.new_sd_card_found); assert_ok!((), device.clear_new_sd_card_warning(ADMIN_PASSWORD)); - let status = device.get_status().unwrap(); + let status = unwrap_ok!(device.get_status()); assert!(!status.new_sd_card_found); } diff --git a/tests/lib.rs b/tests/lib.rs index 697024d..8ab75f6 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,9 +1,11 @@ // Copyright (C) 2019 Robin Krahl // SPDX-License-Identifier: MIT +mod util; + #[test] fn get_library_version() { - let version = nitrokey::get_library_version().unwrap(); + let version = unwrap_ok!(nitrokey::get_library_version()); assert!(version.git.is_empty() || version.git.starts_with("v")); assert!(version.major > 0); diff --git a/tests/otp.rs b/tests/otp.rs index e424673..fc0e79e 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -56,8 +56,7 @@ fn configure_hotp(admin: &ConfigureOtp, counter: u8) { fn check_hotp_codes(device: &GenerateOtp, offset: u8) { HOTP_CODES.iter().enumerate().for_each(|(i, code)| { if i >= offset as usize { - let result = device.get_hotp_code(1); - assert_eq!(code, &result.unwrap()); + assert_ok!(code.to_string(), device.get_hotp_code(1)); } }); } @@ -93,7 +92,7 @@ fn hotp_pin(device: DeviceWrapper) { assert_ok!((), admin.write_config(config)); configure_hotp(&admin, 0); - let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); + let user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); check_hotp_codes(&user, 0); assert_cmd_err!(CommandError::NotAuthorized, user.device().get_hotp_code(1)); @@ -106,10 +105,8 @@ fn hotp_slot_name(device: DeviceWrapper) { assert_ok!((), admin.write_hotp_slot(slot_data, 0)); let device = admin.device(); - let result = device.get_hotp_slot_name(1); - assert_eq!("test-hotp", result.unwrap()); - let result = device.get_hotp_slot_name(4); - assert_lib_err!(LibraryError::InvalidSlot, result); + assert_ok!("test-hotp".to_string(), device.get_hotp_slot_name(1)); + assert_lib_err!(LibraryError::InvalidSlot, device.get_hotp_slot_name(4)); } #[test_device] @@ -149,7 +146,7 @@ fn hotp_erase(device: DeviceWrapper) { let result = device.get_hotp_code(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); - assert_eq!("test2", device.get_hotp_slot_name(2).unwrap()); + assert_ok!("test2".to_string(), device.get_hotp_slot_name(2)); } fn configure_totp(admin: &ConfigureOtp, factor: u64) { @@ -167,7 +164,7 @@ fn check_totp_codes(device: &GenerateOtp, factor: u64, timestamp_size: TotpTimes } assert_ok!((), device.set_time(time, true)); - let code = device.get_totp_code(1).unwrap(); + let code = unwrap_ok!(device.get_totp_code(1)); assert!( code.contains(&code), "Generated TOTP code {} for {}, but expected one of {}", @@ -221,7 +218,7 @@ fn totp_pin(device: DeviceWrapper) { assert_ok!((), admin.write_config(config)); configure_totp(&admin, 1); - let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); + let user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); check_totp_codes(&user, 1, TotpTimestampSize::U32); assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); @@ -235,7 +232,7 @@ fn totp_pin_64(device: Pro) { assert_ok!((), admin.write_config(config)); configure_totp(&admin, 1); - let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); + let user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); check_totp_codes(&user, 1, TotpTimestampSize::U64); assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); @@ -291,5 +288,5 @@ fn totp_erase(device: DeviceWrapper) { let result = device.get_totp_code(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); - assert_eq!("test2", device.get_totp_slot_name(2).unwrap()); + assert_ok!("test2".to_string(), device.get_totp_slot_name(2)); } diff --git a/tests/pws.rs b/tests/pws.rs index df99e1c..3ec7e38 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -37,7 +37,7 @@ fn get_pws(device: &T) -> PasswordSafe where T: Device, { - device.get_password_safe(USER_PASSWORD).unwrap() + unwrap_ok!(device.get_password_safe(USER_PASSWORD)) } #[test_device] @@ -59,7 +59,7 @@ fn drop(device: DeviceWrapper) { { let pws = get_pws(&device); assert_ok!((), pws.write_slot(1, "name", "login", "password")); - assert_eq!("name", pws.get_slot_name(1).unwrap()); + assert_ok!("name".to_string(), pws.get_slot_name(1)); let result = get_slot_name_direct(1); assert_ok!(String::from("name"), result); } @@ -76,11 +76,11 @@ fn get_status(device: DeviceWrapper) { for i in 0..SLOT_COUNT { assert_ok!((), pws.erase_slot(i)); } - let status = pws.get_slot_status().unwrap(); + let status = unwrap_ok!(pws.get_slot_status()); assert_eq!(status, [false; SLOT_COUNT as usize]); assert_ok!((), pws.write_slot(1, "name", "login", "password")); - let status = pws.get_slot_status().unwrap(); + let status = unwrap_ok!(pws.get_slot_status()); for i in 0..SLOT_COUNT { assert_eq!(i == 1, status[i as usize]); } @@ -88,17 +88,16 @@ fn get_status(device: DeviceWrapper) { for i in 0..SLOT_COUNT { assert_ok!((), pws.write_slot(i, "name", "login", "password")); } - let status = pws.get_slot_status().unwrap(); - assert_eq!(status, [true; SLOT_COUNT as usize]); + assert_ok!([true; SLOT_COUNT as usize], pws.get_slot_status()); } #[test_device] fn get_data(device: DeviceWrapper) { let pws = get_pws(&device); assert_ok!((), pws.write_slot(1, "name", "login", "password")); - assert_eq!("name", pws.get_slot_name(1).unwrap()); - assert_eq!("login", pws.get_slot_login(1).unwrap()); - assert_eq!("password", pws.get_slot_password(1).unwrap()); + assert_ok!("name".to_string(), pws.get_slot_name(1)); + assert_ok!("login".to_string(), pws.get_slot_login(1)); + assert_ok!("password".to_string(), pws.get_slot_password(1)); assert_ok!((), pws.erase_slot(1)); assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_name(1)); @@ -109,9 +108,9 @@ fn get_data(device: DeviceWrapper) { let login = "pär@test.com"; let password = "'i3lJc[09?I:,[u7dWz9"; assert_ok!((), pws.write_slot(1, name, login, password)); - assert_eq!(name, pws.get_slot_name(1).unwrap()); - assert_eq!(login, pws.get_slot_login(1).unwrap()); - assert_eq!(password, pws.get_slot_password(1).unwrap()); + assert_ok!(name.to_string(), pws.get_slot_name(1)); + assert_ok!(login.to_string(), pws.get_slot_login(1)); + assert_ok!(password.to_string(), pws.get_slot_password(1)); assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_name(SLOT_COUNT)); assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_login(SLOT_COUNT)); diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 49ec13e..2bda9ba 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -1,9 +1,26 @@ // Copyright (C) 2018-2019 Robin Krahl // SPDX-License-Identifier: MIT +#[allow(dead_code)] pub static ADMIN_PASSWORD: &str = "12345678"; +#[allow(dead_code)] pub static USER_PASSWORD: &str = "123456"; +#[macro_export] +macro_rules! unwrap_ok { + ($val:expr) => {{ + match $val { + Ok(val) => val, + Err(err) => panic!( + r#"assertion failed: `(left == right)` + left: `Ok(_)`, + right: `Err({:?})`"#, + err + ), + } + }}; +} + #[macro_export] macro_rules! assert_ok { ($left:expr, $right:expr) => {{ -- cgit v1.2.3 From d1262390573b758ac4aa610eff96a1b5dcb9f3d6 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 19:45:40 +0000 Subject: Add assert_any_ok macro to unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes we cannot use assert_ok! as we can’t compare the Ok value (or do not want to). For these cases, this patch adds the new assert_any_ok macro to use instead of assert!(x.is_ok()). The advantage is that the error information is not discarded but printed in a helpful error message. --- tests/device.rs | 12 ++++++------ tests/pws.rs | 4 ++-- tests/util/mod.rs | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'tests/util') diff --git a/tests/device.rs b/tests/device.rs index 67c2713..306b33f 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -55,9 +55,9 @@ fn connect_pro(device: Pro) { assert_eq!(device.get_model(), nitrokey::Model::Pro); drop(device); - assert!(nitrokey::connect().is_ok()); - assert!(nitrokey::connect_model(nitrokey::Model::Pro).is_ok()); - assert!(nitrokey::Pro::connect().is_ok()); + assert_any_ok!(nitrokey::connect()); + assert_any_ok!(nitrokey::connect_model(nitrokey::Model::Pro)); + assert_any_ok!(nitrokey::Pro::connect()); } #[test_device] @@ -65,9 +65,9 @@ fn connect_storage(device: Storage) { assert_eq!(device.get_model(), nitrokey::Model::Storage); drop(device); - assert!(nitrokey::connect().is_ok()); - assert!(nitrokey::connect_model(nitrokey::Model::Storage).is_ok()); - assert!(nitrokey::Storage::connect().is_ok()); + assert_any_ok!(nitrokey::connect()); + assert_any_ok!(nitrokey::connect_model(nitrokey::Model::Storage)); + assert_any_ok!(nitrokey::Storage::connect()); } fn assert_empty_serial_number() { diff --git a/tests/pws.rs b/tests/pws.rs index 3ec7e38..32dc8f7 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -46,12 +46,12 @@ fn enable(device: DeviceWrapper) { CommandError::WrongPassword, device.get_password_safe(&(USER_PASSWORD.to_owned() + "123")) ); - assert!(device.get_password_safe(USER_PASSWORD).is_ok()); + assert_any_ok!(device.get_password_safe(USER_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, device.get_password_safe(ADMIN_PASSWORD) ); - assert!(device.get_password_safe(USER_PASSWORD).is_ok()); + assert_any_ok!(device.get_password_safe(USER_PASSWORD)); } #[test_device] diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 2bda9ba..bd207a9 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -21,6 +21,21 @@ macro_rules! unwrap_ok { }}; } +#[macro_export] +macro_rules! assert_any_ok { + ($val:expr) => {{ + match &$val { + Ok(_) => {} + Err(err) => panic!( + r#"assertion failed: `(left == right)` + left: `Ok(_)`, + right: `Err({:?})`"#, + err + ), + } + }}; +} + #[macro_export] macro_rules! assert_ok { ($left:expr, $right:expr) => {{ -- cgit v1.2.3 From 0972bbe82623c3d9649b6023d8f50d304aa0cde6 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 14:24:12 +0000 Subject: Refactor User and Admin to use a mutable reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the initial nitrokey-rs implementation, the Admin and the User struct take the Device by value to make sure that the user cannot initiate a second authentication while this first is still active (which would invalidate the temporary password). Now we realized that this is not necessary – taking a mutable reference has the same effect, but leads to a much cleaner API. This patch refactors the Admin and User structs – and all dependent code – to use a mutable reference instead of a Device value. --- CHANGELOG.md | 2 + src/auth.rs | 183 ++++++++++++++++-------------------------------------- src/device.rs | 42 ++++--------- src/lib.rs | 4 +- src/otp.rs | 16 ++--- tests/device.rs | 137 ++++++++++++++++++++-------------------- tests/otp.rs | 66 +++++++++++--------- tests/util/mod.rs | 12 ++-- 8 files changed, 185 insertions(+), 277 deletions(-) (limited to 'tests/util') diff --git a/CHANGELOG.md b/CHANGELOG.md index e98e857..8e6cb9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ SPDX-License-Identifier: MIT - Implement `DerefMut` for `User` and `Admin`. - Add `device_mut` method to `DeviceWrapper`. - Require a mutable `Device` reference if a method changes the device state. +- Let `Admin` and `User` store a mutable reference to the `Device` instead of + the `Device` value. # v0.3.4 (2019-01-20) - Fix authentication methods that assumed that `char` is signed. diff --git a/src/auth.rs b/src/auth.rs index f9f50fa..573fed3 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -42,16 +42,10 @@ pub trait Authenticate { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; - /// let device = match device.authenticate_user("123456") { - /// Ok(user) => { - /// perform_user_task(&user); - /// user.device() - /// }, - /// Err((device, err)) => { - /// eprintln!("Could not authenticate as user: {}", err); - /// device - /// }, + /// let mut device = nitrokey::connect()?; + /// match device.authenticate_user("123456") { + /// Ok(user) => perform_user_task(&user), + /// Err(err) => eprintln!("Could not authenticate as user: {}", err), /// }; /// perform_other_task(&device); /// # Ok(()) @@ -61,9 +55,9 @@ pub trait Authenticate { /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn authenticate_user(self, password: &str) -> Result, (Self, Error)> + fn authenticate_user(&mut self, password: &str) -> Result, Error> where - Self: Device + Sized; + Self: Device + std::marker::Sized; /// Performs admin authentication. This method consumes the device. If successful, an /// authenticated device is returned. Otherwise, the current unauthenticated device and the @@ -88,16 +82,10 @@ pub trait Authenticate { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; - /// let device = match device.authenticate_admin("123456") { - /// Ok(admin) => { - /// perform_admin_task(&admin); - /// admin.device() - /// }, - /// Err((device, err)) => { - /// eprintln!("Could not authenticate as admin: {}", err); - /// device - /// }, + /// let mut device = nitrokey::connect()?; + /// match device.authenticate_admin("123456") { + /// Ok(admin) => perform_admin_task(&admin), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// }; /// perform_other_task(&device); /// # Ok(()) @@ -107,13 +95,13 @@ pub trait Authenticate { /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> + fn authenticate_admin(&mut self, password: &str) -> Result, Error> where - Self: Device + Sized; + Self: Device + std::marker::Sized; } -trait AuthenticatedDevice { - fn new(device: T, temp_password: Vec) -> Self; +trait AuthenticatedDevice<'a, T> { + fn new(device: &'a mut T, temp_password: Vec) -> Self; fn temp_password_ptr(&self) -> *const c_char; } @@ -128,8 +116,8 @@ trait AuthenticatedDevice { /// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin /// [`device`]: #method.device #[derive(Debug)] -pub struct User { - device: T, +pub struct User<'a, T: Device> { + device: &'a mut T, temp_password: Vec, } @@ -143,89 +131,42 @@ pub struct User { /// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin /// [`device`]: #method.device #[derive(Debug)] -pub struct Admin { - device: T, +pub struct Admin<'a, T: Device> { + device: &'a mut T, temp_password: Vec, } -fn authenticate(device: D, password: &str, callback: T) -> Result +fn authenticate<'a, D, A, T>(device: &'a mut D, password: &str, callback: T) -> Result where D: Device, - A: AuthenticatedDevice, + A: AuthenticatedDevice<'a, D>, T: Fn(*const c_char, *const c_char) -> c_int, { - let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) { - Ok(temp_password) => temp_password, - Err(err) => return Err((device, err)), - }; - let password = match get_cstring(password) { - Ok(password) => password, - Err(err) => return Err((device, err)), - }; + let temp_password = generate_password(TEMPORARY_PASSWORD_LENGTH)?; + let password = get_cstring(password)?; let password_ptr = password.as_ptr(); let temp_password_ptr = temp_password.as_ptr() as *const c_char; match callback(password_ptr, temp_password_ptr) { 0 => Ok(A::new(device, temp_password)), - rv => Err((device, Error::from(rv))), + rv => Err(Error::from(rv)), } } -fn authenticate_user_wrapper( - device: T, - constructor: C, - password: &str, -) -> Result, (DeviceWrapper, Error)> -where - T: Device, - C: Fn(T) -> DeviceWrapper, -{ - let result = device.authenticate_user(password); - match result { - Ok(user) => Ok(User::new(constructor(user.device), user.temp_password)), - Err((device, err)) => Err((constructor(device), err)), - } -} - -fn authenticate_admin_wrapper( - device: T, - constructor: C, - password: &str, -) -> Result, (DeviceWrapper, Error)> -where - T: Device, - C: Fn(T) -> DeviceWrapper, -{ - let result = device.authenticate_admin(password); - match result { - Ok(user) => Ok(Admin::new(constructor(user.device), user.temp_password)), - Err((device, err)) => Err((constructor(device), err)), - } -} - -impl User { - /// Forgets the user authentication and returns an unauthenticated device. This method - /// consumes the authenticated device. It does not perform any actual commands on the - /// Nitrokey. - pub fn device(self) -> T { - self.device - } -} - -impl ops::Deref for User { +impl<'a, T: Device> ops::Deref for User<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { - &self.device + self.device } } -impl ops::DerefMut for User { +impl<'a, T: Device> ops::DerefMut for User<'a, T> { fn deref_mut(&mut self) -> &mut T { - &mut self.device + self.device } } -impl GenerateOtp for User { +impl<'a, T: Device> GenerateOtp for User<'a, T> { fn get_hotp_code(&mut self, slot: u8) -> Result { result_from_string(unsafe { nitrokey_sys::NK_get_hotp_code_PIN(slot, self.temp_password_ptr()) @@ -239,8 +180,8 @@ impl GenerateOtp for User { } } -impl AuthenticatedDevice for User { - fn new(device: T, temp_password: Vec) -> Self { +impl<'a, T: Device> AuthenticatedDevice<'a, T> for User<'a, T> { + fn new(device: &'a mut T, temp_password: Vec) -> Self { User { device, temp_password, @@ -252,28 +193,21 @@ impl AuthenticatedDevice for User { } } -impl ops::Deref for Admin { +impl<'a, T: Device> ops::Deref for Admin<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { - &self.device + self.device } } -impl ops::DerefMut for Admin { +impl<'a, T: Device> ops::DerefMut for Admin<'a, T> { fn deref_mut(&mut self) -> &mut T { - &mut self.device - } -} - -impl Admin { - /// Forgets the user authentication and returns an unauthenticated device. This method - /// consumes the authenticated device. It does not perform any actual commands on the - /// Nitrokey. - pub fn device(self) -> T { self.device } +} +impl<'a, T: Device> Admin<'a, T> { /// Writes the given configuration to the Nitrokey device. /// /// # Errors @@ -287,14 +221,11 @@ impl Admin { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let config = Config::new(None, None, None, false); /// match device.authenticate_admin("12345678") { - /// Ok(mut admin) => { - /// admin.write_config(config); - /// () - /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Ok(mut admin) => admin.write_config(config)?, + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// }; /// # Ok(()) /// # } @@ -316,7 +247,7 @@ impl Admin { } } -impl ConfigureOtp for Admin { +impl<'a, T: Device> ConfigureOtp for Admin<'a, T> { fn write_hotp_slot(&mut self, data: OtpSlotData, counter: u64) -> Result<(), Error> { let raw_data = RawOtpSlotData::new(data)?; get_command_result(unsafe { @@ -364,8 +295,8 @@ impl ConfigureOtp for Admin { } } -impl AuthenticatedDevice for Admin { - fn new(device: T, temp_password: Vec) -> Self { +impl<'a, T: Device> AuthenticatedDevice<'a, T> for Admin<'a, T> { + fn new(device: &'a mut T, temp_password: Vec) -> Self { Admin { device, temp_password, @@ -378,35 +309,27 @@ impl AuthenticatedDevice for Admin { } impl Authenticate for DeviceWrapper { - fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { - match self { - DeviceWrapper::Storage(storage) => { - authenticate_user_wrapper(storage, DeviceWrapper::Storage, password) - } - DeviceWrapper::Pro(pro) => authenticate_user_wrapper(pro, DeviceWrapper::Pro, password), - } + fn authenticate_user(&mut self, password: &str) -> Result, Error> { + authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { + nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) + }) } - fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { - match self { - DeviceWrapper::Storage(storage) => { - authenticate_admin_wrapper(storage, DeviceWrapper::Storage, password) - } - DeviceWrapper::Pro(pro) => { - authenticate_admin_wrapper(pro, DeviceWrapper::Pro, password) - } - } + fn authenticate_admin(&mut self, password: &str) -> Result, Error> { + authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { + nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) + }) } } impl Authenticate for Pro { - fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { + fn authenticate_user(&mut self, password: &str) -> Result, Error> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) }) } - fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { + fn authenticate_admin(&mut self, password: &str) -> Result, Error> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr) }) @@ -414,13 +337,13 @@ impl Authenticate for Pro { } impl Authenticate for Storage { - fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { + fn authenticate_user(&mut self, password: &str) -> Result, Error> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) }) } - fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { + fn authenticate_admin(&mut self, password: &str) -> Result, Error> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr) }) diff --git a/src/device.rs b/src/device.rs index f6492cd..a0df30e 100644 --- a/src/device.rs +++ b/src/device.rs @@ -71,16 +71,10 @@ impl fmt::Display for VolumeMode { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { -/// let device = nitrokey::connect()?; -/// let device = match device.authenticate_user("123456") { -/// Ok(user) => { -/// perform_user_task(&user); -/// user.device() -/// }, -/// Err((device, err)) => { -/// eprintln!("Could not authenticate as user: {}", err); -/// device -/// }, +/// let mut device = nitrokey::connect()?; +/// match device.authenticate_user("123456") { +/// Ok(user) => perform_user_task(&user), +/// Err(err) => eprintln!("Could not authenticate as user: {}", err), /// }; /// perform_other_task(&device); /// # Ok(()) @@ -135,16 +129,10 @@ pub enum DeviceWrapper { /// fn perform_other_task(device: &Pro) {} /// /// # fn try_main() -> Result<(), Error> { -/// let device = nitrokey::Pro::connect()?; -/// let device = match device.authenticate_user("123456") { -/// Ok(user) => { -/// perform_user_task(&user); -/// user.device() -/// }, -/// Err((device, err)) => { -/// eprintln!("Could not authenticate as user: {}", err); -/// device -/// }, +/// let mut device = nitrokey::Pro::connect()?; +/// match device.authenticate_user("123456") { +/// Ok(user) => perform_user_task(&user), +/// Err(err) => eprintln!("Could not authenticate as user: {}", err), /// }; /// perform_other_task(&device); /// # Ok(()) @@ -181,16 +169,10 @@ pub struct Pro { /// fn perform_other_task(device: &Storage) {} /// /// # fn try_main() -> Result<(), Error> { -/// let device = nitrokey::Storage::connect()?; -/// let device = match device.authenticate_user("123456") { -/// Ok(user) => { -/// perform_user_task(&user); -/// user.device() -/// }, -/// Err((device, err)) => { -/// eprintln!("Could not authenticate as user: {}", err); -/// device -/// }, +/// let mut device = nitrokey::Storage::connect()?; +/// match device.authenticate_user("123456") { +/// Ok(user) => perform_user_task(&user), +/// Err(err) => eprintln!("Could not authenticate as user: {}", err), /// }; /// perform_other_task(&device); /// # Ok(()) diff --git a/src/lib.rs b/src/lib.rs index c35829c..d7a8c5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,7 @@ //! # use nitrokey::Error; //! //! # fn try_main() -> Result<(), Error> { -//! let device = nitrokey::connect()?; +//! let mut device = nitrokey::connect()?; //! let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); //! match device.authenticate_admin("12345678") { //! Ok(mut admin) => { @@ -53,7 +53,7 @@ //! Err(err) => eprintln!("Could not write slot: {}", err), //! } //! }, -//! Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), +//! Err(err) => eprintln!("Could not authenticate as admin: {}", err), //! } //! # Ok(()) //! # } diff --git a/src/otp.rs b/src/otp.rs index ee142c7..a8dd20b 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -35,7 +35,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -44,7 +44,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -71,7 +71,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::EightDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -80,7 +80,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -104,7 +104,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_hotp_slot(1) { @@ -112,7 +112,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -134,7 +134,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let device = nitrokey::connect()?; + /// let mut device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_totp_slot(1) { @@ -142,7 +142,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), + /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } diff --git a/tests/device.rs b/tests/device.rs index 7a69214..bffd767 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -98,41 +98,34 @@ fn get_firmware_version(device: Pro) { assert!(version.minor > 0); } -fn admin_retry(device: T, suffix: &str, count: u8) -> T { - let result = device.authenticate_admin(&(ADMIN_PASSWORD.to_owned() + suffix)); - let device = match result { - Ok(admin) => admin.device(), - Err((device, _)) => device, - }; +fn admin_retry(device: &mut T, suffix: &str, count: u8) { + assert_any_ok!(device.authenticate_admin(&(ADMIN_PASSWORD.to_owned() + suffix))); assert_ok!(count, device.get_admin_retry_count()); - return device; } -fn user_retry(device: T, suffix: &str, count: u8) -> T { - let result = device.authenticate_user(&(USER_PASSWORD.to_owned() + suffix)); - let device = match result { - Ok(admin) => admin.device(), - Err((device, _)) => device, - }; +fn user_retry(device: &mut T, suffix: &str, count: u8) { + assert_any_ok!(device.authenticate_user(&(USER_PASSWORD.to_owned() + suffix))); assert_ok!(count, device.get_user_retry_count()); - return device; } #[test_device] fn get_retry_count(device: DeviceWrapper) { - let device = admin_retry(device, "", 3); - let device = admin_retry(device, "123", 2); - let device = admin_retry(device, "456", 1); - let device = admin_retry(device, "", 3); - - let device = user_retry(device, "", 3); - let device = user_retry(device, "123", 2); - let device = user_retry(device, "456", 1); - user_retry(device, "", 3); + let mut device = device; + + admin_retry(&mut device, "", 3); + admin_retry(&mut device, "123", 2); + admin_retry(&mut device, "456", 1); + admin_retry(&mut device, "", 3); + + user_retry(&mut device, "", 3); + user_retry(&mut device, "123", 2); + user_retry(&mut device, "456", 1); + user_retry(&mut device, "", 3); } #[test_device] fn config(device: DeviceWrapper) { + let mut device = device; let mut admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let config = Config::new(None, None, None, true); @@ -153,43 +146,52 @@ fn config(device: DeviceWrapper) { #[test_device] fn change_user_pin(device: DeviceWrapper) { - let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); - let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; - let mut device = device; + assert_any_ok!(device.authenticate_user(USER_PASSWORD)); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_user(USER_NEW_PASSWORD) + ); + assert_ok!((), device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD)); - let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0; - let device = device - .authenticate_user(USER_NEW_PASSWORD) - .unwrap() - .device(); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_user(USER_PASSWORD) + ); + assert_any_ok!(device.authenticate_user(USER_NEW_PASSWORD)); - let mut device = device; let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); assert_cmd_err!(CommandError::WrongPassword, result); assert_ok!((), device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD)); - let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); - assert!(device.authenticate_user(USER_NEW_PASSWORD).is_err()); + assert_any_ok!(device.authenticate_user(USER_PASSWORD)); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_user(USER_NEW_PASSWORD) + ); } #[test_device] fn change_admin_pin(device: DeviceWrapper) { - let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); - let mut device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; + let mut device = device; + assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_admin(ADMIN_NEW_PASSWORD) + ); assert_ok!( (), device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) ); - let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0; - let mut device = device - .authenticate_admin(ADMIN_NEW_PASSWORD) - .unwrap() - .device(); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_admin(ADMIN_PASSWORD) + ); + assert_any_ok!(device.authenticate_admin(ADMIN_NEW_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, @@ -201,28 +203,24 @@ fn change_admin_pin(device: DeviceWrapper) { device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD) ); - let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); - device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); + assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_admin(ADMIN_NEW_PASSWORD) + ); } -fn require_failed_user_login(device: D, password: &str, error: CommandError) -> D -where - D: Device + Authenticate, - nitrokey::User: std::fmt::Debug, -{ - let result = device.authenticate_user(password); - assert!(result.is_err()); - let err = result.unwrap_err(); - match err.1 { - Error::CommandError(err) => assert_eq!(error, err), - _ => assert!(false), - }; - err.0 +fn require_failed_user_login(device: &mut D, password: &str) { + assert_cmd_err!( + CommandError::WrongPassword, + device.authenticate_user(password) + ); } #[test_device] fn unlock_user_pin(device: DeviceWrapper) { - let mut device = device.authenticate_user(USER_PASSWORD).unwrap().device(); + let mut device = device; + assert_any_ok!(device.authenticate_user(USER_PASSWORD)); assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, @@ -231,10 +229,10 @@ fn unlock_user_pin(device: DeviceWrapper) { // block user PIN let wrong_password = USER_PASSWORD.to_owned() + "foo"; - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let mut device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, USER_PASSWORD); // unblock with current PIN assert_cmd_err!( @@ -242,13 +240,13 @@ fn unlock_user_pin(device: DeviceWrapper) { device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) ); assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); - let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); + assert_any_ok!(device.authenticate_user(USER_PASSWORD)); // block user PIN - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); - let mut device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, &wrong_password); + require_failed_user_login(&mut device, USER_PASSWORD); // unblock with new PIN assert_cmd_err!( @@ -274,11 +272,11 @@ fn assert_utf8_err_or_ne(left: &str, right: Result) { #[test_device] fn factory_reset(device: DeviceWrapper) { + let mut device = device; let mut admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let otp_data = OtpSlotData::new(1, "test", "0123468790", OtpMode::SixDigits); assert_ok!((), admin.write_totp_slot(otp_data, 30)); - let mut device = admin.device(); let mut pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); @@ -299,12 +297,11 @@ fn factory_reset(device: DeviceWrapper) { ); assert_ok!((), device.factory_reset(ADMIN_NEW_PASSWORD)); - let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); + assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); assert_cmd_err!(CommandError::SlotNotProgrammed, user.get_totp_slot_name(1)); - let mut device = user.device(); let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); @@ -327,7 +324,7 @@ fn build_aes_key(device: DeviceWrapper) { ); assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); - let mut device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); + assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); diff --git a/tests/otp.rs b/tests/otp.rs index 28a8d7c..8ca8311 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -3,7 +3,6 @@ mod util; -use std::fmt::Debug; use std::ops::DerefMut; use nitrokey::{ @@ -38,14 +37,11 @@ enum TotpTimestampSize { U64, } -fn make_admin_test_device(device: T) -> Admin +fn make_admin_test_device<'a, T>(device: &'a mut T) -> Admin<'a, T> where T: Device, - (T, nitrokey::Error): Debug, { - device - .authenticate_admin(ADMIN_PASSWORD) - .expect("Could not login as admin.") + unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)) } fn configure_hotp(admin: &mut ConfigureOtp, counter: u8) { @@ -72,7 +68,8 @@ fn set_time(device: DeviceWrapper) { #[test_device] fn hotp_no_pin(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -83,36 +80,38 @@ fn hotp_no_pin(device: DeviceWrapper) { check_hotp_codes(admin.deref_mut(), 5); configure_hotp(&mut admin, 0); - check_hotp_codes(&mut admin.device(), 0); + check_hotp_codes(&mut device, 0); } #[test_device] fn hotp_pin(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_hotp(&mut admin, 0); - let mut user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); check_hotp_codes(&mut user, 0); - assert_cmd_err!(CommandError::NotAuthorized, user.device().get_hotp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, user.get_hotp_code(1)); } #[test_device] fn hotp_slot_name(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let slot_data = OtpSlotData::new(1, "test-hotp", HOTP_SECRET, OtpMode::SixDigits); assert_ok!((), admin.write_hotp_slot(slot_data, 0)); - let device = admin.device(); assert_ok!("test-hotp".to_string(), device.get_hotp_slot_name(1)); assert_lib_err!(LibraryError::InvalidSlot, device.get_hotp_slot_name(4)); } #[test_device] fn hotp_error(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let slot_data = OtpSlotData::new(1, "", HOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_hotp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(4, "test", HOTP_SECRET, OtpMode::SixDigits); @@ -131,7 +130,8 @@ fn hotp_error(device: DeviceWrapper) { #[test_device] fn hotp_erase(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); let slot_data = OtpSlotData::new(1, "test1", HOTP_SECRET, OtpMode::SixDigits); @@ -141,7 +141,6 @@ fn hotp_erase(device: DeviceWrapper) { assert_ok!((), admin.erase_hotp_slot(1)); - let mut device = admin.device(); let result = device.get_hotp_slot_name(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); let result = device.get_hotp_code(1); @@ -178,7 +177,8 @@ fn check_totp_codes(device: &mut GenerateOtp, factor: u64, timestamp_size: TotpT #[test_device] fn totp_no_pin(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -189,14 +189,15 @@ fn totp_no_pin(device: DeviceWrapper) { check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U32); configure_totp(&mut admin, 1); - check_totp_codes(&mut admin.device(), 1, TotpTimestampSize::U32); + check_totp_codes(&mut device, 1, TotpTimestampSize::U32); } #[test_device] // Nitrokey Storage does only support timestamps that fit in a 32-bit // unsigned integer, so don't test with it. fn totp_no_pin_64(device: Pro) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -207,43 +208,45 @@ fn totp_no_pin_64(device: Pro) { check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U64); configure_totp(&mut admin, 1); - check_totp_codes(&mut admin.device(), 1, TotpTimestampSize::U64); + check_totp_codes(&mut device, 1, TotpTimestampSize::U64); } #[test_device] fn totp_pin(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); check_totp_codes(&mut user, 1, TotpTimestampSize::U32); - assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, user.get_totp_code(1)); } #[test_device] // See comment for totp_no_pin_64. fn totp_pin_64(device: Pro) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(admin.device().authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(admin.authenticate_user(USER_PASSWORD)); check_totp_codes(&mut user, 1, TotpTimestampSize::U64); - assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, device.get_totp_code(1)); } #[test_device] fn totp_slot_name(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let slot_data = OtpSlotData::new(1, "test-totp", TOTP_SECRET, OtpMode::EightDigits); assert_ok!((), admin.write_totp_slot(slot_data, 0)); - let device = admin.device(); let result = device.get_totp_slot_name(1); assert_ok!("test-totp", result); let result = device.get_totp_slot_name(16); @@ -252,7 +255,8 @@ fn totp_slot_name(device: DeviceWrapper) { #[test_device] fn totp_error(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let slot_data = OtpSlotData::new(1, "", TOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_totp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(20, "test", TOTP_SECRET, OtpMode::SixDigits); @@ -271,7 +275,8 @@ fn totp_error(device: DeviceWrapper) { #[test_device] fn totp_erase(device: DeviceWrapper) { - let mut admin = make_admin_test_device(device); + let mut device = device; + let mut admin = make_admin_test_device(&mut device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); let slot_data = OtpSlotData::new(1, "test1", TOTP_SECRET, OtpMode::SixDigits); @@ -281,7 +286,6 @@ fn totp_erase(device: DeviceWrapper) { assert_ok!((), admin.erase_totp_slot(1)); - let device = admin.device(); let result = device.get_totp_slot_name(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); let result = device.get_totp_code(1); diff --git a/tests/util/mod.rs b/tests/util/mod.rs index bd207a9..f80372d 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -8,7 +8,7 @@ pub static USER_PASSWORD: &str = "123456"; #[macro_export] macro_rules! unwrap_ok { - ($val:expr) => {{ + ($val:expr) => { match $val { Ok(val) => val, Err(err) => panic!( @@ -18,12 +18,12 @@ macro_rules! unwrap_ok { err ), } - }}; + }; } #[macro_export] macro_rules! assert_any_ok { - ($val:expr) => {{ + ($val:expr) => { match &$val { Ok(_) => {} Err(err) => panic!( @@ -33,12 +33,12 @@ macro_rules! assert_any_ok { err ), } - }}; + }; } #[macro_export] macro_rules! assert_ok { - ($left:expr, $right:expr) => {{ + ($left:expr, $right:expr) => { match &$right { Ok(right) => match &$left { left => { @@ -59,7 +59,7 @@ macro_rules! assert_ok { $left, right_err ), } - }}; + }; } #[macro_export] -- cgit v1.2.3 From 606177a61de39ba5e96390d63cff536f895d8c39 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 4 Feb 2019 00:29:11 +0000 Subject: Remove PIN constants from tests In a previous commit, we introduced the DEFAULT_{ADMIN,USER}_PIN constants. Therefore we no longer need in the {ADMIN,USER}_PASSWORD constants in the util module for the tests. --- tests/device.rs | 140 +++++++++++++++++++++++++++++++----------------------- tests/otp.rs | 12 ++--- tests/pws.rs | 15 +++--- tests/util/mod.rs | 5 -- 4 files changed, 92 insertions(+), 80 deletions(-) (limited to 'tests/util') diff --git a/tests/device.rs b/tests/device.rs index bffd767..ecc3cfa 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -10,11 +10,10 @@ use std::{thread, time}; use nitrokey::{ Authenticate, CommandError, CommunicationError, Config, ConfigureOtp, Device, Error, GenerateOtp, GetPasswordSafe, LibraryError, OtpMode, OtpSlotData, Storage, VolumeMode, + DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN, }; use nitrokey_test::test as test_device; -use crate::util::{ADMIN_PASSWORD, USER_PASSWORD}; - static ADMIN_NEW_PASSWORD: &str = "1234567890"; static UPDATE_PIN: &str = "12345678"; static UPDATE_NEW_PIN: &str = "87654321"; @@ -99,12 +98,12 @@ fn get_firmware_version(device: Pro) { } fn admin_retry(device: &mut T, suffix: &str, count: u8) { - assert_any_ok!(device.authenticate_admin(&(ADMIN_PASSWORD.to_owned() + suffix))); + assert_any_ok!(device.authenticate_admin(&(DEFAULT_ADMIN_PIN.to_owned() + suffix))); assert_ok!(count, device.get_admin_retry_count()); } fn user_retry(device: &mut T, suffix: &str, count: u8) { - assert_any_ok!(device.authenticate_user(&(USER_PASSWORD.to_owned() + suffix))); + assert_any_ok!(device.authenticate_user(&(DEFAULT_USER_PIN.to_owned() + suffix))); assert_ok!(count, device.get_user_retry_count()); } @@ -126,7 +125,7 @@ fn get_retry_count(device: DeviceWrapper) { #[test_device] fn config(device: DeviceWrapper) { let mut device = device; - let mut admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + let mut admin = unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); @@ -147,26 +146,32 @@ fn config(device: DeviceWrapper) { #[test_device] fn change_user_pin(device: DeviceWrapper) { let mut device = device; - assert_any_ok!(device.authenticate_user(USER_PASSWORD)); + assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); assert_cmd_err!( CommandError::WrongPassword, device.authenticate_user(USER_NEW_PASSWORD) ); - assert_ok!((), device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD)); + assert_ok!( + (), + device.change_user_pin(DEFAULT_USER_PIN, USER_NEW_PASSWORD) + ); assert_cmd_err!( CommandError::WrongPassword, - device.authenticate_user(USER_PASSWORD) + device.authenticate_user(DEFAULT_USER_PIN) ); assert_any_ok!(device.authenticate_user(USER_NEW_PASSWORD)); - let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); + let result = device.change_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN); assert_cmd_err!(CommandError::WrongPassword, result); - assert_ok!((), device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD)); + assert_ok!( + (), + device.change_user_pin(USER_NEW_PASSWORD, DEFAULT_USER_PIN) + ); - assert_any_ok!(device.authenticate_user(USER_PASSWORD)); + assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); assert_cmd_err!( CommandError::WrongPassword, device.authenticate_user(USER_NEW_PASSWORD) @@ -176,7 +181,7 @@ fn change_user_pin(device: DeviceWrapper) { #[test_device] fn change_admin_pin(device: DeviceWrapper) { let mut device = device; - assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); assert_cmd_err!( CommandError::WrongPassword, device.authenticate_admin(ADMIN_NEW_PASSWORD) @@ -184,26 +189,26 @@ fn change_admin_pin(device: DeviceWrapper) { assert_ok!( (), - device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) + device.change_admin_pin(DEFAULT_ADMIN_PIN, ADMIN_NEW_PASSWORD) ); assert_cmd_err!( CommandError::WrongPassword, - device.authenticate_admin(ADMIN_PASSWORD) + device.authenticate_admin(DEFAULT_ADMIN_PIN) ); assert_any_ok!(device.authenticate_admin(ADMIN_NEW_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, - device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD) + device.change_admin_pin(DEFAULT_ADMIN_PIN, DEFAULT_ADMIN_PIN) ); assert_ok!( (), - device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD) + device.change_admin_pin(ADMIN_NEW_PASSWORD, DEFAULT_ADMIN_PIN) ); - assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); assert_cmd_err!( CommandError::WrongPassword, device.authenticate_admin(ADMIN_NEW_PASSWORD) @@ -220,46 +225,55 @@ fn require_failed_user_login(device: &mut D, password: #[test_device] fn unlock_user_pin(device: DeviceWrapper) { let mut device = device; - assert_any_ok!(device.authenticate_user(USER_PASSWORD)); - assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); + assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); + assert_ok!( + (), + device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN) + ); assert_cmd_err!( CommandError::WrongPassword, - device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) + device.unlock_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN) ); // block user PIN - let wrong_password = USER_PASSWORD.to_owned() + "foo"; + let wrong_password = DEFAULT_USER_PIN.to_owned() + "foo"; require_failed_user_login(&mut device, &wrong_password); require_failed_user_login(&mut device, &wrong_password); require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, USER_PASSWORD); + require_failed_user_login(&mut device, DEFAULT_USER_PIN); // unblock with current PIN assert_cmd_err!( CommandError::WrongPassword, - device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) + device.unlock_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN) ); - assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); - assert_any_ok!(device.authenticate_user(USER_PASSWORD)); + assert_ok!( + (), + device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN) + ); + assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); // block user PIN require_failed_user_login(&mut device, &wrong_password); require_failed_user_login(&mut device, &wrong_password); require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, USER_PASSWORD); + require_failed_user_login(&mut device, DEFAULT_USER_PIN); // unblock with new PIN assert_cmd_err!( CommandError::WrongPassword, - device.unlock_user_pin(USER_PASSWORD, USER_PASSWORD) + device.unlock_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN) ); assert_ok!( (), - device.unlock_user_pin(ADMIN_PASSWORD, USER_NEW_PASSWORD) + device.unlock_user_pin(DEFAULT_ADMIN_PIN, USER_NEW_PASSWORD) ); // reset user PIN - assert_ok!((), device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD)); + assert_ok!( + (), + device.change_user_pin(USER_NEW_PASSWORD, DEFAULT_USER_PIN) + ); } fn assert_utf8_err_or_ne(left: &str, right: Result) { @@ -273,18 +287,21 @@ fn assert_utf8_err_or_ne(left: &str, right: Result) { #[test_device] fn factory_reset(device: DeviceWrapper) { let mut device = device; - let mut admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + let mut admin = unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); let otp_data = OtpSlotData::new(1, "test", "0123468790", OtpMode::SixDigits); assert_ok!((), admin.write_totp_slot(otp_data, 30)); - let mut pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + let mut pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); - assert_ok!((), device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD)); assert_ok!( (), - device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD) + device.change_user_pin(DEFAULT_USER_PIN, USER_NEW_PASSWORD) + ); + assert_ok!( + (), + device.change_admin_pin(DEFAULT_ADMIN_PIN, ADMIN_NEW_PASSWORD) ); assert_cmd_err!( @@ -293,40 +310,40 @@ fn factory_reset(device: DeviceWrapper) { ); assert_cmd_err!( CommandError::WrongPassword, - device.factory_reset(ADMIN_PASSWORD) + device.factory_reset(DEFAULT_ADMIN_PIN) ); assert_ok!((), device.factory_reset(ADMIN_NEW_PASSWORD)); - assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); - let user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); + let user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); assert_cmd_err!(CommandError::SlotNotProgrammed, user.get_totp_slot_name(1)); - let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + let pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); drop(pws); - assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); + assert_ok!((), device.build_aes_key(DEFAULT_ADMIN_PIN)); } #[test_device] fn build_aes_key(device: DeviceWrapper) { let mut device = device; - let mut pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + let mut pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); assert_cmd_err!( CommandError::WrongPassword, - device.build_aes_key(USER_PASSWORD) + device.build_aes_key(DEFAULT_USER_PIN) ); - assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); + assert_ok!((), device.build_aes_key(DEFAULT_ADMIN_PIN)); - assert_any_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); - let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + let pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); @@ -356,7 +373,7 @@ fn encrypted_volume(device: Storage) { device.enable_encrypted_volume("123") ); assert_eq!(1, count_nitrokey_block_devices()); - assert_ok!((), device.enable_encrypted_volume(USER_PASSWORD)); + assert_ok!((), device.enable_encrypted_volume(DEFAULT_USER_PIN)); assert_eq!(2, count_nitrokey_block_devices()); assert_ok!((), device.disable_encrypted_volume()); assert_eq!(1, count_nitrokey_block_devices()); @@ -371,7 +388,7 @@ fn hidden_volume(device: Storage) { assert_ok!((), device.disable_hidden_volume()); assert_eq!(1, count_nitrokey_block_devices()); - assert_ok!((), device.enable_encrypted_volume(USER_PASSWORD)); + assert_ok!((), device.enable_encrypted_volume(DEFAULT_USER_PIN)); assert_eq!(2, count_nitrokey_block_devices()); // TODO: why this error code? @@ -401,7 +418,7 @@ fn hidden_volume(device: Storage) { #[test_device] fn lock(device: Storage) { let mut device = device; - assert_ok!((), device.enable_encrypted_volume(USER_PASSWORD)); + assert_ok!((), device.enable_encrypted_volume(DEFAULT_USER_PIN)); assert_ok!((), device.lock()); assert_eq!(1, count_nitrokey_block_devices()); } @@ -414,26 +431,26 @@ fn set_encrypted_volume_mode(device: Storage) { assert_ok!( (), - device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) + device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) ); // TODO: re-enable once the password is checked in the firmware // assert_cmd_err!( // CommandError::WrongPassword, - // device.set_encrypted_volume_mode(USER_PASSWORD, VolumeMode::ReadOnly) + // device.set_encrypted_volume_mode(DEFAULT_USER_PIN, VolumeMode::ReadOnly) // ); assert_ok!( (), - device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) + device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) ); assert_ok!( (), - device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadWrite) + device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadWrite) ); assert_ok!( (), - device.set_encrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) + device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) ); } @@ -448,7 +465,10 @@ fn set_unencrypted_volume_mode(device: Storage) { } fn assert_success(device: &mut Storage, mode: VolumeMode) { - assert_ok!((), device.set_unencrypted_volume_mode(ADMIN_PASSWORD, mode)); + assert_ok!( + (), + device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, mode) + ); assert_mode(&device, mode); } @@ -457,7 +477,7 @@ fn set_unencrypted_volume_mode(device: Storage) { assert_cmd_err!( CommandError::WrongPassword, - device.set_unencrypted_volume_mode(USER_PASSWORD, VolumeMode::ReadOnly) + device.set_unencrypted_volume_mode(DEFAULT_USER_PIN, VolumeMode::ReadOnly) ); assert_mode(&device, VolumeMode::ReadOnly); @@ -496,9 +516,9 @@ fn get_production_info(device: Storage) { #[test_device] fn clear_new_sd_card_warning(device: Storage) { let mut device = device; - assert_ok!((), device.factory_reset(ADMIN_PASSWORD)); + assert_ok!((), device.factory_reset(DEFAULT_ADMIN_PIN)); thread::sleep(time::Duration::from_secs(3)); - assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); + assert_ok!((), device.build_aes_key(DEFAULT_ADMIN_PIN)); // We have to perform an SD card operation to reset the new_sd_card_found field assert_ok!((), device.lock()); @@ -506,7 +526,7 @@ fn clear_new_sd_card_warning(device: Storage) { let status = unwrap_ok!(device.get_status()); assert!(status.new_sd_card_found); - assert_ok!((), device.clear_new_sd_card_warning(ADMIN_PASSWORD)); + assert_ok!((), device.clear_new_sd_card_warning(DEFAULT_ADMIN_PIN)); let status = unwrap_ok!(device.get_status()); assert!(!status.new_sd_card_found); @@ -519,14 +539,14 @@ fn export_firmware(device: Storage) { CommandError::WrongPassword, device.export_firmware("someadminpn") ); - assert_ok!((), device.export_firmware(ADMIN_PASSWORD)); + assert_ok!((), device.export_firmware(DEFAULT_ADMIN_PIN)); assert_ok!( (), - device.set_unencrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadWrite) + device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadWrite) ); - assert_ok!((), device.export_firmware(ADMIN_PASSWORD)); + assert_ok!((), device.export_firmware(DEFAULT_ADMIN_PIN)); assert_ok!( (), - device.set_unencrypted_volume_mode(ADMIN_PASSWORD, VolumeMode::ReadOnly) + device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) ); } diff --git a/tests/otp.rs b/tests/otp.rs index 8ca8311..d55d54a 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -7,12 +7,10 @@ use std::ops::DerefMut; use nitrokey::{ Admin, Authenticate, CommandError, Config, ConfigureOtp, Device, GenerateOtp, LibraryError, - OtpMode, OtpSlotData, + OtpMode, OtpSlotData, DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN, }; use nitrokey_test::test as test_device; -use crate::util::{ADMIN_PASSWORD, USER_PASSWORD}; - // test suite according to RFC 4226, Appendix D static HOTP_SECRET: &str = "3132333435363738393031323334353637383930"; static HOTP_CODES: &[&str] = &[ @@ -41,7 +39,7 @@ fn make_admin_test_device<'a, T>(device: &'a mut T) -> Admin<'a, T> where T: Device, { - unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)) + unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)) } fn configure_hotp(admin: &mut ConfigureOtp, counter: u8) { @@ -91,7 +89,7 @@ fn hotp_pin(device: DeviceWrapper) { assert_ok!((), admin.write_config(config)); configure_hotp(&mut admin, 0); - let mut user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); check_hotp_codes(&mut user, 0); assert_cmd_err!(CommandError::NotAuthorized, user.get_hotp_code(1)); @@ -219,7 +217,7 @@ fn totp_pin(device: DeviceWrapper) { assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(device.authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); check_totp_codes(&mut user, 1, TotpTimestampSize::U32); assert_cmd_err!(CommandError::NotAuthorized, user.get_totp_code(1)); @@ -234,7 +232,7 @@ fn totp_pin_64(device: Pro) { assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(admin.authenticate_user(USER_PASSWORD)); + let mut user = unwrap_ok!(admin.authenticate_user(DEFAULT_USER_PIN)); check_totp_codes(&mut user, 1, TotpTimestampSize::U64); assert_cmd_err!(CommandError::NotAuthorized, device.get_totp_code(1)); diff --git a/tests/pws.rs b/tests/pws.rs index 7805803..b0e5abe 100644 --- a/tests/pws.rs +++ b/tests/pws.rs @@ -7,13 +7,12 @@ use std::ffi::CStr; use libc::{c_int, c_void, free}; use nitrokey::{ - CommandError, Device, Error, GetPasswordSafe, LibraryError, PasswordSafe, SLOT_COUNT, + CommandError, Device, Error, GetPasswordSafe, LibraryError, PasswordSafe, DEFAULT_ADMIN_PIN, + DEFAULT_USER_PIN, SLOT_COUNT, }; use nitrokey_sys; use nitrokey_test::test as test_device; -use crate::util::{ADMIN_PASSWORD, USER_PASSWORD}; - fn get_slot_name_direct(slot: u8) -> Result { let ptr = unsafe { nitrokey_sys::NK_get_password_safe_slot_name(slot) }; if ptr.is_null() { @@ -37,7 +36,7 @@ fn get_pws(device: &mut T) -> PasswordSafe where T: Device, { - unwrap_ok!(device.get_password_safe(USER_PASSWORD)) + unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)) } #[test_device] @@ -45,14 +44,14 @@ fn enable(device: DeviceWrapper) { let mut device = device; assert_cmd_err!( CommandError::WrongPassword, - device.get_password_safe(&(USER_PASSWORD.to_owned() + "123")) + device.get_password_safe(&(DEFAULT_USER_PIN.to_owned() + "123")) ); - assert_any_ok!(device.get_password_safe(USER_PASSWORD)); + assert_any_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_cmd_err!( CommandError::WrongPassword, - device.get_password_safe(ADMIN_PASSWORD) + device.get_password_safe(DEFAULT_ADMIN_PIN) ); - assert_any_ok!(device.get_password_safe(USER_PASSWORD)); + assert_any_ok!(device.get_password_safe(DEFAULT_USER_PIN)); } #[test_device] diff --git a/tests/util/mod.rs b/tests/util/mod.rs index f80372d..5bd19d1 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -1,11 +1,6 @@ // Copyright (C) 2018-2019 Robin Krahl // SPDX-License-Identifier: MIT -#[allow(dead_code)] -pub static ADMIN_PASSWORD: &str = "12345678"; -#[allow(dead_code)] -pub static USER_PASSWORD: &str = "123456"; - #[macro_export] macro_rules! unwrap_ok { ($val:expr) => { -- cgit v1.2.3 From 83641ca0518e4c766c63e40d0787e4f0b436652a Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 5 Feb 2019 12:47:24 +0000 Subject: Revert "Refactor User and Admin to use a mutable reference" This reverts commit 0972bbe82623c3d9649b6023d8f50d304aa0cde6. --- CHANGELOG.md | 4 -- src/auth.rs | 183 ++++++++++++++++++++++++++++++++++++++---------------- src/device.rs | 42 +++++++++---- src/lib.rs | 4 +- src/otp.rs | 16 ++--- tests/device.rs | 152 ++++++++++++++++++++++----------------------- tests/otp.rs | 62 +++++++++--------- tests/util/mod.rs | 12 ++-- 8 files changed, 277 insertions(+), 198 deletions(-) (limited to 'tests/util') diff --git a/CHANGELOG.md b/CHANGELOG.md index 9227510..e98e857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,10 +38,6 @@ SPDX-License-Identifier: MIT - Implement `DerefMut` for `User` and `Admin`. - Add `device_mut` method to `DeviceWrapper`. - Require a mutable `Device` reference if a method changes the device state. -- Let `Admin` and `User` store a mutable reference to the `Device` instead of - the `Device` value. -- Let `PasswordStore` store a mutable reference to the `Device` instead of a - non-mutable reference. # v0.3.4 (2019-01-20) - Fix authentication methods that assumed that `char` is signed. diff --git a/src/auth.rs b/src/auth.rs index 573fed3..f9f50fa 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -42,10 +42,16 @@ pub trait Authenticate { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; - /// match device.authenticate_user("123456") { - /// Ok(user) => perform_user_task(&user), - /// Err(err) => eprintln!("Could not authenticate as user: {}", err), + /// let device = nitrokey::connect()?; + /// let device = match device.authenticate_user("123456") { + /// Ok(user) => { + /// perform_user_task(&user); + /// user.device() + /// }, + /// Err((device, err)) => { + /// eprintln!("Could not authenticate as user: {}", err); + /// device + /// }, /// }; /// perform_other_task(&device); /// # Ok(()) @@ -55,9 +61,9 @@ pub trait Authenticate { /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn authenticate_user(&mut self, password: &str) -> Result, Error> + fn authenticate_user(self, password: &str) -> Result, (Self, Error)> where - Self: Device + std::marker::Sized; + Self: Device + Sized; /// Performs admin authentication. This method consumes the device. If successful, an /// authenticated device is returned. Otherwise, the current unauthenticated device and the @@ -82,10 +88,16 @@ pub trait Authenticate { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; - /// match device.authenticate_admin("123456") { - /// Ok(admin) => perform_admin_task(&admin), - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// let device = nitrokey::connect()?; + /// let device = match device.authenticate_admin("123456") { + /// Ok(admin) => { + /// perform_admin_task(&admin); + /// admin.device() + /// }, + /// Err((device, err)) => { + /// eprintln!("Could not authenticate as admin: {}", err); + /// device + /// }, /// }; /// perform_other_task(&device); /// # Ok(()) @@ -95,13 +107,13 @@ pub trait Authenticate { /// [`InvalidString`]: enum.LibraryError.html#variant.InvalidString /// [`RngError`]: enum.CommandError.html#variant.RngError /// [`WrongPassword`]: enum.CommandError.html#variant.WrongPassword - fn authenticate_admin(&mut self, password: &str) -> Result, Error> + fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> where - Self: Device + std::marker::Sized; + Self: Device + Sized; } -trait AuthenticatedDevice<'a, T> { - fn new(device: &'a mut T, temp_password: Vec) -> Self; +trait AuthenticatedDevice { + fn new(device: T, temp_password: Vec) -> Self; fn temp_password_ptr(&self) -> *const c_char; } @@ -116,8 +128,8 @@ trait AuthenticatedDevice<'a, T> { /// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin /// [`device`]: #method.device #[derive(Debug)] -pub struct User<'a, T: Device> { - device: &'a mut T, +pub struct User { + device: T, temp_password: Vec, } @@ -131,42 +143,89 @@ pub struct User<'a, T: Device> { /// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin /// [`device`]: #method.device #[derive(Debug)] -pub struct Admin<'a, T: Device> { - device: &'a mut T, +pub struct Admin { + device: T, temp_password: Vec, } -fn authenticate<'a, D, A, T>(device: &'a mut D, password: &str, callback: T) -> Result +fn authenticate(device: D, password: &str, callback: T) -> Result where D: Device, - A: AuthenticatedDevice<'a, D>, + A: AuthenticatedDevice, T: Fn(*const c_char, *const c_char) -> c_int, { - let temp_password = generate_password(TEMPORARY_PASSWORD_LENGTH)?; - let password = get_cstring(password)?; + let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) { + Ok(temp_password) => temp_password, + Err(err) => return Err((device, err)), + }; + let password = match get_cstring(password) { + Ok(password) => password, + Err(err) => return Err((device, err)), + }; let password_ptr = password.as_ptr(); let temp_password_ptr = temp_password.as_ptr() as *const c_char; match callback(password_ptr, temp_password_ptr) { 0 => Ok(A::new(device, temp_password)), - rv => Err(Error::from(rv)), + rv => Err((device, Error::from(rv))), } } -impl<'a, T: Device> ops::Deref for User<'a, T> { +fn authenticate_user_wrapper( + device: T, + constructor: C, + password: &str, +) -> Result, (DeviceWrapper, Error)> +where + T: Device, + C: Fn(T) -> DeviceWrapper, +{ + let result = device.authenticate_user(password); + match result { + Ok(user) => Ok(User::new(constructor(user.device), user.temp_password)), + Err((device, err)) => Err((constructor(device), err)), + } +} + +fn authenticate_admin_wrapper( + device: T, + constructor: C, + password: &str, +) -> Result, (DeviceWrapper, Error)> +where + T: Device, + C: Fn(T) -> DeviceWrapper, +{ + let result = device.authenticate_admin(password); + match result { + Ok(user) => Ok(Admin::new(constructor(user.device), user.temp_password)), + Err((device, err)) => Err((constructor(device), err)), + } +} + +impl User { + /// Forgets the user authentication and returns an unauthenticated device. This method + /// consumes the authenticated device. It does not perform any actual commands on the + /// Nitrokey. + pub fn device(self) -> T { + self.device + } +} + +impl ops::Deref for User { type Target = T; fn deref(&self) -> &Self::Target { - self.device + &self.device } } -impl<'a, T: Device> ops::DerefMut for User<'a, T> { +impl ops::DerefMut for User { fn deref_mut(&mut self) -> &mut T { - self.device + &mut self.device } } -impl<'a, T: Device> GenerateOtp for User<'a, T> { +impl GenerateOtp for User { fn get_hotp_code(&mut self, slot: u8) -> Result { result_from_string(unsafe { nitrokey_sys::NK_get_hotp_code_PIN(slot, self.temp_password_ptr()) @@ -180,8 +239,8 @@ impl<'a, T: Device> GenerateOtp for User<'a, T> { } } -impl<'a, T: Device> AuthenticatedDevice<'a, T> for User<'a, T> { - fn new(device: &'a mut T, temp_password: Vec) -> Self { +impl AuthenticatedDevice for User { + fn new(device: T, temp_password: Vec) -> Self { User { device, temp_password, @@ -193,21 +252,28 @@ impl<'a, T: Device> AuthenticatedDevice<'a, T> for User<'a, T> { } } -impl<'a, T: Device> ops::Deref for Admin<'a, T> { +impl ops::Deref for Admin { type Target = T; fn deref(&self) -> &Self::Target { - self.device + &self.device } } -impl<'a, T: Device> ops::DerefMut for Admin<'a, T> { +impl ops::DerefMut for Admin { fn deref_mut(&mut self) -> &mut T { - self.device + &mut self.device } } -impl<'a, T: Device> Admin<'a, T> { +impl Admin { + /// Forgets the user authentication and returns an unauthenticated device. This method + /// consumes the authenticated device. It does not perform any actual commands on the + /// Nitrokey. + pub fn device(self) -> T { + self.device + } + /// Writes the given configuration to the Nitrokey device. /// /// # Errors @@ -221,11 +287,14 @@ impl<'a, T: Device> Admin<'a, T> { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let device = nitrokey::connect()?; /// let config = Config::new(None, None, None, false); /// match device.authenticate_admin("12345678") { - /// Ok(mut admin) => admin.write_config(config)?, - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// Ok(mut admin) => { + /// admin.write_config(config); + /// () + /// }, + /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), /// }; /// # Ok(()) /// # } @@ -247,7 +316,7 @@ impl<'a, T: Device> Admin<'a, T> { } } -impl<'a, T: Device> ConfigureOtp for Admin<'a, T> { +impl ConfigureOtp for Admin { fn write_hotp_slot(&mut self, data: OtpSlotData, counter: u64) -> Result<(), Error> { let raw_data = RawOtpSlotData::new(data)?; get_command_result(unsafe { @@ -295,8 +364,8 @@ impl<'a, T: Device> ConfigureOtp for Admin<'a, T> { } } -impl<'a, T: Device> AuthenticatedDevice<'a, T> for Admin<'a, T> { - fn new(device: &'a mut T, temp_password: Vec) -> Self { +impl AuthenticatedDevice for Admin { + fn new(device: T, temp_password: Vec) -> Self { Admin { device, temp_password, @@ -309,27 +378,35 @@ impl<'a, T: Device> AuthenticatedDevice<'a, T> for Admin<'a, T> { } impl Authenticate for DeviceWrapper { - fn authenticate_user(&mut self, password: &str) -> Result, Error> { - authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { - nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) - }) + fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { + match self { + DeviceWrapper::Storage(storage) => { + authenticate_user_wrapper(storage, DeviceWrapper::Storage, password) + } + DeviceWrapper::Pro(pro) => authenticate_user_wrapper(pro, DeviceWrapper::Pro, password), + } } - fn authenticate_admin(&mut self, password: &str) -> Result, Error> { - authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { - nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) - }) + fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { + match self { + DeviceWrapper::Storage(storage) => { + authenticate_admin_wrapper(storage, DeviceWrapper::Storage, password) + } + DeviceWrapper::Pro(pro) => { + authenticate_admin_wrapper(pro, DeviceWrapper::Pro, password) + } + } } } impl Authenticate for Pro { - fn authenticate_user(&mut self, password: &str) -> Result, Error> { + fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) }) } - fn authenticate_admin(&mut self, password: &str) -> Result, Error> { + fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr) }) @@ -337,13 +414,13 @@ impl Authenticate for Pro { } impl Authenticate for Storage { - fn authenticate_user(&mut self, password: &str) -> Result, Error> { + fn authenticate_user(self, password: &str) -> Result, (Self, Error)> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_user_authenticate(password_ptr, temp_password_ptr) }) } - fn authenticate_admin(&mut self, password: &str) -> Result, Error> { + fn authenticate_admin(self, password: &str) -> Result, (Self, Error)> { authenticate(self, password, |password_ptr, temp_password_ptr| unsafe { nitrokey_sys::NK_first_authenticate(password_ptr, temp_password_ptr) }) diff --git a/src/device.rs b/src/device.rs index a0df30e..f6492cd 100644 --- a/src/device.rs +++ b/src/device.rs @@ -71,10 +71,16 @@ impl fmt::Display for VolumeMode { /// fn perform_other_task(device: &DeviceWrapper) {} /// /// # fn try_main() -> Result<(), Error> { -/// let mut device = nitrokey::connect()?; -/// match device.authenticate_user("123456") { -/// Ok(user) => perform_user_task(&user), -/// Err(err) => eprintln!("Could not authenticate as user: {}", err), +/// let device = nitrokey::connect()?; +/// let device = match device.authenticate_user("123456") { +/// Ok(user) => { +/// perform_user_task(&user); +/// user.device() +/// }, +/// Err((device, err)) => { +/// eprintln!("Could not authenticate as user: {}", err); +/// device +/// }, /// }; /// perform_other_task(&device); /// # Ok(()) @@ -129,10 +135,16 @@ pub enum DeviceWrapper { /// fn perform_other_task(device: &Pro) {} /// /// # fn try_main() -> Result<(), Error> { -/// let mut device = nitrokey::Pro::connect()?; -/// match device.authenticate_user("123456") { -/// Ok(user) => perform_user_task(&user), -/// Err(err) => eprintln!("Could not authenticate as user: {}", err), +/// let device = nitrokey::Pro::connect()?; +/// let device = match device.authenticate_user("123456") { +/// Ok(user) => { +/// perform_user_task(&user); +/// user.device() +/// }, +/// Err((device, err)) => { +/// eprintln!("Could not authenticate as user: {}", err); +/// device +/// }, /// }; /// perform_other_task(&device); /// # Ok(()) @@ -169,10 +181,16 @@ pub struct Pro { /// fn perform_other_task(device: &Storage) {} /// /// # fn try_main() -> Result<(), Error> { -/// let mut device = nitrokey::Storage::connect()?; -/// match device.authenticate_user("123456") { -/// Ok(user) => perform_user_task(&user), -/// Err(err) => eprintln!("Could not authenticate as user: {}", err), +/// let device = nitrokey::Storage::connect()?; +/// let device = match device.authenticate_user("123456") { +/// Ok(user) => { +/// perform_user_task(&user); +/// user.device() +/// }, +/// Err((device, err)) => { +/// eprintln!("Could not authenticate as user: {}", err); +/// device +/// }, /// }; /// perform_other_task(&device); /// # Ok(()) diff --git a/src/lib.rs b/src/lib.rs index d7a8c5e..c35829c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,7 @@ //! # use nitrokey::Error; //! //! # fn try_main() -> Result<(), Error> { -//! let mut device = nitrokey::connect()?; +//! let device = nitrokey::connect()?; //! let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); //! match device.authenticate_admin("12345678") { //! Ok(mut admin) => { @@ -53,7 +53,7 @@ //! Err(err) => eprintln!("Could not write slot: {}", err), //! } //! }, -//! Err(err) => eprintln!("Could not authenticate as admin: {}", err), +//! Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), //! } //! # Ok(()) //! # } diff --git a/src/otp.rs b/src/otp.rs index a8dd20b..ee142c7 100644 --- a/src/otp.rs +++ b/src/otp.rs @@ -35,7 +35,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::SixDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -44,7 +44,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -71,7 +71,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let device = nitrokey::connect()?; /// let slot_data = OtpSlotData::new(1, "test", "01234567890123456689", OtpMode::EightDigits); /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { @@ -80,7 +80,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not write slot: {}", err), /// } /// }, - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -104,7 +104,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_hotp_slot(1) { @@ -112,7 +112,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } @@ -134,7 +134,7 @@ pub trait ConfigureOtp { /// # use nitrokey::Error; /// /// # fn try_main() -> Result<(), Error> { - /// let mut device = nitrokey::connect()?; + /// let device = nitrokey::connect()?; /// match device.authenticate_admin("12345678") { /// Ok(mut admin) => { /// match admin.erase_totp_slot(1) { @@ -142,7 +142,7 @@ pub trait ConfigureOtp { /// Err(err) => eprintln!("Could not erase slot: {}", err), /// } /// }, - /// Err(err) => eprintln!("Could not authenticate as admin: {}", err), + /// Err((_, err)) => eprintln!("Could not authenticate as admin: {}", err), /// } /// # Ok(()) /// # } diff --git a/tests/device.rs b/tests/device.rs index ecc3cfa..6a3683b 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -97,34 +97,41 @@ fn get_firmware_version(device: Pro) { assert!(version.minor > 0); } -fn admin_retry(device: &mut T, suffix: &str, count: u8) { - assert_any_ok!(device.authenticate_admin(&(DEFAULT_ADMIN_PIN.to_owned() + suffix))); +fn admin_retry(device: T, suffix: &str, count: u8) -> T { + let result = device.authenticate_admin(&(DEFAULT_ADMIN_PIN.to_owned() + suffix)); + let device = match result { + Ok(admin) => admin.device(), + Err((device, _)) => device, + }; assert_ok!(count, device.get_admin_retry_count()); + return device; } -fn user_retry(device: &mut T, suffix: &str, count: u8) { - assert_any_ok!(device.authenticate_user(&(DEFAULT_USER_PIN.to_owned() + suffix))); +fn user_retry(device: T, suffix: &str, count: u8) -> T { + let result = device.authenticate_user(&(DEFAULT_USER_PIN.to_owned() + suffix)); + let device = match result { + Ok(admin) => admin.device(), + Err((device, _)) => device, + }; assert_ok!(count, device.get_user_retry_count()); + return device; } #[test_device] fn get_retry_count(device: DeviceWrapper) { - let mut device = device; - - admin_retry(&mut device, "", 3); - admin_retry(&mut device, "123", 2); - admin_retry(&mut device, "456", 1); - admin_retry(&mut device, "", 3); - - user_retry(&mut device, "", 3); - user_retry(&mut device, "123", 2); - user_retry(&mut device, "456", 1); - user_retry(&mut device, "", 3); + let device = admin_retry(device, "", 3); + let device = admin_retry(device, "123", 2); + let device = admin_retry(device, "456", 1); + let device = admin_retry(device, "", 3); + + let device = user_retry(device, "", 3); + let device = user_retry(device, "123", 2); + let device = user_retry(device, "456", 1); + user_retry(device, "", 3); } #[test_device] fn config(device: DeviceWrapper) { - let mut device = device; let mut admin = unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); let config = Config::new(None, None, None, true); @@ -145,24 +152,19 @@ fn config(device: DeviceWrapper) { #[test_device] fn change_user_pin(device: DeviceWrapper) { - let mut device = device; - assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_user(USER_NEW_PASSWORD) - ); + let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); + let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; - assert_ok!( - (), - device.change_user_pin(DEFAULT_USER_PIN, USER_NEW_PASSWORD) - ); + let mut device = device; + assert_ok!((), device.change_user_pin(DEFAULT_USER_PIN, USER_NEW_PASSWORD)); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_user(DEFAULT_USER_PIN) - ); - assert_any_ok!(device.authenticate_user(USER_NEW_PASSWORD)); + let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap_err().0; + let device = device + .authenticate_user(USER_NEW_PASSWORD) + .unwrap() + .device(); + let mut device = device; let result = device.change_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN); assert_cmd_err!(CommandError::WrongPassword, result); @@ -171,32 +173,25 @@ fn change_user_pin(device: DeviceWrapper) { device.change_user_pin(USER_NEW_PASSWORD, DEFAULT_USER_PIN) ); - assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_user(USER_NEW_PASSWORD) - ); + let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); + assert!(device.authenticate_user(USER_NEW_PASSWORD).is_err()); } #[test_device] fn change_admin_pin(device: DeviceWrapper) { - let mut device = device; - assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_admin(ADMIN_NEW_PASSWORD) - ); + let device = device.authenticate_admin(DEFAULT_ADMIN_PIN).unwrap().device(); + let mut device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; assert_ok!( (), device.change_admin_pin(DEFAULT_ADMIN_PIN, ADMIN_NEW_PASSWORD) ); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_admin(DEFAULT_ADMIN_PIN) - ); - assert_any_ok!(device.authenticate_admin(ADMIN_NEW_PASSWORD)); + let device = device.authenticate_admin(DEFAULT_ADMIN_PIN).unwrap_err().0; + let mut device = device + .authenticate_admin(ADMIN_NEW_PASSWORD) + .unwrap() + .device(); assert_cmd_err!( CommandError::WrongPassword, @@ -208,28 +203,29 @@ fn change_admin_pin(device: DeviceWrapper) { device.change_admin_pin(ADMIN_NEW_PASSWORD, DEFAULT_ADMIN_PIN) ); - assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_admin(ADMIN_NEW_PASSWORD) - ); + let device = device.authenticate_admin(DEFAULT_ADMIN_PIN).unwrap().device(); + device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); } -fn require_failed_user_login(device: &mut D, password: &str) { - assert_cmd_err!( - CommandError::WrongPassword, - device.authenticate_user(password) - ); +fn require_failed_user_login(device: D, password: &str, error: CommandError) -> D +where + D: Device + Authenticate, + nitrokey::User: std::fmt::Debug, +{ + let result = device.authenticate_user(password); + assert!(result.is_err()); + let err = result.unwrap_err(); + match err.1 { + Error::CommandError(err) => assert_eq!(error, err), + _ => assert!(false), + }; + err.0 } #[test_device] fn unlock_user_pin(device: DeviceWrapper) { - let mut device = device; - assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); - assert_ok!( - (), - device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN) - ); + let mut device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); + assert_ok!((), device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN)); assert_cmd_err!( CommandError::WrongPassword, device.unlock_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN) @@ -237,27 +233,24 @@ fn unlock_user_pin(device: DeviceWrapper) { // block user PIN let wrong_password = DEFAULT_USER_PIN.to_owned() + "foo"; - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, DEFAULT_USER_PIN); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let mut device = require_failed_user_login(device, DEFAULT_USER_PIN, CommandError::WrongPassword); // unblock with current PIN assert_cmd_err!( CommandError::WrongPassword, device.unlock_user_pin(DEFAULT_USER_PIN, DEFAULT_USER_PIN) ); - assert_ok!( - (), - device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN) - ); - assert_any_ok!(device.authenticate_user(DEFAULT_USER_PIN)); + assert_ok!((), device.unlock_user_pin(DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN)); + let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); // block user PIN - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, &wrong_password); - require_failed_user_login(&mut device, DEFAULT_USER_PIN); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let device = require_failed_user_login(device, &wrong_password, CommandError::WrongPassword); + let mut device = require_failed_user_login(device, DEFAULT_USER_PIN, CommandError::WrongPassword); // unblock with new PIN assert_cmd_err!( @@ -286,11 +279,11 @@ fn assert_utf8_err_or_ne(left: &str, right: Result) { #[test_device] fn factory_reset(device: DeviceWrapper) { - let mut device = device; let mut admin = unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); let otp_data = OtpSlotData::new(1, "test", "0123468790", OtpMode::SixDigits); assert_ok!((), admin.write_totp_slot(otp_data, 30)); + let mut device = admin.device(); let mut pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); @@ -314,11 +307,12 @@ fn factory_reset(device: DeviceWrapper) { ); assert_ok!((), device.factory_reset(ADMIN_NEW_PASSWORD)); - assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); + let device = device.authenticate_admin(DEFAULT_ADMIN_PIN).unwrap().device(); let user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); assert_cmd_err!(CommandError::SlotNotProgrammed, user.get_totp_slot_name(1)); + let mut device = user.device(); let pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); @@ -341,7 +335,7 @@ fn build_aes_key(device: DeviceWrapper) { ); assert_ok!((), device.build_aes_key(DEFAULT_ADMIN_PIN)); - assert_any_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); + let mut device = device.authenticate_admin(DEFAULT_ADMIN_PIN).unwrap().device(); let pws = unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); diff --git a/tests/otp.rs b/tests/otp.rs index d55d54a..c0bbecf 100644 --- a/tests/otp.rs +++ b/tests/otp.rs @@ -3,6 +3,7 @@ mod util; +use std::fmt::Debug; use std::ops::DerefMut; use nitrokey::{ @@ -35,9 +36,10 @@ enum TotpTimestampSize { U64, } -fn make_admin_test_device<'a, T>(device: &'a mut T) -> Admin<'a, T> +fn make_admin_test_device(device: T) -> Admin where T: Device, + (T, nitrokey::Error): Debug, { unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)) } @@ -66,8 +68,7 @@ fn set_time(device: DeviceWrapper) { #[test_device] fn hotp_no_pin(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -78,38 +79,36 @@ fn hotp_no_pin(device: DeviceWrapper) { check_hotp_codes(admin.deref_mut(), 5); configure_hotp(&mut admin, 0); - check_hotp_codes(&mut device, 0); + check_hotp_codes(&mut admin.device(), 0); } #[test_device] fn hotp_pin(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_hotp(&mut admin, 0); - let mut user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); + let mut user = unwrap_ok!(admin.device().authenticate_user(DEFAULT_USER_PIN)); check_hotp_codes(&mut user, 0); - assert_cmd_err!(CommandError::NotAuthorized, user.get_hotp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_hotp_code(1)); } #[test_device] fn hotp_slot_name(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let slot_data = OtpSlotData::new(1, "test-hotp", HOTP_SECRET, OtpMode::SixDigits); assert_ok!((), admin.write_hotp_slot(slot_data, 0)); + let device = admin.device(); assert_ok!("test-hotp".to_string(), device.get_hotp_slot_name(1)); assert_lib_err!(LibraryError::InvalidSlot, device.get_hotp_slot_name(4)); } #[test_device] fn hotp_error(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let slot_data = OtpSlotData::new(1, "", HOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_hotp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(4, "test", HOTP_SECRET, OtpMode::SixDigits); @@ -128,8 +127,7 @@ fn hotp_error(device: DeviceWrapper) { #[test_device] fn hotp_erase(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); let slot_data = OtpSlotData::new(1, "test1", HOTP_SECRET, OtpMode::SixDigits); @@ -139,6 +137,7 @@ fn hotp_erase(device: DeviceWrapper) { assert_ok!((), admin.erase_hotp_slot(1)); + let mut device = admin.device(); let result = device.get_hotp_slot_name(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); let result = device.get_hotp_code(1); @@ -175,8 +174,7 @@ fn check_totp_codes(device: &mut GenerateOtp, factor: u64, timestamp_size: TotpT #[test_device] fn totp_no_pin(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -187,15 +185,14 @@ fn totp_no_pin(device: DeviceWrapper) { check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U32); configure_totp(&mut admin, 1); - check_totp_codes(&mut device, 1, TotpTimestampSize::U32); + check_totp_codes(&mut admin.device(), 1, TotpTimestampSize::U32); } #[test_device] // Nitrokey Storage does only support timestamps that fit in a 32-bit // unsigned integer, so don't test with it. fn totp_no_pin_64(device: Pro) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); @@ -206,45 +203,43 @@ fn totp_no_pin_64(device: Pro) { check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U64); configure_totp(&mut admin, 1); - check_totp_codes(&mut device, 1, TotpTimestampSize::U64); + check_totp_codes(&mut admin.device(), 1, TotpTimestampSize::U64); } #[test_device] fn totp_pin(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(device.authenticate_user(DEFAULT_USER_PIN)); + let mut user = unwrap_ok!(admin.device().authenticate_user(DEFAULT_USER_PIN)); check_totp_codes(&mut user, 1, TotpTimestampSize::U32); - assert_cmd_err!(CommandError::NotAuthorized, user.get_totp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); } #[test_device] // See comment for totp_no_pin_64. fn totp_pin_64(device: Pro) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); configure_totp(&mut admin, 1); - let mut user = unwrap_ok!(admin.authenticate_user(DEFAULT_USER_PIN)); + let mut user = unwrap_ok!(admin.device().authenticate_user(DEFAULT_USER_PIN)); check_totp_codes(&mut user, 1, TotpTimestampSize::U64); - assert_cmd_err!(CommandError::NotAuthorized, device.get_totp_code(1)); + assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); } #[test_device] fn totp_slot_name(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let slot_data = OtpSlotData::new(1, "test-totp", TOTP_SECRET, OtpMode::EightDigits); assert_ok!((), admin.write_totp_slot(slot_data, 0)); + let device = admin.device(); let result = device.get_totp_slot_name(1); assert_ok!("test-totp", result); let result = device.get_totp_slot_name(16); @@ -253,8 +248,7 @@ fn totp_slot_name(device: DeviceWrapper) { #[test_device] fn totp_error(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let slot_data = OtpSlotData::new(1, "", TOTP_SECRET, OtpMode::SixDigits); assert_cmd_err!(CommandError::NoName, admin.write_totp_slot(slot_data, 0)); let slot_data = OtpSlotData::new(20, "test", TOTP_SECRET, OtpMode::SixDigits); @@ -273,8 +267,7 @@ fn totp_error(device: DeviceWrapper) { #[test_device] fn totp_erase(device: DeviceWrapper) { - let mut device = device; - let mut admin = make_admin_test_device(&mut device); + let mut admin = make_admin_test_device(device); let config = Config::new(None, None, None, false); assert_ok!((), admin.write_config(config)); let slot_data = OtpSlotData::new(1, "test1", TOTP_SECRET, OtpMode::SixDigits); @@ -284,6 +277,7 @@ fn totp_erase(device: DeviceWrapper) { assert_ok!((), admin.erase_totp_slot(1)); + let device = admin.device(); let result = device.get_totp_slot_name(1); assert_cmd_err!(CommandError::SlotNotProgrammed, result); let result = device.get_totp_code(1); diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 5bd19d1..f2b20ec 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -3,7 +3,7 @@ #[macro_export] macro_rules! unwrap_ok { - ($val:expr) => { + ($val:expr) => {{ match $val { Ok(val) => val, Err(err) => panic!( @@ -13,12 +13,12 @@ macro_rules! unwrap_ok { err ), } - }; + }}; } #[macro_export] macro_rules! assert_any_ok { - ($val:expr) => { + ($val:expr) => {{ match &$val { Ok(_) => {} Err(err) => panic!( @@ -28,12 +28,12 @@ macro_rules! assert_any_ok { err ), } - }; + }}; } #[macro_export] macro_rules! assert_ok { - ($left:expr, $right:expr) => { + ($left:expr, $right:expr) => {{ match &$right { Ok(right) => match &$left { left => { @@ -54,7 +54,7 @@ macro_rules! assert_ok { $left, right_err ), } - }; + }}; } #[macro_export] -- cgit v1.2.3