Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fbe/parameters in stack #245

Open
wants to merge 3 commits into
base: fbe/swap_spl_token
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ APPNAME = "Exchange"
APPVERSION_M = 4
APPVERSION_N = 1
APPVERSION_P = 0
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-pkiv1"
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-pkiv2"

# Application source files
APP_SOURCE_PATH += src
Expand Down
14 changes: 8 additions & 6 deletions src/apdu_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,26 +141,28 @@ static uint16_t check_instruction(uint8_t instruction, uint8_t subcommand) {
return INVALID_INSTRUCTION;
}

if (G_swap_ctx.state == WAITING_USER_VALIDATION) {
if (G_swap_ctx->state == WAITING_USER_VALIDATION) {
PRINTF("Refuse all APDUs during UI display\n");
return UNEXPECTED_INSTRUCTION;
}

if (!allowed_during_waiting_for_signing && G_swap_ctx.state == WAITING_SIGNING) {
if (!allowed_during_waiting_for_signing && G_swap_ctx->state == WAITING_SIGNING) {
PRINTF("Received instruction %d, not allowed during WAITING_SIGNING state\n", instruction);
return UNEXPECTED_INSTRUCTION;
}

if (check_subcommand_context && subcommand != G_swap_ctx.subcommand) {
PRINTF("Received subcommand %d, current flow uses %d\n", subcommand, G_swap_ctx.subcommand);
if (check_subcommand_context && subcommand != G_swap_ctx->subcommand) {
PRINTF("Received subcommand %d, current flow uses %d\n",
subcommand,
G_swap_ctx->subcommand);
return UNEXPECTED_INSTRUCTION;
}

if (check_current_state != -1 && G_swap_ctx.state != check_current_state) {
if (check_current_state != -1 && G_swap_ctx->state != check_current_state) {
PRINTF("Received instruction %d requiring state %d, but current state is %d\n",
instruction,
check_current_state,
G_swap_ctx.state);
G_swap_ctx->state);
return UNEXPECTED_INSTRUCTION;
}

Expand Down
116 changes: 59 additions & 57 deletions src/check_addresses_and_amounts.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
static bool check_coin_configuration_signature(buf_t config, buf_t der) {
uint8_t hash[CURVE_SIZE_BYTES];
cx_hash_sha256(config.bytes, config.size, hash, CURVE_SIZE_BYTES);
return cx_ecdsa_verify_no_throw(&G_swap_ctx.ledger_public_key,
return cx_ecdsa_verify_no_throw(&G_swap_ctx->ledger_public_key,
hash,
CURVE_SIZE_BYTES,
der.bytes,
Expand All @@ -30,14 +30,14 @@ static bool check_received_ticker_matches_context(buf_t ticker, const command_t
char *in_currency;
if (cmd->subcommand == SWAP || cmd->subcommand == SWAP_NG) {
if (cmd->ins == CHECK_PAYOUT_ADDRESS) {
in_currency = G_swap_ctx.swap_transaction.currency_to;
in_currency = G_swap_ctx->swap_transaction.currency_to;
} else {
in_currency = G_swap_ctx.swap_transaction.currency_from;
in_currency = G_swap_ctx->swap_transaction.currency_from;
}
} else if (cmd->subcommand == SELL || cmd->subcommand == SELL_NG) {
in_currency = G_swap_ctx.sell_transaction.in_currency;
in_currency = G_swap_ctx->sell_transaction.in_currency;
} else {
in_currency = G_swap_ctx.fund_transaction.in_currency;
in_currency = G_swap_ctx->fund_transaction.in_currency;
}
return check_matching_ticker(ticker, in_currency);
}
Expand All @@ -52,13 +52,15 @@ static uint16_t check_payout_or_refund_address(command_e ins,

// Depending on the current command, check either PAYOUT or REFUND
if (ins == CHECK_PAYOUT_ADDRESS) {
address_to_check = G_swap_ctx.swap_transaction.payout_address;
address_max_size = sizeof(G_swap_ctx.swap_transaction.payout_address);
extra_id_to_check = G_swap_ctx.swap_transaction.payout_extra_id;
PRINTF("Preparing to run CHECK_PAYOUT_ADDRESS\n");
address_to_check = G_swap_ctx->swap_transaction.payout_address;
address_max_size = sizeof(G_swap_ctx->swap_transaction.payout_address);
extra_id_to_check = G_swap_ctx->swap_transaction.payout_extra_id;
} else {
address_to_check = G_swap_ctx.swap_transaction.refund_address;
address_max_size = sizeof(G_swap_ctx.swap_transaction.refund_address);
extra_id_to_check = G_swap_ctx.swap_transaction.refund_extra_id;
PRINTF("Preparing to run CHECK_REFUND_ADDRESS\n");
address_to_check = G_swap_ctx->swap_transaction.refund_address;
address_max_size = sizeof(G_swap_ctx->swap_transaction.refund_address);
extra_id_to_check = G_swap_ctx->swap_transaction.refund_extra_id;
}
if (address_to_check[address_max_size - 1] != '\0') {
PRINTF("Address to check is not NULL terminated\n");
Expand All @@ -81,24 +83,24 @@ static uint16_t format_relevant_amount(command_e ins, buf_t sub_coin_config, cha
pb_bytes_array_16_t *amount;
char *dest;
uint8_t dest_size;
if (G_swap_ctx.subcommand == SWAP || G_swap_ctx.subcommand == SWAP_NG) {
if (G_swap_ctx->subcommand == SWAP || G_swap_ctx->subcommand == SWAP_NG) {
if (ins == CHECK_PAYOUT_ADDRESS) {
amount = (pb_bytes_array_16_t *) &G_swap_ctx.swap_transaction.amount_to_wallet;
dest = G_swap_ctx.printable_get_amount;
dest_size = sizeof(G_swap_ctx.printable_get_amount);
amount = (pb_bytes_array_16_t *) &G_swap_ctx->swap_transaction.amount_to_wallet;
dest = G_swap_ctx->printable_get_amount;
dest_size = sizeof(G_swap_ctx->printable_get_amount);
} else {
amount = (pb_bytes_array_16_t *) &G_swap_ctx.swap_transaction.amount_to_provider;
dest = G_swap_ctx.printable_send_amount;
dest_size = sizeof(G_swap_ctx.printable_send_amount);
amount = (pb_bytes_array_16_t *) &G_swap_ctx->swap_transaction.amount_to_provider;
dest = G_swap_ctx->printable_send_amount;
dest_size = sizeof(G_swap_ctx->printable_send_amount);
}
} else if (G_swap_ctx.subcommand == SELL || G_swap_ctx.subcommand == SELL_NG) {
amount = (pb_bytes_array_16_t *) &G_swap_ctx.sell_transaction.in_amount;
dest = G_swap_ctx.printable_send_amount;
dest_size = sizeof(G_swap_ctx.printable_send_amount);
} else if (G_swap_ctx->subcommand == SELL || G_swap_ctx->subcommand == SELL_NG) {
amount = (pb_bytes_array_16_t *) &G_swap_ctx->sell_transaction.in_amount;
dest = G_swap_ctx->printable_send_amount;
dest_size = sizeof(G_swap_ctx->printable_send_amount);
} else {
amount = (pb_bytes_array_16_t *) &G_swap_ctx.fund_transaction.in_amount;
dest = G_swap_ctx.printable_send_amount;
dest_size = sizeof(G_swap_ctx.printable_send_amount);
amount = (pb_bytes_array_16_t *) &G_swap_ctx->fund_transaction.in_amount;
dest = G_swap_ctx->printable_send_amount;
dest_size = sizeof(G_swap_ctx->printable_send_amount);
}

uint16_t err = get_printable_amount(&sub_coin_config,
Expand All @@ -119,49 +121,49 @@ static uint16_t format_relevant_amount(command_e ins, buf_t sub_coin_config, cha
static uint16_t format_fees(buf_t sub_coin_config, char *appname) {
uint16_t err = get_printable_amount(&sub_coin_config,
appname,
G_swap_ctx.transaction_fee,
G_swap_ctx.transaction_fee_length,
G_swap_ctx.printable_fees_amount,
sizeof(G_swap_ctx.printable_fees_amount),
G_swap_ctx->transaction_fee,
G_swap_ctx->transaction_fee_length,
G_swap_ctx->printable_fees_amount,
sizeof(G_swap_ctx->printable_fees_amount),
true);
if (err != 0) {
PRINTF("Error: Failed to get printable fees amount\n");
return err;
}
PRINTF("Fees: %s\n", G_swap_ctx.printable_fees_amount);
PRINTF("Fees: %s\n", G_swap_ctx->printable_fees_amount);
return 0;
}

static bool format_fiat_amount(void) {
size_t len = strlen(G_swap_ctx.sell_transaction.out_currency);
if (len + 1 >= sizeof(G_swap_ctx.printable_get_amount)) {
size_t len = strlen(G_swap_ctx->sell_transaction.out_currency);
if (len + 1 >= sizeof(G_swap_ctx->printable_get_amount)) {
return false;
}

strlcpy(G_swap_ctx.printable_get_amount,
G_swap_ctx.sell_transaction.out_currency,
sizeof(G_swap_ctx.printable_get_amount));
G_swap_ctx.printable_get_amount[len] = ' ';
G_swap_ctx.printable_get_amount[len + 1] = '\x00';
strlcpy(G_swap_ctx->printable_get_amount,
G_swap_ctx->sell_transaction.out_currency,
sizeof(G_swap_ctx->printable_get_amount));
G_swap_ctx->printable_get_amount[len] = ' ';
G_swap_ctx->printable_get_amount[len + 1] = '\x00';

if (get_fiat_printable_amount(G_swap_ctx.sell_transaction.out_amount.coefficient.bytes,
G_swap_ctx.sell_transaction.out_amount.coefficient.size,
G_swap_ctx.sell_transaction.out_amount.exponent,
G_swap_ctx.printable_get_amount + len + 1,
sizeof(G_swap_ctx.printable_get_amount) - (len + 1)) < 0) {
if (get_fiat_printable_amount(G_swap_ctx->sell_transaction.out_amount.coefficient.bytes,
G_swap_ctx->sell_transaction.out_amount.coefficient.size,
G_swap_ctx->sell_transaction.out_amount.exponent,
G_swap_ctx->printable_get_amount + len + 1,
sizeof(G_swap_ctx->printable_get_amount) - (len + 1)) < 0) {
PRINTF("Error: Failed to get source currency printable amount\n");
return false;
}

PRINTF("%s\n", G_swap_ctx.printable_get_amount);
PRINTF("%s\n", G_swap_ctx->printable_get_amount);
return true;
}

static void format_account_name(void) {
strlcpy(G_swap_ctx.account_name,
G_swap_ctx.fund_transaction.account_name,
sizeof(G_swap_ctx.account_name));
G_swap_ctx.account_name[sizeof(G_swap_ctx.account_name) - 1] = '\x00';
strlcpy(G_swap_ctx->account_name,
G_swap_ctx->fund_transaction.account_name,
sizeof(G_swap_ctx->account_name));
G_swap_ctx->account_name[sizeof(G_swap_ctx->account_name) - 1] = '\x00';
}

// Three possibilities in this function:
Expand Down Expand Up @@ -216,7 +218,7 @@ int check_addresses_and_amounts(const command_t *cmd) {
// On SWAP flows we need to check refund or payout address (depending on step)
// We received them as part of the TX but we couldn't check then as we did not have the
// application_name yet
if (G_swap_ctx.subcommand == SWAP || G_swap_ctx.subcommand == SWAP_NG) {
if (G_swap_ctx->subcommand == SWAP || G_swap_ctx->subcommand == SWAP_NG) {
uint16_t ret = check_payout_or_refund_address(cmd->ins,
sub_coin_config,
address_parameters,
Expand Down Expand Up @@ -245,32 +247,32 @@ int check_addresses_and_amounts(const command_t *cmd) {
}

// On SELL flows we receive a FIAT amount, format it to display it on screen
if (G_swap_ctx.subcommand == SELL || G_swap_ctx.subcommand == SELL_NG) {
if (G_swap_ctx->subcommand == SELL || G_swap_ctx->subcommand == SELL_NG) {
if (!format_fiat_amount()) {
PRINTF("Error: Failed to format FIAT amount\n");
return reply_error(INTERNAL_ERROR);
}
}

// On FUND flows we display the account name that will receive the funds
if (G_swap_ctx.subcommand == FUND || G_swap_ctx.subcommand == FUND_NG) {
if (G_swap_ctx->subcommand == FUND || G_swap_ctx->subcommand == FUND_NG) {
format_account_name();
}

if (cmd->ins != CHECK_PAYOUT_ADDRESS) {
// Save the paying coin application_name, we'll need it to start the app during
// START_SIGNING step
memcpy(G_swap_ctx.payin_binary_name, application_name, sizeof(application_name));
memcpy(G_swap_ctx->payin_binary_name, application_name, sizeof(application_name));

// Save the paying sub coin configuration as the lib app will need it to sign
G_swap_ctx.paying_sub_coin_config_size = sub_coin_config.size;
memset(G_swap_ctx.paying_sub_coin_config, 0, sizeof(G_swap_ctx.paying_sub_coin_config));
memcpy(G_swap_ctx.paying_sub_coin_config, sub_coin_config.bytes, sub_coin_config.size);
G_swap_ctx->paying_sub_coin_config_size = sub_coin_config.size;
memset(G_swap_ctx->paying_sub_coin_config, 0, sizeof(G_swap_ctx->paying_sub_coin_config));
memcpy(G_swap_ctx->paying_sub_coin_config, sub_coin_config.bytes, sub_coin_config.size);

// Save the rate. We could have saved it at the first command and then checked at each ŝtep
// that it did not change, but it is not certain that the Live sends it right from the
// begining and we won't risk regressions for something that is not a security issue.
G_swap_ctx.rate = cmd->rate;
G_swap_ctx->rate = cmd->rate;
}

// Only trigger the UI validation for CHECK_X_AND_DISPLAY
Expand All @@ -284,10 +286,10 @@ int check_addresses_and_amounts(const command_t *cmd) {
}
// If we checked the PAYOUT address (swap flow), we still have the REFUND address to check
if (cmd->ins == CHECK_PAYOUT_ADDRESS) {
G_swap_ctx.state = PAYOUT_ADDRESS_CHECKED;
G_swap_ctx->state = PAYOUT_ADDRESS_CHECKED;
} else {
// Otherwise we are ready to start the display
G_swap_ctx.state = ALL_ADDRESSES_CHECKED;
G_swap_ctx->state = ALL_ADDRESSES_CHECKED;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/check_partner.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ int check_partner(const command_t *cmd) {
return reply_error(INCORRECT_COMMAND_DATA);
}

if (!cx_ecdsa_verify_no_throw(&(G_swap_ctx.ledger_public_key),
G_swap_ctx.sha256_digest_no_prefix,
if (!cx_ecdsa_verify_no_throw(&(G_swap_ctx->ledger_public_key),
G_swap_ctx->sha256_digest_no_prefix,
CURVE_SIZE_BYTES,
cmd->data.bytes,
cmd->data.size)) {
Expand All @@ -29,7 +29,7 @@ int check_partner(const command_t *cmd) {
return -1;
}

G_swap_ctx.state = PROVIDER_CHECKED;
G_swap_ctx->state = PROVIDER_CHECKED;

return 0;
}
16 changes: 8 additions & 8 deletions src/check_tx_signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ int check_tx_signature(const command_t *cmd) {
PRINTF("DER sig: %.*H\n", signature.size, signature.bytes);
const uint8_t *hash;
if (signature_is_computed_on_dot_prefixed_tx) {
hash = G_swap_ctx.sha256_digest_prefixed;
hash = G_swap_ctx->sha256_digest_prefixed;
PRINTF("SHA256 %.*H\n",
sizeof(G_swap_ctx.sha256_digest_prefixed),
G_swap_ctx.sha256_digest_prefixed);
sizeof(G_swap_ctx->sha256_digest_prefixed),
G_swap_ctx->sha256_digest_prefixed);
} else {
hash = G_swap_ctx.sha256_digest_no_prefix;
hash = G_swap_ctx->sha256_digest_no_prefix;
PRINTF("SHA256 %.*H\n",
sizeof(G_swap_ctx.sha256_digest_no_prefix),
G_swap_ctx.sha256_digest_no_prefix);
sizeof(G_swap_ctx->sha256_digest_no_prefix),
G_swap_ctx->sha256_digest_no_prefix);
}

// Check the signature of the sha256_digest we computed from the tx payload
if (!cx_ecdsa_verify_no_throw(&G_swap_ctx.partner.public_key,
if (!cx_ecdsa_verify_no_throw(&G_swap_ctx->partner.public_key,
hash,
CURVE_SIZE_BYTES,
signature.bytes,
Expand All @@ -142,7 +142,7 @@ int check_tx_signature(const command_t *cmd) {
return -1;
}

G_swap_ctx.state = SIGNATURE_CHECKED;
G_swap_ctx->state = SIGNATURE_CHECKED;

return 0;
}
2 changes: 1 addition & 1 deletion src/command_dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ int dispatch_command(const command_t *cmd) {
PRINTF("command: %d, subcommand: %d, current state: %d\n",
cmd->ins,
cmd->subcommand,
G_swap_ctx.state);
G_swap_ctx->state);

int ret = -1;

Expand Down
Loading
Loading