Skip to content

Commit

Permalink
Improve error message returned in swap
Browse files Browse the repository at this point in the history
  • Loading branch information
cedelavergne-ledger committed Oct 16, 2024
1 parent 70cedac commit b2cfe1e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 22 deletions.
7 changes: 4 additions & 3 deletions src_features/signTx/cmd_signTx.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ uint16_t handleSign(uint8_t p1,
// We have encountered an error while trying to sign a SWAP type transaction
// Return dedicated error code and flag an early exit back to Exchange
G_swap_response_ready = true;
return APDU_RESPONSE_MODE_CHECK_FAILED;
} else {
return APDU_RESPONSE_INVALID_DATA;
send_swap_error(ERROR_GENERIC, APP_CODE_CALLDATA_ISSUE, NULL, NULL);
// unreachable
os_sched_exit(0);
}
return APDU_RESPONSE_INVALID_DATA;
default:
PRINTF("Unexpected parser status\n");
return APDU_RESPONSE_INVALID_DATA;
Expand Down
18 changes: 18 additions & 0 deletions src_features/signTx/feature_signTx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@

#include "shared_context.h"

// Error codes for swap, to be moved in SDK?
#define ERROR_WRONG_AMOUNT 0x01
#define ERROR_WRONG_DESTINATION 0x02
#define ERROR_WRONG_FEES 0x03
#define ERROR_WRONG_METHOD 0x04
#define ERROR_CROSSCHAIN_WRONG_MODE 0x05
#define ERROR_CROSSCHAIN_WRONG_METHOD 0x06
#define ERROR_GENERIC 0xFF

// App codes for detail.
typedef enum {
APP_CODE_DEFAULT = 0x00,
APP_CODE_CALLDATA_ISSUE = 0x01,
APP_CODE_NO_STANDARD_UI = 0x02
} app_code_t;

