Now supports EIP-712 filtering with missing chain id & contract address

This commit is contained in:
Alexandre Paillier
2022-08-16 18:44:28 +02:00
parent 089de9e28f
commit 3ee1fa419a
9 changed files with 55 additions and 6 deletions

View File

@@ -52,6 +52,10 @@ bool eip712_context_init(void) {
return false;
}
// Since they are optional, they might not be provided by the JSON data
explicit_bzero(eip712_context->contract_addr, sizeof(eip712_context->contract_addr));
eip712_context->chain_id = 0;
struct_state = NOT_INITIALIZED;
return true;

View File

@@ -8,6 +8,7 @@
typedef struct {
uint8_t contract_addr[ADDRESS_LENGTH];
uint64_t chain_id;
uint8_t schema_hash[224 / 8];
} s_eip712_context;

View File

@@ -181,15 +181,14 @@ static bool field_hash_domain_special_fields(const void *const field_ptr,
}
memcpy(eip712_context->contract_addr, data, data_length);
} else if (strncmp(key, "chainId", keylen) == 0) {
uint64_t chainId = u64_from_BE(data, data_length);
if (chainId != chainConfig->chainId) {
eip712_context->chain_id = u64_from_BE(data, data_length);
if ((eip712_context->chain_id != 0) && (eip712_context->chain_id != chainConfig->chainId)) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
PRINTF("EIP712Domain chain ID mismatch, expected 0x%.*h, got 0x%.*h !\n",
sizeof(chainConfig->chainId),
&chainConfig->chainId,
sizeof(chainId),
&chainId);
sizeof(eip712_context->chain_id),
&eip712_context->chain_id);
return false;
}
}

View File

@@ -66,7 +66,7 @@ static bool verify_filtering_signature(uint8_t dname_length,
cx_sha256_init(&hash_ctx);
// Chain ID
chain_id = __builtin_bswap64(chainConfig->chainId);
chain_id = __builtin_bswap64(eip712_context->chain_id);
hash_nbytes((uint8_t *) &chain_id, sizeof(chain_id), (cx_hash_t *) &hash_ctx);
// Contract address

View File

@@ -286,9 +286,16 @@ def prepare_filtering(filtr_data, message):
else:
filtering_paths = {}
def handle_optional_domain_values(domain):
if "chainId" not in domain.keys():
domain["chainId"] = 0
if "verifyingContract" not in domain.keys():
domain["verifyingContract"] = "0x0000000000000000000000000000000000000000"
def init_signature_context(types, domain):
global sig_ctx
handle_optional_domain_values(domain)
env_key = os.environ["CAL_SIGNATURE_TEST_KEY"]
key = base64.b64decode(env_key).decode() # base 64 string -> decode bytes -> string
sig_ctx["key"] = SigningKey.from_pem(key, hashlib.sha256)

View File

@@ -0,0 +1,23 @@
{
"domain": {
"name": "Who are You?",
"version": "1"
},
"message": {
"banner": "Please sign this message with your wallet",
"curDate": 1660659773,
"id": 38
},
"primaryType": "Auth",
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" }
],
"Auth": [
{ "name": "banner", "type": "string" },
{ "name": "curDate", "type": "uint32" },
{ "name": "id", "type": "uint8" }
]
}
}

View File

@@ -0,0 +1,7 @@
{
"name": "Ethereum sign-in",
"fields": {
"curDate": "Timestamp",
"id": "Identifier"
}
}

View File

@@ -0,0 +1,4 @@
[signature]
v = 1b
r = 7be1671577753c13bfd1da8b234b6df8484daf47351c2366637fd291dd4aa4d9
s = 1a7ffbb01dc8a64e9ee97d19b8f154e9eecbe0b1bfb9dcfa781a65e474573963

View File

@@ -75,6 +75,10 @@ def test_eip712_new(app_client: EthereumClient, input_file: Path, verbose: bool,
assert InputData.process_file(app_client, input_file, filter_file) == True
v, r, s = app_client.eip712_sign_new(bip32)
#print("[signature]")
#print("v = %s" % (v.hex()))
#print("r = %s" % (r.hex()))
#print("s = %s" % (s.hex()))
assert v == bytes.fromhex(config["signature"]["v"])
assert r == bytes.fromhex(config["signature"]["r"])