psbt: reject trailing final witness data

This commit is contained in:
Boris Nagaev 2026-07-06 02:00:47 -05:00
parent 6cfd7172ea
commit 468853e436
No known key found for this signature in database

View file

@ -46,24 +46,24 @@ func Extract(p *Packet) (*wire.MsgTx, error) {
// to extract that as well, parsing the lower-level transaction
// encoding.
if pInput.FinalScriptWitness != nil {
// In order to set the witness, need to re-deserialize
// the field as encoded within the PSBT packet. For
// each input, the witness is encoded as a stack with
// one or more items.
// PSBT_IN_FINAL_SCRIPTWITNESS stores the complete
// scriptWitness for this transaction input. Decode that
// single serialized witness stack into TxWitness below.
witnessReader := bytes.NewReader(
pInput.FinalScriptWitness,
)
// First we extract the number of witness elements
// encoded in the above witnessReader.
// First extract the number of witness items encoded in
// the serialized scriptWitness.
witCount, err := wire.ReadVarInt(witnessReader, 0)
if err != nil {
return nil, err
}
// Now that we know how many inputs we'll need, we'll
// construct a packing slice, then read out each input
// (with a varint prefix) from the witnessReader.
// Allocate one slot per witness item, then read each
// varint-prefixed item from the witness value. The value
// must contain exactly this one stack, so the exhaustion
// check below rejects trailing bytes.
tin.Witness = make(wire.TxWitness, witCount)
for j := uint64(0); j < witCount; j++ {
wit, err := wire.ReadVarBytes(
@ -75,6 +75,10 @@ func Extract(p *Packet) (*wire.MsgTx, error) {
}
tin.Witness[j] = wit
}
if err := assertFullyConsumed(witnessReader); err != nil {
return nil, err
}
}
}