mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-16 04:29:08 +00:00
fix(legacy): Stricter Bitcoin transaction checks.
[no changelog]
This commit is contained in:
parent
253c7a0cc0
commit
9a20edb17d
@ -1321,7 +1321,12 @@ static void tx_info_finish(TxInfo *tx_info) {
|
||||
|
||||
static bool signing_add_input(TxInputType *txinput) {
|
||||
// hash all input data to check it later (relevant for fee computation)
|
||||
tx_input_check_hash(&hasher_check, txinput);
|
||||
if (!tx_input_check_hash(&hasher_check, txinput)) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to hash input"));
|
||||
signing_abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fsm_checkCoinPath(coin, txinput->script_type, txinput->address_n_count,
|
||||
txinput->address_n, txinput->has_multisig, true)) {
|
||||
@ -1585,8 +1590,13 @@ static bool signing_add_orig_input(TxInputType *orig_input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The first original input that has address_n set and a signature gets chosen
|
||||
// as the verification input. Set script_sig for legacy digest computation.
|
||||
// The first original non-multisig input that has address_n set and a
|
||||
// signature gets chosen as the verification input. Set script_sig for legacy
|
||||
// digest computation.
|
||||
// NOTE: Supporting replacement transactions where all internal inputs are
|
||||
// multisig would require checking the signatures of all of the original
|
||||
// internal inputs or not allowing unverified external inputs in transactions
|
||||
// where multisig inputs are present.
|
||||
if (!have_orig_verif_input && orig_input->address_n_count != 0 &&
|
||||
!orig_input->has_multisig &&
|
||||
((orig_input->has_script_sig && orig_input->script_sig.size != 0) ||
|
||||
@ -2598,7 +2608,12 @@ void signing_txack(TransactionType *tx) {
|
||||
if (idx1 == 0) {
|
||||
hasher_Reset(&hasher_check);
|
||||
}
|
||||
tx_input_check_hash(&hasher_check, tx->inputs);
|
||||
if (!tx_input_check_hash(&hasher_check, tx->inputs)) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to hash input"));
|
||||
signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&input, tx->inputs, sizeof(TxInputType));
|
||||
|
||||
@ -2803,7 +2818,12 @@ void signing_txack(TransactionType *tx) {
|
||||
hasher_Reset(&hasher_check);
|
||||
}
|
||||
// check inputs are the same as those in phase 1
|
||||
tx_input_check_hash(&hasher_check, tx->inputs);
|
||||
if (!tx_input_check_hash(&hasher_check, tx->inputs)) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError,
|
||||
_("Failed to hash input"));
|
||||
signing_abort();
|
||||
return;
|
||||
}
|
||||
if (idx2 == idx1) {
|
||||
if (!tx_info_check_input(&info, &tx->inputs[0]) ||
|
||||
!derive_node(&tx->inputs[0]) ||
|
||||
|
@ -556,22 +556,37 @@ uint32_t serialize_script_multisig(const CoinInfo *coin,
|
||||
}
|
||||
|
||||
// tx methods
|
||||
void tx_input_check_hash(Hasher *hasher, const TxInputType *input) {
|
||||
hasher_Update(hasher, input->prev_hash.bytes, sizeof(input->prev_hash.bytes));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->prev_index,
|
||||
sizeof(input->prev_index));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->script_type,
|
||||
sizeof(input->script_type));
|
||||
bool tx_input_check_hash(Hasher *hasher, const TxInputType *input) {
|
||||
hasher_Update(hasher, (const uint8_t *)&input->address_n_count,
|
||||
sizeof(input->address_n_count));
|
||||
for (int i = 0; i < input->address_n_count; ++i)
|
||||
hasher_Update(hasher, (const uint8_t *)&input->address_n[i],
|
||||
sizeof(input->address_n[0]));
|
||||
hasher_Update(hasher, input->prev_hash.bytes, sizeof(input->prev_hash.bytes));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->prev_index,
|
||||
sizeof(input->prev_index));
|
||||
tx_script_hash(hasher, input->script_sig.size, input->script_sig.bytes);
|
||||
hasher_Update(hasher, (const uint8_t *)&input->sequence,
|
||||
sizeof(input->sequence));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->script_type,
|
||||
sizeof(input->script_type));
|
||||
uint8_t multisig_fp[32] = {0};
|
||||
if (input->has_multisig) {
|
||||
if (cryptoMultisigFingerprint(&input->multisig, multisig_fp) == 0) {
|
||||
// Invalid multisig parameters.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hasher_Update(hasher, multisig_fp, sizeof(multisig_fp));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->amount, sizeof(input->amount));
|
||||
tx_script_hash(hasher, input->witness.size, input->witness.bytes);
|
||||
hasher_Update(hasher, (const uint8_t *)&input->has_orig_hash,
|
||||
sizeof(input->has_orig_hash));
|
||||
hasher_Update(hasher, input->orig_hash.bytes, sizeof(input->orig_hash.bytes));
|
||||
hasher_Update(hasher, (const uint8_t *)&input->orig_index,
|
||||
sizeof(input->orig_index));
|
||||
tx_script_hash(hasher, input->script_pubkey.size, input->script_pubkey.bytes);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input) {
|
||||
|
@ -78,7 +78,7 @@ int compile_output(const CoinInfo *coin, AmountUnit amount_unit,
|
||||
int fill_input_script_pubkey(const CoinInfo *coin, const HDNode *root,
|
||||
TxInputType *in);
|
||||
|
||||
void tx_input_check_hash(Hasher *hasher, const TxInputType *input);
|
||||
bool tx_input_check_hash(Hasher *hasher, const TxInputType *input);
|
||||
uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input);
|
||||
uint32_t tx_amount_hash(Hasher *hasher, const TxInputType *input);
|
||||
uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data);
|
||||
|
Loading…
Reference in New Issue
Block a user