Skip to content

Commit

Permalink
style(tests): format python code
Browse files Browse the repository at this point in the history
  • Loading branch information
keiff3r committed Nov 26, 2024
1 parent 3bb1514 commit e8de030
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 93 deletions.
148 changes: 75 additions & 73 deletions tests/application_client/boilerplate_command_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,137 +10,139 @@

CLA: int = 0xE0


class P1(IntEnum):
# Parameter 1 for first APDU number.
P1_START = 0x00
# Parameter 1 for verify address new derivation path
P1_VERIFY_ADDRESS_NEW_PATH = 0x01
# Parameter 1 for maximum APDU number.
P1_MAX = 0x03
P1_MAX = 0x03
# Parameter 1 for screen confirmation for GET_PUBLIC_KEY.
P1_CONFIRM = 0x01


class P2(IntEnum):
# Parameter 2 for last APDU to receive.
P2_LAST = 0x00
# Parameter 2 for more APDU to receive.
P2_MORE = 0x80


class InsType(IntEnum):
VERIFY_ADDRESS = 0x00
GET_VERSION = 0x03
GET_APP_NAME = 0x04
GET_VERSION = 0x03
GET_APP_NAME = 0x04
GET_PUBLIC_KEY = 0x05
SIGN_TX = 0x06
SIGN_TX = 0x06


class Errors(IntEnum):
SW_DENY = 0x6985
SW_WRONG_P1P2 = 0x6A86
SW_WRONG_DATA_LENGTH = 0x6A87
SW_INS_NOT_SUPPORTED = 0x6D00
SW_CLA_NOT_SUPPORTED = 0x6E00
SW_WRONG_RESPONSE_LENGTH = 0xB000
SW_DENY = 0x6985
SW_WRONG_P1P2 = 0x6A86
SW_WRONG_DATA_LENGTH = 0x6A87
SW_INS_NOT_SUPPORTED = 0x6D00
SW_CLA_NOT_SUPPORTED = 0x6E00
SW_WRONG_RESPONSE_LENGTH = 0xB000
SW_DISPLAY_BIP32_PATH_FAIL = 0xB001
SW_DISPLAY_ADDRESS_FAIL = 0xB002
SW_DISPLAY_AMOUNT_FAIL = 0xB003
SW_WRONG_TX_LENGTH = 0xB004
SW_TX_PARSING_FAIL = 0xB005
SW_TX_HASH_FAIL = 0xB006
SW_BAD_STATE = 0xB007
SW_SIGNATURE_FAIL = 0xB008
SW_DISPLAY_ADDRESS_FAIL = 0xB002
SW_DISPLAY_AMOUNT_FAIL = 0xB003
SW_WRONG_TX_LENGTH = 0xB004
SW_TX_PARSING_FAIL = 0xB005
SW_TX_HASH_FAIL = 0xB006
SW_BAD_STATE = 0xB007
SW_SIGNATURE_FAIL = 0xB008


def split_message(message: bytes, max_size: int) -> List[bytes]:
return [message[x:x + max_size] for x in range(0, len(message), max_size)]
return [message[x : x + max_size] for x in range(0, len(message), max_size)]


class BoilerplateCommandSender:
def __init__(self, backend: BackendInterface) -> None:
self.backend = backend


def get_app_and_version(self) -> RAPDU:
return self.backend.exchange(cla=0xB0, # specific CLA for BOLOS
ins=0x01, # specific INS for get_app_and_version
p1=P1.P1_START,
p2=P2.P2_LAST,
data=b"")

return self.backend.exchange(
cla=0xB0, # specific CLA for BOLOS
ins=0x01, # specific INS for get_app_and_version
p1=P1.P1_START,
p2=P2.P2_LAST,
data=b"",
)

def get_version(self) -> RAPDU:
return self.backend.exchange(cla=CLA,
ins=InsType.GET_VERSION,
p1=P1.P1_START,
p2=P2.P2_LAST,
data=b"")

