Fix improper handling of empty arrays in EIP712 messages
This commit is contained in:
@@ -143,14 +143,18 @@ static cx_sha3_t *get_last_hash_ctx(void) {
|
||||
* Finalize the last hashing context
|
||||
*
|
||||
* @param[out] hash pointer to buffer where the hash will be stored
|
||||
* @return whether there was anything hashed at this depth
|
||||
*/
|
||||
static void finalize_hash_depth(uint8_t *hash) {
|
||||
static bool finalize_hash_depth(uint8_t *hash) {
|
||||
const cx_sha3_t *hash_ctx;
|
||||
size_t hashed_bytes;
|
||||
|
||||
hash_ctx = get_last_hash_ctx();
|
||||
hashed_bytes = hash_ctx->blen;
|
||||
// finalize hash
|
||||
cx_hash((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE);
|
||||
mem_dealloc(sizeof(*hash_ctx)); // remove hash context
|
||||
return hashed_bytes > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,6 +196,7 @@ static bool push_new_hash_depth(bool init) {
|
||||
*/
|
||||
static bool path_depth_list_pop(void) {
|
||||
uint8_t hash[KECCAK256_HASH_BYTESIZE];
|
||||
bool to_feed;
|
||||
|
||||
if (path_struct == NULL) {
|
||||
return false;
|
||||
@@ -201,9 +206,11 @@ static bool path_depth_list_pop(void) {
|
||||
}
|
||||
path_struct->depth_count -= 1;
|
||||
|
||||
finalize_hash_depth(hash);
|
||||
to_feed = finalize_hash_depth(hash);
|
||||
if (path_struct->depth_count > 0) {
|
||||
feed_last_hash_depth(hash);
|
||||
if (to_feed) {
|
||||
feed_last_hash_depth(hash);
|
||||
}
|
||||
} else {
|
||||
switch (path_struct->root_type) {
|
||||
case ROOT_DOMAIN:
|
||||
@@ -261,7 +268,7 @@ static bool array_depth_list_pop(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
finalize_hash_depth(hash);
|
||||
finalize_hash_depth(hash); // return value not checked on purpose
|
||||
feed_last_hash_depth(hash);
|
||||
|
||||
path_struct->array_depth_count -= 1;
|
||||
@@ -421,6 +428,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
uint8_t total_count = 0;
|
||||
uint8_t pidx;
|
||||
bool is_custom;
|
||||
uint8_t array_size;
|
||||
uint8_t array_depth_count_bak;
|
||||
|
||||
if (path_struct == NULL) {
|
||||
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
|
||||
@@ -430,6 +439,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
array_size = *data;
|
||||
array_depth_count_bak = path_struct->array_depth_count;
|
||||
for (pidx = 0; pidx < path_struct->depth_count; ++pidx) {
|
||||
if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) {
|
||||
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
|
||||
@@ -442,7 +453,7 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
}
|
||||
total_count += depth_count;
|
||||
if (total_count > path_struct->array_depth_count) {
|
||||
if (!check_and_add_array_depth(depth, total_count, pidx, *data)) {
|
||||
if (!check_and_add_array_depth(depth, total_count, pidx, array_size)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -463,9 +474,18 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
cx_sha3_t *hash_ctx = get_last_hash_ctx();
|
||||
cx_sha3_t *old_ctx = hash_ctx - 1;
|
||||
|
||||
memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
|
||||
if (array_size > 0) {
|
||||
memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
|
||||
} else {
|
||||
cx_keccak_init(hash_ctx, 256);
|
||||
}
|
||||
cx_keccak_init(old_ctx, 256); // init hash
|
||||
}
|
||||
if (array_size == 0) {
|
||||
do {
|
||||
path_advance();
|
||||
} while (path_struct->array_depth_count != array_depth_count_bak);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -515,7 +535,7 @@ static bool path_advance_in_array(void) {
|
||||
|
||||
if ((path_struct->array_depth_count > 0) &&
|
||||
(arr_depth->path_index == (path_struct->depth_count - 1))) {
|
||||
arr_depth->size -= 1;
|
||||
if (arr_depth->size > 0) arr_depth->size -= 1;
|
||||
if (arr_depth->size == 0) {
|
||||
array_depth_list_pop();
|
||||
end_reached = true;
|
||||
|
||||
Reference in New Issue
Block a user