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

fix(legacy): Sync input sanitization with trezor-core.

This commit is contained in:
Andrew Kozlik 2022-09-21 14:41:31 +02:00 committed by matejcik
parent 102ab3c7d6
commit 2a3cc688a1
3 changed files with 50 additions and 12 deletions

View File

@ -1436,8 +1436,8 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin, const HDNode *_root,
static bool signing_validate_input(const TxInputType *txinput) { static bool signing_validate_input(const TxInputType *txinput) {
if (txinput->prev_hash.size != 32) { if (txinput->prev_hash.size != 32) {
fsm_sendFailure(FailureType_Failure_ProcessError, fsm_sendFailure(FailureType_Failure_DataError,
_("Encountered invalid prevhash")); _("Provided prev_hash is invalid."));
signing_abort(); signing_abort();
return false; return false;
} }
@ -1450,7 +1450,22 @@ static bool signing_validate_input(const TxInputType *txinput) {
return false; return false;
} }
if (!txinput->has_multisig &&
txinput->script_type == InputScriptType_SPENDMULTISIG) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Multisig details required."));
signing_abort();
return false;
}
if (is_internal_input_script_type(txinput->script_type)) { if (is_internal_input_script_type(txinput->script_type)) {
if (txinput->address_n_count == 0) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Missing address_n field."));
signing_abort();
return false;
}
if (txinput->has_script_pubkey) { if (txinput->has_script_pubkey) {
// scriptPubKey should only be provided for external inputs // scriptPubKey should only be provided for external inputs
fsm_sendFailure(FailureType_Failure_DataError, fsm_sendFailure(FailureType_Failure_DataError,
@ -1487,6 +1502,14 @@ static bool signing_validate_input(const TxInputType *txinput) {
return false; return false;
} }
if (!coin->decred && txinput->has_decred_tree) {
fsm_sendFailure(
FailureType_Failure_DataError,
_("Decred details provided but Decred coin not specified."));
signing_abort();
return false;
}
if (is_segwit_input_script_type(txinput->script_type)) { if (is_segwit_input_script_type(txinput->script_type)) {
if (!coin->has_segwit) { if (!coin->has_segwit) {
fsm_sendFailure(FailureType_Failure_DataError, fsm_sendFailure(FailureType_Failure_DataError,
@ -1520,8 +1543,8 @@ static bool signing_validate_input(const TxInputType *txinput) {
} }
if (txinput->orig_hash.size != 32) { if (txinput->orig_hash.size != 32) {
fsm_sendFailure(FailureType_Failure_ProcessError, fsm_sendFailure(FailureType_Failure_DataError,
_("Encountered invalid orig_hash")); _("Provided orig_hash is invalid."));
signing_abort(); signing_abort();
return false; return false;
} }
@ -1530,6 +1553,25 @@ static bool signing_validate_input(const TxInputType *txinput) {
return true; return true;
} }
static bool signing_validate_prev_input(const TxInputType *txinput) {
if (txinput->prev_hash.size != 32) {
fsm_sendFailure(FailureType_Failure_DataError,
_("Provided prev_hash is invalid."));
signing_abort();
return false;
}
if (!coin->decred && txinput->has_decred_tree) {
fsm_sendFailure(
FailureType_Failure_DataError,
_("Decred details provided but Decred coin not specified."));
signing_abort();
return false;
}
return true;
}
static bool signing_validate_output(TxOutputType *txoutput) { static bool signing_validate_output(TxOutputType *txoutput) {
if (txoutput->has_multisig && if (txoutput->has_multisig &&
!is_multisig_output_script_type(txoutput->script_type)) { !is_multisig_output_script_type(txoutput->script_type)) {
@ -3657,7 +3699,7 @@ void signing_txack(TransactionType *tx) {
} }
return; return;
case STAGE_REQUEST_3_PREV_INPUT: case STAGE_REQUEST_3_PREV_INPUT:
if (!signing_validate_input(&tx->inputs[0])) { if (!signing_validate_prev_input(&tx->inputs[0])) {
return; return;
} }
progress_substep++; progress_substep++;

View File

@ -210,8 +210,7 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type,
ecdsa_get_address_segwit_p2sh( ecdsa_get_address_segwit_p2sh(
node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey, node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey,
coin->curve->hasher_base58, address, MAX_ADDR_SIZE); coin->curve->hasher_base58, address, MAX_ADDR_SIZE);
} else if (script_type == InputScriptType_SPENDADDRESS || } else if (script_type == InputScriptType_SPENDADDRESS) {
script_type == InputScriptType_SPENDMULTISIG) {
#if !BITCOIN_ONLY #if !BITCOIN_ONLY
if (coin->cashaddr_prefix) { if (coin->cashaddr_prefix) {
ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160, ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160,

View File

@ -63,14 +63,11 @@ def hash_tx(data: bytes) -> bytes:
def _check_error_message(value: bytes, model: str, message: str): def _check_error_message(value: bytes, model: str, message: str):
if model != "1":
assert message == "Provided prev_hash is invalid."
# T1 has several possible errors # T1 has several possible errors
elif len(value) > 32: if model == "1" and len(value) > 32:
assert message.endswith("bytes overflow") assert message.endswith("bytes overflow")
else: else:
assert message.endswith("Encountered invalid prevhash") assert message.endswith("Provided prev_hash is invalid.")
with_bad_prevhashes = pytest.mark.parametrize( with_bad_prevhashes = pytest.mark.parametrize(