summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-01-01 23:38:14 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-01-02 00:43:32 +0100
commit52afed9c6a17ec9c120a5a91b445afa74be87f0e (patch)
treef2c177d068c61aea4ed85b134110bac25f027332
parentbf1e181a1bbbc8e42d1313e80676c1955499b87c (diff)
downloadnitrokey-rs-52afed9c6a17ec9c120a5a91b445afa74be87f0e.tar.gz
nitrokey-rs-52afed9c6a17ec9c120a5a91b445afa74be87f0e.tar.bz2
Add force argument to ConfigureOtp::set_time
This patch adds the force argument to the set_time method in the ConfigureOtp trait that allows the user to choose whether jumps to the past are allowed when updating the time. It is implemented by using the NK_totp_set_time_soft function. Previously, jumps where unconditionally allowed.
-rw-r--r--CHANGELOG.md3
-rw-r--r--TODO.md1
-rw-r--r--src/otp.rs33
-rw-r--r--tests/otp.rs12
4 files changed, 33 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5064d4f..34f9ac9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# Unreleased
+- Add a `force` argument to `ConfigureOtp::set_time`.
+
# v0.2.3 (2018-12-31)
- Dummy release to fix an issue with the crates.io tarball.
diff --git a/TODO.md b/TODO.md
index 6086ad8..16ec558 100644
--- a/TODO.md
+++ b/TODO.md
@@ -27,7 +27,6 @@
- `NK_get_major_library_version`
- `NK_get_minor_libray_version`
- `NK_get_storage_production_info`
- - `NK_totp_set_time_soft`
- `NK_wink`
- Fix timing issues with the `totp_no_pin` and `totp_pin` test cases.
- Clear passwords from memory.
diff --git a/src/otp.rs b/src/otp.rs
index 6f6bd80..9f0a388 100644
--- a/src/otp.rs
+++ b/src/otp.rs
@@ -151,27 +151,27 @@ pub trait ConfigureOtp {
/// Provides methods to generate OTP codes and to query OTP slots on a Nitrokey
/// device.
pub trait GenerateOtp {
- /// Sets the time on the Nitrokey. This command may set the time to arbitrary values. `time`
- /// is the number of seconds since January 1st, 1970 (Unix timestamp).
+ /// Sets the time on the Nitrokey.
+ ///
+ /// `time` is the number of seconds since January 1st, 1970 (Unix timestamp). Unless `force`
+ /// is set to `true`, this command fails if the timestamp on the device is larger than the
+ /// given timestamp or if it is zero.
///
/// The time is used for TOTP generation (see [`get_totp_code`][]).
///
/// # Example
///
- /// ```ignore
- /// extern crate chrono;
- ///
- /// use chrono::Utc;
- /// use nitrokey::Device;
+ /// ```no_run
+ /// use std::time;
+ /// use nitrokey::GenerateOtp;
/// # use nitrokey::CommandError;
///
/// # fn try_main() -> Result<(), CommandError> {
/// let device = nitrokey::connect()?;
- /// let time = Utc::now().timestamp();
- /// if time < 0 {
- /// println!("Timestamps before 1970-01-01 are not supported!");
- /// } else {
- /// device.set_time(time as u64);
+ /// let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH);
+ /// match time {
+ /// Ok(time) => device.set_time(time.as_secs(), false)?,
+ /// Err(_) => println!("The system time is before the Unix epoch!"),
/// }
/// # Ok(())
/// # }
@@ -183,8 +183,13 @@ pub trait GenerateOtp {
///
/// [`get_totp_code`]: #method.get_totp_code
/// [`Timestamp`]: enum.CommandError.html#variant.Timestamp
- fn set_time(&self, time: u64) -> Result<(), CommandError> {
- unsafe { get_command_result(nitrokey_sys::NK_totp_set_time(time)) }
+ fn set_time(&self, time: u64, force: bool) -> Result<(), CommandError> {
+ let result = if force {
+ unsafe { nitrokey_sys::NK_totp_set_time(time) }
+ } else {
+ unsafe { nitrokey_sys::NK_totp_set_time_soft(time) }
+ };
+ get_command_result(result)
}
/// Returns the name of the given HOTP slot.
diff --git a/tests/otp.rs b/tests/otp.rs
index 8e7ae08..c7d6e68 100644
--- a/tests/otp.rs
+++ b/tests/otp.rs
@@ -55,6 +55,16 @@ fn check_hotp_codes(device: &GenerateOtp, offset: u8) {
#[test]
#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)]
+fn set_time() {
+ let device = Target::connect().expect("Could not connect to the Nitrokey.");
+ assert_eq!(Ok(()), device.set_time(1546385382, true));
+ assert_eq!(Ok(()), device.set_time(1546385392, false));
+ assert_eq!(Err(CommandError::Timestamp), device.set_time(1546385292, false));
+ assert_eq!(Ok(()), device.set_time(1546385382, true));
+}
+
+#[test]
+#[cfg_attr(not(any(feature = "test-pro", feature = "test-storage")), ignore)]
fn hotp_no_pin() {
let admin = get_admin_test_device();
let config = Config::new(None, None, None, false);
@@ -152,7 +162,7 @@ fn check_totp_codes(device: &GenerateOtp, factor: u64, timestamp_size: TotpTimes
continue;
}
- assert!(device.set_time(time).is_ok());
+ assert!(device.set_time(time, true).is_ok());
let result = device.get_totp_code(1);
assert!(result.is_ok());
let result_code = result.unwrap();