return self.backend.exchange(
cla=CLA, ins=InsType.GET_VERSION, p1=P1.P1_START, p2=P2.P2_LAST, data=b""
)

def get_app_name(self) -> RAPDU:
return self.backend.exchange(cla=CLA,
ins=InsType.GET_APP_NAME,
p1=P1.P1_START,
p2=P2.P2_LAST,
data=b"")

return self.backend.exchange(
cla=CLA, ins=InsType.GET_APP_NAME, p1=P1.P1_START, p2=P2.P2_LAST, data=b""
)

def get_public_key(self, path: str) -> RAPDU:
return self.backend.exchange(cla=CLA,
ins=InsType.GET_PUBLIC_KEY,
p1=P1.P1_START,
p2=P2.P2_LAST,
data=pack_derivation_path(path))

return self.backend.exchange(
cla=CLA,
ins=InsType.GET_PUBLIC_KEY,
p1=P1.P1_START,
p2=P2.P2_LAST,
data=pack_derivation_path(path),
)

@contextmanager
def get_public_key_with_confirmation(self, path: str) -> Generator[None, None, None]:
with self.backend.exchange_async(cla=CLA,
ins=InsType.GET_PUBLIC_KEY,
p1=P1.P1_CONFIRM,
p2=P2.P2_LAST,
data=pack_derivation_path(path)) as response:
def get_public_key_with_confirmation(
self, path: str
) -> Generator[None, None, None]:
with self.backend.exchange_async(
cla=CLA,
ins=InsType.GET_PUBLIC_KEY,
p1=P1.P1_CONFIRM,
p2=P2.P2_LAST,
data=pack_derivation_path(path),
) as response:
yield response

@contextmanager
def verify_address(self, identity_index: int, credential_counter: int, idp_index: int = -1) -> Generator[None, None, None]:
def verify_address(
self, identity_index: int, credential_counter: int, idp_index: int = -1
) -> Generator[None, None, None]:
data = b""
p1 = P1.P1_START

if idp_index != -1:
data += idp_index.to_bytes(4, byteorder='big')
data += idp_index.to_bytes(4, byteorder="big")
p1 = P1.P1_VERIFY_ADDRESS_NEW_PATH

data += identity_index.to_bytes(4, byteorder='big') + credential_counter.to_bytes(4, byteorder='big')
with self.backend.exchange_async(cla=CLA,
ins=InsType.VERIFY_ADDRESS,
p1=p1,
p2=P2.P2_LAST,
data=data) as response:
data += identity_index.to_bytes(
4, byteorder="big"
) + credential_counter.to_bytes(4, byteorder="big")
with self.backend.exchange_async(
cla=CLA, ins=InsType.VERIFY_ADDRESS, p1=p1, p2=P2.P2_LAST, data=data
) as response:
yield response


@contextmanager
def sign_tx(self, path: str, transaction: bytes) -> Generator[None, None, None]:
self.backend.exchange(cla=CLA,
ins=InsType.SIGN_TX,
p1=P1.P1_START,
p2=P2.P2_MORE,
data=pack_derivation_path(path))
self.backend.exchange(
cla=CLA,
ins=InsType.SIGN_TX,
p1=P1.P1_START,
p2=P2.P2_MORE,
data=pack_derivation_path(path),
)
messages = split_message(transaction, MAX_APDU_LEN)
idx: int = P1.P1_START + 1

for msg in messages[:-1]:
self.backend.exchange(cla=CLA,
ins=InsType.SIGN_TX,
p1=idx,
p2=P2.P2_MORE,
data=msg)
self.backend.exchange(
cla=CLA, ins=InsType.SIGN_TX, p1=idx, p2=P2.P2_MORE, data=msg
)
idx += 1

with self.backend.exchange_async(cla=CLA,
ins=InsType.SIGN_TX,
p1=idx,
p2=P2.P2_LAST,
data=messages[-1]) as response:
with self.backend.exchange_async(
cla=CLA, ins=InsType.SIGN_TX, p1=idx, p2=P2.P2_LAST, data=messages[-1]
) as response:
yield response

