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

feat: optimize the signing process of unverified contracts. #52

Merged
merged 26 commits into from
Jul 20, 2024
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Updated
- Give an alert when enabling hash signing in settings. (Ledger Stax and Ledger Flex)
- Default to prohibit signing unverified contracts, need to enable "Custom contracts" in settings.
- Bug fixes.

## v5.4.1
Expand Down
3 changes: 2 additions & 1 deletion src/handler/get_app_configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ int handler_get_app_configuration() {
MINOR_VERSION,
PATCH_VERSION,
RAW_DATA_MAX_SIZE >> 8,
RAW_DATA_MAX_SIZE & 0xFF};
RAW_DATA_MAX_SIZE & 0xFF,
HAS_SETTING(S_UNVERIFIED_CONTRACTS_ENABLED)};

return io_send_response_pointer(config, sizeof(config), SW_OK);
}
35 changes: 34 additions & 1 deletion src/handler/sign_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
#include "sign_tx.h"
#include "sw.h"
#include "globals.h"
#include "plugin.h"
#include "settings.h"
#include "ui/display.h"
#include "crypto.h"
#include "helper/send_response.h"
#include "swap/handle_swap_sign_transaction.h"
#include "stellar/parser.h"
#include "stellar/formatter.h"

static bool check_include_custom_contract();

int handler_sign_auth(buffer_t *cdata, bool is_first_chunk, bool more) {
if (is_first_chunk) {
explicit_bzero(&G_context, sizeof(G_context));
Expand Down Expand Up @@ -92,5 +96,34 @@ int handler_sign_auth(buffer_t *cdata, bool is_first_chunk, bool more) {
return io_send_sw(SW_DATA_HASH_FAIL);
}

G_context.unverified_contracts = check_include_custom_contract();
PRINTF("G_context.unverified_contracts: %d\n", G_context.unverified_contracts);
if (G_context.unverified_contracts && !HAS_SETTING(S_UNVERIFIED_CONTRACTS_ENABLED)) {
return io_send_sw(SW_UNVERIFIED_CONTRACTS_MODE_NOT_ENABLED);
}

return ui_display_auth();
};
};

static bool check_include_custom_contract() {
// Check if the contract is a unverified contract
if (G_context.envelope.soroban_authorization.auth_function_type ==
SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN) {
const uint8_t *contract_address =
G_context.envelope.soroban_authorization.invoke_contract_args.address.address;
if (!plugin_check_presence(contract_address)) {
return true;
}

if (plugin_init_contract(contract_address) != STELLAR_PLUGIN_RESULT_OK) {
return true;
}

uint8_t data_pair_count_tmp = 0;
if (plugin_query_data_pair_count(contract_address, &data_pair_count_tmp) !=
STELLAR_PLUGIN_RESULT_OK) {
return true;
}
}
return false;
}
47 changes: 46 additions & 1 deletion src/handler/sign_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
#include "sign_tx.h"
#include "sw.h"
#include "globals.h"
#include "plugin.h"
#include "settings.h"
#include "ui/display.h"
#include "crypto.h"
#include "helper/send_response.h"
#include "swap/handle_swap_sign_transaction.h"
#include "stellar/parser.h"
#include "stellar/formatter.h"

static bool check_include_custom_contract();

int handler_sign_tx(buffer_t *cdata, bool is_first_chunk, bool more) {
if (is_first_chunk) {
explicit_bzero(&G_context, sizeof(G_context));
Expand Down Expand Up @@ -126,6 +130,47 @@ int handler_sign_tx(buffer_t *cdata, bool is_first_chunk, bool more) {
HASH_SIZE) {
return io_send_sw(SW_DATA_HASH_FAIL);
}

G_context.unverified_contracts = check_include_custom_contract();
PRINTF("G_context.unverified_contracts: %d\n", G_context.unverified_contracts);
if (G_context.unverified_contracts && !HAS_SETTING(S_UNVERIFIED_CONTRACTS_ENABLED)) {
return io_send_sw(SW_UNVERIFIED_CONTRACTS_MODE_NOT_ENABLED);
}

return ui_display_transaction();
}
};
};

static bool check_include_custom_contract() {
// check if the transaction contains a unverified contract
for (uint8_t i = 0; i < G_context.envelope.tx_details.tx.operations_count; i++) {
if (!parse_transaction_operation(G_context.raw,
G_context.raw_size,
&G_context.envelope,
i)) {
// should not happen
return io_send_sw(SW_DATA_PARSING_FAIL);
}
if (G_context.envelope.tx_details.tx.op_details.type == OPERATION_INVOKE_HOST_FUNCTION &&
G_context.envelope.tx_details.tx.op_details.invoke_host_function_op
.host_function_type == HOST_FUNCTION_TYPE_INVOKE_CONTRACT) {
const uint8_t *contract_address =
G_context.envelope.tx_details.tx.op_details.invoke_host_function_op
.invoke_contract_args.address.address;
if (!plugin_check_presence(contract_address)) {
return true;
}

if (plugin_init_contract(contract_address) != STELLAR_PLUGIN_RESULT_OK) {
return true;
}

uint8_t data_pair_count_tmp = 0;
if (plugin_query_data_pair_count(contract_address, &data_pair_count_tmp) !=
STELLAR_PLUGIN_RESULT_OK) {
return true;
}
}
}
return false;
}
2 changes: 1 addition & 1 deletion src/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ stellar_plugin_result_t plugin_query_data_pair(const uint8_t *contract_address,
params[2] = (uint32_t) &query_data_pair_param;
os_lib_call(params);
return query_data_pair_param.result;
};
};
2 changes: 1 addition & 1 deletion src/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ stellar_plugin_result_t plugin_query_data_pair(const uint8_t *contract_address,
char *caption,
uint8_t caption_len,
char *value,
uint8_t value_len);
uint8_t value_len);
5 changes: 3 additions & 2 deletions src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ extern const internal_storage_t N_storage_real;
// check a setting item
#define HAS_SETTING(k) ((N_settings & (1 << (k))) >> (k))

