Skip to content

Commit b93f95c

Browse files
committed
test: make presign display evidence fail closed
1 parent c0dcb40 commit b93f95c

6 files changed

Lines changed: 1238 additions & 175 deletions

scripts/generate-test-report.py

Lines changed: 672 additions & 144 deletions
Large diffs are not rendered by default.

tests/test_msg_display_disclosure.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
from __future__ import print_function
5454

55+
import os
5556
import unittest
5657

5758
import common
@@ -69,17 +70,28 @@ class ScreenRecorder(object):
6970
displayed; reading it afterwards would only ever see the home screen.
7071
"""
7172

72-
def __init__(self, client, answer=True):
73+
def __init__(self, client, answer=True, screenshot_group=None):
7374
self.client = client
7475
self.answer = answer
76+
self.screenshot_group = screenshot_group
7577
self.screens = []
7678
self._original = None
79+
self._original_screenshot_dir = None
80+
self._original_screenshot_id = None
7781

7882
def __enter__(self):
7983
client = self.client
8084
recorder = self
8185

8286
self._original = client.callback_ButtonRequest
87+
if self.screenshot_group and getattr(client, 'screenshot_dir', None):
88+
self._original_screenshot_dir = client.screenshot_dir
89+
self._original_screenshot_id = client.screenshot_id
90+
client.screenshot_dir = os.path.join(
91+
client.screenshot_dir, self.screenshot_group
92+
)
93+
os.makedirs(client.screenshot_dir, exist_ok=True)
94+
client.screenshot_id = 0
8395

8496
def recording_callback(msg):
8597
try:
@@ -112,6 +124,9 @@ def recording_callback(msg):
112124

113125
def __exit__(self, exc_type, exc_value, tb):
114126
self.client.callback_ButtonRequest = self._original
127+
if self._original_screenshot_dir is not None:
128+
self.client.screenshot_dir = self._original_screenshot_dir
129+
self.client.screenshot_id = self._original_screenshot_id
115130
return False
116131

117132
@property
@@ -131,6 +146,12 @@ class TestDisplayDisclosesSignedContent(common.KeepKeyTest):
131146
def setUp(self):
132147
super(TestDisplayDisclosesSignedContent, self).setUp()
133148
self.requires_firmware(self.MIN_FIRMWARE)
149+
# These are positive display-binding controls, not refusal tests. A
150+
# fresh emulator is uninitialized; without an explicit seed setup every
151+
# request is rejected before its first ButtonRequest, the differential
152+
# cases vacuously "pass", and the only non-vacuity control skips. Keep
153+
# the fixture capable of reaching the confirmation path.
154+
self.setup_mnemonic_allallall()
134155

135156
# ── helpers ─────────────────────────────────────────────────────────
136157

@@ -244,8 +265,11 @@ def test_signing_shows_at_least_one_screen(self):
244265
empty tuples and the suite would pass while showing the user nothing.
245266
"""
246267
screens = self._sign_message_screens(b"hello")
247-
if screens is None:
248-
self.skipTest("device refused to sign the control message")
268+
self.assertIsNotNone(
269+
screens,
270+
"device refused the control request; the display-binding A/B "
271+
"tests did not prove they can reach a confirmation path",
272+
)
249273
self.assertGreater(
250274
len(screens), 0,
251275
"signing produced no ButtonRequest, so nothing was shown to the "

tests/test_msg_solana_display_disclosure.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ def setUp(self):
6060
self.requires_firmware("7.14.2")
6161
self.setup_mnemonic_allallall()
6262

63-
def _capture(self, request):
64-
recorder = ScreenRecorder(self.client, answer=True)
63+
def _capture(self, request, screenshot_group):
64+
recorder = ScreenRecorder(
65+
self.client,
66+
answer=True,
67+
screenshot_group=screenshot_group,
68+
)
6569
try:
6670
with recorder:
6771
self.client.call(request)
@@ -74,8 +78,8 @@ def _assert_tail_mutation_changes_review(self, make_request):
7478
payload_b = payload_a[:96] + b"B" + payload_a[97:]
7579
self.assertEqual(payload_a[:32], payload_b[:32])
7680

77-
screens_a = self._capture(make_request(payload_a))
78-
screens_b = self._capture(make_request(payload_b))
81+
screens_a = self._capture(make_request(payload_a), "payload-a")
82+
screens_b = self._capture(make_request(payload_b), "payload-b")
7983
self.assertIsNotNone(screens_a)
8084
self.assertIsNotNone(screens_b)
8185
self.assertGreater(len(screens_a), 1)
@@ -113,15 +117,17 @@ def test_offchain_format_changes_oled_review(self):
113117
version=0,
114118
message_format=0,
115119
message=payload,
116-
)
120+
),
121+
"format-ascii",
117122
)
118123
screens_utf8 = self._capture(
119124
solana.SolanaSignOffchainMessage(
120125
address_n=PATH,
121126
version=0,
122127
message_format=1,
123128
message=payload,
124-
)
129+
),
130+
"format-utf8",
125131
)
126132
self.assertIsNotNone(screens_ascii)
127133
self.assertIsNotNone(screens_utf8)
@@ -142,4 +148,3 @@ def test_memo_tail_changes_oled_review(self):
142148
raw_tx=build_memo_tx(signer, payload),
143149
)
144150
)
145-

0 commit comments

Comments
 (0)