Skip to content

Commit

Permalink
feat(cardano): fix certificate checks
Browse files Browse the repository at this point in the history
  • Loading branch information
jaskp committed Nov 23, 2023
1 parent c1c9988 commit e5f9d1e
Showing 1 changed file with 44 additions and 36 deletions.
80 changes: 44 additions & 36 deletions core/src/apps/cardano/certificates.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ def validate(
if certificate.drep is None:
raise ProcessError("Invalid certificate")
validate_drep(
certificate.drep.type,
certificate.drep.script_hash,
certificate.drep.key_hash,
certificate.drep,
ProcessError("Invalid certificate"),
)
validate_stake_credential(
Expand Down Expand Up @@ -168,6 +166,7 @@ def cborize(
certificate.pool,
)
elif cert_type == CardanoCertificateType.VOTE_DELEGATION:
assert certificate.drep is not None
return (
cert_type,
cborize_stake_credential(
Expand All @@ -176,7 +175,7 @@ def cborize(
certificate.script_hash,
certificate.key_hash,
),
cborize_drep(certificate.drep) if certificate.drep else None,
cborize_drep(certificate.drep),
)
else:
raise RuntimeError # should be unreachable
Expand All @@ -198,38 +197,6 @@ def cborize_stake_credential(
raise RuntimeError


def cborize_drep(drep: messages.CardanoDRep) -> tuple[int, bytes | None] | tuple[int]:
if drep.type == CardanoDRepType.KEY_HASH:
return 0, drep.key_hash
elif drep.type == CardanoDRepType.SCRIPT_HASH:
return 1, drep.script_hash
elif drep.type == CardanoDRepType.ALWAYS_ABSTAIN:
return (2,)
elif drep.type == CardanoDRepType.ALWAYS_NO_CONFIDENCE:
return (3,)
else:
raise RuntimeError # should be unreachable


def validate_drep(
type: CardanoDRepType,
script_hash: bytes | None,
key_hash: bytes | None,
error: ProcessError,
) -> None:
from .helpers import ADDRESS_KEY_HASH_SIZE, SCRIPT_HASH_SIZE

if type == CardanoDRepType.KEY_HASH:
if script_hash or not key_hash or len(key_hash) != ADDRESS_KEY_HASH_SIZE:
raise error
elif type == CardanoDRepType.SCRIPT_HASH:
if key_hash or not script_hash or len(script_hash) != SCRIPT_HASH_SIZE:
raise error
elif type in (CardanoDRepType.ALWAYS_ABSTAIN, CardanoDRepType.ALWAYS_NO_CONFIDENCE):
if script_hash or key_hash:
raise error


def cborize_pool_registration_init(
certificate: messages.CardanoTxCertificate,
) -> CborSequence:
Expand Down Expand Up @@ -291,6 +258,32 @@ def _validate_pool_parameters(
assert_cond(all((32 <= ord(c) < 127) for c in pool_metadata.url))


def validate_drep(
drep: messages.CardanoDRep,
error: ProcessError,
) -> None:
from .helpers import ADDRESS_KEY_HASH_SIZE, SCRIPT_HASH_SIZE

drep_type = drep.type
script_hash = drep.script_hash
key_hash = drep.key_hash

if drep_type == CardanoDRepType.KEY_HASH:
if script_hash or not key_hash or len(key_hash) != ADDRESS_KEY_HASH_SIZE:
raise error
elif drep_type == CardanoDRepType.SCRIPT_HASH:
if key_hash or not script_hash or len(script_hash) != SCRIPT_HASH_SIZE:
raise error
elif drep_type in (
CardanoDRepType.ALWAYS_ABSTAIN,
CardanoDRepType.ALWAYS_NO_CONFIDENCE,
):
if script_hash or key_hash:
raise error
else:
raise RuntimeError # should be unreachable


def validate_pool_owner(
owner: messages.CardanoPoolOwner, account_path_checker: AccountPathChecker
) -> None:
Expand Down Expand Up @@ -330,6 +323,21 @@ def validate_pool_relay(pool_relay: messages.CardanoPoolRelayParameters) -> None
raise RuntimeError # should be unreachable


def cborize_drep(drep: messages.CardanoDRep) -> tuple[int, bytes] | tuple[int]:
if drep.type == CardanoDRepType.KEY_HASH:
assert drep.key_hash is not None
return 0, drep.key_hash
elif drep.type == CardanoDRepType.SCRIPT_HASH:
assert drep.script_hash is not None
return 1, drep.script_hash
elif drep.type == CardanoDRepType.ALWAYS_ABSTAIN:
return (2,)
elif drep.type == CardanoDRepType.ALWAYS_NO_CONFIDENCE:
return (3,)
else:
raise RuntimeError # should be unreachable


def cborize_pool_owner(
keychain: seed.Keychain, pool_owner: messages.CardanoPoolOwner
) -> bytes:
Expand Down

0 comments on commit e5f9d1e

Please sign in to comment.