diff --git a/src/handler/sign_tx.c b/src/handler/sign_tx.c index 7f0c581b..ba0c378d 100644 --- a/src/handler/sign_tx.c +++ b/src/handler/sign_tx.c @@ -89,7 +89,17 @@ int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more) { PRINTF("Hash: %.*H\n", sizeof(G_context.tx_info.m_hash), G_context.tx_info.m_hash); - return ui_display_transaction(); + // Example to trig a blind-sign flow + if (strcmp((char *) G_context.tx_info.transaction.memo, "Blind-sign") == 0) { +// to remove when Nbgl will be available for Nanos +#ifdef HAVE_NBGL + return ui_display_blind_signed_transaction(); +#else + return ui_display_transaction(); +#endif + } else { + return ui_display_transaction(); + } } } diff --git a/src/ui/display.h b/src/ui/display.h index 2168e700..ab066c46 100644 --- a/src/ui/display.h +++ b/src/ui/display.h @@ -22,3 +22,11 @@ int ui_display_address(void); * */ int ui_display_transaction(void); + +/** + * Display blind-sign transaction information on the device and ask confirmation to sign. + * + * @return 0 if success, negative integer otherwise. + * + */ +int ui_display_blind_signed_transaction(void); diff --git a/src/ui/nbgl_display_transaction.c b/src/ui/nbgl_display_transaction.c index 307a151a..b7ad1087 100755 --- a/src/ui/nbgl_display_transaction.c +++ b/src/ui/nbgl_display_transaction.c @@ -60,7 +60,8 @@ static void review_choice(bool confirm) { // - Check if the app is in the right state for transaction review // - Format the amount and address strings in g_amount and g_address buffers // - Display the first screen of the transaction review -int ui_display_transaction() { +// - Display a warning if the transaction is blind-signed +int ui_display_transaction_bs_choice(bool is_blind_signed) { if (G_context.req_type != CONFIRM_TRANSACTION || G_context.state != STATE_PARSED) { G_context.state = STATE_NONE; return io_send_sw(SW_BAD_STATE); @@ -94,15 +95,38 @@ int ui_display_transaction() { pairList.nbPairs = 2; pairList.pairs = pairs; - // Start review - nbgl_useCaseReview(TYPE_TRANSACTION, - &pairList, - &C_app_boilerplate_64px, - "Review transaction\nto send BOL", - NULL, - "Sign transaction\nto send BOL", - review_choice); + if (is_blind_signed) { + // Start blind-signing review flow + nbgl_useCaseReviewBlindSigning(TYPE_TRANSACTION, + &pairList, + &C_app_boilerplate_64px, + "Review transaction\nto send BOL", + NULL, + "Sign transaction\nto send BOL", + NULL, + review_choice); + } else { + // Start review flow + nbgl_useCaseReview(TYPE_TRANSACTION, + &pairList, + &C_app_boilerplate_64px, + "Review transaction\nto send BOL", + NULL, + "Sign transaction\nto send BOL", + review_choice); + } + return 0; } +// Flow used to display a blind-signed transaction +int ui_display_blind_signed_transaction(void) { + return ui_display_transaction_bs_choice(true); +} + +// Flow used to display a clear-signed transaction +int ui_display_transaction() { + return ui_display_transaction_bs_choice(false); +} + #endif diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00000.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00000.png new file mode 100644 index 00000000..2c0913d4 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00000.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00001.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00001.png new file mode 100644 index 00000000..1b13f863 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00001.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00002.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00002.png new file mode 100644 index 00000000..8cad97c3 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00002.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00003.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00003.png new file mode 100644 index 00000000..be51a9d5 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00003.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00004.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00004.png new file mode 100644 index 00000000..8a1cfc78 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/00004.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00000.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00000.png new file mode 100644 index 00000000..4397e0e0 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00000.png differ diff --git a/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00001.png b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00001.png new file mode 100644 index 00000000..a3c76138 Binary files /dev/null and b/tests/snapshots/flex/test_sign_tx_short_tx_blind_sign/part1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png index 1fd64ec5..7a73b923 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/00001.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/00001.png index 1fd64ec5..7a73b923 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/00001.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00000.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00000.png new file mode 100644 index 00000000..d4f2169d Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00001.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00001.png new file mode 100644 index 00000000..9699e754 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00002.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00002.png new file mode 100644 index 00000000..72a8d7bc Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00003.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00003.png new file mode 100644 index 00000000..392165d4 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00004.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00004.png new file mode 100644 index 00000000..751fa6c1 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00000.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00000.png new file mode 100644 index 00000000..04055db7 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00001.png b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00001.png new file mode 100644 index 00000000..d4f2169d Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_short_tx_blind_sign/part1/00001.png differ diff --git a/tests/test_sign_cmd.py b/tests/test_sign_cmd.py index 8c950680..56515570 100644 --- a/tests/test_sign_cmd.py +++ b/tests/test_sign_cmd.py @@ -4,12 +4,13 @@ from application_client.boilerplate_command_sender import BoilerplateCommandSender, Errors from application_client.boilerplate_response_unpacker import unpack_get_public_key_response, unpack_sign_tx_response from ragger.error import ExceptionRAPDU +from ragger.navigator import NavInsID from utils import check_signature_validity # In this tests we check the behavior of the device when asked to sign a transaction -# In this test se send to the device a transaction to sign and validate it on screen +# In this test we send to the device a transaction to sign and validate it on screen # The transaction is short and will be sent in one chunk # We will ensure that the displayed information is correct by using screenshots comparison def test_sign_tx_short_tx(backend, scenario_navigator): @@ -43,6 +44,45 @@ def test_sign_tx_short_tx(backend, scenario_navigator): assert check_signature_validity(public_key, der_sig, transaction) +# In this test we send to the device a transaction to trig a blind-signing flow +# The transaction is short and will be sent in one chunk +# We will ensure that the displayed information is correct by using screenshots comparison +def test_sign_tx_short_tx_blind_sign(firmware, navigator, backend, scenario_navigator, test_name, default_screenshot_path): + if not firmware.is_nano: + # Use the app interface instead of raw interface + client = BoilerplateCommandSender(backend) + # The path used for this entire test + path: str = "m/44'/1'/0'/0/0" + + # First we need to get the public key of the device in order to build the transaction + rapdu = client.get_public_key(path=path) + _, public_key, _, _ = unpack_get_public_key_response(rapdu.data) + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + nonce=1, + to="0x0000000000000000000000000000000000000000", + value=0, + memo="Blind-sign" + ).serialize() + + # Send the sign device instruction. + # As it requires on-screen validation, the function is asynchronous. + # It will yield the result when the navigation is done + with client.sign_tx(path=path, transaction=transaction): + navigator.navigate_and_compare(default_screenshot_path, + test_name+"/part1", + [NavInsID.USE_CASE_CHOICE_REJECT], + screen_change_after_last_instruction=False) + + # Validate the on-screen request by performing the navigation appropriate for this device + scenario_navigator.review_approve() + + # The device as yielded the result, parse it and ensure that the signature is correct + response = client.get_async_response().data + _, der_sig, _ = unpack_sign_tx_response(response) + assert check_signature_validity(public_key, der_sig, transaction) + # In this test se send to the device a transaction to sign and validate it on screen # This test is mostly the same as the previous one but with different values. # In particular the long memo will force the transaction to be sent in multiple chunks