Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic clear-signing #699

Merged
merged 45 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
afc52f2
Added missing mem_init at app start
apaillier-ledger Dec 6, 2024
ae626b8
mem_dealloc can now print a warning
apaillier-ledger Dec 9, 2024
084eac5
Small refactoring of the handler of the sign transaction APDU
apaillier-ledger Oct 16, 2024
8536e21
Now returns an error RAPDU if the hashing of the TxType failed
apaillier-ledger Oct 17, 2024
33bded6
Small change in variable naming
apaillier-ledger Dec 16, 2024
fd3d72b
Renamed some functions, removed useless fields from the txContent struct
apaillier-ledger Dec 16, 2024
526e803
Moved ethUstream and rlp_utils from the signTx feature folder
apaillier-ledger Oct 17, 2024
463a025
Restrict include of signTx header files to where necessary
apaillier-ledger Oct 18, 2024
8b7d496
New time formatting functions
apaillier-ledger Nov 20, 2024
b5c69ac
Support for new TX sign modes
apaillier-ledger Dec 16, 2024
2c96cf8
Now stores calldata in RAM
apaillier-ledger Oct 21, 2024
4656df5
Now does not start the flow if in store calldata mode
apaillier-ledger Oct 22, 2024
0f3272c
Added bytearray handling to format_tlv function in Python client
apaillier-ledger Nov 4, 2024
b606721
Commonize RLP parsing status handling
apaillier-ledger Oct 31, 2024
6b3e7ec
Prevent plugin init when in store mode
apaillier-ledger Oct 31, 2024
397d0e6
Fix blind signing warning in store mode
apaillier-ledger Oct 31, 2024
41cfa3b
Store mode now sends RAPDU immediately when finished parsing
apaillier-ledger Oct 31, 2024
79f5a6e
New util functions for string and buffer manipulation + SET_BIT macro
apaillier-ledger Dec 3, 2024
e2dff52
New non feature-specific TLV parser
apaillier-ledger Oct 23, 2024
118d237
util function to extract TLV from an APDU
apaillier-ledger Dec 6, 2024
67f6e96
Provide enum value APDU implementation
apaillier-ledger Dec 6, 2024
c837905
Added provide_enum_value APDU in Python client
apaillier-ledger Dec 2, 2024
e740101
GTP APDU handling
apaillier-ledger Dec 2, 2024
d7cea40
Python client can now take an optional mode for the sign operation
apaillier-ledger Nov 26, 2024
60a52c2
Added transaction info APDU to Python client
apaillier-ledger Dec 2, 2024
c83d6a9
Added field descriptor TLV serialization to the Python client
apaillier-ledger Dec 3, 2024
613bceb
Added new send_raw_async function to Python client
apaillier-ledger Dec 16, 2024
4d35cd1
TX info handler
apaillier-ledger Dec 2, 2024
2221ba1
GTP Field table implementation
apaillier-ledger Dec 18, 2024
3c10eee
Added empty UI implementations
apaillier-ledger Nov 15, 2024
4cf52d5
get_public_key function is now usable from outside the signTx feature
apaillier-ledger Nov 19, 2024
7b42507
GTP field support + param_raw
apaillier-ledger Dec 18, 2024
e2b87cf
Added GTP param_amount
apaillier-ledger Dec 16, 2024
7513e98
Added GTP param_token_amount
apaillier-ledger Dec 16, 2024
3dcf42a
Added GTP param_nft
apaillier-ledger Dec 16, 2024
4d137b9
Added GTP param_datetime
apaillier-ledger Dec 16, 2024
ccdf5d4
Added GTP param_duration
apaillier-ledger Dec 16, 2024
3e375e3
Added GTP param_unit
apaillier-ledger Dec 16, 2024
27a5e99
Added GTP param_enum
apaillier-ledger Dec 16, 2024
3ac3e87
Added GTP param_trusted_name
apaillier-ledger Dec 16, 2024
cdaef75
Max fees & network formatting functions are now accessible from outsi…
apaillier-ledger Nov 15, 2024
f7960b5
BAGL GCS UI implementation
apaillier-ledger Nov 13, 2024
04c6ce6
NBGL GCS UI implementation
apaillier-ledger Nov 22, 2024
ee9fd30
Ragger tests
apaillier-ledger Nov 5, 2024
6743966
Added new APDUs to doc
apaillier-ledger Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions client/src/ledger_app_clients/ethereum/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ class PKIPubKeyUsage(IntEnum):
PUBKEY_USAGE_SEED_ID_AUTH = 0x09


class SignMode(IntEnum):
BASIC = 0x00
STORE = 0x01
START_FLOW = 0x02


class PKIClient:
_CLA: int = 0xB0
_INS: int = 0x06
Expand Down Expand Up @@ -130,6 +136,15 @@ def send_raw(self, cla: int, ins: int, p1: int, p2: int, payload: bytes):
header.append(len(payload))
return self._exchange(header + payload)

def send_raw_async(self, cla: int, ins: int, p1: int, p2: int, payload: bytes):
header = bytearray()
header.append(cla)
header.append(ins)
header.append(p1)
header.append(p2)
header.append(len(payload))
return self._exchange_async(header + payload)

def eip712_send_struct_def_struct_name(self, name: str):
return self._exchange_async(self._cmd_builder.eip712_send_struct_def_struct_name(name))

Expand Down Expand Up @@ -211,7 +226,8 @@ def eip712_filtering_raw(self, name: str, sig: bytes, discarded: bool):

