Skip to content

Commit

Permalink
Merge pull request #1 from trilitech/main
Browse files Browse the repository at this point in the history
app-tezos: fix Swap flow & implement expert mode
  • Loading branch information
fbeutin-ledger authored Jan 18, 2024
2 parents 972fe55 + f29a747 commit 527c960
Show file tree
Hide file tree
Showing 297 changed files with 1,233 additions and 967 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
device: [nanos, nanosp, nanox, stax]
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:3.11.0
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:3.12.0
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/swap.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: Swap feature tests
name: Swap functional tests

on:
workflow_dispatch:
push:
branches:
- main
- develop
pull_request:

jobs:
job_functional_tests:
uses: functori/app-exchange/.github/workflows/reusable_swap_functional_tests.yml@ebc5932d939e2bad5eaf3d5e316626169da6ff23
uses: LedgerHQ/app-exchange/.github/workflows/reusable_swap_functional_tests.yml@develop
with:
repo_for_exchange: 'functori/app-exchange'
branch_for_exchange: 'ajinkyaraj-23@display-source-field'
branch_for_exchange: 'develop'
branch_for_tezos: ${{ github.ref }}
run_for_devices: '["nanos", "nanosp", "stax"]'
test_filter: '"tezos_new"'
repo_for_tezos: ${{ github.repository }}
test_filter: '"tezos"'
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ docker_speculos:
$(DOCKER) image tag $(LEDGERHQ)/speculos speculos

docker_ledger_app_builder:
$(DOCKER) pull $(LEDGERHQ)/ledger-app-builder/ledger-app-builder:3.11.0
$(DOCKER) image tag $(LEDGERHQ)/ledger-app-builder/ledger-app-builder:3.11.0 \
$(DOCKER) pull $(LEDGERHQ)/ledger-app-builder/ledger-app-builder:3.12.0
$(DOCKER) image tag $(LEDGERHQ)/ledger-app-builder/ledger-app-builder:3.12.0 \
ledger-app-builder

docker_ledger_app_ocaml:
Expand Down
3 changes: 2 additions & 1 deletion app/src/apdu_pubkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ handle_apdu_get_public_key(command_t *cmd)
bool prompt = cmd->ins == INS_PROMPT_PUBLIC_KEY;
TZ_PREAMBLE(("cmd=%p", cmd));

TZ_ASSERT(EXC_UNEXPECTED_STATE, global.step == ST_IDLE);
TZ_ASSERT(EXC_UNEXPECTED_STATE,
global.step == ST_IDLE || global.step == ST_SWAP_SIGN);
TZ_ASSERT(EXC_WRONG_PARAM, cmd->p1 == 0);

// do not expose pks without prompt through U2F (permissionless legacy
Expand Down
168 changes: 66 additions & 102 deletions app/src/apdu_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <parser.h>
#include <ux.h>

#ifdef HAVE_SWAP
#include <swap.h>
#endif

#include "apdu.h"
#include "apdu_sign.h"
#include "globals.h"
Expand All @@ -51,7 +55,6 @@ static void send_reject(int);
static void send_continue(void);
static void send_cancel(void);
static void refill(void);
static void pass_from_clear_to_blind(void);
static void stream_cb(tz_ui_cb_type_t);
static void handle_first_apdu(command_t *);
static void handle_first_apdu_clear(command_t *);
Expand Down Expand Up @@ -151,82 +154,6 @@ send_continue(void)

TZ_POSTAMBLE;
}
#ifdef HAVE_NBGL

static void
cancel_operation(uint8_t reject_code)
{
TZ_PREAMBLE(("void"));
global.keys.apdu.sign.received_last_msg = true;
stream_cb(reject_code);
global.step = ST_IDLE;
nbgl_useCaseStatus("Transaction rejected", false, ui_home_init);

TZ_POSTAMBLE;
}

static void
cancel_operation_blindsign(void)
{
cancel_operation(TZ_UI_STREAM_CB_BLINDSIGN_REJECT);
}

static void
blindsign_splash(void)
{
TZ_PREAMBLE(("void"));
nbgl_useCaseReviewStart(
&C_round_warning_64px, "Blind signing",
"This transaction can not be securely interpreted by Ledger Stax. It "
"might put your assets at risk.",
"Reject transaction", pass_from_clear_to_blind,
cancel_operation_blindsign);

TZ_POSTAMBLE;
}

static void
handle_blindsigning(bool confirm)
{
TZ_PREAMBLE(("void"));
if (confirm) {
if (!N_settings.blindsigning)
toggle_blindsigning();
nbgl_useCaseReviewStart(&C_round_check_64px, "Blind signing enabled",
NULL, "Reject transaction", blindsign_splash,
cancel_operation_blindsign);

} else {
cancel_operation_blindsign();
}
TZ_POSTAMBLE;
}

