1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 06:18:07 +00:00

Fix Cardano Shelley public key validation

In Shelley Cardano started using the purpose 1852'. Unfortunately,
we completely missed that the public key path validation fuction checks
for purpose 44' explicitly, which means that the user is shown a warning
when deriving public key with the purpose 1852'. Which is always when
"logging in" to a wallet. This commit should fix that.

I've also updated type hinting in get_public_key.
This commit is contained in:
gabrielkerekes 2020-08-04 12:24:53 +02:00 committed by Tomas Susanka
parent c3afb93837
commit 683d7420ff

View File

@ -4,21 +4,23 @@ from trezor import log, wire
from trezor.messages.CardanoPublicKey import CardanoPublicKey
from trezor.messages.HDNodeType import HDNodeType
from apps.common import layout, paths
from apps.common import HARDENED, layout, paths
from apps.common.seed import remove_ed25519_prefix
from . import CURVE, seed
from .helpers import purposes
if False:
from typing import List
from trezor.messages import CardanoGetPublicKey
@seed.with_keychain
async def get_public_key(ctx, msg, keychain: seed.Keychain):
async def get_public_key(
ctx: wire.Context, msg: CardanoGetPublicKey, keychain: seed.Keychain
):
await paths.validate_path(
ctx,
paths.validate_path_for_get_public_key,
keychain,
msg.address_n,
CURVE,
slip44_id=1815,
ctx, _validate_path_for_get_public_key, keychain, msg.address_n, CURVE,
)
try:
@ -33,7 +35,9 @@ async def get_public_key(ctx, msg, keychain: seed.Keychain):
return key
def _get_public_key(keychain, derivation_path: list):
def _get_public_key(
keychain: seed.Keychain, derivation_path: List[int]
) -> CardanoPublicKey:
node = keychain.derive(derivation_path)
public_key = hexlify(remove_ed25519_prefix(node.public_key())).decode()
@ -49,3 +53,26 @@ def _get_public_key(keychain, derivation_path: list):
)
return CardanoPublicKey(node=node_type, xpub=xpub_key)
def _validate_path_for_get_public_key(path: List[int]) -> bool:
"""
Modified version of paths.validate_path_for_get_public_key.
Checks if path has at least three hardened items, Byron or Shelley purpose
and slip44 id 1815. The path is allowed to have more than three items,
but all the following items have to be non-hardened.
"""
length = len(path)
if length < 3 or length > 5:
return False
if path[0] not in (purposes.BYRON, purposes.SHELLEY):
return False
if path[1] != 1815 | HARDENED:
return False
if path[2] < HARDENED or path[2] > 20 | HARDENED:
return False
if length > 3 and paths.is_hardened(path[3]):
return False
if length > 4 and paths.is_hardened(path[4]):
return False
return True