From aac2e7a5f4c84398d0dac4df46e4379b5e2f143a Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:09:58 +0100 Subject: [PATCH 1/2] Make sure that legacy inputs do not have witness-utxo in the psbt --- src/handler/sign_psbt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 91efaf910..34e234823 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -969,10 +969,14 @@ preprocess_inputs(dispatcher_context_t *dc, int segwit_version = get_policy_segwit_version(st->wallet_policy_map); // For legacy inputs, the non-witness utxo must be present - if (segwit_version == -1 && !input.has_nonWitnessUtxo) { - PRINTF("Non-witness utxo missing for legacy input\n"); - SEND_SW(dc, SW_INCORRECT_DATA); - return false; + // and the witness utxo must be absent. + // (This assumption is later relied on when signing). + if (segwit_version == -1) { + if (!input.has_nonWitnessUtxo || input.has_witnessUtxo) { + PRINTF("Legacy inputs must have the non-witness utxo, but no witness utxo.\n"); + SEND_SW(dc, SW_INCORRECT_DATA); + return false; + } } // For segwitv0 inputs, the non-witness utxo _should_ be present; we show a warning From bdcbe1bfe14e33b950345071a5d06508adf60002 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:18:51 +0100 Subject: [PATCH 2/2] Avoid sending a status word twice on failure, which would cause an app crash --- src/handler/sign_psbt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/handler/sign_psbt.c b/src/handler/sign_psbt.c index 34e234823..b90375d84 100644 --- a/src/handler/sign_psbt.c +++ b/src/handler/sign_psbt.c @@ -2473,10 +2473,12 @@ sign_transaction(dispatcher_context_t *dc, return false; if (!sign_transaction_input(dc, st, &hashes, &placeholder_info, &input, i)) { - SEND_SW(dc, SW_BAD_STATE); // should never happen if (!G_swap_state.called_from_swap) { ui_post_processing_confirm_transaction(dc, false); } + + // we do not send a status word, since sign_transaction_input + // already does it on failure return false; } }