aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--TODO.md2
-rw-r--r--src/tests/device.rs184
-rw-r--r--src/tests/mod.rs5
-rw-r--r--src/tests/no_device.rs8
-rw-r--r--src/tests/otp.rs (renamed from src/tests/pro.rs)191
-rw-r--r--src/tests/util.rs2
7 files changed, 200 insertions, 198 deletions
diff --git a/README.md b/README.md
index 77eb84f..1be2aee 100644
--- a/README.md
+++ b/README.md
@@ -38,9 +38,9 @@ To execute this test suite, run `cargo test --no-default-features --features
test-pro -- --test-threads 1`. Note that this test suite might lock your stick
if you have different passwords!
-The `totp` and `totp_pin` tests can occasionally fail due to bad timing. Also
-make sure to run the tests sequentially (`--test-threads 1`), otherwise they
-might interfere.
+The `totp_no_pin` and `totp_pin` tests can occasionally fail due to bad timing.
+Also make sure to run the tests sequentially (`--test-threads 1`), otherwise
+they might interfere.
## Contact
diff --git a/TODO.md b/TODO.md
index 8538715..d57260c 100644
--- a/TODO.md
+++ b/TODO.md
@@ -35,7 +35,7 @@
- `NK_get_progress_bar_value`
- `NK_list_devices_by_cpuID`
- `NK_connect_with_ID`
-- Fix timing issues with the `totp` and `totp_pin` test cases.
+- Fix timing issues with the `totp_no_pin` and `totp_pin` test cases.
- Clear passwords from memory.
- Find a nicer syntax for the `write_config` test.
- Fix segmentation faults when freeing string literals with old Nitrokey
diff --git a/src/tests/device.rs b/src/tests/device.rs
new file mode 100644
index 0000000..394861c
--- /dev/null
+++ b/src/tests/device.rs
@@ -0,0 +1,184 @@
+use std::ffi::CStr;
+use {Authenticate, CommandError, CommandStatus, Config, Device, Pro};
+use tests::util::{ADMIN_PASSWORD, USER_PASSWORD};
+
+static ADMIN_NEW_PASSWORD: &str = "1234567890";
+static USER_NEW_PASSWORD: &str = "abcdefghij";
+
+#[test]
+#[cfg_attr(not(feature = "test-no-device"), ignore)]
+fn connect_no_device() {
+ assert!(::connect().is_err());
+ assert!(::Pro::connect().is_err());
+ // TODO: test storage
+ // assert!(::Storage::connect().is_err());
+}
+
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn connect_pro() {
+ assert!(::connect().is_ok());
+ assert!(Pro::connect().is_ok());
+ // TODO: test storage
+ // assert!(::Storage::connect().is_err());
+}
+
+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]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn disconnect() {
+ ::connect().unwrap();
+ assert_empty_serial_number();
+ ::connect()
+ .unwrap()
+ .authenticate_admin(ADMIN_PASSWORD)
+ .unwrap();
+ assert_empty_serial_number();
+ ::connect()
+ .unwrap()
+ .authenticate_user(USER_PASSWORD)
+ .unwrap();
+ assert_empty_serial_number();
+}
+
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn get_serial_number() {
+ let device = ::connect().unwrap();
+ let result = device.get_serial_number();
+ assert!(result.is_ok());
+ let serial_number = result.unwrap();
+ assert!(serial_number.is_ascii());
+ assert!(serial_number.chars().all(|c| c.is_ascii_hexdigit()));
+}
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn get_firmware_version() {
+ let device = ::connect().unwrap();
+ assert_eq!(0, device.get_major_firmware_version());
+ let minor = device.get_minor_firmware_version();
+ assert!(minor == 7 || minor == 8);
+}
+
+fn admin_retry<T: Authenticate + Device>(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,
+ };
+ assert_eq!(count, device.get_admin_retry_count());
+ return device;
+}
+
+fn user_retry<T: Authenticate + Device>(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,
+ };
+ assert_eq!(count, device.get_user_retry_count());
+ return device;
+}
+
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn get_retry_count() {
+ let device = ::connect().unwrap();
+
+ 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]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn config() {
+ let device = ::connect().unwrap();
+ let admin = device.authenticate_admin(ADMIN_PASSWORD).unwrap();
+ let config = Config::new(None, None, None, true);
+ assert_eq!(CommandStatus::Success, admin.write_config(config));
+ let get_config = admin.get_config().unwrap();
+ assert_eq!(config, get_config);
+
+ let config = Config::new(None, Some(9), None, true);
+ assert_eq!(
+ CommandStatus::Error(CommandError::InvalidSlot),
+ admin.write_config(config)
+ );
+
+ let config = Config::new(Some(1), None, Some(0), false);
+ assert_eq!(CommandStatus::Success, admin.write_config(config));
+ let get_config = admin.get_config().unwrap();
+ assert_eq!(config, get_config);
+
+ let config = Config::new(None, None, None, false);
+ assert_eq!(CommandStatus::Success, admin.write_config(config));
+ let get_config = admin.get_config().unwrap();
+ assert_eq!(config, get_config);
+}
+
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn change_user_pin() {
+ let device = ::connect().unwrap();
+ let device = device.authenticate_user(USER_PASSWORD).unwrap().device();
+ let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0;
+
+ let result = device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD);
+ assert_eq!(CommandStatus::Success, result);
+
+ let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0;
+ let device = device
+ .authenticate_user(USER_NEW_PASSWORD)
+ .unwrap()
+ .device();
+
+ let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD);
+ assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result);
+
+ let result = device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD);
+ assert_eq!(CommandStatus::Success, result);
+
+ let device = device.authenticate_user(USER_PASSWORD).unwrap().device();
+ device.authenticate_user(USER_NEW_PASSWORD).unwrap_err();
+}
+
+#[test]
+#[cfg_attr(not(feature = "test-pro"), ignore)]
+fn change_admin_pin() {
+ let device = ::connect().unwrap();
+ let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device();
+ let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0;
+
+ let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD);
+ assert_eq!(CommandStatus::Success, result);
+
+ let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0;
+ let device = device
+ .authenticate_admin(ADMIN_NEW_PASSWORD)
+ .unwrap()
+ .device();
+
+ let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD);
+ assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result);
+
+ let result = device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD);
+ assert_eq!(CommandStatus::Success, result);
+
+ let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device();
+ device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err();
+}
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index 5f01b67..c2c9f9d 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -1,2 +1,3 @@
-mod no_device;
-mod pro;
+mod device;
+mod otp;
+mod util;
diff --git a/src/tests/no_device.rs b/src/tests/no_device.rs
deleted file mode 100644
index 4118bcd..0000000
--- a/src/tests/no_device.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#[test]
-#[cfg_attr(not(feature = "test-no-device"), ignore)]
-fn connect() {
- assert!(::connect().is_err());
- assert!(::Pro::connect().is_err());
- // TODO: test storage
- // assert!(::Storage::connect().is_err());
-}
diff --git a/src/tests/pro.rs b/src/tests/otp.rs
index 5415ff9..e96bbfe 100644
--- a/src/tests/pro.rs
+++ b/src/tests/otp.rs
@@ -1,12 +1,7 @@
-use std::ffi::CStr;
use std::ops::Deref;
-use {Admin, Authenticate, CommandError, CommandStatus, Config, ConfigureOtp, Device, GenerateOtp,
- OtpMode, OtpSlotData, Pro};
-
-static ADMIN_PASSWORD: &str = "12345678";
-static ADMIN_NEW_PASSWORD: &str = "1234567890";
-static USER_PASSWORD: &str = "123456";
-static USER_NEW_PASSWORD: &str = "abcdefghij";
+use {Admin, Authenticate, CommandError, CommandStatus, Config, ConfigureOtp, DeviceWrapper, GenerateOtp,
+ OtpMode, OtpSlotData};
+use tests::util::{ADMIN_PASSWORD, USER_PASSWORD};
// test suite according to RFC 4226, Appendix D
static HOTP_SECRET: &str = "3132333435363738393031323334353637383930";
@@ -26,62 +21,12 @@ static TOTP_CODES: &[(u64, &str)] = &[
(20000000000, "65353130"),
];
-fn get_test_device() -> Pro {
- Pro::connect().expect("Could not connect to the Nitrokey Pro.")
-}
-
-fn get_admin_test_device() -> Admin<Pro> {
- get_test_device()
+fn get_admin_test_device() -> Admin<DeviceWrapper> {
+ ::connect().expect("Could not connect to the Nitrokey Pro.")
.authenticate_admin(ADMIN_PASSWORD)
.expect("Could not login as admin.")
}
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn connect() {
- assert!(::connect().is_ok());
- assert!(Pro::connect().is_ok());
- // TODO: test storage
- // assert!(::Storage::connect().is_err());
-}
-
-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]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn disconnect() {
- Pro::connect().unwrap();
- assert_empty_serial_number();
- Pro::connect()
- .unwrap()
- .authenticate_admin(ADMIN_PASSWORD)
- .unwrap();
- assert_empty_serial_number();
- Pro::connect()
- .unwrap()
- .authenticate_user(USER_PASSWORD)
- .unwrap();
- assert_empty_serial_number();
-}
-
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn get_serial_number() {
- let device = get_test_device();
- let result = device.get_serial_number();
- assert!(result.is_ok());
- let serial_number = result.unwrap();
- assert!(serial_number.is_ascii());
- assert!(serial_number.chars().all(|c| c.is_ascii_hexdigit()));
-}
-
fn configure_hotp(admin: &ConfigureOtp) {
let slot_data = OtpSlotData::new(1, "test-hotp", HOTP_SECRET, OtpMode::SixDigits);
assert_eq!(CommandStatus::Success, admin.write_hotp_slot(slot_data, 0));
@@ -96,7 +41,7 @@ fn check_hotp_codes(device: &GenerateOtp) {
#[test]
#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn hotp() {
+fn hotp_no_pin() {
let admin = get_admin_test_device();
let config = Config::new(None, None, None, false);
assert_eq!(CommandStatus::Success, admin.write_config(config));
@@ -197,7 +142,7 @@ fn check_totp_codes(device: &GenerateOtp) {
#[test]
#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn totp() {
+fn totp_no_pin() {
// TODO: this test may fail due to bad timing --> find solution
let admin = get_admin_test_device();
let config = Config::new(None, None, None, false);
@@ -280,125 +225,3 @@ fn totp_erase() {
assert_eq!("test2", device.get_totp_slot_name(2).unwrap());
}
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn get_firmware_version() {
- let device = get_test_device();
- assert_eq!(0, device.get_major_firmware_version());
- let minor = device.get_minor_firmware_version();
- assert!(minor == 7 || minor == 8);
-}
-
-fn admin_retry(device: Pro, suffix: &str, count: u8) -> Pro {
- let result = device.authenticate_admin(&(ADMIN_PASSWORD.to_owned() + suffix));
- let device = match result {
- Ok(admin) => admin.device(),
- Err((device, _)) => device,
- };
- assert_eq!(count, device.get_admin_retry_count());
- return device;
-}
-
-fn user_retry(device: Pro, suffix: &str, count: u8) -> Pro {
- let result = device.authenticate_user(&(USER_PASSWORD.to_owned() + suffix));
- let device = match result {
- Ok(admin) => admin.device(),
- Err((device, _)) => device,
- };
- assert_eq!(count, device.get_user_retry_count());
- return device;
-}
-
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn get_retry_count() {
- let device = get_test_device();
-
- 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]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn read_write_config() {
- let admin = get_admin_test_device();
- let config = Config::new(None, None, None, true);
- assert_eq!(CommandStatus::Success, admin.write_config(config));
- let get_config = admin.get_config().unwrap();
- assert_eq!(config, get_config);
-
- let config = Config::new(None, Some(9), None, true);
- assert_eq!(
- CommandStatus::Error(CommandError::InvalidSlot),
- admin.write_config(config)
- );
-
- let config = Config::new(Some(1), None, Some(0), false);
- assert_eq!(CommandStatus::Success, admin.write_config(config));
- let get_config = admin.get_config().unwrap();
- assert_eq!(config, get_config);
-
- let config = Config::new(None, None, None, false);
- assert_eq!(CommandStatus::Success, admin.write_config(config));
- let get_config = admin.get_config().unwrap();
- assert_eq!(config, get_config);
-}
-
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn change_user_pin() {
- let device = get_test_device();
- let device = device.authenticate_user(USER_PASSWORD).unwrap().device();
- let device = device.authenticate_user(USER_NEW_PASSWORD).unwrap_err().0;
-
- let result = device.change_user_pin(USER_PASSWORD, USER_NEW_PASSWORD);
- assert_eq!(CommandStatus::Success, result);
-
- let device = device.authenticate_user(USER_PASSWORD).unwrap_err().0;
- let device = device
- .authenticate_user(USER_NEW_PASSWORD)
- .unwrap()
- .device();
-
- let result = device.change_user_pin(USER_PASSWORD, USER_PASSWORD);
- assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result);
-
- let result = device.change_user_pin(USER_NEW_PASSWORD, USER_PASSWORD);
- assert_eq!(CommandStatus::Success, result);
-
- let device = device.authenticate_user(USER_PASSWORD).unwrap().device();
- device.authenticate_user(USER_NEW_PASSWORD).unwrap_err();
-}
-
-#[test]
-#[cfg_attr(not(feature = "test-pro"), ignore)]
-fn change_admin_pin() {
- let device = get_test_device();
- let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device();
- let device = device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err().0;
-
- let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_NEW_PASSWORD);
- assert_eq!(CommandStatus::Success, result);
-
- let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap_err().0;
- let device = device
- .authenticate_admin(ADMIN_NEW_PASSWORD)
- .unwrap()
- .device();
-
- let result = device.change_admin_pin(ADMIN_PASSWORD, ADMIN_PASSWORD);
- assert_eq!(CommandStatus::Error(CommandError::WrongPassword), result);
-
- let result = device.change_admin_pin(ADMIN_NEW_PASSWORD, ADMIN_PASSWORD);
- assert_eq!(CommandStatus::Success, result);
-
- let device = device.authenticate_admin(ADMIN_PASSWORD).unwrap().device();
- device.authenticate_admin(ADMIN_NEW_PASSWORD).unwrap_err();
-}
diff --git a/src/tests/util.rs b/src/tests/util.rs
new file mode 100644
index 0000000..cbf6b93
--- /dev/null
+++ b/src/tests/util.rs
@@ -0,0 +1,2 @@
+pub static ADMIN_PASSWORD: &str = "12345678";
+pub static USER_PASSWORD: &str = "123456";