chanfunding: verify inputs are signed in raw tx

This commit is contained in:
Oliver Gugger 2020-09-07 18:02:44 +02:00
parent d581cd02fc
commit 1c832cbce7
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
2 changed files with 62 additions and 0 deletions

@ -316,6 +316,14 @@ func (i *PsbtIntent) FinalizeRawTX(rawTx *wire.MsgTx) error {
return fmt.Errorf("inputs differ from verified PSBT: %v", err)
}
// We also check that we have a signed TX. This is only necessary if the
// FinalizeRawTX is called directly with a wire format TX instead of
// extracting the TX from a PSBT.
err = verifyInputsSigned(rawTx.TxIn)
if err != nil {
return fmt.Errorf("inputs not signed: %v", err)
}
// As far as we can tell, this TX is ok to be used as a funding
// transaction.
i.State = PsbtFinalized
@ -539,3 +547,18 @@ func verifyInputPrevOutpointsEqual(ins1, ins2 []*wire.TxIn) error {
}
return nil
}
// verifyInputsSigned verifies that the given list of inputs is non-empty and
// that all the inputs either contain a script signature or a witness stack.
func verifyInputsSigned(ins []*wire.TxIn) error {
if len(ins) == 0 {
return fmt.Errorf("no inputs in transaction")
}
for idx, in := range ins {
if len(in.SignatureScript) == 0 && len(in.Witness) == 0 {
return fmt.Errorf("input %d has no signature data "+
"attached", idx)
}
}
return nil
}

@ -18,6 +18,7 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
"github.com/stretchr/testify/require"
)
var (
@ -496,6 +497,44 @@ func TestPsbtFinalize(t *testing.T) {
return i.Finalize(p)
},
},
{
name: "raw tx - nil transaction",
expectedErr: "raw transaction is nil",
doFinalize: func(amt int64, p *psbt.Packet,
i *PsbtIntent) error {
return i.FinalizeRawTX(nil)
},
},
{
name: "raw tx - no witness data in raw tx",
expectedErr: "inputs not signed: input 0 has no " +
"signature data attached",
doFinalize: func(amt int64, p *psbt.Packet,
i *PsbtIntent) error {
rawTx, err := psbt.Extract(p)
require.NoError(t, err)
rawTx.TxIn[0].Witness = nil
return i.FinalizeRawTX(rawTx)
},
},
{
name: "happy path",
expectedErr: "",
doFinalize: func(amt int64, p *psbt.Packet,
i *PsbtIntent) error {
err := i.Finalize(p)
require.NoError(t, err)
require.Equal(t, PsbtFinalized, i.State)
require.NotNil(t, i.FinalTX)
return nil
},
},
}
// Create a simple assembler and ask it to provision a channel to get