From 81a288088c4e54ffce81e1971c4ccdfe2ec80b8a Mon Sep 17 00:00:00 2001
From: Robin Krahl <me@robin-krahl.de>
Date: Fri, 18 May 2018 09:26:56 +0200
Subject: Add set_time_soft to replace get_time
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The SetTime command supports two modes: set the time without checking
the currently set time, or verify that the currently set time is not
zero and not larger than the new time (see cmd_set_time(uint8_t*,
uint8_t*) in src/keyboard/report_protocol.c, lines 678--710, in the
Nitrokey Pro firmware).

NitrokeyManager called these two modes set_time(uint64_t) and
get_time(uint64_t), which is highly misleading -- the command does never
get the time.  Furthermore, the get_time method per default calls the
command with the time zero, which will always result in an error.

The C API has the methods NK_totp_set_time(uint64_t) and
NK_totp_get_time().  NK_totp_get_time() calls get_time(uint64_t) with
the time zero, leading to an error, and is therefore useless.

This patch proposes a new wording.  While it would make sense to call
the first mode “reset” and the second mode “set”, this would break
compatibility.  Therefore, new methods set_time_soft(uint64_t) and
NK_totp_set_time_soft(uint64_t) are introduced to represent the
difference between a hard and a soft setting of the time.

The old methods, get_time(uint64_t) and NK_totp_get_time(), are not
removed but marked as deprecated.  They should be removed in an upcoming
major release.
---
 NK_C_API.cc                   |  7 +++++++
 NK_C_API.h                    | 13 +++++++++++++
 NitrokeyManager.cc            |  6 +++++-
 libnitrokey/NitrokeyManager.h | 11 +++++++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/NK_C_API.cc b/NK_C_API.cc
index 00694c7..c679597 100644
--- a/NK_C_API.cc
+++ b/NK_C_API.cc
@@ -358,6 +358,13 @@ extern "C" {
 		});
 	}
 
