aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2016-07-20 12:26:53 +0200
committerSzczepan Zalega <szczepan@nitrokey.com>2016-08-01 13:54:56 +0200
commit8d21114df0ee75e2129916acb38b212704ed78cf (patch)
tree625eced9f399e5028cd51958e5ff38b90aa9be67
parent02a46831a552d443adfbd3c61542cf6925675349 (diff)
downloadlibnitrokey-8d21114df0ee75e2129916acb38b212704ed78cf.tar.gz
libnitrokey-8d21114df0ee75e2129916acb38b212704ed78cf.tar.bz2
Working TOTP handling (passing RFC tests)
Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
-rw-r--r--NK_C_API.cc12
-rw-r--r--NK_C_API.h5
-rw-r--r--NitrokeyManager.cc24
-rw-r--r--build/test.py33
-rw-r--r--include/NitrokeyManager.h4
-rw-r--r--include/stick10_commands.h6
6 files changed, 69 insertions, 15 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc
index 4d9b17e..8fbd6db 100644
--- a/NK_C_API.cc
+++ b/NK_C_API.cc
@@ -47,9 +47,9 @@ extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const
}
extern int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window,
- const char *temporary_password) {
+ bool use_8_digits, const char *temporary_password) {
auto m = NitrokeyManager::instance();
- return m->write_TOTP_slot(slot_number, slot_name, secret, time_window, temporary_password);
+ return m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, temporary_password);
}
extern const char* NK_get_totp_slot_name(uint8_t slot_number){
@@ -66,5 +66,13 @@ extern void NK_set_debug(bool state){
m->set_debug(state);
}
+extern int NK_totp_set_time(uint64_t time){
+ auto m = NitrokeyManager::instance();
+ return m->set_time(time);
+}
+extern int NK_totp_mark_time(){
+ auto m = NitrokeyManager::instance();
+ return m->mark_time();
+}
} \ No newline at end of file
diff --git a/NK_C_API.h b/NK_C_API.h
index db441c4..e0d0ede 100644
--- a/NK_C_API.h
+++ b/NK_C_API.h
@@ -8,6 +8,7 @@
extern "C"
{
+//Make sure each function's declaration is in one line (for automatic python declaration processing)
extern void NK_set_debug(bool state);
extern int NK_login(const char *pin, const char *temporary_password);
extern int NK_logout();
@@ -16,9 +17,11 @@ extern const char * NK_get_totp_slot_name(uint8_t slot_number);
extern const char * NK_get_hotp_slot_name(uint8_t slot_number);
extern int NK_erase_slot(uint8_t slot_number);
extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, const char *temporary_password);
-extern int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, const char *temporary_password);
+extern int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, const char *temporary_password);
extern uint32_t NK_get_hotp_code(uint8_t slot_number);
extern uint32_t NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval);
+extern int NK_totp_set_time(uint64_t time);
+extern int NK_totp_mark_time();
}
diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc
index d35e333..0fb4c57 100644
--- a/NitrokeyManager.cc
+++ b/NitrokeyManager.cc
@@ -68,6 +68,7 @@ namespace nitrokey{
uint32_t NitrokeyManager::get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time,
uint8_t last_interval) {
assert(is_valid_totp_slot_number(slot_number));
+ slot_number = get_internal_slot_number_for_totp(slot_number);
auto gt = get_payload<GetTOTP>();
gt.slot_number = slot_number;
gt.challenge = challenge;
@@ -119,8 +120,10 @@ namespace nitrokey{
return false;
}
+ enum totp_config{digits8=0, enter, tokenID};
+
bool NitrokeyManager::write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret,
- uint16_t time_window, const char *temporary_password) {
+ uint16_t time_window, bool use_8_digits, const char *temporary_password) {
assert(is_valid_totp_slot_number(slot_number));
assert(strlen(secret)==20); //160 bits
assert(strlen(slot_name)<=15);
@@ -131,7 +134,9 @@ namespace nitrokey{
strcpy((char *) payload.slot_secret, secret);
strcpy((char *) payload.slot_name, slot_name);
payload.slot_interval = time_window; //FIXME naming
- payload.slot_config; //TODO
+ bitset<8> config; //FIXME better config manipulation
+ config.set(totp_config::digits8, use_8_digits);
+ payload.slot_config = (uint8_t) config.to_ulong();
auto auth = get_payload<Authorize>();
strcpy((char *) (auth.temporary_password), temporary_password);
@@ -168,5 +173,20 @@ namespace nitrokey{
return true;
}
+ bool NitrokeyManager::set_time(uint64_t time) {
+ auto p = get_payload<SetTime>();
+ p.reset = 1;
+ p.time = time;
+ SetTime::CommandTransaction::run(*device, p);
+ return false;
+ }
+
+ bool NitrokeyManager::mark_time() {
+ auto p = get_payload<SetTime>();
+ p.reset = 0;
+ SetTime::CommandTransaction::run(*device, p);
+ return false;
+ }
+
} \ No newline at end of file
diff --git a/build/test.py b/build/test.py
index 9d967ca..5117410 100644
--- a/build/test.py
+++ b/build/test.py
@@ -46,15 +46,30 @@ if __name__ == "__main__":
for i in range(3):
s.append(C.NK_get_hotp_code(i))
print(repr(s))
- print((s))
+ print(s)
# C.NK_set_debug(True)
- s = []
- C.NK_write_hotp_slot(1, 'python_test', '12345678901234567890', 0, '123123123')
- C.NK_set_debug(False)
- for i in range(3):
- s.append(C.NK_get_hotp_code(1))
- print((s))
+ # s = []
+ # C.NK_write_hotp_slot(1, 'python_test', '12345678901234567890', 0, '123123123')
+ # C.NK_set_debug(False)
+ # for i in range(3):
+ # s.append(C.NK_get_hotp_code(1))
+ # print((s))
+
+ # C.NK_totp_mark_time()
+
+ # test according to https://tools.ietf.org/html/rfc6238#appendix-B
+ C.NK_write_totp_slot(1, 'python_test', '12345678901234567890', 30, True, '123123123')
C.NK_set_debug(True)
- C.NK_write_totp_slot(1, 'python_test', '12345678901234567890', 30, '123123123')
- print ( C.NK_get_totp_code(1, 59, 0, 30) ) \ No newline at end of file
+ test_data = [
+ (59, 1, 94287082),
+ (1111111109, 0x00000000023523EC, 7081804),
+ (1111111111, 0x00000000023523ED, 14050471),
+ (1234567890, 0x000000000273EF07, 89005924),
+ ]
+ a = []
+ for t, T, code in test_data:
+ C.NK_totp_set_time(t)
+ r = C.NK_get_totp_code(1, T, 0, 30) # FIXME T is not changing the outcome
+ a.append((r, code == r))
+ print(a)
diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h
index 551bea7..7d04799 100644
--- a/include/NitrokeyManager.h
+++ b/include/NitrokeyManager.h
@@ -21,10 +21,12 @@ namespace nitrokey {
bool write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter,
const char *temporary_password);
bool write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret,
- uint16_t time_window, const char *temporary_password);
+ uint16_t time_window, bool use_8_digits, const char *temporary_password);
uint32_t get_HOTP_code(uint8_t slot_number);
uint32_t get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time,
uint8_t last_interval);
+ bool set_time(uint64_t time);
+ bool mark_time();
bool erase_totp_slot(uint8_t slot_number);
bool erase_hotp_slot(uint8_t slot_number);
bool connect();
diff --git a/include/stick10_commands.h b/include/stick10_commands.h
index 13842fb..ca836db 100644
--- a/include/stick10_commands.h
+++ b/include/stick10_commands.h
@@ -68,6 +68,12 @@ class SetTime : Command<CommandID::SET_TIME> {
uint64_t time; // posix time
bool isValid() const { return reset && reset != 1; }
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "reset:\t" << (int)(reset) << std::endl;
+ ss << "time:\t" << (time) << std::endl;
+ return ss.str();
+ }
} __packed;
typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>