Fixup borked PSBT signing + finalize - #203
Conversation
4f72c10 to
036db5a
Compare
| if (input->partial_sigs) { | ||
| for (j = 0; j < input->partial_sigs->num_items; j++) { | ||
| struct wally_partial_sigs_item *item = &input->partial_sigs->items[j]; | ||
| if ((item->pubkey[0] == 0x04 |
There was a problem hiding this comment.
In 6f6f30d "psbt: dont sign inputs we've already got a sig for"
I don't think it's necessary to check whether it is compressed or uncompressed. item->pubkey is a fixed size of EC_PUBLIC_KEY_UNCOMPRESSED_LEN so you can just always do a memcmp on that. It should still check both sizes as compressed keys could have garbage at the end of the buffer.
There was a problem hiding this comment.
this is basically a port/copy of https://github.com/ElementsProject/libwally-core/blob/master/src/psbt.c#L2555-L2559
There was a problem hiding this comment.
Right, but that's specifically to check for compressed-ness which we don't need here.
There was a problem hiding this comment.
It should still check both sizes as compressed keys could have garbage at the end of the buffer.
i'm not sure i understand what you're suggesting here. given the quoted comment, i think you're saying i should drop the pubkey[0] == 0x04 check. is this correct?
| unsigned char *out_script = NULL; /* Script that determines how we should finalize this input, typically output script */ | ||
| size_t out_script_len, type; | ||
| /* Expanded script, only applicable for P2SH variants. Used for determining if is multisig */ | ||
| unsigned char *script = NULL; |
There was a problem hiding this comment.
In 036db5a "psbt: fix signing for p2sh-p2wpkh and test"
It's not clear to me why script is necessary here. It's just replacing a few places where out_script is being checked that AFAICT, could still be out_script if it were updated in the correct places.
There was a problem hiding this comment.
it's not 'scriptly necessary' -- i added it so as not to re-use out_script. the intention of having a second placeholder for the 'definitely the script' is to simplify the various 'levels' of scripts that out_script could possibly represent, as that seemed to be part of the root cause of the problems in the first place.
There was a problem hiding this comment.
IMO keeping it out_script makes it more readable as out_script is supposed to be the scriptcode and scriptcode is what matters, regardless of the 'levels'. It seems like the root cause is setting out_script in the wrong order.
There was a problem hiding this comment.
i'm going to agree to disagree with you here. if reusing out_script is necessary to get this PR approved, i will update it to reuse out-script.
8adbee0 to
24a1720
Compare
|
hey @achow101 i've made the changes you requested, would you mind taking another look? this is currently blocking some other work. |
| out_script_len = input->witness_script_len; | ||
| witness = true; | ||
| } | ||
| if (input->redeem_script) { |
There was a problem hiding this comment.
This if block can be swapped with the one above. Then the if (type == WALLY_SCRIPT_TYPE_P2WSH...) block can be dropped.
|
|
||
| /* Note that if we patch libwally to supply the non-witness utxo tx field (tx) for | ||
| * witness inputs also, we'll need a different way to signal p2wpkh scripts */ | ||
| * witness inputs also, we'll need a different way to signal p2sh-p2wpkh scripts */ |
There was a problem hiding this comment.
turns out uncrustify wants it this way, so reverted this suggested change.
if we sign an input twice, it'll marshal to b64 correctly but blow up on the unmarshal. rather than creating invalid psbts, we simply refuse to sign an input that's already been signed by the given pubkey
24a1720 to
f727cbe
Compare
|
squashed + updated |
|
ACK f727cbe |
as implemented, we don't properly sign for p2sh-p2wpkh inputs; here we fix the issue and add a new test case to cover both p2sh-p2wpkh and p2wpkh signature generation
prior to this patch, p2sh-p2wpkh doesn't finalize correctly -- it omits filling in the scriptSig with the redeem-script data fixing this matches bitcoind's `finalizepsbt` behavior
f727cbe to
e0d0634
Compare
|
ACK e0d0634 |
| if (input->redeem_script) { | ||
| /* P2SH wrapped witness requires final scriptsig of pushing the redeemScript */ | ||
| script_sig_len = varint_get_length(input->redeem_script_len) + input->redeem_script_len; | ||
| input->final_script_sig = wally_malloc(script_sig_len); |
There was a problem hiding this comment.
May be worth explicitly checking the value returned by wally_malloc for null and returning WALLY_ENOMEM
There was a problem hiding this comment.
this is copied from https://github.com/ElementsProject/libwally-core/blob/master/src/psbt.c#L2860-L2868, which will also need to be cleaned up
There was a problem hiding this comment.
in the interest of getting my PRs in c-lightning unblocked, we should merge this PR and clean up the malloc problems in a second fixup
There was a problem hiding this comment.
ok, i went through and updated all wally_alloc calls in psbt.c that were missing a NULL check, see #204
Found
twothree problems with the PSBT sign + finalize code; this PR contains suggested fixes for them and tests.Note: disallowing duplicate key'd partial_sigs made the invalid_sigs tests start to pass since the existing test already had partial_sig data populated for the given key; we revert them to 'failing' by removing the existing partial_sig data from the test case.