Updated Ragger app client for trusted name & sign APDUs

Also added two new optional arguments to pytest :
--gold for screenshot generation
--chainid to specify an alternative app chain ID
This commit is contained in:
Alexandre Paillier
2023-02-27 10:54:36 +01:00
parent 2b463e95aa
commit 37a6dab7be
6 changed files with 133 additions and 5 deletions
+55 -1
View File
@@ -2,14 +2,18 @@ from enum import IntEnum, auto
from typing import Optional
from ragger.backend import BackendInterface
from ragger.utils import RAPDU
from ragger.navigator import NavInsID, NavIns, NanoNavigator
from app.command_builder import EthereumCmdBuilder
from app.setting import SettingType, SettingImpl
from app.eip712 import EIP712FieldType
from app.response_parser import EthereumRespParser
import signal
import time
from pathlib import Path
ROOT_SCREENSHOT_PATH = Path(__file__).parent.parent
class EthereumClient:
_settings: dict[SettingType, SettingImpl] = {
SettingType.BLIND_SIGNING: SettingImpl(
@@ -21,6 +25,9 @@ class EthereumClient:
SettingType.NONCE: SettingImpl(
[ "nanos", "nanox", "nanosp" ]
),
SettingType.VERBOSE_ENS: SettingImpl(
[ "nanox", "nanosp" ]
),
SettingType.VERBOSE_EIP712: SettingImpl(
[ "nanox", "nanosp" ]
)
@@ -28,10 +35,12 @@ class EthereumClient:
_click_delay = 1/4
_eip712_filtering = False
def __init__(self, client: BackendInterface):
def __init__(self, client: BackendInterface, chain_id: int, golden_run: bool):
self._client = client
self._chain_id = chain_id
self._cmd_builder = EthereumCmdBuilder()
self._resp_parser = EthereumRespParser()
self._nav = NanoNavigator(client, client.firmware, golden_run)
signal.signal(signal.SIGALRM, self._click_signal_timeout)
for setting in self._settings.values():
setting.value = False
@@ -156,3 +165,48 @@ class EthereumClient:
with self._send(self._cmd_builder.eip712_filtering_show_field(name, sig)):
pass
assert self._recv().status == 0x9000
def send_fund(self,
bip32_path: list[Optional[int]],
nonce: int,
gas_price: int,
gas_limit: int,
to: bytes,
amount: float,
chain_id: int,
screenshot_collection: str = None):
for chunk in self._cmd_builder.send_fund(bip32_path,
nonce,
gas_price,
gas_limit,
to,
amount,
chain_id):
with self._send(chunk):
nav_ins = NavIns(NavInsID.RIGHT_CLICK)
final_ins = [ NavIns(NavInsID.BOTH_CLICK) ]
target_text = "and send"
if screenshot_collection:
self._nav.navigate_until_text_and_compare(nav_ins,
final_ins,
target_text,
ROOT_SCREENSHOT_PATH,
screenshot_collection)
else:
self._nav.navigate_until_text(nav_ins,
final_ins,
target_text)
assert self._recv().status == 0x9000
def get_challenge(self) -> int:
with self._send(self._cmd_builder.get_challenge()):
pass
resp = self._recv()
assert resp.status == 0x9000
return self._resp_parser.challenge(resp.data)
def provide_trusted_name(self, name: str, key_id: int, algo_id: int, sig: bytes):
for chunk in self._cmd_builder.provide_trusted_name(name, key_id, algo_id, sig):
with self._send(chunk):
pass
assert self._recv().status == 0x9000