typedef enum {

PLUGIN_UI_INSIDE = 0,
Expand All @@ -15,4 +31,6 @@ uint16_t finalizeParsing();
void ux_approve_tx(bool fromPlugin);
void start_signature_flow(void);

void send_swap_error(uint8_t error_code, app_code_t app_code, const char *str1, const char *str2);

#endif // _SIGN_TX_H_
99 changes: 80 additions & 19 deletions src_features/signTx/logic_signTx.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "crypto_helpers.h"
#include "format.h"
#include "manage_asset_info.h"
#include "handle_swap_sign_transaction.h"
#include "os_math.h"

static bool g_use_standard_ui;

Expand Down Expand Up @@ -323,6 +325,56 @@ static int strcasecmp_workaround(const char *str1, const char *str2) {
return 0;
}

__attribute__((noreturn)) void send_swap_error(uint8_t error_code,
app_code_t app_code,
const char *str1,
const char *str2) {
uint32_t tx = 0;
uint len = 0;
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED: 0x%x\n", error_code);
// Set RAPDU error codes
G_io_apdu_buffer[tx++] = error_code;
G_io_apdu_buffer[tx++] = app_code;
// Set RAPDU error message
if (str1 != NULL) {
PRINTF("Expected %s\n", str1);
// If the string is too long, truncate it
len = MIN(strlen((const char *) str1), sizeof(G_io_apdu_buffer) - tx - 2);
memmove(G_io_apdu_buffer + tx, str1, len);
tx += len;
if (len < strlen((const char *) str1)) {
PRINTF("Truncated %s to %d bytes\n", str1, len);
G_io_apdu_buffer[tx - 1] = '*';
}
}
if (str2 != NULL) {
PRINTF("Received %s\n", str2);
// Do we have enough space to add a separator?
if ((tx + 1 + 2) < sizeof(G_io_apdu_buffer)) {
G_io_apdu_buffer[tx++] = '#';
}
// Do we have enough space to add at least one character?
if ((tx + 1 + 2) < sizeof(G_io_apdu_buffer)) {
// If the string is too long, truncate it
len = MIN(strlen((const char *) str2), sizeof(G_io_apdu_buffer) - tx - 2);
memmove(G_io_apdu_buffer + tx, str2, len);
tx += len;
if (len < strlen((const char *) str2)) {
PRINTF("Truncated %s to %d bytes\n", str2, len);
G_io_apdu_buffer[tx - 1] = '*';
}
}
}
// Set RAPDU status word, with previous check we are sure there is at least 2 bytes left
U2BE_ENCODE(G_io_apdu_buffer, tx, APDU_RESPONSE_MODE_CHECK_FAILED);
tx += 2;
// Send RAPDU
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// In case of success, the apdu is sent immediately and eth exits
// Reaching this code means we encountered an error
finalize_exchange_sign_transaction(false);
}

__attribute__((noinline)) static uint16_t finalize_parsing_helper(void) {
char displayBuffer[50];
uint8_t decimals = WEI_TO_ETHER;
Expand Down Expand Up @@ -453,19 +505,20 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) {
G_swap_response_ready = true;
}

// User has just validated a swap but ETH received apdus about a non standard plugin / contract
if (G_called_from_swap && !g_use_standard_ui) {
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, G_called_from_swap\n");
return APDU_RESPONSE_MODE_CHECK_FAILED;
}

// Specific calldata check when in swap mode
if (G_called_from_swap) {
// User has just validated a swap but ETH received apdus about a non standard plugin /
// contract
if (!g_use_standard_ui) {
send_swap_error(ERROR_WRONG_METHOD, APP_CODE_NO_STANDARD_UI, NULL, NULL);
// unreachable
os_sched_exit(0);
}
// Two success cases: we are in standard mode and no calldata was received
// We are in crosschain mode and the correct calldata has been received
if (G_swap_mode != SWAP_MODE_STANDARD && G_swap_mode != SWAP_MODE_CROSSCHAIN_SUCCESS) {
PRINTF("Error: G_swap_mode %d refused\n", G_swap_mode);
return APDU_RESPONSE_MODE_CHECK_FAILED;
send_swap_error(ERROR_CROSSCHAIN_WRONG_MODE, APP_CODE_DEFAULT, NULL, NULL);
// unreachable
os_sched_exit(0);
}
}

Expand All @@ -491,8 +544,12 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) {
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcasecmp_workaround(strings.common.toAddress, displayBuffer) != 0) {
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, address check failed\n");
return APDU_RESPONSE_MODE_CHECK_FAILED;
send_swap_error(ERROR_WRONG_DESTINATION,
APP_CODE_DEFAULT,
strings.common.toAddress,
displayBuffer);
// unreachable
os_sched_exit(0);
}
} else {
strlcpy(strings.common.toAddress, displayBuffer, sizeof(strings.common.toAddress));
Expand All @@ -514,10 +571,12 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) {
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.fullAmount, displayBuffer) != 0) {
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, amount check failed\n");
PRINTF("Expected %s\n", strings.common.fullAmount);
PRINTF("Received %s\n", displayBuffer);
return APDU_RESPONSE_MODE_CHECK_FAILED;
send_swap_error(ERROR_WRONG_AMOUNT,
APP_CODE_DEFAULT,
strings.common.fullAmount,
displayBuffer);
// unreachable
os_sched_exit(0);
}
} else {
strlcpy(strings.common.fullAmount, displayBuffer, sizeof(strings.common.fullAmount));
Expand All @@ -536,10 +595,12 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) {
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.maxFee, displayBuffer) != 0) {
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, fees check failed\n");
PRINTF("Expected %s\n", strings.common.maxFee);
PRINTF("Received %s\n", displayBuffer);
return APDU_RESPONSE_MODE_CHECK_FAILED;
send_swap_error(ERROR_WRONG_FEES,
APP_CODE_DEFAULT,
strings.common.maxFee,
displayBuffer);
// unreachable
os_sched_exit(0);
}
} else {
strlcpy(strings.common.maxFee, displayBuffer, sizeof(strings.common.maxFee));
Expand Down

0 comments on commit b2cfe1e

Please sign in to comment.