diff --git a/.github/workflows/build_and_functional_tests.yml b/.github/workflows/build_and_functional_tests.yml index 647f417b..25408fff 100644 --- a/.github/workflows/build_and_functional_tests.yml +++ b/.github/workflows/build_and_functional_tests.yml @@ -22,7 +22,7 @@ jobs: name: Build application using the reusable workflow uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1 with: - run_for_devices: '["nanox", "nanosp"]' + run_for_devices: '["nanox", "nanosp", "stax"]' upload_app_binaries_artifact: compiled_app_binaries ragger_tests: @@ -32,6 +32,8 @@ jobs: include: - model: nanox + - model: stax + - model: nanosp args: "--fast" diff --git a/.github/workflows/guidelines_enforcer.yml b/.github/workflows/guidelines_enforcer.yml index fabb7702..748c4806 100644 --- a/.github/workflows/guidelines_enforcer.yml +++ b/.github/workflows/guidelines_enforcer.yml @@ -22,4 +22,4 @@ jobs: name: Call Ledger guidelines_enforcer uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1 with: - run_for_devices: '["nanox", "nanosp"]' + run_for_devices: '["nanox", "nanosp", "stax"]' diff --git a/.github/workflows/misspellings_checks.yml b/.github/workflows/misspellings_checks.yml index 0333481f..60499ab7 100644 --- a/.github/workflows/misspellings_checks.yml +++ b/.github/workflows/misspellings_checks.yml @@ -22,7 +22,8 @@ jobs: uses: actions/checkout@v3 - name: Check misspellings - uses: codespell-project/actions-codespell@v1 + uses: codespell-project/actions-codespell@v2 with: builtin: clear,rare check_filenames: true + ignore_words_list: onTop, dummy diff --git a/Makefile b/Makefile index ff0e52c9..87d75018 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ endif include $(BOLOS_SDK)/Makefile.defines $(info TARGET_NAME=$(TARGET_NAME)) -ifneq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) +ifneq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2 TARGET_STAX)) $(error Environment variable TARGET_NAME is not valid or not supported) endif @@ -38,6 +38,7 @@ APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) ICON_NANOX=icons/icon_security_key.gif ICON_NANOSP=icons/icon_security_key.gif +ICON_STAX=icons/icon_security_key_stax.gif ################ # Attestations # diff --git a/conformance/prod-stax.json b/conformance/prod-stax.json new file mode 100644 index 00000000..da7afffa --- /dev/null +++ b/conformance/prod-stax.json @@ -0,0 +1,87 @@ +{ + "legalHeader": "Submission of this statement and retrieval and use of this statement indicates acceptance of the appropriate agreement located at https://fidoalliance.org/metadata/metadata-legal-terms/.", + "aaguid": "6e24d385-004a-16a0-7bfe-efd963845b34", + "description": "Ledger Stax FIDO2 Authenticator", + "alternativeDescriptions": {}, + "authenticatorVersion": 1, + "protocolFamily": "fido2", + "schema": 3, + "upv": [{ + "major": 1, + "minor": 0 + }], + "authenticationAlgorithms": [ + "secp256r1_ecdsa_sha256_raw", + "secp256k1_ecdsa_sha256_raw", + "ed25519_eddsa_sha512_raw" + ], + "publicKeyAlgAndEncodings": ["cose"], + "attestationTypes": [ + "basic_full" + ], + "userVerificationDetails": [ + [{ + "userVerificationMethod": "none" + } + ], + [{ + "userVerificationMethod": "presence_internal" + } + ], + [{ + "userVerificationMethod": "passcode_external" + } + ], + [{ + "userVerificationMethod": "presence_internal" + }, + { + "userVerificationMethod": "passcode_external" + } + ], + [{ + "userVerificationMethod": "passcode_internal", + "caDesc": { + "base": 10, + "minLength": 4, + "maxRetries": 3 + } + } + ], + [{ + "userVerificationMethod": "presence_internal" + }, + { + "userVerificationMethod": "passcode_internal", + "caDesc": { + "base": 10, + "minLength": 4, + "maxRetries": 3 + } + } + ] + ], + "keyProtection": ["hardware", "secure_element"], + "matcherProtection": ["on_chip"], + "cryptoStrength": 128, + "attachmentHint": ["external", "wired"], + "tcDisplay": ["any", "hardware"], + "tcDisplayContentType": "text/plain", + "attestationRootCertificates": [ + "MIIBgTCCAScCFBlo0s5QYFdXbfusRdQeoLX6QenlMAoGCCqGSM49BAMCMEMxCzAJBgNVBAYTAkZSMQ8wDQYDVQQKDAZMZWRnZXIxIzAhBgNVBAMMGkxlZGdlciBGSURPIEF0dGVzdGF0aW9uIENBMB4XDTIzMDIyMzEwMzMwOFoXDTMzMDIyMDEwMzMwOFowQzELMAkGA1UEBhMCRlIxDzANBgNVBAoMBkxlZGdlcjEjMCEGA1UEAwwaTGVkZ2VyIEZJRE8gQXR0ZXN0YXRpb24gQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATK7nXyH4pgN3TMwCWSoMDRe4EV8Jl3XzuhicZ/2gvh+zz3WmW0OZ/EcRYEA8F26ceeuMcd21WQRRKWpjWD+JWiMAoGCCqGSM49BAMCA0gAMEUCIQCwcsHuL8ZFL3FNyU/DOQn3bmx08lnn0O5RktLbOnoPHQIgOEi6ImAZ181q8RJiL0hbw7ZquuniRq6fjWjGoBu1Moo=" + ], + "icon": "data:image/png;base64,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", + "authenticatorGetInfo": { + "versions": ["U2F_V2", "FIDO_2_0"], + "extensions": ["hmac-secret", "txAuthSimple"], + "aaguid": "6e24d385004a16a07bfeefd963845b34", + "options": { + "rk": true, + "up": true, + "uv": true, + "clientPin": true + }, + "maxMsgSize": 1024, + "pinUvAuthProtocols": [1] + } +} \ No newline at end of file diff --git a/conformance/test-stax.json b/conformance/test-stax.json new file mode 100644 index 00000000..9dc9efd9 --- /dev/null +++ b/conformance/test-stax.json @@ -0,0 +1,87 @@ +{ + "legalHeader": "Submission of this statement and retrieval and use of this statement indicates acceptance of the appropriate agreement located at https://fidoalliance.org/metadata/metadata-legal-terms/.", + "aaguid": "6e24d385-004a-16a0-7bfe-efd963845b34", + "description": "Ledger Stax FIDO2 Authenticator", + "alternativeDescriptions": {}, + "authenticatorVersion": 1, + "protocolFamily": "fido2", + "schema": 3, + "upv": [{ + "major": 1, + "minor": 0 + }], + "authenticationAlgorithms": [ + "secp256r1_ecdsa_sha256_raw", + "secp256k1_ecdsa_sha256_raw", + "ed25519_eddsa_sha512_raw" + ], + "publicKeyAlgAndEncodings": ["cose"], + "attestationTypes": [ + "basic_full" + ], + "userVerificationDetails": [ + [{ + "userVerificationMethod": "none" + } + ], + [{ + "userVerificationMethod": "presence_internal" + } + ], + [{ + "userVerificationMethod": "passcode_external" + } + ], + [{ + "userVerificationMethod": "presence_internal" + }, + { + "userVerificationMethod": "passcode_external" + } + ], + [{ + "userVerificationMethod": "passcode_internal", + "caDesc": { + "base": 10, + "minLength": 4, + "maxRetries": 3 + } + } + ], + [{ + "userVerificationMethod": "presence_internal" + }, + { + "userVerificationMethod": "passcode_internal", + "caDesc": { + "base": 10, + "minLength": 4, + "maxRetries": 3 + } + } + ] + ], + "keyProtection": ["hardware", "secure_element"], + "matcherProtection": ["on_chip"], + "cryptoStrength": 128, + "attachmentHint": ["external", "wired"], + "tcDisplay": ["any", "hardware"], + "tcDisplayContentType": "text/plain", + "attestationRootCertificates": [ + "MIIBgTCCAScCFCCm+doNCJYpK4mBmyd2xdAMieATMAoGCCqGSM49BAMCMEMxCzAJBgNVBAYTAkZSMQ8wDQYDVQQKDAZMZWRnZXIxIzAhBgNVBAMMGkxlZGdlciBGSURPIEF0dGVzdGF0aW9uIENBMB4XDTIyMDkyNjA4MDUzN1oXDTMyMDkyMzA4MDUzN1owQzELMAkGA1UEBhMCRlIxDzANBgNVBAoMBkxlZGdlcjEjMCEGA1UEAwwaTGVkZ2VyIEZJRE8gQXR0ZXN0YXRpb24gQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQBNQxWyIb4hypWXXlxpGG0VMc5xyFsg/A5wq8q7NoNcHmNAkBtn7EOB21c107fcO1DC3OjNxqo6keVIGOj09hJMAoGCCqGSM49BAMCA0gAMEUCIQDirkVesYHsQU+cZiZA3K14MgBl0naL4BfAXdsAYgSBkgIgI9YDiMQGWt9eQPkBAyGv0A2Xx/+jRbkU9c0umz1cSXs=" + ], + "icon": "data:image/png;base64,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", + "authenticatorGetInfo": { + "versions": ["U2F_V2", "FIDO_2_0"], + "extensions": ["hmac-secret", "txAuthSimple"], + "aaguid": "6e24d385004a16a07bfeefd963845b34", + "options": { + "rk": true, + "up": true, + "uv": true, + "clientPin": true + }, + "maxMsgSize": 1024, + "pinUvAuthProtocols": [1] + } +} \ No newline at end of file diff --git a/glyphs/icon_security_key_64px.gif b/glyphs/icon_security_key_64px.gif new file mode 100644 index 00000000..5c048cf6 Binary files /dev/null and b/glyphs/icon_security_key_64px.gif differ diff --git a/icons/icon_security_key_stax.gif b/icons/icon_security_key_stax.gif new file mode 100644 index 00000000..7065a24f Binary files /dev/null and b/icons/icon_security_key_stax.gif differ diff --git a/include/ui_shared.h b/include/ui_shared.h index 728be748..4c6d31d5 100644 --- a/include/ui_shared.h +++ b/include/ui_shared.h @@ -21,4 +21,21 @@ void ui_idle(); +#ifdef HAVE_NBGL + +#include "nbgl_use_case.h" +#include "nbgl_layout.h" + +void app_nbgl_start_review(uint8_t nb_pairs, + const nbgl_layoutTagValue_t *pairs, + const char *confirm_text, + nbgl_choiceCallback_t on_choice, + nbgl_callback_t on_select); + +void app_nbgl_status(const char *message, + bool is_success, + nbgl_callback_t on_quit, + tune_index_e tune); +#endif + #endif diff --git a/src/ctap2_get_assertion.c b/src/ctap2_get_assertion.c index cd13ee59..18de8ff0 100644 --- a/src/ctap2_get_assertion.c +++ b/src/ctap2_get_assertion.c @@ -830,14 +830,10 @@ void ctap2_get_assertion_confirm(uint16_t idx) { uint32_t dataLen; credential_data_t credData; - ctap2UxState = CTAP2_UX_STATE_NONE; - PRINTF("ctap2_get_assertion_confirm %d\n", idx); ctap2_send_keepalive_processing(); - ui_idle(); - // Perform User Verification if required if (ctap2AssertData->pinRequired) { performBuiltInUv(); @@ -905,7 +901,5 @@ void ctap2_get_assertion_confirm(uint16_t idx) { } void ctap2_get_assertion_user_cancel() { - ctap2UxState = CTAP2_UX_STATE_NONE; send_cbor_error(&G_io_u2f, ERROR_OPERATION_DENIED); - ui_idle(); } diff --git a/src/ctap2_get_assertion_flow.c b/src/ctap2_get_assertion_flow.c index 6823870f..3ce6c9d2 100644 --- a/src/ctap2_get_assertion_flow.c +++ b/src/ctap2_get_assertion_flow.c @@ -25,36 +25,54 @@ #include "ctap2.h" #include "credential.h" #include "globals.h" +#include "ui_shared.h" -static void ctap2_ux_display_user_assertion(void) { +static void ctap2_ux_display_user_assertion(char buffer[static 36]) { ctap2_assert_data_t *ctap2AssertData = globals_get_ctap2_assert_data(); credential_data_t credData; - uint8_t nameLength = 0; - // TODO show that user.id is truncated if necessary if (credential_decode(&credData, ctap2AssertData->credential, ctap2AssertData->credentialLen, true) != 0) { // This should never happen, but keep a consistent state if it ever does - verifyHash[0] = '\0'; + buffer[0] = '\0'; } else if (credData.userStr != NULL) { - nameLength = MIN(credData.userStrLen, sizeof(verifyHash) - 1); - memcpy(verifyHash, credData.userStr, nameLength); - verifyHash[nameLength] = '\0'; + nameLength = MIN(credData.userStrLen, 36 - 1); + memcpy(buffer, credData.userStr, nameLength); + buffer[nameLength] = '\0'; } else { - nameLength = MIN(credData.userIdLen, (sizeof(verifyHash) - 1) / 2); - - format_hex(credData.userId, nameLength, verifyHash, sizeof(verifyHash)); + nameLength = MIN(credData.userIdLen, (36 / 2) - 1); + format_hex(credData.userId, nameLength, buffer, 36); nameLength = nameLength * 2; } if (nameLength > 32) { - memcpy(verifyHash + 32, "...", sizeof("...")); + memcpy(buffer + 32, "...", sizeof("...")); } - PRINTF("name %s\n", verifyHash); + PRINTF("name %s\n", buffer); +} + +static void ctap_ux_on_user_choice(bool confirm, uint16_t idx) { + ctap2UxState = CTAP2_UX_STATE_NONE; + + if (confirm) { + ctap2_get_assertion_confirm(idx); +#ifdef HAVE_NBGL + app_nbgl_status("Login request signed", true, ui_idle, TUNE_SUCCESS); +#else + ui_idle(); +#endif + } else { + ctap2_get_assertion_user_cancel(); +#ifdef HAVE_NBGL + app_nbgl_status("Log in cancelled", false, ui_idle, NBGL_NO_TUNE); +#else + ui_idle(); +#endif + } } #if defined(HAVE_BAGL) @@ -83,12 +101,12 @@ UX_STEP_NOCB(ux_ctap2_get_assertion_flow_user_step, UX_STEP_CB(ux_ctap2_get_assertion_flow_accept_step, pb, - ctap2_get_assertion_confirm(1), + ctap_ux_on_user_choice(true, 1), {&C_icon_validate_14, "Log in"}); UX_STEP_CB(ux_ctap2_get_assertion_flow_refuse_step, pbb, - ctap2_get_assertion_user_cancel(), + ctap_ux_on_user_choice(false, 0), {&C_icon_crossmark, "Reject", "login request"}); UX_FLOW(ux_ctap2_get_assertion_flow, @@ -124,7 +142,7 @@ static void display_next_multiple_flow_state(uint16_t idx) { "Log in user %d/%d", ctap2AssertData->currentCredentialIndex, ctap2AssertData->availableCredentials); - ctap2_ux_display_user_assertion(); + ctap2_ux_display_user_assertion(verifyHash); } static void display_next_state(uint8_t state) { @@ -162,7 +180,7 @@ UX_STEP_INIT(ux_ctap2_get_assertion_multiple_left_border, NULL, NULL, { UX_STEP_CB_INIT(ux_ctap2_get_assertion_multiple_user_border, bnnn_paging, { display_next_state(STATE_VARIABLE); }, - ctap2_get_assertion_confirm(ux_step), + ctap_ux_on_user_choice(true, ux_step), { .title = verifyName, .text = verifyHash, @@ -199,7 +217,7 @@ UX_STEP_NOCB(ux_ctap2_no_assertion_flow_1_step, UX_STEP_CB(ux_ctap2_no_assertion_flow_3_step, pb, - ctap2_get_assertion_confirm(0), + ctap_ux_on_user_choice(true, 0), {&C_icon_back_x, "Close"}); UX_FLOW(ux_ctap2_no_assertion_flow, @@ -208,6 +226,129 @@ UX_FLOW(ux_ctap2_no_assertion_flow, &ux_ctap2_get_assertion_flow_domain_step, &ux_ctap2_no_assertion_flow_3_step); +#elif defined(HAVE_NBGL) + +#include "nbgl_use_case.h" +#include "nbgl_layout.h" + +static nbgl_page_t *pageContext; +#define NB_OF_PAIRS 2 +static const nbgl_layoutTagValue_t pairs[NB_OF_PAIRS] = {{.item = "Website", .value = rpID}, + {.item = "User ID", .value = verifyHash}}; + +#define SELECT_MAX_ID_NB 5 +#define SELECT_ID_BUFFER_SIZE 36 +static char user_id_list[SELECT_MAX_ID_NB][SELECT_ID_BUFFER_SIZE]; +static const char *const bar_texts[SELECT_MAX_ID_NB] = {user_id_list[0], + user_id_list[1], + user_id_list[2], + user_id_list[3], + user_id_list[4]}; +static uint8_t token_list[SELECT_MAX_ID_NB]; +uint8_t available_credentials; +uint8_t selected_credential; + +static void on_user_choice(bool confirm) { + ctap_ux_on_user_choice(confirm, selected_credential); +} + +static void on_user_select(void); + +static void on_user_select_exit() { + // Relauch without changing previously shown user id + ctap2_get_assertion_credential_idx(selected_credential); + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Log in", on_user_choice, on_user_select); +} + +static bool on_user_select_navigation_callback(uint8_t page, nbgl_pageContent_t *content) { + if (page > available_credentials / SELECT_MAX_ID_NB) { + return false; + } + int first_page_index = page * SELECT_MAX_ID_NB + 1; + int i = 0; + while ((i < SELECT_MAX_ID_NB) && ((i + first_page_index) <= available_credentials)) { + ctap2_get_assertion_credential_idx(first_page_index + i); + ctap2_ux_display_user_assertion(user_id_list[i]); + token_list[i] = FIRST_USER_TOKEN + first_page_index + i; + i++; + } + content->tuneId = NBGL_NO_TUNE; + content->type = BARS_LIST; + content->barsList.barTexts = bar_texts; + content->barsList.tokens = token_list; + content->barsList.nbBars = i; + content->barsList.tuneId = TUNE_TAP_CASUAL; + return true; +} + +static void on_user_select_callback(int token, uint8_t index) { + UNUSED(index); + + if (token <= FIRST_USER_TOKEN) { + PRINTF("Should not happen!"); + return; + } + + int idx = token - FIRST_USER_TOKEN; + if (idx > available_credentials) { + PRINTF("Should not happen!"); + return; + } + + PRINTF("User selected %d\n", idx); + + // change the current credential idx and relaunch the review + selected_credential = idx; + ctap2_get_assertion_credential_idx(selected_credential); + ctap2_ux_display_user_assertion(verifyHash); + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Log in", on_user_choice, on_user_select); +} + +static void on_user_select(void) { + // Reuse useCaseSettings which fit our needs + nbgl_useCaseSettings("User IDs", + 0, + (available_credentials - 1 / SELECT_MAX_ID_NB) + 1, + false, + on_user_select_exit, + on_user_select_navigation_callback, + on_user_select_callback); +} + +static void on_no_assertion_user_choice(int token, uint8_t index) { + UNUSED(token); + UNUSED(index); + + nbgl_pageRelease(pageContext); + + ctap2UxState = CTAP2_UX_STATE_NONE; + + ctap2_get_assertion_confirm(0); + ui_idle(); +} + +static void app_nbgl_no_assertion(void) { + snprintf(verifyHash, sizeof(verifyHash), "Login details not found\nfor %s", rpID); + nbgl_pageInfoDescription_t info = { + .bottomButtonStyle = NO_BUTTON_STYLE, + .footerText = NULL, + .centeredInfo.icon = &C_icon_security_key_64px, + .centeredInfo.offsetY = 0, + .centeredInfo.onTop = false, + .centeredInfo.style = LARGE_CASE_INFO, + .centeredInfo.text1 = verifyHash, + .centeredInfo.text2 = "Make sure to log in\nusing the same Ledger\nyou registered with.", + .centeredInfo.text3 = NULL, + .tapActionText = "Tap to dismiss", + .tapActionToken = FIRST_USER_TOKEN, + .topRightStyle = NO_BUTTON_STYLE, + .actionButtonText = NULL, + .tuneId = TUNE_TAP_CASUAL}; + + pageContext = nbgl_pageDrawInfo(&on_no_assertion_user_choice, NULL, &info); + nbgl_refresh(); +} + #endif void ctap2_get_assertion_ux(ctap2_ux_state_t state) { @@ -219,28 +360,45 @@ void ctap2_get_assertion_ux(ctap2_ux_state_t state) { rpID[len] = '\0'; PRINTF("rpId %s\n", rpID); - ctap2_ux_display_user_assertion(); - ctap2UxState = state; #if defined(HAVE_BAGL) - ux_step = 0; - ux_step_count = ctap2AssertData->availableCredentials; +#elif defined(HAVE_NBGL) + selected_credential = 1; + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); +#endif switch (state) { case CTAP2_UX_STATE_GET_ASSERTION: { + ctap2_ux_display_user_assertion(verifyHash); +#if defined(HAVE_BAGL) ux_flow_init(0, ux_ctap2_get_assertion_flow, NULL); break; +#elif defined(HAVE_NBGL) + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Log in", on_user_choice, NULL); +#endif + break; } case CTAP2_UX_STATE_MULTIPLE_ASSERTION: { +#if defined(HAVE_BAGL) + ux_step_count = ctap2AssertData->availableCredentials; ux_flow_init(0, ux_ctap2_get_assertion_multiple_flow, NULL); +#elif defined(HAVE_NBGL) + available_credentials = ctap2AssertData->availableCredentials; + ctap2_get_assertion_credential_idx(selected_credential); + ctap2_ux_display_user_assertion(verifyHash); + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Log in", on_user_choice, on_user_select); +#endif break; } default: { +#if defined(HAVE_BAGL) ux_flow_init(0, ux_ctap2_no_assertion_flow, NULL); +#elif defined(HAVE_NBGL) + app_nbgl_no_assertion(); +#endif break; } } -#endif } diff --git a/src/ctap2_make_credential.c b/src/ctap2_make_credential.c index d5e968f4..035004b9 100644 --- a/src/ctap2_make_credential.c +++ b/src/ctap2_make_credential.c @@ -658,14 +658,10 @@ void ctap2_make_credential_confirm() { uint8_t nonce[CREDENTIAL_NONCE_SIZE]; int status; - ctap2UxState = CTAP2_UX_STATE_NONE; - PRINTF("ctap2_make_credential_confirm\n"); ctap2_send_keepalive_processing(); - ui_idle(); - // Perform User Verification if required if (ctap2RegisterData->pinRequired) { performBuiltInUv(); @@ -716,7 +712,5 @@ void ctap2_make_credential_confirm() { } void ctap2_make_credential_user_cancel() { - ctap2UxState = CTAP2_UX_STATE_NONE; send_cbor_error(&G_io_u2f, ERROR_OPERATION_DENIED); - ui_idle(); } diff --git a/src/ctap2_make_credential_flow.c b/src/ctap2_make_credential_flow.c index b8738a53..b9a282dd 100644 --- a/src/ctap2_make_credential_flow.c +++ b/src/ctap2_make_credential_flow.c @@ -24,10 +24,12 @@ #include "ctap2.h" #include "globals.h" +#include "ui_shared.h" static void ctap2_ux_get_display_user(void) { ctap2_register_data_t *ctap2RegisterData = globals_get_ctap2_register_data(); + // TODO show that user.id is truncated if necessary if (ctap2RegisterData->userStr) { uint8_t nameLength = MIN(ctap2RegisterData->userStrLen, sizeof(verifyHash) - 1); @@ -40,6 +42,26 @@ static void ctap2_ux_get_display_user(void) { } } +static void ctap_ux_on_user_choice(bool confirm) { + ctap2UxState = CTAP2_UX_STATE_NONE; + + if (confirm) { + ctap2_make_credential_confirm(); +#ifdef HAVE_NBGL + app_nbgl_status("Registration details\nsent", true, ui_idle, TUNE_SUCCESS); +#else + ui_idle(); +#endif + } else { + ctap2_make_credential_user_cancel(); +#ifdef HAVE_NBGL + app_nbgl_status("Registration cancelled", false, ui_idle, NBGL_NO_TUNE); +#else + ui_idle(); +#endif + } +} + #if defined(HAVE_BAGL) UX_STEP_NOCB(ux_ctap2_make_cred_flow_first_step, @@ -66,7 +88,7 @@ UX_STEP_NOCB(ux_ctap2_make_cred_flow_user_step, UX_STEP_CB(ux_ctap2_make_cred_flow_accept_step, pb, - ctap2_make_credential_confirm(), + ctap_ux_on_user_choice(true), { &C_icon_validate_14, "Register", @@ -74,7 +96,7 @@ UX_STEP_CB(ux_ctap2_make_cred_flow_accept_step, UX_STEP_CB(ux_ctap2_make_cred_flow_refuse_step, pb, - ctap2_make_credential_user_cancel(), + ctap_ux_on_user_choice(false), { &C_icon_crossmark, "Don't register", @@ -82,7 +104,7 @@ UX_STEP_CB(ux_ctap2_make_cred_flow_refuse_step, UX_STEP_CB(ux_ctap2_make_cred_resident_flow_accept_step, pbb, - ctap2_make_credential_confirm(), + ctap_ux_on_user_choice(true), { &C_icon_validate_14, "Register", @@ -103,6 +125,21 @@ UX_FLOW(ux_ctap2_make_cred_resident_flow, &ux_ctap2_make_cred_resident_flow_accept_step, &ux_ctap2_make_cred_flow_refuse_step); +#elif defined(HAVE_NBGL) + +#include "nbgl_use_case.h" +#include "nbgl_layout.h" + +#define NB_OF_PAIRS 2 +static const nbgl_layoutTagValue_t pairs[NB_OF_PAIRS] = {{ + .item = "Website", + .value = rpID, + }, + { + .item = "User ID", + .value = verifyHash, + }}; + #endif void ctap2_make_credential_ux(void) { @@ -123,5 +160,17 @@ void ctap2_make_credential_ux(void) { (ctap2RegisterData->residentKey ? ux_ctap2_make_cred_resident_flow : ux_ctap2_make_cred_flow), NULL); +#elif defined(HAVE_NBGL) + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + + if (ctap2RegisterData->residentKey) { + app_nbgl_start_review(NB_OF_PAIRS, + pairs, + "Register resident key", + ctap_ux_on_user_choice, + NULL); + } else { + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Register", ctap_ux_on_user_choice, NULL); + } #endif } diff --git a/src/ctap2_reset.c b/src/ctap2_reset.c index d59dad88..d0789e6d 100644 --- a/src/ctap2_reset.c +++ b/src/ctap2_reset.c @@ -33,17 +33,12 @@ void ctap2_reset_handle(u2f_service_t *service, uint8_t *buffer, uint16_t length } void ctap2_reset_confirm() { - ctap2UxState = CTAP2_UX_STATE_NONE; - config_process_ctap2_reset(); G_io_apdu_buffer[0] = ERROR_NONE; send_cbor_response(&G_io_u2f, 1); - ui_idle(); } void ctap2_reset_cancel() { - ctap2UxState = CTAP2_UX_STATE_NONE; send_cbor_error(&G_io_u2f, ERROR_OPERATION_DENIED); - ui_idle(); } diff --git a/src/ctap2_reset_flow.c b/src/ctap2_reset_flow.c index f0afa1a7..81eaf4bc 100644 --- a/src/ctap2_reset_flow.c +++ b/src/ctap2_reset_flow.c @@ -21,6 +21,19 @@ #include "ctap2.h" #include "globals.h" +#include "ui_shared.h" + +static void ctap_ux_on_user_action(bool confirm) { + ctap2UxState = CTAP2_UX_STATE_NONE; + + if (confirm) { + ctap2_reset_confirm(); + ui_idle(); + } else { + ctap2_reset_cancel(); + ui_idle(); + } +} #if defined(HAVE_BAGL) @@ -34,12 +47,12 @@ UX_STEP_NOCB(ux_ctap2_reset_flow_0_step, UX_STEP_CB(ux_ctap2_reset_flow_1_step, pb, - ctap2_reset_confirm(), + ctap_ux_on_user_action(true), {&C_icon_validate_14, "Yes, delete"}); UX_STEP_CB(ux_ctap2_reset_flow_2_step, pb, - ctap2_reset_cancel(), + ctap_ux_on_user_action(false), { &C_icon_crossmark, "No, don't delete", @@ -56,4 +69,22 @@ void ctap2_reset_ux(void) { ux_flow_init(0, ux_ctap2_reset_flow, NULL); } +#elif defined(HAVE_NBGL) +#include "nbgl_use_case.h" + +void ctap2_reset_ux(void) { + ctap2UxState = CTAP2_UX_STATE_RESET; + + io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + + nbgl_useCaseChoice(&C_warning64px, + "Delete saved login\n" + "details for all\n" + "websites?\n", + NULL, + "Yes, delete", + "No, don't delete", + ctap_ux_on_user_action); +} + #endif \ No newline at end of file diff --git a/src/u2f_processing.c b/src/u2f_processing.c index b4844dfd..a8f3d629 100644 --- a/src/u2f_processing.c +++ b/src/u2f_processing.c @@ -400,6 +400,8 @@ static int u2f_process_user_presence_confirmed(void) { /* U2F UX Flows */ /******************************************/ +#if defined(HAVE_BAGL) + static unsigned int u2f_callback_cancel(void) { io_send_sw(SW_PROPRIETARY_INTERNAL); ui_idle(); @@ -472,6 +474,42 @@ UX_FLOW(ux_login_flow, &ux_login_flow_2_step, FLOW_LOOP); +#elif defined(HAVE_NBGL) + +#include "nbgl_use_case.h" + +#define NB_OF_PAIRS 2 +static const nbgl_layoutTagValue_t pairs[NB_OF_PAIRS] = {{ + .item = "Website", + .value = verifyName, + }, + { + .item = "Website ID", + .value = verifyHash, + }}; + +static void on_register_choice(bool confirm) { + if (confirm) { + u2f_process_user_presence_confirmed(); + app_nbgl_status("Registration details\nsent", true, ui_idle, TUNE_SUCCESS); + } else { + io_send_sw(SW_PROPRIETARY_INTERNAL); + app_nbgl_status("Registration cancelled", false, ui_idle, NBGL_NO_TUNE); + } +} + +static void on_login_choice(bool confirm) { + if (confirm) { + u2f_process_user_presence_confirmed(); + app_nbgl_status("Login request signed", true, ui_idle, TUNE_SUCCESS); + } else { + io_send_sw(SW_PROPRIETARY_INTERNAL); + app_nbgl_status("Log in cancelled", false, ui_idle, NBGL_NO_TUNE); + } +} + +#endif + static void u2f_prompt_user_presence(bool enroll, uint8_t *applicationParameter) { UX_WAKE_UP(); @@ -483,11 +521,19 @@ static void u2f_prompt_user_presence(bool enroll, uint8_t *applicationParameter) strlcpy(verifyName, name, sizeof(verifyName)); } +#if defined(HAVE_BAGL) if (enroll) { ux_flow_init(0, ux_register_flow, NULL); } else { ux_flow_init(0, ux_login_flow, NULL); } +#elif defined(HAVE_NBGL) + if (enroll) { + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Register", on_register_choice, NULL); + } else { + app_nbgl_start_review(NB_OF_PAIRS, pairs, "Login", on_login_choice, NULL); + } +#endif } /******************************************/ diff --git a/src/ui_shared.c b/src/ui_shared.c index 974f404e..cc3a2a8a 100644 --- a/src/ui_shared.c +++ b/src/ui_shared.c @@ -31,7 +31,7 @@ static void app_quit(void) { static void display_warning(); static void display_settings(); -static void toogle_settings(); +static void toggle_settings(); UX_STEP_NOCB(ux_settings_enabling_flow_warning_step, bn_paging, @@ -59,7 +59,7 @@ UX_STEP_CB(ux_settings_warning_flow_cancel_step, UX_STEP_CB(ux_settings_enabling_flow_confirm_step, pbb, - toogle_settings(), + toggle_settings(), { &C_icon_validate_14, "Enable", @@ -75,7 +75,7 @@ static void display_warning() { ux_flow_init(0, ux_settings_enabling_flow, NULL); } -static void toogle_settings() { +static void toggle_settings() { if (config_get_rk_enabled()) { config_set_rk_enabled(false); } else { @@ -84,7 +84,7 @@ static void toogle_settings() { display_settings(); } -UX_STEP_CB(ux_settings_flow_1_enabled_step, bn, toogle_settings(), {"Resident keys", "Enabled"}); +UX_STEP_CB(ux_settings_flow_1_enabled_step, bn, toggle_settings(), {"Resident keys", "Enabled"}); UX_STEP_CB(ux_settings_flow_1_disabled_step, bn, display_warning(), {"Resident keys", "Disabled"}); @@ -154,4 +154,256 @@ void ui_idle(void) { ux_flow_init(0, ux_idle_flow, NULL); } -#endif \ No newline at end of file +#elif defined(HAVE_NBGL) + +#include "nbgl_use_case.h" +#include "nbgl_page.h" +#include "nbgl_layout.h" + +// 'About' menu + +static const char *const INFO_TYPES[] = {"Version", "Developer", "Copyright"}; +static const char *const INFO_CONTENTS[] = {APPVERSION, "Ledger", "(c) 2023 Ledger"}; + +#ifdef HAVE_RK_SUPPORT_SETTING + +static nbgl_layoutSwitch_t toggle; +static void ui_menu_settings_page(void); + +static void warning_choice(bool accept) { + if (accept) { + config_set_rk_enabled(true); + app_nbgl_status("Resident keys enabled", true, ui_menu_settings_page, NBGL_NO_TUNE); + } else { + ui_menu_settings_page(); + } +} + +static void settings_callback(int token, uint8_t index) { + UNUSED(index); + switch (token) { + case FIRST_USER_TOKEN: + if (config_get_rk_enabled()) { + config_set_rk_enabled(false); + } else { + nbgl_useCaseChoice(&C_warning64px, + "Enable resident keys?", + "Updating the OS or this app\n" + "will delete login info stored on\n" + "this device, causing login\n" + "issues.", + "Enable", + "Cancel", + warning_choice); + } + break; + default: + PRINTF("Should not happen!"); + break; + } +} +#endif // HAVE_RK_SUPPORT_SETTING + +static bool nav_callback(uint8_t page, nbgl_pageContent_t *content) { + if (page == 0) { + content->type = INFOS_LIST; + content->infosList.nbInfos = 3; + content->infosList.infoTypes = INFO_TYPES; + content->infosList.infoContents = INFO_CONTENTS; + } +#ifdef HAVE_RK_SUPPORT_SETTING + else if (page == 1) { + toggle.text = "Resident keys"; + toggle.subText = + "Stores login info on this\n" + "device's memory and lets you\n" + "login without username.\n\n" + "Caution: Updating the OS or\n" + "this app will delete the stored\n" + "login info, causing login issues\n" + "for connected accounts"; + toggle.token = FIRST_USER_TOKEN; + toggle.tuneId = TUNE_TAP_CASUAL; + toggle.initState = config_get_rk_enabled(); + content->type = SWITCHES_LIST; + content->switchesList.nbSwitches = 1; + content->switchesList.switches = &toggle; + } else { +#endif // HAVE_RK_SUPPORT_SETTING + return false; + } + return true; +} + +static void ui_menu_settings(uint8_t init_page) { + nbgl_useCaseSettings(APPNAME, + init_page, +#ifdef HAVE_RK_SUPPORT_SETTING + 2, +#else + 1, +#endif + false, + ui_idle, + nav_callback, + settings_callback); +} + +static void ui_menu_settings_home(void) { + ui_menu_settings(0); +} + +static void ui_menu_settings_page(void) { + ui_menu_settings(1); +} + +void ui_idle(void) { + nbgl_useCaseHome(APPNAME, + &C_icon_security_key_64px, + "Use this app for two-factor\nauthentication and\npassword-less log ins.", +#ifdef HAVE_RK_SUPPORT_SETTING + true, +#else + false, +#endif + ui_menu_settings_home, + app_quit); +} + +static nbgl_layout_t *layout; +static nbgl_page_t *pageContext; +static nbgl_choiceCallback_t onChoice; +static nbgl_callback_t onSelect; +static nbgl_callback_t onQuit; + +enum { TITLE_TOKEN = FIRST_USER_TOKEN, CHOICE_TOKEN, SELECT_TOKEN, QUIT_TOKEN }; + +static void onActionCallback(int token, uint8_t index) { + if (token == CHOICE_TOKEN && onChoice != NULL) { + // Release the review layout. + nbgl_layoutRelease(layout); + + onChoice(index == 0); + } else if (token == SELECT_TOKEN && onSelect != NULL) { + // Release the review layout. + nbgl_layoutRelease(layout); + + onSelect(); + } else if (token == QUIT_TOKEN && onQuit != NULL) { + // Release the review layout. + nbgl_layoutRelease(layout); + + onQuit(); + } +} + +void app_nbgl_start_review(uint8_t nb_pairs, + const nbgl_layoutTagValue_t *pairs, + const char *confirm_text, + nbgl_choiceCallback_t on_choice, + nbgl_callback_t on_select) { + nbgl_layoutDescription_t layoutDescription; + onChoice = on_choice; + onSelect = on_select; + + layoutDescription.modal = false; + layoutDescription.withLeftBorder = true; + layoutDescription.onActionCallback = onActionCallback; + layoutDescription.tapActionText = NULL; + layoutDescription.ticker.tickerCallback = NULL; + + layout = nbgl_layoutGet(&layoutDescription); + + nbgl_layoutBar_t bar; + bar.text = APPNAME; + bar.subText = NULL; + bar.iconRight = NULL; + bar.iconLeft = NULL; + bar.token = TITLE_TOKEN; + bar.centered = true; + bar.inactive = false; + bar.tuneId = NBGL_NO_TUNE; + nbgl_layoutAddTouchableBar(layout, &bar); + nbgl_layoutAddSeparationLine(layout); + + const nbgl_layoutTagValueList_t tagValueList = {.nbPairs = nb_pairs, + .pairs = pairs, + .smallCaseForValue = false, + .nbMaxLinesForValue = 0, + .wrapping = false}; + + nbgl_layoutAddTagValueList(layout, &tagValueList); + + if (onSelect) { + nbgl_layoutButton_t select_button_info = {.text = "Select another ID", + .icon = NULL, + .token = SELECT_TOKEN, + .style = WHITE_BACKGROUND, + .fittingContent = true, + .onBottom = false, + .tuneId = TUNE_TAP_CASUAL}; + + nbgl_layoutAddButton(layout, &select_button_info); + } + + nbgl_layoutChoiceButtons_t choice_buttons_info = {.bottomText = "Cancel", + .token = CHOICE_TOKEN, + .topText = confirm_text, + .style = ROUNDED_AND_FOOTER_STYLE, + .tuneId = TUNE_TAP_CASUAL}; + nbgl_layoutAddChoiceButtons(layout, &choice_buttons_info); + + nbgl_layoutDraw(layout); + + nbgl_refresh(); +} + +static void tickerCallback(void) { + nbgl_pageRelease(pageContext); + if (onQuit != NULL) { + onQuit(); + } +} + +void app_nbgl_status(const char *message, + bool is_success, + nbgl_callback_t on_quit, + tune_index_e tune) { + if (tune != NBGL_NO_TUNE) { + io_seproxyhal_play_tune(tune); + } + + nbgl_screenTickerConfiguration_t ticker = { + .tickerCallback = &tickerCallback, + .tickerIntervale = 0, // not periodic + .tickerValue = 3000 // 3 seconds + }; + onQuit = on_quit; + + nbgl_pageInfoDescription_t info = {.bottomButtonStyle = NO_BUTTON_STYLE, + .footerText = NULL, + .centeredInfo.icon = &C_round_cross_64px, + .centeredInfo.offsetY = 0, + .centeredInfo.onTop = false, + .centeredInfo.style = LARGE_CASE_INFO, + .centeredInfo.text1 = message, + .centeredInfo.text2 = NULL, + .centeredInfo.text3 = NULL, + .tapActionText = "", + .tapActionToken = QUIT_TOKEN, + .topRightStyle = NO_BUTTON_STYLE, + .actionButtonText = NULL, + .tuneId = TUNE_TAP_CASUAL}; + + if (is_success) { + info.centeredInfo.icon = &C_round_check_64px; + } else { + info.centeredInfo.icon = &C_round_warning_64px; + } + + pageContext = nbgl_pageDrawInfo(&onActionCallback, &ticker, &info); + + nbgl_refresh(); +} + +#endif diff --git a/tests/speculos/conftest.py b/tests/speculos/conftest.py index fde6e084..34ab150f 100644 --- a/tests/speculos/conftest.py +++ b/tests/speculos/conftest.py @@ -32,7 +32,7 @@ BACKENDS = ["speculos"] -DEVICES = ["nanox", "nanosp", "all"] +DEVICES = ["nanox", "nanosp", "stax", "all"] def pytest_addoption(parser): diff --git a/tests/speculos/ctap1_client.py b/tests/speculos/ctap1_client.py index 435cb481..53295a63 100644 --- a/tests/speculos/ctap1_client.py +++ b/tests/speculos/ctap1_client.py @@ -51,11 +51,17 @@ def __init__(self, device, model, navigator, debug=False): self.debug = debug def confirm(self): - instructions = [NavInsID.BOTH_CLICK] + if self.model == "stax": + instructions = [NavInsID.USE_CASE_CHOICE_CONFIRM] + else: + instructions = [NavInsID.BOTH_CLICK] self.navigator.navigate(instructions, screen_change_after_last_instruction=False) def wait_for_return_on_dashboard(self): + if self.model == "stax": + # On Stax tap on the center to dismiss the status message faster + self.navigator.navigate([NavInsID.USE_CASE_STATUS_DISMISS]) self.navigator._backend.wait_for_home_screen() def parse_response(self, response): @@ -102,6 +108,12 @@ def register(self, client_param, app_param, user_accept=True, text = "Register" else: text = "Abort" + elif self.model == "stax": + if user_accept is not None: + if not user_accept: + val_ins = [NavInsID.USE_CASE_CHOICE_REJECT] + else: + val_ins = [NavInsID.USE_CASE_CHOICE_CONFIRM] navigate(self.navigator, user_accept, @@ -158,6 +170,12 @@ def authenticate(self, client_param, app_param, key_handle, text = "Login" else: text = "Abort" + elif self.model == "stax": + if user_accept is not None: + if not user_accept: + val_ins = [NavInsID.USE_CASE_CHOICE_REJECT] + else: + val_ins = [NavInsID.USE_CASE_CHOICE_CONFIRM] navigate(self.navigator, user_accept, diff --git a/tests/speculos/ctap2_client.py b/tests/speculos/ctap2_client.py index 70318e8d..e0fc4bb3 100644 --- a/tests/speculos/ctap2_client.py +++ b/tests/speculos/ctap2_client.py @@ -2,7 +2,7 @@ from typing import Mapping -from ragger.navigator import NavInsID +from ragger.navigator import NavInsID, NavIns from fido2 import cbor from fido2.ctap import CtapError @@ -35,11 +35,21 @@ def __init__(self, device, model, navigator, ctap2_u2f_proxy, debug=False): super().__init__(device) def confirm(self): - instructions = [NavInsID.BOTH_CLICK] + if self.model == "stax": + instructions = [NavInsID.USE_CASE_CHOICE_CONFIRM] + else: + instructions = [NavInsID.BOTH_CLICK] self.navigator.navigate(instructions, screen_change_after_last_instruction=False) def wait_for_return_on_dashboard(self): + if self.model == "stax": + # On Stax tap on the center to dismiss the status message faster + # Ignore if there is nothing that happen (probably already on home screen), + # which is expected for flow without status (reset) + self.navigator.navigate([NavInsID.USE_CASE_STATUS_DISMISS], + screen_change_after_last_instruction=False) + self.navigator._backend.wait_for_home_screen() def send_cbor_nowait(self, cmd, data=None, *, event=None, on_keepalive=None): @@ -134,6 +144,12 @@ def make_credential(self, client_data_hash, rp, user, key_params, text = "Don't register" else: text = "Register$" + elif self.model == "stax": + if user_accept is not None: + if not user_accept: + val_ins = [NavInsID.USE_CASE_CHOICE_REJECT] + else: + val_ins = [NavInsID.USE_CASE_CHOICE_CONFIRM] navigate(self.navigator, user_accept, @@ -208,6 +224,21 @@ def get_assertion(self, rp_id, client_data_hash, allow_list=None, text = "Log in" else: text = "Reject" + elif self.model == "stax": + if user_accept is not None: + if login_type == "none": + val_ins = [NavInsID.TAPPABLE_CENTER_TAP] + + if not user_accept: + val_ins = [NavInsID.USE_CASE_CHOICE_REJECT] + else: + if login_type == "multi" and select_user_idx != 1: + assert select_user_idx <= 5 + val_ins = [NavIns(NavInsID.TOUCH, (200, 350)), + NavIns(NavInsID.TOUCH, (200, 40 + 90 * select_user_idx)), + NavInsID.USE_CASE_CHOICE_CONFIRM] + else: + val_ins = [NavInsID.USE_CASE_CHOICE_CONFIRM] navigate(self.navigator, user_accept, @@ -251,6 +282,12 @@ def reset(self, *, event=None, on_keepalive=None, user_accept=True, text = "Yes, delete" else: text = "No, don't delete" + elif self.model == "stax": + if user_accept is not None: + if not user_accept: + val_ins = [NavInsID.USE_CASE_CHOICE_REJECT] + else: + val_ins = [NavInsID.USE_CASE_CHOICE_CONFIRM] navigate(self.navigator, user_accept, diff --git a/tests/speculos/fido2/test_fido2_screens.py b/tests/speculos/fido2/test_fido2_screens.py index a8bcac8a..8091848e 100644 --- a/tests/speculos/fido2/test_fido2_screens.py +++ b/tests/speculos/fido2/test_fido2_screens.py @@ -8,45 +8,64 @@ from utils import generate_make_credentials_params from utils import HAVE_RK_SUPPORT_SETTING -from ragger.navigator import NavInsID +from ragger.navigator import NavInsID, NavIns @pytest.mark.skipif(not HAVE_RK_SUPPORT_SETTING, reason="settings not enable") def test_fido_screens_settings(client, test_name): - instructions = [] - # Screen 0 -> 1 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 1 -> 2 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 2 -> 3 - instructions.append(NavInsID.RIGHT_CLICK) - # enter settings - instructions.append(NavInsID.BOTH_CLICK) - - # Enable and check "Enabling" warning message - instructions.append(NavInsID.BOTH_CLICK) - # Screen 0 -> 1 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 1 -> 2 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 2 -> 3 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 3 -> 4 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 4 -> 5 - instructions.append(NavInsID.RIGHT_CLICK) - # Confirm - instructions.append(NavInsID.BOTH_CLICK) - - # Disable - instructions.append(NavInsID.BOTH_CLICK) - - # leave settings - # Screen 0 -> 1 - instructions.append(NavInsID.RIGHT_CLICK) - # confirm - instructions.append(NavInsID.BOTH_CLICK) + + if client.model.startswith("nano"): + instructions = [] + # Screen 0 -> 1 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 1 -> 2 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 2 -> 3 + instructions.append(NavInsID.RIGHT_CLICK) + # enter settings + instructions.append(NavInsID.BOTH_CLICK) + + # Enable and check "Enabling" warning message + instructions.append(NavInsID.BOTH_CLICK) + # Screen 0 -> 1 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 1 -> 2 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 2 -> 3 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 3 -> 4 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 4 -> 5 + instructions.append(NavInsID.RIGHT_CLICK) + # Confirm + instructions.append(NavInsID.BOTH_CLICK) + + # Disable + instructions.append(NavInsID.BOTH_CLICK) + + # leave settings + # Screen 0 -> 1 + instructions.append(NavInsID.RIGHT_CLICK) + # confirm + instructions.append(NavInsID.BOTH_CLICK) + else: + instructions = [ + # Enter in the settings + NavInsID.USE_CASE_HOME_SETTINGS, + NavInsID.USE_CASE_SETTINGS_NEXT, + + # Enable and skip "Enabling" message + NavIns(NavInsID.CHOICE_CHOOSE, (1,)), + NavInsID.USE_CASE_CHOICE_CONFIRM, + NavInsID.USE_CASE_STATUS_DISMISS, + + # Disable + NavIns(NavInsID.CHOICE_CHOOSE, (1,)), + + # Leave settings + NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT, + ] client.navigator.navigate_and_compare(TESTS_SPECULOS_DIR, test_name, instructions, screen_change_before_first_instruction=False) diff --git a/tests/speculos/fido2/test_get_info.py b/tests/speculos/fido2/test_get_info.py index b29400fe..9c3230d5 100644 --- a/tests/speculos/fido2/test_get_info.py +++ b/tests/speculos/fido2/test_get_info.py @@ -41,6 +41,10 @@ def test_get_info_aaguid(client): hs = sha256("Ledger FIDO 2 1.0 NanoS+".encode('utf-8')).hexdigest() hs = hs[:32] # Keep only the 16 first bytes assert hs == info.aaguid.hex() + elif client.model == "stax": + hs = sha256("Ledger FIDO 2 1.0 Stax".encode('utf-8')).hexdigest() + hs = hs[:32] # Keep only the 16 first bytes + assert hs == info.aaguid.hex() else: raise ValueError("Unhandled model") diff --git a/tests/speculos/fido2/test_option_rk.py b/tests/speculos/fido2/test_option_rk.py index df903c85..a84123ef 100644 --- a/tests/speculos/fido2/test_option_rk.py +++ b/tests/speculos/fido2/test_option_rk.py @@ -9,7 +9,7 @@ from utils import generate_get_assertion_params from utils import HAVE_RK_SUPPORT_SETTING -from ragger.navigator import NavInsID +from ragger.navigator import NavInsID, NavIns @pytest.mark.skipif(not HAVE_RK_SUPPORT_SETTING, @@ -39,26 +39,42 @@ def enable_rk_option(client): if not HAVE_RK_SUPPORT_SETTING: raise ValueError("rk and setting not enabled") - instructions = [ - # Enter in the settings - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.BOTH_CLICK, - - # Enable and skip "Enabling" message - NavInsID.BOTH_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.RIGHT_CLICK, - NavInsID.BOTH_CLICK, - - # Leave settings - NavInsID.RIGHT_CLICK, - NavInsID.BOTH_CLICK - ] + if client.model.startswith("nano"): + instructions = [ + # Enter in the settings + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.BOTH_CLICK, + + # Enable and skip "Enabling" message + NavInsID.BOTH_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.RIGHT_CLICK, + NavInsID.BOTH_CLICK, + + # Leave settings + NavInsID.RIGHT_CLICK, + NavInsID.BOTH_CLICK + ] + else: + instructions = [ + # Enter in the settings + NavInsID.USE_CASE_HOME_SETTINGS, + NavInsID.USE_CASE_SETTINGS_NEXT, + + # Enable and skip "Enabling" message + NavIns(NavInsID.CHOICE_CHOOSE, (1,)), + NavInsID.USE_CASE_CHOICE_CONFIRM, + NavInsID.USE_CASE_STATUS_DISMISS, + + # Leave settings + NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT, + ] + client.navigator.navigate(instructions, screen_change_before_first_instruction=False) diff --git a/tests/speculos/snapshots/stax/test_authenticate_ok/00000.png b/tests/speculos/snapshots/stax/test_authenticate_ok/00000.png new file mode 100644 index 00000000..4f831132 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_authenticate_ok/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_authenticate_user_refused/00000.png b/tests/speculos/snapshots/stax/test_authenticate_user_refused/00000.png new file mode 100644 index 00000000..4f831132 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_authenticate_user_refused/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_short_id/get/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_short_id/get/00000.png new file mode 100644 index 00000000..c9459bee Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_short_id/get/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_short_id/make/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_short_id/make/00000.png new file mode 100644 index 00000000..90972db4 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_short_id/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/get/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/get/00000.png new file mode 100644 index 00000000..774b948a Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/get/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/make/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/make/00000.png new file mode 100644 index 00000000..9fa51473 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_display_name/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/get/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/get/00000.png new file mode 100644 index 00000000..c9459bee Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/get/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/make/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/make/00000.png new file mode 100644 index 00000000..90972db4 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_icon/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_name/get/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_name/get/00000.png new file mode 100644 index 00000000..43d97aad Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_name/get/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_name/make/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_name/make/00000.png new file mode 100644 index 00000000..eee3ae51 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_name/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/get/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/get/00000.png new file mode 100644 index 00000000..774b948a Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/get/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/make/00000.png b/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/make/00000.png new file mode 100644 index 00000000..9fa51473 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido2_screens_user_name_and_display_name/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00000.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00000.png new file mode 100644 index 00000000..3b0c2b11 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00001.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00001.png new file mode 100644 index 00000000..95a58ef2 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00002.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00002.png new file mode 100644 index 00000000..422f08df Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00003.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00003.png new file mode 100644 index 00000000..a70b2888 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00003.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00004.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00004.png new file mode 100644 index 00000000..643f1da5 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00004.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00005.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00005.png new file mode 100644 index 00000000..3da7058c Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00005.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00006.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00006.png new file mode 100644 index 00000000..422f08df Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00006.png differ diff --git a/tests/speculos/snapshots/stax/test_fido_screens_settings/00007.png b/tests/speculos/snapshots/stax/test_fido_screens_settings/00007.png new file mode 100644 index 00000000..3b0c2b11 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_fido_screens_settings/00007.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion/00000.png b/tests/speculos/snapshots/stax/test_get_assertion/00000.png new file mode 100644 index 00000000..e422a642 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00000.png new file mode 100644 index 00000000..fec1390c Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00001.png b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00001.png new file mode 100644 index 00000000..ec92e9bb Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00002.png b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00002.png new file mode 100644 index 00000000..3a7b8238 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_allow_list/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_duplicate_allow_list_entries/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_duplicate_allow_list_entries/00000.png new file mode 100644 index 00000000..e422a642 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_duplicate_allow_list_entries/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_no_credentials/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_no_credentials/00000.png new file mode 100644 index 00000000..649cbc24 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_no_credentials/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_user_refused/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_user_refused/00000.png new file mode 100644 index 00000000..e422a642 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_user_refused/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_uv/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_uv/00000.png new file mode 100644 index 00000000..e422a642 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_uv/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_wrong_id/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_wrong_id/00000.png new file mode 100644 index 00000000..649cbc24 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_wrong_id/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_get_assertion_wrong_rp/00000.png b/tests/speculos/snapshots/stax/test_get_assertion_wrong_rp/00000.png new file mode 100644 index 00000000..a39b5049 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_get_assertion_wrong_rp/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential/00000.png b/tests/speculos/snapshots/stax/test_make_credential/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential_certificate/00000.png b/tests/speculos/snapshots/stax/test_make_credential_certificate/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential_certificate/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential_exclude_list/00000.png b/tests/speculos/snapshots/stax/test_make_credential_exclude_list/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential_exclude_list/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential_up/00000.png b/tests/speculos/snapshots/stax/test_make_credential_up/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential_up/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential_user_refused/00000.png b/tests/speculos/snapshots/stax/test_make_credential_user_refused/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential_user_refused/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_make_credential_uv/00000.png b/tests/speculos/snapshots/stax/test_make_credential_uv/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_make_credential_uv/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_allow_list/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_allow_list/00000.png new file mode 100644 index 00000000..ba399e6b Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_allow_list/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_rk/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_rk/00000.png new file mode 100644 index 00000000..ba399e6b Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/get_rk/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/make/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/make/00000.png new file mode 100644 index 00000000..95d136f3 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/0/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00000.png new file mode 100644 index 00000000..62620c05 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00001.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00001.png new file mode 100644 index 00000000..4ccfab54 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00002.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00002.png new file mode 100644 index 00000000..62620c05 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_allow_list/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00000.png new file mode 100644 index 00000000..62620c05 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00001.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00001.png new file mode 100644 index 00000000..4ccfab54 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00002.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00002.png new file mode 100644 index 00000000..62620c05 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/get_rk/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/make/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/make/00000.png new file mode 100644 index 00000000..9b0d559e Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/1/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00000.png new file mode 100644 index 00000000..4e39ed60 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00001.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00001.png new file mode 100644 index 00000000..c438d024 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00002.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00002.png new file mode 100644 index 00000000..4e39ed60 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_allow_list/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00000.png new file mode 100644 index 00000000..4e39ed60 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00001.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00001.png new file mode 100644 index 00000000..c438d024 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00002.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00002.png new file mode 100644 index 00000000..4e39ed60 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/get_rk/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/make/00000.png b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/make/00000.png new file mode 100644 index 00000000..88155763 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_get_assertion/2/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_make_cred_exclude_refused/00000.png b/tests/speculos/snapshots/stax/test_option_rk_make_cred_exclude_refused/00000.png new file mode 100644 index 00000000..e987a9ff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_make_cred_exclude_refused/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/get_assertion/00000.png b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/get_assertion/00000.png new file mode 100644 index 00000000..37106758 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/get_assertion/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/make/00000.png b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/make/00000.png new file mode 100644 index 00000000..27ee25b5 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/1/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/get_assertion/00000.png b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/get_assertion/00000.png new file mode 100644 index 00000000..567b6ee3 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/get_assertion/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/make/00000.png b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/make/00000.png new file mode 100644 index 00000000..55e66354 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_option_rk_overwrite_get_assertion/2/make/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_register_ok/00000.png b/tests/speculos/snapshots/stax/test_register_ok/00000.png new file mode 100644 index 00000000..8d190f17 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_register_ok/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_register_user_refused/00000.png b/tests/speculos/snapshots/stax/test_register_user_refused/00000.png new file mode 100644 index 00000000..8d190f17 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_register_user_refused/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_reset/False/00000.png b/tests/speculos/snapshots/stax/test_reset/False/00000.png new file mode 100644 index 00000000..bf508056 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_reset/False/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_reset/True/00000.png b/tests/speculos/snapshots/stax/test_reset/True/00000.png new file mode 100644 index 00000000..bf508056 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_reset/True/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/0_Binance/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/0_Binance/00000.png new file mode 100644 index 00000000..26953251 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/0_Binance/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/10_Fedora/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/10_Fedora/00000.png new file mode 100644 index 00000000..45d1635d Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/10_Fedora/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/11_Gandi/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/11_Gandi/00000.png new file mode 100644 index 00000000..e2a1f529 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/11_Gandi/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/12_GitHub/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/12_GitHub/00000.png new file mode 100644 index 00000000..f895eae1 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/12_GitHub/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/13_GitLab/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/13_GitLab/00000.png new file mode 100644 index 00000000..88ce6c14 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/13_GitLab/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/14_Google/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/14_Google/00000.png new file mode 100644 index 00000000..b93b3405 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/14_Google/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/15_Keeper/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/15_Keeper/00000.png new file mode 100644 index 00000000..e5bfaf2b Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/15_Keeper/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/16_LastPass/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/16_LastPass/00000.png new file mode 100644 index 00000000..f7520db2 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/16_LastPass/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/17_Slush Pool/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/17_Slush Pool/00000.png new file mode 100644 index 00000000..b26be14d Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/17_Slush Pool/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/18_Stripe/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/18_Stripe/00000.png new file mode 100644 index 00000000..be1b674e Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/18_Stripe/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/19_u2f.bin.coffee/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/19_u2f.bin.coffee/00000.png new file mode 100644 index 00000000..1416629d Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/19_u2f.bin.coffee/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/1_Bitbucket/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/1_Bitbucket/00000.png new file mode 100644 index 00000000..acde8ed5 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/1_Bitbucket/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/20_webauthn.bin.coffee/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/20_webauthn.bin.coffee/00000.png new file mode 100644 index 00000000..7af877bd Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/20_webauthn.bin.coffee/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/21_WebAuthn.io/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/21_WebAuthn.io/00000.png new file mode 100644 index 00000000..23f7aa08 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/21_WebAuthn.io/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/22_WebAuthn.me/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/22_WebAuthn.me/00000.png new file mode 100644 index 00000000..42d8c9b9 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/22_WebAuthn.me/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/23_demo.yubico.com/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/23_demo.yubico.com/00000.png new file mode 100644 index 00000000..733bcc81 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/23_demo.yubico.com/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/2_Bitfinex/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/2_Bitfinex/00000.png new file mode 100644 index 00000000..c3fb8983 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/2_Bitfinex/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/3_Bitwarden/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/3_Bitwarden/00000.png new file mode 100644 index 00000000..f89d7b3d Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/3_Bitwarden/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/4_Coinbase/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/4_Coinbase/00000.png new file mode 100644 index 00000000..a707f335 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/4_Coinbase/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/5_Dashlane/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/5_Dashlane/00000.png new file mode 100644 index 00000000..f929e484 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/5_Dashlane/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/6_Dropbox/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/6_Dropbox/00000.png new file mode 100644 index 00000000..15c2ca8a Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/6_Dropbox/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/7_Dropbox/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/7_Dropbox/00000.png new file mode 100644 index 00000000..ac24a0a7 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/7_Dropbox/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/8_Duo/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/8_Duo/00000.png new file mode 100644 index 00000000..6fef6aec Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/8_Duo/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/9_FastMail/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/9_FastMail/00000.png new file mode 100644 index 00000000..ead1a1f3 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/log/9_FastMail/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/0_Binance/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/0_Binance/00000.png new file mode 100644 index 00000000..f2f92145 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/0_Binance/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/10_Fedora/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/10_Fedora/00000.png new file mode 100644 index 00000000..2c4321f5 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/10_Fedora/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/11_Gandi/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/11_Gandi/00000.png new file mode 100644 index 00000000..fddc2c99 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/11_Gandi/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/12_GitHub/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/12_GitHub/00000.png new file mode 100644 index 00000000..b8c22b2c Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/12_GitHub/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/13_GitLab/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/13_GitLab/00000.png new file mode 100644 index 00000000..715858c1 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/13_GitLab/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/14_Google/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/14_Google/00000.png new file mode 100644 index 00000000..4acef417 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/14_Google/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/15_Keeper/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/15_Keeper/00000.png new file mode 100644 index 00000000..2e5aabb9 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/15_Keeper/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/16_LastPass/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/16_LastPass/00000.png new file mode 100644 index 00000000..011901f0 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/16_LastPass/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/17_Slush Pool/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/17_Slush Pool/00000.png new file mode 100644 index 00000000..c4ec1fff Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/17_Slush Pool/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/18_Stripe/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/18_Stripe/00000.png new file mode 100644 index 00000000..7a4d8a94 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/18_Stripe/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/19_u2f.bin.coffee/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/19_u2f.bin.coffee/00000.png new file mode 100644 index 00000000..4ff13e7f Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/19_u2f.bin.coffee/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/1_Bitbucket/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/1_Bitbucket/00000.png new file mode 100644 index 00000000..423cfd3a Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/1_Bitbucket/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/20_webauthn.bin.coffee/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/20_webauthn.bin.coffee/00000.png new file mode 100644 index 00000000..733a1ccf Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/20_webauthn.bin.coffee/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/21_WebAuthn.io/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/21_WebAuthn.io/00000.png new file mode 100644 index 00000000..fdc9675f Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/21_WebAuthn.io/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/22_WebAuthn.me/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/22_WebAuthn.me/00000.png new file mode 100644 index 00000000..0dcccf36 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/22_WebAuthn.me/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/23_demo.yubico.com/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/23_demo.yubico.com/00000.png new file mode 100644 index 00000000..316ea048 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/23_demo.yubico.com/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/2_Bitfinex/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/2_Bitfinex/00000.png new file mode 100644 index 00000000..f63cd614 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/2_Bitfinex/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/3_Bitwarden/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/3_Bitwarden/00000.png new file mode 100644 index 00000000..5cd86976 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/3_Bitwarden/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/4_Coinbase/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/4_Coinbase/00000.png new file mode 100644 index 00000000..fa8f1405 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/4_Coinbase/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/5_Dashlane/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/5_Dashlane/00000.png new file mode 100644 index 00000000..8840a0d4 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/5_Dashlane/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/6_Dropbox/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/6_Dropbox/00000.png new file mode 100644 index 00000000..009d565d Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/6_Dropbox/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/7_Dropbox/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/7_Dropbox/00000.png new file mode 100644 index 00000000..da4622d5 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/7_Dropbox/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/8_Duo/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/8_Duo/00000.png new file mode 100644 index 00000000..86819f52 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/8_Duo/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/9_FastMail/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/9_FastMail/00000.png new file mode 100644 index 00000000..965d26a3 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_fido_known_list/reg/9_FastMail/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_idle/00000.png b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00000.png new file mode 100644 index 00000000..3b0c2b11 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00000.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_idle/00001.png b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00001.png new file mode 100644 index 00000000..95a58ef2 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00001.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_idle/00002.png b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00002.png new file mode 100644 index 00000000..422f08df Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00002.png differ diff --git a/tests/speculos/snapshots/stax/test_u2f_screens_idle/00003.png b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00003.png new file mode 100644 index 00000000..3b0c2b11 Binary files /dev/null and b/tests/speculos/snapshots/stax/test_u2f_screens_idle/00003.png differ diff --git a/tests/speculos/u2f/test_u2f_screens.py b/tests/speculos/u2f/test_u2f_screens.py index 01ca8a95..44303170 100644 --- a/tests/speculos/u2f/test_u2f_screens.py +++ b/tests/speculos/u2f/test_u2f_screens.py @@ -9,22 +9,29 @@ from utils import HAVE_RK_SUPPORT_SETTING -def test_u2f_screens_idle(client, test_name): +def test_u2f_screens_idle(client, test_name, firmware): # Refresh navigator screen content reference time.sleep(0.1) client.navigator._backend.get_current_screen_content() instructions = [] - # Screen 0 -> 1 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 1 -> 2 - instructions.append(NavInsID.RIGHT_CLICK) - # Screen 2 -> 3 - instructions.append(NavInsID.RIGHT_CLICK) - - if HAVE_RK_SUPPORT_SETTING: - # Screen 3 -> 4 + if firmware.device.startswith("nano"): + # Screen 0 -> 1 instructions.append(NavInsID.RIGHT_CLICK) + # Screen 1 -> 2 + instructions.append(NavInsID.RIGHT_CLICK) + # Screen 2 -> 3 + instructions.append(NavInsID.RIGHT_CLICK) + + if HAVE_RK_SUPPORT_SETTING: + # Screen 3 -> 4 + instructions.append(NavInsID.RIGHT_CLICK) + else: + instructions = [ + NavInsID.USE_CASE_HOME_SETTINGS, + NavInsID.USE_CASE_SETTINGS_NEXT, + NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT + ] client.navigator.navigate_and_compare(TESTS_SPECULOS_DIR, test_name, instructions, screen_change_before_first_instruction=False) diff --git a/tests/speculos/utils.py b/tests/speculos/utils.py index b2932f1f..d9c752b3 100644 --- a/tests/speculos/utils.py +++ b/tests/speculos/utils.py @@ -7,6 +7,8 @@ from fido2.utils import sha256 from fido2.webauthn import AttestedCredentialData +from ragger.navigator import NavIns, NavInsID + # Application build configuration HAVE_NO_RESET_GENERATION_INCREMENT = True HAVE_RK_SUPPORT_SETTING = True @@ -16,26 +18,6 @@ "101112131415161718191a1b1c1d1e1f") -CRED_PARAMS = [ - ("webctap.myservice.com", - bytes.fromhex("000102030405060708090a0b0c0d0e0f" - "101112131415161718191a1b1c1d1e1f"), - "My user name"), - ("webctap.myservice_1.com", - bytes.fromhex("00000000000000000000000000000000" - "00000000000000000000000000000001"), - "My user 1 name"), - ("webctap.myservice_2.com", - bytes.fromhex("00000000000000000000000000000000" - "00000000000000000000000000000002"), - "My user 2 name"), - ("webctap.myservice_3.com", - bytes.fromhex("00000000000000000000000000000000" - "00000000000000000000000000000003"), - "My user 3 name") -] - - def prepare_apdu(cla=0, ins=0, p1=0, p2=0, data=b""): size = len(data) size_h = size >> 16 & 0xFF @@ -60,7 +42,16 @@ def generate_make_credentials_params(ref=None): user_id = generate_random_bytes(64) user_name = None else: - rp_id, user_id, user_name = CRED_PARAMS[ref] + if ref == 0: + rp_id = "webctap.myservice.com" + user_id = bytes.fromhex("000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f") + user_name = "My user name" + else: + rp_id = f"webctap.myservice_{ref}.com" + user_id = bytes.fromhex("00000000000000000000000000000000" + f"0000000000000000000000000000000{ref}") + user_name = f"My user {ref} name" client_data_hash = generate_random_bytes(32) rp = {"id": rp_id} @@ -163,14 +154,22 @@ def navigate(navigator, if user_accept is not None: # Over U2F endpoint (but not over HID) the device needs the # response to be retrieved before continuing the UX flow. - navigator.navigate_until_text_and_compare( - nav_ins, - val_ins, - text, - root, - test_name, - screen_change_after_last_instruction=False) + + if text: + navigator.navigate_until_text_and_compare( + nav_ins, + val_ins, + text, + root, + test_name, + screen_change_after_last_instruction=False) + else: + navigator.navigate_and_compare( + root, + test_name, + val_ins, + screen_change_after_last_instruction=False) elif check_cancel: - navigator.navigate([nav_ins], + navigator.navigate([NavIns(NavInsID.WAIT, (0.1,))], screen_change_after_last_instruction=False)