def sign(self,
bip32_path: str,
tx_params: dict):
tx_params: dict,
mode: SignMode = SignMode.BASIC):
tx = Web3().eth.account.create().sign_transaction(tx_params).rawTransaction
prefix = bytes()
suffix = []
Expand All @@ -223,7 +239,7 @@ def sign(self,
suffix = [int(tx_params["chainId"]), bytes(), bytes()]
decoded = rlp.decode(tx)[:-3] # remove already computed signature
tx = prefix + rlp.encode(decoded + suffix)
chunks = self._cmd_builder.sign(bip32_path, tx, suffix)
chunks = self._cmd_builder.sign(bip32_path, tx, mode)
for chunk in chunks[:-1]:
self._exchange(chunk)
return self._exchange_async(chunks[-1])
Expand Down Expand Up @@ -530,3 +546,15 @@ def provide_network_information(self,
assert response.status == StatusWord.OK
response = self._exchange(chunks[-1])
assert response.status == StatusWord.OK

def provide_enum_value(self, payload: bytes) -> RAPDU:
chunks = self._cmd_builder.provide_enum_value(payload)
for chunk in chunks[:-1]:
self._exchange(chunk)
return self._exchange(chunks[-1])

def provide_transaction_info(self, payload: bytes) -> RAPDU:
chunks = self._cmd_builder.provide_transaction_info(payload)
for chunk in chunks[:-1]:
self._exchange(chunk)
return self._exchange(chunks[-1])
28 changes: 25 additions & 3 deletions client/src/ledger_app_clients/ethereum/command_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class InsType(IntEnum):
SIGN = 0x04
PERSONAL_SIGN = 0x08
PROVIDE_ERC20_TOKEN_INFORMATION = 0x0a
EXTERNAL_PLUGIN_SETUP = 0x12
PROVIDE_NFT_INFORMATION = 0x14
SET_PLUGIN = 0x16
PERFORM_PRIVACY_OPERATION = 0x18
Expand All @@ -24,7 +25,8 @@ class InsType(IntEnum):
EIP712_SIGN = 0x0c
GET_CHALLENGE = 0x20
PROVIDE_TRUSTED_NAME = 0x22
EXTERNAL_PLUGIN_SETUP = 0x12
PROVIDE_ENUM_VALUE = 0x24
PROVIDE_TRANSACTION_INFO = 0x26
PROVIDE_NETWORK_INFORMATION = 0x30


Expand Down Expand Up @@ -261,15 +263,15 @@ def set_external_plugin(self, plugin_name: str, contract_address: bytes, selecto
0x00,
data)

def sign(self, bip32_path: str, rlp_data: bytes, vrs: list) -> list[bytes]:
def sign(self, bip32_path: str, rlp_data: bytes, p2: int) -> list[bytes]:
apdus = list()
payload = pack_derivation_path(bip32_path)
payload += rlp_data
p1 = P1Type.SIGN_FIRST_CHUNK
while len(payload) > 0:
apdus.append(self._serialize(InsType.SIGN,
p1,
0x00,
p2,
payload[:0xff]))
payload = payload[0xff:]
p1 = P1Type.SIGN_SUBSQT_CHUNK
Expand Down Expand Up @@ -427,3 +429,23 @@ def provide_network_information(self,
icon = icon[0xff:]
p1 = P1Type.FOLLOWING_CHUNK
return chunks

def common_tlv_serialize(self, tlv_payload: bytes, ins: InsType) -> list[bytes]:
apaillier-ledger marked this conversation as resolved.
Show resolved Hide resolved
chunks = list()
payload = struct.pack(">H", len(tlv_payload))
payload += tlv_payload
p1 = 1
while len(payload) > 0:
chunks.append(self._serialize(ins,
p1,
0x00,
payload[:0xff]))
payload = payload[0xff:]
p1 = 0
return chunks

def provide_enum_value(self, tlv_payload: bytes) -> list[bytes]:
return self.common_tlv_serialize(tlv_payload, InsType.PROVIDE_ENUM_VALUE)

def provide_transaction_info(self, tlv_payload: bytes) -> list[bytes]:
return self.common_tlv_serialize(tlv_payload, InsType.PROVIDE_TRANSACTION_INFO)
59 changes: 59 additions & 0 deletions client/src/ledger_app_clients/ethereum/enum_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from enum import IntEnum
from typing import Optional
from .tlv import format_tlv
from .keychain import sign_data, Key


class Tag(IntEnum):
VERSION = 0x00
CHAIN_ID = 0x01
CONTRACT_ADDR = 0x02
SELECTOR = 0x03
ID = 0x04
VALUE = 0x05
NAME = 0x06
SIGNATURE = 0xff


class EnumValue:
version: int
chain_id: int
contract_addr: bytes
selector: bytes
id: int
value: int
name: str
signature: Optional[bytes] = None

def __init__(self,
version: int,
chain_id: int,
contract_addr: bytes,
selector: bytes,
id: int,
value: int,
name: str,
signature: Optional[bytes] = None):
self.version = version
self.chain_id = chain_id
self.contract_addr = contract_addr
self.selector = selector
self.id = id
self.value = value
self.name = name
self.signature = signature

def serialize(self) -> bytes:
payload = bytearray()
payload += format_tlv(Tag.VERSION, self.version)
payload += format_tlv(Tag.CHAIN_ID, self.chain_id)
payload += format_tlv(Tag.CONTRACT_ADDR, self.contract_addr)
payload += format_tlv(Tag.SELECTOR, self.selector)
payload += format_tlv(Tag.ID, self.id)
payload += format_tlv(Tag.VALUE, self.value)
payload += format_tlv(Tag.NAME, self.name)
sig = self.signature
if sig is None:
sig = sign_data(Key.CAL, payload)
payload += format_tlv(Tag.SIGNATURE, sig)
return payload
Loading
Loading