#include #include "NK_C_API.h" using namespace nitrokey; static uint8_t NK_last_command_status = 0; template T* array_dup(std::vector& v){ auto d = new T[v.size()]; std::copy(v.begin(), v.end(), d); return d; } template uint8_t * get_with_array_result(T func){ try { return func(); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return nullptr; } } template const char* get_with_string_result(T func){ try { return func(); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return ""; } } template auto get_with_result(T func){ try { return func(); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } } template uint8_t get_without_result(T func){ try { func(); NK_last_command_status = 0; return 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } } extern "C" { extern uint8_t NK_get_last_command_status(){ auto _copy = NK_last_command_status; NK_last_command_status = 0; return _copy; } extern int NK_login(const char *device_model) { auto m = NitrokeyManager::instance(); try { m->connect(device_model); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_logout() { auto m = NitrokeyManager::instance(); try { m->disconnect(); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password){ auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->first_authenticate(admin_password, admin_temporary_password); }); } extern int NK_user_authenticate(const char* user_password, const char* user_temporary_password){ auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->user_authenticate(user_password, user_temporary_password); }); } extern int NK_factory_reset(const char* admin_password){ auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->factory_reset(admin_password); }); } extern int NK_build_aes_key(const char* admin_password){ auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->build_aes_key(admin_password); }); } extern int NK_unlock_user_password(const char* admin_password){ auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->unlock_user_password(admin_password); }); } extern int NK_write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result( [&](){ return m->write_config(numlock, capslock, scrolllock, enable_user_password, delete_user_password, admin_temporary_password); }); } extern uint8_t* NK_read_config(){ auto m = NitrokeyManager::instance(); return get_with_array_result( [&](){ auto v = m->read_config(); return array_dup(v); }); } extern const char * NK_status() { auto m = NitrokeyManager::instance(); try { string s = m->get_status(); NK_last_command_status = 0; return strdup(s.c_str()); //FIXME leak? } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } return ""; } extern uint32_t NK_get_hotp_code(uint8_t slot_number) { return NK_get_hotp_code_PIN(slot_number, ""); } extern uint32_t NK_get_hotp_code_PIN(uint8_t slot_number, const char* user_temporary_password){ auto m = NitrokeyManager::instance(); try { const auto code = m->get_HOTP_code(slot_number, user_temporary_password); NK_last_command_status = 0; return code; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } return 0; } extern uint32_t NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval){ return NK_get_totp_code_PIN(slot_number, challenge, last_totp_time, last_interval, ""); } extern uint32_t NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char* user_temporary_password){ auto m = NitrokeyManager::instance(); try { const auto totp_code = m->get_TOTP_code(slot_number, challenge, last_totp_time, last_interval, user_temporary_password); NK_last_command_status = 0; return totp_code; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } return 0; } extern int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password) { auto m = NitrokeyManager::instance(); try { m->erase_hotp_slot(slot_number, temporary_password); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password) { auto m = NitrokeyManager::instance(); try { m->erase_totp_slot(slot_number, temporary_password); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, bool use_8_digits, const char *temporary_password) { auto m = NitrokeyManager::instance(); try { m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, temporary_password); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } 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) { auto m = NitrokeyManager::instance(); try { m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, temporary_password); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern const char* NK_get_totp_slot_name(uint8_t slot_number){ auto m = NitrokeyManager::instance(); try { const auto slot_name = m->get_totp_slot_name(slot_number); NK_last_command_status = 0; return slot_name; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return ""; } } extern const char* NK_get_hotp_slot_name(uint8_t slot_number){ auto m = NitrokeyManager::instance(); try { const auto slot_name = m->get_hotp_slot_name(slot_number); NK_last_command_status = 0; return slot_name; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return ""; } } extern void NK_set_debug(bool state){ auto m = NitrokeyManager::instance(); m->set_debug(state); } extern int NK_totp_set_time(uint64_t time){ auto m = NitrokeyManager::instance(); try { m->set_time(time); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_totp_get_time(){ auto m = NitrokeyManager::instance(); try { m->get_time(); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_change_admin_PIN(char *current_PIN, char *new_PIN){ auto m = NitrokeyManager::instance(); try { m->change_admin_PIN(current_PIN, new_PIN); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_change_user_PIN(char *current_PIN, char *new_PIN){ auto m = NitrokeyManager::instance(); try { m->change_user_PIN(current_PIN, new_PIN); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern int NK_enable_password_safe(const char *user_pin){ auto m = NitrokeyManager::instance(); try { m->enable_password_safe(user_pin); NK_last_command_status = 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } return 0; } extern uint8_t * NK_get_password_safe_slot_status(){ auto m = NitrokeyManager::instance(); auto res = new uint8_t[16]; memset(res, 0, 16); try { const auto slot_status = m->get_password_safe_slot_status(); NK_last_command_status = 0; return slot_status; //TODO FIXME } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } return res; } extern uint8_t NK_get_user_retry_count(){ auto m = NitrokeyManager::instance(); return get_with_result([&](){ return m->get_user_retry_count(); }); } extern uint8_t NK_get_admin_retry_count(){ auto m = NitrokeyManager::instance(); return get_with_result([&](){ return m->get_admin_retry_count(); }); } extern int NK_lock_device(){ auto m = NitrokeyManager::instance(); return get_without_result([&](){ m->lock_device(); }); } extern const char *NK_get_password_safe_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&](){ return m->get_password_safe_slot_name(slot_number); }); } extern const char *NK_get_password_safe_slot_login(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&](){ return m->get_password_safe_slot_login(slot_number); }); } extern const char *NK_get_password_safe_slot_password(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&](){ return m->get_password_safe_slot_password(slot_number); }); } extern int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, const char *slot_password) { auto m = NitrokeyManager::instance(); return get_without_result([&](){ m->write_password_safe_slot(slot_number, slot_name, slot_login, slot_password); }); } extern int NK_erase_password_safe_slot(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_without_result([&](){ m->erase_password_safe_slot(slot_number); }); } }