From f49e61589e32217f97c94aa86d826f6b65170fba Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 28 Jan 2019 12:27:15 +0000 Subject: Require mutable reference if method changes device state Previously, all methods that access a Nitrokey device took a reference to the device as input. This method changes methods that change the device state to require a mutable reference instead. In most case, this is straightforward as the method writes data to the device (for example write_config or change_user_pin). But there are two edge cases: - Authenticating with a PIN changes the device state as it may decrease the PIN retry counter if the authentication fails. - Generating an HOTP code changes the device state as it increases the HOTP counter. --- tests/device.rs | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'tests/device.rs') diff --git a/tests/device.rs b/tests/device.rs index 969a7df..7a69214 100644 --- a/tests/device.rs +++ b/tests/device.rs @@ -133,7 +133,7 @@ fn get_retry_count(device: DeviceWrapper) { #[test_device] fn config(device: DeviceWrapper) { - let admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + let mut admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); let config = Config::new(None, None, None, true); assert_ok!((), admin.write_config(config)); @@ -156,6 +156,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; + let mut device = device; assert_ok!((), device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD)); let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0; @@ -164,6 +165,7 @@ fn change_user_pin(device: DeviceWrapper) { .unwrap() .device(); + let mut device = device; let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD); assert_cmd_err!(CommandError::WrongPassword, result); @@ -176,7 +178,7 @@ fn change_user_pin(device: DeviceWrapper) { #[test_device] 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; + let mut device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0; assert_ok!( (), @@ -184,7 +186,7 @@ fn change_admin_pin(device: DeviceWrapper) { ); let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0; - let device = device + let mut device = device .authenticate_admin(ADMIN_NEW_PASSWORD) .unwrap() .device(); @@ -220,7 +222,7 @@ where #[test_device] fn unlock_user_pin(device: DeviceWrapper) { - let device = device.authenticate_user(USER_PASSWORD).unwrap().device(); + let mut device = device.authenticate_user(USER_PASSWORD).unwrap().device(); assert_ok!((), device.unlock_user_pin(ADMIN_PASSWORD, USER_PASSWORD)); assert_cmd_err!( CommandError::WrongPassword, @@ -232,7 +234,7 @@ fn unlock_user_pin(device: DeviceWrapper) { 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 device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); + let mut device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); // unblock with current PIN assert_cmd_err!( @@ -246,7 +248,7 @@ fn unlock_user_pin(device: DeviceWrapper) { 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 device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); + let mut device = require_failed_user_login(device, USER_PASSWORD, CommandError::WrongPassword); // unblock with new PIN assert_cmd_err!( @@ -272,12 +274,12 @@ fn assert_utf8_err_or_ne(left: &str, right: Result) { #[test_device] fn factory_reset(device: DeviceWrapper) { - let admin = unwrap_ok!(device.authenticate_admin(ADMIN_PASSWORD)); + 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 device = admin.device(); - let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + 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); @@ -302,18 +304,20 @@ fn factory_reset(device: DeviceWrapper) { 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 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)); assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); + drop(pws); assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); } #[test_device] fn build_aes_key(device: DeviceWrapper) { - let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); + let mut device = device; + let mut pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); drop(pws); @@ -323,7 +327,7 @@ fn build_aes_key(device: DeviceWrapper) { ); assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); - let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); + let mut device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device(); let pws = unwrap_ok!(device.get_password_safe(USER_PASSWORD)); assert_utf8_err_or_ne("test", pws.get_slot_name(0)); @@ -333,6 +337,7 @@ fn build_aes_key(device: DeviceWrapper) { #[test_device] fn change_update_pin(device: Storage) { + let mut device = device; assert_cmd_err!( CommandError::WrongPassword, device.change_update_pin(UPDATE_NEW_PIN, UPDATE_PIN) @@ -343,6 +348,7 @@ fn change_update_pin(device: Storage) { #[test_device] fn encrypted_volume(device: Storage) { + let mut device = device; assert_ok!((), device.lock()); assert_eq!(1, count_nitrokey_block_devices()); @@ -361,6 +367,7 @@ fn encrypted_volume(device: Storage) { #[test_device] fn hidden_volume(device: Storage) { + let mut device = device; assert_ok!((), device.lock()); assert_eq!(1, count_nitrokey_block_devices()); @@ -396,6 +403,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.lock()); assert_eq!(1, count_nitrokey_block_devices()); @@ -405,6 +413,7 @@ fn lock(device: Storage) { fn set_encrypted_volume_mode(device: Storage) { // This test case does not check the device status as the command only works with firmware // version 0.49. For later versions, it does not do anything and always returns Ok(()). + let mut device = device; assert_ok!( (), @@ -441,12 +450,13 @@ fn set_unencrypted_volume_mode(device: Storage) { ); } - fn assert_success(device: &Storage, mode: VolumeMode) { + fn assert_success(device: &mut Storage, mode: VolumeMode) { assert_ok!((), device.set_unencrypted_volume_mode(ADMIN_PASSWORD, mode)); assert_mode(&device, mode); } - assert_success(&device, VolumeMode::ReadOnly); + let mut device = device; + assert_success(&mut device, VolumeMode::ReadOnly); assert_cmd_err!( CommandError::WrongPassword, @@ -454,9 +464,9 @@ fn set_unencrypted_volume_mode(device: Storage) { ); assert_mode(&device, VolumeMode::ReadOnly); - assert_success(&device, VolumeMode::ReadWrite); - assert_success(&device, VolumeMode::ReadWrite); - assert_success(&device, VolumeMode::ReadOnly); + assert_success(&mut device, VolumeMode::ReadWrite); + assert_success(&mut device, VolumeMode::ReadWrite); + assert_success(&mut device, VolumeMode::ReadOnly); } #[test_device] @@ -488,6 +498,7 @@ 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)); thread::sleep(time::Duration::from_secs(3)); assert_ok!((), device.build_aes_key(ADMIN_PASSWORD)); @@ -506,6 +517,7 @@ fn clear_new_sd_card_warning(device: Storage) { #[test_device] fn export_firmware(device: Storage) { + let mut device = device; assert_cmd_err!( CommandError::WrongPassword, device.export_firmware("someadminpn") -- cgit v1.2.1