+	NK_C_API int NK_totp_set_time_soft(uint64_t time) {
+		auto m = NitrokeyManager::instance();
+		return get_without_result([&]() {
+			m->set_time_soft(time);
+		});
+        }
+
 	NK_C_API int NK_totp_get_time() {
 		auto m = NitrokeyManager::instance();
 		return get_without_result([&]() {
diff --git a/NK_C_API.h b/NK_C_API.h
index 5bcc484..28e83b9 100644
--- a/NK_C_API.h
+++ b/NK_C_API.h
@@ -386,6 +386,19 @@ extern "C" {
 	 */
 	NK_C_API int NK_totp_set_time(uint64_t time);
 
+	/**
+	 * Set the device time used for TOTP to the given time.  Contrary to
+	 * {@code set_time(uint64_t)}, this command fails if {@code old_time}
+	 * &gt; {@code time} or if {@code old_time} is zero (where {@code
+	 * old_time} is the current time on the device).
+	 *
+	 * @param time new device time as Unix timestamp (seconds since
+	 *        1970-01-01)
+	 * @return command processing error code
+	 */
+	NK_C_API int NK_totp_set_time_soft(uint64_t time);
+
+	/* NK_totp_get_time() is deprecated -- use NK_totp_set_time_soft */
 	NK_C_API int NK_totp_get_time();
 
 	//passwords
diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc
index 085bf78..addfdbf 100644
--- a/NitrokeyManager.cc
+++ b/NitrokeyManager.cc
@@ -666,11 +666,15 @@ using nitrokey::misc::strcpyT;
         return false;
     }
 
-    bool NitrokeyManager::get_time(uint64_t time) {
+    void NitrokeyManager::set_time_soft(uint64_t time) {
         auto p = get_payload<SetTime>();
         p.reset = 0;
         p.time = time;
         SetTime::CommandTransaction::run(device, p);
+    }
+
+    bool NitrokeyManager::get_time(uint64_t time) {
+        set_time_soft(time);
         return true;
     }
 
diff --git a/libnitrokey/NitrokeyManager.h b/libnitrokey/NitrokeyManager.h
index d4630b0..f7a99da 100644
--- a/libnitrokey/NitrokeyManager.h
+++ b/libnitrokey/NitrokeyManager.h
@@ -65,6 +65,17 @@ char * strndup(const char* str, size_t maxlen);
         stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number);
 
         bool set_time(uint64_t time);
+        /**
+         * Set the device time used for TOTP to the given time.  Contrary to
+         * {@code set_time(uint64_t)}, this command fails if {@code old_time}
+         * &gt; {@code time} or if {@code old_time} is zero (where {@code
+         * old_time} is the current time on the device).
+         *
+         * @param time new device time as Unix timestamp (seconds since
+         *        1970-01-01)
+         */
+        void set_time_soft(uint64_t time);
+        /* get_time is deprecated -- use set_time_soft instead */
         bool get_time(uint64_t time = 0);
         bool erase_totp_slot(uint8_t slot_number, const char *temporary_password);
         bool erase_hotp_slot(uint8_t slot_number, const char *temporary_password);
-- 
cgit v1.2.3


From 2cbea6ce4e5e14af06c0ffa3794e4a07ebb04752 Mon Sep 17 00:00:00 2001
From: Szczepan Zalega <szczepan@nitrokey.com>
Date: Tue, 19 Jun 2018 19:52:26 +0200
Subject: Add "deprecated" tags to get_time and NK_totp_get_time functions

Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
---
 NK_C_API.h                    | 2 +-
 libnitrokey/NitrokeyManager.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/NK_C_API.h b/NK_C_API.h
index 28e83b9..f23bb5d 100644
--- a/NK_C_API.h
+++ b/NK_C_API.h
@@ -398,7 +398,7 @@ extern "C" {
 	 */
 	NK_C_API int NK_totp_set_time_soft(uint64_t time);
 
-	/* NK_totp_get_time() is deprecated -- use NK_totp_set_time_soft */
+  [[deprecated("NK_totp_get_time is deprecated -- use NK_totp_set_time_soft instead")]]
 	NK_C_API int NK_totp_get_time();
 
 	//passwords
diff --git a/libnitrokey/NitrokeyManager.h b/libnitrokey/NitrokeyManager.h
index f7a99da..0689c3f 100644
--- a/libnitrokey/NitrokeyManager.h
+++ b/libnitrokey/NitrokeyManager.h
@@ -75,7 +75,8 @@ char * strndup(const char* str, size_t maxlen);
          *        1970-01-01)
          */
         void set_time_soft(uint64_t time);
-        /* get_time is deprecated -- use set_time_soft instead */
+
+        [[deprecated("get_time is deprecated -- use set_time_soft instead")]]
         bool get_time(uint64_t time = 0);
         bool erase_totp_slot(uint8_t slot_number, const char *temporary_password);
         bool erase_hotp_slot(uint8_t slot_number, const char *temporary_password);
-- 
cgit v1.2.3


From 9a4e5a3e0161ea2d0d72d371439ee44b8b137489 Mon Sep 17 00:00:00 2001
From: Szczepan Zalega <szczepan@nitrokey.com>
Date: Tue, 19 Jun 2018 19:54:08 +0200
Subject: Remove NK_totp_get_time implementation, since it always results in
 error on device's side

Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
---
 NK_C_API.cc | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/NK_C_API.cc b/NK_C_API.cc
index c679597..01963fc 100644
--- a/NK_C_API.cc
+++ b/NK_C_API.cc
@@ -366,10 +366,7 @@ extern "C" {
         }
 
 	NK_C_API int NK_totp_get_time() {
-		auto m = NitrokeyManager::instance();
-		return get_without_result([&]() {
-			m->get_time(0); // FIXME check how that should work
-		});
+	  return 0;
 	}
 
 	NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN) {
-- 
cgit v1.2.3