diff options
Diffstat (limited to 'nitrokey/tests')
| -rw-r--r-- | nitrokey/tests/device.rs | 575 | ||||
| -rw-r--r-- | nitrokey/tests/lib.rs | 28 | ||||
| -rw-r--r-- | nitrokey/tests/otp.rs | 287 | ||||
| -rw-r--r-- | nitrokey/tests/pws.rs | 159 | ||||
| -rw-r--r-- | nitrokey/tests/util/mod.rs | 113 | 
5 files changed, 0 insertions, 1162 deletions
diff --git a/nitrokey/tests/device.rs b/nitrokey/tests/device.rs deleted file mode 100644 index e367558..0000000 --- a/nitrokey/tests/device.rs +++ /dev/null @@ -1,575 +0,0 @@ -// Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: MIT - -mod util; - -use std::ffi::CStr; -use std::process::Command; -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; - -static ADMIN_NEW_PASSWORD: &str = "1234567890"; -static UPDATE_PIN: &str = "12345678"; -static UPDATE_NEW_PIN: &str = "87654321"; -static USER_NEW_PASSWORD: &str = "abcdefghij"; - -fn count_nitrokey_block_devices() -> usize { -    thread::sleep(time::Duration::from_secs(2)); -    let output = Command::new("lsblk") -        .args(&["-o", "MODEL"]) -        .output() -        .expect("Could not list block devices"); -    String::from_utf8_lossy(&output.stdout) -        .split("\n") -        .filter(|&s| s.replace("_", " ") == "Nitrokey Storage") -        .count() -} - -#[test_device] -fn connect_no_device() { -    let mut manager = unwrap_ok!(nitrokey::take()); - -    assert_cmu_err!(CommunicationError::NotConnected, manager.connect()); -    assert_cmu_err!( -        CommunicationError::NotConnected, -        manager.connect_model(nitrokey::Model::Pro) -    ); -    assert_cmu_err!( -        CommunicationError::NotConnected, -        manager.connect_model(nitrokey::Model::Storage) -    ); -    assert_cmu_err!(CommunicationError::NotConnected, manager.connect_pro()); -    assert_cmu_err!(CommunicationError::NotConnected, manager.connect_storage()); -} - -#[test_device] -fn connect_pro(device: Pro) { -    assert_eq!(device.get_model(), nitrokey::Model::Pro); - -    let manager = device.into_manager(); -    assert_any_ok!(manager.connect()); -    assert_any_ok!(manager.connect_model(nitrokey::Model::Pro)); -    assert_any_ok!(manager.connect_pro()); -} - -#[test_device] -fn connect_storage(device: Storage) { -    assert_eq!(device.get_model(), nitrokey::Model::Storage); - -    let manager = device.into_manager(); -    assert_any_ok!(manager.connect()); -    assert_any_ok!(manager.connect_model(nitrokey::Model::Storage)); -    assert_any_ok!(manager.connect_storage()); -} - -fn assert_empty_serial_number() { -    unsafe { -        let ptr = nitrokey_sys::NK_device_serial_number(); -        assert!(!ptr.is_null()); -        let cstr = CStr::from_ptr(ptr); -        assert_eq!(cstr.to_string_lossy(), ""); -    } -} - -#[test_device] -fn disconnect(device: DeviceWrapper) { -    drop(device); -    assert_empty_serial_number(); -} - -#[test_device] -fn get_serial_number(device: DeviceWrapper) { -    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 = unwrap_ok!(device.get_firmware_version()); -    assert_eq!(0, version.major); -    assert!(version.minor > 0); -} - -fn admin_retry<'a, T>(device: T, suffix: &str, count: u8) -> T -where -    T: Authenticate<'a> + Device<'a> + 'a, -{ -    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<'a, T>(device: T, suffix: &str, count: u8) -> T -where -    T: Authenticate<'a> + Device<'a> + 'a, -{ -    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 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 admin = unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)); - -    let config = Config::new(None, None, None, true); -    assert_ok!((), admin.write_config(config)); -    assert_ok!(config, admin.get_config()); - -    let config = Config::new(None, Some(9), None, true); -    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)); -    assert_ok!(config, admin.get_config()); - -    let config = Config::new(None, None, None, false); -    assert_ok!((), admin.write_config(config)); -    assert_ok!(config, admin.get_config()); -} - -#[test_device] -fn change_user_pin(device: DeviceWrapper) { -    let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); -    let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0; - -    let mut device = device; -    assert_ok!( -        (), -        device.change_user_pin(DEFAULT_USER_PIN, 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); - -    assert_ok!( -        (), -        device.change_user_pin(USER_NEW_PASSWORD, DEFAULT_USER_PIN) -    ); - -    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 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) -    ); - -    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, -        device.change_admin_pin(DEFAULT_ADMIN_PIN, DEFAULT_ADMIN_PIN) -    ); - -    assert_ok!( -        (), -        device.change_admin_pin(ADMIN_NEW_PASSWORD, DEFAULT_ADMIN_PIN) -    ); - -    let device = device -        .authenticate_admin(DEFAULT_ADMIN_PIN) -        .unwrap() -        .device(); -    device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err(); -} - -fn require_failed_user_login<'a, D>(device: D, password: &str, error: CommandError) -> D -where -    D: Device<'a> + Authenticate<'a> + 'a, -    nitrokey::User<'a, D>: 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.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) -    ); - -    // block user PIN -    let wrong_password = DEFAULT_USER_PIN.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, 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) -    ); -    let device = device.authenticate_user(DEFAULT_USER_PIN).unwrap().device(); - -    // 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, DEFAULT_USER_PIN, CommandError::WrongPassword); - -    // unblock with new 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, USER_NEW_PASSWORD) -    ); - -    // reset user PIN -    assert_ok!( -        (), -        device.change_user_pin(USER_NEW_PASSWORD, DEFAULT_USER_PIN) -    ); -} - -fn assert_utf8_err_or_ne(left: &str, right: Result<String, Error>) { -    match right { -        Ok(s) => assert_ne!(left.to_string(), s), -        Err(Error::Utf8Error(_)) => {} -        Err(err) => panic!("Expected Utf8Error, got {}!", err), -    } -} - -#[test_device] -fn factory_reset(device: DeviceWrapper) { -    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); - -    assert_ok!( -        (), -        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!( -        CommandError::WrongPassword, -        device.factory_reset(USER_NEW_PASSWORD) -    ); -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.factory_reset(DEFAULT_ADMIN_PIN) -    ); -    assert_ok!((), device.factory_reset(ADMIN_NEW_PASSWORD)); - -    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)); -    assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); -    drop(pws); - -    assert_ok!(3, device.get_user_retry_count()); -    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(DEFAULT_USER_PIN)); -    assert_ok!((), pws.write_slot(0, "test", "testlogin", "testpw")); -    drop(pws); - -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.build_aes_key(DEFAULT_USER_PIN) -    ); -    assert_ok!((), device.build_aes_key(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)); -    assert_utf8_err_or_ne("testlogin", pws.get_slot_login(0)); -    assert_utf8_err_or_ne("testpw", pws.get_slot_password(0)); -} - -#[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) -    ); -    assert_ok!((), device.change_update_pin(UPDATE_PIN, UPDATE_NEW_PIN)); -    assert_ok!((), device.change_update_pin(UPDATE_NEW_PIN, UPDATE_PIN)); -} - -#[test_device] -fn encrypted_volume(device: Storage) { -    let mut device = device; -    assert_ok!((), device.lock()); - -    assert_eq!(1, count_nitrokey_block_devices()); -    assert_ok!((), device.disable_encrypted_volume()); -    assert_eq!(1, count_nitrokey_block_devices()); -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.enable_encrypted_volume("123") -    ); -    assert_eq!(1, count_nitrokey_block_devices()); -    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()); -} - -#[test_device] -fn hidden_volume(device: Storage) { -    let mut device = device; -    assert_ok!((), device.lock()); - -    assert_eq!(1, count_nitrokey_block_devices()); -    assert_ok!((), device.disable_hidden_volume()); -    assert_eq!(1, count_nitrokey_block_devices()); - -    assert_ok!((), device.enable_encrypted_volume(DEFAULT_USER_PIN)); -    assert_eq!(2, count_nitrokey_block_devices()); - -    // TODO: why this error code? -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.create_hidden_volume(5, 0, 100, "hiddenpw") -    ); -    assert_ok!((), device.create_hidden_volume(0, 20, 21, "hidden-pw")); -    assert_ok!((), device.create_hidden_volume(0, 20, 21, "hiddenpassword")); -    assert_ok!((), device.create_hidden_volume(1, 0, 1, "otherpw")); -    // TODO: test invalid range (not handled by libnitrokey) -    assert_eq!(2, count_nitrokey_block_devices()); - -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.enable_hidden_volume("blubb") -    ); -    assert_ok!((), device.enable_hidden_volume("hiddenpassword")); -    assert_eq!(2, count_nitrokey_block_devices()); -    assert_ok!((), device.enable_hidden_volume("otherpw")); -    assert_eq!(2, count_nitrokey_block_devices()); - -    assert_ok!((), device.disable_hidden_volume()); -    assert_eq!(1, count_nitrokey_block_devices()); -} - -#[test_device] -fn lock(device: Storage) { -    let mut device = device; -    assert_ok!((), device.enable_encrypted_volume(DEFAULT_USER_PIN)); -    assert_ok!((), device.lock()); -    assert_eq!(1, count_nitrokey_block_devices()); -} - -#[test_device] -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!( -        (), -        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(DEFAULT_USER_PIN, VolumeMode::ReadOnly) -    // ); - -    assert_ok!( -        (), -        device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) -    ); -    assert_ok!( -        (), -        device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadWrite) -    ); -    assert_ok!( -        (), -        device.set_encrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) -    ); -} - -#[test_device] -fn set_unencrypted_volume_mode(device: Storage) { -    fn assert_mode(device: &Storage, mode: VolumeMode) { -        let status = unwrap_ok!(device.get_status()); -        assert_eq!( -            status.unencrypted_volume.read_only, -            mode == VolumeMode::ReadOnly -        ); -    } - -    fn assert_success(device: &mut Storage, mode: VolumeMode) { -        assert_ok!( -            (), -            device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, mode) -        ); -        assert_mode(&device, mode); -    } - -    let mut device = device; -    assert_success(&mut device, VolumeMode::ReadOnly); - -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.set_unencrypted_volume_mode(DEFAULT_USER_PIN, VolumeMode::ReadOnly) -    ); -    assert_mode(&device, VolumeMode::ReadOnly); - -    assert_success(&mut device, VolumeMode::ReadWrite); -    assert_success(&mut device, VolumeMode::ReadWrite); -    assert_success(&mut device, VolumeMode::ReadOnly); -} - -#[test_device] -fn get_storage_status(device: Storage) { -    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 = 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); -    assert!(info.sd_card.serial_number != 0); -    assert!(info.sd_card.size > 0); -    assert!(info.sd_card.manufacturing_year > 10); -    assert!(info.sd_card.manufacturing_year < 100); -    // TODO: month value is not valid atm -    // assert!(info.sd_card.manufacturing_month < 12); -    assert!(info.sd_card.oem != 0); -    assert!(info.sd_card.manufacturer != 0); - -    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); -} - -#[test_device] -fn clear_new_sd_card_warning(device: Storage) { -    let mut device = device; -    assert_ok!((), device.factory_reset(DEFAULT_ADMIN_PIN)); -    thread::sleep(time::Duration::from_secs(3)); -    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()); - -    let status = unwrap_ok!(device.get_status()); -    assert!(status.new_sd_card_found); - -    assert_ok!((), device.clear_new_sd_card_warning(DEFAULT_ADMIN_PIN)); - -    let status = unwrap_ok!(device.get_status()); -    assert!(!status.new_sd_card_found); -} - -#[test_device] -fn export_firmware(device: Storage) { -    let mut device = device; -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.export_firmware("someadminpn") -    ); -    assert_ok!((), device.export_firmware(DEFAULT_ADMIN_PIN)); -    assert_ok!( -        (), -        device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadWrite) -    ); -    assert_ok!((), device.export_firmware(DEFAULT_ADMIN_PIN)); -    assert_ok!( -        (), -        device.set_unencrypted_volume_mode(DEFAULT_ADMIN_PIN, VolumeMode::ReadOnly) -    ); -} diff --git a/nitrokey/tests/lib.rs b/nitrokey/tests/lib.rs deleted file mode 100644 index 25aae0f..0000000 --- a/nitrokey/tests/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2019 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: MIT - -mod util; - -#[test] -fn get_library_version() { -    let version = unwrap_ok!(nitrokey::get_library_version()); - -    assert!(version.git.is_empty() || version.git.starts_with("v")); -    assert!(version.major > 0); -} - -#[test] -fn take_manager() { -    assert!(nitrokey::take().is_ok()); - -    let result = nitrokey::take(); -    assert!(result.is_ok()); -    let result2 = nitrokey::take(); -    match result2 { -        Ok(_) => panic!("Expected error, got Ok(_)!"), -        Err(nitrokey::Error::ConcurrentAccessError) => {} -        Err(err) => panic!("Expected ConcurrentAccessError, got {}", err), -    } -    drop(result); -    assert!(nitrokey::take().is_ok()); -} diff --git a/nitrokey/tests/otp.rs b/nitrokey/tests/otp.rs deleted file mode 100644 index 38cd8a9..0000000 --- a/nitrokey/tests/otp.rs +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: MIT - -mod util; - -use std::fmt::Debug; -use std::ops::DerefMut; - -use nitrokey::{ -    Admin, Authenticate, CommandError, Config, ConfigureOtp, Device, GenerateOtp, LibraryError, -    OtpMode, OtpSlotData, DEFAULT_ADMIN_PIN, DEFAULT_USER_PIN, -}; -use nitrokey_test::test as test_device; - -// test suite according to RFC 4226, Appendix D -static HOTP_SECRET: &str = "3132333435363738393031323334353637383930"; -static HOTP_CODES: &[&str] = &[ -    "755224", "287082", "359152", "969429", "338314", "254676", "287922", "162583", "399871", -    "520489", -]; - -// test suite according to RFC 6238, Appendix B -static TOTP_SECRET: &str = "3132333435363738393031323334353637383930"; -static TOTP_CODES: &[(u64, &[&str])] = &[ -    (59, &["94287082", "37359152"]), -    (1111111109, &["07081804"]), -    (1111111111, &["14050471"]), -    (1234567890, &["89005924"]), -    (2000000000, &["69279037"]), -    (20000000000, &["65353130"]), -]; - -#[derive(PartialEq)] -enum TotpTimestampSize { -    U32, -    U64, -} - -fn make_admin_test_device<'a, T>(device: T) -> Admin<'a, T> -where -    T: Device<'a>, -    (T, nitrokey::Error): Debug, -{ -    unwrap_ok!(device.authenticate_admin(DEFAULT_ADMIN_PIN)) -} - -fn configure_hotp(admin: &mut dyn ConfigureOtp, counter: u8) { -    let slot_data = OtpSlotData::new(1, "test-hotp", HOTP_SECRET, OtpMode::SixDigits); -    assert_ok!((), admin.write_hotp_slot(slot_data, counter.into())); -} - -fn check_hotp_codes(device: &mut dyn GenerateOtp, offset: u8) { -    HOTP_CODES.iter().enumerate().for_each(|(i, code)| { -        if i >= offset as usize { -            assert_ok!(code.to_string(), device.get_hotp_code(1)); -        } -    }); -} - -#[test_device] -fn set_time(device: DeviceWrapper) { -    let mut device = device; -    assert_ok!((), device.set_time(1546385382, true)); -    assert_ok!((), device.set_time(1546385392, false)); -    assert_cmd_err!(CommandError::Timestamp, device.set_time(1546385292, false)); -    assert_ok!((), device.set_time(1546385382, true)); -} - -#[test_device] -fn hotp_no_pin(device: DeviceWrapper) { -    let mut admin = make_admin_test_device(device); -    let config = Config::new(None, None, None, false); -    assert_ok!((), admin.write_config(config)); - -    configure_hotp(&mut admin, 0); -    check_hotp_codes(admin.deref_mut(), 0); - -    configure_hotp(&mut admin, 5); -    check_hotp_codes(admin.deref_mut(), 5); - -    configure_hotp(&mut admin, 0); -    check_hotp_codes(&mut admin.device(), 0); -} - -#[test_device] -fn hotp_pin(device: DeviceWrapper) { -    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!(admin.device().authenticate_user(DEFAULT_USER_PIN)); -    check_hotp_codes(&mut user, 0); - -    assert_cmd_err!(CommandError::NotAuthorized, user.device().get_hotp_code(1)); -} - -#[test_device] -fn hotp_slot_name(device: DeviceWrapper) { -    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 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); -    assert_lib_err!( -        LibraryError::InvalidSlot, -        admin.write_hotp_slot(slot_data, 0) -    ); -    let slot_data = OtpSlotData::new(1, "test", "foobar", OtpMode::SixDigits); -    assert_lib_err!( -        LibraryError::InvalidHexString, -        admin.write_hotp_slot(slot_data, 0) -    ); -    let code = admin.get_hotp_code(4); -    assert_lib_err!(LibraryError::InvalidSlot, code); -} - -#[test_device] -fn hotp_erase(device: DeviceWrapper) { -    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); -    assert_ok!((), admin.write_hotp_slot(slot_data, 0)); -    let slot_data = OtpSlotData::new(2, "test2", HOTP_SECRET, OtpMode::SixDigits); -    assert_ok!((), admin.write_hotp_slot(slot_data, 0)); - -    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); -    assert_cmd_err!(CommandError::SlotNotProgrammed, result); - -    assert_ok!("test2".to_string(), device.get_hotp_slot_name(2)); -} - -fn configure_totp(admin: &mut dyn ConfigureOtp, factor: u64) { -    let slot_data = OtpSlotData::new(1, "test-totp", TOTP_SECRET, OtpMode::EightDigits); -    let time_window = 30u64.checked_mul(factor).unwrap(); -    assert_ok!((), admin.write_totp_slot(slot_data, time_window as u16)); -} - -fn check_totp_codes(device: &mut dyn GenerateOtp, factor: u64, timestamp_size: TotpTimestampSize) { -    for (base_time, codes) 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) { -            continue; -        } - -        assert_ok!((), device.set_time(time, true)); -        let code = unwrap_ok!(device.get_totp_code(1)); -        assert!( -            code.contains(&code), -            "Generated TOTP code {} for {}, but expected one of {}", -            code, -            base_time, -            codes.join(", ") -        ); -    } -} - -#[test_device] -fn totp_no_pin(device: DeviceWrapper) { -    let mut admin = make_admin_test_device(device); -    let config = Config::new(None, None, None, false); -    assert_ok!((), admin.write_config(config)); - -    configure_totp(&mut admin, 1); -    check_totp_codes(admin.deref_mut(), 1, TotpTimestampSize::U32); - -    configure_totp(&mut admin, 2); -    check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U32); - -    configure_totp(&mut admin, 1); -    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 admin = make_admin_test_device(device); -    let config = Config::new(None, None, None, false); -    assert_ok!((), admin.write_config(config)); - -    configure_totp(&mut admin, 1); -    check_totp_codes(admin.deref_mut(), 1, TotpTimestampSize::U64); - -    configure_totp(&mut admin, 2); -    check_totp_codes(admin.deref_mut(), 2, TotpTimestampSize::U64); - -    configure_totp(&mut admin, 1); -    check_totp_codes(&mut admin.device(), 1, TotpTimestampSize::U64); -} - -#[test_device] -fn totp_pin(device: DeviceWrapper) { -    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.device().authenticate_user(DEFAULT_USER_PIN)); -    check_totp_codes(&mut user, 1, TotpTimestampSize::U32); - -    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 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.device().authenticate_user(DEFAULT_USER_PIN)); -    check_totp_codes(&mut user, 1, TotpTimestampSize::U64); - -    assert_cmd_err!(CommandError::NotAuthorized, user.device().get_totp_code(1)); -} - -#[test_device] -fn totp_slot_name(device: DeviceWrapper) { -    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); -    assert_lib_err!(LibraryError::InvalidSlot, result); -} - -#[test_device] -fn totp_error(device: DeviceWrapper) { -    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); -    assert_lib_err!( -        LibraryError::InvalidSlot, -        admin.write_totp_slot(slot_data, 0) -    ); -    let slot_data = OtpSlotData::new(4, "test", "foobar", OtpMode::SixDigits); -    assert_lib_err!( -        LibraryError::InvalidHexString, -        admin.write_totp_slot(slot_data, 0) -    ); -    let code = admin.get_totp_code(20); -    assert_lib_err!(LibraryError::InvalidSlot, code); -} - -#[test_device] -fn totp_erase(device: DeviceWrapper) { -    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); -    assert_ok!((), admin.write_totp_slot(slot_data, 0)); -    let slot_data = OtpSlotData::new(2, "test2", TOTP_SECRET, OtpMode::SixDigits); -    assert_ok!((), admin.write_totp_slot(slot_data, 0)); - -    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); -    assert_cmd_err!(CommandError::SlotNotProgrammed, result); - -    assert_ok!("test2".to_string(), device.get_totp_slot_name(2)); -} diff --git a/nitrokey/tests/pws.rs b/nitrokey/tests/pws.rs deleted file mode 100644 index 7169695..0000000 --- a/nitrokey/tests/pws.rs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: MIT - -mod util; - -use std::ffi::CStr; - -use libc::{c_int, c_void, free}; -use nitrokey::{ -    CommandError, Device, Error, GetPasswordSafe, LibraryError, PasswordSafe, DEFAULT_ADMIN_PIN, -    DEFAULT_USER_PIN, SLOT_COUNT, -}; -use nitrokey_sys; -use nitrokey_test::test as test_device; - -fn get_slot_name_direct(slot: u8) -> Result<String, Error> { -    let ptr = unsafe { nitrokey_sys::NK_get_password_safe_slot_name(slot) }; -    if ptr.is_null() { -        return Err(Error::UnexpectedError); -    } -    let s = unsafe { CStr::from_ptr(ptr).to_string_lossy().into_owned() }; -    unsafe { free(ptr as *mut c_void) }; -    match s.is_empty() { -        true => { -            let error = unsafe { nitrokey_sys::NK_get_last_command_status() } as c_int; -            match error { -                0 => Ok(s), -                other => Err(Error::from(other)), -            } -        } -        false => Ok(s), -    } -} - -fn get_pws<'a, T>(device: &mut T) -> PasswordSafe<'_, 'a> -where -    T: Device<'a>, -{ -    unwrap_ok!(device.get_password_safe(DEFAULT_USER_PIN)) -} - -#[test_device] -fn enable(device: DeviceWrapper) { -    let mut device = device; -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.get_password_safe(&(DEFAULT_USER_PIN.to_owned() + "123")) -    ); -    assert_any_ok!(device.get_password_safe(DEFAULT_USER_PIN)); -    assert_cmd_err!( -        CommandError::WrongPassword, -        device.get_password_safe(DEFAULT_ADMIN_PIN) -    ); -    assert_any_ok!(device.get_password_safe(DEFAULT_USER_PIN)); -} - -#[test_device] -fn drop(device: DeviceWrapper) { -    let mut device = device; -    { -        let mut pws = get_pws(&mut device); -        assert_ok!((), pws.write_slot(1, "name", "login", "password")); -        assert_ok!("name".to_string(), pws.get_slot_name(1)); -        let result = get_slot_name_direct(1); -        assert_ok!(String::from("name"), result); -    } -    let result = get_slot_name_direct(1); -    assert_ok!(String::from("name"), result); -    assert_ok!((), device.lock()); -    let result = get_slot_name_direct(1); -    assert_cmd_err!(CommandError::NotAuthorized, result); -} - -#[test_device] -fn get_status(device: DeviceWrapper) { -    let mut device = device; -    let mut pws = get_pws(&mut device); -    for i in 0..SLOT_COUNT { -        assert_ok!((), pws.erase_slot(i)); -    } -    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 = unwrap_ok!(pws.get_slot_status()); -    for i in 0..SLOT_COUNT { -        assert_eq!(i == 1, status[i as usize]); -    } - -    for i in 0..SLOT_COUNT { -        assert_ok!((), pws.write_slot(i, "name", "login", "password")); -    } -    assert_ok!([true; SLOT_COUNT as usize], pws.get_slot_status()); -} - -#[test_device] -fn get_data(device: DeviceWrapper) { -    let mut device = device; -    let mut pws = get_pws(&mut device); -    assert_ok!((), pws.write_slot(1, "name", "login", "password")); -    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)); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_login(1)); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_password(1)); - -    let name = "with å"; -    let login = "pär@test.com"; -    let password = "'i3lJc[09?I:,[u7dWz9"; -    assert_ok!((), pws.write_slot(1, name, login, password)); -    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)); -    assert_lib_err!(LibraryError::InvalidSlot, pws.get_slot_password(SLOT_COUNT)); -} - -#[test_device] -fn write(device: DeviceWrapper) { -    let mut device = device; -    let mut pws = get_pws(&mut device); - -    assert_lib_err!( -        LibraryError::InvalidSlot, -        pws.write_slot(SLOT_COUNT, "name", "login", "password") -    ); - -    assert_ok!((), pws.write_slot(0, "", "login", "password")); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_name(0)); -    assert_ok!(String::from("login"), pws.get_slot_login(0)); -    assert_ok!(String::from("password"), pws.get_slot_password(0)); - -    assert_ok!((), pws.write_slot(0, "name", "", "password")); -    assert_ok!(String::from("name"), pws.get_slot_name(0)); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_login(0)); -    assert_ok!(String::from("password"), pws.get_slot_password(0)); - -    assert_ok!((), pws.write_slot(0, "name", "login", "")); -    assert_ok!(String::from("name"), pws.get_slot_name(0)); -    assert_ok!(String::from("login"), pws.get_slot_login(0)); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_password(0)); -} - -#[test_device] -fn erase(device: DeviceWrapper) { -    let mut device = device; -    let mut pws = get_pws(&mut device); -    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)); -    assert_ok!((), pws.erase_slot(0)); -    assert_cmd_err!(CommandError::SlotNotProgrammed, pws.get_slot_name(0)); -} diff --git a/nitrokey/tests/util/mod.rs b/nitrokey/tests/util/mod.rs deleted file mode 100644 index f2b20ec..0000000 --- a/nitrokey/tests/util/mod.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2018-2019 Robin Krahl <robin.krahl@ireas.org> -// SPDX-License-Identifier: MIT - -#[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_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) => {{ -        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); -    }; -} - -#[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) => { -        assert_err!(::nitrokey::Error::LibraryError, $left, $right); -    }; -}  | 
