diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/NitrokeyManager.h | 16 | ||||
| -rw-r--r-- | include/device.h | 2 | ||||
| -rw-r--r-- | include/device_proto.h | 5 | ||||
| -rw-r--r-- | include/stick10_commands.h | 126 | 
4 files changed, 89 insertions, 60 deletions
| diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 4f1dcfa..7bc2673 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -21,10 +21,12 @@ namespace nitrokey {          static 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, 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, const char *temporary_password); +        bool write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_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);          uint32_t get_HOTP_code(uint8_t slot_number, const char *user_temporary_password);          uint32_t get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval,                                 const char *user_temporary_password); @@ -68,13 +70,15 @@ namespace nitrokey {          void build_aes_key(const char *admin_password); -        void unlock_user_password(const char *admin_password); +        void unlock_user_password(const char *admin_password, const char *new_user_password); -        void write_config(bool numlock, bool capslock, bool scrolllock, bool enable_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); +      private:          NitrokeyManager();          ~NitrokeyManager(); diff --git a/include/device.h b/include/device.h index ffc38e5..0553d2e 100644 --- a/include/device.h +++ b/include/device.h @@ -50,7 +50,7 @@ public:    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() const; +    int get_last_command_status() {auto a = last_command_status; last_command_status = 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;} diff --git a/include/device_proto.h b/include/device_proto.h index 6e21f9f..78abe38 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -215,11 +215,14 @@ class Transaction : semantics::non_constructible {      Log::instance()("Incoming HID packet:", Loglevel::DEBUG);      Log::instance()((std::string)(resp), Loglevel::DEBUG); +    Log::instance()(std::string("Retry count: ") + std::to_string(retry), Loglevel::DEBUG);      if (!resp.isValid()) throw std::runtime_error("Invalid incoming packet"); +    if (retry <= 0) throw std::runtime_error("Maximum retry count reached for receiving response from the device!");      if (resp.last_command_status!=0) throw CommandFailedException(resp.command_id, resp.last_command_status); -    // See: DeviceResponse + +      // See: DeviceResponse      return resp.payload;    } diff --git a/include/stick10_commands.h b/include/stick10_commands.h index 6df8727..ef83747 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -81,7 +81,6 @@ class SetTime : Command<CommandID::SET_TIME> {  }; -// TODO duplicate TOTP  class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> {   public:    struct CommandPayload { @@ -96,7 +95,15 @@ class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> {              bool use_tokenID    : 1;          };      }; -    uint8_t slot_token_id[13]; +      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; +      };        uint64_t slot_counter;      bool isValid() const { return !(slot_number & 0xF0); } @@ -137,7 +144,15 @@ class WriteToTOTPSlot : Command<CommandID::WRITE_TO_SLOT> {                bool use_tokenID    : 1;            };        }; -    uint8_t slot_token_id[13]; +      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 @@ -160,27 +175,6 @@ class WriteToTOTPSlot : Command<CommandID::WRITE_TO_SLOT> {        CommandTransaction;  }; -class GetCode : 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); } -  } __packed; - -  struct ResponsePayload { -    uint8_t code[18]; - -    bool isValid() const { return true; } -  } __packed; - -  typedef Transaction<command_id(), struct CommandPayload, -                      struct ResponsePayload> CommandTransaction; -}; -  class GetTOTP : Command<CommandID::GET_CODE> {   public:    struct CommandPayload { @@ -202,18 +196,28 @@ class GetTOTP : Command<CommandID::GET_CODE> {    struct ResponsePayload {        union { -          uint8_t whole_response[18]; //TODO remove if not needed +          uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1            struct {                uint32_t code; -              uint8_t config; -          } __packed; -      } __packed; +              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 << "config:\t" << "TODO" /*(config) */<< std::endl; //TODO show byte field options +        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; @@ -237,10 +241,17 @@ class GetHOTP : Command<CommandID::GET_CODE> {    struct ResponsePayload {        union { -          uint8_t whole_response[18]; //TODO remove if not needed +          uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1            struct {                uint32_t code; -              uint8_t config; +              union{ +                  uint8_t _slot_config; +                  struct{ +                      bool use_8_digits   : 1; +                      bool use_enter      : 1; +                      bool use_tokenID    : 1; +                  }; +              };            } __packed;        } __packed; @@ -248,7 +259,10 @@ class GetHOTP : Command<CommandID::GET_CODE> {      std::string dissect() const {        std::stringstream ss;        ss << "code:\t" << (code) << std::endl; -      ss << "config:\t" << "TODO" /*(config) */<< std::endl; //TODO show byte field options +        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; @@ -301,14 +315,14 @@ class GetStatus : Command<CommandID::GET_STATUS> {        union {            uint8_t general_config[5];            struct{ -              uint8_t numlock; -              uint8_t capslock; -              uint8_t scrolllock; +              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;            };        }; -    bool isValid() const { return true; } +    bool isValid() const { return enable_user_password!=delete_user_password; }      std::string dissect() const {        std::stringstream ss; @@ -319,9 +333,9 @@ class GetStatus : Command<CommandID::GET_STATUS> {        ss << "general_config:\t"           << ::nitrokey::misc::hexdump((const char *)(general_config),                                        sizeof general_config); -        ss << "numlock:\t" << (bool)numlock << std::endl; -        ss << "capslock:\t" << (bool)capslock << std::endl; -        ss << "scrolllock:\t" << (bool)scrolllock << std::endl; +        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; @@ -557,13 +571,18 @@ class EnablePasswordSafe : Command<CommandID::PW_SAFE_ENABLE> {  };  class PasswordSafeInitKey : Command<CommandID::PW_SAFE_INIT_KEY> { +    /** +     * never used in Nitrokey App +     */   public:    typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload>        CommandTransaction;  }; -// TODO naming screwed up, see above  class PasswordSafeSendSlotViaHID : Command<CommandID::PW_SAFE_SEND_DATA> { +    /** +     * never used in Nitrokey App +     */   public:    struct CommandPayload {      uint8_t slot_number; @@ -584,18 +603,18 @@ class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> {      union{          uint8_t config[5];          struct{ -            uint8_t numlock; -            uint8_t capslock; -            uint8_t scrolllock; +            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" << (bool)numlock << std::endl; -          ss << "capslock:\t" << (bool)capslock << std::endl; -          ss << "scrolllock:\t" << (bool)scrolllock << std::endl; +          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(); @@ -666,7 +685,7 @@ class Authorize : Command<CommandID::AUTHORIZE> {  class UserAuthorize : Command<CommandID::USER_AUTHORIZE> {   public:    struct CommandPayload { -    uint64_t crc_to_authorize; +    uint32_t crc_to_authorize;      uint8_t temporary_password[25];      std::string dissect() const {        std::stringstream ss; @@ -683,7 +702,8 @@ class UserAuthorize : Command<CommandID::USER_AUTHORIZE> {  class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {   public:    struct CommandPayload { -    uint8_t admin_password[20]; +    uint8_t admin_password[25]; +    uint8_t user_new_password[25];        std::string dissect() const {            std::stringstream ss;            ss << " admin_password:\t" <<  admin_password<< std::endl; @@ -691,8 +711,6 @@ class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {        }    } __packed; -  // TODO could we get the stick to return the retry count? -    typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload>        CommandTransaction;  }; @@ -714,11 +732,15 @@ class ChangeUserPin : Command<CommandID::CHANGE_USER_PIN> {        CommandTransaction;  }; -// TODO why is it needed?  class IsAESSupported : Command<CommandID::DETECT_SC_AES> {   public:    struct CommandPayload { -    uint8_t password[20]; +    uint8_t user_password[20]; +      std::string dissect() const { +          std::stringstream ss; +          ss << " user_password:\t" <<  user_password<< std::endl; +          return ss.str(); +      }    } __packed;    typedef Transaction<command_id(), struct CommandPayload, struct EmptyPayload> | 
