summaryrefslogtreecommitdiff
path: root/include/stick10_commands.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/stick10_commands.h')
-rw-r--r--include/stick10_commands.h582
1 files changed, 582 insertions, 0 deletions
diff --git a/include/stick10_commands.h b/include/stick10_commands.h
new file mode 100644
index 0000000..de31e95
--- /dev/null
+++ b/include/stick10_commands.h
@@ -0,0 +1,582 @@
+#ifndef STICK10_COMMANDS_H
+#define STICK10_COMMANDS_H
+#include <string>
+#include <sstream>
+#include "inttypes.h"
+#include "command.h"
+
+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 & 0xF0);
+ }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_name[15];
+
+ bool isValid() const {
+ return true;
+ }
+ } __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);
+ }
+ } __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;
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ // TODO duplicate TOTP
+ class WriteToHOTPSlot : Command<CommandID::WRITE_TO_SLOT> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+ uint8_t slot_name[15];
+ uint8_t slot_secret[20];
+ uint8_t slot_config;
+ uint8_t slot_token_id[13];
+ uint8_t slot_counter[8];
+
+ bool isValid() const {
+ return !(slot_number & 0xF0);
+ }
+ } __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];
+ uint8_t slot_config;
+ uint8_t slot_token_id[13];
+ uint16_t slot_interval;
+
+ bool isValid() const {
+ return !(slot_number & 0xF0);
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> 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 GetHOTP : Command<CommandID::GET_CODE> {
+ public:
+ struct CommandPayload {
+ uint8_t slot_number;
+
+ bool isValid() const {
+ return !(slot_number & 0xF0);
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> 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];
+ uint8_t config;
+ uint8_t token_id[13];
+ uint64_t counter;
+
+ bool isValid() const {
+ return true;
+ }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "slot_name:\t" << slot_name << std::endl;
+ ss << "config:\t" << config << std::endl;
+ ss << "token_id:\t" << token_id << std::endl;
+ ss << "counter:\t" << counter << std::endl;
+ return ss.str();
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct ResponsePayload> CommandTransaction;
+ };
+
+ class GetStatus : Command<CommandID::GET_STATUS> {
+ public:
+ struct ResponsePayload {
+ uint16_t firmware_version;
+ uint8_t card_serial[4];
+ uint8_t general_config[3];
+ uint8_t otp_password_config[2];
+
+ bool isValid() const {
+ return true;
+ }
+
+ std::string dissect() const {
+ std::stringstream ss;
+ ss << "firmware_version:\t" << firmware_version << std::endl;
+ ss << "card_serial:\t"
+ << ::nitrokey::misc::hexdump((const char *)(card_serial), sizeof card_serial);
+ ss << "general_config:\t"
+ << ::nitrokey::misc::hexdump((const char *)(general_config), sizeof general_config);
+ ss << "otp_password_config:\t"
+ << ::nitrokey::misc::hexdump((const char *)(otp_password_config), sizeof otp_password_config);
+ 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;
+ }
+ } __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;
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct EmptyPayload,
+ struct ResponsePayload> CommandTransaction;
+ };
+
+ 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;
+ }
+ } __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);
+ }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_name[PWS_SLOTNAME_LENGTH];
+
+ bool isValid() const {
+ return true;
+ }
+ } __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);
+ }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_password[PWS_PASSWORD_LENGTH];
+
+ bool isValid() const {
+ return true;
+ }
+ } __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);
+ }
+ } __packed;
+
+ struct ResponsePayload {
+ uint8_t slot_login[PWS_LOGINNAME_LENGTH];
+
+ bool isValid() const {
+ return true;
+ }
+ } __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);
+ }
+ } __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_name[PWS_SLOTNAME_LENGTH];
+
+ bool isValid() const {
+ return !(slot_number & 0xF0);
+ }
+ } __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);
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class EnablePasswordSafe : Command<CommandID::PW_SAFE_ENABLE> {
+ public:
+ struct CommandPayload {
+ uint8_t password[30];
+
+ bool isValid() const {
+ return true;
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class PasswordSafeInitKey : Command<CommandID::PW_SAFE_INIT_KEY> {
+ public:
+ typedef Transaction<command_id(),
+ struct EmptyPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ // TODO naming screwed up, see above
+ class PasswordSafeSendSlotViaHID: Command<CommandID::PW_SAFE_SEND_DATA> {
+ 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 {
+ uint8_t config[5];
+ } __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;
+ ss << "card_password:\t" << card_password << std::endl;
+ ss << "temporary_password:\t" << temporary_password << std::endl;
+ 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;
+ }
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class Authorize : Command<CommandID::AUTHORIZE> {
+ public:
+ struct CommandPayload {
+ uint8_t crc[4];
+ uint8_t password[25];
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class UserAuthorize : Command<CommandID::USER_AUTHORIZE> {
+ public:
+ struct CommandPayload {
+ uint8_t crc[4];
+ uint8_t password[25];
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class UnlockUserPassword : Command<CommandID::UNLOCK_USER_PASSWORD> {
+ public:
+ struct CommandPayload {
+ uint8_t admin_password[20]; // TODO
+ } __packed;
+
+ // TODO could we get the stick to return the retry count?
+
+ 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];
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ // TODO why is it needed?
+ class IsAESSupported : Command<CommandID::DETECT_SC_AES> {
+ public:
+ struct CommandPayload {
+ uint8_t password[20];
+ } __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];
+ } __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 password[20];
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+
+ class BuildAESKey : Command<CommandID::NEW_AES_KEY> {
+ public:
+ struct CommandPayload {
+ uint8_t password[20];
+ } __packed;
+
+ typedef Transaction<command_id(),
+ struct CommandPayload,
+ struct EmptyPayload> CommandTransaction;
+ };
+}
+
+}
+}
+#endif