What changed, and why it matters
This commit is a test-suite maintenance change for the COLDCARD firmware. It updates a test file to match new menu labels and adds a small helper fixture, while also adding a comment in the non-volatile storage code describing a new setting key ('lfr') that records why a spending policy blocked the last transaction. There is no code change that alters security behavior, fixes a vulnerability, or introduces an obvious bug.
No security action required. Treat as ordinary test maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff touches shared/nvstore.py only to add a documentation comment for a new NV storage key ‘lfr’ (last fail reason). The bulk of the change is in testing/test_ccc.py: it introduces a goto_ccc_menu pytest fixture, updates get_last_violation to read the new ‘lfr’ setting instead of calling into CCCFeature.last_fail_reason, and adjusts menu navigation/assertions to match renamed menu items (‘Spending Policy’ / ‘Co-Sign Multi.’ / ‘Co-Sign Multisig (CCC)’). These are test-alignment changes, not security-relevant firmware logic changes.
Changed components
shared/nvstore.py (comment only)testing/test_ccc.py (test fixtures and assertions)Inspect captured patch +21 / −15
diff --git a/shared/nvstore.py b/shared/nvstore.py
index e3e51b4..9142432 100644
--- a/shared/nvstore.py
+++ b/shared/nvstore.py
@@ -68,6 +68,7 @@ from utils import call_later_ms
# ccc = (complex) If present, CCC feature is enabled and key details stored here.
# ktrx = (privkey) Key teleport Rx has been started, this will be our keypair
# sssp = (complex) If present, spending-policy (single signer) feature are defined
+# lfr = (string) If present, the reason why Spending Policy blocked last transaction
# Stored w/ key=00 for access before login
# _skip_pin = hard code a PIN value (dangerous, only for debug)
diff --git a/testing/test_ccc.py b/testing/test_ccc.py
index 0b7698d..18142c5 100644
--- a/testing/test_ccc.py
+++ b/testing/test_ccc.py
@@ -21,6 +21,16 @@ from psbt import BasicPSBT
# pubkey for production server.
SERVER_PUBKEY = '0231301ec4acec08c1c7d0181f4ffb8be70d693acccc86cccb8f00bf2e00fcabfd'
+@pytest.fixture
+def goto_ccc_menu(goto_home, pick_menu_item, is_mark4):
+ def doit():
+ goto_home()
+ pick_menu_item("Advanced/Tools")
+ pick_menu_item("Spending Policy")
+ pick_menu_item("Co-Sign Multi." if is_mark4 else "Co-Sign Multisig (CCC)")
+
+ return doit
+
def make_session_key(his_pubkey=None):
# - second call: given the pubkey of far side, calculate the shared pt on curve
@@ -168,24 +178,22 @@ def test_2fa_links(shared_secret, label_len, q_mode, roundtrip_2fa, sim_exec, re
assert ans == f'CCC-AUTH:{nonce}'.upper() if q_mode else nonce
@pytest.fixture
-def get_last_violation(sim_exec):
+def get_last_violation(settings_get):
def doit():
- return sim_exec('from ccc import CCCFeature; RV.write(CCCFeature.last_fail_reason)')
+ return settings_get('lfr')
return doit
_skip_quiz = False
@pytest.fixture
-def setup_ccc(goto_home, pick_menu_item, cap_story, press_select, pass_word_quiz, is_q1,
+def setup_ccc(goto_ccc_menu, pick_menu_item, cap_story, press_select, pass_word_quiz, is_q1,
seed_story_to_words, cap_menu, OK, word_menu_entry, press_cancel, press_delete,
enter_number, scan_a_qr, cap_screen, settings_get, need_keypress, microsd_path,
master_settings_get):
def doit(c_words=None, mag=None, vel=None, whitelist=None, w2fa=None, first_time=True):
if first_time:
- goto_home()
- pick_menu_item("Advanced/Tools")
- pick_menu_item("Coldcard Co-Signing")
+ goto_ccc_menu()
time.sleep(.1)
title, story = cap_story()
assert title == ("Coldcard Co-Signing" if is_q1 else "CC Co-Sign")
@@ -242,7 +250,7 @@ def setup_ccc(goto_home, pick_menu_item, cap_story, press_select, pass_word_quiz
m = cap_menu()
- assert m[0] == f"CCC [{xfp}]"
+ assert f"[{xfp}]" in m[0]
assert "Spending Policy" in m
assert "Export CCC XPUBs" in m
assert "Multisig Wallets" in m
@@ -274,6 +282,7 @@ def setup_ccc(goto_home, pick_menu_item, cap_story, press_select, pass_word_quiz
assert f"{mag} {'BTC' if int(mag) < 1000 else 'SATS'}" in story
press_select()
+ time.sleep(.1)
assert settings_get("ccc")["pol"]["mag"] == mag
if vel:
@@ -362,12 +371,10 @@ def setup_ccc(goto_home, pick_menu_item, cap_story, press_select, pass_word_quiz
return doit
@pytest.fixture
-def enter_enabled_ccc(goto_home, pick_menu_item, cap_story, press_select, is_q1,
+def enter_enabled_ccc(goto_ccc_menu, pick_menu_item, cap_story, press_select, is_q1,
word_menu_entry, cap_menu):
def doit(c_words, seed_vault=False):
- goto_home()
- pick_menu_item("Advanced/Tools")
- pick_menu_item("Coldcard Co-Signing")
+ goto_ccc_menu()
time.sleep(.1)
title, story = cap_story()
if seed_vault:
@@ -1159,7 +1166,7 @@ def test_remove_ccc(settings_set, setup_ccc, ccc_ms_setup, settings_get, policy_
@pytest.mark.parametrize("has_candidates", [True, False])
def test_c_key_from_seed_vault(has_candidates, setup_ccc, build_test_seed_vault, settings_set,
- goto_home, pick_menu_item, press_select, need_keypress, cap_menu,
+ goto_ccc_menu, pick_menu_item, press_select, need_keypress, cap_menu,
cap_story, press_cancel, enter_enabled_ccc):
goto_home()
settings_set("ccc", None)
@@ -1173,9 +1180,7 @@ def test_c_key_from_seed_vault(has_candidates, setup_ccc, build_test_seed_vault,
settings_set("seeds", sv)
- goto_home()
- pick_menu_item("Advanced/Tools")
- pick_menu_item("Coldcard Co-Signing")
+ goto_ccc_menu()
press_select()
time.sleep(.1)
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.