Skip to content

Commit 22f2f3f

Browse files
Merge pull request #998 from LedgerHQ/ref/eip712_amount_joins
EIP-712 amount-joins filtering refactoring
2 parents 5b2c852 + 8c0a5a1 commit 22f2f3f

87 files changed

Lines changed: 146 additions & 153 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

client/src/ledger_app_clients/ethereum/eip712/InputData.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -191,37 +191,31 @@ def encode_bytes_dyn(value: str, typesize: int) -> bytes:
191191
encoding_functions[EIP712FieldType.DYN_BYTES] = encode_bytes_dyn
192192

193193

194-
def send_filtering_token(token_idx: int):
195-
assert token_idx < len(filtering_tokens)
196-
if len(filtering_tokens[token_idx]) > 0:
197-
token = filtering_tokens[token_idx]
198-
if not token["sent"]:
199-
response = app_client.provide_token_metadata(token["ticker"],
200-
bytes.fromhex(token["addr"][2:]),
201-
token["decimals"],
202-
token["chain_id"])
203-
assert response.status == StatusWord.OK, \
204-
f"Error sending token metadata for {token['ticker']}: {response.status}"
205-
token["sent"] = True
194+
def send_all_filtering_tokens(tokens: list[dict]):
195+
for token in tokens:
196+
response = app_client.provide_token_metadata(token["ticker"],
197+
bytes.fromhex(token["addr"][2:]),
198+
token["decimals"],
199+
token["chain_id"])
200+
assert response.status == StatusWord.OK, \
201+
f"Error sending token metadata for {token['ticker']}: {response.status}"
206202

207203

208204
def send_filter(path: str, discarded: bool) -> Optional[Callable]:
209205
ret: Optional[Callable] = None
210206
assert path in filtering_paths.keys()
211207

212208
if filtering_paths[path]["type"].startswith("amount_join_"):
213-
if "token" in filtering_paths[path].keys():
214-
token_idx = filtering_paths[path]["token"]
215-
send_filtering_token(token_idx)
209+
if "id" in filtering_paths[path].keys():
210+
join_id = filtering_paths[path]["id"]
216211
else:
217212
# Permit (ERC-2612)
218-
send_filtering_token(0)
219-
token_idx = 0xff
213+
join_id = 0xff
220214
if filtering_paths[path]["type"].endswith("_token"):
221-
send_filtering_amount_join_token(path, token_idx, discarded)
215+
send_filtering_amount_join_token(path, join_id, discarded)
222216
elif filtering_paths[path]["type"].endswith("_value"):
223217
send_filtering_amount_join_value(path,
224-
token_idx,
218+
join_id,
225219
filtering_paths[path]["name"],
226220
discarded)
227221
elif filtering_paths[path]["type"] == "datetime":
@@ -366,29 +360,29 @@ def send_filtering_message_info(display_name: str, filters_count: int):
366360
f"Error sending filtering message info for {display_name}: {response.status}"
367361

368362

369-
def send_filtering_amount_join_token(path: str, token_idx: int, discarded: bool):
363+
def send_filtering_amount_join_token(path: str, join_id: int, discarded: bool):
370364
to_sign = start_signature_payload(sig_ctx, 11)
371365
to_sign += path.encode()
372-
to_sign.append(token_idx)
366+
to_sign.append(join_id)
373367
sig = keychain.sign_data(keychain.Key.CAL, to_sign)
374-
with app_client.eip712_filtering_amount_join_token(token_idx, sig, discarded):
368+
with app_client.eip712_filtering_amount_join_token(join_id, sig, discarded):
375369
pass
376370
response = app_client.response()
377371
assert response.status == StatusWord.OK, \
378-
f"Error sending filtering amount join token for {path} with token index {token_idx}: {response.status}"
372+
f"Error sending filtering amount join token for {path} with token index {join_id}: {response.status}"
379373

380374

