From cbccc871329c5522449010ae5007278123508820 Mon Sep 17 00:00:00 2001
From: Szczepan Zalega <szczepan@nitrokey.com>
Date: Wed, 16 Nov 2016 18:32:38 +0100
Subject: Use another OTP writing protocol and test it

Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
---
 unittest/constants.py |   2 +-
 unittest/test3.cc     | 111 +++++++++++++++++++++++++++++++-------------------
 unittest/test_pro.py  |  33 +++++++++++++--
 3 files changed, 101 insertions(+), 45 deletions(-)

(limited to 'unittest')

diff --git a/unittest/constants.py b/unittest/constants.py
index 78a219b..3c19a9b 100644
--- a/unittest/constants.py
+++ b/unittest/constants.py
@@ -2,7 +2,7 @@ from enum import Enum
 from misc import to_hex
 
 RFC_SECRET_HR = '12345678901234567890'
-RFC_SECRET = to_hex(RFC_SECRET_HR)  # '12345678901234567890'
+RFC_SECRET = to_hex(RFC_SECRET_HR)  # '3031323334353637383930...'
 
 
 # print( repr((RFC_SECRET, RFC_SECRET_, len(RFC_SECRET))) )
diff --git a/unittest/test3.cc b/unittest/test3.cc
index 7f779a5..7b37a60 100644
--- a/unittest/test3.cc
+++ b/unittest/test3.cc
@@ -49,18 +49,26 @@ TEST_CASE("write slot", "[pronew]"){
   connect_and_setup(stick);
   authorize(stick);
 
-  auto p = get_payload<WriteToHOTPSlot>();
-  strcpyT(p.slot_secret, RFC_SECRET);
-  strcpyT(p.temporary_admin_password, temporary_password);
-  p.use_8_digits = true;
-  stick10_08::WriteToHOTPSlot::CommandTransaction::run(stick, p);
+  auto p2 = get_payload<SendOTPData>();
+  strcpyT(p2.temporary_admin_password, temporary_password);
+  p2.setTypeName();
+  strcpyT(p2.data, "test name aaa");
+  p2.length = strlen((const char *) p2.data);
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
 
-  auto p2 = get_payload<WriteToHOTPSlot_2>();
+  p2 = get_payload<SendOTPData>();
   strcpyT(p2.temporary_admin_password, temporary_password);
-  p2.slot_number = 0 + 0x10;
-  p2.slot_counter = 0;
-  strcpyT(p2.slot_name, "test name aaa");
-  stick10_08::WriteToHOTPSlot_2::CommandTransaction::run(stick, p2);
+  strcpyT(p2.data, RFC_SECRET);
+  p2.length = strlen(RFC_SECRET);
+  p2.setTypeSecret();
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
+
+  auto p = get_payload<WriteToOTPSlot>();
+  strcpyT(p.temporary_admin_password, temporary_password);
+  p.use_8_digits = true;
+  p.slot_number = 0 + 0x10;
+  p.slot_counter_or_interval = 0;
+  stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p);
 
   auto pc = get_payload<WriteGeneralConfig>();
   pc.enable_user_password = 0;
@@ -119,23 +127,34 @@ TEST_CASE("authorize user HOTP", "[pronew]") {
   connect_and_setup(stick);
   authorize(stick);
 
-  auto p = get_payload<WriteGeneralConfig>();
-  p.enable_user_password = 1;
-  strcpyT(p.temporary_admin_password, temporary_password);
-  WriteGeneralConfig::CommandTransaction::run(stick, p);
+  {
+    auto p = get_payload<WriteGeneralConfig>();
+    p.enable_user_password = 1;
+    strcpyT(p.temporary_admin_password, temporary_password);
+    WriteGeneralConfig::CommandTransaction::run(stick, p);
+  }
+
+  auto p2 = get_payload<SendOTPData>();
+  strcpyT(p2.temporary_admin_password, temporary_password);
+  p2.setTypeName();
+  strcpyT(p2.data, "test name aaa");
+  p2.length = strlen((const char *) p2.data);
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
+
+  p2 = get_payload<SendOTPData>();
+  strcpyT(p2.temporary_admin_password, temporary_password);
+  strcpyT(p2.data, RFC_SECRET);
+  p2.length = strlen(RFC_SECRET);
+  p2.setTypeSecret();
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
 
-  auto pw = get_payload<WriteToHOTPSlot>();
-  strcpyT(pw.slot_secret, RFC_SECRET);
-  strcpyT(pw.temporary_admin_password, temporary_password);
-  pw.use_8_digits = true;
-  WriteToHOTPSlot::CommandTransaction::run(stick, pw);
+  auto p = get_payload<WriteToOTPSlot>();
+  strcpyT(p.temporary_admin_password, temporary_password);
+  p.use_8_digits = true;
+  p.slot_number = 0 + 0x10;
+  p.slot_counter_or_interval = 0;
+  stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p);
 
-  auto pw2 = get_payload<WriteToHOTPSlot_2>();
-  strcpyT(pw2.temporary_admin_password, temporary_password);
-  pw2.slot_number = 0 + 0x10;
-  pw2.slot_counter = 0;
-  strcpyT(pw2.slot_name, "test name aaa");
-  WriteToHOTPSlot_2::CommandTransaction::run(stick, pw2);
 
   auto p3 = get_payload<GetHOTP>();
   p3.slot_number = 0 + 0x10;
