From c595fecc9cb857c41d6a90fe24fdb5c18f3e8958 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Wed, 6 Jun 2018 15:34:21 +0200 Subject: Adapt TOTP test cases for Nitrokey Storage The current Nitrokey Storage firmware does not support timestamps that do not fit into an unsigned integer. Therefore, the tests totp_pin and totp_no_pin are restricted to 32-bit timestamps. New tests totp_pin_64 and totp_no_pin_64 are introduced for 64-bit timestamps. These are expected to panic for the Nitrokey Storage. --- src/tests/otp.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'src/tests/otp.rs') diff --git a/src/tests/otp.rs b/src/tests/otp.rs index ea41e68..91f9f1b 100644 --- a/src/tests/otp.rs +++ b/src/tests/otp.rs @@ -21,6 +21,12 @@ static TOTP_CODES: &[(u64, &str)] = &[ (20000000000, "65353130"), ]; +#[derive(PartialEq)] +enum TotpTimestampSize { + U32, + U64, +} + fn get_admin_test_device() -> Admin { Target::connect() .expect("Could not connect to the Nitrokey.") @@ -139,9 +145,14 @@ fn configure_totp(admin: &ConfigureOtp, factor: u64) { ); } -fn check_totp_codes(device: &GenerateOtp, factor: u64) { +fn check_totp_codes(device: &GenerateOtp, factor: u64, timestamp_size: TotpTimestampSize) { for (i, &(base_time, code)) in TOTP_CODES.iter().enumerate() { 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_eq!(CommandStatus::Success, device.set_time(time)); let result = device.get_totp_code(1); assert!(result.is_ok()); @@ -163,13 +174,33 @@ fn totp_no_pin() { assert_eq!(CommandStatus::Success, admin.write_config(config)); configure_totp(&admin, 1); - check_totp_codes(admin.deref(), 1); + check_totp_codes(admin.deref(), 1, TotpTimestampSize::U32); configure_totp(&admin, 2); - check_totp_codes(admin.deref(), 2); + check_totp_codes(admin.deref(), 2, TotpTimestampSize::U32); configure_totp(&admin, 1); - check_totp_codes(&admin.device(), 1); + check_totp_codes(&admin.device(), 1, TotpTimestampSize::U32); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +#[cfg_attr(feature = "test-storage", should_panic(expected = "assertion failed"))] +// Nitrokey Storage does only support timestamps that fit in a 32-bit unsigned integer. Therefore +// the last RFC test case is expected to fail. +fn totp_no_pin_64() { + let admin = get_admin_test_device(); + let config = Config::new(None, None, None, false); + assert_eq!(CommandStatus::Success, admin.write_config(config)); + + configure_totp(&admin, 1); + check_totp_codes(admin.deref(), 1, TotpTimestampSize::U64); + + configure_totp(&admin, 2); + check_totp_codes(admin.deref(), 2, TotpTimestampSize::U64); + + configure_totp(&admin, 1); + check_totp_codes(&admin.device(), 1, TotpTimestampSize::U64); } #[test] @@ -182,7 +213,23 @@ fn totp_pin() { configure_totp(&admin, 1); let user = admin.device().authenticate_user(USER_PASSWORD).unwrap(); - check_totp_codes(&user, 1); + check_totp_codes(&user, 1, TotpTimestampSize::U32); + + assert!(user.device().get_totp_code(1).is_err()); +} + +#[test] +#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)] +#[cfg_attr(feature = "test-storage", should_panic(expected = "assertion failed"))] +// See comment for totp_no_pin_64. +fn totp_pin_64() { + let admin = get_admin_test_device(); + let config = Config::new(None, None, None, true); + assert_eq!(CommandStatus::Success, admin.write_config(config)); + + configure_totp(&admin, 1); + 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()); } -- cgit v1.2.1