#define S_HASH_SIGNING_ENABLED 0
#define S_SEQUENCE_NUMBER_ENABLED 1
#define S_HASH_SIGNING_ENABLED 0
#define S_SEQUENCE_NUMBER_ENABLED 1
#define S_UNVERIFIED_CONTRACTS_ENABLED 2

#define S_INITIALIZED 7
4 changes: 4 additions & 0 deletions src/sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
* Status word for hash signing model not enabled.
*/
#define SW_HASH_SIGNING_MODE_NOT_ENABLED 0x6C66
/**
* Status word for unverified contracts model not enabled.
*/
#define SW_UNVERIFIED_CONTRACTS_MODE_NOT_ENABLED 0x6C77
/**
* Status word for unknown command with this INS.
*/
Expand Down
1 change: 1 addition & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ typedef struct {
uint8_t bip32_path_len; // length of BIP32 path
state_e state; // state of the context
request_type_e req_type; // user request
bool unverified_contracts;
} global_ctx_t;

/**
Expand Down
39 changes: 34 additions & 5 deletions src/ui/bagl_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,52 @@ static void ui_idle(void);
static void display_settings(const ux_flow_step_t* const start_step);
static void switch_settings_hash_signing();
static void switch_settings_sequence_number();
static void switch_settings_unverified_contracts();

// FLOW for the settings menu:
// #1 screen: enable hash signing
// #2 screen: quit
#if defined(TARGET_NANOS)

UX_STEP_CB(ux_settings_unverified_contracts_step,
bnnn_paging,
switch_settings_unverified_contracts(),
{
.title = "Custom contracts",
.text = G.ui.detail_value,
});
UX_STEP_CB(ux_settings_hash_signing_step,
bnnn_paging,
switch_settings_hash_signing(),
{
.title = "Hash signing",
.text = G.ui.detail_value,
.text = G.ui.detail_value + 12,
});
UX_STEP_CB(ux_settings_sequence_number_step,
bnnn_paging,
switch_settings_sequence_number(),
{
.title = "Sequence Number",
.text = G.ui.detail_value + 12,
.text = G.ui.detail_value + 24,
});
#else
UX_STEP_CB(ux_settings_unverified_contracts_step,
bnnn,
switch_settings_unverified_contracts(),
{
"Custom contracts",
"Allow unverified",
"contracts",
G.ui.detail_value,
});
UX_STEP_CB(ux_settings_hash_signing_step,
bnnn,
switch_settings_hash_signing(),
{
"Hash signing",
"Enable hash",
"signing",
G.ui.detail_value,
G.ui.detail_value + 12,
});
UX_STEP_CB(ux_settings_sequence_number_step,
bnnn,
Expand All @@ -60,8 +78,9 @@ UX_STEP_CB(ux_settings_sequence_number_step,
"Sequence Number",
"Display sequence",
"in transactions",
G.ui.detail_value + 12,
G.ui.detail_value + 24,
});

#endif
UX_STEP_CB(ux_settings_exit_step,
pb,
Expand All @@ -71,6 +90,7 @@ UX_STEP_CB(ux_settings_exit_step,
"Back",
});
UX_FLOW(ux_settings_flow,
&ux_settings_unverified_contracts_step,
&ux_settings_hash_signing_step,
&ux_settings_sequence_number_step,
&ux_settings_exit_step);
Expand Down Expand Up @@ -109,11 +129,15 @@ static void ui_idle(void) {

static void display_settings(const ux_flow_step_t* const start_step) {
strlcpy(G.ui.detail_value,
(HAS_SETTING(S_HASH_SIGNING_ENABLED) ? "Enabled" : "NOT Enabled"),
(HAS_SETTING(S_UNVERIFIED_CONTRACTS_ENABLED) ? "Enabled" : "NOT Enabled"),
12);
strlcpy(G.ui.detail_value + 12,
(HAS_SETTING(S_HASH_SIGNING_ENABLED) ? "Enabled" : "NOT Enabled"),
12);
strlcpy(G.ui.detail_value + 24,
(HAS_SETTING(S_SEQUENCE_NUMBER_ENABLED) ? "Displayed" : "NOT Displayed"),
14);

ux_flow_init(0, ux_settings_flow, start_step);
}

Expand All @@ -126,4 +150,9 @@ static void switch_settings_sequence_number() {
SETTING_TOGGLE(S_SEQUENCE_NUMBER_ENABLED);
display_settings(&ux_settings_sequence_number_step);
}

static void switch_settings_unverified_contracts() {
SETTING_TOGGLE(S_UNVERIFIED_CONTRACTS_ENABLED);
display_settings(&ux_settings_unverified_contracts_step);
}
#endif // HAVE_BAGL
Loading
Loading