381-
def send_filtering_amount_join_value(path: str, token_idx: int, display_name: str, discarded: bool):
375+
def send_filtering_amount_join_value(path: str, join_id: int, display_name: str, discarded: bool):
382376
to_sign = start_signature_payload(sig_ctx, 22)
383377
to_sign += path.encode()
384378
to_sign += display_name.encode()
385-
to_sign.append(token_idx)
379+
to_sign.append(join_id)
386380
sig = keychain.sign_data(keychain.Key.CAL, to_sign)
387-
with app_client.eip712_filtering_amount_join_value(token_idx, display_name, sig, discarded):
381+
with app_client.eip712_filtering_amount_join_value(join_id, display_name, sig, discarded):
388382
pass
389383
response = app_client.response()
390384
assert response.status == StatusWord.OK, \
391-
f"Error sending filtering amount join value for {path} with token index {token_idx}: {response.status}"
385+
f"Error sending filtering amount join value for {path} with token index {join_id}: {response.status}"
392386

393387

394388
def send_filtering_datetime(path: str, display_name: str, discarded: bool):
@@ -536,9 +530,6 @@ def prepare_filtering(data_json, filtr_data):
536530

537531
if "tokens" in filtr_data:
538532
filtering_tokens = filtr_data["tokens"]
539-
for token in filtering_tokens:
540-
if len(token) > 0:
541-
token["sent"] = False
542533
else:
543534
filtering_tokens = []
544535

