diff options
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  | 
