Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
public MAX_CHUNK_SIZE, total_size check, BASE_KEY_SCRIPT, Ledger link, remove multisig case
  • Loading branch information
jaskp committed Jan 27, 2024
1 parent b161ebe commit 218b6a0
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 33 deletions.
6 changes: 4 additions & 2 deletions core/src/apps/cardano/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@

ADDRESS_TYPES_MESSAGE = (
CardanoAddressType.BASE,
CardanoAddressType.BASE_KEY_SCRIPT,
CardanoAddressType.ENTERPRISE,
CardanoAddressType.REWARD
CardanoAddressType.REWARD,
)

ADDRESS_TYPES_PAYMENT = ADDRESS_TYPES_PAYMENT_KEY + ADDRESS_TYPES_PAYMENT_SCRIPT
Expand Down Expand Up @@ -247,8 +248,9 @@ def validate_cvote_payment_address_parameters(
validate_address_parameters(parameters)
assert_params_cond(parameters.address_type in ADDRESS_TYPES_SHELLEY)


def validate_message_address_parameters(
parameters: messages.CardanoAddressParametersType,
parameters: messages.CardanoAddressParametersType,
) -> None:
validate_address_parameters(parameters)
assert_params_cond(parameters.address_type in ADDRESS_TYPES_MESSAGE)
Expand Down
16 changes: 10 additions & 6 deletions core/src/apps/cardano/helpers/chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
Generic = (object,)
C = Chunk = 0

_MAX_CHUNK_SIZE = const(1024)
MAX_CHUNK_SIZE = const(1024)


def _get_chunks_count(size: int) -> int:
"""Integer-only version of `ceil(size / _MAX_CHUNK_SIZE)`."""
"""Integer-only version of `ceil(size / MAX_CHUNK_SIZE)`."""
assert size >= 0
return 0 if size == 0 else (size - 1) // _MAX_CHUNK_SIZE + 1
return 0 if size == 0 else (size - 1) // MAX_CHUNK_SIZE + 1


def _validate_chunk(
Expand All @@ -39,15 +39,19 @@ def _validate_chunk(

chunk_name = chunk.__class__.__name__

if len(chunk.data) > _MAX_CHUNK_SIZE:
if len(chunk.data) > MAX_CHUNK_SIZE:
raise ProcessError(f"Invalid {chunk_name}: Too large")

is_last_chunk = chunk_index == chunks_count - 1

if not is_last_chunk and len(chunk.data) < _MAX_CHUNK_SIZE:
if not is_last_chunk and len(chunk.data) < MAX_CHUNK_SIZE:
raise ProcessError(f"Invalid intermediate {chunk_name}: Too small")

if is_last_chunk and len(chunk.data) != total_size % _MAX_CHUNK_SIZE:
if (
is_last_chunk
# check whether this chunk and preceding chunks add up to the supposed size
and len(chunk.data) + MAX_CHUNK_SIZE * (chunks_count - 1) != total_size
):
raise ProcessError(
f"Invalid last {chunk_name}: Size inconsistent with total bytes"
)
Expand Down
18 changes: 11 additions & 7 deletions core/src/apps/cardano/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,27 +121,31 @@ def is_printable_ascii(bytestring: bytes) -> bool:


def is_unambiguous_ascii(bytestring: bytes) -> bool:
"""Checks whether the bytestring can be printed as ASCII without confusion."""
# empty string is unambiguous
# because text consisting only of spaces gets rejected later in this function
"""
Checks whether the bytestring can be printed as ASCII without confusion.
Based on https://github.com/vacuumlabs/ledger-app-cardano-shelley/blob/6ddc60e8fdff13e35bff5cdf108b84b81a79f10c/src/textUtils.c#L274
"""
# no empty strings
if len(bytestring) == 0:
return True
return False

# no non-printable ascii except spaces
if not is_printable_ascii(bytestring):
return False

SPACE = ord(" ")

# no leading space
if bytestring[0] == ord(" "):
if bytestring[0] == SPACE:
return False

# no trailing space
if bytestring[-1] == ord(" "):
if bytestring[-1] == SPACE:
return False

# no consecutive spaces
for a, b in zip(bytestring, bytestring[1:]):
if a == ord(" ") and b == ord(" "):
if a == SPACE and b == SPACE:
return False

return True
29 changes: 17 additions & 12 deletions core/src/apps/cardano/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,17 @@ async def confirm_inline_datum(first_chunk: bytes, inline_datum_size: int) -> No
)


async def confirm_reference_script(
first_chunk: bytes, reference_script_size: int
) -> None:
await _confirm_tx_data_chunk(
"confirm_reference_script",
"Reference script",
first_chunk,
reference_script_size,
)


async def confirm_message_payload(
payload_first_chunk: bytes,
payload_hash: bytes,
Expand All @@ -283,7 +294,12 @@ async def confirm_message_payload(
) -> None:
props: list[PropertyType]

if is_unambiguous_ascii(payload_first_chunk) and not prefer_hex_display:
if not payload_first_chunk:
assert payload_size == 0
props = _get_data_chunk_props(
"Empty message", payload_first_chunk, payload_size
)
elif not prefer_hex_display and is_unambiguous_ascii(payload_first_chunk):
props = _get_data_chunk_props(
"Message text", payload_first_chunk.decode("ascii"), payload_size
)
Expand All @@ -300,17 +316,6 @@ async def confirm_message_payload(
)


async def confirm_reference_script(
first_chunk: bytes, reference_script_size: int
) -> None:
await _confirm_tx_data_chunk(
"confirm_reference_script",
"Reference script",
first_chunk,
reference_script_size,
)


def _get_data_chunk_props(
title: str, first_chunk: bytes | str, data_size: int
) -> list[PropertyType]:
Expand Down
8 changes: 3 additions & 5 deletions core/src/apps/cardano/sign_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from trezor.wire import ProcessError
from trezor.wire.context import call as ctx_call

from apps.cardano.helpers.chunks import ChunkIterator
from apps.cardano.helpers.chunks import MAX_CHUNK_SIZE, ChunkIterator
from apps.cardano.helpers.paths import SCHEMA_PUBKEY
from apps.common import cbor

Expand All @@ -23,11 +23,9 @@
_COSE_HEADER_ALGORITHM_KEY = const(1)
_COSE_EDDSA_ALGORITHM_ID = const(-8)

_MAX_CHUNK_SIZE = const(1024)


def _validate_message_signing_path(path: list[int]) -> None:
if not (SCHEMA_PUBKEY.match(path) or seed.is_multisig_path(path)):
if not SCHEMA_PUBKEY.match(path):
raise ProcessError("Invalid signing path")


Expand All @@ -46,7 +44,7 @@ def _validate_message_init(msg: CardanoSignMessageInit) -> None:
if msg.address_parameters:
addresses.validate_message_address_parameters(msg.address_parameters)

if msg.payload_size > _MAX_CHUNK_SIZE and not msg.hash_payload:
if msg.payload_size > MAX_CHUNK_SIZE and not msg.hash_payload:
raise ProcessError("Payload too long to sign without hashing")

_validate_message_signing_path(msg.signing_path)
Expand Down
2 changes: 1 addition & 1 deletion core/src/apps/cardano/sign_tx/signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from trezor.wire import DataError, ProcessError
from trezor.wire.context import call as ctx_call

from apps.common import safety_checks
from apps.cardano.helpers.chunks import ChunkIterator
from apps.common import safety_checks

from .. import addresses, certificates, layout, seed
from ..helpers import INPUT_PREV_HASH_SIZE, LOVELACE_MAX_SUPPLY
Expand Down

0 comments on commit 218b6a0

Please sign in to comment.