@@ -161,23 +180,33 @@ TEST_CASE("authorize user TOTP", "[pronew]") {
   connect_and_setup(stick);
   authorize(stick);
 
-  auto p = get_payload<WriteGeneralConfig>();
-  p.enable_user_password = 1;
-  strcpyT(p.temporary_admin_password, temporary_password);
-  WriteGeneralConfig::CommandTransaction::run(stick, p);
+  {
+    auto p = get_payload<WriteGeneralConfig>();
+    p.enable_user_password = 1;
+    strcpyT(p.temporary_admin_password, temporary_password);
+    WriteGeneralConfig::CommandTransaction::run(stick, p);
+  }
 
-  auto pw = get_payload<WriteToTOTPSlot>();
-  strcpyT(pw.slot_secret, RFC_SECRET);
-  strcpyT(pw.temporary_admin_password, temporary_password);
-  pw.use_8_digits = true;
-  WriteToTOTPSlot::CommandTransaction::run(stick, pw);
-
-  auto pw2 = get_payload<WriteToTOTPSlot_2>();
-  strcpyT(pw2.temporary_admin_password, temporary_password);
-  pw2.slot_number = 0 + 0x20;
-  pw2.slot_interval= 30;
-  strcpyT(pw2.slot_name, "test name TOTP");
-  WriteToTOTPSlot_2::CommandTransaction::run(stick, pw2);
+  auto p2 = get_payload<SendOTPData>();
+  strcpyT(p2.temporary_admin_password, temporary_password);
+  p2.setTypeName();
+  strcpyT(p2.data, "test name TOTP");
+  p2.length = strlen((const char *) p2.data);
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
+
+  p2 = get_payload<SendOTPData>();
+  strcpyT(p2.temporary_admin_password, temporary_password);
+  strcpyT(p2.data, RFC_SECRET);
+  p2.length = strlen(RFC_SECRET);
+  p2.setTypeSecret();
+  stick10_08::SendOTPData::CommandTransaction::run(stick, p2);
+
+  auto p = get_payload<WriteToOTPSlot>();
+  strcpyT(p.temporary_admin_password, temporary_password);
+  p.use_8_digits = true;
+  p.slot_number = 0 + 0x20;
+  p.slot_counter_or_interval = 30;
+  stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p);
 
   auto p_get_totp = get_payload<GetTOTP>();
   p_get_totp.slot_number = 0 + 0x20;
diff --git a/unittest/test_pro.py b/unittest/test_pro.py
index a9e9fa4..3632ecd 100644
--- a/unittest/test_pro.py
+++ b/unittest/test_pro.py
@@ -536,7 +536,7 @@ def test_HOTP_slots_read_write_counter(C, counter):
     lib_res = []
     for slot_number in range(3):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_hotp_slot(slot_number, 'null_secret', secret, counter, use_8_digits, False, False, "",
+        assert C.NK_write_hotp_slot(slot_number, 'HOTP rw' + str(slot_number), secret, counter, use_8_digits, False, False, "",
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         code_device = str(C.NK_get_hotp_code(slot_number))
         code_device = '0'+code_device if len(code_device) < 6 else code_device
@@ -546,7 +546,7 @@ def test_HOTP_slots_read_write_counter(C, counter):
 
 
 @pytest.mark.parametrize("period", [30,60] )
-@pytest.mark.parametrize("time", range(20,70,20) )
+@pytest.mark.parametrize("time", range(21,70,20) )
 def test_TOTP_slots_read_write_at_time_period(C, time, period):
     secret = RFC_SECRET
     oath = pytest.importorskip("oath")
@@ -561,7 +561,7 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period):
     lib_res = []
     for slot_number in range(15):
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
-        assert C.NK_write_totp_slot(slot_number, 'null_secret', secret, period, use_8_digits, False, False, "",
+        assert C.NK_write_totp_slot(slot_number, 'TOTP rw' + str(slot_number), secret, period, use_8_digits, False, False, "",
                                     DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
         assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK
@@ -572,5 +572,32 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period):
     assert dev_res == lib_res
 
 
+@pytest.mark.parametrize("secret", [RFC_SECRET, 2*RFC_SECRET] )
+def test_TOTP_secrets(C, secret):
+    slot_number = 0
+    time = 0
+    period = 30
+    oath = pytest.importorskip("oath")
+    lib_at = lambda t: oath.totp(secret, t=t, period=period)
+    PIN_protection = False
+    use_8_digits = False
+    T = 0
+    assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection,
+                             DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+    dev_res = []
+    lib_res = []
+    assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+    assert C.NK_write_totp_slot(slot_number, 'TOTP secret' + str(slot_number), secret, period, use_8_digits, False, False, "",
+                                DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+    assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+    assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK
+    code_device = str(C.NK_get_totp_code(slot_number, T, 0, period))
+    code_device = '0'+code_device if len(code_device) < 6 else code_device
+    dev_res += (time, code_device)
+    lib_res += (time, lib_at(time))
+    assert dev_res == lib_res
+
+
 
 
-- 
cgit v1.2.3