Skip to content

Commit

Permalink
Merge pull request #450 from Cypherock/fix/handle-unverified-wallet-b…
Browse files Browse the repository at this point in the history
…efore-delete

fix(core): Treat unverified wallets as non existant
  • Loading branch information
ujjwal-cyph authored Dec 26, 2023
2 parents 1d6e70c + 4e391d9 commit 7d8bd84
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 47 deletions.
81 changes: 64 additions & 17 deletions src/card_flows/card_flow_delete_wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@
/*****************************************************************************
* INCLUDES
*****************************************************************************/
#include "buzzer.h"
#include "card_operations.h"
#include "constant_texts.h"
#include "core_error.h"
#include "nfc.h"
#include "ui_instruction.h"

#include "ui_screens.h"
/*****************************************************************************
* EXTERN VARIABLES
*****************************************************************************/
Expand Down Expand Up @@ -102,6 +102,17 @@ static void check_card_state_and_delete_wallet(const char *wallet_name);
static bool check_wallet_already_deleted_on_card(
card_delete_share_cfg_t *delete_config);

/**
* The function `handle_wallet_deleted_from_card` deletes a wallet from a card.
*
* @param delete_config A pointer to a structure of type
* `card_delete_share_cfg_t`, which contains the following members:
*
* @return void, which means it does not return any value.
*/
static void handle_wallet_deleted_from_card(
card_delete_share_cfg_t *delete_config);

/*****************************************************************************
* STATIC VARIABLES
*****************************************************************************/
Expand All @@ -120,6 +131,7 @@ static void check_card_state_and_delete_wallet(const char *wallet_name) {
if (0 == get_wallet_card_state(flash_wallet_index)) {
ASSERT(SUCCESS_ == delete_wallet_share_from_sec_flash(flash_wallet_index));
ASSERT(SUCCESS_ == delete_wallet_from_flash(flash_wallet_index));
delay_scr_init(ui_text_wallet_deleted_successfully, DELAY_TIME);
}
return;
}
Expand All @@ -138,61 +150,96 @@ static bool check_wallet_already_deleted_on_card(
return false;
}

static void handle_wallet_deleted_from_card(
card_delete_share_cfg_t *delete_config) {
uint8_t flash_wallet_index = 0xFF;

ASSERT(SUCCESS ==
get_index_by_name((const char *)delete_config->wallet->wallet_name,
&flash_wallet_index));
ASSERT(SUCCESS == delete_from_kth_card_flash(flash_wallet_index,
delete_config->card_number));
return;
}

