Skip to content

Commit 2ae8e0d

Browse files
Merge pull request #698 from LedgerHQ/feat/apa/trusted_name_changes
Trusted name misc changes & fixes
2 parents ef0839b + d6ac35f commit 2ae8e0d

File tree

9 files changed

+182
-134
lines changed

9 files changed

+182
-134
lines changed

client/src/ledger_app_clients/ethereum/client.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def perform_privacy_operation(self,
255255
bip32_path,
256256
pubkey))
257257

258-
def _provide_trusted_name_common(self, payload: bytes) -> RAPDU:
258+
def _provide_trusted_name_common(self, payload: bytes, name_source: TrustedNameSource) -> RAPDU:
259259
if self._pki_client is None:
260260
print(f"Ledger-PKI Not supported on '{self._firmware.name}'")
261261
else:
@@ -272,10 +272,16 @@ def _provide_trusted_name_common(self, payload: bytes) -> RAPDU:
272272

273273
self._pki_client.send_certificate(PKIPubKeyUsage.PUBKEY_USAGE_COIN_META, bytes.fromhex(cert_apdu))
274274
payload += format_tlv(FieldTag.STRUCT_TYPE, 3) # TrustedName
275-
payload += format_tlv(FieldTag.SIGNER_KEY_ID, 0) # test key
275+
if name_source == TrustedNameSource.CAL:
276+
key_id = 6
277+
key = Key.CAL
278+
else:
279+
key_id = 3
280+
key = Key.TRUSTED_NAME
281+
payload += format_tlv(FieldTag.SIGNER_KEY_ID, key_id) # test key
276282
payload += format_tlv(FieldTag.SIGNER_ALGO, 1) # secp256k1
277283
payload += format_tlv(FieldTag.DER_SIGNATURE,
278-
sign_data(Key.TRUSTED_NAME, payload))
284+
sign_data(key, payload))
279285
chunks = self._cmd_builder.provide_trusted_name(payload)
280286
for chunk in chunks[:-1]:
281287
self._exchange(chunk)
@@ -287,7 +293,7 @@ def provide_trusted_name_v1(self, addr: bytes, name: str, challenge: int) -> RAP
287293
payload += format_tlv(FieldTag.COIN_TYPE, 0x3c) # ETH in slip-44
288294
payload += format_tlv(FieldTag.TRUSTED_NAME, name)
289295
payload += format_tlv(FieldTag.ADDRESS, addr)
290-
return self._provide_trusted_name_common(payload)
296+
return self._provide_trusted_name_common(payload, TrustedNameSource.ENS)
291297

