Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 106 additions & 27 deletions src/commander.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ static void commander_process_random(yajl_val json_node)
encoded_report = aes_cbc_b64_encrypt((unsigned char *)echo_number,
strlens(echo_number),
&encrypt_len,
memory_report_aeskey(PASSWORD_VERIFY));
memory_report_verification_key());
if (encoded_report) {
commander_fill_report(cmd_str(CMD_echo), encoded_report, DBB_OK);
free(encoded_report);
Expand Down Expand Up @@ -779,7 +779,7 @@ static void commander_process_verifypass(yajl_val json_node)

if (strlens(value)) {
if (strcmp(value, attr_str(ATTR_export)) == 0) {
memcpy(text, utils_uint8_to_hex(memory_report_aeskey(PASSWORD_VERIFY), 32), 64 + 1);
memcpy(text, utils_uint8_to_hex(memory_report_verification_key(), 32), 64 + 1);
utils_clear_buffers();
int ret = sd_write(VERIFYPASS_FILENAME, text, NULL,
DBB_SD_REPLACE, CMD_verifypass);
Expand Down Expand Up @@ -837,7 +837,7 @@ static void commander_process_verifypass(yajl_val json_node)
char *enc = aes_cbc_b64_encrypt((const unsigned char *)VERIFYPASS_CRYPT_TEST,
strlens(VERIFYPASS_CRYPT_TEST),
&encrypt_len,
memory_report_aeskey(PASSWORD_VERIFY));
memory_report_verification_key());
if (enc) {
snprintf(msg, sizeof(msg), "{\"%s\":\"%s\", \"%s\":\"%s\"}",
cmd_str(CMD_ecdh), utils_uint8_to_hex(out_pubkey, sizeof(out_pubkey)),
Expand Down Expand Up @@ -877,7 +877,7 @@ static void commander_process_xpub(yajl_val json_node)
encoded_report = aes_cbc_b64_encrypt((unsigned char *)xpub,
strlens(xpub),
&encrypt_len,
memory_report_aeskey(PASSWORD_VERIFY));
memory_report_verification_key());
if (encoded_report) {
commander_fill_report(cmd_str(CMD_echo), encoded_report, DBB_OK);
free(encoded_report);
Expand All @@ -903,6 +903,33 @@ static uint8_t commander_bootloader_unlocked(void)
}


static void commander_process_session(yajl_val json_node)
{
const char *path[] = { cmd_str(CMD_session), NULL };
const char *value = YAJL_GET_STRING(yajl_tree_get(json_node, path, yajl_t_string));

if (!strlens(value)) {
commander_fill_report(cmd_str(CMD_session), NULL, DBB_ERR_IO_INVALID_CMD);
return;
}

if (strcmp(value, attr_str(ATTR_set)) == 0) {
commander_fill_report(cmd_str(CMD_session),
utils_uint8_to_hex(memory_session_key_update(),
MEM_PAGE_LEN), DBB_OK);
return;
}

if (strcmp(value, attr_str(ATTR_off)) == 0) {
memory_session_key_off();
commander_fill_report(cmd_str(CMD_session), attr_str(ATTR_success), DBB_OK);
return;
}

commander_fill_report(cmd_str(CMD_session), NULL, DBB_ERR_IO_INVALID_CMD);
}


static void commander_process_device(yajl_val json_node)
{
const char *path[] = { cmd_str(CMD_device), NULL };
Expand Down Expand Up @@ -986,7 +1013,7 @@ static void commander_process_device(yajl_val json_node)
char *tfa = aes_cbc_b64_encrypt((const unsigned char *)VERIFYPASS_CRYPT_TEST,
strlens(VERIFYPASS_CRYPT_TEST),
&tfa_len,
memory_report_aeskey(PASSWORD_VERIFY));
memory_report_verification_key());
if (!tfa) {
commander_clear_report();
commander_fill_report(cmd_str(CMD_device), NULL, DBB_ERR_MEM_ENCRYPT);
Expand Down Expand Up @@ -1148,9 +1175,16 @@ static void commander_process_password(yajl_val json_node, int cmd, PASSWORD_ID

ret = commander_process_aes_key(value, strlens(value), id);

if (!memcmp(memory_report_aeskey(PASSWORD_STAND), memory_report_aeskey(PASSWORD_HIDDEN),
if (!memcmp(memory_read_aeskey(PASSWORD_STAND), memory_read_aeskey(PASSWORD_HIDDEN),
MEM_PAGE_LEN)) {

if (memory_session_key_get_state() == MEM_SESSION_KEY_STATE_STATIC) {
memory_session_key_set(memory_read_aeskey(PASSWORD_STAND));
memory_session_key_off();
}

memory_random_password(PASSWORD_HIDDEN);
memory_clear_passwords();
commander_fill_report(cmd_str(CMD_password), NULL, DBB_ERR_IO_PW_COLLIDE);
return;
}
Expand Down Expand Up @@ -1179,6 +1213,10 @@ static int commander_process(int cmd, yajl_val json_node)
commander_process_password(json_node, cmd, PASSWORD_STAND);
break;

case CMD_session:
commander_process_session(json_node);
break;

case CMD_verifypass:
commander_process_verifypass(json_node);
break;
Expand Down Expand Up @@ -1365,7 +1403,7 @@ static int commander_echo_command(yajl_val json_node)
encoded_report = aes_cbc_b64_encrypt((unsigned char *)json_report,
strlens(json_report),
&encrypt_len,
memory_report_aeskey(PASSWORD_VERIFY));
memory_report_verification_key());
commander_clear_report();
if (encoded_report) {
commander_fill_report(cmd_str(CMD_echo), encoded_report, DBB_OK);
Expand Down Expand Up @@ -1495,8 +1533,11 @@ static void commander_parse(char *command)
encoded_report = aes_cbc_b64_encrypt((unsigned char *)json_report,
strlens(json_report),
&encrypt_len,
wallet_is_hidden() ? memory_report_aeskey(PASSWORD_HIDDEN) : memory_report_aeskey(
PASSWORD_STAND));
memory_session_key_report());

if (memory_session_key_get_state() == MEM_SESSION_KEY_STATE_UPDATING) {
memory_session_key_set(NULL);
}
commander_clear_report();
if (encoded_report) {
commander_fill_report(cmd_str(CMD_ciphertext), encoded_report, DBB_OK);
Expand All @@ -1509,19 +1550,73 @@ static void commander_parse(char *command)
}


static void commander_set_session_key(const char *encrypted_command)
{
char *command;
int command_len = 0;
size_t json_object_len = 0;
uint8_t *key;

// Try standard wallet password
key = memory_read_aeskey(PASSWORD_STAND);
command = aes_cbc_b64_decrypt((const unsigned char *)encrypted_command,
strlens(encrypted_command),
&command_len, key);

if (strlens(command)) {
yajl_val json_node = yajl_tree_parse(command, NULL, 0);
if (json_node && YAJL_IS_OBJECT(json_node)) {
json_object_len = json_node->u.object.len;
}
yajl_tree_free(json_node);
free(command);

if (json_object_len) {
wallet_set_hidden(0);
memory_session_key_set(key);
return;
}
}

// Try hidden wallet password
key = memory_read_aeskey(PASSWORD_HIDDEN);
command = aes_cbc_b64_decrypt((const unsigned char *)encrypted_command,
strlens(encrypted_command),
&command_len, key);

if (strlens(command)) {
yajl_val json_node = yajl_tree_parse(command, NULL, 0);
if (json_node && YAJL_IS_OBJECT(json_node)) {
json_object_len = json_node->u.object.len;
}
yajl_tree_free(json_node);
free(command);

if (json_object_len) {
wallet_set_hidden(1);
memory_session_key_set(key);
return;
}
}
}


static char *commander_decrypt(const char *encrypted_command)
{
char *command;
int command_len = 0, err = 0;
uint16_t err_count = 0, err_iter = 0;
size_t json_object_len = 0;

wallet_set_hidden(0);
if (memory_session_key_get_state() == MEM_SESSION_KEY_STATE_OFF) {
commander_set_session_key(encrypted_command);
memory_clear_passwords();
}

command = aes_cbc_b64_decrypt((const unsigned char *)encrypted_command,
strlens(encrypted_command),
&command_len,
memory_report_aeskey(PASSWORD_STAND));
memory_session_key_report());

err_count = memory_report_access_err_count();
err_iter = memory_report_access_err_count() + 1;
Expand All @@ -1547,22 +1642,6 @@ static char *commander_decrypt(const char *encrypted_command)
free(command);
}

// Check if hidden wallet is requested
command = aes_cbc_b64_decrypt((const unsigned char *)encrypted_command,
strlens(encrypted_command),
&command_len,
memory_report_aeskey(PASSWORD_HIDDEN));
if (strlens(command)) {
yajl_val json_node = yajl_tree_parse(command, NULL, 0);
if (json_node && YAJL_IS_OBJECT(json_node)) {
wallet_set_hidden(1);
yajl_tree_free(json_node);
return command;
}
yajl_tree_free(json_node);
free(command);
}

// Incorrect input
err_iter = memory_access_err_count(DBB_ACCESS_ITERATE);
commander_access_err(DBB_ERR_IO_JSON_PARSE, err_iter);
Expand Down
3 changes: 3 additions & 0 deletions src/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ X(REQUIRE_TOUCH) /* placeholder - do not move */\
/* parent keys */\
/* w/o touch */\
X(verifypass) \
X(session) \
X(led) \
X(xpub) \
X(name) \
Expand Down Expand Up @@ -145,6 +146,8 @@ X(unlock) \
X(decrypt) \
X(encrypt) \
X(verify) \
X(set) \
X(off) \
X(true) \
X(false) \
X(erase) \
Expand Down
Loading