From fa2ec53c6e27539033eea08b9eccfdd7e7f5c175 Mon Sep 17 00:00:00 2001 From: Juan Leni Date: Sat, 15 Aug 2020 19:07:03 +0200 Subject: [PATCH 1/3] generalize review UI --- app/script.ld | 2 +- app/src/apdu_handler.c | 15 ++- deps/ledger-zxlib/app/common/view.c | 105 +++++++------------ deps/ledger-zxlib/app/common/view.h | 21 +++- deps/ledger-zxlib/app/common/view_internal.h | 31 +++--- deps/ledger-zxlib/app/common/view_s.c | 57 ++-------- deps/ledger-zxlib/include/zxversion.h | 4 +- tests_zemu/snapshots/show_address/2.png | Bin 334 -> 443 bytes 8 files changed, 94 insertions(+), 141 deletions(-) diff --git a/app/script.ld b/app/script.ld index 40eb84c3..ceca5659 100644 --- a/app/script.ld +++ b/app/script.ld @@ -30,7 +30,7 @@ MEMORY } PAGE_SIZE = 64; -STACK_SIZE = 2840; +STACK_SIZE = 2824; END_STACK = ORIGIN(SRAM) + LENGTH(SRAM); SECTIONS diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index 9d18b72c..63c1c623 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -24,6 +24,7 @@ #include "view.h" #include "actions.h" #include "tx.h" +#include "addr.h" #include "crypto.h" #include "coin.h" #include "zxmacros.h" @@ -135,7 +136,7 @@ __Z_INLINE void handle_getversion(volatile uint32_t *flags, volatile uint32_t *t G_io_apdu_buffer[0] = 0x01; #endif - #if defined(APP_RESTRICTED) +#if defined(APP_RESTRICTED) G_io_apdu_buffer[0] = 0x02; #endif @@ -166,7 +167,10 @@ __Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, u if (requireConfirmation) { app_fill_address(); - view_address_show(addr_ed22519); + + view_review_init(addr_getItem, addr_getNumItems, app_reply_address, app_reject); + view_review_show(); + *flags |= IO_ASYNCH_REPLY; return; } @@ -194,7 +198,8 @@ __Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint } CHECK_APP_CANARY() - view_sign_show(); + view_review_init(tx_getItem, tx_getNumItems, app_sign, app_reject); + view_review_show(); *flags |= IO_ASYNCH_REPLY; } @@ -225,6 +230,8 @@ __Z_INLINE void handleAllowlistSetMasterkey(volatile uint32_t *flags, volatile u zemu_log_stack("allowlist: try update pubkey"); + // FIXME: Add user confirmation + if (!allowlist_pubkey_set(G_io_apdu_buffer + OFFSET_DATA, 32)) { THROW(APDU_CODE_EXECUTION_ERROR); // 6400 } @@ -255,6 +262,8 @@ __Z_INLINE void handleAllowlistUpload(volatile uint32_t *flags, volatile uint32_ } CHECK_APP_CANARY() + // FIXME: Add user confirmation + zemu_log_stack("allowlist: try update"); if (!allowlist_upgrade(tx_get_buffer(), tx_get_buffer_length())) { THROW(APDU_CODE_EXECUTION_ERROR); diff --git a/deps/ledger-zxlib/app/common/view.c b/deps/ledger-zxlib/app/common/view.c index c031f2f4..5556c408 100644 --- a/deps/ledger-zxlib/app/common/view.c +++ b/deps/ledger-zxlib/app/common/view.c @@ -36,38 +36,33 @@ view_t viewdata; -void h_address_accept(unsigned int _) { +void h_accept(unsigned int _) { UNUSED(_); view_idle_show(0); UX_WAIT(); - app_reply_address(); + viewdata.viewfuncAccept(); } -void h_error_accept(unsigned int _) { +void h_reject(unsigned int _) { UNUSED(_); view_idle_show(0); UX_WAIT(); - app_reply_error(); + viewdata.viewfuncReject(); } -void h_sign_accept(unsigned int _) { - UNUSED(_); - view_idle_show(0); - UX_WAIT(); - app_sign(); -} - -void h_sign_reject(unsigned int _) { +void h_error_accept(unsigned int _) { UNUSED(_); view_idle_show(0); UX_WAIT(); - app_reject(); + app_reply_error(); } /////////////////////////////////// // Paging related void h_paging_init() { + zemu_log_stack("-- h_paging_init"); + viewdata.itemIdx = 0; viewdata.pageIdx = 0; viewdata.pageCount = 1; @@ -121,60 +116,34 @@ void h_paging_decrease() { } } -void h_paging_set_page_count(uint8_t pageCount) { - viewdata.pageCount = pageCount; - if (viewdata.pageIdx > viewdata.pageCount) { - viewdata.pageIdx = viewdata.pageCount - 1; - } -} - /////////////////////////////////// // Paging related zxerr_t h_review_update_data() { + if (viewdata.viewfuncGetNumItems == NULL) { + return zxerr_no_data; + } + do { viewdata.pageCount = 1; - switch (viewdata.mode) { - case review_tx: { - CHECK_ZXERR(tx_getNumItems(&viewdata.itemCount)) - - // be sure we are not out of bounds - CHECK_ZXERR(tx_getItem(viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, MAX_CHARS_PER_VALUE1_LINE, - 0, &viewdata.pageCount)) - if (viewdata.pageCount != 0 && viewdata.pageIdx > viewdata.pageCount) { - // try again and get last page - viewdata.pageIdx = viewdata.pageCount - 1; - } - CHECK_ZXERR( - tx_getItem(viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, MAX_CHARS_PER_VALUE1_LINE, - viewdata.pageIdx, &viewdata.pageCount)) - break; - } - case review_address: { - CHECK_ZXERR(addr_getNumItems(&viewdata.itemCount)) - // be sure we are not out of bounds - CHECK_ZXERR(addr_getItem(viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, MAX_CHARS_PER_VALUE1_LINE, - 0, &viewdata.pageCount)) - if (viewdata.pageCount != 0 && viewdata.pageIdx > viewdata.pageCount) { - // try again and get last page - viewdata.pageIdx = viewdata.pageCount - 1; - } - CHECK_ZXERR( - addr_getItem(viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, MAX_CHARS_PER_VALUE1_LINE, - viewdata.pageIdx, &viewdata.pageCount)) - break; - } - default: - return zxerr_unknown; + CHECK_ZXERR(viewdata.viewfuncGetNumItems(&viewdata.itemCount)) + + // be sure we are not out of bounds + CHECK_ZXERR(viewdata.viewfuncGetItem( + viewdata.itemIdx, + viewdata.key, MAX_CHARS_PER_KEY_LINE, + viewdata.value, MAX_CHARS_PER_VALUE1_LINE, + 0, &viewdata.pageCount)) + if (viewdata.pageCount != 0 && viewdata.pageIdx > viewdata.pageCount) { + // try again and get last page + viewdata.pageIdx = viewdata.pageCount - 1; } + CHECK_ZXERR(viewdata.viewfuncGetItem( + viewdata.itemIdx, + viewdata.key, MAX_CHARS_PER_KEY_LINE, + viewdata.value, MAX_CHARS_PER_VALUE1_LINE, + viewdata.pageIdx, &viewdata.pageCount)) + viewdata.itemCount++; if (viewdata.pageCount > 1) { @@ -209,14 +178,18 @@ void view_idle_show(uint8_t item_idx) { view_idle_show_impl(item_idx); } -void view_address_show() { - viewdata.mode = review_address; - view_address_show_impl(); +void view_review_init(viewfunc_getItem_t viewfuncGetItem, + viewfunc_getNumItems_t viewfuncGetNumItems, + viewfunc_accept_t viewfuncAccept, + viewfunc_reject_t viewfuncReject) { + viewdata.viewfuncGetItem = viewfuncGetItem; + viewdata.viewfuncGetNumItems = viewfuncGetNumItems; + viewdata.viewfuncAccept = viewfuncAccept; + viewdata.viewfuncReject = viewfuncReject; } -void view_sign_show() { - viewdata.mode = review_tx; - view_sign_show_impl(); +void view_review_show() { + view_review_show_impl(); } void view_error_show() { diff --git a/deps/ledger-zxlib/app/common/view.h b/deps/ledger-zxlib/app/common/view.h index a95b4bc1..581330be 100644 --- a/deps/ledger-zxlib/app/common/view.h +++ b/deps/ledger-zxlib/app/common/view.h @@ -18,6 +18,7 @@ #include #include "coin.h" +#include "zxerror.h" #if defined(LEDGER_SPECIFIC) #include "bolos_target.h" @@ -27,6 +28,17 @@ #endif #endif +typedef zxerr_t (*viewfunc_getNumItems_t)(uint8_t *num_items); + +typedef zxerr_t (*viewfunc_getItem_t)(int8_t displayIdx, + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount); + +typedef zxerr_t (*viewfunc_accept_t)(); + +typedef zxerr_t (*viewfunc_reject_t)(); + /// view_init (initializes UI) void view_init(); @@ -36,8 +48,9 @@ void view_idle_show(uint8_t item_idx); /// view_error (error view) void view_error_show(); -// shows address in the screen -void view_address_show(); +void view_review_init(viewfunc_getItem_t viewfuncGetItem, + viewfunc_getNumItems_t viewfuncGetNumItems, + viewfunc_accept_t viewfuncAccept, + viewfunc_reject_t viewfuncReject); -// Shows review screen + later sign menu -void view_sign_show(); +void view_review_show(); diff --git a/deps/ledger-zxlib/app/common/view_internal.h b/deps/ledger-zxlib/app/common/view_internal.h index 5481e9f0..a133ef0c 100644 --- a/deps/ledger-zxlib/app/common/view_internal.h +++ b/deps/ledger-zxlib/app/common/view_internal.h @@ -19,6 +19,7 @@ #include #include "coin.h" #include "zxerror.h" +#include "view.h" #define CUR_FLOW G_ux.flow_stack[G_ux.stack_count-1] @@ -36,11 +37,6 @@ // This takes data from G_io_apdu_buffer that is prefilled with the address -typedef enum { - review_tx = 0, - review_address = 1 -} review_mode_e; - typedef struct { struct { char key[MAX_CHARS_PER_KEY_LINE]; @@ -49,7 +45,11 @@ typedef struct { char value2[MAX_CHARS_PER_VALUE2_LINE]; #endif }; - review_mode_e mode; + viewfunc_getItem_t viewfuncGetItem; + viewfunc_getNumItems_t viewfuncGetNumItems; + viewfunc_accept_t viewfuncAccept; + viewfunc_reject_t viewfuncReject; + uint8_t itemIdx; uint8_t itemCount; uint8_t pageIdx; @@ -79,20 +79,9 @@ void splitValueField(); void view_idle_show_impl(uint8_t item_idx); -void view_address_show_impl(); void view_error_show_impl(); -void view_sign_show_impl(); - -void h_address_accept(unsigned int _); - -void h_error_accept(unsigned int _); - -void h_sign_accept(unsigned int _); - -void h_sign_reject(unsigned int _); - void h_paging_init(); uint8_t h_paging_can_increase(); @@ -103,6 +92,12 @@ uint8_t h_paging_can_decrease(); void h_paging_decrease(); -void h_paging_set_page_count(uint8_t pageCount); +void view_review_show_impl(); + +void h_accept(unsigned int _); + +void h_reject(unsigned int _); + +void h_error_accept(unsigned int _); zxerr_t h_review_update_data(); diff --git a/deps/ledger-zxlib/app/common/view_s.c b/deps/ledger-zxlib/app/common/view_s.c index 96a3568a..ee62be56 100644 --- a/deps/ledger-zxlib/app/common/view_s.c +++ b/deps/ledger-zxlib/app/common/view_s.c @@ -36,7 +36,6 @@ void h_expert_toggle(); void h_expert_update(); void h_review_button_left(); void h_review_button_right(); -void view_review_show(); void view_review_decision_s(); ux_state_t ux; @@ -55,16 +54,9 @@ const ux_menu_entry_t menu_main[] = { UX_MENU_END }; -void h_review(unsigned int _) { UNUSED(_); view_sign_show_impl(); } - -const ux_menu_entry_t menu_decision_sign[] = { - {NULL, h_sign_accept, 0, NULL, "Approve", NULL, 0, 0}, - {NULL, h_sign_reject, 0, NULL, "Reject", NULL, 0, 0}, - UX_MENU_END -}; - -const ux_menu_entry_t menu_decision_address[] = { - {NULL, h_address_accept, 0, NULL, "Accept", NULL, 0, 0}, +const ux_menu_entry_t menu_decision_review[] = { + {NULL, h_accept, 0, NULL, "Approve", NULL, 0, 0}, + {NULL, h_reject, 0, NULL, "Reject", NULL, 0, 0}, UX_MENU_END }; @@ -145,8 +137,7 @@ void h_review_button_left() { zxerr_t err = h_review_update_data(); switch(err) { case zxerr_ok: - view_review_show(); - UX_WAIT(); + UX_DISPLAY(view_review, view_prepro); break; case zxerr_no_data: view_review_decision_s(); @@ -165,8 +156,7 @@ void h_review_button_right() { switch(err) { case zxerr_ok: - view_review_show(); - UX_WAIT(); + UX_DISPLAY(view_review, view_prepro); break; case zxerr_no_data: view_review_decision_s(); @@ -203,20 +193,7 @@ void view_error_show_impl() { } void view_review_decision_s(void){ - switch (viewdata.mode) { - case review_tx: { - UX_MENU_DISPLAY(0, menu_decision_sign, NULL); - break; - } - case review_address: { - UX_MENU_DISPLAY(0, menu_decision_address, NULL); - break; - } - } -} - -void view_review_show() { - UX_DISPLAY(view_review, view_prepro); + UX_MENU_DISPLAY(0, menu_decision_review, NULL); } void h_expert_toggle() { @@ -231,29 +208,15 @@ void h_expert_update() { } } -void view_sign_show_impl() { - h_paging_init(); +void view_review_show_impl() { + zemu_log_stack("-- view_review_show_impl"); - zxerr_t err = h_review_update_data(); - switch(err) { - case zxerr_ok: - view_review_show(); - break; - case zxerr_no_data: - view_review_decision_s(); - break; - default: - view_error_show(); - break; - } -} - -void view_address_show_impl() { h_paging_init(); + zxerr_t err = h_review_update_data(); switch(err) { case zxerr_ok: - view_review_show(); + UX_DISPLAY(view_review, view_prepro); break; case zxerr_no_data: view_review_decision_s(); diff --git a/deps/ledger-zxlib/include/zxversion.h b/deps/ledger-zxlib/include/zxversion.h index e5f303d2..4090e752 100644 --- a/deps/ledger-zxlib/include/zxversion.h +++ b/deps/ledger-zxlib/include/zxversion.h @@ -15,6 +15,6 @@ ********************************************************************************/ #pragma once -#define ZXLIB_MAJOR 4 -#define ZXLIB_MINOR 1 +#define ZXLIB_MAJOR 5 +#define ZXLIB_MINOR 0 #define ZXLIB_PATCH 0 diff --git a/tests_zemu/snapshots/show_address/2.png b/tests_zemu/snapshots/show_address/2.png index 9c74268512a23aafb8593c178d33cd633316e2e4..4aa28b6bfdc9668cf49edfe790ea290941e99f83 100644 GIT binary patch delta 417 zcmX@dw3~T?N_~^3i(^Oy4N4D`XKD{6YX0;vUx80!Y>Tq+K>5XY-XlTbIHmPm<(+fm-m$$urzvCmX zl-vm)UjCG2Y$+KtQkJz%K6Az3ysXI89wxcuPM6AGWFwN00LcS6DWa4_%xl@G5t9JW_?K0KE#rEXWDDzCi% zv*Z&O8hCh5{K@?AQp(Th#2l%(NtK?@G-obP0U0@IW{TZ3ptOzg4z8J#>(2!9>YMIy zO#|9=Ps!Nyg2UnC6DnODcJ6BPeCBvqWwWhRj<An%J*?f%8lB8p6CLWok_@h~WO(4q*)36P0+}AP=O6f){X3gG`&?`3Q9IM{7 z^DOGcg~cD^cN{pn(yk(1Pi~5dIKS7dZg$nPN7cOw3X3mJnd4I5U^%gSI#9;exCj>PY`U!J2$Y&0v**d9XH4StPanzF6j+J>pEAj_NqFZDpyXLr zuehL3lP2W{f8t}AaT%yr4rs*Lqs^0^J#zFc{B%zVt0~Z?-JBrT o`Zh!+v+97|yXIn(X%vbl;#c;kvs+vV^J4%4Pgg&ebxsLQ0E4TFApigX From 0edf03c85bda87fcf6acf8fe281486081920312b Mon Sep 17 00:00:00 2001 From: Juan Leni Date: Sat, 15 Aug 2020 21:05:09 +0200 Subject: [PATCH 2/3] add allowlist UI --- app/src/allowlist.c | 51 +++++++++++++++++++++++++++-- app/src/allowlist.h | 11 +++++++ app/src/apdu_handler.c | 51 ++++++++++++++++++++--------- deps/ledger-zxlib/app/common/view.c | 8 +++-- deps/ledger-zxlib/app/common/view.h | 4 +-- tests_zemu/tests/Ledgeracio.test.js | 30 ++++++++++++++--- 6 files changed, 128 insertions(+), 27 deletions(-) diff --git a/app/src/allowlist.c b/app/src/allowlist.c index 2bc5fb71..49c69582 100644 --- a/app/src/allowlist.c +++ b/app/src/allowlist.c @@ -18,6 +18,8 @@ #include "os.h" #include "cx.h" +#include "coin.h" +#include "app_main.h" #include "allowlist.h" typedef struct { @@ -155,7 +157,6 @@ bool allowlist_list_validate(const uint8_t *new_list_buffer, size_t new_list_buf return false; } - zemu_log_stack("\n"); // Hash allowlist (len + items) uint8_t digest[32]; @@ -202,7 +203,6 @@ bool allowlist_list_validate(const uint8_t *new_list_buffer, size_t new_list_buf } return valid_signature; -// return true; } bool allowlist_upgrade(const uint8_t *new_list_buffer, size_t new_list_buffer_len) { @@ -214,4 +214,51 @@ bool allowlist_upgrade(const uint8_t *new_list_buffer, size_t new_list_buffer_le return true; } +zxerr_t allowlist_getNumItems(uint8_t *num_items) { + zemu_log_stack("allowlist_getNumItems"); + *num_items = 1; + return zxerr_ok; +} + +zxerr_t allowlist_getItem(int8_t displayIdx, + char *outKey, uint16_t outKeyLen, + char *outVal, uint16_t outValLen, + uint8_t pageIdx, uint8_t *pageCount) { + zemu_log_stack("allowlist_getItem"); + if (displayIdx != 0) { + return zxerr_no_data; + } + + switch (G_io_apdu_buffer[OFFSET_INS]) { + case INS_ALLOWLIST_SET_PUBKEY: { + snprintf(outKey, outKeyLen, "Set Pubkey"); + + char bufferUI[100]; + if (array_to_hexstr(bufferUI, sizeof(bufferUI), G_io_apdu_buffer+OFFSET_DATA, 32) != 64) { + return zxerr_encoding_failed; + } + pageString(outVal, outValLen, bufferUI, pageIdx, pageCount); + return zxerr_ok; + } + case INS_ALLOWLIST_UPLOAD: { + snprintf(outKey, outKeyLen, "Allowlist Upload"); + + uint8_t digest[32]; + allowlist_t *new_list = (allowlist_t *) tx_get_buffer(); + allowlist_calculate_digest(digest, new_list); + + char bufferUI[100]; + if (array_to_hexstr(bufferUI, sizeof(bufferUI), digest, sizeof(digest)) != 64) { + return zxerr_encoding_failed; + } + pageString(outVal, outValLen, bufferUI, pageIdx, pageCount); + return zxerr_ok; + } + default: + break; + } + + return zxerr_no_data; +} + #endif diff --git a/app/src/allowlist.h b/app/src/allowlist.h index f519ee9d..24ed01c2 100644 --- a/app/src/allowlist.h +++ b/app/src/allowlist.h @@ -14,8 +14,10 @@ * limitations under the License. ********************************************************************************/ #pragma once + #include "zxmacros.h" #include +#include "zxerror.h" #define ALLOW_LIST_SIZE 128 // Length is limited to 63 because it must be zero terminated @@ -52,8 +54,17 @@ void allowlist_hash(uint8_t *digest); bool allowlist_item_validate(const char *address); +bool allowlist_list_validate(const uint8_t *new_list_buffer, size_t new_list_buffer_len); + bool allowlist_upgrade(const uint8_t *new_list_buffer, size_t new_list_buffer_len); +zxerr_t allowlist_getNumItems(uint8_t *num_items); + +zxerr_t allowlist_getItem(int8_t displayIdx, + char *outKey, uint16_t outKeyLen, + char *outValue, uint16_t outValueLen, + uint8_t pageIdx, uint8_t *pageCount); + #ifdef __cplusplus } #endif diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index 63c1c623..0b067a5d 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -100,6 +100,7 @@ __Z_INLINE bool process_chunk(volatile uint32_t *tx, uint32_t rx) { THROW(APDU_CODE_INVALIDP1P2); } +#if defined(APP_RESTRICTED) __Z_INLINE bool process_chunk_update(volatile uint32_t *tx, uint32_t rx) { const uint8_t payloadType = G_io_apdu_buffer[OFFSET_PAYLOAD_TYPE]; @@ -128,6 +129,7 @@ __Z_INLINE bool process_chunk_update(volatile uint32_t *tx, uint32_t rx) { return payloadType == 2; } +#endif __Z_INLINE void handle_getversion(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { G_io_apdu_buffer[0] = 0; @@ -218,7 +220,18 @@ __Z_INLINE void handleAllowlistGetMasterkey(volatile uint32_t *flags, volatile u THROW(APDU_CODE_OK); } -__Z_INLINE void handleAllowlistSetMasterkey(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { +void app_allowlist_SetPublicKey() { + if (!allowlist_pubkey_set(G_io_apdu_buffer + OFFSET_DATA, 32)) { + set_code(G_io_apdu_buffer, 0, APDU_CODE_EXECUTION_ERROR); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + } + zemu_log_stack("allowlist: pubkey updated"); + + set_code(G_io_apdu_buffer, 0, APDU_CODE_OK); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); +} + +__Z_INLINE void handleAllowlistSetPublicKey(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { if (allowlist_pubkey_is_set()) { // Can only be set once THROW(APDU_CODE_COMMAND_NOT_ALLOWED); // 0x6986 @@ -230,14 +243,9 @@ __Z_INLINE void handleAllowlistSetMasterkey(volatile uint32_t *flags, volatile u zemu_log_stack("allowlist: try update pubkey"); - // FIXME: Add user confirmation - - if (!allowlist_pubkey_set(G_io_apdu_buffer + OFFSET_DATA, 32)) { - THROW(APDU_CODE_EXECUTION_ERROR); // 6400 - } - - zemu_log_stack("allowlist: pubkey updated"); - THROW(APDU_CODE_OK); + view_review_init(allowlist_getItem, allowlist_getNumItems, app_allowlist_SetPublicKey, app_reject); + view_review_show(); + *flags |= IO_ASYNCH_REPLY; } __Z_INLINE void handleAllowlistGetHash(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { @@ -250,6 +258,18 @@ __Z_INLINE void handleAllowlistGetHash(volatile uint32_t *flags, volatile uint32 THROW(APDU_CODE_OK); } +void app_allowlist_Upload() { + zemu_log_stack("allowlist: try update"); + if (!allowlist_upgrade(tx_get_buffer(), tx_get_buffer_length())) { + set_code(G_io_apdu_buffer, 0, APDU_CODE_EXECUTION_ERROR); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + } + + zemu_log_stack("allowlist: updated"); + set_code(G_io_apdu_buffer, 0, APDU_CODE_OK); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); +} + __Z_INLINE void handleAllowlistUpload(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { if (!allowlist_pubkey_is_set()) { zemu_log_stack("allowlist: pubkey has not been set"); @@ -262,15 +282,14 @@ __Z_INLINE void handleAllowlistUpload(volatile uint32_t *flags, volatile uint32_ } CHECK_APP_CANARY() - // FIXME: Add user confirmation - - zemu_log_stack("allowlist: try update"); - if (!allowlist_upgrade(tx_get_buffer(), tx_get_buffer_length())) { + if (!allowlist_list_validate(tx_get_buffer(), tx_get_buffer_length())) { + // conditions to update allowlist are not satisfied THROW(APDU_CODE_EXECUTION_ERROR); } - zemu_log_stack("allowlist: updated"); - THROW(APDU_CODE_OK); + view_review_init(allowlist_getItem, allowlist_getNumItems, app_allowlist_Upload, app_reject); + view_review_show(); + *flags |= IO_ASYNCH_REPLY; } #endif @@ -313,7 +332,7 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { } case INS_ALLOWLIST_SET_PUBKEY: { - handleAllowlistSetMasterkey(flags, tx, rx); + handleAllowlistSetPublicKey(flags, tx, rx); break; } diff --git a/deps/ledger-zxlib/app/common/view.c b/deps/ledger-zxlib/app/common/view.c index 5556c408..04a4756a 100644 --- a/deps/ledger-zxlib/app/common/view.c +++ b/deps/ledger-zxlib/app/common/view.c @@ -40,14 +40,18 @@ void h_accept(unsigned int _) { UNUSED(_); view_idle_show(0); UX_WAIT(); - viewdata.viewfuncAccept(); + if (viewdata.viewfuncAccept != NULL) { + viewdata.viewfuncAccept(); + } } void h_reject(unsigned int _) { UNUSED(_); view_idle_show(0); UX_WAIT(); - viewdata.viewfuncReject(); + if (viewdata.viewfuncReject != NULL) { + viewdata.viewfuncReject(); + } } void h_error_accept(unsigned int _) { diff --git a/deps/ledger-zxlib/app/common/view.h b/deps/ledger-zxlib/app/common/view.h index 581330be..b302f47e 100644 --- a/deps/ledger-zxlib/app/common/view.h +++ b/deps/ledger-zxlib/app/common/view.h @@ -35,9 +35,9 @@ typedef zxerr_t (*viewfunc_getItem_t)(int8_t displayIdx, char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount); -typedef zxerr_t (*viewfunc_accept_t)(); +typedef void (*viewfunc_accept_t)(); -typedef zxerr_t (*viewfunc_reject_t)(); +typedef void (*viewfunc_reject_t)(); /// view_init (initializes UI) void view_init(); diff --git a/tests_zemu/tests/Ledgeracio.test.js b/tests_zemu/tests/Ledgeracio.test.js index 69675498..7bbb99c7 100644 --- a/tests_zemu/tests/Ledgeracio.test.js +++ b/tests_zemu/tests/Ledgeracio.test.js @@ -21,7 +21,7 @@ import ed25519 from "ed25519-supercop"; import {dummyAllowlist, TESTING_ALLOWLIST_SEED} from "./common"; const Resolve = require("path").resolve; -const APP_PATH = Resolve("../app/bin/app_ledgeracio.elf"); +const APP_PATH = Resolve("../app/bin/app.elf"); const APP_SEED = "equip will roof matter pink blind book anxiety banner elbow sun young" const sim_options = { @@ -87,7 +87,12 @@ describe('Basic checks', function () { const pk = Buffer.from("1234000000000000000000000000000000000000000000000000000000000000", "hex") - let resp = await app.setAllowlistPubKey(pk); + let req = app.setAllowlistPubKey(pk); + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); + await sim.clickRight(); + await sim.clickRight(); + await sim.clickBoth(); + let resp = await req; expect(resp.return_code).toEqual(0x9000); expect(resp.error_message).toEqual("No errors"); @@ -158,13 +163,23 @@ describe('Basic checks', function () { console.log("\n\n------------ Set pubkey") const keypair = ed25519.createKeyPair(TESTING_ALLOWLIST_SEED) - let resp = await app.setAllowlistPubKey(keypair.publicKey); + let req = app.setAllowlistPubKey(keypair.publicKey); + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); + await sim.clickRight(); + await sim.clickRight(); + await sim.clickBoth(); + let resp = await req; expect(resp.return_code).toEqual(0x9000); expect(resp.error_message).toEqual("No errors"); let allowlist = dummyAllowlist(10); console.log(`\n\n------------ Upload allowlist : ${allowlist.length} bytes`) - resp = await app.uploadAllowlist(allowlist); + req = app.uploadAllowlist(allowlist); + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); + await sim.clickRight(); + await sim.clickRight(); + await sim.clickBoth(); + resp = await req; console.log(resp); expect(resp.return_code).toEqual(0x9000); @@ -184,7 +199,12 @@ describe('Basic checks', function () { console.log(`\n\n------------ Upload allowlist : Again but change nonce`) allowlist = dummyAllowlist(11); - resp = await app.uploadAllowlist(allowlist); + req = app.uploadAllowlist(allowlist); + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); + await sim.clickRight(); + await sim.clickRight(); + await sim.clickBoth(); + resp = await req; console.log(resp); expect(resp.return_code).toEqual(0x9000); expect(resp.error_message).toEqual("No errors"); From 5c0acad056bc74688274464a0d183603cb20da40 Mon Sep 17 00:00:00 2001 From: Juan Leni Date: Sat, 15 Aug 2020 21:05:42 +0200 Subject: [PATCH 3/3] bump version number --- app/Makefile.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Makefile.version b/app/Makefile.version index 1a6877aa..34e3eda9 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -1,3 +1,3 @@ APPVERSION_M=2 APPVERSION_N=2019 -APPVERSION_P=4 +APPVERSION_P=5