From cc62502ab182c4f38f85b67b52d1f4ecf6076d2b Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Sun, 30 Mar 2025 23:51:38 +0200 Subject: [PATCH] test fixes --- shared/msgsign.py | 14 ++++---------- shared/teleport.py | 34 +++++++++++++--------------------- testing/conftest.py | 5 +++-- testing/run_sim_tests.py | 2 +- testing/test_bbqr.py | 6 ++---- testing/test_ephemeral.py | 1 - testing/test_multisig.py | 1 - testing/test_nfc.py | 17 ++++------------- testing/test_notes.py | 1 - testing/test_pwsave.py | 1 - testing/test_seed_xor.py | 1 - testing/test_teleport.py | 17 ++++++++--------- testing/test_vdisk.py | 2 +- 13 files changed, 36 insertions(+), 66 deletions(-) diff --git a/shared/msgsign.py b/shared/msgsign.py index 4a080cd0..ec7eb381 100644 --- a/shared/msgsign.py +++ b/shared/msgsign.py @@ -9,8 +9,9 @@ from ubinascii import unhexlify as a2b_hex from uhashlib import sha256 from public_constants import MSG_SIGNING_MAX_LENGTH from public_constants import AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH -from charcodes import KEY_QR, KEY_NFC, KEY_ENTER, KEY_CANCEL -from ux import ux_show_story, OK, X, ux_enter_bip32_index +from charcodes import KEY_QR, KEY_NFC, KEY_CANCEL +from ux import (ux_show_story, OK, ux_enter_bip32_index, ux_input_text, the_ux, + import_export_prompt, ux_aborted) from utils import problem_file_line, to_ascii_printable, show_single_address from files import CardSlot, CardMissingError, needs_microsd @@ -202,8 +203,6 @@ def sign_export_contents(content_list, deriv, addr_fmt, pk=None): def verify_signed_file_digest(msg): # Look inside a list of hashs and file names, and # verify at their actual hashes and return list of issues if any. - from files import CardSlot - parsed_msg = parse_signature_file_msg(msg) if not parsed_msg: # not our format @@ -238,8 +237,6 @@ def verify_signed_file_digest(msg): return err, warn def write_sig_file(content_list, derive=None, addr_fmt=AF_CLASSIC, pk=None, sig_name=None): - from glob import dis - if derive is None: ct = chains.current_chain().b44_cointype derive = "m/44'/%d'/0'/0/0" % ct @@ -405,7 +402,6 @@ def sign_message_digest(digest, subpath, prompt, addr_fmt=AF_CLASSIC, pk=None): async def ux_sign_msg(txt, approved_cb=None, kill_menu=True): from menu import MenuSystem, MenuItem - from ux import the_ux async def done(_1, _2, item): from auth import approve_msg_sign @@ -424,8 +420,6 @@ async def ux_sign_msg(txt, approved_cb=None, kill_menu=True): the_ux.push(MenuSystem(rv)) async def msg_signing_done(signature, address, text): - from ux import import_export_prompt - ch = await import_export_prompt("Signed Msg", is_import=False, no_qr=not version.has_qwerty) if ch == KEY_CANCEL: @@ -446,11 +440,11 @@ async def sign_with_own_address(subpath, addr_fmt): # used for cases where we already have the key picked, but need the message: # * address_explorer custom path # * positive ownership test - from glob import dis to_sign = await ux_input_text("", scan_ok=True, prompt="Enter MSG") # max len is 100 only here if not to_sign: return + from auth import approve_msg_sign await approve_msg_sign(to_sign, subpath, addr_fmt, approved_cb=msg_signing_done, kill_menu=True) async def sd_sign_msg_done(signature, address, text, base=None, orig_path=None, diff --git a/shared/teleport.py b/shared/teleport.py index f4cb4af3..9d6ca870 100644 --- a/shared/teleport.py +++ b/shared/teleport.py @@ -3,12 +3,13 @@ # teleport.py - Magically transport extremely sensitive data between the # secure environment of two Q's. # -import sys, uzlib, ngu, aes256ctr, bip39, json, stash -from utils import problem_file_line, B2A, xfp2str, deserialize_secret, keypath_to_str +import ngu, aes256ctr, bip39, json, ndef, chains +from io import BytesIO +from utils import xfp2str, deserialize_secret from ubinascii import unhexlify as a2b_hex from ubinascii import hexlify as b2a_hex from glob import settings -from ux import ux_show_story, ux_confirm, show_qr_code, the_ux, ux_dramatic_pause +from ux import ux_show_story, ux_confirm, the_ux, ux_dramatic_pause from ux_q1 import show_bbqr_codes, QRScannerInteraction, ux_input_text from charcodes import KEY_QR, KEY_NFC, KEY_CANCEL from bbqr import b32encode, b32decode @@ -16,6 +17,7 @@ from menu import MenuItem, MenuSystem from notes import NoteContentBase from sffile import SFFile from multisig import MultisigWallet +from stash import SensitiveValues, SecretStash, blank_object, bip39_passphrase # One page github-hosted static website that shows QR based on URL contents pushed by NFC KT_DOMAIN = 'keyteleport.com' @@ -35,7 +37,6 @@ def short_bbqr(type_code, data): async def nfc_push_kt(qrdata): # NFC push to send them to our QR-rendering website - import ndef url = KT_DOMAIN + '#' + qrdata @@ -132,8 +133,6 @@ async def tk_show_payload(type_code, payload, title, msg, cta=None): # show the QR and/or NFC # - MAYBE: make easier/faster to pick NFC from QR screen and vice-versa from glob import NFC - from bbqr import num_qr_needed - from ux_q1 import show_bbqr_codes hints = KEY_QR if NFC and len(payload) < NFC_SIZE_LIMIT: @@ -218,7 +217,7 @@ async def kt_do_send(rx_pubkey, dtype, raw=None, obj=None, prefix=b'', rx_label= if not prefix: # not PSBT case ... reset menus, we are deep! - from flow import goto_top_menu + from actions import goto_top_menu goto_top_menu() def pick_noid_key(): @@ -308,7 +307,6 @@ async def kt_accept_values(dtype, raw): - `v` - seed vault export (JSON: one secret key but includes includes name, source of key) - `p` - binary PSBT to be signed ''' - from chains import current_chain, slip32_deserialize from flow import has_se_secrets, goto_top_menu enc = None @@ -324,9 +322,9 @@ async def kt_accept_values(dtype, raw): # it's an XPRV, but in binary.. some extra data we throw away here; sigh # XXX no way to send this .. but was thinking of address explorer txt = ngu.codecs.b58_encode(raw) - node, ch, _, _ = slip32_deserialize(txt) - assert ch.name == chains.current_chain.name, 'wrong chain' - enc = stash.SecretStash.encode(node=node) + node, ch, _, _ = chains.slip32_deserialize(txt) + assert ch.name == chains.current_chain().name, 'wrong chain' + enc = SecretStash.encode(xprv=node) elif dtype == 'p': # raw PSBT -- much bigger more complex @@ -473,7 +471,6 @@ class SecretPickerMenu(MenuSystem): self.rx_pubkey = rx_pubkey from flow import word_based_seed, is_tmp - from stash import bip39_passphrase has_notes = bool(NoteContentBase.count()) has_ms = bool(settings.get('multisig', False)) has_sv = bool(settings.get('seedvault', False)) @@ -513,7 +510,6 @@ class SecretPickerMenu(MenuSystem): async def pick_note_submenu(self, *a): # Make a submenu to select a single note/password - rv = [] for note in NoteContentBase.get_all(): rv.append(MenuItem('%d: %s' % (note.idx+1, note.title), f=self.picked_note, arg=note)) @@ -547,9 +543,8 @@ class SecretPickerMenu(MenuSystem): async def share_master_secret(self, _, _2, item): # altho menu items look different we are sharing same thing: # - up to 72 bytes from secure elements - from stash import SensitiveValues, SecretStash, blank_object - with stash.SensitiveValues(bypass_tmp=False, enforce_delta=True) as sv: + with SensitiveValues(bypass_tmp=False, enforce_delta=True) as sv: raw = bytearray(sv.secret) xfp = xfp2str(sv.get_xfp()) @@ -573,16 +568,16 @@ class SecretPickerMenu(MenuSystem): async def kt_send_psbt(psbt, psbt_len=None, post_signing=False): - # We just finishing adding our signature to an incomplete PSBT. + # We just finished adding our signature to an incomplete PSBT. # User wants to send to one or more other senders for them to complete signing. # who remains to sign? look at inputs ms = psbt.active_multisig - all_xfps = [x for x,p in ms.get_xfp_paths()] + all_xfps = [x for x,*p in ms.get_xfp_paths()] need = [x for x in psbt.multisig_xfps_needed() if x in all_xfps] # maybe it's not really a PSBT where we know the other signers? might be - # a weird coinjoin we dont fully understand + # a weird coinjoin we don't fully understand if not need: if not post_signing: await ux_show_story("No more signers?") @@ -612,8 +607,6 @@ async def kt_send_psbt(psbt, psbt_len=None, post_signing=False): if not psbt_len: # we need it serialized, might have only saved into Base64 or something - from io import BytesIO - with BytesIO() as fd: psbt.serialize(fd) # need prog bar? @@ -750,6 +743,5 @@ async def kt_send_file_psbt(*a): return await kt_send_psbt(psbt, psbt_len=psbt_len) - # EOF diff --git a/testing/conftest.py b/testing/conftest.py index d645e57c..65185d21 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -2518,7 +2518,7 @@ def build_test_seed_vault(): # useful fixtures from test_backup import backup_system -from test_bbqr import readback_bbqr, render_bbqr, readback_bbqr_ll, try_sign_bbqr +from test_bbqr import readback_bbqr, render_bbqr, readback_bbqr_ll, try_sign_bbqr, split_scan_bbqr from test_bip39pw import set_bip39_pw from test_drv_entro import derive_bip85_secret, activate_bip85_ephemeral from test_ephemeral import generate_ephemeral_words, import_ephemeral_xprv, goto_eph_seed_menu @@ -2527,7 +2527,8 @@ from test_ephemeral import verify_ephemeral_secret_ui, get_identity_story, get_s from test_msg import verify_msg_sign_story, sign_msg_from_text, msg_sign_export, sign_msg_from_address from test_multisig import import_ms_wallet, make_multisig, offer_ms_import, fake_ms_txn from test_multisig import make_ms_address, clear_ms, make_myself_wallet, import_multisig -from test_nfc import try_sign_nfc +from test_notes import need_some_notes, need_some_passwords +from test_nfc import try_sign_nfc, ndef_parse_txn_psbt from test_se2 import goto_trick_menu, clear_all_tricks, new_trick_pin, se2_gate, new_pin_confirmed from test_seed_xor import restore_seed_xor from test_ux import pass_word_quiz, word_menu_entry, enable_hw_ux diff --git a/testing/run_sim_tests.py b/testing/run_sim_tests.py index e499d1b3..25bf88b6 100644 --- a/testing/run_sim_tests.py +++ b/testing/run_sim_tests.py @@ -284,7 +284,7 @@ def main(): test_args = ["--eject"] + DEFAULT_SIMULATOR_ARGS + ["--set", "vidsk=1"] if test_module == "test_bip39pw.py": test_args = [] - if test_module in ["test_unit.py", "test_se2.py", "test_backup.py"]: + if test_module in ["test_unit.py", "test_se2.py", "test_backup.py", "test_teleport.py"]: # test_nvram_mk4 needs to run without --eff # se2 duress wallet activated as ephemeral seed requires proper `settings.load` test_args = ["--set", "nfc=1"] diff --git a/testing/test_bbqr.py b/testing/test_bbqr.py index b95d473d..c84494dc 100644 --- a/testing/test_bbqr.py +++ b/testing/test_bbqr.py @@ -407,10 +407,7 @@ KDOloGMDU3fv+Y3NRSe17SoO4uSKo9IUU2+baJ/pqaHZBuvmW6j5nnv/N4M5BCVawiUig/qzExZpFsA7 @pytest.mark.qrcode @pytest.mark.manual @pytest.mark.parametrize("i", range(1,25)) -def test_qr_sizes(i, scan_a_qr, readback_bbqr, press_select, need_keypress, - qr_quality_check, render_bbqr, goto_home, use_regtest, cap_story, - decode_psbt_with_bitcoind, decode_with_bitcoind, fake_txn, dev, - start_sign, end_sign, press_cancel, cap_screen_qr, try_sign_bbqr): +def test_qr_sizes(i, dev, fake_txn, press_cancel, cap_screen_qr, try_sign_bbqr): # QRs from version 10 to version 25, everything from v26(included) and above is BBQR # only v17 contains 2 lines of txid @@ -418,5 +415,6 @@ def test_qr_sizes(i, scan_a_qr, readback_bbqr, press_select, need_keypress, try_sign_bbqr(psbt, type_code="P") cap_screen_qr() + press_cancel() # EOF diff --git a/testing/test_ephemeral.py b/testing/test_ephemeral.py index 1f05cd6e..a2cae03f 100644 --- a/testing/test_ephemeral.py +++ b/testing/test_ephemeral.py @@ -8,7 +8,6 @@ from constants import simulator_fixed_tpub, simulator_fixed_xfp, simulator_fixed from constants import simulator_fixed_words, simulator_fixed_tprv from ckcc.protocol import CCProtocolPacker from txn import fake_txn -from test_ux import word_menu_entry from bip32 import BIP32Node from helpers import xfp2str, a2b_hex from charcodes import KEY_CLEAR, KEY_NFC diff --git a/testing/test_multisig.py b/testing/test_multisig.py index 78d05b26..ddd47b98 100644 --- a/testing/test_multisig.py +++ b/testing/test_multisig.py @@ -3314,7 +3314,6 @@ def test_bare_cc_ms_qr_import(N, make_multisig, scan_a_qr, clear_ms, goto_home, title, story = cap_story() assert title == 'Simple Text' - assert "We can't do any more with it." in story press_cancel() diff --git a/testing/test_nfc.py b/testing/test_nfc.py index 1352c663..73dd1eb9 100644 --- a/testing/test_nfc.py +++ b/testing/test_nfc.py @@ -149,7 +149,7 @@ def test_ndef_ccfile(ccfile, load_shared_mod): @pytest.fixture def try_sign_nfc(cap_story, pick_menu_item, goto_home, need_keypress, sim_exec, nfc_read, nfc_write, nfc_block4rf, press_select, - press_cancel, press_nfc, nfc_read_txn): + press_cancel, press_nfc, nfc_read_txn, ndef_parse_txn_psbt): # like "try_sign" but use NFC to send/receive PSBT/results @@ -263,7 +263,7 @@ def try_sign_nfc(cap_story, pick_menu_item, goto_home, need_keypress, press_select() txid = None - got_psbt, got_txn, got_txid = ndef_parse_txn_psbt(contents, txid, encoding, expect_finalize) + got_psbt, got_txn, got_txid = ndef_parse_txn_psbt(contents, txid, ip, expect_finalize) return ip, (got_psbt or got_txn), (txid or got_txid) @@ -275,7 +275,7 @@ def try_sign_nfc(cap_story, pick_menu_item, goto_home, need_keypress, @pytest.fixture def ndef_parse_txn_psbt(press_cancel): - def doit(contents, txid=None, encoding='binary', expect_finalized=True): + def doit(contents, txid=None, orig=None, expect_finalized=True): # from NFC data read, what did we get? got_txid = None got_txn = None @@ -317,15 +317,6 @@ def ndef_parse_txn_psbt(press_cancel): open("debug/nfc-result.psbt", 'wb').write(result) - if 0: - # check output encoding matches input - if encoding == 'hex' or finalize: - result = a2b_hex(result.strip()) - elif encoding == 'base64': - result = b64decode(result) - else: - assert encoding == 'binary' - # read back final product if got_txn: from ctransaction import CTransaction @@ -340,7 +331,7 @@ def ndef_parse_txn_psbt(press_cancel): assert got_psbt[0:5] == b'psbt\xff' from psbt import BasicPSBT - was = BasicPSBT().parse(ip) + was = BasicPSBT().parse(orig) now = BasicPSBT().parse(got_psbt) assert was.txn == now.txn assert was != now diff --git a/testing/test_notes.py b/testing/test_notes.py index b46199ef..af33cfb2 100644 --- a/testing/test_notes.py +++ b/testing/test_notes.py @@ -6,7 +6,6 @@ import pytest, time, json, random, os, pdb from helpers import prandom from charcodes import * from constants import AF_CLASSIC, AF_P2WPKH_P2SH, AF_P2WPKH -from test_bbqr import readback_bbqr from bbqr import split_qrs diff --git a/testing/test_pwsave.py b/testing/test_pwsave.py index 41b335ee..3f98d051 100644 --- a/testing/test_pwsave.py +++ b/testing/test_pwsave.py @@ -3,7 +3,6 @@ # tests for ../shared/pwsave.py # import pytest, time, os, shutil -from test_ux import word_menu_entry from binascii import a2b_hex from constants import simulator_fixed_tprv diff --git a/testing/test_seed_xor.py b/testing/test_seed_xor.py index bdd2f929..c6a9febd 100644 --- a/testing/test_seed_xor.py +++ b/testing/test_seed_xor.py @@ -8,7 +8,6 @@ from mnemonic import Mnemonic from constants import simulator_fixed_words from xor import prepare_test_pairs, xor from bip32 import BIP32Node -from test_ux import word_menu_entry, pass_word_quiz from charcodes import KEY_QR, KEY_RIGHT, KEY_DOWN wordlist = Mnemonic('english').wordlist diff --git a/testing/test_teleport.py b/testing/test_teleport.py index 1033c134..bb7393be 100644 --- a/testing/test_teleport.py +++ b/testing/test_teleport.py @@ -6,16 +6,11 @@ # import pytest, time, re, pdb from helpers import prandom, xfp2str, str2xfp -from binascii import a2b_hex -from bbqr import split_qrs, join_qrs +from bbqr import join_qrs from charcodes import KEY_QR, KEY_NFC from base64 import b32encode from constants import * - -from test_bbqr import readback_bbqr, split_scan_bbqr -from test_notes import need_some_notes, need_some_passwords from test_ephemeral import SEEDVAULT_TEST_DATA -from test_nfc import ndef_parse_txn_psbt # All tests in this file are exclusively meant for Q # @@ -404,7 +399,7 @@ def test_teleport_ms_sign(M, use_regtest, make_myself_wallet, segwit, num_ins, d cap_menu, pick_menu_item, grab_payload, rx_complete, press_select, ndef_parse_txn_psbt, press_nfc, nfc_read, settings_get, settings_set): - # IMPORTANT: wont work if you start simulator with --ms flag. Use no args + # IMPORTANT: won't work if you start simulator with --ms flag. Use no args all_out_styles = list(unmap_addr_fmt.keys()) num_outs = len(all_out_styles) @@ -530,8 +525,12 @@ def test_teleport_big_ms(make_myself_wallet, clear_ms, pick_menu_item('Teleport Multisig PSBT') need_keypress('1') # top slot - - pick_menu_item(fname) + + try: + pick_menu_item(fname) + except KeyError: + # maybe just one file that is suitable --> str8 to xfp picking + pass # on Co-signer list menu m = cap_menu() diff --git a/testing/test_vdisk.py b/testing/test_vdisk.py index a9dba104..ce023e8c 100644 --- a/testing/test_vdisk.py +++ b/testing/test_vdisk.py @@ -107,7 +107,7 @@ def try_sign_virtdisk(press_select, virtdisk_path, cap_story, virtdisk_wipe, pre else: reexport_msg = split_story[2] - assert "Press (0) to re-export." == reexport_msg + assert "Press (0) to save again by another method." == reexport_msg got_psbt = None got_txn = None txid, got_txid = None, None