diff options
author | David Seifert <soap@gentoo.org> | 2018-03-11 11:31:57 +0100 |
---|---|---|
committer | Szczepan Zalega <szczepan@nitrokey.com> | 2018-03-13 09:37:35 +0100 |
commit | 15dc909b1bd2621b64c7fd58a7cf55a4778876cf (patch) | |
tree | 527ebfbade550a70c3794308e7e93b8085624d5c /include | |
parent | 350fa7670ff63d0833d80edee42c1a798c3064c3 (diff) | |
download | libnitrokey-15dc909b1bd2621b64c7fd58a7cf55a4778876cf.tar.gz libnitrokey-15dc909b1bd2621b64c7fd58a7cf55a4778876cf.tar.bz2 |
Make unbundling easier
Diffstat (limited to 'include')
-rw-r--r-- | include/CommandFailedException.h | 76 | ||||
-rw-r--r-- | include/DeviceCommunicationExceptions.h | 73 | ||||
-rw-r--r-- | include/LibraryException.h | 118 | ||||
-rw-r--r-- | include/LongOperationInProgressException.h | 45 | ||||
-rw-r--r-- | include/NitrokeyManager.h | 283 | ||||
-rw-r--r-- | include/command.h | 112 | ||||
-rw-r--r-- | include/command_id.h | 152 | ||||
-rw-r--r-- | include/cxx_semantics.h | 44 | ||||
-rw-r--r-- | include/device.h | 169 | ||||
-rw-r--r-- | include/device_proto.h | 491 | ||||
-rw-r--r-- | include/dissect.h | 145 | ||||
-rw-r--r-- | include/hidapi/hidapi.h | 391 | ||||
-rw-r--r-- | include/log.h | 108 | ||||
-rw-r--r-- | include/misc.h | 94 | ||||
-rw-r--r-- | include/stick10_commands.h | 884 | ||||
-rw-r--r-- | include/stick10_commands_0.8.h | 344 | ||||
-rw-r--r-- | include/stick20_commands.h | 388 |
17 files changed, 0 insertions, 3917 deletions
diff --git a/include/CommandFailedException.h b/include/CommandFailedException.h deleted file mode 100644 index 32bd6b7..0000000 --- a/include/CommandFailedException.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef LIBNITROKEY_COMMANDFAILEDEXCEPTION_H -#define LIBNITROKEY_COMMANDFAILEDEXCEPTION_H - -#include <exception> -#include <cstdint> -#include "log.h" -#include "command_id.h" - -using cs = nitrokey::proto::stick10::command_status; -using cs2 = nitrokey::proto::stick20::device_status; - -class CommandFailedException : public std::exception { -public: - const uint8_t last_command_id; - const uint8_t last_command_status; - - CommandFailedException(uint8_t last_command_id, uint8_t last_command_status) : - last_command_id(last_command_id), - last_command_status(last_command_status){ - LOG(std::string("CommandFailedException, status: ")+ std::to_string(last_command_status), nitrokey::log::Loglevel::DEBUG); - } - - virtual const char *what() const throw() { - return "Command execution has failed on device"; - } - - - bool reason_timestamp_warning() const throw(){ - return last_command_status == static_cast<uint8_t>(cs::timestamp_warning); - } - - bool reason_AES_not_initialized() const throw(){ - return last_command_status == static_cast<uint8_t>(cs::AES_dec_failed); - } - - bool reason_not_authorized() const throw(){ - return last_command_status == static_cast<uint8_t>(cs::not_authorized); - } - - bool reason_slot_not_programmed() const throw(){ - return last_command_status == static_cast<uint8_t>(cs::slot_not_programmed); - } - - bool reason_wrong_password() const throw(){ - return last_command_status == static_cast<uint8_t>(cs::wrong_password); - } - - bool reason_smartcard_busy() const throw(){ - return last_command_status == static_cast<uint8_t>(cs2::smartcard_error); - } - -}; - - -#endif //LIBNITROKEY_COMMANDFAILEDEXCEPTION_H diff --git a/include/DeviceCommunicationExceptions.h b/include/DeviceCommunicationExceptions.h deleted file mode 100644 index f710d0b..0000000 --- a/include/DeviceCommunicationExceptions.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - - -#ifndef LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H -#define LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H - -#include <atomic> -#include <exception> -#include <stdexcept> -#include <string> - - -class DeviceCommunicationException: public std::runtime_error -{ - std::string message; - static std::atomic_int occurred; -public: - DeviceCommunicationException(std::string _msg): std::runtime_error(_msg), message(_msg){ - ++occurred; - } - uint8_t getType() const {return 1;}; -// virtual const char* what() const throw() override { -// return message.c_str(); -// } - static bool has_occurred(){ return occurred > 0; }; - static void reset_occurred_flag(){ occurred = 0; }; -}; - -class DeviceNotConnected: public DeviceCommunicationException { -public: - DeviceNotConnected(std::string msg) : DeviceCommunicationException(msg){} - uint8_t getType() const {return 2;}; -}; - -class DeviceSendingFailure: public DeviceCommunicationException { -public: - DeviceSendingFailure(std::string msg) : DeviceCommunicationException(msg){} - uint8_t getType() const {return 3;}; -}; - -class DeviceReceivingFailure: public DeviceCommunicationException { -public: - DeviceReceivingFailure(std::string msg) : DeviceCommunicationException(msg){} - uint8_t getType() const {return 4;}; -}; - -class InvalidCRCReceived: public DeviceReceivingFailure { -public: - InvalidCRCReceived(std::string msg) : DeviceReceivingFailure(msg){} - uint8_t getType() const {return 5;}; -}; - - -#endif //LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H diff --git a/include/LibraryException.h b/include/LibraryException.h deleted file mode 100644 index 3b9d177..0000000 --- a/include/LibraryException.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef LIBNITROKEY_LIBRARYEXCEPTION_H -#define LIBNITROKEY_LIBRARYEXCEPTION_H - -#include <exception> -#include <cstdint> -#include <string> -#include "log.h" - -class LibraryException: std::exception { -public: - virtual uint8_t exception_id()= 0; -}; - -class TargetBufferSmallerThanSource: public LibraryException { -public: - virtual uint8_t exception_id() override { - return 203; - } - -public: - size_t source_size; - size_t target_size; - - TargetBufferSmallerThanSource( - size_t source_size, size_t target_size - ) : source_size(source_size), target_size(target_size) {} - - virtual const char *what() const throw() override { - std::string s = " "; - auto ts = [](size_t x){ return std::to_string(x); }; - std::string msg = std::string("Target buffer size is smaller than source: [source size, buffer size]") - +s+ ts(source_size) +s+ ts(target_size); - return msg.c_str(); - } - -}; - -class InvalidHexString : public LibraryException { -public: - virtual uint8_t exception_id() override { - return 202; - } - -public: - uint8_t invalid_char; - - InvalidHexString (uint8_t invalid_char) : invalid_char( invalid_char) {} - - virtual const char *what() const throw() override { - return "Invalid character in hex string"; - } - -}; - -class InvalidSlotException : public LibraryException { -public: - virtual uint8_t exception_id() override { - return 201; - } - -public: - uint8_t slot_selected; - - InvalidSlotException(uint8_t slot_selected) : slot_selected(slot_selected) {} - - virtual const char *what() const throw() override { - return "Wrong slot selected"; - } - -}; - - - -class TooLongStringException : public LibraryException { -public: - virtual uint8_t exception_id() override { - return 200; - } - - std::size_t size_source; - std::size_t size_destination; - std::string message; - - TooLongStringException(size_t size_source, size_t size_destination, const std::string &message = "") : size_source( - size_source), size_destination(size_destination), message(message) { - LOG(std::string("TooLongStringException, size diff: ")+ std::to_string(size_source-size_destination), nitrokey::log::Loglevel::DEBUG); - - } - - virtual const char *what() const throw() override { - //TODO add sizes and message data to final message - return "Too long string has been supplied as an argument"; - } - -}; - -#endif //LIBNITROKEY_LIBRARYEXCEPTION_H diff --git a/include/LongOperationInProgressException.h b/include/LongOperationInProgressException.h deleted file mode 100644 index 865d6b5..0000000 --- a/include/LongOperationInProgressException.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H -#define LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H - -#include "CommandFailedException.h" - -class LongOperationInProgressException : public CommandFailedException { - -public: - unsigned char progress_bar_value; - - LongOperationInProgressException( - unsigned char _command_id, uint8_t last_command_status, unsigned char _progress_bar_value) - : CommandFailedException(_command_id, last_command_status), progress_bar_value(_progress_bar_value){ - LOG( - std::string("LongOperationInProgressException, progress bar status: ")+ - std::to_string(progress_bar_value), nitrokey::log::Loglevel::DEBUG); - } - virtual const char *what() const throw() { - return "Device returned busy status with long operation in progress"; - } -}; - - -#endif //LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h deleted file mode 100644 index ca58d24..0000000 --- a/include/NitrokeyManager.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef LIBNITROKEY_NITROKEYMANAGER_H -#define LIBNITROKEY_NITROKEYMANAGER_H - -#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 <vector> -#include <memory> -#include <unordered_map> - -namespace nitrokey { - using namespace nitrokey::device; - using namespace std; - using namespace nitrokey::proto::stick10; - using namespace nitrokey::proto::stick20; - using namespace nitrokey::proto; - using namespace nitrokey::log; - - -#ifdef __WIN32 -char * strndup(const char* str, size_t maxlen); -#endif - - class NitrokeyManager { - public: - static shared_ptr <NitrokeyManager> instance(); - - bool first_authenticate(const char *pin, const char *temporary_password); - bool write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - bool write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - string get_HOTP_code(uint8_t slot_number, const char *user_temporary_password); - string get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, - uint8_t last_interval, - const char *user_temporary_password); - string get_TOTP_code(uint8_t slot_number, const char *user_temporary_password); - stick10::ReadSlot::ResponsePayload get_TOTP_slot_data(const uint8_t slot_number); - stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number); - - bool set_time(uint64_t time); - bool get_time(uint64_t time = 0); - bool erase_totp_slot(uint8_t slot_number, const char *temporary_password); - bool erase_hotp_slot(uint8_t slot_number, const char *temporary_password); - std::vector<std::string> list_devices(); - std::vector<std::string> list_devices_by_cpuID(); - - /** - * Connect to the device using unique smartcard:datacard id. - * Needs list_device_by_cpuID() run first - * @param id Current ID of the target device - * @return true on success, false on failure - */ - bool connect_with_ID(const std::string id); - bool connect_with_path (std::string path); - bool connect(const char *device_model); - bool connect(); - bool disconnect(); - bool is_connected() throw() ; - bool could_current_device_be_enumerated(); - bool set_default_commands_delay(int delay); - - DeviceModel get_connected_device_model() const; - void set_debug(bool state); - stick10::GetStatus::ResponsePayload get_status(); - string get_status_as_string(); - string get_serial_number(); - - const char * get_totp_slot_name(uint8_t slot_number); - const char * get_hotp_slot_name(uint8_t slot_number); - - void change_user_PIN(const char *current_PIN, const char *new_PIN); - void change_admin_PIN(const char *current_PIN, const char *new_PIN); - - void enable_password_safe(const char *user_pin); - - vector <uint8_t> get_password_safe_slot_status(); - - uint8_t get_admin_retry_count(); - uint8_t get_user_retry_count(); - - void lock_device(); - - const char *get_password_safe_slot_name(uint8_t slot_number); - const char *get_password_safe_slot_password(uint8_t slot_number); - const char *get_password_safe_slot_login(uint8_t slot_number); - - void - write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, - const char *slot_password); - - void erase_password_safe_slot(uint8_t slot_number); - - void user_authenticate(const char *user_password, const char *temporary_password); - - void factory_reset(const char *admin_password); - - void build_aes_key(const char *admin_password); - - void unlock_user_password(const char *admin_password, const char *new_user_password); - - void write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, - bool delete_user_password, const char *admin_temporary_password); - - vector<uint8_t> read_config(); - - bool is_AES_supported(const char *user_password); - - void unlock_encrypted_volume(const char *user_password); - void lock_encrypted_volume(); - - void unlock_hidden_volume(const char *hidden_volume_password); - void lock_hidden_volume(); - - /** - * Sets unencrypted volume read-only. - * Works until v0.48 (incl. v0.50), where User PIN was sufficient - * Does nothing otherwise. - * @param user_pin User PIN - */ - void set_unencrypted_read_only(const char *user_pin); - - /** - * Sets unencrypted volume read-only. - * Works from v0.49 (except v0.50) accepts Admin PIN - * Does nothing otherwise. - * @param admin_pin Admin PIN - */ - void set_unencrypted_read_only_admin(const char *admin_pin); - - /** - * Sets unencrypted volume read-write. - * Works until v0.48 (incl. v0.50), where User PIN was sufficient - * Does nothing otherwise. - * @param user_pin User PIN - */ - void set_unencrypted_read_write(const char *user_pin); - - /** - * Sets unencrypted volume read-write. - * Works from v0.49 (except v0.50) accepts Admin PIN - * Does nothing otherwise. - * @param admin_pin Admin PIN - */ - void set_unencrypted_read_write_admin(const char *admin_pin); - - void export_firmware(const char *admin_pin); - void enable_firmware_update(const char *firmware_pin); - - void clear_new_sd_card_warning(const char *admin_pin); - - void fill_SD_card_with_random_data(const char *admin_pin); - - uint8_t get_SD_card_size(); - - void change_update_password(const char *current_update_password, const char *new_update_password); - - void create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, - const char *hidden_volume_password); - - void send_startup(uint64_t seconds_from_epoch); - - const char * get_status_storage_as_string(); - stick20::DeviceConfigurationResponsePacket::ResponsePayload get_status_storage(); - - const char *get_SD_usage_data_as_string(); - std::pair<uint8_t,uint8_t> get_SD_usage_data(); - - - int get_progress_bar_value(); - - ~NitrokeyManager(); - bool is_authorization_command_supported(); - bool is_320_OTP_secret_supported(); - - - template <typename S, typename A, typename T> - void authorize_packet(T &package, const char *admin_temporary_password, shared_ptr<Device> device); - int get_minor_firmware_version(); - - explicit NitrokeyManager(); - void set_log_function(std::function<void(std::string)> log_function); - private: - - static shared_ptr <NitrokeyManager> _instance; - std::shared_ptr<Device> device; - std::string current_device_id; - public: - const string get_current_device_id() const; - - private: - std::unordered_map<std::string, shared_ptr<Device> > connected_devices; - std::unordered_map<std::string, shared_ptr<Device> > connected_devices_byID; - - - stick10::ReadSlot::ResponsePayload get_OTP_slot_data(const uint8_t slot_number); - bool is_valid_hotp_slot_number(uint8_t slot_number) const; - bool is_valid_totp_slot_number(uint8_t slot_number) const; - bool is_valid_password_safe_slot_number(uint8_t slot_number) const; - uint8_t get_internal_slot_number_for_hotp(uint8_t slot_number) const; - uint8_t get_internal_slot_number_for_totp(uint8_t slot_number) const; - bool erase_slot(uint8_t slot_number, const char *temporary_password); - const char * get_slot_name(uint8_t slot_number); - - template <typename ProCommand, PasswordKind StoKind> - void change_PIN_general(const char *current_PIN, const char *new_PIN); - - void write_HOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - - void write_TOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - - void write_OTP_slot_no_authorize(uint8_t internal_slot_number, const char *slot_name, const char *secret, - uint64_t counter_or_interval, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password) const; - bool _disconnect_no_lock(); - - public: - bool set_current_device_speed(int retry_delay, int send_receive_delay); - void set_loglevel(Loglevel loglevel); - - void set_loglevel(int loglevel); - - /** - * Sets encrypted volume read-only. - * Supported from future versions of Storage. - * @param admin_pin Admin PIN - */ - void set_encrypted_volume_read_only(const char *admin_pin); - - /** - * Sets encrypted volume read-write. - * Supported from future versions of Storage. - * @param admin_pin Admin PIN - */ - void set_encrypted_volume_read_write(const char *admin_pin); - - int get_major_firmware_version(); - - bool is_smartcard_in_use(); - - /** - * Function to determine unencrypted volume PIN type - * @param minor_firmware_version - * @return Returns true, if set unencrypted volume ro/rw pin type is User, false otherwise. - */ - bool set_unencrypted_volume_rorw_pin_type_user(); - }; -} - - - -#endif //LIBNITROKEY_NITROKEYMANAGER_H diff --git a/include/command.h b/include/command.h deleted file mode 100644 index 6852bf0..0000000 --- a/include/command.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef COMMAND_H -#define COMMAND_H -#include <string> -#include "command_id.h" -#include "cxx_semantics.h" - -#define print_to_ss(x) ( ss << " " << (#x) <<":\t" << (x) << std::endl ); -#ifdef LOG_VOLATILE_DATA -#define print_to_ss_volatile(x) print_to_ss(x); -#else -#define print_to_ss_volatile(x) ( ss << " " << (#x) <<":\t" << "***********" << std::endl ); -#endif -#define hexdump_to_ss(x) (ss << #x":\n"\ - << ::nitrokey::misc::hexdump((const uint8_t *) (&x), sizeof x, false)); - -namespace nitrokey { - namespace proto { - - template<CommandID cmd_id> - class Command : semantics::non_constructible { - public: - constexpr static CommandID command_id() { return cmd_id; } - - template<typename T> - std::string dissect(const T &) { - return std::string("Payload dissection is unavailable"); - } - }; - -namespace stick20{ - enum class PasswordKind : uint8_t { - User = 'P', - Admin = 'A', - AdminPrefixed - }; - - template<CommandID cmd_id, PasswordKind Tpassword_kind = PasswordKind::User, int password_length = 20> - class PasswordCommand : public Command<cmd_id> { - constexpr static CommandID _command_id() { return cmd_id; } - public: - struct CommandPayload { - uint8_t kind; - uint8_t password[password_length]; - - std::string dissect() const { - std::stringstream ss; - print_to_ss( kind ); - print_to_ss_volatile(password); - return ss.str(); - } - void set_kind_admin() { - kind = (uint8_t) 'A'; - } - void set_kind_admin_prefixed() { - kind = (uint8_t) 'P'; - } - void set_kind_user() { - kind = (uint8_t) 'P'; - } - - void set_defaults(){ - set_kind(Tpassword_kind); - } - - void set_kind(PasswordKind password_kind){ - switch (password_kind){ - case PasswordKind::Admin: - set_kind_admin(); - break; - case PasswordKind::User: - set_kind_user(); - break; - case PasswordKind::AdminPrefixed: - set_kind_admin_prefixed(); - break; - } - }; - - } __packed; - - //typedef Transaction<Command<cmd_id>::command_id(), struct CommandPayload, struct EmptyPayload> - // CommandTransaction; - using CommandTransaction = Transaction<cmd_id, CommandPayload, EmptyPayload>; - //using CommandTransaction = Transaction<_command_id(), CommandPayload, EmptyPayload>; - - }; - } - } -} - -#endif diff --git a/include/command_id.h b/include/command_id.h deleted file mode 100644 index 1092ea9..0000000 --- a/include/command_id.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef COMMAND_ID_H -#define COMMAND_ID_H -#include <stdint.h> - -namespace nitrokey { -namespace proto { - namespace stick20 { - enum class device_status : uint8_t { - idle = 0, - ok, - busy, - wrong_password, - busy_progressbar, - password_matrix_ready, - no_user_password_unlock, // FIXME: translate on receive to command status error (fix in firmware?) - smartcard_error, - security_bit_active - }; - const int CMD_START_VALUE = 0x20; - const int CMD_END_VALUE = 0x60; - } - namespace stick10 { - enum class command_status : uint8_t { - ok = 0, - wrong_CRC, - wrong_slot, - slot_not_programmed, - wrong_password = 4, - not_authorized, - timestamp_warning, - no_name_error, - not_supported, - unknown_command, - AES_dec_failed - }; - enum class device_status : uint8_t { - ok = 0, - busy = 1, - error, - received_report, - }; - } - - -enum class CommandID : uint8_t { - GET_STATUS = 0x00, - WRITE_TO_SLOT = 0x01, - READ_SLOT_NAME = 0x02, - READ_SLOT = 0x03, - GET_CODE = 0x04, - WRITE_CONFIG = 0x05, - ERASE_SLOT = 0x06, - FIRST_AUTHENTICATE = 0x07, - AUTHORIZE = 0x08, - GET_PASSWORD_RETRY_COUNT = 0x09, - CLEAR_WARNING = 0x0A, - SET_TIME = 0x0B, - TEST_COUNTER = 0x0C, - TEST_TIME = 0x0D, - USER_AUTHENTICATE = 0x0E, - GET_USER_PASSWORD_RETRY_COUNT = 0x0F, - USER_AUTHORIZE = 0x10, - UNLOCK_USER_PASSWORD = 0x11, - LOCK_DEVICE = 0x12, - FACTORY_RESET = 0x13, - CHANGE_USER_PIN = 0x14, - CHANGE_ADMIN_PIN = 0x15, - WRITE_TO_SLOT_2 = 0x16, - SEND_OTP_DATA = 0x17, - - ENABLE_CRYPTED_PARI = 0x20, - DISABLE_CRYPTED_PARI = 0x20 + 1, - ENABLE_HIDDEN_CRYPTED_PARI = 0x20 + 2, - DISABLE_HIDDEN_CRYPTED_PARI = 0x20 + 3, - ENABLE_FIRMWARE_UPDATE = 0x20 + 4, //enables update mode - EXPORT_FIRMWARE_TO_FILE = 0x20 + 5, - GENERATE_NEW_KEYS = 0x20 + 6, - FILL_SD_CARD_WITH_RANDOM_CHARS = 0x20 + 7, - - WRITE_STATUS_DATA = 0x20 + 8, //@unused - ENABLE_READONLY_UNCRYPTED_LUN = 0x20 + 9, - ENABLE_READWRITE_UNCRYPTED_LUN = 0x20 + 10, - - SEND_PASSWORD_MATRIX = 0x20 + 11, //@unused - SEND_PASSWORD_MATRIX_PINDATA = 0x20 + 12, //@unused - SEND_PASSWORD_MATRIX_SETUP = 0x20 + 13, //@unused - - GET_DEVICE_STATUS = 0x20 + 14, - SEND_DEVICE_STATUS = 0x20 + 15, - - SEND_HIDDEN_VOLUME_PASSWORD = 0x20 + 16, //@unused - SEND_HIDDEN_VOLUME_SETUP = 0x20 + 17, - SEND_PASSWORD = 0x20 + 18, - SEND_NEW_PASSWORD = 0x20 + 19, - CLEAR_NEW_SD_CARD_FOUND = 0x20 + 20, - - SEND_STARTUP = 0x20 + 21, - SEND_CLEAR_STICK_KEYS_NOT_INITIATED = 0x20 + 22, - SEND_LOCK_STICK_HARDWARE = 0x20 + 23, //locks firmware upgrade - - PRODUCTION_TEST = 0x20 + 24, - SEND_DEBUG_DATA = 0x20 + 25, //@unused - - CHANGE_UPDATE_PIN = 0x20 + 26, - - //added in v0.48.5 - ENABLE_ADMIN_READONLY_UNCRYPTED_LUN = 0x20 + 28, - ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN = 0x20 + 29, - ENABLE_ADMIN_READONLY_ENCRYPTED_LUN = 0x20 + 30, - ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN = 0x20 + 31, - CHECK_SMARTCARD_USAGE = 0x20 + 32, - - GET_PW_SAFE_SLOT_STATUS = 0x60, - GET_PW_SAFE_SLOT_NAME = 0x61, - GET_PW_SAFE_SLOT_PASSWORD = 0x62, - GET_PW_SAFE_SLOT_LOGINNAME = 0x63, - SET_PW_SAFE_SLOT_DATA_1 = 0x64, - SET_PW_SAFE_SLOT_DATA_2 = 0x65, - PW_SAFE_ERASE_SLOT = 0x66, - PW_SAFE_ENABLE = 0x67, - PW_SAFE_INIT_KEY = 0x68, //@unused - PW_SAFE_SEND_DATA = 0x69, //@unused - SD_CARD_HIGH_WATERMARK = 0x70, - DETECT_SC_AES = 0x6a, - NEW_AES_KEY = 0x6b -}; - -const char *commandid_to_string(CommandID id); -} -} -#endif diff --git a/include/cxx_semantics.h b/include/cxx_semantics.h deleted file mode 100644 index 36ed142..0000000 --- a/include/cxx_semantics.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef CXX_SEMANTICS_H -#define CXX_SEMANTICS_H - -#ifndef _MSC_VER -#define __packed __attribute__((__packed__)) -#else -#define __packed -#endif - -#ifdef _MSC_VER -#define strdup _strdup -#endif - -/* - * There's no need to include Boost for a simple subset this project needs. - */ -namespace semantics { -class non_constructible { - non_constructible() {} -}; -} - -#endif diff --git a/include/device.h b/include/device.h deleted file mode 100644 index f6d2380..0000000 --- a/include/device.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef DEVICE_H -#define DEVICE_H -#include <chrono> -#include "hidapi/hidapi.h" -#include <cstdint> -#include <string> -#include <vector> - -#define HID_REPORT_SIZE 65 - -#include <atomic> - -namespace nitrokey { -namespace device { - using namespace std::chrono_literals; - using std::chrono::milliseconds; - - struct EnumClassHash - { - template <typename T> - std::size_t operator()(T t) const - { - return static_cast<std::size_t>(t); - } - }; - -enum class DeviceModel{ - PRO, - STORAGE -}; - -#include <atomic> - -class Device { - -public: - - struct ErrorCounters{ - using cnt = std::atomic_int; - cnt wrong_CRC; - cnt CRC_other_than_awaited; - cnt busy; - cnt total_retries; - cnt sending_error; - cnt receiving_error; - cnt total_comm_runs; - cnt successful_storage_commands; - cnt command_successful_recv; - cnt recv_executed; - cnt sends_executed; - cnt busy_progressbar; - cnt command_result_not_equal_0_recv; - cnt communication_successful; - cnt low_level_reconnect; - std::string get_as_string(); - - } m_counters = {}; - - - Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, - const milliseconds send_receive_delay, const int retry_receiving_count, - const milliseconds retry_timeout); - - virtual ~Device(); - - // lack of device is not actually an error, - // so it doesn't throw - virtual bool connect(); - virtual bool disconnect(); - - /* - * Sends packet of HID_REPORT_SIZE. - */ - virtual int send(const void *packet); - - /* - * Gets packet of HID_REPORT_SIZE. - * Can sleep. See below. - */ - virtual int recv(void *packet); - - /*** - * Returns true if some device is visible by OS with given VID and PID - * whether the device is connected through HID API or not. - * @return true if visible by OS - */ - bool could_be_enumerated(); - std::vector<std::string> enumerate(); - - - void show_stats(); -// ErrorCounters get_stats(){ return m_counters; } - int get_retry_receiving_count() const { return m_retry_receiving_count; }; - int get_retry_sending_count() const { return m_retry_sending_count; }; - std::chrono::milliseconds get_retry_timeout() const { return m_retry_timeout; }; - std::chrono::milliseconds get_send_receive_delay() const {return m_send_receive_delay;} - - int get_last_command_status() {int a = std::atomic_exchange(&last_command_status, static_cast<uint8_t>(0)); return a;}; - void set_last_command_status(uint8_t _err) { last_command_status = _err;} ; - bool last_command_sucessfull() const {return last_command_status == 0;}; - DeviceModel get_device_model() const {return m_model;} - void set_receiving_delay(std::chrono::milliseconds delay); - void set_retry_delay(std::chrono::milliseconds delay); - static void set_default_device_speed(int delay); - void setDefaultDelay(); - void set_path(const std::string path); - - - private: - std::atomic<uint8_t> last_command_status; - void _reconnect(); - bool _connect(); - bool _disconnect(); - -protected: - const uint16_t m_vid; - const uint16_t m_pid; - const DeviceModel m_model; - - /* - * While the project uses Signal11 portable HIDAPI - * library, there's no way of doing it asynchronously, - * hence polling. - */ - const int m_retry_sending_count; - const int m_retry_receiving_count; - std::chrono::milliseconds m_retry_timeout; - std::chrono::milliseconds m_send_receive_delay; - std::atomic<hid_device *>mp_devhandle; - std::string m_path; - - static std::atomic_int instances_count; - static std::chrono::milliseconds default_delay ; -}; - -class Stick10 : public Device { - public: - Stick10(); - -}; - -class Stick20 : public Device { - public: - Stick20(); -}; -} -} -#endif diff --git a/include/device_proto.h b/include/device_proto.h deleted file mode 100644 index 45a6c16..0000000 --- a/include/device_proto.h +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef DEVICE_PROTO_H -#define DEVICE_PROTO_H - -#include <utility> -#include <thread> -#include <type_traits> -#include <stdexcept> -#include <string> -// a local version for compatibility with Windows -#include <stdint.h> -#include "cxx_semantics.h" -#include "device.h" -#include "misc.h" -#include "log.h" -#include "command_id.h" -#include "dissect.h" -#include "CommandFailedException.h" -#include "LongOperationInProgressException.h" - -#define STICK20_UPDATE_MODE_VID 0x03EB -#define STICK20_UPDATE_MODE_PID 0x2FF1 - -#define PAYLOAD_SIZE 53 -#define PWS_SLOT_COUNT 16 -#define PWS_SLOTNAME_LENGTH 11 -#define PWS_PASSWORD_LENGTH 20 -#define PWS_LOGINNAME_LENGTH 32 - -#define PWS_SEND_PASSWORD 0 -#define PWS_SEND_LOGINNAME 1 -#define PWS_SEND_TAB 2 -#define PWS_SEND_CR 3 - -#include <mutex> -#include "DeviceCommunicationExceptions.h" -#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) - -namespace nitrokey { - namespace proto { - extern std::mutex send_receive_mtx; - - -/* - * POD types for HID proto commands - * Instances are meant to be __packed. - * - * TODO (future) support for Big Endian - */ -#pragma pack (push,1) -/* - * Every packet is a USB HID report (check USB spec) - */ - template<CommandID cmd_id, typename Payload> - struct HIDReport { - uint8_t _zero; - CommandID command_id; // uint8_t - union { - uint8_t _padding[HID_REPORT_SIZE - 6]; - Payload payload; - } __packed; - uint32_t crc; - - // POD types can't have non-default constructors - // used in Transaction<>::run() - void initialize() { - bzero(this, sizeof *this); - command_id = cmd_id; - } - - uint32_t calculate_CRC() const { - // w/o leading zero, a part of each HID packet - // w/o 4-byte crc - return misc::stm_crc32((const uint8_t *) (this) + 1, - (size_t) (HID_REPORT_SIZE - 5)); - } - - void update_CRC() { crc = calculate_CRC(); } - - bool isCRCcorrect() const { return crc == calculate_CRC(); } - - bool isValid() const { - return true; - // return !_zero && payload.isValid() && isCRCcorrect(); - } - - operator std::string() const { - // Packet type is known upfront in normal operation. - // Can't be used to dissect random packets. - return QueryDissector<cmd_id, decltype(*this)>::dissect(*this); - } - } __packed; - -/* - * Response payload (the parametrized type inside struct HIDReport) - * - * command_id member in incoming HIDReport structure carries the command - * type last used. - */ - namespace DeviceResponseConstants{ - //magic numbers from firmware - static constexpr auto storage_status_absolute_address = 21; - static constexpr auto storage_data_absolute_address = storage_status_absolute_address + 5; - static constexpr auto header_size = 8; //from _zero to last_command_status inclusive - static constexpr auto footer_size = 4; //crc - static constexpr auto wrapping_size = header_size + footer_size; - } - - template<CommandID cmd_id, typename ResponsePayload> - struct DeviceResponse { - static constexpr auto storage_status_padding_size = - DeviceResponseConstants::storage_status_absolute_address - DeviceResponseConstants::header_size; - - uint8_t _zero; - uint8_t device_status; - uint8_t command_id; // originally last_command_type - uint32_t last_command_crc; - uint8_t last_command_status; - - union { - uint8_t _padding[HID_REPORT_SIZE - DeviceResponseConstants::wrapping_size]; - ResponsePayload payload; - struct { - uint8_t _storage_status_padding[storage_status_padding_size]; - uint8_t command_counter; - uint8_t command_id; - uint8_t device_status; //@see stick20::device_status - uint8_t progress_bar_value; - } __packed storage_status; - } __packed; - - uint32_t crc; - - void initialize() { bzero(this, sizeof *this); } - - uint32_t calculate_CRC() const { - // w/o leading zero, a part of each HID packet - // w/o 4-byte crc - return misc::stm_crc32((const uint8_t *) (this) + 1, - (size_t) (HID_REPORT_SIZE - 5)); - } - - void update_CRC() { crc = calculate_CRC(); } - bool isCRCcorrect() const { return crc == calculate_CRC(); } - bool isValid() const { - // return !_zero && payload.isValid() && isCRCcorrect() && - // command_id == (uint8_t)(cmd_id); - return crc != 0; - } - - operator std::string() const { - return ResponseDissector<cmd_id, decltype(*this)>::dissect(*this); - } - } __packed; - - struct EmptyPayload { - bool isValid() const { return true; } - - std::string dissect() const { return std::string("Empty Payload."); } - } __packed; - - template<typename command_packet, typename response_payload> - class ClearingProxy { - public: - ClearingProxy(command_packet &p) { - packet = p; - bzero(&p, sizeof(p)); - } - - ~ClearingProxy() { - bzero(&packet, sizeof(packet)); - } - - response_payload &data() { - return packet.payload; - } - - command_packet packet; - }; - - template<CommandID cmd_id, typename command_payload, typename response_payload> - class Transaction : semantics::non_constructible { - public: - // Types declared in command class scope can't be reached from there. - typedef command_payload CommandPayload; - typedef response_payload ResponsePayload; - - - typedef struct HIDReport<cmd_id, CommandPayload> OutgoingPacket; - typedef struct DeviceResponse<cmd_id, ResponsePayload> ResponsePacket; -#pragma pack (pop) - - static_assert(std::is_pod<OutgoingPacket>::value, - "outgoingpacket must be a pod type"); - static_assert(std::is_pod<ResponsePacket>::value, - "ResponsePacket must be a POD type"); - static_assert(sizeof(OutgoingPacket) == HID_REPORT_SIZE, - "OutgoingPacket type is not the right size"); - static_assert(sizeof(ResponsePacket) == HID_REPORT_SIZE, - "ResponsePacket type is not the right size"); - - static uint32_t getCRC( - const command_payload &payload) { - OutgoingPacket outp; - outp.initialize(); - outp.payload = payload; - outp.update_CRC(); - return outp.crc; - } - - template<typename T> - static void clear_packet(T &st) { - bzero(&st, sizeof(st)); - } - - static ClearingProxy<ResponsePacket, response_payload> run(std::shared_ptr<device::Device> dev, - const command_payload &payload) { - using namespace ::nitrokey::device; - using namespace ::nitrokey::log; - using namespace std::chrono_literals; - - std::lock_guard<std::mutex> guard(send_receive_mtx); - - LOG(__FUNCTION__, Loglevel::DEBUG_L2); - - if (dev == nullptr){ - LOG(std::string("Throw: Device not initialized"), Loglevel::DEBUG_L1); - throw DeviceNotConnected("Device not initialized"); - } - dev->m_counters.total_comm_runs++; - - int status; - OutgoingPacket outp; - ResponsePacket resp; - - // POD types can't have non-default constructors - outp.initialize(); - resp.initialize(); - - outp.payload = payload; - outp.update_CRC(); - - LOG("-------------------", Loglevel::DEBUG); - LOG("Outgoing HID packet:", Loglevel::DEBUG); - LOG(static_cast<std::string>(outp), Loglevel::DEBUG); - LOG(std::string("=> ") + std::string(commandid_to_string(static_cast<CommandID>(outp.command_id))), Loglevel::DEBUG_L1); - - - if (!outp.isValid()) { - LOG(std::string("Throw: Invalid outgoing packet"), Loglevel::DEBUG_L1); - throw DeviceSendingFailure("Invalid outgoing packet"); - } - - bool successful_communication = false; - int receiving_retry_counter = 0; - int sending_retry_counter = dev->get_retry_sending_count(); - while (sending_retry_counter-- > 0) { - dev->m_counters.sends_executed++; - status = dev->send(&outp); - if (status <= 0){ - //FIXME early disconnection not yet working properly -// LOG("Encountered communication error, disconnecting device", Loglevel::DEBUG_L2); -// dev->disconnect(); - dev->m_counters.sending_error++; - LOG(std::string("Throw: Device error while sending command "), Loglevel::DEBUG_L1); - throw DeviceSendingFailure( - std::string("Device error while sending command ") + - std::to_string(status)); - } - - std::this_thread::sleep_for(dev->get_send_receive_delay()); - - // FIXME make checks done in device:recv here - receiving_retry_counter = dev->get_retry_receiving_count(); - int busy_counter = 0; - auto retry_timeout = dev->get_retry_timeout(); - while (receiving_retry_counter-- > 0) { - dev->m_counters.recv_executed++; - status = dev->recv(&resp); - - if (dev->get_device_model() == DeviceModel::STORAGE && - resp.command_id >= stick20::CMD_START_VALUE && - resp.command_id < stick20::CMD_END_VALUE ) { - LOG(std::string("Detected storage device cmd, status: ") + - std::to_string(resp.storage_status.device_status), Loglevel::DEBUG_L2); - - resp.last_command_status = static_cast<uint8_t>(stick10::command_status::ok); - switch (static_cast<stick20::device_status>(resp.storage_status.device_status)) { - case stick20::device_status::idle : - case stick20::device_status::ok: - resp.device_status = static_cast<uint8_t>(stick10::device_status::ok); - break; - case stick20::device_status::busy: - case stick20::device_status::busy_progressbar: //TODO this will be modified later for getting progressbar status - resp.device_status = static_cast<uint8_t>(stick10::device_status::busy); - break; - case stick20::device_status::wrong_password: - resp.last_command_status = static_cast<uint8_t>(stick10::command_status::wrong_password); - resp.device_status = static_cast<uint8_t>(stick10::device_status::ok); - break; - case stick20::device_status::no_user_password_unlock: - resp.last_command_status = static_cast<uint8_t>(stick10::command_status::AES_dec_failed); - resp.device_status = static_cast<uint8_t>(stick10::device_status::ok); - break; - default: - LOG(std::string("Unknown storage device status, cannot translate: ") + - std::to_string(resp.storage_status.device_status), Loglevel::DEBUG); - resp.device_status = resp.storage_status.device_status; - break; - }; - } - - //Some of the commands return wrong CRC, for now skip checking it (TODO list and report) - //if (resp.device_status == 0 && resp.last_command_crc == outp.crc && resp.isCRCcorrect()) break; - auto CRC_equal_awaited = true; // resp.last_command_crc == outp.crc; - if (resp.device_status == static_cast<uint8_t>(stick10::device_status::ok) && - CRC_equal_awaited && resp.isValid()){ - successful_communication = true; - break; - } - if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy)) { - dev->m_counters.busy++; - - if (busy_counter++<10) { - receiving_retry_counter++; - LOG("Status busy, not decreasing receiving_retry_counter counter: " + - std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); - } else { - retry_timeout *= 2; - retry_timeout = std::min(retry_timeout, 300ms); - busy_counter = 0; - LOG("Status busy, decreasing receiving_retry_counter counter: " + - std::to_string(receiving_retry_counter) + ", current delay:" - + std::to_string(retry_timeout.count()), Loglevel::DEBUG); - LOG(std::string("Busy retry: status ") - + std::to_string(resp.storage_status.device_status) - + ", " - + std::to_string(retry_timeout.count()) - + "ms, counter " - + std::to_string(receiving_retry_counter) - + ", progress: " - + std::to_string(resp.storage_status.progress_bar_value) - , Loglevel::DEBUG_L1); - } - } - if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy) && - static_cast<stick20::device_status>(resp.storage_status.device_status) - == stick20::device_status::busy_progressbar){ - successful_communication = true; - break; - } - LOG(std::string("Retry status - dev status, awaited cmd crc, correct packet CRC: ") - + std::to_string(resp.device_status) + - " " + std::to_string(CRC_equal_awaited) + - " " + std::to_string(resp.isCRCcorrect()), Loglevel::DEBUG_L2); - - if (!resp.isCRCcorrect()) dev->m_counters.wrong_CRC++; - if (!CRC_equal_awaited) dev->m_counters.CRC_other_than_awaited++; - - - LOG( - "Device is not ready or received packet's last CRC is not equal to sent CRC packet, retrying...", - Loglevel::DEBUG_L2); - LOG("Invalid incoming HID packet:", Loglevel::DEBUG_L2); - LOG(static_cast<std::string>(resp), Loglevel::DEBUG_L2); - dev->m_counters.total_retries++; - LOG(".", Loglevel::DEBUG_L1); - std::this_thread::sleep_for(retry_timeout); - continue; - } - if (successful_communication) break; - LOG(std::string("Resending (outer loop) "), Loglevel::DEBUG_L2); - LOG(std::string("sending_retry_counter count: ") + std::to_string(sending_retry_counter), - Loglevel::DEBUG); - } - - if(resp.last_command_crc != outp.crc){ - LOG(std::string("Accepting response with CRC other than expected ") - + "Command ID: " + std::to_string(resp.command_id) + " " + - commandid_to_string(static_cast<CommandID>(resp.command_id)) + " " - + "Reported by response and expected: " + std::to_string(resp.last_command_crc) + "!=" + std::to_string(outp.crc), - Loglevel::WARNING - ); - } - - dev->set_last_command_status(resp.last_command_status); // FIXME should be handled on device.recv - - clear_packet(outp); - - - if (status <= 0) { - dev->m_counters.receiving_error++; - LOG(std::string("Throw: Device error while executing command "), Loglevel::DEBUG_L1); - throw DeviceReceivingFailure( //FIXME replace with CriticalErrorException - std::string("Device error while executing command ") + - std::to_string(status)); - } - - LOG(std::string("<= ") + - std::string( - commandid_to_string(static_cast<CommandID>(resp.command_id)) - + std::string(" ") - + std::to_string(resp.device_status) - + std::string(" ") - + std::to_string(resp.storage_status.device_status) -// + std::to_string( status_translate_command(resp.storage_status.device_status)) - ), Loglevel::DEBUG_L1); - - LOG("Incoming HID packet:", Loglevel::DEBUG); - LOG(static_cast<std::string>(resp), Loglevel::DEBUG); - if (dev->get_retry_receiving_count() - receiving_retry_counter > 2) { - LOG(std::string("Packet received with receiving_retry_counter count: ") + - std::to_string(receiving_retry_counter), - Loglevel::DEBUG_L1); - } - - if (resp.device_status == static_cast<uint8_t>(stick10::device_status::busy) && - static_cast<stick20::device_status>(resp.storage_status.device_status) - == stick20::device_status::busy_progressbar){ - dev->m_counters.busy_progressbar++; - LOG(std::string("Throw: Long operation in progress exception"), Loglevel::DEBUG_L1); - throw LongOperationInProgressException( - resp.command_id, resp.device_status, resp.storage_status.progress_bar_value); - } - - if (!resp.isValid()) { - LOG(std::string("Throw: Invalid incoming packet"), Loglevel::DEBUG_L1); - throw InvalidCRCReceived("Invalid incoming packet"); - } - if (receiving_retry_counter <= 0){ - LOG(std::string("Throw: \"Maximum receiving_retry_counter count reached for receiving response from the device!\"" - + std::to_string(receiving_retry_counter)), Loglevel::DEBUG_L1); - throw DeviceReceivingFailure( - "Maximum receiving_retry_counter count reached for receiving response from the device!"); - } - dev->m_counters.communication_successful++; - - if (resp.last_command_status != static_cast<uint8_t>(stick10::command_status::ok)){ - dev->m_counters.command_result_not_equal_0_recv++; - LOG(std::string("Throw: CommandFailedException ") + std::to_string(resp.last_command_status), Loglevel::DEBUG_L1); - throw CommandFailedException(resp.command_id, resp.last_command_status); - } - - dev->m_counters.command_successful_recv++; - - if (dev->get_device_model() == DeviceModel::STORAGE && - resp.command_id >= stick20::CMD_START_VALUE && - resp.command_id < stick20::CMD_END_VALUE ) { - dev->m_counters.successful_storage_commands++; - } - - if (!resp.isCRCcorrect()) - LOG(std::string("Accepting response from device with invalid CRC. ") - + "Command ID: " + std::to_string(resp.command_id) + " " + - commandid_to_string(static_cast<CommandID>(resp.command_id)) + " " - + "Reported and calculated: " + std::to_string(resp.crc) + "!=" + std::to_string(resp.calculate_CRC()), - Loglevel::WARNING - ); - - // See: DeviceResponse - return resp; - } - - static ClearingProxy<ResponsePacket, response_payload> run(std::shared_ptr<device::Device> dev) { - command_payload empty_payload; - return run(dev, empty_payload); - } - }; - } -} -#endif diff --git a/include/dissect.h b/include/dissect.h deleted file mode 100644 index 690b5b7..0000000 --- a/include/dissect.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -/* - * Protocol packet dissection - */ -#ifndef DISSECT_H -#define DISSECT_H -#include <string> -#include <sstream> -#include <iomanip> -#include "misc.h" -#include "cxx_semantics.h" -#include "command_id.h" -#include "device_proto.h" - -namespace nitrokey { -namespace proto { - -template <CommandID id, class HIDPacket> -class QueryDissector : semantics::non_constructible { - public: - static std::string dissect(const HIDPacket &pod) { - std::stringstream out; - -#ifdef LOG_VOLATILE_DATA - out << "Raw HID packet:" << std::endl; - out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); -#endif - - out << "Contents:" << std::endl; - out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) - << std::endl; - out << "CRC:\t" - << std::hex << std::setw(2) << std::setfill('0') - << pod.crc << std::endl; - - out << "Payload:" << std::endl; - out << pod.payload.dissect(); - return out.str(); - } -}; - - - - -template <CommandID id, class HIDPacket> -class ResponseDissector : semantics::non_constructible { - public: - static std::string status_translate_device(int status){ - auto enum_status = static_cast<proto::stick10::device_status>(status); - switch (enum_status){ - case stick10::device_status::ok: return "OK"; - case stick10::device_status::busy: return "BUSY"; - case stick10::device_status::error: return "ERROR"; - case stick10::device_status::received_report: return "RECEIVED_REPORT"; - } - return std::string("UNKNOWN: ") + std::to_string(status); - } - - static std::string to_upper(std::string str){ - for (auto & c: str) c = toupper(c); - return str; - } - static std::string status_translate_command(int status){ - auto enum_status = static_cast<proto::stick10::command_status >(status); - switch (enum_status) { -#define p(X) case X: return to_upper(std::string(#X)); - p(stick10::command_status::ok) - p(stick10::command_status::wrong_CRC) - p(stick10::command_status::wrong_slot) - p(stick10::command_status::slot_not_programmed) - p(stick10::command_status::wrong_password) - p(stick10::command_status::not_authorized) - p(stick10::command_status::timestamp_warning) - p(stick10::command_status::no_name_error) - p(stick10::command_status::not_supported) - p(stick10::command_status::unknown_command) - p(stick10::command_status::AES_dec_failed) -#undef p - } - return std::string("UNKNOWN: ") + std::to_string(status); - } - - static std::string dissect(const HIDPacket &pod) { - std::stringstream out; - - // FIXME use values from firmware (possibly generate separate - // header automatically) - -#ifdef LOG_VOLATILE_DATA - out << "Raw HID packet:" << std::endl; - out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); -#endif - - out << "Device status:\t" << pod.device_status + 0 << " " - << status_translate_device(pod.device_status) << std::endl; - out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) << " hex: " << std::hex << (int)pod.command_id - << std::endl; - out << "Last command CRC:\t" - << std::hex << std::setw(2) << std::setfill('0') - << pod.last_command_crc << std::endl; - out << "Last command status:\t" << pod.last_command_status + 0 << " " - << status_translate_command(pod.last_command_status) << std::endl; - out << "CRC:\t" - << std::hex << std::setw(2) << std::setfill('0') - << pod.crc << std::endl; - if((int)pod.command_id == pod.storage_status.command_id){ - out << "Storage stick status (where applicable):" << std::endl; -#define d(x) out << " "#x": \t"<< std::hex << std::setw(2) \ - << std::setfill('0')<< static_cast<int>(x) << std::endl; - d(pod.storage_status.command_counter); - d(pod.storage_status.command_id); - d(pod.storage_status.device_status); - d(pod.storage_status.progress_bar_value); -#undef d - } - - out << "Payload:" << std::endl; - out << pod.payload.dissect(); - return out.str(); - } -}; -} -} - -#endif diff --git a/include/hidapi/hidapi.h b/include/hidapi/hidapi.h deleted file mode 100644 index e5bc2dc..0000000 --- a/include/hidapi/hidapi.h +++ /dev/null @@ -1,391 +0,0 @@ -/******************************************************* - HIDAPI - Multi-Platform library for - communication with HID devices. - - Alan Ott - Signal 11 Software - - 8/22/2009 - - Copyright 2009, All Rights Reserved. - - At the discretion of the user of this library, - this software may be licensed under the terms of the - GNU General Public License v3, a BSD-Style license, or the - original HIDAPI license as outlined in the LICENSE.txt, - LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt - files located at the root of the source distribution. - These files may also be found in the public source - code repository located at: - http://github.com/signal11/hidapi . -********************************************************/ - -/** @file - * @defgroup API hidapi API - */ - -#ifndef HIDAPI_H__ -#define HIDAPI_H__ - -#include <wchar.h> - -#ifdef _WIN32 - #define HID_API_EXPORT __declspec(dllexport) - #define HID_API_CALL -#else - #define HID_API_EXPORT /**< API export macro */ - #define HID_API_CALL /**< API call macro */ -#endif - -#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ - -#ifdef __cplusplus -extern "C" { -#endif - struct hid_device_; - typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ - - /** hidapi info structure */ - struct hid_device_info { - /** Platform-specific device path */ - char *path; - /** Device Vendor ID */ - unsigned short vendor_id; - /** Device Product ID */ - unsigned short product_id; - /** Serial Number */ - wchar_t *serial_number; - /** Device Release Number in binary-coded decimal, - also known as Device Version Number */ - unsigned short release_number; - /** Manufacturer String */ - wchar_t *manufacturer_string; - /** Product string */ - wchar_t *product_string; - /** Usage Page for this Device/Interface - (Windows/Mac only). */ - unsigned short usage_page; - /** Usage for this Device/Interface - (Windows/Mac only).*/ - unsigned short usage; - /** The USB interface which this logical device - represents. Valid on both Linux implementations - in all cases, and valid on the Windows implementation - only if the device contains more than one interface. */ - int interface_number; - - /** Pointer to the next device */ - struct hid_device_info *next; - }; - - - /** @brief Initialize the HIDAPI library. - - This function initializes the HIDAPI library. Calling it is not - strictly necessary, as it will be called automatically by - hid_enumerate() and any of the hid_open_*() functions if it is - needed. This function should be called at the beginning of - execution however, if there is a chance of HIDAPI handles - being opened by different threads simultaneously. - - @ingroup API - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_init(void); - - /** @brief Finalize the HIDAPI library. - - This function frees all of the static data associated with - HIDAPI. It should be called at the end of execution to avoid - memory leaks. - - @ingroup API - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_exit(void); - - /** @brief Enumerate the HID Devices. - - This function returns a linked list of all the HID devices - attached to the system which match vendor_id and product_id. - If @p vendor_id is set to 0 then any vendor matches. - If @p product_id is set to 0 then any product matches. - If @p vendor_id and @p product_id are both set to 0, then - all HID devices will be returned. - - @ingroup API - @param vendor_id The Vendor ID (VID) of the types of device - to open. - @param product_id The Product ID (PID) of the types of - device to open. - - @returns - This function returns a pointer to a linked list of type - struct #hid_device, containing information about the HID devices - attached to the system, or NULL in the case of failure. Free - this linked list by calling hid_free_enumeration(). - */ - struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); - - /** @brief Free an enumeration Linked List - - This function frees a linked list created by hid_enumerate(). - - @ingroup API - @param devs Pointer to a list of struct_device returned from - hid_enumerate(). - */ - void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); - - /** @brief Open a HID device using a Vendor ID (VID), Product ID - (PID) and optionally a serial number. - - If @p serial_number is NULL, the first device with the - specified VID and PID is opened. - - @ingroup API - @param vendor_id The Vendor ID (VID) of the device to open. - @param product_id The Product ID (PID) of the device to open. - @param serial_number The Serial Number of the device to open - (Optionally NULL). - - @returns - This function returns a pointer to a #hid_device object on - success or NULL on failure. - */ - HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); - - /** @brief Open a HID device by its path name. - - The path name be determined by calling hid_enumerate(), or a - platform-specific path name can be used (eg: /dev/hidraw0 on - Linux). - - @ingroup API - @param path The path name of the device to open - - @returns - This function returns a pointer to a #hid_device object on - success or NULL on failure. - */ - HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); - - /** @brief Write an Output report to a HID device. - - The first byte of @p data[] must contain the Report ID. For - devices which only support a single report, this must be set - to 0x0. The remaining bytes contain the report data. Since - the Report ID is mandatory, calls to hid_write() will always - contain one more byte than the report contains. For example, - if a hid report is 16 bytes long, 17 bytes must be passed to - hid_write(), the Report ID (or 0x0, for devices with a - single report), followed by the report data (16 bytes). In - this example, the length passed in would be 17. - - hid_write() will send the data on the first OUT endpoint, if - one exists. If it does not, it will send the data through - the Control Endpoint (Endpoint 0). - - @ingroup API - @param device A device handle returned from hid_open(). - @param data The data to send, including the report number as - the first byte. - @param length The length in bytes of the data to send. - - @returns - This function returns the actual number of bytes written and - -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); - - /** @brief Read an Input report from a HID device with timeout. - - Input reports are returned - to the host through the INTERRUPT IN endpoint. The first byte will - contain the Report number if the device uses numbered reports. - - @ingroup API - @param device A device handle returned from hid_open(). - @param data A buffer to put the read data into. - @param length The number of bytes to read. For devices with - multiple reports, make sure to read an extra byte for - the report number. - @param milliseconds timeout in milliseconds or -1 for blocking wait. - - @returns - This function returns the actual number of bytes read and - -1 on error. If no packet was available to be read within - the timeout period, this function returns 0. - */ - int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); - - /** @brief Read an Input report from a HID device. - - Input reports are returned - to the host through the INTERRUPT IN endpoint. The first byte will - contain the Report number if the device uses numbered reports. - - @ingroup API - @param device A device handle returned from hid_open(). - @param data A buffer to put the read data into. - @param length The number of bytes to read. For devices with - multiple reports, make sure to read an extra byte for - the report number. - - @returns - This function returns the actual number of bytes read and - -1 on error. If no packet was available to be read and - the handle is in non-blocking mode, this function returns 0. - */ - int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); - - /** @brief Set the device handle to be non-blocking. - - In non-blocking mode calls to hid_read() will return - immediately with a value of 0 if there is no data to be - read. In blocking mode, hid_read() will wait (block) until - there is data to read before returning. - - Nonblocking can be turned on and off at any time. - - @ingroup API - @param device A device handle returned from hid_open(). - @param nonblock enable or not the nonblocking reads - - 1 to enable nonblocking - - 0 to disable nonblocking. - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); - - /** @brief Send a Feature report to the device. - - Feature reports are sent over the Control endpoint as a - Set_Report transfer. The first byte of @p data[] must - contain the Report ID. For devices which only support a - single report, this must be set to 0x0. The remaining bytes - contain the report data. Since the Report ID is mandatory, - calls to hid_send_feature_report() will always contain one - more byte than the report contains. For example, if a hid - report is 16 bytes long, 17 bytes must be passed to - hid_send_feature_report(): the Report ID (or 0x0, for - devices which do not use numbered reports), followed by the - report data (16 bytes). In this example, the length passed - in would be 17. - - @ingroup API - @param device A device handle returned from hid_open(). - @param data The data to send, including the report number as - the first byte. - @param length The length in bytes of the data to send, including - the report number. - - @returns - This function returns the actual number of bytes written and - -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); - - /** @brief Get a feature report from a HID device. - - Set the first byte of @p data[] to the Report ID of the - report to be read. Make sure to allow space for this - extra byte in @p data[]. Upon return, the first byte will - still contain the Report ID, and the report data will - start in data[1]. - - @ingroup API - @param device A device handle returned from hid_open(). - @param data A buffer to put the read data into, including - the Report ID. Set the first byte of @p data[] to the - Report ID of the report to be read, or set it to zero - if your device does not use numbered reports. - @param length The number of bytes to read, including an - extra byte for the report ID. The buffer can be longer - than the actual report. - - @returns - This function returns the number of bytes read plus - one for the report ID (which is still in the first - byte), or -1 on error. - */ - int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); - - /** @brief Close a HID device. - - @ingroup API - @param device A device handle returned from hid_open(). - */ - void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); - - /** @brief Get The Manufacturer String from a HID device. - - @ingroup API - @param device A device handle returned from hid_open(). - @param string A wide string buffer to put the data into. - @param maxlen The length of the buffer in multiples of wchar_t. - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); - - /** @brief Get The Product String from a HID device. - - @ingroup API - @param device A device handle returned from hid_open(). - @param string A wide string buffer to put the data into. - @param maxlen The length of the buffer in multiples of wchar_t. - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); - - /** @brief Get The Serial Number String from a HID device. - - @ingroup API - @param device A device handle returned from hid_open(). - @param string A wide string buffer to put the data into. - @param maxlen The length of the buffer in multiples of wchar_t. - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); - - /** @brief Get a string from a HID device, based on its string index. - - @ingroup API - @param device A device handle returned from hid_open(). - @param string_index The index of the string to get. - @param string A wide string buffer to put the data into. - @param maxlen The length of the buffer in multiples of wchar_t. - - @returns - This function returns 0 on success and -1 on error. - */ - int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); - - /** @brief Get a string describing the last error which occurred. - - @ingroup API - @param device A device handle returned from hid_open(). - - @returns - This function returns a string containing the last error - which occurred or NULL if none has occurred. - */ - HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/include/log.h b/include/log.h deleted file mode 100644 index 2a64bef..0000000 --- a/include/log.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef LOG_H -#define LOG_H - -#include <string> -#include <functional> - -namespace nitrokey { - namespace log { - -//for MSVC -#ifdef ERROR -#undef ERROR -#endif - - - enum class Loglevel : int { - ERROR, - WARNING, - INFO, - DEBUG_L1, - DEBUG, - DEBUG_L2 - }; - - class LogHandler { - public: - virtual void print(const std::string &, Loglevel lvl) = 0; - protected: - std::string loglevel_to_str(Loglevel); - std::string format_message_to_string(const std::string &str, const Loglevel &lvl); - - }; - - class StdlogHandler : public LogHandler { - public: - virtual void print(const std::string &, Loglevel lvl); - }; - - class FunctionalLogHandler : public LogHandler { - using log_function_type = std::function<void(std::string)>; - log_function_type log_function; - public: - FunctionalLogHandler(log_function_type _log_function); - virtual void print(const std::string &, Loglevel lvl); - - }; - - extern StdlogHandler stdlog_handler; - - class Log { - public: - Log() : mp_loghandler(&stdlog_handler), m_loglevel(Loglevel::WARNING) {} - - static Log &instance() { - if (mp_instance == nullptr) mp_instance = new Log; - return *mp_instance; - } - - void operator()(const std::string &, Loglevel); - void set_loglevel(Loglevel lvl) { m_loglevel = lvl; } - void set_handler(LogHandler *handler) { mp_loghandler = handler; } - - private: - LogHandler *mp_loghandler; - Loglevel m_loglevel; - static std::string prefix; - public: - static void setPrefix(std::string prefix = std::string()); - - private: - - static Log *mp_instance; - }; - } -} - - -#ifdef NO_LOG -#define LOG(string, level) while(false){} -#define LOGD(string) while(false){} -#else -#define LOG(string, level) nitrokey::log::Log::instance()((string), (level)) -#define LOGD1(string) nitrokey::log::Log::instance()((string), (nitrokey::log::Loglevel::DEBUG_L1)) -#define LOGD(string) nitrokey::log::Log::instance()((string), (nitrokey::log::Loglevel::DEBUG_L2)) -#endif - -#endif diff --git a/include/misc.h b/include/misc.h deleted file mode 100644 index 88254dd..0000000 --- a/include/misc.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - - -#ifndef MISC_H -#define MISC_H -#include <stdio.h> -#include <string> -#include <vector> -#include <string.h> -#include "log.h" -#include "LibraryException.h" -#include <sstream> -#include <iomanip> - - -namespace nitrokey { -namespace misc { - - template<typename T> - std::string toHex(T value){ - using namespace std; - std::ostringstream oss; - oss << std::hex << std::setw(sizeof(value)*2) << std::setfill('0') << value; - return oss.str(); - } - - /** - * Copies string from pointer to fixed size C-style array. Src needs to be a valid C-string - eg. ended with '\0'. - * Throws when source is bigger than destination. - * @tparam T type of destination array - * @param dest fixed size destination array - * @param src pointer to source c-style valid string - */ - template <typename T> - void strcpyT(T& dest, const char* src){ - - if (src == nullptr) -// throw EmptySourceStringException(slot_number); - return; - const size_t s_dest = sizeof dest; - LOG(std::string("strcpyT sizes dest src ") - +std::to_string(s_dest)+ " " - +std::to_string(strlen(src))+ " " - ,nitrokey::log::Loglevel::DEBUG_L2); - if (strlen(src) > s_dest){ - throw TooLongStringException(strlen(src), s_dest, src); - } - strncpy((char*) &dest, src, s_dest); - } - -#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) - template <typename T> -typename T::CommandPayload get_payload(){ - //Create, initialize and return by value command payload - typename T::CommandPayload st; - bzero(&st, sizeof(st)); - return st; -} - - template<typename CMDTYPE, typename Tdev> - void execute_password_command(Tdev &stick, const char *password) { - auto p = get_payload<CMDTYPE>(); - p.set_defaults(); - strcpyT(p.password, password); - CMDTYPE::CommandTransaction::run(stick, p); - } - - std::string hexdump(const uint8_t *p, size_t size, bool print_header=true, bool print_ascii=true, - bool print_empty=true); - uint32_t stm_crc32(const uint8_t *data, size_t size); - std::vector<uint8_t> hex_string_to_byte(const char* hexString); -} -} - -#endif diff --git a/include/stick10_commands.h b/include/stick10_commands.h deleted file mode 100644 index 893b98f..0000000 --- a/include/stick10_commands.h +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef STICK10_COMMANDS_H -#define STICK10_COMMANDS_H - -#include <bitset> -#include <iomanip> -#include <string> -#include <sstream> -#include <stdint.h> -#include "device_proto.h" -#include "command.h" - -#pragma pack (push,1) - -namespace nitrokey { -namespace proto { - - - -/* - * Stick10 protocol definition - */ -namespace stick10 { -class GetSlotName : public Command<CommandID::READ_SLOT_NAME> { - 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<command_id(), struct CommandPayload, - struct ResponsePayload> CommandTransaction; -}; - -class EraseSlot : Command<CommandID::ERASE_SLOT> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class SetTime : Command<CommandID::SET_TIME> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - - -class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> { - 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 uint8_t *)(&slot_counter), sizeof slot_counter, false); - - return ss.str(); - } - } __packed; - - typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class WriteToTOTPSlot : Command<CommandID::WRITE_TO_SLOT> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class GetTOTP : Command<CommandID::GET_CODE> { - 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<command_id(), struct CommandPayload, struct ResponsePayload> - CommandTransaction; -}; - -class GetHOTP : Command<CommandID::GET_CODE> { - 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<command_id(), struct CommandPayload, struct ResponsePayload> - CommandTransaction; -}; - -class ReadSlot : Command<CommandID::READ_SLOT> { - 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 uint8_t *)(&slot_counter), sizeof slot_counter, false); - return ss.str(); - } - } __packed; - - typedef Transaction<command_id(), struct CommandPayload, - struct ResponsePayload> CommandTransaction; -}; - -class GetStatus : Command<CommandID::GET_STATUS> { - public: - struct ResponsePayload { - union { - uint16_t firmware_version; - struct { - uint8_t minor; - uint8_t major; - } firmware_version_st; - }; - 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 uint8_t *)(&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 uint8_t *)(card_serial), - sizeof card_serial, false); - ss << "general_config:\t" - << ::nitrokey::misc::hexdump((const uint8_t *)(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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; -}; - -class GetPasswordRetryCount : Command<CommandID::GET_PASSWORD_RETRY_COUNT> { - 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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; -}; - -class GetUserPasswordRetryCount - : Command<CommandID::GET_USER_PASSWORD_RETRY_COUNT> { - 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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; -}; - - template <typename T, typename Q, int N> - void write_array(T &ss, Q (&arr)[N]){ - for (int i=0; i<N; i++){ - ss << std::hex << std::setfill('0') << std::setw(2) << (int)arr[i] << " "; - } - ss << std::endl; - }; - - -class GetPasswordSafeSlotStatus : Command<CommandID::GET_PW_SAFE_SLOT_STATUS> { - 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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; -}; - -class GetPasswordSafeSlotName : Command<CommandID::GET_PW_SAFE_SLOT_NAME> { - 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<command_id(), struct CommandPayload, - struct ResponsePayload> CommandTransaction; -}; - -class GetPasswordSafeSlotPassword - : Command<CommandID::GET_PW_SAFE_SLOT_PASSWORD> { - 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<command_id(), struct CommandPayload, - struct ResponsePayload> CommandTransaction; -}; - -class GetPasswordSafeSlotLogin - : Command<CommandID::GET_PW_SAFE_SLOT_LOGINNAME> { - 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<command_id(), struct CommandPayload, - struct ResponsePayload> CommandTransaction; -}; - -class SetPasswordSafeSlotData : Command<CommandID::SET_PW_SAFE_SLOT_DATA_1> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class SetPasswordSafeSlotData2 : Command<CommandID::SET_PW_SAFE_SLOT_DATA_2> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class ErasePasswordSafeSlot : Command<CommandID::PW_SAFE_ERASE_SLOT> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class EnablePasswordSafe : Command<CommandID::PW_SAFE_ENABLE> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class PasswordSafeInitKey : Command<CommandID::PW_SAFE_INIT_KEY> { - /** - * never used in Nitrokey App - */ - public: - typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload> - CommandTransaction; -}; - -class PasswordSafeSendSlotViaHID : Command<CommandID::PW_SAFE_SEND_DATA> { - /** - * 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -// TODO "Device::passwordSafeSendSlotDataViaHID" - -class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class FirstAuthenticate : Command<CommandID::FIRST_AUTHENTICATE> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class UserAuthenticate : Command<CommandID::USER_AUTHENTICATE> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class Authorize : Command<CommandID::AUTHORIZE> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class UserAuthorize : Command<CommandID::USER_AUTHORIZE> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class ChangeUserPin : Command<CommandID::CHANGE_USER_PIN> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class IsAESSupported : Command<CommandID::DETECT_SC_AES> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - - -class ChangeAdminPin : Command<CommandID::CHANGE_ADMIN_PIN> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class LockDevice : Command<CommandID::LOCK_DEVICE> { - public: - typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload> - CommandTransaction; -}; - -class FactoryReset : Command<CommandID::FACTORY_RESET> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; -}; - -class BuildAESKey : Command<CommandID::NEW_AES_KEY> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - 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 a04946f..0000000 --- a/include/stick10_commands_0.8.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - - -#ifndef LIBNITROKEY_STICK10_COMMANDS_0_8_H -#define LIBNITROKEY_STICK10_COMMANDS_0_8_H - -#include <bitset> -#include <iomanip> -#include <string> -#include <sstream> -#include <cstdint> -#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<CommandID::ERASE_SLOT> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; - }; - - class SendOTPData : Command<CommandID::SEND_OTP_DATA> { - //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 uint8_t *) (&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 uint8_t *) (&data), sizeof data); -#else - ss << " Volatile data not logged" << std::endl; -#endif - return ss.str(); - } - } __packed; - - - typedef Transaction<command_id(), struct CommandPayload, struct ResponsePayload> - CommandTransaction; - }; - - class WriteToOTPSlot : Command<CommandID::WRITE_TO_SLOT> { - //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 uint8_t *) (&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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; - }; - - class GetHOTP : Command<CommandID::GET_CODE> { - 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<command_id(), struct CommandPayload, struct ResponsePayload> - CommandTransaction; - }; - - - class GetTOTP : Command<CommandID::GET_CODE> { - //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<command_id(), struct CommandPayload, struct ResponsePayload> - CommandTransaction; - }; - - - class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> { - //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<command_id(), struct CommandPayload, struct EmptyPayload> - 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 4b75e6a..0000000 --- a/include/stick20_commands.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2015-2018 Nitrokey UG - * - * This file is part of libnitrokey. - * - * libnitrokey is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * libnitrokey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. - * - * SPDX-License-Identifier: LGPL-3.0 - */ - -#ifndef STICK20_COMMANDS_H -#define STICK20_COMMANDS_H - - - -#include <cstdint> -#include "command.h" -#include <string> -#include <sstream> -#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<CommandID::SEND_PASSWORD, PasswordKind::Admin> {}; - class ChangeAdminUserPin20New : - public PasswordCommand<CommandID::SEND_NEW_PASSWORD, PasswordKind::Admin> {}; - class UnlockUserPin : - public PasswordCommand<CommandID::UNLOCK_USER_PASSWORD, PasswordKind::Admin> {}; - - class EnableEncryptedPartition : public PasswordCommand<CommandID::ENABLE_CRYPTED_PARI> {}; - class EnableHiddenEncryptedPartition : public PasswordCommand<CommandID::ENABLE_HIDDEN_CRYPTED_PARI> {}; - - class SetUnencryptedVolumeReadOnlyAdmin : - public PasswordCommand<CommandID::ENABLE_ADMIN_READONLY_UNCRYPTED_LUN, PasswordKind::Admin> {}; - class SetUnencryptedVolumeReadWriteAdmin : - public PasswordCommand<CommandID::ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN, PasswordKind::Admin> {}; - class SetEncryptedVolumeReadOnly : - public PasswordCommand<CommandID::ENABLE_ADMIN_READONLY_ENCRYPTED_LUN, PasswordKind::Admin> {}; - class SetEncryptedVolumeReadWrite : - public PasswordCommand<CommandID::ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN, PasswordKind::Admin> {}; - - //FIXME the volume disabling commands do not need password - class DisableEncryptedPartition : public PasswordCommand<CommandID::DISABLE_CRYPTED_PARI> {}; - class DisableHiddenEncryptedPartition : public PasswordCommand<CommandID::DISABLE_HIDDEN_CRYPTED_PARI> {}; - - class EnableFirmwareUpdate : public PasswordCommand<CommandID::ENABLE_FIRMWARE_UPDATE> {}; - - class ChangeUpdatePassword : Command<CommandID::CHANGE_UPDATE_PIN> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; - }; - - class ExportFirmware : public PasswordCommand<CommandID::EXPORT_FIRMWARE_TO_FILE> {}; - - class CreateNewKeys : - public PasswordCommand<CommandID::GENERATE_NEW_KEYS, PasswordKind::AdminPrefixed, 30> {}; - - - class FillSDCardWithRandomChars : Command<CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS> { - 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<uint8_t>(ChosenVolumes::encrypted_volume); - } - - } __packed; - - typedef Transaction<Command<CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS>::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 uint8_t *) (_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 major; - uint8_t minor; - uint8_t _reserved2; - uint8_t build_iteration; - } __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) ReadWriteFlagHiddenVolume_u8 ); - print_to_ss((int) versionInfo.major ); - print_to_ss((int) versionInfo.minor ); - print_to_ss((int) versionInfo.build_iteration ); - print_to_ss((int) FirmwareLocked_u8 ); - print_to_ss((int) NewSDCardFound_u8 ); - print_to_ss((int) NewSDCardFound_st.NewCard ); - print_to_ss((int) NewSDCardFound_st.Counter ); - print_to_ss((int) SDFillWithRandomChars_u8 ); - print_to_ss( ActiveSD_CardID_u32 ); - print_to_ss((int) VolumeActiceFlag_u8 ); - print_to_ss((int) VolumeActiceFlag_st.unencrypted ); - print_to_ss((int) VolumeActiceFlag_st.encrypted ); - print_to_ss((int) VolumeActiceFlag_st.hidden); - 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<CommandID::SEND_STARTUP> { - 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::seconds> ( - std::chrono::system_clock::now().time_since_epoch()).count(); - } - }__packed; - - using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; - - typedef Transaction<command_id(), struct CommandPayload, ResponsePayload> - CommandTransaction; - }; - - -// TODO fix original nomenclature - class SendSetReadonlyToUncryptedVolume : public PasswordCommand<CommandID::ENABLE_READONLY_UNCRYPTED_LUN> {}; - class SendSetReadwriteToUncryptedVolume : public PasswordCommand<CommandID::ENABLE_READWRITE_UNCRYPTED_LUN> {}; - class SendClearNewSdCardFound : public PasswordCommand<CommandID::CLEAR_NEW_SD_CARD_FOUND> {}; - - class GetDeviceStatus : Command<CommandID::GET_DEVICE_STATUS> { - public: - using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; - - typedef Transaction<command_id(), struct EmptyPayload, ResponsePayload> - CommandTransaction; - }; - - class CheckSmartcardUsage : Command<CommandID::CHECK_SMARTCARD_USAGE> { - public: - typedef Transaction<command_id(), struct EmptyPayload, EmptyPayload> - CommandTransaction; - }; - - class GetSDCardOccupancy : Command<CommandID::SD_CARD_HIGH_WATERMARK> { - 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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; - }; - - - class SetupHiddenVolume : Command<CommandID::SEND_HIDDEN_VOLUME_SETUP> { - 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<command_id(), struct CommandPayload, struct EmptyPayload> - CommandTransaction; - }; - - -//disable this command for now -// class LockFirmware : public PasswordCommand<CommandID::SEND_LOCK_STICK_HARDWARE> {}; - - class ProductionTest : Command<CommandID::PRODUCTION_TEST> { - 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<command_id(), struct EmptyPayload, struct ResponsePayload> - CommandTransaction; - }; - - } - } -} - -#undef print_to_ss -#pragma pack (pop) - -#endif |