def get_async_response(self) -> Optional[RAPDU]:
Expand Down
69 changes: 49 additions & 20 deletions tests/test_verify_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,52 @@
from bip_utils import Bip32Slip10Ed25519
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
from application_client.boilerplate_command_sender import BoilerplateCommandSender, Errors
from application_client.boilerplate_response_unpacker import unpack_get_public_key_response
from application_client.boilerplate_command_sender import (
BoilerplateCommandSender,
Errors,
)
from application_client.boilerplate_response_unpacker import (
unpack_get_public_key_response,
)
from ragger.bip import calculate_public_key_and_chaincode, CurveChoice
from ragger.error import ExceptionRAPDU
from ragger.navigator import NavInsID, NavIns, NavigateWithScenario


nbgl_instructions_address_confirmation = [NavInsID.SWIPE_CENTER_TO_LEFT,NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM]
nbgl_instructions_address_confirmation_reject = [NavInsID.SWIPE_CENTER_TO_LEFT,NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CANCEL, NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM]
bagl_instructions_address_confirmation = [NavInsID.RIGHT_CLICK,NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,NavInsID.BOTH_CLICK]
nbgl_instructions_address_confirmation = [
NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM,
]
nbgl_instructions_address_confirmation_reject = [
NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.SWIPE_CENTER_TO_LEFT,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CANCEL,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM,
]
bagl_instructions_address_confirmation = [
NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
]

bagl_instructions_address_confirmation_reject = [
NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
]

bagl_instructions_address_confirmation_reject = [NavInsID.RIGHT_CLICK,NavInsID.RIGHT_CLICK,
NavInsID.RIGHT_CLICK,NavInsID.RIGHT_CLICK,NavInsID.BOTH_CLICK]

# In this test we check that the VERIFY ADDRESS works in confirmation mode
def test_verify_address_confirm_legacy_path_accepted(backend, scenario_navigator: NavigateWithScenario, test_name: str, default_screenshot_path: str):
def test_verify_address_confirm_legacy_path_accepted(
backend,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: str,
):
client = BoilerplateCommandSender(backend)
with client.verify_address(identity_index=0, credential_counter=0):
instructions = []
Expand All @@ -36,10 +63,13 @@ def test_verify_address_confirm_legacy_path_accepted(backend, scenario_navigator
)

response = client.get_async_response().status
assert(response == 0x9000)
assert response == 0x9000


# In this test we check that the VERIFY ADDRESS works in confirmation mode
def test_verify_address_confirm_new_path_accepted(backend, scenario_navigator, test_name, default_screenshot_path):
def test_verify_addressß_confirm_new_path_accepted(
backend, scenario_navigator, test_name, default_screenshot_path
):
client = BoilerplateCommandSender(backend)
with client.verify_address(identity_index=0, credential_counter=0, idp_index=0):
instructions = []
Expand All @@ -49,18 +79,17 @@ def test_verify_address_confirm_new_path_accepted(backend, scenario_navigator, t
instructions.extend(bagl_instructions_address_confirmation)

scenario_navigator.navigator.navigate_and_compare(
default_screenshot_path,
test_name,
instructions
default_screenshot_path, test_name, instructions
)


response = client.get_async_response().status
assert(response == 0x9000)
assert response == 0x9000


# In this test we check that the VERIFY ADDRESS in confirmation mode replies an error if the user refuses
def test_verify_address_confirm_refused(backend, scenario_navigator, test_name, default_screenshot_path):
def test_verify_address_confirm_refused(
backend, scenario_navigator, test_name, default_screenshot_path
):
client = BoilerplateCommandSender(backend)
try:
with client.verify_address(identity_index=0, credential_counter=0, idp_index=0):
Expand All @@ -78,4 +107,4 @@ def test_verify_address_confirm_refused(backend, scenario_navigator, test_name,
except ExceptionRAPDU as e:
response = e.status

assert(response == 0x6985)
assert response == 0x6985

0 comments on commit e8de030

Please sign in to comment.