diff --git a/testing/conftest.py b/testing/conftest.py index ccfd5c6d..1916b221 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -2627,6 +2627,27 @@ def build_test_seed_vault(): return sv return doit +@pytest.fixture +def get_deltamode(sim_exec): + # get current "deltamode" status: T or F + def doit(): + return eval(sim_exec('RV.write(repr(pa.is_deltamode()))')) + return doit + +@pytest.fixture +def set_deltamode(sim_exec): + # control current "deltamode" status: T or F + def doit(val): + # TC_DELTA_MODE = const(0x0400) + if val: + sim_exec('pa.delay_required |= 0x400') + else: + sim_exec('pa.delay_required &= ~0x400') + + yield doit + + doit(False) + # useful fixtures from test_backup import backup_system diff --git a/testing/test_hobble.py b/testing/test_hobble.py index 3cba9fe8..dc4ed9ea 100644 --- a/testing/test_hobble.py +++ b/testing/test_hobble.py @@ -17,6 +17,7 @@ from test_ux import word_menu_entry # # - test_teleport.py::test_teleport_ms_sign # - verifies: MS psbt KT should still work in hobbled mode +# # - test_teleport.py::test_hobble_limited # - verifies: scan a KT and have it rejected if not PSBT type: so R and E types @@ -392,8 +393,6 @@ def test_h_usbcmds(en_okeys, set_hobble, dev): got = dev.send_recv(cmd) assert 'Spending policy in effect' in str(ee) -# TODO: verify that PSBT can be "signed" when SP enabled and delta-mode pin is active. seed not wiped. - # TODO verify whitelist of QR types is correct when in hobbled mode # - no private key material, no teleport starting, unless "okeys" is set diff --git a/testing/test_se2.py b/testing/test_se2.py index 75f18256..78d640aa 100644 --- a/testing/test_se2.py +++ b/testing/test_se2.py @@ -916,6 +916,14 @@ def build_duress_wallets(request, seed_vault=False): return 4 +def test_deltamode_toggle(get_deltamode, set_deltamode): + # check test fixture works. + assert get_deltamode() == False + set_deltamode(True) + assert get_deltamode() == True + set_deltamode(False) + assert get_deltamode() == False + # TODO # - make trick and do login, check arrives right state? diff --git a/testing/test_sssp.py b/testing/test_sssp.py index 264c207a..b14d469a 100644 --- a/testing/test_sssp.py +++ b/testing/test_sssp.py @@ -566,4 +566,56 @@ def test_use_trick_pin_as_unlock(hide, setup_sssp, cap_story, new_trick_pin, pic assert "already in use" in story assert "PIN codes must be unique" in story + + +@pytest.mark.parametrize("active_policy", [False, True]) +def test_deltamode_signature(active_policy, setup_sssp, bitcoind, settings_set, + start_sign, end_sign, + set_deltamode, bitcoind_d_sim_watch, settings_get): + + # verify that "deltamode" trick pins will work in SSSP mode + # - and that resulting signature is bad + # - device should **not** wipe itself + + dest = "bcrt1qlk39jrclgnawa42tvhu2n7se987qm96qg8v76e" + wo = bitcoind_d_sim_watch + wo.keypoolrefill(20) + + settings_set("chain", "XRT") + + if active_policy: + setup_sssp("11-11", mag=100) + + bitcoind.supply_wallet.sendtoaddress(address=wo.getnewaddress(), amount=2) + bitcoind.supply_wallet.generatetoaddress(1, bitcoind.supply_wallet.getnewaddress()) + + # create funded PSBT, first tx + # - within active policy. + init_block_height = bitcoind.supply_wallet.getblockchaininfo()["blocks"] # block height + psbt_resp = wo.walletcreatefundedpsbt([], [{dest: 0.06}], + init_block_height, {"fee_rate":2, "replaceable": False}) + psbt = psbt_resp.get("psbt") + + po = BasicPSBT().parse(base64.b64decode(psbt)) + assert po.parsed_txn.nLockTime == init_block_height + + start_sign(base64.b64decode(psbt), finalize=True) + signed = end_sign(accept=True, finalize=True) + + set_deltamode(True) + + start_sign(base64.b64decode(psbt), finalize=True) + signed2 = end_sign(accept=True, finalize=True) + + # check wrong signature happened + assert signed != signed2 + probs = wo.testmempoolaccept([signed2.hex()])[0] + assert 'Signature must be zero' in probs['reject-reason'], probs + assert not probs['allowed'] + + # check right signature + no_probs = wo.testmempoolaccept([signed.hex()])[0] + assert no_probs['allowed'] + + # EOF