-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtest_quit_node_cmd.py
More file actions
79 lines (61 loc) · 3.94 KB
/
test_quit_node_cmd.py
File metadata and controls
79 lines (61 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import pytest
from application_client.boilerplate_transaction import Transaction
from application_client.boilerplate_command_sender import BoilerplateCommandSender, Errors
from application_client.boilerplate_response_unpacker import unpack_get_public_key_response, unpack_sign_tx_response
from ragger.error import ExceptionRAPDU
from utils import check_signature_validity
import hashlib
# In this tests we check the behavior of the device when asked to sign a transaction
import logging
# Configure logger
logger = logging.getLogger("test_logger")
logger.setLevel(logging.DEBUG)
# In this test we send to the device a transaction to sign and validate it on screen
# The transaction is short and will be sent in one chunk
# We will ensure that the displayed information is correct by using screenshots comparison
def test_sign_quit_node_tx_short_tx(backend, scenario_navigator):
# Use the app interface instead of raw interface
client = BoilerplateCommandSender(backend)
# The path used for this entire test
path: str = "m/44'/1024'/0'/0/0"
# First we need to get the public key of the device in order to build the transaction
rapdu = client.get_public_key(path=path)
logger.debug("rapu.data.hex:%s", rapdu.data.hex())
_, public_key, _, _ = unpack_get_public_key_response(rapdu.data)
logger.debug("pubkey:%s", public_key.hex())
# Create the transaction that will be sent to the device for signing
transaction = Transaction(
rawtx="00d1358bdff1c409000000000000204e000000000000825995774fc9f599e6f5270176b37495d85798269900c66b423033383764303737636433616339373030303532666631376134306463376438633736366534313164363533316231386332393666613235623139373934343463636a7cc814825995774fc9f599e6f5270176b37495d85798266a7cc86c08717569744e6f64651400000000000000000000000000000000000000070068164f6e746f6c6f67792e4e61746976652e496e766f6b6500"
).serialize()
# Send the sign device instruction.
# As it requires on-screen validation, the function is asynchronous.
# It will yield the result when the navigation is done
logger.debug("tx:%s", transaction.hex())
with client.sign_tx(path=path, transaction=transaction):
# Validate the on-screen request by performing the navigation appropriate for this device
scenario_navigator.review_approve()
# The device as yielded the result, parse it and ensure that the signature is correct
response = client.get_async_response().data
_, der_sig, _ = unpack_sign_tx_response(response)
first_hash = hashlib.sha256(transaction).digest()
second_hash = hashlib.sha256(first_hash).digest()
logger.debug("pubkey:%s,der_sig:%s,transaction:%s,first_hash:%s", public_key.hex(), der_sig.hex(),
transaction.hex(), first_hash.hex())
assert check_signature_validity(public_key, der_sig, second_hash)
# Transaction signature refused test
# The test will ask for a transaction signature that will be refused on screen
def test_sign_quit_node_tx_refused(backend, scenario_navigator):
# Use the app interface instead of raw interface
client = BoilerplateCommandSender(backend)
path: str = "m/44'/1024'/0'/0/0"
rapdu = client.get_public_key(path=path)
_, pub_key, _, _ = unpack_get_public_key_response(rapdu.data)
transaction = Transaction(
rawtx="00d1358bdff1c409000000000000204e000000000000825995774fc9f599e6f5270176b37495d85798269900c66b423033383764303737636433616339373030303532666631376134306463376438633736366534313164363533316231386332393666613235623139373934343463636a7cc814825995774fc9f599e6f5270176b37495d85798266a7cc86c08717569744e6f64651400000000000000000000000000000000000000070068164f6e746f6c6f67792e4e61746976652e496e766f6b6500"
).serialize()
with pytest.raises(ExceptionRAPDU) as e:
with client.sign_tx(path=path, transaction=transaction):
scenario_navigator.review_reject()
# Assert that we have received a refusal
assert e.value.status == Errors.SW_DENY
assert len(e.value.data) == 0