void
switch_to_blindsigning(__attribute__((unused)) const char *err_type,
const char *err_code)
{
TZ_PREAMBLE(("void"));
PRINTF("[DEBUG] refill_error: global.step = %d\n", global.step);
TZ_ASSERT(EXC_UNEXPECTED_STATE, global.step == ST_CLEAR_SIGN);
global.keys.apdu.sign.step = SIGN_ST_WAIT_USER_INPUT;
global.step = ST_BLIND_SIGN;
if (N_settings.blindsigning) {
nbgl_useCaseReviewStart(&C_round_warning_64px,
"Blind signing required:\nParsing Error",
err_code, "Reject transaction",
blindsign_splash, cancel_operation_blindsign);
} else {
nbgl_useCaseChoice(&C_round_warning_64px,
"Enable blind signing to authorize this "
"transaction:\nParsing Error",
err_code, "Enable blind signing",
"Reject transaction", handle_blindsigning);
}

TZ_POSTAMBLE;
}
#endif

static void
refill_blo_im_full(void)
Expand All @@ -235,8 +162,15 @@ refill_blo_im_full(void)
size_t wrote = 0;
TZ_PREAMBLE(("void"));

global.keys.apdu.sign.step = SIGN_ST_WAIT_USER_INPUT;
#ifdef HAVE_SWAP
if (G_called_from_swap) {
tz_parser_flush(st, global.line_buf, TZ_UI_STREAM_CONTENTS_SIZE);
// invoke refill until we consume entire msg.
TZ_SUCCEED();
}
#endif

global.keys.apdu.sign.step = SIGN_ST_WAIT_USER_INPUT;
#ifdef HAVE_BAGL
if (st->field_info.is_field_complex && !N_settings.expert_mode) {
tz_ui_stream_push(TZ_UI_STREAM_CB_NOCB, st->field_info.field_name,
Expand Down Expand Up @@ -285,7 +219,6 @@ refill_blo_im_full(void)
}

#endif

tz_parser_flush_up_to(st, global.line_buf, TZ_UI_STREAM_CONTENTS_SIZE,
wrote);
TZ_POSTAMBLE;
Expand All @@ -305,7 +238,12 @@ refill_blo_done(void)
refill_blo_im_full();
TZ_SUCCEED();
}

global.keys.apdu.sign.step = SIGN_ST_WAIT_USER_INPUT;
if (global.step == ST_SWAP_SIGN) {
TZ_CHECK(sign_packet());
TZ_SUCCEED();
}
#ifdef HAVE_BAGL
tz_ui_stream_push_accept_reject();
#endif
Expand All @@ -321,6 +259,12 @@ refill_error(void)
TZ_PREAMBLE(("void"));

global.keys.apdu.sign.step = SIGN_ST_WAIT_USER_INPUT;
#ifdef HAVE_SWAP
if (G_called_from_swap) {
global.keys.apdu.sign.u.clear.received_msg = false;
TZ_FAIL(EXC_PARSE_ERROR);
}
#endif

#ifdef HAVE_BAGL
tz_ui_stream_push_all(TZ_UI_STREAM_CB_NOCB, "Parsing error",
Expand Down Expand Up @@ -515,10 +459,11 @@ handle_first_apdu(command_t *cmd)
*/
global.keys.apdu.sign.tag = 0;

TZ_ASSERT(EXC_UNEXPECTED_STATE, global.step == ST_CLEAR_SIGN);

TZ_CHECK(handle_first_apdu_clear(cmd));

TZ_ASSERT(EXC_UNEXPECTED_STATE,
global.step == ST_CLEAR_SIGN || global.step == ST_SWAP_SIGN);

io_send_sw(SW_OK);
global.keys.apdu.sign.step = SIGN_ST_WAIT_DATA;

Expand All @@ -528,23 +473,36 @@ handle_first_apdu(command_t *cmd)
static void
handle_first_apdu_clear(__attribute__((unused)) command_t *cmd)
{
TZ_PREAMBLE(("global.step=%d", global.step));
tz_parser_state *st = &global.keys.apdu.sign.u.clear.parser_state;

global.keys.apdu.sign.u.clear.received_msg = false;

tz_ui_stream_init(stream_cb);

// NO ui display during swap.
#ifdef HAVE_SWAP
if (!G_called_from_swap) {
#endif
tz_ui_stream_init(stream_cb);
global.step = ST_CLEAR_SIGN;
if (global.step == ST_CLEAR_SIGN) {
#ifdef TARGET_NANOS
tz_ui_stream_push(TZ_UI_STREAM_CB_NOCB, "Review operation", "",
TZ_UI_LAYOUT_HOME_PB, TZ_UI_ICON_EYE);
tz_ui_stream_push(TZ_UI_STREAM_CB_NOCB, "Review operation", "",
TZ_UI_LAYOUT_HOME_PB, TZ_UI_ICON_EYE);
#elif defined(HAVE_BAGL)
tz_ui_stream_push(TZ_UI_STREAM_CB_NOCB, "Review", "operation",
TZ_UI_LAYOUT_HOME_PB, TZ_UI_ICON_EYE);
tz_ui_stream_push(TZ_UI_STREAM_CB_NOCB, "Review", "operation",
TZ_UI_LAYOUT_HOME_PB, TZ_UI_ICON_EYE);
#endif
}
#ifdef HAVE_SWAP
} else {
PRINTF("[DEBUG] If called from SWAP : global.step =%d\n",
global.step);
}
#endif

tz_operation_parser_init(st, TZ_UNKNOWN_SIZE, false);
tz_parser_refill(st, NULL, 0);
tz_parser_flush(st, global.line_buf, TZ_UI_STREAM_CONTENTS_SIZE);

TZ_POSTAMBLE;
}

static void
Expand Down Expand Up @@ -580,7 +538,9 @@ handle_data_apdu(command_t *cmd)

// clang-format off
switch (global.step) {
case ST_CLEAR_SIGN: TZ_CHECK(handle_data_apdu_clear(cmd)); break;
case ST_CLEAR_SIGN:
case ST_SWAP_SIGN:
TZ_CHECK(handle_data_apdu_clear(cmd)); break;
case ST_BLIND_SIGN: TZ_CHECK(handle_data_apdu_blind()); break;
default: TZ_FAIL(EXC_UNEXPECTED_STATE); break;
}
Expand Down Expand Up @@ -608,10 +568,16 @@ handle_data_apdu_clear(command_t *cmd)
if (PKT_IS_LAST(cmd))
tz_operation_parser_set_size(
st, global.keys.apdu.sign.u.clear.total_length);
TZ_CHECK(refill());
if (global.keys.apdu.sign.step == SIGN_ST_WAIT_USER_INPUT)
tz_ui_stream();

if (global.step == ST_SWAP_SIGN) {
do {
TZ_CHECK(refill());
} while (global.keys.apdu.sign.u.clear.received_msg);
} else {
TZ_CHECK(refill());
if (global.keys.apdu.sign.step == SIGN_ST_WAIT_USER_INPUT
&& global.step != ST_SWAP_SIGN)
tz_ui_stream();
}
TZ_POSTAMBLE;
}

