From 7197f19f38b06fe2953cfba1fe755d4562f5786e Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 29 May 2018 20:49:40 +0000 Subject: Add support for password safes A password safe (PWS) stores names, logins and passwords in slots. PWS are supported both by the Nitrokey Pro and the Nitrokey Storage. They are implemented as a struct wrapping a device as the device may not be disconnected while the password safe is alive. The creation of a password safe is handled by the GetPasswordSafe trait, implemented by DeviceWrapper, Pro and Storage. --- src/tests/pws.rs | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/tests/pws.rs (limited to 'src/tests/pws.rs') diff --git a/src/tests/pws.rs b/src/tests/pws.rs new file mode 100644 index 0000000..5f5a325 --- /dev/null +++ b/src/tests/pws.rs @@ -0,0 +1,169 @@ +use util::{CommandError, CommandStatus}; +use pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; +use tests::util::{Target, ADMIN_PASSWORD, USER_PASSWORD}; + +fn get_pws() -> PasswordSafe { + Target::connect() + .unwrap() + .get_password_safe(USER_PASSWORD) + .unwrap() +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +fn enable() { + assert!( + Target::connect() + .unwrap() + .get_password_safe(&(USER_PASSWORD.to_owned() + "123")) + .is_err() + ); + assert!( + Target::connect() + .unwrap() + .get_password_safe(USER_PASSWORD) + .is_ok() + ); + assert!( + Target::connect() + .unwrap() + .get_password_safe(ADMIN_PASSWORD) + .is_err() + ); + assert!( + Target::connect() + .unwrap() + .get_password_safe(USER_PASSWORD) + .is_ok() + ); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +fn get_status() { + let pws = get_pws(); + for i in 0..SLOT_COUNT { + assert_eq!( + CommandStatus::Success, + pws.erase_slot(i), + "Could not erase slot {}", + i + ); + } + let status = pws.get_slot_status().unwrap(); + assert_eq!(status, [false; SLOT_COUNT as usize]); + + assert_eq!( + CommandStatus::Success, + pws.write_slot(1, "name", "login", "password") + ); + let status = pws.get_slot_status().unwrap(); + for i in 0..SLOT_COUNT { + assert_eq!(i == 1, status[i as usize]); + } + + for i in 0..SLOT_COUNT { + assert_eq!( + CommandStatus::Success, + pws.write_slot(i, "name", "login", "password") + ); + } + let status = pws.get_slot_status().unwrap(); + assert_eq!(status, [true; SLOT_COUNT as usize]); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +fn get_data() { + let pws = get_pws(); + assert_eq!( + CommandStatus::Success, + 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_eq!(CommandStatus::Success, pws.erase_slot(1)); + // TODO: check error codes + assert_eq!(Err(CommandError::Unknown), pws.get_slot_name(1)); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_login(1)); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_password(1)); + + let name = "with å"; + let login = "pär@test.com"; + let password = "'i3lJc[09?I:,[u7dWz9"; + assert_eq!( + CommandStatus::Success, + 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_eq!( + Err(CommandError::InvalidSlot), + pws.get_slot_name(SLOT_COUNT) + ); + assert_eq!( + Err(CommandError::InvalidSlot), + pws.get_slot_login(SLOT_COUNT) + ); + assert_eq!( + Err(CommandError::InvalidSlot), + pws.get_slot_password(SLOT_COUNT) + ); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +fn write() { + let pws = get_pws(); + + assert_eq!( + CommandStatus::Error(CommandError::InvalidSlot), + pws.write_slot(SLOT_COUNT, "name", "login", "password") + ); + + assert_eq!( + CommandStatus::Success, + pws.write_slot(0, "", "login", "password") + ); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_name(0)); + assert_eq!(Ok(String::from("login")), pws.get_slot_login(0)); + assert_eq!(Ok(String::from("password")), pws.get_slot_password(0)); + + assert_eq!( + CommandStatus::Success, + pws.write_slot(0, "name", "", "password") + ); + assert_eq!(Ok(String::from("name")), pws.get_slot_name(0)); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_login(0)); + assert_eq!(Ok(String::from("password")), pws.get_slot_password(0)); + + assert_eq!( + CommandStatus::Success, + pws.write_slot(0, "name", "login", "") + ); + assert_eq!(Ok(String::from("name")), pws.get_slot_name(0)); + assert_eq!(Ok(String::from("login")), pws.get_slot_login(0)); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_password(0)); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +fn erase() { + let pws = get_pws(); + assert_eq!( + CommandStatus::Error(CommandError::InvalidSlot), + pws.erase_slot(SLOT_COUNT) + ); + + assert_eq!( + CommandStatus::Success, + pws.write_slot(0, "name", "login", "password") + ); + assert_eq!(CommandStatus::Success, pws.erase_slot(0)); + assert_eq!(CommandStatus::Success, pws.erase_slot(0)); + assert_eq!(Err(CommandError::Unknown), pws.get_slot_name(0)); +} -- cgit v1.2.1