/*****************************************************************************
* GLOBAL FUNCTIONS
*****************************************************************************/
card_error_type_e card_flow_delete_wallet(Wallet *selected_wallet) {
card_delete_share_cfg_t cfg = {.wallet = selected_wallet, .card_number = 0};
card_delete_share_cfg_t delete_cfg = {.wallet = selected_wallet,
.card_number = 0};
card_error_type_e error_code = 0;

card_fetch_share_config_t configuration = {0};
card_fetch_share_config_t fetch_cfg = {0};
card_fetch_share_response_t response = {0};
char heading[MAX_HEADING_LEN] = "";
configuration.xcor = 0;
configuration.operation.expected_family_id = get_family_id();
configuration.frontend.msg = ui_text_place_card_below;
configuration.frontend.heading = heading;
configuration.frontend.unexpected_card_error = ui_text_wrong_card_sequence;
configuration.operation.skip_card_removal = true;
configuration.operation.buzzer_on_success = false;
fetch_cfg.xcor = 0;
fetch_cfg.operation.expected_family_id = get_family_id();
fetch_cfg.frontend.msg = ui_text_place_card_below;
fetch_cfg.frontend.heading = heading;
fetch_cfg.frontend.unexpected_card_error = ui_text_wrong_card_sequence;
fetch_cfg.operation.skip_card_removal = true;
fetch_cfg.operation.buzzer_on_success = false;
response.card_info.tapped_family_id = NULL;

for (int i = 1; i <= 4; i++) {
snprintf(heading, MAX_HEADING_LEN, UI_TEXT_TAP_CARD, i);
configuration.operation.acceptable_cards = encode_card_number(i);
fetch_cfg.operation.acceptable_cards = encode_card_number(i);

error_code = CARD_OPERATION_DEFAULT_INVALID;
cfg.card_number = i;
delete_cfg.card_number = i;

// If wallet already deleted from ith card, skip card tapping
if (true == check_wallet_already_deleted_on_card(&cfg)) {
if (true == check_wallet_already_deleted_on_card(&delete_cfg)) {
error_code = CARD_OPERATION_SUCCESS;
continue;
}

error_code = card_fetch_share(&configuration, &response);
error_code = card_fetch_share(&fetch_cfg, &response);

if (CARD_OPERATION_SUCCESS != error_code) {
if (CARD_OPERATION_ABORT_OPERATION == error_code &&
SW_RECORD_NOT_FOUND == response.card_info.status) {
// In case wallet is not found on card, consider it as a success case as
// wallet is already deleted or not created on the card.
clear_core_error_screen();
// Let it pass to wallet delete flow as the card operation will get
// completed there.
} else if (CARD_OPERATION_VERIFICATION_FAILED == error_code) {
// In case wallet verification fails, consider it as a success case
// wallet on card does not match with the required verification.
clear_core_error_screen();
handle_wallet_deleted_from_card(&delete_cfg);

// NOTE: When this case occurs, we are skipping card removal. This is
// because it is not possible to detect card's presence after desection.
// Card deselection is performed in fetch_card_share in this case.
buzzer_start(BUZZER_DURATION);
// TODO: Inform user that wallets with same name but failed verification
// might exist.
continue;
} else {
break;
}
}

if (STM_SUCCESS != nfc_wait_for_card(DEFAULT_NFC_TG_INIT_TIME)) {
instruction_scr_change_text(ui_text_card_removed_fast, true);
}

// Operation to delete wallet from card and update card state on flash
error_code = card_delete_share(&cfg);
error_code =
card_delete_share(&delete_cfg, &handle_wallet_deleted_from_card);

if (CARD_OPERATION_SUCCESS != error_code) {
break;
}
}

// If wallet is deleted on all cards, delete from flash as well
check_card_state_and_delete_wallet((const char *)cfg.wallet->wallet_name);
check_card_state_and_delete_wallet(
(const char *)delete_cfg.wallet->wallet_name);
clear_wallet_data();

return error_code;
}
31 changes: 5 additions & 26 deletions src/card_operations/card_delete_share.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/**
* @file delete_from_cards_controller.c
* @file card_delete_share.c
* @author Cypherock X1 Team
* @brief Delete from cards controller.
* This file contains the implementation of the functions for deleting
* @brief This file contains the implementation of the functions for deleting
* wallets from cards.
* @copyright Copyright (c) 2023 HODL TECH PTE LTD
* <br/> You may obtain a copy of license at <a href="https://mitcc.org/"
Expand Down Expand Up @@ -86,17 +85,6 @@
* STATIC FUNCTION PROTOTYPES
*****************************************************************************/

/**
* The function `handle_wallet_deleted_from_card` deletes a wallet from a card.
*
* @param delete_config A pointer to a structure of type
* `card_delete_share_cfg_t`, which contains the following members:
*
* @return void, which means it does not return any value.
*/
static void handle_wallet_deleted_from_card(
card_delete_share_cfg_t *delete_config);

/*****************************************************************************
* STATIC VARIABLES
*****************************************************************************/
Expand All @@ -108,22 +96,13 @@ static void handle_wallet_deleted_from_card(
/*****************************************************************************
* STATIC FUNCTIONS
*****************************************************************************/
static void handle_wallet_deleted_from_card(
card_delete_share_cfg_t *delete_config) {
uint8_t flash_wallet_index = 0xFF;

ASSERT(SUCCESS ==
get_index_by_name((const char *)delete_config->wallet->wallet_name,
&flash_wallet_index));
ASSERT(SUCCESS == delete_from_kth_card_flash(flash_wallet_index,
delete_config->card_number));
return;
}

/*****************************************************************************
* GLOBAL FUNCTIONS
*****************************************************************************/
card_error_type_e card_delete_share(card_delete_share_cfg_t *delete_config) {
card_error_type_e card_delete_share(
card_delete_share_cfg_t *delete_config,
void (*handle_wallet_deleted_from_card)(card_delete_share_cfg_t *)) {
card_operation_data_t card_data = {0};
card_error_type_e result = CARD_OPERATION_DEFAULT_INVALID;
char heading[50] = "";
Expand Down
11 changes: 9 additions & 2 deletions src/card_operations/card_delete_share.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ typedef struct card_delete_share_cfg {
* error cases and returns an appropriate error code. For special case such as
* incorrect pin, it indicates the no. of attempts left.
*
* @param config A pointer to the configuration of the card delete operation.
* @param delete_config A pointer to the configuration of the card delete
* operation.
* @param handle_wallet_deleted_from_card Function pointer that needs to be
* called to handle successful deletion of wallet on a card. The function takes
* the delete_config as an argument.
*
* @return A card_error_type_e value representing the result of the operation.
*/
card_error_type_e card_delete_share(card_delete_share_cfg_t *config);
card_error_type_e card_delete_share(
card_delete_share_cfg_t *delete_config,
void (*handle_wallet_deleted_from_card)(card_delete_share_cfg_t *));
#endif
2 changes: 1 addition & 1 deletion src/card_operations/card_fetch_share.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ card_error_type_e card_fetch_share(const card_fetch_share_config_t *config,
if (card_data.nfc_data.status == SW_NO_ERROR) {
remaining_cards = card_data.nfc_data.acceptable_cards;
if (!_handle_retrieve_wallet_success(config->xcor)) {
card_data.error_type = CARD_OPERATION_VERIFICATION_FAILED;
result = card_data.error_type = CARD_OPERATION_VERIFICATION_FAILED;
card_data.nfc_data.status = SW_RECORD_NOT_FOUND;
mark_core_error_screen(
ui_text_wallet_verification_failed_in_reconstruction, true);
Expand Down
2 changes: 1 addition & 1 deletion src/constant_texts.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ const char *ui_text_card_null_pointer_exception =
const char *ui_text_card_crypto_exception =
"Operation failed on card (Crypto Exp)";
const char *ui_text_card_invalid_apdu_length =
"Operation failed on card (APDU len exp)";
"Wallet with same name or seed already exists";
const char *ui_text_card_invalid_tag_in_apdu =
"Operation failed on card (Tag exp)";
const char *ui_text_unknown_error_contact_support =
Expand Down

0 comments on commit 7d8bd84

Please sign in to comment.