diff --git a/legacy/firmware/signing.c b/legacy/firmware/signing.c index dfb760f546..96a971f559 100644 --- a/legacy/firmware/signing.c +++ b/legacy/firmware/signing.c @@ -1436,8 +1436,8 @@ void signing_init(const SignTx *msg, const CoinInfo *_coin, const HDNode *_root, static bool signing_validate_input(const TxInputType *txinput) { if (txinput->prev_hash.size != 32) { - fsm_sendFailure(FailureType_Failure_ProcessError, - _("Encountered invalid prevhash")); + fsm_sendFailure(FailureType_Failure_DataError, + _("Provided prev_hash is invalid.")); signing_abort(); return false; } @@ -1450,7 +1450,22 @@ static bool signing_validate_input(const TxInputType *txinput) { 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 (txinput->address_n_count == 0) { + fsm_sendFailure(FailureType_Failure_DataError, + _("Missing address_n field.")); + signing_abort(); + return false; + } + if (txinput->has_script_pubkey) { // scriptPubKey should only be provided for external inputs fsm_sendFailure(FailureType_Failure_DataError, @@ -1487,6 +1502,14 @@ static bool signing_validate_input(const TxInputType *txinput) { 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 (!coin->has_segwit) { fsm_sendFailure(FailureType_Failure_DataError, @@ -1520,8 +1543,8 @@ static bool signing_validate_input(const TxInputType *txinput) { } if (txinput->orig_hash.size != 32) { - fsm_sendFailure(FailureType_Failure_ProcessError, - _("Encountered invalid orig_hash")); + fsm_sendFailure(FailureType_Failure_DataError, + _("Provided orig_hash is invalid.")); signing_abort(); return false; } @@ -1530,6 +1553,25 @@ static bool signing_validate_input(const TxInputType *txinput) { 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) { if (txoutput->has_multisig && !is_multisig_output_script_type(txoutput->script_type)) { @@ -3657,7 +3699,7 @@ void signing_txack(TransactionType *tx) { } return; case STAGE_REQUEST_3_PREV_INPUT: - if (!signing_validate_input(&tx->inputs[0])) { + if (!signing_validate_prev_input(&tx->inputs[0])) { return; } progress_substep++; diff --git a/legacy/firmware/transaction.c b/legacy/firmware/transaction.c index fbf045fed0..584c0f13eb 100644 --- a/legacy/firmware/transaction.c +++ b/legacy/firmware/transaction.c @@ -210,8 +210,7 @@ bool compute_address(const CoinInfo *coin, InputScriptType script_type, ecdsa_get_address_segwit_p2sh( node->public_key, coin->address_type_p2sh, coin->curve->hasher_pubkey, coin->curve->hasher_base58, address, MAX_ADDR_SIZE); - } else if (script_type == InputScriptType_SPENDADDRESS || - script_type == InputScriptType_SPENDMULTISIG) { + } else if (script_type == InputScriptType_SPENDADDRESS) { #if !BITCOIN_ONLY if (coin->cashaddr_prefix) { ecdsa_get_address_raw(node->public_key, CASHADDR_P2KH | CASHADDR_160, diff --git a/tests/device_tests/bitcoin/test_signtx_prevhash.py b/tests/device_tests/bitcoin/test_signtx_prevhash.py index ee7d610697..3f7e1693d4 100644 --- a/tests/device_tests/bitcoin/test_signtx_prevhash.py +++ b/tests/device_tests/bitcoin/test_signtx_prevhash.py @@ -63,14 +63,11 @@ def hash_tx(data: bytes) -> bytes: 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 - elif len(value) > 32: + if model == "1" and len(value) > 32: assert message.endswith("bytes overflow") else: - assert message.endswith("Encountered invalid prevhash") + assert message.endswith("Provided prev_hash is invalid.") with_bad_prevhashes = pytest.mark.parametrize(