Update the ragger app client to support "set external plugin" APDU and take into account PR review remarks
This commit is contained in:
committed by
Alexandre Paillier
parent
eeb52344df
commit
5d1d16c2de
@@ -2,7 +2,7 @@ import rlp
|
||||
from enum import IntEnum
|
||||
from ragger.backend import BackendInterface
|
||||
from ragger.utils import RAPDU
|
||||
from typing import List, Optional, Union
|
||||
from typing import List, Optional
|
||||
|
||||
from .command_builder import CommandBuilder
|
||||
from .eip712 import EIP712FieldType
|
||||
@@ -30,8 +30,7 @@ class StatusWord(IntEnum):
|
||||
CONDITION_NOT_SATISFIED = 0x6985
|
||||
REF_DATA_NOT_FOUND = 0x6a88
|
||||
|
||||
|
||||
class DOMAIN_NAME_TAG(IntEnum):
|
||||
class DomainNameTag(IntEnum):
|
||||
STRUCTURE_TYPE = 0x01
|
||||
STRUCTURE_VERSION = 0x02
|
||||
CHALLENGE = 0x12
|
||||
@@ -52,7 +51,7 @@ class EthAppClient:
|
||||
return self._client.exchange_async_raw(payload)
|
||||
|
||||
def response(self) -> Optional[RAPDU]:
|
||||
return self._client._last_async_response
|
||||
return self._client.last_async_response
|
||||
|
||||
def eip712_send_struct_def_struct_name(self, name: str):
|
||||
return self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name))
|
||||
@@ -190,15 +189,15 @@ class EthAppClient:
|
||||
chain_id))
|
||||
|
||||
def provide_domain_name(self, challenge: int, name: str, addr: bytes):
|
||||
payload = format_tlv(DOMAIN_NAME_TAG.STRUCTURE_TYPE, 3) # TrustedDomainName
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.STRUCTURE_VERSION, 1)
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_KEY_ID, 0) # test key
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_ALGO, 1) # secp256k1
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.CHALLENGE, challenge)
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.COIN_TYPE, 0x3c) # ETH in slip-44
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.DOMAIN_NAME, name)
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.ADDRESS, addr)
|
||||
payload += format_tlv(DOMAIN_NAME_TAG.SIGNATURE,
|
||||
payload = format_tlv(DomainNameTag.STRUCTURE_TYPE, 3) # TrustedDomainName
|
||||
payload += format_tlv(DomainNameTag.STRUCTURE_VERSION, 1)
|
||||
payload += format_tlv(DomainNameTag.SIGNER_KEY_ID, 0) # test key
|
||||
payload += format_tlv(DomainNameTag.SIGNER_ALGO, 1) # secp256k1
|
||||
payload += format_tlv(DomainNameTag.CHALLENGE, challenge)
|
||||
payload += format_tlv(DomainNameTag.COIN_TYPE, 0x3c) # ETH in slip-44
|
||||
payload += format_tlv(DomainNameTag.DOMAIN_NAME, name)
|
||||
payload += format_tlv(DomainNameTag.ADDRESS, addr)
|
||||
payload += format_tlv(DomainNameTag.SIGNATURE,
|
||||
sign_data(Key.DOMAIN_NAME, payload))
|
||||
|
||||
chunks = self._cmd_builder.provide_domain_name(payload)
|
||||
@@ -271,3 +270,7 @@ class EthAppClient:
|
||||
key_id,
|
||||
algo_id,
|
||||
sig))
|
||||
|
||||
|
||||
def external_plugin_setup(self, plugin_name: str, contract_address: bytes, method_selelector: bytes, sig: bytes):
|
||||
return self._send(self._cmd_builder.external_plugin_setup(plugin_name, contract_address, method_selelector, sig))
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# documentation about APDU format is available here:
|
||||
# https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc
|
||||
|
||||
import struct
|
||||
from enum import IntEnum
|
||||
from typing import Optional
|
||||
@@ -18,6 +21,7 @@ class InsType(IntEnum):
|
||||
EIP712_SIGN = 0x0c
|
||||
GET_CHALLENGE = 0x20
|
||||
PROVIDE_DOMAIN_NAME = 0x22
|
||||
EXTERNAL_PLUGIN_SETUP = 0x12
|
||||
|
||||
|
||||
class P1Type(IntEnum):
|
||||
@@ -178,6 +182,19 @@ class CommandBuilder:
|
||||
P2Type.FILTERING_FIELD_NAME,
|
||||
self._eip712_filtering_send_name(name, sig))
|
||||
|
||||
def external_plugin_setup(self, plugin_name: str, contract_address: bytes, method_selelector: bytes, sig: bytes) -> bytes:
|
||||
data = bytearray()
|
||||
data.append(len(plugin_name))
|
||||
data += self._string_to_bytes(plugin_name)
|
||||
data += contract_address
|
||||
data += method_selelector
|
||||
data += sig
|
||||
|
||||
return self._serialize(InsType.EXTERNAL_PLUGIN_SETUP,
|
||||
P1Type.COMPLETE_SEND,
|
||||
0x00,
|
||||
data)
|
||||
|
||||
def sign(self, bip32_path: str, rlp_data: bytes) -> list[bytes]:
|
||||
apdus = list()
|
||||
payload = pack_derivation_path(bip32_path)
|
||||
|
||||
@@ -49,20 +49,36 @@ __attribute__((section(".boot"))) int main(int arg0) {
|
||||
|
||||
check_api_level(CX_COMPAT_APILEVEL);
|
||||
|
||||
// Check if plugin is called from the dashboard.
|
||||
if (!arg0) {
|
||||
// Called from dashboard, launch Ethereum app
|
||||
call_app_ethereum();
|
||||
return 0;
|
||||
} else {
|
||||
// Not called from dashboard: called from the ethereum app!
|
||||
// launch plugin main
|
||||
plugin_main(arg0);
|
||||
BEGIN_TRY {
|
||||
TRY {
|
||||
// Check if plugin is called from the dashboard.
|
||||
if (!arg0) {
|
||||
// Called from dashboard, launch Ethereum app
|
||||
call_app_ethereum();
|
||||
|
||||
// Will not get reached.
|
||||
__builtin_unreachable();
|
||||
|
||||
os_sched_exit(-1);
|
||||
|
||||
} else {
|
||||
// Not called from dashboard: called from the ethereum app!
|
||||
// launch plugin main
|
||||
plugin_main(arg0);
|
||||
}
|
||||
|
||||
// Call `os_lib_end`, go back to the ethereum app.
|
||||
os_lib_end();
|
||||
|
||||
// Will not get reached.
|
||||
__builtin_unreachable();
|
||||
}
|
||||
CATCH_OTHER(e) {
|
||||
PRINTF("Exiting following exception: %d\n", e);
|
||||
}
|
||||
FINALLY {
|
||||
os_lib_end();
|
||||
}
|
||||
}
|
||||
|
||||
// Call `os_lib_end`, go back to the ethereum app.
|
||||
os_lib_end();
|
||||
|
||||
// Will not get reached.
|
||||
return 0;
|
||||
}
|
||||
END_TRY;
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
*****************************************************************************/
|
||||
|
||||
// applicative main for plugins
|
||||
void plugin_main(int arg0);
|
||||
void plugin_main(int arg0);
|
||||
|
||||
Reference in New Issue
Block a user