Skip to content

Commit

Permalink
Date/Time EIP-712 filtering implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
apaillier-ledger committed May 21, 2024
1 parent 65ae3a5 commit e0d0929
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src_features/signMessageEIP712/commands_712.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define P2_IMPL_FIELD P2_DEF_FIELD
#define P2_FILT_ACTIVATE 0x00
#define P2_FILT_MESSAGE_INFO 0x0F
#define P2_FILT_DATE_TIME 0xFC
#define P2_FILT_AMOUNT_JOIN_TOKEN 0xFD
#define P2_FILT_AMOUNT_JOIN_VALUE 0xFE
#define P2_FILT_RAW_FIELD 0xFF
Expand Down Expand Up @@ -177,6 +178,9 @@ bool handle_eip712_filtering(const uint8_t *const apdu_buf) {
reply_apdu = false;
}
break;
case P2_FILT_DATE_TIME:
ret = filtering_date_time(&apdu_buf[OFFSET_CDATA], apdu_buf[OFFSET_LC]);
break;
case P2_FILT_AMOUNT_JOIN_TOKEN:
ret = filtering_amount_join_token(&apdu_buf[OFFSET_CDATA], apdu_buf[OFFSET_LC]);
break;
Expand Down
67 changes: 64 additions & 3 deletions src_features/signMessageEIP712/filtering.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define FILT_MAGIC_MESSAGE_INFO 183
#define FILT_MAGIC_AMOUNT_JOIN_TOKEN 11
#define FILT_MAGIC_AMOUNT_JOIN_VALUE 22
#define FILT_MAGIC_DATETIME 33
#define FILT_MAGIC_RAW_FIELD 72

/**
Expand Down Expand Up @@ -214,6 +215,66 @@ bool filtering_message_info(const uint8_t *payload, uint8_t length) {
return true;
}

/**
* Command to display a field as a date-time
*
* @param[in] payload the payload to parse
* @param[in] length the payload length
* @return whether it was successful or not
*/
bool filtering_date_time(const uint8_t *payload, uint8_t length) {
uint8_t name_len;
const char *name;
uint8_t sig_len;
const uint8_t *sig;
uint8_t offset = 0;

if (path_get_root_type() != ROOT_MESSAGE) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}

// Parsing
if ((offset + sizeof(name_len)) > length) {
return false;
}
name_len = payload[offset++];
if ((offset + name_len) > length) {
return false;
}
name = (char *) &payload[offset];
offset += name_len;
if ((offset + sizeof(sig_len)) > length) {
return false;
}
sig_len = payload[offset++];
if ((offset + sig_len) != length) {
return false;
}
sig = &payload[offset];

// Verification
cx_sha256_t hash_ctx;
if (!sig_verif_start(&hash_ctx, FILT_MAGIC_DATETIME)) {
return false;
}
hash_filtering_path((cx_hash_t *) &hash_ctx);
hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx);
if (!sig_verif_end(&hash_ctx, sig, sig_len)) {
return false;
}

// Handling
if (!check_typename("uint")) {
return false;
}
if (name_len > 0) { // don't substitute for an empty name
ui_712_set_title(name, name_len);
}
ui_712_flag_field(true, name_len > 0, false, true);
return true;
}

