From 05ae75697be8df1b2179035d3ef8dc6b2e7fe30f Mon Sep 17 00:00:00 2001 From: Elie Tournier Date: Tue, 18 Apr 2017 09:27:17 +0100 Subject: Rename files: s/stick10/NKPro and s/stick20/NKStorage Signed-off-by: Elie Tournier --- CMakeLists.txt | 6 +- NitrokeyManager.cc | 2 +- README.md | 2 +- include/NKPro_commands.h | 857 +++++++++++++++++++++++++++++++++++++++++ include/NKPro_commands_0.8.h | 326 ++++++++++++++++ include/NKStorage_commands.h | 346 +++++++++++++++++ include/NitrokeyManager.h | 6 +- include/stick10_commands.h | 857 ----------------------------------------- include/stick10_commands_0.8.h | 326 ---------------- include/stick20_commands.h | 346 ----------------- unittest/test.cc | 2 +- unittest/test2.cc | 4 +- unittest/test_HOTP.cc | 2 +- 13 files changed, 1541 insertions(+), 1541 deletions(-) create mode 100644 include/NKPro_commands.h create mode 100644 include/NKPro_commands_0.8.h create mode 100644 include/NKStorage_commands.h delete mode 100644 include/stick10_commands.h delete mode 100644 include/stick10_commands_0.8.h delete mode 100644 include/stick20_commands.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b1103db..270d13e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,12 +48,12 @@ set(SOURCE_FILES include/log.h include/misc.h include/NitrokeyManager.h - include/stick10_commands.h - include/stick20_commands.h + include/NKPro_commands.h + include/NKStorage_commands.h include/CommandFailedException.h include/LibraryException.h include/LongOperationInProgressException.h - include/stick10_commands_0.8.h + include/NKPro_commands_0.8.h command_id.cc device.cc log.cc diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 9a9d106..d491fa9 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -4,7 +4,7 @@ #include "include/LibraryException.h" #include #include -#include +#include #include "include/misc.h" #include #include "include/cxx_semantics.h" diff --git a/README.md b/README.md index 99c4a44..d0e1ce6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # libnitrokey Libnitrokey is a project to communicate with Nitrokey Pro and Storage devices in a clean and easy manner. Written in C++14, testable with `py.test` and `Catch` frameworks, with C API, Python access (through CFFI and C API, in future with Pybind11). -The development of this project is aimed to make it itself a living documentation of communication protocol between host and the Nitrokey stick devices. The command packets' format is described here: [Pro v0.7](include/stick10_commands.h), [Pro v0.8](include/stick10_commands_0.8.h), [Storage](include/stick20_commands.h). Handling and additional operations are described here: [NitrokeyManager.cc](NitrokeyManager.cc). +The development of this project is aimed to make it itself a living documentation of communication protocol between host and the Nitrokey stick devices. The command packets' format is described here: [Pro v0.7](include/NKPro_commands.h), [Pro v0.8](include/NKPro_commands_0.8.h), [Storage](include/NKStorage_commands.h). Handling and additional operations are described here: [NitrokeyManager.cc](NitrokeyManager.cc). A C++14 complying compiler is required due to heavy use of variable templates. For feature support tables please check [table 1](https://gcc.gnu.org/projects/cxx-status.html#cxx14) or [table 2](http://en.cppreference.com/w/cpp/compiler_support). diff --git a/include/NKPro_commands.h b/include/NKPro_commands.h new file mode 100644 index 0000000..e863328 --- /dev/null +++ b/include/NKPro_commands.h @@ -0,0 +1,857 @@ +#ifndef STICK10_COMMANDS_H +#define STICK10_COMMANDS_H + +#include +#include +#include +#include +#include +#include "device_proto.h" +#include "command.h" + +#pragma pack (push,1) + +namespace nitrokey { +namespace proto { + + + +/* + * Stick10 protocol definition + */ +namespace stick10 { +class GetSlotName : public Command { + public: + // reachable as a typedef in Transaction + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return slot_number<0x10+3; } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + uint8_t slot_name[15]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(slot_name); + return ss.str(); + } + } __packed; + + typedef Transaction CommandTransaction; +}; + +class EraseSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class SetTime : Command { + public: + struct CommandPayload { + uint8_t reset; // 0 - get time, 1 - 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 + CommandTransaction; +}; + + +class WriteToHOTPSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t slot_name[15]; + uint8_t slot_secret[20]; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + union{ + uint8_t slot_token_id[13]; /** OATH Token Identifier */ + struct{ /** @see https://openauthentication.org/token-specs/ */ + uint8_t omp[2]; + uint8_t tt[2]; + uint8_t mui[8]; + uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 + } slot_token_fields; + }; + union{ + uint64_t slot_counter; + uint8_t slot_counter_s[8]; + } __packed; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + print_to_ss_volatile(slot_name); + print_to_ss_volatile(slot_secret); + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + + ss << "slot_token_id:\t"; + for (auto i : slot_token_id) + ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; + ss << std::endl; + ss << "slot_counter:\t[" << (int)slot_counter << "]\t" + << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); + + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class WriteToTOTPSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t slot_name[15]; + uint8_t slot_secret[20]; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + union{ + uint8_t slot_token_id[13]; /** OATH Token Identifier */ + struct{ /** @see https://openauthentication.org/token-specs/ */ + uint8_t omp[2]; + uint8_t tt[2]; + uint8_t mui[8]; + uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 + } slot_token_fields; + }; + uint16_t slot_interval; + + bool isValid() const { return !(slot_number & 0xF0); } //TODO check + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + print_to_ss_volatile(slot_name); + print_to_ss_volatile(slot_secret); + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "slot_token_id:\t"; + for (auto i : slot_token_id) + ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; + ss << std::endl; + ss << "slot_interval:\t" << (int)slot_interval << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class GetTOTP : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint64_t challenge; + uint64_t last_totp_time; + uint8_t last_interval; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + ss << "challenge:\t" << (challenge) << std::endl; + ss << "last_totp_time:\t" << (last_totp_time) << std::endl; + ss << "last_interval:\t" << (int)(last_interval) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + union { + uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 + struct { + uint32_t code; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + } __packed ; + } __packed ; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << "code:\t" << (code) << std::endl; + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class GetHOTP : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return (slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + union { + uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 + struct { + uint32_t code; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + } __packed; + } __packed; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << "code:\t" << (code) << std::endl; + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class ReadSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + uint8_t slot_name[15]; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + union{ + uint8_t slot_token_id[13]; /** OATH Token Identifier */ + struct{ /** @see https://openauthentication.org/token-specs/ */ + uint8_t omp[2]; + uint8_t tt[2]; + uint8_t mui[8]; + uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 + } slot_token_fields; + }; + union{ + uint64_t slot_counter; + uint8_t slot_counter_s[8]; + } __packed; + + bool isValid() const { return true; } + + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(slot_name); + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + + ss << "slot_token_id:\t"; + for (auto i : slot_token_id) + ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; + ss << std::endl; + ss << "slot_counter:\t[" << (int)slot_counter << "]\t" + << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); + return ss.str(); + } + } __packed; + + typedef Transaction CommandTransaction; +}; + +class GetStatus : Command { + public: + struct ResponsePayload { + uint16_t firmware_version; + union{ + uint8_t card_serial[4]; + uint32_t card_serial_u32; + } __packed; + union { + uint8_t general_config[5]; + struct{ + uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ + uint8_t capslock; /** same as numlock */ + uint8_t scrolllock; /** same as numlock */ + uint8_t enable_user_password; + uint8_t delete_user_password; + } __packed; + } __packed; + bool isValid() const { return enable_user_password!=delete_user_password; } + + std::string get_card_serial_hex() const { + return nitrokey::misc::toHex(card_serial_u32); + } + + std::string dissect() const { + std::stringstream ss; + ss << "firmware_version:\t" + << "[" << firmware_version << "]" << "\t" + << ::nitrokey::misc::hexdump( + (const char *)(&firmware_version), sizeof firmware_version, false); + ss << "card_serial_u32:\t" << std::hex << card_serial_u32 << std::endl; + ss << "card_serial:\t" + << ::nitrokey::misc::hexdump((const char *)(card_serial), + sizeof card_serial, false); + ss << "general_config:\t" + << ::nitrokey::misc::hexdump((const char *)(general_config), + sizeof general_config, false); + ss << "numlock:\t" << (int)numlock << std::endl; + ss << "capslock:\t" << (int)capslock << std::endl; + ss << "scrolllock:\t" << (int)scrolllock << std::endl; + ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; + ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; + + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class GetPasswordRetryCount : Command { + public: + struct ResponsePayload { + uint8_t password_retry_count; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << " password_retry_count\t" << (int)password_retry_count << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class GetUserPasswordRetryCount + : Command { + public: + struct ResponsePayload { + uint8_t password_retry_count; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << " password_retry_count\t" << (int)password_retry_count << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + + template + void write_array(T &ss, Q (&arr)[N]){ + for (int i=0; i { + public: + struct ResponsePayload { + uint8_t password_safe_status[PWS_SLOT_COUNT]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << "password_safe_status\t"; + write_array(ss, password_safe_status); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class GetPasswordSafeSlotName : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number\t" << (int)slot_number << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + uint8_t slot_name[PWS_SLOTNAME_LENGTH]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(slot_name); + return ss.str(); + } + } __packed; + + typedef Transaction CommandTransaction; +}; + +class GetPasswordSafeSlotPassword + : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << " slot_number\t" << (int)slot_number << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + uint8_t slot_password[PWS_PASSWORD_LENGTH]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(slot_password); + return ss.str(); + } + } __packed; + + typedef Transaction CommandTransaction; +}; + +class GetPasswordSafeSlotLogin + : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << " slot_number\t" << (int)slot_number << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + uint8_t slot_login[PWS_LOGINNAME_LENGTH]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(slot_login); + return ss.str(); + } + } __packed; + + typedef Transaction CommandTransaction; +}; + +class SetPasswordSafeSlotData : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t slot_name[PWS_SLOTNAME_LENGTH]; + uint8_t slot_password[PWS_PASSWORD_LENGTH]; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << " slot_number\t" << (int)slot_number << std::endl; + print_to_ss_volatile(slot_name); + print_to_ss_volatile(slot_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class SetPasswordSafeSlotData2 : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t slot_login_name[PWS_LOGINNAME_LENGTH]; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << " slot_number\t" << (int)slot_number << std::endl; + print_to_ss_volatile(slot_login_name); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class ErasePasswordSafeSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << " slot_number\t" << (int)slot_number << std::endl; + return ss.str(); + } + + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class EnablePasswordSafe : Command { + public: + struct CommandPayload { + uint8_t user_password[30]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(user_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class PasswordSafeInitKey : Command { + /** + * never used in Nitrokey App + */ + public: + typedef Transaction + CommandTransaction; +}; + +class PasswordSafeSendSlotViaHID : Command { + /** + * never used in Nitrokey App + */ + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t slot_kind; + + bool isValid() const { return !(slot_number & 0xF0); } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +// TODO "Device::passwordSafeSendSlotDataViaHID" + +class WriteGeneralConfig : Command { + public: + struct CommandPayload { + union{ + uint8_t config[5]; + struct{ + uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ + uint8_t capslock; /** same as numlock */ + uint8_t scrolllock; /** same as numlock */ + uint8_t enable_user_password; + uint8_t delete_user_password; + }; + }; + std::string dissect() const { + std::stringstream ss; + ss << "numlock:\t" << (int)numlock << std::endl; + ss << "capslock:\t" << (int)capslock << std::endl; + ss << "scrolllock:\t" << (int)scrolllock << std::endl; + ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; + ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class FirstAuthenticate : Command { + public: + struct CommandPayload { + uint8_t card_password[25]; + uint8_t temporary_password[25]; + + bool isValid() const { return true; } + + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(card_password); + hexdump_to_ss(temporary_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class UserAuthenticate : Command { + public: + struct CommandPayload { + uint8_t card_password[25]; + uint8_t temporary_password[25]; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(card_password); + hexdump_to_ss(temporary_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class Authorize : Command { + public: + struct CommandPayload { + uint32_t crc_to_authorize; + uint8_t temporary_password[25]; + + std::string dissect() const { + std::stringstream ss; + ss << " crc_to_authorize:\t" << std::hex << std::setw(2) << std::setfill('0') << crc_to_authorize<< std::endl; + hexdump_to_ss(temporary_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class UserAuthorize : Command { + public: + struct CommandPayload { + uint32_t crc_to_authorize; + uint8_t temporary_password[25]; + std::string dissect() const { + std::stringstream ss; + ss << " crc_to_authorize:\t" << crc_to_authorize<< std::endl; + hexdump_to_ss(temporary_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class UnlockUserPassword : Command { + public: + struct CommandPayload { + uint8_t admin_password[25]; + uint8_t user_new_password[25]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(admin_password); + print_to_ss_volatile(user_new_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class ChangeUserPin : Command { + public: + struct CommandPayload { + uint8_t old_pin[25]; + uint8_t new_pin[25]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(old_pin); + print_to_ss_volatile(new_pin); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class IsAESSupported : Command { + public: + struct CommandPayload { + uint8_t user_password[20]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(user_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + + +class ChangeAdminPin : Command { + public: + struct CommandPayload { + uint8_t old_pin[25]; + uint8_t new_pin[25]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(old_pin); + print_to_ss_volatile(new_pin); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class LockDevice : Command { + public: + typedef Transaction + CommandTransaction; +}; + +class FactoryReset : Command { + public: + struct CommandPayload { + uint8_t admin_password[20]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(admin_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; +}; + +class BuildAESKey : Command { + public: + struct CommandPayload { + uint8_t admin_password[20]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile(admin_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + +}; + +} +} +} +#pragma pack (pop) +#endif diff --git a/include/NKPro_commands_0.8.h b/include/NKPro_commands_0.8.h new file mode 100644 index 0000000..76bb030 --- /dev/null +++ b/include/NKPro_commands_0.8.h @@ -0,0 +1,326 @@ +// +// Created by sz on 08.11.16. +// + +#ifndef LIBNITROKEY_STICK10_COMMANDS_0_8_H +#define LIBNITROKEY_STICK10_COMMANDS_0_8_H + +#include +#include +#include +#include +#include +#include "command.h" +#include "device_proto.h" +#include "NKPro_commands.h" + +#pragma pack (push,1) + + +namespace nitrokey { + namespace proto { + +/* + * Stick10 protocol definition + */ + namespace stick10_08 { + using stick10::FirstAuthenticate; + using stick10::UserAuthenticate; + using stick10::SetTime; + using stick10::GetStatus; + using stick10::BuildAESKey; + using stick10::ChangeAdminPin; + using stick10::ChangeUserPin; + using stick10::EnablePasswordSafe; + using stick10::ErasePasswordSafeSlot; + using stick10::FactoryReset; + using stick10::GetPasswordRetryCount; + using stick10::GetUserPasswordRetryCount; + using stick10::GetPasswordSafeSlotLogin; + using stick10::GetPasswordSafeSlotName; + using stick10::GetPasswordSafeSlotPassword; + using stick10::GetPasswordSafeSlotStatus; + using stick10::GetSlotName; + using stick10::IsAESSupported; + using stick10::LockDevice; + using stick10::PasswordSafeInitKey; + using stick10::PasswordSafeSendSlotViaHID; + using stick10::SetPasswordSafeSlotData; + using stick10::SetPasswordSafeSlotData2; + using stick10::UnlockUserPassword; + using stick10::ReadSlot; + + class EraseSlot : Command { + public: + struct CommandPayload { + uint8_t slot_number; + uint8_t temporary_admin_password[25]; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + hexdump_to_ss(temporary_admin_password); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + class SendOTPData : Command { + //admin auth + public: + struct CommandPayload { + uint8_t temporary_admin_password[25]; + uint8_t type; //S-secret, N-name + uint8_t id; //multiple reports for values longer than 30 bytes + uint8_t data[30]; //data, does not need null termination + + bool isValid() const { return true; } + + void setTypeName(){ + type = 'N'; + } + void setTypeSecret(){ + type = 'S'; + } + + std::string dissect() const { + std::stringstream ss; + hexdump_to_ss(temporary_admin_password); + ss << "type:\t" << type << std::endl; + ss << "id:\t" << (int)id << std::endl; +#ifdef LOG_VOLATILE_DATA + ss << "data:" << std::endl + << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); +#else + ss << " Volatile data not logged" << std::endl; +#endif + return ss.str(); + } + } __packed; + + + struct ResponsePayload { + union { + uint8_t data[40]; + } __packed; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; +#ifdef LOG_VOLATILE_DATA + ss << "data:" << std::endl + << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); +#else + ss << " Volatile data not logged" << std::endl; +#endif + return ss.str(); + } + } __packed; + + + typedef Transaction + CommandTransaction; + }; + + class WriteToOTPSlot : Command { + //admin auth + public: + struct CommandPayload { + uint8_t temporary_admin_password[25]; + uint8_t slot_number; + union { + uint64_t slot_counter_or_interval; + uint8_t slot_counter_s[8]; + } __packed; + union { + uint8_t _slot_config; + struct { + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + union { + uint8_t slot_token_id[13]; /** OATH Token Identifier */ + struct { /** @see https://openauthentication.org/token-specs/ */ + uint8_t omp[2]; + uint8_t tt[2]; + uint8_t mui[8]; + uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 + } slot_token_fields; + }; + + bool isValid() const { return true; } + + std::string dissect() const { + std::stringstream ss; + hexdump_to_ss(temporary_admin_password); + ss << "slot_config:\t" << std::bitset<8>((int) _slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + ss << "slot_number:\t" << (int) (slot_number) << std::endl; + ss << "slot_counter_or_interval:\t[" << (int) slot_counter_or_interval << "]\t" + << ::nitrokey::misc::hexdump((const char *) (&slot_counter_or_interval), sizeof slot_counter_or_interval, false); + + ss << "slot_token_id:\t"; + for (auto i : slot_token_id) + ss << std::hex << std::setw(2) << std::setfill('0') << (int) i << " "; + ss << std::endl; + + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + class GetHOTP : Command { + public: + struct CommandPayload { + uint8_t slot_number; + struct { + uint64_t challenge; //@unused + uint64_t last_totp_time; //@unused + uint8_t last_interval; //@unused + } __packed _unused; + uint8_t temporary_user_password[25]; + + bool isValid() const { return (slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + hexdump_to_ss(temporary_user_password); + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + union { + uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 + struct { + uint32_t code; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + } __packed; + } __packed; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << "code:\t" << (code) << std::endl; + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + + class GetTOTP : Command { + //user auth + public: + struct CommandPayload { + uint8_t slot_number; + uint64_t challenge; //@unused + uint64_t last_totp_time; //@unused + uint8_t last_interval; //@unused + uint8_t temporary_user_password[25]; + + bool isValid() const { return !(slot_number & 0xF0); } + std::string dissect() const { + std::stringstream ss; + hexdump_to_ss(temporary_user_password); + ss << "slot_number:\t" << (int)(slot_number) << std::endl; + ss << "challenge:\t" << (challenge) << std::endl; + ss << "last_totp_time:\t" << (last_totp_time) << std::endl; + ss << "last_interval:\t" << (int)(last_interval) << std::endl; + return ss.str(); + } + } __packed; + + struct ResponsePayload { + union { + uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 + struct { + uint32_t code; + union{ + uint8_t _slot_config; + struct{ + bool use_8_digits : 1; + bool use_enter : 1; + bool use_tokenID : 1; + }; + }; + } __packed ; + } __packed ; + + bool isValid() const { return true; } + std::string dissect() const { + std::stringstream ss; + ss << "code:\t" << (code) << std::endl; + ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; + ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; + ss << "\tuse_enter(1):\t" << use_enter << std::endl; + ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + + class WriteGeneralConfig : Command { + //admin auth + public: + struct CommandPayload { + union{ + uint8_t config[5]; + struct{ + uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ + uint8_t capslock; /** same as numlock */ + uint8_t scrolllock; /** same as numlock */ + uint8_t enable_user_password; + uint8_t delete_user_password; + }; + }; + uint8_t temporary_admin_password[25]; + + std::string dissect() const { + std::stringstream ss; + ss << "numlock:\t" << (int)numlock << std::endl; + ss << "capslock:\t" << (int)capslock << std::endl; + ss << "scrolllock:\t" << (int)scrolllock << std::endl; + ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; + ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + } + } +} +#pragma pack (pop) + +#endif //LIBNITROKEY_STICK10_COMMANDS_0_8_H diff --git a/include/NKStorage_commands.h b/include/NKStorage_commands.h new file mode 100644 index 0000000..5f99d28 --- /dev/null +++ b/include/NKStorage_commands.h @@ -0,0 +1,346 @@ +#ifndef STICK20_COMMANDS_H +#define STICK20_COMMANDS_H + + + +#include +#include "command.h" +#include +#include +#include "device_proto.h" + +#pragma pack (push,1) + +namespace nitrokey { + namespace proto { + +/* +* STICK20 protocol command ids +* a superset (almost) of STICK10 +*/ + + namespace stick20 { + + class ChangeAdminUserPin20Current : + public PasswordCommand {}; + class ChangeAdminUserPin20New : + public PasswordCommand {}; + class UnlockUserPin : + public PasswordCommand {}; + + class EnableEncryptedPartition : public PasswordCommand {}; + class EnableHiddenEncryptedPartition : public PasswordCommand {}; + + //FIXME the volume disabling commands do not need password + class DisableEncryptedPartition : public PasswordCommand {}; + class DisableHiddenEncryptedPartition : public PasswordCommand {}; + + class EnableFirmwareUpdate : public PasswordCommand {}; + + class ChangeUpdatePassword : Command { + public: + struct CommandPayload { + uint8_t __gap; + uint8_t current_update_password[20]; + uint8_t __gap2; + uint8_t new_update_password[20]; + std::string dissect() const { + std::stringstream ss; + print_to_ss_volatile( current_update_password ); + print_to_ss_volatile( new_update_password ); + return ss.str(); + } + }; + + typedef Transaction + CommandTransaction; + }; + + class ExportFirmware : public PasswordCommand {}; + + class CreateNewKeys : + public PasswordCommand {}; + + + class FillSDCardWithRandomChars : Command { + public: + enum class ChosenVolumes : uint8_t { + all_volumes = 0, + encrypted_volume = 1 + }; + + struct CommandPayload { + uint8_t volume_flag; + uint8_t kind; + uint8_t admin_pin[20]; + + std::string dissect() const { + std::stringstream ss; + print_to_ss( (int) volume_flag ); + print_to_ss( kind ); + print_to_ss_volatile(admin_pin); + return ss.str(); + } + void set_kind_user() { + kind = (uint8_t) 'P'; + } + void set_defaults(){ + set_kind_user(); + volume_flag = static_cast(ChosenVolumes::encrypted_volume); + } + + } __packed; + + typedef Transaction::command_id(), + struct CommandPayload, struct EmptyPayload> + CommandTransaction; + }; + + namespace StorageCommandResponsePayload{ + using namespace DeviceResponseConstants; + static constexpr auto padding_size = + storage_data_absolute_address - header_size; + struct TransmissionData{ + uint8_t _padding[padding_size]; + + uint8_t SendCounter_u8; + uint8_t SendDataType_u8; + uint8_t FollowBytesFlag_u8; + uint8_t SendSize_u8; + + std::string dissect() const { + std::stringstream ss; + ss << "_padding:" << std::endl + << ::nitrokey::misc::hexdump((const char *) (_padding), + sizeof _padding); + print_to_ss((int) SendCounter_u8); + print_to_ss((int) SendDataType_u8); + print_to_ss((int) FollowBytesFlag_u8); + print_to_ss((int) SendSize_u8); + return ss.str(); + } + + } __packed; + } + + namespace DeviceConfigurationResponsePacket{ + + struct ResponsePayload { + StorageCommandResponsePayload::TransmissionData transmission_data; + + uint16_t MagicNumber_StickConfig_u16; + /** + * READ_WRITE_ACTIVE = ReadWriteFlagUncryptedVolume_u8 == 0; + */ + uint8_t ReadWriteFlagUncryptedVolume_u8; + uint8_t ReadWriteFlagCryptedVolume_u8; + + union{ + uint8_t VersionInfo_au8[4]; + struct { + uint8_t __reserved; + uint8_t minor; + uint8_t __reserved2; + uint8_t major; + } __packed versionInfo; + } __packed; + + uint8_t ReadWriteFlagHiddenVolume_u8; + uint8_t FirmwareLocked_u8; + + union{ + uint8_t NewSDCardFound_u8; + struct { + bool NewCard :1; + uint8_t Counter :7; + } __packed NewSDCardFound_st; + } __packed; + + /** + * SD card FILLED with random chars + */ + uint8_t SDFillWithRandomChars_u8; + uint32_t ActiveSD_CardID_u32; + union{ + uint8_t VolumeActiceFlag_u8; + struct { + bool unencrypted :1; + bool encrypted :1; + bool hidden :1; + } __packed VolumeActiceFlag_st; + } __packed; + uint8_t NewSmartCardFound_u8; + uint8_t UserPwRetryCount; + uint8_t AdminPwRetryCount; + uint32_t ActiveSmartCardID_u32; + uint8_t StickKeysNotInitiated; + + bool isValid() const { return true; } + + std::string dissect() const { + std::stringstream ss; + + print_to_ss(transmission_data.dissect()); + print_to_ss( MagicNumber_StickConfig_u16 ); + print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 ); + print_to_ss((int) ReadWriteFlagCryptedVolume_u8 ); + print_to_ss((int) VersionInfo_au8[1] ); + print_to_ss((int) VersionInfo_au8[3] ); + print_to_ss((int) ReadWriteFlagHiddenVolume_u8 ); + print_to_ss((int) FirmwareLocked_u8 ); + print_to_ss((int) NewSDCardFound_u8 ); + print_to_ss((int) SDFillWithRandomChars_u8 ); + print_to_ss( ActiveSD_CardID_u32 ); + print_to_ss((int) VolumeActiceFlag_u8 ); + print_to_ss((int) NewSmartCardFound_u8 ); + print_to_ss((int) UserPwRetryCount ); + print_to_ss((int) AdminPwRetryCount ); + print_to_ss( ActiveSmartCardID_u32 ); + print_to_ss((int) StickKeysNotInitiated ); + + return ss.str(); + } + } __packed; + } + + class SendStartup : Command { + public: + struct CommandPayload { + uint64_t localtime; // POSIX seconds from epoch start, supports until year 2106 + std::string dissect() const { + std::stringstream ss; + print_to_ss( localtime ); + return ss.str(); + } + void set_defaults(){ + localtime = + std::chrono::duration_cast ( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + }__packed; + + using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; + + typedef Transaction + CommandTransaction; + }; + + +// TODO fix original nomenclature + class SendSetReadonlyToUncryptedVolume : public PasswordCommand {}; + class SendSetReadwriteToUncryptedVolume : public PasswordCommand {}; + class SendClearNewSdCardFound : public PasswordCommand {}; + + class GetDeviceStatus : Command { + public: + using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; + + typedef Transaction + CommandTransaction; + }; + + class GetSDCardOccupancy : Command { + public: + struct ResponsePayload { + uint8_t WriteLevelMin; + uint8_t WriteLevelMax; + uint8_t ReadLevelMin; + uint8_t ReadLevelMax; + std::string dissect() const { + std::stringstream ss; + print_to_ss((int) WriteLevelMin); + print_to_ss((int) WriteLevelMax); + print_to_ss((int) ReadLevelMin); + print_to_ss((int) ReadLevelMax); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + + class SetupHiddenVolume : Command { + public: + constexpr static int MAX_HIDDEN_VOLUME_PASSWORD_SIZE = 20; + struct CommandPayload { + uint8_t SlotNr_u8; + uint8_t StartBlockPercent_u8; + uint8_t EndBlockPercent_u8; + uint8_t HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSWORD_SIZE]; + std::string dissect() const { + std::stringstream ss; + print_to_ss((int) SlotNr_u8); + print_to_ss((int) StartBlockPercent_u8); + print_to_ss((int) EndBlockPercent_u8); + print_to_ss_volatile(HiddenVolumePassword_au8); + return ss.str(); + } + } __packed; + + typedef Transaction + CommandTransaction; + }; + + +//disable this command for now +// class LockFirmware : public PasswordCommand {}; + + class ProductionTest : Command { + public: + struct ResponsePayload { + + StorageCommandResponsePayload::TransmissionData transmission_data; + + uint8_t FirmwareVersion_au8[2]; // 2 byte // 2 + uint8_t FirmwareVersionInternal_u8; // 1 byte // 3 + uint8_t SD_Card_Size_u8; // 1 byte // 4 + uint32_t CPU_CardID_u32; // 4 byte // 8 + uint32_t SmartCardID_u32; // 4 byte // 12 + uint32_t SD_CardID_u32; // 4 byte // 16 + uint8_t SC_UserPwRetryCount; // User PIN retry count 1 byte // 17 + uint8_t SC_AdminPwRetryCount; // Admin PIN retry count 1 byte // 18 + uint8_t SD_Card_ManufacturingYear_u8; // 1 byte // 19 + uint8_t SD_Card_ManufacturingMonth_u8; // 1 byte // 20 + uint16_t SD_Card_OEM_u16; // 2 byte // 22 + uint16_t SD_WriteSpeed_u16; // in kbyte / sec 2 byte // 24 + uint8_t SD_Card_Manufacturer_u8; // 1 byte // 25 + + bool isValid() const { return true; } + + std::string dissect() const { + std::stringstream ss; + + print_to_ss(transmission_data.dissect()); + print_to_ss((int) FirmwareVersion_au8[0]); + print_to_ss((int) FirmwareVersion_au8[1]); + print_to_ss((int) FirmwareVersionInternal_u8); + print_to_ss((int) SD_Card_Size_u8); + print_to_ss( CPU_CardID_u32); + print_to_ss( SmartCardID_u32); + print_to_ss( SD_CardID_u32); + print_to_ss((int) SC_UserPwRetryCount); + print_to_ss((int) SC_AdminPwRetryCount); + print_to_ss((int) SD_Card_ManufacturingYear_u8); + print_to_ss((int) SD_Card_ManufacturingMonth_u8); + print_to_ss( SD_Card_OEM_u16); + print_to_ss( SD_WriteSpeed_u16); + print_to_ss((int) SD_Card_Manufacturer_u8); + return ss.str(); + } + + } __packed; + + typedef Transaction + CommandTransaction; + }; + + } + } +} + +#undef print_to_ss +#pragma pack (pop) + +#endif diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index de14fbc..f6977d9 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -4,9 +4,9 @@ #include "device.h" #include "log.h" #include "device_proto.h" -#include "stick10_commands.h" -#include "stick10_commands_0.8.h" -#include "stick20_commands.h" +#include "NKPro_commands.h" +#include "NKPro_commands_0.8.h" +#include "NKStorage_commands.h" #include #include diff --git a/include/stick10_commands.h b/include/stick10_commands.h deleted file mode 100644 index e863328..0000000 --- a/include/stick10_commands.h +++ /dev/null @@ -1,857 +0,0 @@ -#ifndef STICK10_COMMANDS_H -#define STICK10_COMMANDS_H - -#include -#include -#include -#include -#include -#include "device_proto.h" -#include "command.h" - -#pragma pack (push,1) - -namespace nitrokey { -namespace proto { - - - -/* - * Stick10 protocol definition - */ -namespace stick10 { -class GetSlotName : public Command { - public: - // reachable as a typedef in Transaction - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return slot_number<0x10+3; } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - uint8_t slot_name[15]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(slot_name); - return ss.str(); - } - } __packed; - - typedef Transaction CommandTransaction; -}; - -class EraseSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class SetTime : Command { - public: - struct CommandPayload { - uint8_t reset; // 0 - get time, 1 - 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 - CommandTransaction; -}; - - -class WriteToHOTPSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t slot_name[15]; - uint8_t slot_secret[20]; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - union{ - uint8_t slot_token_id[13]; /** OATH Token Identifier */ - struct{ /** @see https://openauthentication.org/token-specs/ */ - uint8_t omp[2]; - uint8_t tt[2]; - uint8_t mui[8]; - uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 - } slot_token_fields; - }; - union{ - uint64_t slot_counter; - uint8_t slot_counter_s[8]; - } __packed; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - print_to_ss_volatile(slot_name); - print_to_ss_volatile(slot_secret); - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - - ss << "slot_token_id:\t"; - for (auto i : slot_token_id) - ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; - ss << std::endl; - ss << "slot_counter:\t[" << (int)slot_counter << "]\t" - << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); - - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class WriteToTOTPSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t slot_name[15]; - uint8_t slot_secret[20]; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - union{ - uint8_t slot_token_id[13]; /** OATH Token Identifier */ - struct{ /** @see https://openauthentication.org/token-specs/ */ - uint8_t omp[2]; - uint8_t tt[2]; - uint8_t mui[8]; - uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 - } slot_token_fields; - }; - uint16_t slot_interval; - - bool isValid() const { return !(slot_number & 0xF0); } //TODO check - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - print_to_ss_volatile(slot_name); - print_to_ss_volatile(slot_secret); - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "slot_token_id:\t"; - for (auto i : slot_token_id) - ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; - ss << std::endl; - ss << "slot_interval:\t" << (int)slot_interval << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class GetTOTP : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint64_t challenge; - uint64_t last_totp_time; - uint8_t last_interval; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - ss << "challenge:\t" << (challenge) << std::endl; - ss << "last_totp_time:\t" << (last_totp_time) << std::endl; - ss << "last_interval:\t" << (int)(last_interval) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - union { - uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 - struct { - uint32_t code; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - } __packed ; - } __packed ; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << "code:\t" << (code) << std::endl; - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class GetHOTP : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return (slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - union { - uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 - struct { - uint32_t code; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - } __packed; - } __packed; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << "code:\t" << (code) << std::endl; - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class ReadSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - uint8_t slot_name[15]; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - union{ - uint8_t slot_token_id[13]; /** OATH Token Identifier */ - struct{ /** @see https://openauthentication.org/token-specs/ */ - uint8_t omp[2]; - uint8_t tt[2]; - uint8_t mui[8]; - uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 - } slot_token_fields; - }; - union{ - uint64_t slot_counter; - uint8_t slot_counter_s[8]; - } __packed; - - bool isValid() const { return true; } - - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(slot_name); - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - - ss << "slot_token_id:\t"; - for (auto i : slot_token_id) - ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; - ss << std::endl; - ss << "slot_counter:\t[" << (int)slot_counter << "]\t" - << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); - return ss.str(); - } - } __packed; - - typedef Transaction CommandTransaction; -}; - -class GetStatus : Command { - public: - struct ResponsePayload { - uint16_t firmware_version; - union{ - uint8_t card_serial[4]; - uint32_t card_serial_u32; - } __packed; - union { - uint8_t general_config[5]; - struct{ - uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ - uint8_t capslock; /** same as numlock */ - uint8_t scrolllock; /** same as numlock */ - uint8_t enable_user_password; - uint8_t delete_user_password; - } __packed; - } __packed; - bool isValid() const { return enable_user_password!=delete_user_password; } - - std::string get_card_serial_hex() const { - return nitrokey::misc::toHex(card_serial_u32); - } - - std::string dissect() const { - std::stringstream ss; - ss << "firmware_version:\t" - << "[" << firmware_version << "]" << "\t" - << ::nitrokey::misc::hexdump( - (const char *)(&firmware_version), sizeof firmware_version, false); - ss << "card_serial_u32:\t" << std::hex << card_serial_u32 << std::endl; - ss << "card_serial:\t" - << ::nitrokey::misc::hexdump((const char *)(card_serial), - sizeof card_serial, false); - ss << "general_config:\t" - << ::nitrokey::misc::hexdump((const char *)(general_config), - sizeof general_config, false); - ss << "numlock:\t" << (int)numlock << std::endl; - ss << "capslock:\t" << (int)capslock << std::endl; - ss << "scrolllock:\t" << (int)scrolllock << std::endl; - ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; - ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; - - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class GetPasswordRetryCount : Command { - public: - struct ResponsePayload { - uint8_t password_retry_count; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << " password_retry_count\t" << (int)password_retry_count << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class GetUserPasswordRetryCount - : Command { - public: - struct ResponsePayload { - uint8_t password_retry_count; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << " password_retry_count\t" << (int)password_retry_count << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - - template - void write_array(T &ss, Q (&arr)[N]){ - for (int i=0; i { - public: - struct ResponsePayload { - uint8_t password_safe_status[PWS_SLOT_COUNT]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << "password_safe_status\t"; - write_array(ss, password_safe_status); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class GetPasswordSafeSlotName : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number\t" << (int)slot_number << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - uint8_t slot_name[PWS_SLOTNAME_LENGTH]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(slot_name); - return ss.str(); - } - } __packed; - - typedef Transaction CommandTransaction; -}; - -class GetPasswordSafeSlotPassword - : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << " slot_number\t" << (int)slot_number << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - uint8_t slot_password[PWS_PASSWORD_LENGTH]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(slot_password); - return ss.str(); - } - } __packed; - - typedef Transaction CommandTransaction; -}; - -class GetPasswordSafeSlotLogin - : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << " slot_number\t" << (int)slot_number << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - uint8_t slot_login[PWS_LOGINNAME_LENGTH]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(slot_login); - return ss.str(); - } - } __packed; - - typedef Transaction CommandTransaction; -}; - -class SetPasswordSafeSlotData : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t slot_name[PWS_SLOTNAME_LENGTH]; - uint8_t slot_password[PWS_PASSWORD_LENGTH]; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << " slot_number\t" << (int)slot_number << std::endl; - print_to_ss_volatile(slot_name); - print_to_ss_volatile(slot_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class SetPasswordSafeSlotData2 : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t slot_login_name[PWS_LOGINNAME_LENGTH]; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << " slot_number\t" << (int)slot_number << std::endl; - print_to_ss_volatile(slot_login_name); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class ErasePasswordSafeSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << " slot_number\t" << (int)slot_number << std::endl; - return ss.str(); - } - - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class EnablePasswordSafe : Command { - public: - struct CommandPayload { - uint8_t user_password[30]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(user_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class PasswordSafeInitKey : Command { - /** - * never used in Nitrokey App - */ - public: - typedef Transaction - CommandTransaction; -}; - -class PasswordSafeSendSlotViaHID : Command { - /** - * never used in Nitrokey App - */ - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t slot_kind; - - bool isValid() const { return !(slot_number & 0xF0); } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -// TODO "Device::passwordSafeSendSlotDataViaHID" - -class WriteGeneralConfig : Command { - public: - struct CommandPayload { - union{ - uint8_t config[5]; - struct{ - uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ - uint8_t capslock; /** same as numlock */ - uint8_t scrolllock; /** same as numlock */ - uint8_t enable_user_password; - uint8_t delete_user_password; - }; - }; - std::string dissect() const { - std::stringstream ss; - ss << "numlock:\t" << (int)numlock << std::endl; - ss << "capslock:\t" << (int)capslock << std::endl; - ss << "scrolllock:\t" << (int)scrolllock << std::endl; - ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; - ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class FirstAuthenticate : Command { - public: - struct CommandPayload { - uint8_t card_password[25]; - uint8_t temporary_password[25]; - - bool isValid() const { return true; } - - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(card_password); - hexdump_to_ss(temporary_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class UserAuthenticate : Command { - public: - struct CommandPayload { - uint8_t card_password[25]; - uint8_t temporary_password[25]; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(card_password); - hexdump_to_ss(temporary_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class Authorize : Command { - public: - struct CommandPayload { - uint32_t crc_to_authorize; - uint8_t temporary_password[25]; - - std::string dissect() const { - std::stringstream ss; - ss << " crc_to_authorize:\t" << std::hex << std::setw(2) << std::setfill('0') << crc_to_authorize<< std::endl; - hexdump_to_ss(temporary_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class UserAuthorize : Command { - public: - struct CommandPayload { - uint32_t crc_to_authorize; - uint8_t temporary_password[25]; - std::string dissect() const { - std::stringstream ss; - ss << " crc_to_authorize:\t" << crc_to_authorize<< std::endl; - hexdump_to_ss(temporary_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class UnlockUserPassword : Command { - public: - struct CommandPayload { - uint8_t admin_password[25]; - uint8_t user_new_password[25]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(admin_password); - print_to_ss_volatile(user_new_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class ChangeUserPin : Command { - public: - struct CommandPayload { - uint8_t old_pin[25]; - uint8_t new_pin[25]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(old_pin); - print_to_ss_volatile(new_pin); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class IsAESSupported : Command { - public: - struct CommandPayload { - uint8_t user_password[20]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(user_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - - -class ChangeAdminPin : Command { - public: - struct CommandPayload { - uint8_t old_pin[25]; - uint8_t new_pin[25]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(old_pin); - print_to_ss_volatile(new_pin); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class LockDevice : Command { - public: - typedef Transaction - CommandTransaction; -}; - -class FactoryReset : Command { - public: - struct CommandPayload { - uint8_t admin_password[20]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(admin_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; -}; - -class BuildAESKey : Command { - public: - struct CommandPayload { - uint8_t admin_password[20]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile(admin_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - -}; - -} -} -} -#pragma pack (pop) -#endif diff --git a/include/stick10_commands_0.8.h b/include/stick10_commands_0.8.h deleted file mode 100644 index 4209380..0000000 --- a/include/stick10_commands_0.8.h +++ /dev/null @@ -1,326 +0,0 @@ -// -// Created by sz on 08.11.16. -// - -#ifndef LIBNITROKEY_STICK10_COMMANDS_0_8_H -#define LIBNITROKEY_STICK10_COMMANDS_0_8_H - -#include -#include -#include -#include -#include -#include "command.h" -#include "device_proto.h" -#include "stick10_commands.h" - -#pragma pack (push,1) - - -namespace nitrokey { - namespace proto { - -/* - * Stick10 protocol definition - */ - namespace stick10_08 { - using stick10::FirstAuthenticate; - using stick10::UserAuthenticate; - using stick10::SetTime; - using stick10::GetStatus; - using stick10::BuildAESKey; - using stick10::ChangeAdminPin; - using stick10::ChangeUserPin; - using stick10::EnablePasswordSafe; - using stick10::ErasePasswordSafeSlot; - using stick10::FactoryReset; - using stick10::GetPasswordRetryCount; - using stick10::GetUserPasswordRetryCount; - using stick10::GetPasswordSafeSlotLogin; - using stick10::GetPasswordSafeSlotName; - using stick10::GetPasswordSafeSlotPassword; - using stick10::GetPasswordSafeSlotStatus; - using stick10::GetSlotName; - using stick10::IsAESSupported; - using stick10::LockDevice; - using stick10::PasswordSafeInitKey; - using stick10::PasswordSafeSendSlotViaHID; - using stick10::SetPasswordSafeSlotData; - using stick10::SetPasswordSafeSlotData2; - using stick10::UnlockUserPassword; - using stick10::ReadSlot; - - class EraseSlot : Command { - public: - struct CommandPayload { - uint8_t slot_number; - uint8_t temporary_admin_password[25]; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - hexdump_to_ss(temporary_admin_password); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - class SendOTPData : Command { - //admin auth - public: - struct CommandPayload { - uint8_t temporary_admin_password[25]; - uint8_t type; //S-secret, N-name - uint8_t id; //multiple reports for values longer than 30 bytes - uint8_t data[30]; //data, does not need null termination - - bool isValid() const { return true; } - - void setTypeName(){ - type = 'N'; - } - void setTypeSecret(){ - type = 'S'; - } - - std::string dissect() const { - std::stringstream ss; - hexdump_to_ss(temporary_admin_password); - ss << "type:\t" << type << std::endl; - ss << "id:\t" << (int)id << std::endl; -#ifdef LOG_VOLATILE_DATA - ss << "data:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); -#else - ss << " Volatile data not logged" << std::endl; -#endif - return ss.str(); - } - } __packed; - - - struct ResponsePayload { - union { - uint8_t data[40]; - } __packed; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; -#ifdef LOG_VOLATILE_DATA - ss << "data:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); -#else - ss << " Volatile data not logged" << std::endl; -#endif - return ss.str(); - } - } __packed; - - - typedef Transaction - CommandTransaction; - }; - - class WriteToOTPSlot : Command { - //admin auth - public: - struct CommandPayload { - uint8_t temporary_admin_password[25]; - uint8_t slot_number; - union { - uint64_t slot_counter_or_interval; - uint8_t slot_counter_s[8]; - } __packed; - union { - uint8_t _slot_config; - struct { - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - union { - uint8_t slot_token_id[13]; /** OATH Token Identifier */ - struct { /** @see https://openauthentication.org/token-specs/ */ - uint8_t omp[2]; - uint8_t tt[2]; - uint8_t mui[8]; - uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 - } slot_token_fields; - }; - - bool isValid() const { return true; } - - std::string dissect() const { - std::stringstream ss; - hexdump_to_ss(temporary_admin_password); - ss << "slot_config:\t" << std::bitset<8>((int) _slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - ss << "slot_number:\t" << (int) (slot_number) << std::endl; - ss << "slot_counter_or_interval:\t[" << (int) slot_counter_or_interval << "]\t" - << ::nitrokey::misc::hexdump((const char *) (&slot_counter_or_interval), sizeof slot_counter_or_interval, false); - - ss << "slot_token_id:\t"; - for (auto i : slot_token_id) - ss << std::hex << std::setw(2) << std::setfill('0') << (int) i << " "; - ss << std::endl; - - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - class GetHOTP : Command { - public: - struct CommandPayload { - uint8_t slot_number; - struct { - uint64_t challenge; //@unused - uint64_t last_totp_time; //@unused - uint8_t last_interval; //@unused - } __packed _unused; - uint8_t temporary_user_password[25]; - - bool isValid() const { return (slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - hexdump_to_ss(temporary_user_password); - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - union { - uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 - struct { - uint32_t code; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - } __packed; - } __packed; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << "code:\t" << (code) << std::endl; - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - - class GetTOTP : Command { - //user auth - public: - struct CommandPayload { - uint8_t slot_number; - uint64_t challenge; //@unused - uint64_t last_totp_time; //@unused - uint8_t last_interval; //@unused - uint8_t temporary_user_password[25]; - - bool isValid() const { return !(slot_number & 0xF0); } - std::string dissect() const { - std::stringstream ss; - hexdump_to_ss(temporary_user_password); - ss << "slot_number:\t" << (int)(slot_number) << std::endl; - ss << "challenge:\t" << (challenge) << std::endl; - ss << "last_totp_time:\t" << (last_totp_time) << std::endl; - ss << "last_interval:\t" << (int)(last_interval) << std::endl; - return ss.str(); - } - } __packed; - - struct ResponsePayload { - union { - uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 - struct { - uint32_t code; - union{ - uint8_t _slot_config; - struct{ - bool use_8_digits : 1; - bool use_enter : 1; - bool use_tokenID : 1; - }; - }; - } __packed ; - } __packed ; - - bool isValid() const { return true; } - std::string dissect() const { - std::stringstream ss; - ss << "code:\t" << (code) << std::endl; - ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; - ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; - ss << "\tuse_enter(1):\t" << use_enter << std::endl; - ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - - class WriteGeneralConfig : Command { - //admin auth - public: - struct CommandPayload { - union{ - uint8_t config[5]; - struct{ - uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ - uint8_t capslock; /** same as numlock */ - uint8_t scrolllock; /** same as numlock */ - uint8_t enable_user_password; - uint8_t delete_user_password; - }; - }; - uint8_t temporary_admin_password[25]; - - std::string dissect() const { - std::stringstream ss; - ss << "numlock:\t" << (int)numlock << std::endl; - ss << "capslock:\t" << (int)capslock << std::endl; - ss << "scrolllock:\t" << (int)scrolllock << std::endl; - ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; - ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - } - } -} -#pragma pack (pop) - -#endif //LIBNITROKEY_STICK10_COMMANDS_0_8_H diff --git a/include/stick20_commands.h b/include/stick20_commands.h deleted file mode 100644 index 5f99d28..0000000 --- a/include/stick20_commands.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef STICK20_COMMANDS_H -#define STICK20_COMMANDS_H - - - -#include -#include "command.h" -#include -#include -#include "device_proto.h" - -#pragma pack (push,1) - -namespace nitrokey { - namespace proto { - -/* -* STICK20 protocol command ids -* a superset (almost) of STICK10 -*/ - - namespace stick20 { - - class ChangeAdminUserPin20Current : - public PasswordCommand {}; - class ChangeAdminUserPin20New : - public PasswordCommand {}; - class UnlockUserPin : - public PasswordCommand {}; - - class EnableEncryptedPartition : public PasswordCommand {}; - class EnableHiddenEncryptedPartition : public PasswordCommand {}; - - //FIXME the volume disabling commands do not need password - class DisableEncryptedPartition : public PasswordCommand {}; - class DisableHiddenEncryptedPartition : public PasswordCommand {}; - - class EnableFirmwareUpdate : public PasswordCommand {}; - - class ChangeUpdatePassword : Command { - public: - struct CommandPayload { - uint8_t __gap; - uint8_t current_update_password[20]; - uint8_t __gap2; - uint8_t new_update_password[20]; - std::string dissect() const { - std::stringstream ss; - print_to_ss_volatile( current_update_password ); - print_to_ss_volatile( new_update_password ); - return ss.str(); - } - }; - - typedef Transaction - CommandTransaction; - }; - - class ExportFirmware : public PasswordCommand {}; - - class CreateNewKeys : - public PasswordCommand {}; - - - class FillSDCardWithRandomChars : Command { - public: - enum class ChosenVolumes : uint8_t { - all_volumes = 0, - encrypted_volume = 1 - }; - - struct CommandPayload { - uint8_t volume_flag; - uint8_t kind; - uint8_t admin_pin[20]; - - std::string dissect() const { - std::stringstream ss; - print_to_ss( (int) volume_flag ); - print_to_ss( kind ); - print_to_ss_volatile(admin_pin); - return ss.str(); - } - void set_kind_user() { - kind = (uint8_t) 'P'; - } - void set_defaults(){ - set_kind_user(); - volume_flag = static_cast(ChosenVolumes::encrypted_volume); - } - - } __packed; - - typedef Transaction::command_id(), - struct CommandPayload, struct EmptyPayload> - CommandTransaction; - }; - - namespace StorageCommandResponsePayload{ - using namespace DeviceResponseConstants; - static constexpr auto padding_size = - storage_data_absolute_address - header_size; - struct TransmissionData{ - uint8_t _padding[padding_size]; - - uint8_t SendCounter_u8; - uint8_t SendDataType_u8; - uint8_t FollowBytesFlag_u8; - uint8_t SendSize_u8; - - std::string dissect() const { - std::stringstream ss; - ss << "_padding:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (_padding), - sizeof _padding); - print_to_ss((int) SendCounter_u8); - print_to_ss((int) SendDataType_u8); - print_to_ss((int) FollowBytesFlag_u8); - print_to_ss((int) SendSize_u8); - return ss.str(); - } - - } __packed; - } - - namespace DeviceConfigurationResponsePacket{ - - struct ResponsePayload { - StorageCommandResponsePayload::TransmissionData transmission_data; - - uint16_t MagicNumber_StickConfig_u16; - /** - * READ_WRITE_ACTIVE = ReadWriteFlagUncryptedVolume_u8 == 0; - */ - uint8_t ReadWriteFlagUncryptedVolume_u8; - uint8_t ReadWriteFlagCryptedVolume_u8; - - union{ - uint8_t VersionInfo_au8[4]; - struct { - uint8_t __reserved; - uint8_t minor; - uint8_t __reserved2; - uint8_t major; - } __packed versionInfo; - } __packed; - - uint8_t ReadWriteFlagHiddenVolume_u8; - uint8_t FirmwareLocked_u8; - - union{ - uint8_t NewSDCardFound_u8; - struct { - bool NewCard :1; - uint8_t Counter :7; - } __packed NewSDCardFound_st; - } __packed; - - /** - * SD card FILLED with random chars - */ - uint8_t SDFillWithRandomChars_u8; - uint32_t ActiveSD_CardID_u32; - union{ - uint8_t VolumeActiceFlag_u8; - struct { - bool unencrypted :1; - bool encrypted :1; - bool hidden :1; - } __packed VolumeActiceFlag_st; - } __packed; - uint8_t NewSmartCardFound_u8; - uint8_t UserPwRetryCount; - uint8_t AdminPwRetryCount; - uint32_t ActiveSmartCardID_u32; - uint8_t StickKeysNotInitiated; - - bool isValid() const { return true; } - - std::string dissect() const { - std::stringstream ss; - - print_to_ss(transmission_data.dissect()); - print_to_ss( MagicNumber_StickConfig_u16 ); - print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 ); - print_to_ss((int) ReadWriteFlagCryptedVolume_u8 ); - print_to_ss((int) VersionInfo_au8[1] ); - print_to_ss((int) VersionInfo_au8[3] ); - print_to_ss((int) ReadWriteFlagHiddenVolume_u8 ); - print_to_ss((int) FirmwareLocked_u8 ); - print_to_ss((int) NewSDCardFound_u8 ); - print_to_ss((int) SDFillWithRandomChars_u8 ); - print_to_ss( ActiveSD_CardID_u32 ); - print_to_ss((int) VolumeActiceFlag_u8 ); - print_to_ss((int) NewSmartCardFound_u8 ); - print_to_ss((int) UserPwRetryCount ); - print_to_ss((int) AdminPwRetryCount ); - print_to_ss( ActiveSmartCardID_u32 ); - print_to_ss((int) StickKeysNotInitiated ); - - return ss.str(); - } - } __packed; - } - - class SendStartup : Command { - public: - struct CommandPayload { - uint64_t localtime; // POSIX seconds from epoch start, supports until year 2106 - std::string dissect() const { - std::stringstream ss; - print_to_ss( localtime ); - return ss.str(); - } - void set_defaults(){ - localtime = - std::chrono::duration_cast ( - std::chrono::system_clock::now().time_since_epoch()).count(); - } - }__packed; - - using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; - - typedef Transaction - CommandTransaction; - }; - - -// TODO fix original nomenclature - class SendSetReadonlyToUncryptedVolume : public PasswordCommand {}; - class SendSetReadwriteToUncryptedVolume : public PasswordCommand {}; - class SendClearNewSdCardFound : public PasswordCommand {}; - - class GetDeviceStatus : Command { - public: - using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; - - typedef Transaction - CommandTransaction; - }; - - class GetSDCardOccupancy : Command { - public: - struct ResponsePayload { - uint8_t WriteLevelMin; - uint8_t WriteLevelMax; - uint8_t ReadLevelMin; - uint8_t ReadLevelMax; - std::string dissect() const { - std::stringstream ss; - print_to_ss((int) WriteLevelMin); - print_to_ss((int) WriteLevelMax); - print_to_ss((int) ReadLevelMin); - print_to_ss((int) ReadLevelMax); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - - class SetupHiddenVolume : Command { - public: - constexpr static int MAX_HIDDEN_VOLUME_PASSWORD_SIZE = 20; - struct CommandPayload { - uint8_t SlotNr_u8; - uint8_t StartBlockPercent_u8; - uint8_t EndBlockPercent_u8; - uint8_t HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSWORD_SIZE]; - std::string dissect() const { - std::stringstream ss; - print_to_ss((int) SlotNr_u8); - print_to_ss((int) StartBlockPercent_u8); - print_to_ss((int) EndBlockPercent_u8); - print_to_ss_volatile(HiddenVolumePassword_au8); - return ss.str(); - } - } __packed; - - typedef Transaction - CommandTransaction; - }; - - -//disable this command for now -// class LockFirmware : public PasswordCommand {}; - - class ProductionTest : Command { - public: - struct ResponsePayload { - - StorageCommandResponsePayload::TransmissionData transmission_data; - - uint8_t FirmwareVersion_au8[2]; // 2 byte // 2 - uint8_t FirmwareVersionInternal_u8; // 1 byte // 3 - uint8_t SD_Card_Size_u8; // 1 byte // 4 - uint32_t CPU_CardID_u32; // 4 byte // 8 - uint32_t SmartCardID_u32; // 4 byte // 12 - uint32_t SD_CardID_u32; // 4 byte // 16 - uint8_t SC_UserPwRetryCount; // User PIN retry count 1 byte // 17 - uint8_t SC_AdminPwRetryCount; // Admin PIN retry count 1 byte // 18 - uint8_t SD_Card_ManufacturingYear_u8; // 1 byte // 19 - uint8_t SD_Card_ManufacturingMonth_u8; // 1 byte // 20 - uint16_t SD_Card_OEM_u16; // 2 byte // 22 - uint16_t SD_WriteSpeed_u16; // in kbyte / sec 2 byte // 24 - uint8_t SD_Card_Manufacturer_u8; // 1 byte // 25 - - bool isValid() const { return true; } - - std::string dissect() const { - std::stringstream ss; - - print_to_ss(transmission_data.dissect()); - print_to_ss((int) FirmwareVersion_au8[0]); - print_to_ss((int) FirmwareVersion_au8[1]); - print_to_ss((int) FirmwareVersionInternal_u8); - print_to_ss((int) SD_Card_Size_u8); - print_to_ss( CPU_CardID_u32); - print_to_ss( SmartCardID_u32); - print_to_ss( SD_CardID_u32); - print_to_ss((int) SC_UserPwRetryCount); - print_to_ss((int) SC_AdminPwRetryCount); - print_to_ss((int) SD_Card_ManufacturingYear_u8); - print_to_ss((int) SD_Card_ManufacturingMonth_u8); - print_to_ss( SD_Card_OEM_u16); - print_to_ss( SD_WriteSpeed_u16); - print_to_ss((int) SD_Card_Manufacturer_u8); - return ss.str(); - } - - } __packed; - - typedef Transaction - CommandTransaction; - }; - - } - } -} - -#undef print_to_ss -#pragma pack (pop) - -#endif diff --git a/unittest/test.cc b/unittest/test.cc index 15235bd..46b6ae1 100644 --- a/unittest/test.cc +++ b/unittest/test.cc @@ -4,7 +4,7 @@ #include #include "device_proto.h" #include "log.h" -#include "stick10_commands.h" +#include "NKPro_commands.h" using namespace std; using namespace nitrokey::device; diff --git a/unittest/test2.cc b/unittest/test2.cc index 31dbce8..13e33a3 100644 --- a/unittest/test2.cc +++ b/unittest/test2.cc @@ -9,8 +9,8 @@ static const char *const default_user_pin = "123456"; #include #include "device_proto.h" #include "log.h" -//#include "stick10_commands.h" -#include "stick20_commands.h" +//#include "NKPro_commands.h" +#include "NKStorage_commands.h" using namespace std; using namespace nitrokey::device; diff --git a/unittest/test_HOTP.cc b/unittest/test_HOTP.cc index e6f7d7c..a1301ab 100644 --- a/unittest/test_HOTP.cc +++ b/unittest/test_HOTP.cc @@ -2,7 +2,7 @@ #include #include "device_proto.h" #include "log.h" -#include "stick10_commands.h" +#include "NKPro_commands.h" #include #include "misc.h" -- cgit v1.2.3