From b6e543bc2b78cde81588a8513436fcbf4a3834df Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Tue, 27 Feb 2024 23:28:36 +0100 Subject: [PATCH] test wrong pin (login_settings_tests) --- shared/login.py | 4 +-- testing/login_settings_tests.py | 64 +++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/shared/login.py b/shared/login.py index abd3b3d9..0a5a3738 100644 --- a/shared/login.py +++ b/shared/login.py @@ -189,7 +189,7 @@ Restore your seed words onto a new Coldcard.''' % num_fails ch = await ux_show_story(msg, title='I Am Brick!', escape='6') if ch == '6': break - async def confirm_attempt(self, attempts_left, num_fails, value): + async def confirm_attempt(self, attempts_left, value): ch = await ux_show_story('''You have %d attempts left before this Coldcard BRICKS \ ITSELF FOREVER. @@ -227,7 +227,7 @@ Press OK to continue, X to stop for now. if pa.num_fails > 3: # they are approaching brickage, so warn them each attempt - await self.confirm_attempt(pa.attempts_left, pa.num_fails, pin) + await self.confirm_attempt(pa.attempts_left, pin) dis.fullscreen("Wait...") # do the actual login attempt now diff --git a/testing/login_settings_tests.py b/testing/login_settings_tests.py index ff915596..9d4d8735 100644 --- a/testing/login_settings_tests.py +++ b/testing/login_settings_tests.py @@ -154,7 +154,7 @@ def _set_kill_key(device, val, is_Q): if is_Q: assert "press this key at any point during login" in story else: - assert "press this key while the anti-phishing words are shown during login" in story + assert "press this key while the anti- phishing words are shown during login" in story assert ("Best if this does not match the first number" " of the second half of your PIN.") in story @@ -172,9 +172,11 @@ def _remap_pin(pin, key_map): remap_pin += ch return remap_pin -def _login(device, pin, is_Q, scrambled=False, mk4_kbtn=None): +def _login(device, pin, is_Q, scrambled=False, mk4_kbtn=None, num_failed=None): orig_pin = pin scr = _cap_screen(device) + if num_failed: + assert f"{num_failed} failures, {13-num_failed} tries left" in scr if is_Q: top = scr.split("\n")[0].split() is_scrambled = len(top) == 10 @@ -414,6 +416,64 @@ def test_terms_ok(request): sim.stop() +@pytest.mark.parametrize("brick", [True, False]) +def test_wrong_pin_input(request, brick): + is_Q = request.config.getoption('--Q') + clean_sim_data() # remove all from previous + sim = ColdcardSimulator(args=["--early-usb", "--q1" if is_Q else "", "--pin", "22-22"]) + sim.start(start_wait=6) + device = ColdcardDevice(sn=CKCC_SIMULATOR_PATH) + time.sleep(.1) + num_attmeptss = 13 + for ii, i in enumerate(range(31, 43), start=1): + # pdb.set_trace() + pin = f"{i}-{i}" + scr_num_failed = (ii - 1) if ii > 1 else None + _login(device, pin, is_Q, num_failed=scr_num_failed) + time.sleep(.5) + title, story = _cap_story(device) + if ii > 4: + assert title == "WARNING" + assert pin in story # showing to user to double-check his input + assert "BRICKS ITSELF FOREVER" in story + assert f"{num_attmeptss - ii + 1} attempts left" in story + _press_select(device, is_Q) + time.sleep(.1) + title, story = _cap_story(device) + + assert "WRONG PIN" in title + assert f"{num_attmeptss - ii} attempts left" in story + assert f"{ii} failure" in story + _press_select(device, is_Q) + time.sleep(.1) + + if brick: + # one more wrong pin + _login(device, "91-11", is_Q, num_failed=12) + time.sleep(.5) + title, story = _cap_story(device) + assert "WARNING" == title + _press_select(device, is_Q) + time.sleep(.1) + title, story = _cap_story(device) + assert title == "I Am Brick!" + assert "After 13 failed PIN attempts this Coldcard is locked forever" in story + assert "no way to reset or recover the secure element" in story + assert "forever inaccessible" in story + assert "Restore your seed words onto a new Coldcard" in story + else: + _login(device, "22-22", is_Q, num_failed=12) + time.sleep(.5) + title, story = _cap_story(device) + assert "WARNING" == title + _press_select(device, is_Q) + time.sleep(.1) + m = _cap_menu(device) + assert "Ready To Sign" in m + + sim.stop() + + @pytest.mark.parametrize("nick", [None, "In trust we trust NOT"]) @pytest.mark.parametrize("randomize", [False, True]) @pytest.mark.parametrize("login_ctdwn", [None, " 5 minutes", "15 minutes"])