/**
* Command to display a field as an amount-join (token part)
*
Expand Down Expand Up @@ -261,7 +322,7 @@ bool filtering_amount_join_token(const uint8_t *payload, uint8_t length) {
if (!check_typename("address") || !check_token_index(token_idx)) {
return false;
}
ui_712_flag_field(false, false, true);
ui_712_flag_field(false, false, true, false);
ui_712_token_join_prepare_addr_check(token_idx);
return true;
}
Expand Down Expand Up @@ -328,7 +389,7 @@ bool filtering_amount_join_value(const uint8_t *payload, uint8_t length) {
if (!check_typename("uint") || !check_token_index(token_idx)) {
return false;
}
ui_712_flag_field(false, false, true);
ui_712_flag_field(false, false, true, false);
ui_712_token_join_prepare_amount(token_idx, name, name_len);
return true;
}
Expand Down Expand Up @@ -386,7 +447,7 @@ bool filtering_raw_field(const uint8_t *payload, uint8_t length) {
if (name_len > 0) { // don't substitute for an empty name
ui_712_set_title(name, name_len);
}
ui_712_flag_field(true, name_len > 0, false);
ui_712_flag_field(true, name_len > 0, false, false);
return true;
}

Expand Down
1 change: 1 addition & 0 deletions src_features/signMessageEIP712/filtering.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdint.h>

bool filtering_message_info(const uint8_t *payload, uint8_t length);
bool filtering_date_time(const uint8_t *payload, uint8_t length);
bool filtering_amount_join_token(const uint8_t *payload, uint8_t length);
bool filtering_amount_join_value(const uint8_t *payload, uint8_t length);
bool filtering_raw_field(const uint8_t *payload, uint8_t length);
Expand Down
50 changes: 49 additions & 1 deletion src_features/signMessageEIP712/ui_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "ui_logic.h"
#include "mem.h"
#include "mem_utils.h"
Expand Down Expand Up @@ -39,6 +40,7 @@ typedef enum {
#define UI_712_FIELD_SHOWN (1 << 0)
#define UI_712_FIELD_NAME_PROVIDED (1 << 1)
#define UI_712_AMOUNT_JOIN (1 << 2)
#define UI_712_DATETIME (1 << 3)

typedef struct {
s_amount_join joins[MAX_ITEMS];
Expand Down Expand Up @@ -426,6 +428,42 @@ static bool update_amount_join(const uint8_t *data, uint8_t length) {
return true;
}

/**
* Format given data as a human-readable date/time representation
*
* @param[in] data the data that needs formatting
* @param[in] length its length
* @return whether it was successful or not
*/
static bool ui_712_format_datetime(const uint8_t *data, uint8_t length) {
struct tm tstruct;
int shown_hour;
time_t timestamp = u64_from_BE(data, length);

if (gmtime_r(&timestamp, &tstruct) == NULL) {
return false;
}
if (tstruct.tm_hour == 0) {
shown_hour = 12;
} else {
shown_hour = tstruct.tm_hour;
if (shown_hour > 12) {
shown_hour -= 12;
}
}
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"%04d-%02d-%02d\n%02d:%02d:%02d %s UTC",
tstruct.tm_year + 1900,
tstruct.tm_mon + 1,
tstruct.tm_mday,
shown_hour,
tstruct.tm_min,
tstruct.tm_sec,
(tstruct.tm_hour < 12) ? "AM" : "PM");
return true;
}

/**
* Used to notify of a new field to review in the current struct (key + value)
*
Expand Down Expand Up @@ -497,6 +535,12 @@ bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data, ui
}
}

if (ui_ctx->field_flags & UI_712_DATETIME) {
if (!ui_712_format_datetime(data, length)) {
return false;
}
}

// Check if this field is supposed to be displayed
if (ui_712_field_shown()) {
ui_712_redraw_generic_step();
Expand Down Expand Up @@ -573,8 +617,9 @@ unsigned int ui_712_reject() {
* @param[in] show if this field should be shown on the device
* @param[in] name_provided if a substitution name has been provided
* @param[in] token_join if this field is part of a token join
* @param[in] datetime if this field should be shown and formatted as a date/time
*/
void ui_712_flag_field(bool show, bool name_provided, bool token_join) {
void ui_712_flag_field(bool show, bool name_provided, bool token_join, bool datetime) {
if (show) {
ui_ctx->field_flags |= UI_712_FIELD_SHOWN;
}
Expand All @@ -584,6 +629,9 @@ void ui_712_flag_field(bool show, bool name_provided, bool token_join) {
if (token_join) {
ui_ctx->field_flags |= UI_712_AMOUNT_JOIN;
}
if (datetime) {
ui_ctx->field_flags |= UI_712_DATETIME;
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src_features/signMessageEIP712/ui_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void ui_712_set_title(const char *const str, uint8_t length);
void ui_712_set_value(const char *const str, uint8_t length);
void ui_712_message_hash(void);
void ui_712_redraw_generic_step(void);
void ui_712_flag_field(bool show, bool name_provided, bool token_join);
void ui_712_flag_field(bool show, bool name_provided, bool token_join, bool datetime);
void ui_712_field_flags_reset(void);
void ui_712_finalize_field(void);
void ui_712_set_filtering_mode(e_eip712_filtering_mode mode);
Expand Down

0 comments on commit e0d0929

Please sign in to comment.