@@ -627,6 +618,7 @@ def process_data(aclient: EthAppClient,
627618
assert response.status == StatusWord.OK, \
628619
f"Error activating filtering: {response.status}"
629620
prepare_filtering(data_json, filters)
621+
send_all_filtering_tokens(filtering_tokens)
630622

631623
# Send ledgerPKI certificate
632624
app_client.pki_client.send_certificate(PKIPubKeyUsage.PUBKEY_USAGE_COIN_META)

doc/ethapp.adoc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -850,18 +850,18 @@ The first byte is used as a magic number so that a signature of one type cannot
850850
851851
The signature is computed on :
852852
853-
11 || chain ID (BE) || contract address || schema hash || field path || token index
853+
11 || chain ID (BE) || contract address || schema hash || field path || join identifier
854854
855855
##### Amount-join value
856856
857857
This command should come before the corresponding *SEND STRUCT IMPLEMENTATION* and are only usable for message fields (and not domain ones).
858858
The first byte is used as a magic number so that a signature of one type cannot be valid as another type.
859859
860-
A token index of 0xFF indicates the token address is in the _verifyingContract_ field of the EIP712Domain so the app won't receive an amount-join token filtering APDU. This enables support for Permit (ERC-2612) messages.
860+
A join identifier of 0xFF indicates the token address is in the _verifyingContract_ field of the EIP712Domain so the app won't receive an amount-join token filtering APDU. This enables support for Permit (ERC-2612) messages.
861861
862862
The signature is computed on :
863863
864-
22 || chain ID (BE) || contract address || schema hash || field path || display name || token index
864+
22 || chain ID (BE) || contract address || schema hash || field path || display name || join identifier
865865
866866
##### Date / Time
867867
@@ -1145,7 +1145,7 @@ enum CalldataParamPresence
11451145
[width="80%"]
11461146
|==========================================
11471147
| *Description* | *Length (byte)*
1148-
| Token index | 1
1148+
| Join identifier | 1
11491149
| Signature length | 1
11501150
| Signature | variable
11511151
|==========================================
@@ -1157,7 +1157,7 @@ enum CalldataParamPresence
11571157
| *Description* | *Length (byte)*
11581158
| Display name length | 1
11591159
| Display name | variable
1160-
| Token index | 1
1160+
| Join identifier | 1
11611161
| Signature length | 1
11621162
| Signature | variable
11631163
|==========================================

src/features/sign_message_eip712/filtering.c

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,6 @@ static bool sig_verif_end(cx_sha256_t *hash_ctx, const uint8_t *sig, uint8_t sig
145145
return true;
146146
}
147147

148-
/**
149-
* Check if the given token index is valid
150-
*
151-
* @param[in] idx token index
152-
* @return whether the index is valid or not
153-
*/
154-
static bool check_token_index(uint8_t idx) {
155-
if (idx >= MAX_ASSETS) {
156-
PRINTF("Error: token index out of range (%u)\n", idx);
157-
return false;
158-
}
159-
return true;
160-
}
161-
162148
/**
163149
* Check if the current element's typename matches the expected one
164150
*
@@ -1038,7 +1024,7 @@ bool filtering_amount_join_token(const uint8_t *payload,
10381024
uint8_t length,
10391025
bool discarded,
10401026
uint32_t *path_crc) {
1041-
uint8_t token_idx;
1027+
uint8_t join_id;
10421028
uint8_t sig_len;
10431029
const uint8_t *sig;
10441030
uint8_t offset = 0;
@@ -1049,10 +1035,10 @@ bool filtering_amount_join_token(const uint8_t *payload,
10491035
}
10501036

10511037
// Parsing
1052-
if ((offset + sizeof(token_idx)) > length) {
1038+
if ((offset + sizeof(join_id)) > length) {
10531039
return false;
10541040
}
1055-
token_idx = payload[offset++];
1041+
join_id = payload[offset++];
10561042
if ((offset + sizeof(sig_len)) > length) {
10571043
return false;
10581044
}
@@ -1068,17 +1054,17 @@ bool filtering_amount_join_token(const uint8_t *payload,
10681054
return false;
10691055
}
10701056
hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc);
1071-
hash_byte(token_idx, (cx_hash_t *) &hash_ctx);
1057+
hash_byte(join_id, (cx_hash_t *) &hash_ctx);
10721058
if (!sig_verif_end(&hash_ctx, sig, sig_len)) {
10731059
return false;
10741060
}
10751061

10761062
// Handling
1077-
if (!check_typename("address") || !check_token_index(token_idx)) {
1063+
if (!check_typename("address")) {
10781064
return false;
10791065
}
10801066
ui_712_flag_field(false, false, true, false, false, false);
1081-
ui_712_token_join_prepare_addr_check(token_idx);
1067+
ui_712_token_join_prepare_addr_check(join_id);
10821068
return true;
10831069
}
10841070

@@ -1097,7 +1083,7 @@ bool filtering_amount_join_value(const uint8_t *payload,
10971083
uint32_t *path_crc) {
10981084
uint8_t name_len;
10991085
const char *name;
1100-
uint8_t token_idx;
1086+
uint8_t join_id;
11011087
uint8_t sig_len;
11021088
const uint8_t *sig;
11031089
uint8_t offset = 0;
@@ -1120,10 +1106,10 @@ bool filtering_amount_join_value(const uint8_t *payload,
11201106
}
11211107
name = (char *) &payload[offset];
11221108
offset += name_len;
1123-
if ((offset + sizeof(token_idx)) > length) {
1109+
if ((offset + sizeof(join_id)) > length) {
11241110
return false;
11251111
}
1126-
token_idx = payload[offset++];
1112+
join_id = payload[offset++];
11271113
if ((offset + sizeof(sig_len)) > length) {
11281114
return false;
11291115
}
@@ -1140,32 +1126,25 @@ bool filtering_amount_join_value(const uint8_t *payload,
11401126
}
11411127
hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc);
11421128
hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx);
1143-
hash_byte(token_idx, (cx_hash_t *) &hash_ctx);
1129+
hash_byte(join_id, (cx_hash_t *) &hash_ctx);
11441130
if (!sig_verif_end(&hash_ctx, sig, sig_len)) {
11451131
return false;
11461132
}
11471133

11481134
// Handling
1149-
if (token_idx == TOKEN_IDX_ADDR_IN_DOMAIN) {
1135+
if (join_id == TOKEN_IDX_ADDR_IN_DOMAIN) {
11501136
// Permit (ERC-2612)
1151-
int resolved_idx = get_asset_index_by_addr(eip712_context->contract_addr);
1152-
1153-
if (resolved_idx == -1) {
1154-
PRINTF("ERROR: Could not find asset info for verifyingContract address!\n");
1155-
return false;
1156-
}
1157-
token_idx = (uint8_t) resolved_idx;
1137+
ui_712_token_join_prepare_addr_check(join_id);
11581138
// simulate as if we had received a token-join addr
1159-
ui_712_token_join_prepare_addr_check(token_idx);
1160-
if (!amount_join_set_token_received()) {
1139+
if (!ui_712_set_amount_join_token_addr(eip712_context->contract_addr)) {
11611140
return false;
11621141
}
11631142
}
1164-
if (!check_typename("uint") || !check_token_index(token_idx)) {
1143+
if (!check_typename("uint")) {
11651144
return false;
11661145
}
11671146
ui_712_flag_field(false, false, true, false, false, false);
1168-
return ui_712_token_join_prepare_amount(token_idx, name, name_len);
1147+
return ui_712_token_join_prepare_amount(join_id, name, name_len);
11691148
}
11701149

11711150
/**

0 commit comments

Comments
 (0)