36#include "status_words.h"
37#include "tlv_library.h"
48#if defined(HAVE_ADDRESS_BOOK) && defined(HAVE_ADDRESS_BOOK_LEDGER_ACCOUNT)
51#define STRUCT_VERSION 0x01
59 TLV_reception_t received_tags;
60} s_ledger_account_ctx;
63#define LEDGER_ACCOUNT_TAGS(X) \
64 X(0x01, TAG_STRUCTURE_TYPE, handle_struct_type, ENFORCE_UNIQUE_TAG) \
65 X(0x02, TAG_STRUCTURE_VERSION, handle_struct_version, ENFORCE_UNIQUE_TAG) \
66 X(0xf0, TAG_CONTACT_NAME, handle_contact_name, ENFORCE_UNIQUE_TAG) \
67 X(0x21, TAG_DERIVATION_PATH, handle_derivation_path, ENFORCE_UNIQUE_TAG) \
68 X(0x23, TAG_CHAIN_ID, handle_chain_id, ENFORCE_UNIQUE_TAG) \
69 X(0x51, TAG_BLOCKCHAIN_FAMILY, handle_blockchain_family, ENFORCE_UNIQUE_TAG)
82static bool handle_struct_type(
const tlv_data_t *data, s_ledger_account_ctx *context)
86 PRINTF(
"[Register Ledger Account] Invalid STRUCTURE_TYPE value\n");
99static bool handle_struct_version(
const tlv_data_t *data, s_ledger_account_ctx *context)
102 if (!tlv_enforce_u8_value(data, STRUCT_VERSION)) {
103 PRINTF(
"[Register Ledger Account] Invalid STRUCTURE_VERSION value\n");
116static bool handle_contact_name(
const tlv_data_t *data, s_ledger_account_ctx *context)
118 if (!address_book_handle_printable_string(data,
119 context->ledger_account->account_name,
120 sizeof(context->ledger_account->account_name))) {
121 PRINTF(
"CONTACT_NAME: failed to parse\n");
134static bool handle_derivation_path(
const tlv_data_t *data, s_ledger_account_ctx *context)
136 return address_book_handle_derivation_path(data, &context->ledger_account->bip32_path);
146static bool handle_chain_id(
const tlv_data_t *data, s_ledger_account_ctx *context)
148 return address_book_handle_chain_id(data, &context->ledger_account->chain_id);
158static bool handle_blockchain_family(
const tlv_data_t *data, s_ledger_account_ctx *context)
160 return address_book_handle_blockchain_family(data, &context->ledger_account->blockchain_family);
163DEFINE_TLV_PARSER(LEDGER_ACCOUNT_TAGS, NULL, ledger_account_tlv_parser)
171static bool verify_fields(
const s_ledger_account_ctx *context)
173 bool result = TLV_CHECK_RECEIVED_TAGS(context->received_tags,
175 TAG_STRUCTURE_VERSION,
178 TAG_BLOCKCHAIN_FAMILY);
180 PRINTF(
"Missing mandatory fields in Ledger Account descriptor!\n");
184 result = TLV_CHECK_RECEIVED_TAGS(context->received_tags, TAG_CHAIN_ID);
186 PRINTF(
"Missing CHAIN_ID for Ethereum family in Ledger Account descriptor!\n");
199static void print_payload(
const s_ledger_account_ctx *context)
204 PRINTF(
"****************************************************************************\n");
205 PRINTF(
"[Ledger Account] - Retrieved Descriptor:\n");
206 PRINTF(
"[Ledger Account] - Account name: %s\n",
207 context->ledger_account->account_name);
209 PRINTF(
"[Ledger Account] - Derivation path[%d]: %s\n",
210 context->ledger_account->bip32_path.length,
214 PRINTF(
"[Ledger Account] - Derivation path length[%d] (failed to format)\n",
215 context->ledger_account->bip32_path.length);
217 PRINTF(
"[Ledger Account] - Blockchain family: %s\n",
220 PRINTF(
"[Ledger Account] - Chain ID: %llu\n",
221 context->ledger_account->chain_id);
233static bool build_and_send_response(
void)
235 uint8_t hmac_proof[CX_SHA256_SIZE] = {0};
237 if (!address_book_compute_hmac_proof_ledger_account(
238 &g_ab_payload.ledger_account.bip32_path,
239 (
const char *) g_ab_payload.ledger_account.account_name,
240 g_ab_payload.ledger_account.blockchain_family,
241 g_ab_payload.ledger_account.chain_id,
243 PRINTF(
"[Ledger Account] Error: Failed to compute HMAC proof\n");
248 explicit_bzero(hmac_proof,
sizeof(hmac_proof));
257static void review_choice(
bool confirm)
260 bool ok = build_and_send_response();
262 PRINTF(
"[Ledger Account] Error: Failed to build and send response\n");
264 address_book_finalize_review(
265 ok,
"Name confirmed",
"Error saving account", finalize_ui_register_ledger_account);
268 address_book_handle_review_rejected(finalize_ui_register_ledger_account);
283 const buffer_t payload = {.
ptr = buffer_in, .size = buffer_in_length};
284 s_ledger_account_ctx ctx = {0};
287 ctx.ledger_account = &g_ab_payload.ledger_account;
288 memset(&g_ab_payload.ledger_account, 0,
sizeof(g_ab_payload.ledger_account));
291 if (!ledger_account_tlv_parser(&payload, &ctx, &ctx.received_tags)) {
292 PRINTF(
"[Ledger Account] Failed to parse TLV payload\n");
293 return SWO_INCORRECT_DATA;
295 if (!verify_fields(&ctx)) {
296 return SWO_INCORRECT_DATA;
301 if (!handle_check_register_ledger_account(ctx.ledger_account)) {
302 PRINTF(
"[Ledger Account] Error: Account rejected by coin application\n");
303 return SWO_WRONG_PARAMETER_VALUE;
307 display_register_ledger_account_review(review_choice);
308 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_REGISTER_LEDGER_ACCOUNT
bolos_err_t register_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 Register Ledger Account TLV payload.