37#include "status_words.h"
49#if defined(HAVE_ADDRESS_BOOK) && defined(HAVE_ADDRESS_BOOK_LEDGER_ACCOUNT)
52#define STRUCT_VERSION 0x01
61 uint8_t hmac_proof[CX_SHA256_SIZE];
62} s_edit_ledger_account_ctx;
65#define EDIT_LEDGER_ACCOUNT_TAGS(X) \
66 X(0x01, TAG_STRUCTURE_TYPE, handle_struct_type, ENFORCE_UNIQUE_TAG) \
67 X(0x02, TAG_STRUCTURE_VERSION, handle_struct_version, ENFORCE_UNIQUE_TAG) \
68 X(0xf0, TAG_CONTACT_NAME, handle_contact_name, ENFORCE_UNIQUE_TAG) \
69 X(0xf3, TAG_PREVIOUS_NAME, handle_previous_name, ENFORCE_UNIQUE_TAG) \
70 X(0x69, TAG_DERIVATION_PATH, handle_derivation_path, ENFORCE_UNIQUE_TAG) \
71 X(0x23, TAG_CHAIN_ID, handle_chain_id, ENFORCE_UNIQUE_TAG) \
72 X(0x29, TAG_HMAC_PROOF, handle_hmac_proof, ENFORCE_UNIQUE_TAG) \
73 X(0x51, TAG_BLOCKCHAIN_FAMILY, handle_blockchain_family, ENFORCE_UNIQUE_TAG)
86static bool handle_struct_type(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
90 PRINTF(
"[Edit Ledger Account] Invalid STRUCTURE_TYPE value\n");
103static bool handle_struct_version(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
107 PRINTF(
"[Edit Ledger Account] Invalid STRUCTURE_VERSION value\n");
120static bool handle_contact_name(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
122 if (!address_book_handle_printable_string(data,
123 context->edit->ledger_account.account_name,
124 sizeof(context->edit->ledger_account.account_name))) {
125 PRINTF(
"CONTACT_NAME: failed to parse\n");
138static bool handle_previous_name(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
140 if (!address_book_handle_printable_string(
141 data, context->edit->old_account_name,
sizeof(context->edit->old_account_name))) {
142 PRINTF(
"PREVIOUS_NAME: failed to parse\n");
155static bool handle_derivation_path(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
157 return address_book_handle_derivation_path(data, &context->edit->ledger_account.bip32_path);
169 return address_book_handle_chain_id(data, &context->edit->ledger_account.chain_id);
179static bool handle_blockchain_family(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
181 return address_book_handle_blockchain_family(data,
182 &context->edit->ledger_account.blockchain_family);
192static bool handle_hmac_proof(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
196 PRINTF(
"[Edit Ledger Account] HMAC_PROOF: invalid length (expected %d bytes)\n",
200 memmove(context->hmac_proof, buf.
ptr, CX_SHA256_SIZE);
212static bool verify_fields(
const s_edit_ledger_account_ctx *context)
216 TAG_STRUCTURE_VERSION,
220 TAG_BLOCKCHAIN_FAMILY,
223 PRINTF(
"Missing mandatory fields in Edit Ledger Account descriptor!\n");
226 if (context->edit->ledger_account.blockchain_family ==
FAMILY_ETHEREUM) {
229 PRINTF(
"Missing CHAIN_ID for Ethereum family in Edit Ledger Account descriptor!\n");
242static void print_payload(
const s_edit_ledger_account_ctx *context)
247 PRINTF(
"****************************************************************************\n");
248 PRINTF(
"[Edit Ledger Account] - Retrieved Descriptor:\n");
249 PRINTF(
"[Edit Ledger Account] - Old name: %s\n", context->edit->old_account_name);
250 PRINTF(
"[Edit Ledger Account] - New name: %s\n",
251 context->edit->ledger_account.account_name);
253 PRINTF(
"[Edit Ledger Account] - Derivation path[%d]: %s\n",
254 context->edit->ledger_account.bip32_path.length,
258 PRINTF(
"[Edit Ledger Account] - Derivation path length[%d] (failed to format)\n",
259 context->edit->ledger_account.bip32_path.length);
261 PRINTF(
"[Edit Ledger Account] - Blockchain family: %s\n",
262 FAMILY_AS_STR(context->edit->ledger_account.blockchain_family));
263 if (context->edit->ledger_account.blockchain_family ==
FAMILY_ETHEREUM) {
264 PRINTF(
"[Edit Ledger Account] - Chain ID: %llu\n",
265 context->edit->ledger_account.chain_id);
277static bool build_and_send_response(
void)
279 uint8_t hmac_proof[CX_SHA256_SIZE] = {0};
281 if (!address_book_compute_hmac_proof_ledger_account(
282 &g_ab_payload.edit_ledger_account.ledger_account.bip32_path,
283 (
const char *) g_ab_payload.edit_ledger_account.ledger_account.account_name,
284 g_ab_payload.edit_ledger_account.ledger_account.blockchain_family,
285 g_ab_payload.edit_ledger_account.ledger_account.chain_id,
287 PRINTF(
"[Edit Ledger Account] Error: Failed to compute new HMAC proof\n");
292 explicit_bzero(hmac_proof,
sizeof(hmac_proof));
301static void review_choice(
bool confirm)
304 bool ok = build_and_send_response();
306 on_edit_ledger_account_applied(&g_ab_payload.edit_ledger_account);
309 PRINTF(
"[Edit Ledger Account] Error: Failed to build and send HMAC proof\n");
311 address_book_finalize_review(
312 ok,
"Account name changed",
"Error during update", finalize_ui_ledger_account);
315 address_book_handle_review_rejected(finalize_ui_ledger_account);
330 const buffer_t payload = {.
ptr = buffer_in, .size = buffer_in_length};
331 s_edit_ledger_account_ctx ctx = {0};
334 ctx.edit = &g_ab_payload.edit_ledger_account;
335 memset(&g_ab_payload.edit_ledger_account, 0,
sizeof(g_ab_payload.edit_ledger_account));
338 if (!edit_ledger_account_tlv_parser(&payload, &ctx, &ctx.received_tags)) {
339 PRINTF(
"[Edit Ledger Account] TLV parsing failed\n");
340 return SWO_INCORRECT_DATA;
342 if (!verify_fields(&ctx)) {
343 return SWO_INCORRECT_DATA;
348 if (!address_book_verify_hmac_proof_ledger_account(
349 &g_ab_payload.edit_ledger_account.ledger_account.bip32_path,
350 g_ab_payload.edit_ledger_account.old_account_name,
351 g_ab_payload.edit_ledger_account.ledger_account.blockchain_family,
352 g_ab_payload.edit_ledger_account.ledger_account.chain_id,
354 PRINTF(
"[Edit Ledger Account] HMAC proof verification failed\n");
355 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
359 if (!handle_check_edit_ledger_account(&g_ab_payload.edit_ledger_account)) {
360 PRINTF(
"[Edit Ledger Account] Coin-app rejected edit\n");
361 return SWO_INCORRECT_DATA;
365 display_register_ledger_account_review(review_choice);
366 return SWO_NO_RESPONSE;
bool bip32_path_format_simple(path_bip32_t *bip32, char *out, size_t out_len)
Format a BIP32 path as a string.
#define TYPE_EDIT_LEDGER_ACCOUNT
bolos_err_t edit_ledger_account(uint8_t *buffer_in, size_t buffer_in_length)
API of the Advanced BOLOS Graphical Library, for typical application use-cases.
Data extracted from a Rename Ledger Account TLV payload.
bool tlv_enforce_u8_value(const tlv_data_t *data, uint8_t expected_value)
Enforce that a TLV data contains the expected uint8 value.
bool get_buffer_from_tlv_data(const tlv_data_t *data, buffer_t *out, uint16_t min_size, uint16_t max_size)
Extract a sized buffer from TLV data (zero-copy).
#define DEFINE_TLV_PARSER(TAG_LIST, COMMON_HANDLER, PARSE_FUNCTION_NAME)
Creates a parser function for a given TLV use case.
#define TLV_CHECK_RECEIVED_TAGS(received,...)
static bool handle_chain_id(const tlv_data_t *data, tlv_extracted_t *tlv_extracted)