Expand Down Expand Up @@ -658,8 +624,7 @@ reviewChoice(bool confirm)
if (confirm) {
nbgl_useCaseStatus("TRANSACTION\nSIGNED", true, accept_blindsign_cb);
} else {
nbgl_useCaseStatus("Transaction rejected", false,
reject_blindsign_cb);
tz_reject_ui();
}

FUNC_LEAVE();
Expand Down Expand Up @@ -763,19 +728,18 @@ handle_apdu_sign(command_t *cmd)
TZ_ASSERT(EXC_WRONG_LENGTH_FOR_INS, cmd->lc <= MAX_APDU_SIZE);

if (PKT_IS_FIRST(cmd)) {
TZ_ASSERT(EXC_UNEXPECTED_STATE, global.step == ST_IDLE);
TZ_ASSERT(EXC_UNEXPECTED_STATE,
global.step == ST_IDLE || global.step == ST_SWAP_SIGN);

memset(&global.keys, 0, sizeof(global.keys));

global.step = ST_CLEAR_SIGN;

TZ_CHECK(handle_first_apdu(cmd));
global.keys.apdu.sign.return_hash = return_hash;
goto end;
}

TZ_ASSERT(EXC_UNEXPECTED_STATE,
global.step == ST_BLIND_SIGN || global.step == ST_CLEAR_SIGN);
TZ_ASSERT(EXC_UNEXPECTED_STATE, global.step == ST_BLIND_SIGN
|| global.step == ST_CLEAR_SIGN
|| global.step == ST_SWAP_SIGN);
TZ_ASSERT(EXC_INVALID_INS,
return_hash == global.keys.apdu.sign.return_hash);
TZ_CHECK(handle_data_apdu(cmd));
Expand Down
4 changes: 0 additions & 4 deletions app/src/apdu_sign.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,3 @@ typedef struct {
} blind;
} u;
} apdu_sign_state_t;

#ifdef HAVE_NBGL
void switch_to_blindsigning(const char *, const char *);
#endif
12 changes: 10 additions & 2 deletions app/src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#include <cx.h>
#include <io.h>
#include <parser.h>

#ifdef HAVE_SWAP
#include <swap.h>
#endif
#include "apdu.h"
#include "app_main.h"
#include "globals.h"
Expand Down Expand Up @@ -124,9 +126,15 @@ app_main(void)

/* ST_ERROR implies that we are completely unknown and need to reset */
global.step = ST_ERROR;

for (;;) {
TZ_PREAMBLE(("void"));
#ifdef HAVE_SWAP
if (G_called_from_swap) {
global.step = ST_SWAP_SIGN;
}
PRINTF("[SWAP] : G_called_from_swap = %d , global.step = %d",
G_called_from_swap, global.step);
#endif
if (global.step == ST_ERROR) {
global.step = ST_IDLE;
ui_home_init();
Expand Down
1 change: 1 addition & 0 deletions app/src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ typedef enum {
ST_CLEAR_SIGN,
ST_BLIND_SIGN,
ST_PROMPT,
ST_SWAP_SIGN,
ST_ERROR
} main_step_t;

Expand Down
Loading

0 comments on commit 527c960

Please sign in to comment.