292298
def provide_trusted_name_v2(self,
293299
addr: bytes,
@@ -311,7 +317,7 @@ def provide_trusted_name_v2(self,
311317
if not_valid_after is not None:
312318
assert len(not_valid_after) == 3
313319
payload += format_tlv(FieldTag.NOT_VALID_AFTER, struct.pack("BBB", *not_valid_after))
314-
return self._provide_trusted_name_common(payload)
320+
return self._provide_trusted_name_common(payload, name_source)
315321

316322
def set_plugin(self,
317323
plugin_name: str,

src_bagl/ui_flow_signTx.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,10 @@ void ux_approve_tx(bool fromPlugin) {
267267
}
268268
#ifdef HAVE_TRUSTED_NAME
269269
uint64_t chain_id = get_tx_chain_id();
270-
e_name_type type = TYPE_ACCOUNT;
271-
if (has_trusted_name(1, &type, &chain_id, tmpContent.txContent.destination)) {
270+
e_name_type type = TN_TYPE_ACCOUNT;
271+
e_name_source source = TN_SOURCE_ENS;
272+
if (get_trusted_name(1, &type, 1, &source, &chain_id, tmpContent.txContent.destination) !=
273+
NULL) {
272274
ux_approval_tx_flow[step++] = &ux_trusted_name_step;
273275
if (N_storage.verbose_trusted_name) {
274276
ux_approval_tx_flow[step++] = &ux_approval_to_step;

src_features/provideTrustedName/cmd_provide_trusted_name.c

Lines changed: 99 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ typedef enum {
6363
NFT_ID = 0x72,
6464
} e_tlv_tag;
6565

66-
typedef enum { KEY_ID_TEST = 0x00, KEY_ID_PROD = 0x03 } e_key_id;
66+
typedef enum { TN_KEY_ID_DOMAIN_SVC = 0x03, TN_KEY_ID_CAL = 0x06 } e_tn_key_id;
6767

6868
typedef struct {
6969
uint8_t *buf;
@@ -90,7 +90,7 @@ typedef struct {
9090
} s_trusted_name_info;
9191

9292
typedef struct {
93-
e_key_id key_id;
93+
e_tn_key_id key_id;
9494
uint8_t input_sig_size;
9595
const uint8_t *input_sig;
9696
cx_sha256_t hash_ctx;
@@ -110,10 +110,56 @@ static s_tlv_payload g_tlv_payload = {0};
110110
static s_trusted_name_info g_trusted_name_info = {0};
111111
char g_trusted_name[TRUSTED_NAME_MAX_LENGTH + 1];
112112

113+
static bool matching_type(e_name_type type, uint8_t type_count, const e_name_type *types) {
114+
for (int i = 0; i < type_count; ++i) {
115+
if (type == types[i]) return true;
116+
}
117+
return false;
118+
}
119+
120+
static bool matching_source(e_name_source source,
121+
uint8_t source_count,
122+
const e_name_source *sources) {
123+
for (int i = 0; i < source_count; ++i) {
124+
if (source == sources[i]) return true;
125+
}
126+
return false;
127+
}
128+
129+
static bool matching_trusted_name(const s_trusted_name_info *trusted_name,
130+
uint8_t type_count,
131+
const e_name_type *types,
132+
uint8_t source_count,
133+
const e_name_source *sources,
134+
const uint64_t *chain_id,
135+
const uint8_t *addr) {
136+
switch (trusted_name->struct_version) {
137+
case 1:
138+
if (!matching_type(TN_TYPE_ACCOUNT, type_count, types)) {
139+
return false;
140+
}
141+
if (!chain_is_ethereum_compatible(chain_id)) {
142+
return false;
143+
}
144+
break;
145+
case 2:
146+
if (!matching_type(trusted_name->name_type, type_count, types)) {
147+
return false;
148+
}
149+
if (!matching_source(trusted_name->name_source, source_count, sources)) {
150+
return false;
151+
}
152+
if (*chain_id != trusted_name->chain_id) {
153+
return false;
154+
}
155+
break;
156+
}
157+
return memcmp(addr, trusted_name->addr, ADDRESS_LENGTH) == 0;
158+
}
159+
113160
/**
114161
* Checks if a trusted name matches the given parameters
115162
*
116-
* Does not care about the trusted name source for now.
117163
* Always wipes the content of \ref g_trusted_name_info
118164
*
119165
* @param[in] types_count number of given trusted name types
@@ -122,36 +168,23 @@ char g_trusted_name[TRUSTED_NAME_MAX_LENGTH + 1];
122168
* @param[in] addr given address
123169
* @return whether there is or not
124170
*/
125-
bool has_trusted_name(uint8_t types_count,
126-
const e_name_type *types,
127-
const uint64_t *chain_id,
128-
const uint8_t *addr) {
129-
bool ret = false;
171+
const char *get_trusted_name(uint8_t type_count,
172+
const e_name_type *types,
173+
uint8_t source_count,
174+
const e_name_source *sources,
175+
const uint64_t *chain_id,
176+
const uint8_t *addr) {
177+
const char *ret = NULL;
130178

131179
if (g_trusted_name_info.rcv_flags != 0) {
132-
for (int i = 0; i < types_count; ++i) {
133-
switch (g_trusted_name_info.struct_version) {
134-
case 1:
135-
if (types[i] == TYPE_ACCOUNT) {
136-
// Check if chain ID is known to be Ethereum-compatible (same derivation
137-
// path)
138-
if ((chain_is_ethereum_compatible(chain_id)) &&
139-
(memcmp(addr, g_trusted_name_info.addr, ADDRESS_LENGTH) == 0)) {
140-
ret = true;
141-
}
142-
}
143-
break;
144-
case 2:
145-
if (types[i] == g_trusted_name_info.name_type) {
146-
if (*chain_id == g_trusted_name_info.chain_id) {
147-
ret = true;
148-
}
149-
}
150-
break;
151-
default:
152-
ret = false;
153-
}
154-
if (ret) break;
180+
if (matching_trusted_name(&g_trusted_name_info,
181+
type_count,
182+
types,
183+
source_count,
184+
sources,
185+
chain_id,
186+
addr)) {
187+
ret = g_trusted_name_info.name;
155188
}
156189
explicit_bzero(&g_trusted_name_info, sizeof(g_trusted_name_info));
157190
}
@@ -378,7 +411,7 @@ static bool handle_trusted_name(const s_tlv_data *data,
378411
return false;
379412
}
380413
if ((trusted_name_info->struct_version == 1) ||
381-
(trusted_name_info->name_type == TYPE_ACCOUNT)) {
414+
(trusted_name_info->name_type == TN_TYPE_ACCOUNT)) {
382415
// TODO: Remove once other domain name providers are supported
383416
if ((data->length < 5) ||
384417
(strncmp(".eth", (char *) &data->value[data->length - 4], 4) != 0)) {
@@ -474,10 +507,13 @@ static bool handle_trusted_name_type(const s_tlv_data *data,
474507
return false;
475508
}
476509
switch (value) {
477-
case TYPE_ACCOUNT:
478-
case TYPE_CONTRACT:
510+
case TN_TYPE_ACCOUNT:
511+
case TN_TYPE_CONTRACT:
479512
break;
480-
case TYPE_NFT:
513+
case TN_TYPE_NFT_COLLECTION:
514+
case TN_TYPE_TOKEN:
515+
case TN_TYPE_WALLET:
516+
case TN_TYPE_CONTEXT_ADDRESS:
481517
default:
482518
PRINTF("Error: unsupported trusted name type (%u)!\n", value);
483519
return false;
@@ -505,13 +541,14 @@ static bool handle_trusted_name_source(const s_tlv_data *data,
505541
return false;
506542
}
507543
switch (value) {
508-
case SOURCE_CAL:
509-
case SOURCE_ENS:
544+
case TN_SOURCE_CAL:
545+
case TN_SOURCE_ENS:
510546
break;
511-
case SOURCE_LAB:
512-
case SOURCE_UD:
513-
case SOURCE_FN:
514-
case SOURCE_DNS:
547+
case TN_SOURCE_LAB:
548+
case TN_SOURCE_UD:
549+
case TN_SOURCE_FN:
550+
case TN_SOURCE_DNS:
551+
case TN_SOURCE_DYNAMIC_RESOLVER:
515552
default:
516553
PRINTF("Error: unsupported trusted name source (%u)!\n", value);
517554
return false;
@@ -555,16 +592,22 @@ static bool handle_nft_id(const s_tlv_data *data,
555592
static bool verify_signature(const s_sig_ctx *sig_ctx) {
556593
uint8_t hash[INT256_LENGTH];
557594
cx_err_t error = CX_INTERNAL_ERROR;
558-
#ifdef HAVE_TRUSTED_NAME_TEST_KEY
559-
e_key_id valid_key_id = KEY_ID_TEST;
560-
#else
561-
e_key_id valid_key_id = KEY_ID_PROD;
562-
#endif
563595
bool ret_code = false;
596+
const uint8_t *pk;
597+
size_t pk_size;
564598

565-
if (sig_ctx->key_id != valid_key_id) {
566-
PRINTF("Error: Unknown metadata key ID %u\n", sig_ctx->key_id);
567-
return false;
599+
switch (sig_ctx->key_id) {
600+
case TN_KEY_ID_DOMAIN_SVC:
601+
pk = TRUSTED_NAME_PUB_KEY;
602+
pk_size = sizeof(TRUSTED_NAME_PUB_KEY);
603+
break;
604+
case TN_KEY_ID_CAL:
605+
pk = LEDGER_SIGNATURE_PUBLIC_KEY;
606+
pk_size = sizeof(LEDGER_SIGNATURE_PUBLIC_KEY);
607+
break;
608+
default:
609+
PRINTF("Error: Unknown metadata key ID %u\n", sig_ctx->key_id);
610+
return false;
568611
}
569612

570613
CX_CHECK(
@@ -573,10 +616,10 @@ static bool verify_signature(const s_sig_ctx *sig_ctx) {
573616
CX_CHECK(check_signature_with_pubkey("Domain Name",
574617
hash,
575618
sizeof(hash),
576-
TRUSTED_NAME_PUB_KEY,
577-
sizeof(TRUSTED_NAME_PUB_KEY),
619+
pk,
620+
pk_size,
578621
#ifdef HAVE_LEDGER_PKI
579-
CERTIFICATE_PUBLIC_KEY_USAGE_COIN_META,
622+
CERTIFICATE_PUBLIC_KEY_USAGE_TRUSTED_NAME,
580623
#endif
581624
(uint8_t *) (sig_ctx->input_sig),
582625
sig_ctx->input_sig_size));
@@ -651,8 +694,8 @@ static bool verify_struct(const s_trusted_name_info *trusted_name_info) {
651694
return false;
652695
}
653696
switch (trusted_name_info->name_type) {
654-
case TYPE_ACCOUNT:
655-
if (trusted_name_info->name_source == SOURCE_CAL) {
697+
case TN_TYPE_ACCOUNT:
698+
if (trusted_name_info->name_source == TN_SOURCE_CAL) {
656699
PRINTF("Error: cannot accept an account name from the CAL!\n");
657700
return false;
658701
}
@@ -661,8 +704,8 @@ static bool verify_struct(const s_trusted_name_info *trusted_name_info) {
661704
return false;
662705
}
663706
break;
664-
case TYPE_CONTRACT:
665-
if (trusted_name_info->name_source != SOURCE_CAL) {
707+
case TN_TYPE_CONTRACT:
708+
if (trusted_name_info->name_source != TN_SOURCE_CAL) {
666709
PRINTF("Error: cannot accept a contract name from given source (%u)!\n",
667710
trusted_name_info->name_source);
668711
return false;

src_features/provideTrustedName/trusted_name.h

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,35 @@
99
#define TRUSTED_NAME_MAX_LENGTH 30
1010

1111
typedef enum {
12-
TYPE_ACCOUNT = 1,
13-
TYPE_CONTRACT,
14-
TYPE_NFT,
12+
TN_TYPE_ACCOUNT = 1,
13+
TN_TYPE_CONTRACT,
14+
TN_TYPE_NFT_COLLECTION,
15+
TN_TYPE_TOKEN,
16+
TN_TYPE_WALLET,
17+
TN_TYPE_CONTEXT_ADDRESS,
18+
_TN_TYPE_COUNT_,
1519
} e_name_type;
1620

21+
// because the enum does not start at 0
22+
#define TN_TYPE_COUNT (_TN_TYPE_COUNT_ - TN_TYPE_ACCOUNT)
23+
1724
typedef enum {
18-
SOURCE_LAB = 0,
19-
SOURCE_CAL,
20-
SOURCE_ENS,
21-
SOURCE_UD,
22-
SOURCE_FN,
23-
SOURCE_DNS,
25+
TN_SOURCE_LAB = 0,
26+
TN_SOURCE_CAL,
27+
TN_SOURCE_ENS,
28+
TN_SOURCE_UD,
29+
TN_SOURCE_FN,
30+
TN_SOURCE_DNS,
31+
TN_SOURCE_DYNAMIC_RESOLVER,
32+
TN_SOURCE_COUNT,
2433
} e_name_source;
2534

26-
bool has_trusted_name(uint8_t types_count,
27-
const e_name_type *types,
28-
const uint64_t *chain_id,
29-
const uint8_t *addr);
35+
const char *get_trusted_name(uint8_t type_count,
36+
const e_name_type *types,
37+
uint8_t source_count,
38+
const e_name_source *sources,
39+
const uint64_t *chain_id,
40+
const uint8_t *addr);
3041
uint16_t handle_provide_trusted_name(uint8_t p1, const uint8_t *data, uint8_t length);
3142

3243
extern char g_trusted_name[TRUSTED_NAME_MAX_LENGTH + 1];

0 commit comments

Comments
 (0)