mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
Merge pull request #7127 from morehouse/native_fuzzing
brontide+lnwire+wtwire+zpay32: migrate fuzz tests
This commit is contained in:
commit
404e18afab
709
brontide/fuzz_test.go
Normal file
709
brontide/fuzz_test.go
Normal file
@ -0,0 +1,709 @@
|
||||
package brontide
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
)
|
||||
|
||||
var (
|
||||
initBytes = []byte{
|
||||
0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||
0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
||||
0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||
}
|
||||
|
||||
respBytes = []byte{
|
||||
0xaa, 0xb6, 0x37, 0xd9, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
0x63, 0x59, 0xe6, 0x99, 0x31, 0x13, 0xa1, 0x17,
|
||||
0xd, 0xe7, 0x95, 0xe9, 0xb7, 0x25, 0xb8, 0x4d,
|
||||
0x1e, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||
}
|
||||
|
||||
// Returns the initiator's ephemeral private key.
|
||||
initEphemeral = EphemeralGenerator(func() (*btcec.PrivateKey, error) {
|
||||
e := "121212121212121212121212121212121212121212121212121212" +
|
||||
"1212121212"
|
||||
eBytes, err := hex.DecodeString(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
priv, _ := btcec.PrivKeyFromBytes(eBytes)
|
||||
|
||||
return priv, nil
|
||||
})
|
||||
|
||||
// Returns the responder's ephemeral private key.
|
||||
respEphemeral = EphemeralGenerator(func() (*btcec.PrivateKey, error) {
|
||||
e := "222222222222222222222222222222222222222222222222222" +
|
||||
"2222222222222"
|
||||
eBytes, err := hex.DecodeString(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
priv, _ := btcec.PrivKeyFromBytes(eBytes)
|
||||
|
||||
return priv, nil
|
||||
})
|
||||
)
|
||||
|
||||
// completeHandshake takes two brontide machines (initiator, responder)
|
||||
// and completes the brontide handshake between them. If any part of the
|
||||
// handshake fails, this function will panic.
|
||||
func completeHandshake(t *testing.T, initiator, responder *Machine) {
|
||||
t.Helper()
|
||||
|
||||
if err := handshake(initiator, responder); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
}
|
||||
|
||||
// handshake actually completes the brontide handshake and bubbles up
|
||||
// an error to the calling function.
|
||||
func handshake(initiator, responder *Machine) error {
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate ActTwo and send to initiator.
|
||||
actTwo, err := responder.GenActTwo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initiator.RecvActTwo(actTwo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate ActThree and send to responder.
|
||||
actThree, err := initiator.GenActThree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return responder.RecvActThree(actThree)
|
||||
}
|
||||
|
||||
// nilAndPanic first nils the initiator and responder's Curve fields and then
|
||||
// panics.
|
||||
func nilAndPanic(t *testing.T, initiator, responder *Machine, err error) {
|
||||
t.Helper()
|
||||
|
||||
t.Fatalf("error: %v, initiator: %v, responder: %v", err,
|
||||
spew.Sdump(initiator), spew.Sdump(responder))
|
||||
}
|
||||
|
||||
// getBrontideMachines returns two brontide machines that use random keys
|
||||
// everywhere.
|
||||
func getBrontideMachines() (*Machine, *Machine) {
|
||||
initPriv, _ := btcec.NewPrivateKey()
|
||||
respPriv, _ := btcec.NewPrivateKey()
|
||||
respPub := (respPriv.PubKey())
|
||||
|
||||
initPrivECDH := &keychain.PrivKeyECDH{PrivKey: initPriv}
|
||||
respPrivECDH := &keychain.PrivKeyECDH{PrivKey: respPriv}
|
||||
|
||||
initiator := NewBrontideMachine(true, initPrivECDH, respPub)
|
||||
responder := NewBrontideMachine(false, respPrivECDH, nil)
|
||||
|
||||
return initiator, responder
|
||||
}
|
||||
|
||||
// getStaticBrontideMachines returns two brontide machines that use static keys
|
||||
// everywhere.
|
||||
func getStaticBrontideMachines() (*Machine, *Machine) {
|
||||
initPriv, _ := btcec.PrivKeyFromBytes(initBytes)
|
||||
respPriv, respPub := btcec.PrivKeyFromBytes(respBytes)
|
||||
|
||||
initPrivECDH := &keychain.PrivKeyECDH{PrivKey: initPriv}
|
||||
respPrivECDH := &keychain.PrivKeyECDH{PrivKey: respPriv}
|
||||
|
||||
initiator := NewBrontideMachine(
|
||||
true, initPrivECDH, respPub, initEphemeral,
|
||||
)
|
||||
responder := NewBrontideMachine(
|
||||
false, respPrivECDH, nil, respEphemeral,
|
||||
)
|
||||
|
||||
return initiator, responder
|
||||
}
|
||||
|
||||
// FuzzRandomActOne fuzz tests ActOne in the brontide handshake.
|
||||
func FuzzRandomActOne(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActOneSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
_, responder := getBrontideMachines()
|
||||
|
||||
// Copy data into [ActOneSize]byte.
|
||||
var actOne [ActOneSize]byte
|
||||
copy(actOne[:], data)
|
||||
|
||||
// Responder receives ActOne, should fail on the MAC check.
|
||||
if err := responder.RecvActOne(actOne); err == nil {
|
||||
nilAndPanic(t, nil, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomActThree fuzz tests ActThree in the brontide handshake.
|
||||
func FuzzRandomActThree(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActThreeSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Receiving ActOne should succeed, so we panic on error.
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Generate ActTwo - this is not sent to the initiator because
|
||||
// nothing is done with the initiator after this point and it
|
||||
// would slow down fuzzing. GenActTwo needs to be called to set
|
||||
// the appropriate state in the responder machine.
|
||||
_, err = responder.GenActTwo()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActThreeSize]byte.
|
||||
var actThree [ActThreeSize]byte
|
||||
copy(actThree[:], data)
|
||||
|
||||
// Responder receives ActThree, should fail on the MAC check.
|
||||
if err := responder.RecvActThree(actThree); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomActTwo fuzz tests ActTwo in the brontide handshake.
|
||||
func FuzzRandomActTwo(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActTwoSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, _ := getBrontideMachines()
|
||||
|
||||
// Generate ActOne - this isn't sent to the responder because
|
||||
// nothing is done with the responder machine and this would
|
||||
// slow down fuzzing. GenActOne needs to be called to set the
|
||||
// appropriate state in the initiator machine.
|
||||
_, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, nil, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActTwoSize]byte.
|
||||
var actTwo [ActTwoSize]byte
|
||||
copy(actTwo[:], data)
|
||||
|
||||
// Initiator receives ActTwo, should fail.
|
||||
if err := initiator.RecvActTwo(actTwo); err == nil {
|
||||
nilAndPanic(t, initiator, nil, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomInitDecrypt fuzz tests decrypting arbitrary data with the
|
||||
// initiator.
|
||||
func FuzzRandomInitDecrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ initiator
|
||||
// machine.
|
||||
if _, err := initiator.ReadMessage(r); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomInitEncDec fuzz tests round-trip encryption and decryption between
|
||||
// the initiator and the responder.
|
||||
func FuzzRandomInitEncDec(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ responder
|
||||
// machine.
|
||||
plaintext, err := responder.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are
|
||||
// equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomInitEncrypt fuzz tests the encryption of arbitrary data with the
|
||||
// initiator.
|
||||
func FuzzRandomInitEncrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomRespDecrypt fuzz tests the decryption of arbitrary data with the
|
||||
// responder.
|
||||
func FuzzRandomRespDecrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ responder
|
||||
// machine.
|
||||
if _, err := responder.ReadMessage(r); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomRespEncDec fuzz tests round-trip encryption and decryption between
|
||||
// the responder and the initiator.
|
||||
func FuzzRandomRespEncDec(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ initiator
|
||||
// machine.
|
||||
plaintext, err := initiator.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are
|
||||
// equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzRandomRespEncrypt fuzz tests encryption of arbitrary data with the
|
||||
// responder.
|
||||
func FuzzRandomRespEncrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticActOne fuzz tests ActOne in the brontide handshake.
|
||||
func FuzzStaticActOne(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActOneSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
_, responder := getStaticBrontideMachines()
|
||||
|
||||
// Copy data into [ActOneSize]byte.
|
||||
var actOne [ActOneSize]byte
|
||||
copy(actOne[:], data)
|
||||
|
||||
// Responder receives ActOne, should fail.
|
||||
if err := responder.RecvActOne(actOne); err == nil {
|
||||
nilAndPanic(t, nil, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticActThree fuzz tests ActThree in the brontide handshake.
|
||||
func FuzzStaticActThree(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActThreeSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Receiving ActOne should succeed, so we panic on error.
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Generate ActTwo - this is not sent to the initiator because
|
||||
// nothing is done with the initiator after this point and it
|
||||
// would slow down fuzzing. GenActTwo needs to be called to set
|
||||
// the appropriate state in the responder machine.
|
||||
_, err = responder.GenActTwo()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActThreeSize]byte.
|
||||
var actThree [ActThreeSize]byte
|
||||
copy(actThree[:], data)
|
||||
|
||||
// Responder receives ActThree, should fail.
|
||||
if err := responder.RecvActThree(actThree); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticActTwo fuzz tests ActTwo in the brontide handshake.
|
||||
func FuzzStaticActTwo(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Check if data is large enough.
|
||||
if len(data) < ActTwoSize {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, _ := getStaticBrontideMachines()
|
||||
|
||||
// Generate ActOne - this isn't sent to the responder because
|
||||
// nothing is done with the responder machine and this would
|
||||
// slow down fuzzing. GenActOne needs to be called to set the
|
||||
// appropriate state in the initiator machine.
|
||||
_, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, nil, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActTwoSize]byte.
|
||||
var actTwo [ActTwoSize]byte
|
||||
copy(actTwo[:], data)
|
||||
|
||||
// Initiator receives ActTwo, should fail.
|
||||
if err := initiator.RecvActTwo(actTwo); err == nil {
|
||||
nilAndPanic(t, initiator, nil, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticInitDecrypt fuzz tests the decryption of arbitrary data with the
|
||||
// initiator.
|
||||
func FuzzStaticInitDecrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ initiator
|
||||
// machine.
|
||||
if _, err := initiator.ReadMessage(r); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticInitEncDec fuzz tests round-trip encryption and decryption between
|
||||
// the initiator and the responder.
|
||||
func FuzzStaticInitEncDec(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ responder
|
||||
// machine.
|
||||
plaintext, err := responder.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are
|
||||
// equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticInitEncrypt fuzz tests the encryption of arbitrary data with the
|
||||
// initiator.
|
||||
func FuzzStaticInitEncrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticRespDecrypt fuzz tests the decryption of arbitrary data with the
|
||||
// responder.
|
||||
func FuzzStaticRespDecrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ responder
|
||||
// machine.
|
||||
if _, err := responder.ReadMessage(r); err == nil {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticRespEncDec fuzz tests the round-trip encryption and decryption
|
||||
// between the responder and the initiator.
|
||||
func FuzzStaticRespEncDec(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ initiator
|
||||
// machine.
|
||||
plaintext, err := initiator.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are
|
||||
// equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(t, initiator, responder, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// FuzzStaticRespEncrypt fuzz tests the encryption of arbitrary data with the
|
||||
// responder.
|
||||
func FuzzStaticRespEncrypt(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Ensure that length of message is not greater than max allowed
|
||||
// size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(t, initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(t, initiator, responder, err)
|
||||
}
|
||||
})
|
||||
}
|
@ -131,6 +131,9 @@ certain large transactions](https://github.com/lightningnetwork/lnd/pull/7100).
|
||||
* [Fixed a bug where paying an invoice with a malformed route hint triggers a
|
||||
never-ending retry loop](https://github.com/lightningnetwork/lnd/pull/6766)
|
||||
|
||||
* [Migrated from go-fuzz to Go 1.18's new standard fuzz testing
|
||||
library](https://github.com/lightningnetwork/lnd/pull/7127).
|
||||
|
||||
## `lncli`
|
||||
* [Add an `insecure` flag to skip tls auth as well as a `metadata` string slice
|
||||
flag](https://github.com/lightningnetwork/lnd/pull/6818) that allows the
|
||||
@ -226,6 +229,7 @@ to refactor the itest for code health and maintenance.
|
||||
|
||||
* andreihod
|
||||
* Carla Kirk-Cohen
|
||||
* Conner Babinchak
|
||||
* cutiful
|
||||
* Daniel McNally
|
||||
* Elle Mouton
|
||||
|
@ -1,139 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
)
|
||||
|
||||
var (
|
||||
initBytes = []byte{
|
||||
0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
|
||||
0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
|
||||
0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||
}
|
||||
|
||||
respBytes = []byte{
|
||||
0xaa, 0xb6, 0x37, 0xd9, 0xfc, 0xd2, 0xc6, 0xda,
|
||||
0x63, 0x59, 0xe6, 0x99, 0x31, 0x13, 0xa1, 0x17,
|
||||
0xd, 0xe7, 0x95, 0xe9, 0xb7, 0x25, 0xb8, 0x4d,
|
||||
0x1e, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9,
|
||||
}
|
||||
|
||||
// Returns the initiator's ephemeral private key.
|
||||
initEphemeral = brontide.EphemeralGenerator(func() (*btcec.PrivateKey, error) {
|
||||
e := "121212121212121212121212121212121212121212121212121212" +
|
||||
"1212121212"
|
||||
eBytes, err := hex.DecodeString(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
priv, _ := btcec.PrivKeyFromBytes(eBytes)
|
||||
return priv, nil
|
||||
})
|
||||
|
||||
// Returns the responder's ephemeral private key.
|
||||
respEphemeral = brontide.EphemeralGenerator(func() (*btcec.PrivateKey, error) {
|
||||
e := "222222222222222222222222222222222222222222222222222" +
|
||||
"2222222222222"
|
||||
eBytes, err := hex.DecodeString(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
priv, _ := btcec.PrivKeyFromBytes(eBytes)
|
||||
return priv, nil
|
||||
})
|
||||
)
|
||||
|
||||
// completeHandshake takes two brontide machines (initiator, responder)
|
||||
// and completes the brontide handshake between them. If any part of the
|
||||
// handshake fails, this function will panic.
|
||||
func completeHandshake(initiator, responder *brontide.Machine) {
|
||||
if err := handshake(initiator, responder); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
}
|
||||
|
||||
// handshake actually completes the brontide handshake and bubbles up
|
||||
// an error to the calling function.
|
||||
func handshake(initiator, responder *brontide.Machine) error {
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate ActTwo and send to initiator.
|
||||
actTwo, err := responder.GenActTwo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initiator.RecvActTwo(actTwo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate ActThree and send to responder.
|
||||
actThree, err := initiator.GenActThree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return responder.RecvActThree(actThree)
|
||||
}
|
||||
|
||||
// nilAndPanic first nils the initiator and responder's Curve fields and then
|
||||
// panics.
|
||||
func nilAndPanic(initiator, responder *brontide.Machine, err error) {
|
||||
panic(fmt.Errorf("error: %v, initiator: %v, responder: %v", err,
|
||||
spew.Sdump(initiator), spew.Sdump(responder)))
|
||||
}
|
||||
|
||||
// getBrontideMachines returns two brontide machines that use random keys
|
||||
// everywhere.
|
||||
func getBrontideMachines() (*brontide.Machine, *brontide.Machine) {
|
||||
initPriv, _ := btcec.NewPrivateKey()
|
||||
respPriv, _ := btcec.NewPrivateKey()
|
||||
respPub := (*btcec.PublicKey)(&respPriv.PublicKey)
|
||||
|
||||
initPrivECDH := &keychain.PrivKeyECDH{PrivKey: initPriv}
|
||||
respPrivECDH := &keychain.PrivKeyECDH{PrivKey: respPriv}
|
||||
|
||||
initiator := brontide.NewBrontideMachine(true, initPrivECDH, respPub)
|
||||
responder := brontide.NewBrontideMachine(false, respPrivECDH, nil)
|
||||
|
||||
return initiator, responder
|
||||
}
|
||||
|
||||
// getStaticBrontideMachines returns two brontide machines that use static keys
|
||||
// everywhere.
|
||||
func getStaticBrontideMachines() (*brontide.Machine, *brontide.Machine) {
|
||||
initPriv, _ := btcec.PrivKeyFromBytes(initBytes)
|
||||
respPriv, respPub := btcec.PrivKeyFromBytes(respBytes)
|
||||
|
||||
initPrivECDH := &keychain.PrivKeyECDH{PrivKey: initPriv}
|
||||
respPrivECDH := &keychain.PrivKeyECDH{PrivKey: respPriv}
|
||||
|
||||
initiator := brontide.NewBrontideMachine(
|
||||
true, initPrivECDH, respPub, initEphemeral,
|
||||
)
|
||||
responder := brontide.NewBrontideMachine(
|
||||
false, respPrivECDH, nil, respEphemeral,
|
||||
)
|
||||
|
||||
return initiator, responder
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_random_actone is a go-fuzz harness for ActOne in the brontide
|
||||
// handshake.
|
||||
func Fuzz_random_actone(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActOneSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
_, responder := getBrontideMachines()
|
||||
|
||||
// Copy data into [ActOneSize]byte.
|
||||
var actOne [brontide.ActOneSize]byte
|
||||
copy(actOne[:], data)
|
||||
|
||||
// Responder receives ActOne, should fail on the MAC check.
|
||||
if err := responder.RecvActOne(actOne); err == nil {
|
||||
nilAndPanic(nil, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_random_actthree is a go-fuzz harness for ActThree in the brontide
|
||||
// handshake.
|
||||
func Fuzz_random_actthree(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActThreeSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Receiving ActOne should succeed, so we panic on error.
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Generate ActTwo - this is not sent to the initiator because nothing is
|
||||
// done with the initiator after this point and it would slow down fuzzing.
|
||||
// GenActTwo needs to be called to set the appropriate state in the
|
||||
// responder machine.
|
||||
_, err = responder.GenActTwo()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActThreeSize]byte.
|
||||
var actThree [brontide.ActThreeSize]byte
|
||||
copy(actThree[:], data)
|
||||
|
||||
// Responder receives ActThree, should fail on the MAC check.
|
||||
if err := responder.RecvActThree(actThree); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_random_acttwo is a go-fuzz harness for ActTwo in the brontide
|
||||
// handshake.
|
||||
func Fuzz_random_acttwo(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActTwoSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, _ := getBrontideMachines()
|
||||
|
||||
// Generate ActOne - this isn't sent to the responder because nothing is
|
||||
// done with the responder machine and this would slow down fuzzing.
|
||||
// GenActOne needs to be called to set the appropriate state in the
|
||||
// initiator machine.
|
||||
_, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, nil, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActTwoSize]byte.
|
||||
var actTwo [brontide.ActTwoSize]byte
|
||||
copy(actTwo[:], data)
|
||||
|
||||
// Initiator receives ActTwo, should fail.
|
||||
if err := initiator.RecvActTwo(actTwo); err == nil {
|
||||
nilAndPanic(initiator, nil, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// Fuzz_random_init_decrypt is a go-fuzz harness that decrypts arbitrary data
|
||||
// with the initiator.
|
||||
func Fuzz_random_init_decrypt(data []byte) int {
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ initiator machine.
|
||||
if _, err := initiator.ReadMessage(r); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_random_init_enc_dec is a go-fuzz harness that tests round-trip
|
||||
// encryption and decryption between the initiator and the responder.
|
||||
func Fuzz_random_init_enc_dec(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ responder machine.
|
||||
plaintext, err := responder.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_random_init_encrypt is a go-fuzz harness that encrypts arbitrary data
|
||||
// with the initiator.
|
||||
func Fuzz_random_init_encrypt(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// Fuzz_random_resp_decrypt is a go-fuzz harness that decrypts arbitrary data
|
||||
// with the responder.
|
||||
func Fuzz_random_resp_decrypt(data []byte) int {
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ responder machine.
|
||||
if _, err := responder.ReadMessage(r); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_random_resp_enc_dec is a go-fuzz harness that tests round-trip
|
||||
// encryption and decryption between the responder and the initiator.
|
||||
func Fuzz_random_resp_enc_dec(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ initiator machine.
|
||||
plaintext, err := initiator.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_random_resp_encrypt is a go-fuzz harness that encrypts arbitrary data
|
||||
// with the responder.
|
||||
func Fuzz_random_resp_encrypt(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with random keys.
|
||||
initiator, responder := getBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_static_actone is a go-fuzz harness for ActOne in the brontide
|
||||
// handshake.
|
||||
func Fuzz_static_actone(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActOneSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
_, responder := getStaticBrontideMachines()
|
||||
|
||||
// Copy data into [ActOneSize]byte.
|
||||
var actOne [brontide.ActOneSize]byte
|
||||
copy(actOne[:], data)
|
||||
|
||||
// Responder receives ActOne, should fail.
|
||||
if err := responder.RecvActOne(actOne); err == nil {
|
||||
nilAndPanic(nil, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_static_actthree is a go-fuzz harness for ActThree in the brontide
|
||||
// handshake.
|
||||
func Fuzz_static_actthree(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActThreeSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Generate ActOne and send to the responder.
|
||||
actOne, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Receiving ActOne should succeed, so we panic on error.
|
||||
if err := responder.RecvActOne(actOne); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Generate ActTwo - this is not sent to the initiator because nothing is
|
||||
// done with the initiator after this point and it would slow down fuzzing.
|
||||
// GenActTwo needs to be called to set the appropriate state in the responder
|
||||
// machine.
|
||||
_, err = responder.GenActTwo()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActThreeSize]byte.
|
||||
var actThree [brontide.ActThreeSize]byte
|
||||
copy(actThree[:], data)
|
||||
|
||||
// Responder receives ActThree, should fail.
|
||||
if err := responder.RecvActThree(actThree); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
)
|
||||
|
||||
// Fuzz_static_acttwo is a go-fuzz harness for ActTwo in the brontide
|
||||
// handshake.
|
||||
func Fuzz_static_acttwo(data []byte) int {
|
||||
// Check if data is large enough.
|
||||
if len(data) < brontide.ActTwoSize {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, _ := getStaticBrontideMachines()
|
||||
|
||||
// Generate ActOne - this isn't sent to the responder because nothing is
|
||||
// done with the responder machine and this would slow down fuzzing.
|
||||
// GenActOne needs to be called to set the appropriate state in the initiator
|
||||
// machine.
|
||||
_, err := initiator.GenActOne()
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, nil, err)
|
||||
}
|
||||
|
||||
// Copy data into [ActTwoSize]byte.
|
||||
var actTwo [brontide.ActTwoSize]byte
|
||||
copy(actTwo[:], data)
|
||||
|
||||
// Initiator receives ActTwo, should fail.
|
||||
if err := initiator.RecvActTwo(actTwo); err == nil {
|
||||
nilAndPanic(initiator, nil, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// Fuzz_static_init_decrypt is a go-fuzz harness that decrypts arbitrary data
|
||||
// with the initiator.
|
||||
func Fuzz_static_init_decrypt(data []byte) int {
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ initiator machine.
|
||||
if _, err := initiator.ReadMessage(r); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_static_init_enc_dec is a go-fuzz harness that tests round-trip
|
||||
// encryption and decryption
|
||||
// between the initiator and the responder.
|
||||
func Fuzz_static_init_enc_dec(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ responder machine.
|
||||
plaintext, err := responder.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_static_init_encrypt is a go-fuzz harness that encrypts arbitrary data
|
||||
// with the initiator.
|
||||
func Fuzz_static_init_encrypt(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ initiator machine.
|
||||
if err := initiator.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ initiator machine.
|
||||
if _, err := initiator.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// Fuzz_static_resp_decrypt is a go-fuzz harness that decrypts arbitrary data
|
||||
// with the responder.
|
||||
func Fuzz_static_resp_decrypt(data []byte) int {
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Decrypt the encrypted message using ReadMessage w/ responder machine.
|
||||
if _, err := responder.ReadMessage(r); err == nil {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_static_resp_enc_dec is a go-fuzz harness that tests round-trip
|
||||
// encryption and decryption between the responder and the initiator.
|
||||
func Fuzz_static_resp_enc_dec(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Decrypt the ciphertext using ReadMessage w/ initiator machine.
|
||||
plaintext, err := initiator.ReadMessage(&b)
|
||||
if err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Check that the decrypted message and the original message are equal.
|
||||
if !bytes.Equal(data, plaintext) {
|
||||
nilAndPanic(initiator, responder, nil)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package brontidefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Fuzz_static_resp_encrypt is a go-fuzz harness that encrypts arbitrary data
|
||||
// with the responder.
|
||||
func Fuzz_static_resp_encrypt(data []byte) int {
|
||||
// Ensure that length of message is not greater than max allowed size.
|
||||
if len(data) > math.MaxUint16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// This will return brontide machines with static keys.
|
||||
initiator, responder := getStaticBrontideMachines()
|
||||
|
||||
// Complete the brontide handshake.
|
||||
completeHandshake(initiator, responder)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
// Encrypt the message using WriteMessage w/ responder machine.
|
||||
if err := responder.WriteMessage(data); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
// Flush the encrypted message w/ responder machine.
|
||||
if _, err := responder.Flush(&b); err != nil {
|
||||
nilAndPanic(initiator, responder, err)
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_accept_channel is used by go-fuzz.
|
||||
func Fuzz_accept_channel(data []byte) int {
|
||||
// Prefix with MsgAcceptChannel.
|
||||
data = prefixWithMsgType(data, lnwire.MsgAcceptChannel)
|
||||
|
||||
// We have to do this here instead of in fuzz.Harness so that
|
||||
// reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript
|
||||
// encoding, the first message and second message aren't deeply equal since
|
||||
// the first has a nil slice and the other has an empty slice.
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message type) is
|
||||
// less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > lnwire.MaxMsgBody {
|
||||
return 1
|
||||
}
|
||||
|
||||
msg, err := lnwire.ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
// go-fuzz generated []byte that cannot be represented as a
|
||||
// wire message but we will return 0 so go-fuzz can modify the
|
||||
// input.
|
||||
return 1
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := lnwire.ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual.
|
||||
// For UpfrontShutdownScript, we only compare bytes. This probably takes
|
||||
// up more branches than necessary, but that's fine for now.
|
||||
var shouldPanic bool
|
||||
first := msg.(*lnwire.AcceptChannel)
|
||||
second := newMsg.(*lnwire.AcceptChannel)
|
||||
|
||||
if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.DustLimit != second.DustLimit {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxValueInFlight != second.MaxValueInFlight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelReserve != second.ChannelReserve {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.HtlcMinimum != second.HtlcMinimum {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MinAcceptDepth != second.MinAcceptDepth {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.CsvDelay != second.CsvDelay {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FundingKey.IsEqual(second.FundingKey) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.RevocationPoint.IsEqual(second.RevocationPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.PaymentPoint.IsEqual(second.PaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.HtlcPoint.IsEqual(second.HtlcPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
panic("original message and deserialized message are not equal")
|
||||
}
|
||||
|
||||
// Add this input to the corpus.
|
||||
return 1
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_announce_signatures is used by go-fuzz.
|
||||
func Fuzz_announce_signatures(data []byte) int {
|
||||
// Prefix with MsgAnnounceSignatures.
|
||||
data = prefixWithMsgType(data, lnwire.MsgAnnounceSignatures)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_channel_announcement is used by go-fuzz.
|
||||
func Fuzz_channel_announcement(data []byte) int {
|
||||
// Prefix with MsgChannelAnnouncement.
|
||||
data = prefixWithMsgType(data, lnwire.MsgChannelAnnouncement)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_channel_reestablish is used by go-fuzz.
|
||||
func Fuzz_channel_reestablish(data []byte) int {
|
||||
// Prefix with MsgChannelReestablish.
|
||||
data = prefixWithMsgType(data, lnwire.MsgChannelReestablish)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_channel_update is used by go-fuzz.
|
||||
func Fuzz_channel_update(data []byte) int {
|
||||
// Prefix with MsgChannelUpdate.
|
||||
data = prefixWithMsgType(data, lnwire.MsgChannelUpdate)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_closing_signed is used by go-fuzz.
|
||||
func Fuzz_closing_signed(data []byte) int {
|
||||
// Prefix with MsgClosingSigned.
|
||||
data = prefixWithMsgType(data, lnwire.MsgClosingSigned)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_commit_sig is used by go-fuzz.
|
||||
func Fuzz_commit_sig(data []byte) int {
|
||||
// Prefix with MsgCommitSig.
|
||||
data = prefixWithMsgType(data, lnwire.MsgCommitSig)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_error is used by go-fuzz.
|
||||
func Fuzz_error(data []byte) int {
|
||||
// Prefix with MsgError.
|
||||
data = prefixWithMsgType(data, lnwire.MsgError)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_funding_created is used by go-fuzz.
|
||||
func Fuzz_funding_created(data []byte) int {
|
||||
// Prefix with MsgFundingCreated.
|
||||
data = prefixWithMsgType(data, lnwire.MsgFundingCreated)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_funding_locked is used by go-fuzz.
|
||||
func Fuzz_funding_locked(data []byte) int {
|
||||
// Prefix with MsgFundingLocked.
|
||||
data = prefixWithMsgType(data, lnwire.MsgFundingLocked)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_funding_signed is used by go-fuzz.
|
||||
func Fuzz_funding_signed(data []byte) int {
|
||||
// Prefix with MsgFundingSigned.
|
||||
prefixWithMsgType(data, lnwire.MsgFundingSigned)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// prefixWithMsgType takes []byte and adds a wire protocol prefix
|
||||
// to make the []byte into an actual message to be used in fuzzing.
|
||||
func prefixWithMsgType(data []byte, prefix lnwire.MessageType) []byte {
|
||||
var prefixBytes [2]byte
|
||||
binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix))
|
||||
data = append(prefixBytes[:], data...)
|
||||
return data
|
||||
}
|
||||
|
||||
// harness performs the actual fuzz testing of the appropriate wire message.
|
||||
// This function will check that the passed-in message passes wire length checks,
|
||||
// is a valid message once deserialized, and passes a sequence of serialization
|
||||
// and deserialization checks. Returns an int that determines whether the input
|
||||
// is unique or not.
|
||||
func harness(data []byte) int {
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Check that the created message is not greater than the maximum
|
||||
// message size.
|
||||
if len(data) > lnwire.MaxSliceLength {
|
||||
return 1
|
||||
}
|
||||
|
||||
msg, err := lnwire.ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := lnwire.ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(msg, newMsg) {
|
||||
// Deserialized message and original message are not deeply equal.
|
||||
panic("original message and deserialized message are not deeply equal")
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_gossip_timestamp_range is used by go-fuzz.
|
||||
func Fuzz_gossip_timestamp_range(data []byte) int {
|
||||
// Prefix with MsgGossipTimestampRange.
|
||||
data = prefixWithMsgType(data, lnwire.MsgGossipTimestampRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_init is used by go-fuzz.
|
||||
func Fuzz_init(data []byte) int {
|
||||
// Prefix with MsgInit.
|
||||
data = prefixWithMsgType(data, lnwire.MsgInit)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_node_announcement is used by go-fuzz.
|
||||
func Fuzz_node_announcement(data []byte) int {
|
||||
// Prefix with MsgNodeAnnouncement.
|
||||
data = prefixWithMsgType(data, lnwire.MsgNodeAnnouncement)
|
||||
|
||||
// We have to do this here instead of in fuzz.Harness so that
|
||||
// reflect.DeepEqual isn't called. Address (de)serialization messes up
|
||||
// the fuzzing assertions.
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message type) is
|
||||
// less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > lnwire.MaxMsgBody {
|
||||
return 1
|
||||
}
|
||||
|
||||
msg, err := lnwire.ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := lnwire.ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual for the
|
||||
// Addresses field.
|
||||
var shouldPanic bool
|
||||
first := msg.(*lnwire.NodeAnnouncement)
|
||||
second := newMsg.(*lnwire.NodeAnnouncement)
|
||||
if !bytes.Equal(first.Signature[:], second.Signature[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.Features, second.Features) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.Timestamp != second.Timestamp {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.NodeID[:], second.NodeID[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.RGBColor, second.RGBColor) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.Alias[:], second.Alias[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if len(first.Addresses) != len(second.Addresses) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
for i := range first.Addresses {
|
||||
if first.Addresses[i].String() != second.Addresses[i].String() {
|
||||
shouldPanic = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.ExtraOpaqueData, second.ExtraOpaqueData) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
panic("original message and deserialized message are not equal")
|
||||
}
|
||||
|
||||
// Add this input to the corpus.
|
||||
return 1
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_open_channel is used by go-fuzz.
|
||||
func Fuzz_open_channel(data []byte) int {
|
||||
// Prefix with MsgOpenChannel.
|
||||
data = prefixWithMsgType(data, lnwire.MsgOpenChannel)
|
||||
|
||||
// We have to do this here instead of in fuzz.Harness so that
|
||||
// reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript
|
||||
// encoding, the first message and second message aren't deeply equal since
|
||||
// the first has a nil slice and the other has an empty slice.
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message type) is
|
||||
// less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > lnwire.MaxMsgBody {
|
||||
return 1
|
||||
}
|
||||
|
||||
msg, err := lnwire.ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := lnwire.ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual.
|
||||
// For UpfrontShutdownScript, we only compare bytes. This probably takes
|
||||
// up more branches than necessary, but that's fine for now.
|
||||
var shouldPanic bool
|
||||
first := msg.(*lnwire.OpenChannel)
|
||||
second := newMsg.(*lnwire.OpenChannel)
|
||||
|
||||
if !first.ChainHash.IsEqual(&second.ChainHash) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.FundingAmount != second.FundingAmount {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.PushAmount != second.PushAmount {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.DustLimit != second.DustLimit {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxValueInFlight != second.MaxValueInFlight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelReserve != second.ChannelReserve {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.HtlcMinimum != second.HtlcMinimum {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.FeePerKiloWeight != second.FeePerKiloWeight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.CsvDelay != second.CsvDelay {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FundingKey.IsEqual(second.FundingKey) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.RevocationPoint.IsEqual(second.RevocationPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.PaymentPoint.IsEqual(second.PaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.HtlcPoint.IsEqual(second.HtlcPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelFlags != second.ChannelFlags {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
panic("original message and deserialized message are not equal")
|
||||
}
|
||||
|
||||
// Add this input to the corpus.
|
||||
return 1
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_ping is used by go-fuzz.
|
||||
func Fuzz_ping(data []byte) int {
|
||||
// Prefix with MsgPing.
|
||||
data = prefixWithMsgType(data, lnwire.MsgPing)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_pong is used by go-fuzz.
|
||||
func Fuzz_pong(data []byte) int {
|
||||
// Prefix with MsgPong.
|
||||
data = prefixWithMsgType(data, lnwire.MsgPong)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_query_channel_range is used by go-fuzz.
|
||||
func Fuzz_query_channel_range(data []byte) int {
|
||||
// Prefix with MsgQueryChannelRange.
|
||||
data = prefixWithMsgType(data, lnwire.MsgQueryChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_query_short_chan_ids is used by go-fuzz.
|
||||
func Fuzz_query_short_chan_ids(data []byte) int {
|
||||
// Prefix with MsgQueryShortChanIDs.
|
||||
data = prefixWithMsgType(data, lnwire.MsgQueryShortChanIDs)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_query_short_chan_ids_zlib is used by go-fuzz.
|
||||
func Fuzz_query_short_chan_ids_zlib(data []byte) int {
|
||||
|
||||
var buf bytes.Buffer
|
||||
zlibWriter := zlib.NewWriter(&buf)
|
||||
_, err := zlibWriter.Write(data)
|
||||
if err != nil {
|
||||
// Zlib bug?
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := zlibWriter.Close(); err != nil {
|
||||
// Zlib bug?
|
||||
panic(err)
|
||||
}
|
||||
|
||||
compressedPayload := buf.Bytes()
|
||||
|
||||
chainhash := []byte("00000000000000000000000000000000")
|
||||
numBytesInBody := len(compressedPayload) + 1
|
||||
zlibByte := []byte("\x01")
|
||||
|
||||
bodyBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody))
|
||||
|
||||
payload := append(chainhash, bodyBytes...)
|
||||
payload = append(payload, zlibByte...)
|
||||
payload = append(payload, compressedPayload...)
|
||||
|
||||
// Prefix with MsgQueryShortChanIDs.
|
||||
payload = prefixWithMsgType(payload, lnwire.MsgQueryShortChanIDs)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(payload)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_reply_channel_range is used by go-fuzz.
|
||||
func Fuzz_reply_channel_range(data []byte) int {
|
||||
// Prefix with MsgReplyChannelRange.
|
||||
data = prefixWithMsgType(data, lnwire.MsgReplyChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_reply_channel_range_zlib is used by go-fuzz.
|
||||
func Fuzz_reply_channel_range_zlib(data []byte) int {
|
||||
|
||||
var buf bytes.Buffer
|
||||
zlibWriter := zlib.NewWriter(&buf)
|
||||
_, err := zlibWriter.Write(data)
|
||||
if err != nil {
|
||||
// Zlib bug?
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := zlibWriter.Close(); err != nil {
|
||||
// Zlib bug?
|
||||
panic(err)
|
||||
}
|
||||
|
||||
compressedPayload := buf.Bytes()
|
||||
|
||||
// Initialize some []byte vars which will prefix our payload
|
||||
chainhash := []byte("00000000000000000000000000000000")
|
||||
firstBlockHeight := []byte("\x00\x00\x00\x00")
|
||||
numBlocks := []byte("\x00\x00\x00\x00")
|
||||
completeByte := []byte("\x00")
|
||||
|
||||
numBytesInBody := len(compressedPayload) + 1
|
||||
zlibByte := []byte("\x01")
|
||||
|
||||
bodyBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody))
|
||||
|
||||
payload := append(chainhash, firstBlockHeight...)
|
||||
payload = append(payload, numBlocks...)
|
||||
payload = append(payload, completeByte...)
|
||||
payload = append(payload, bodyBytes...)
|
||||
payload = append(payload, zlibByte...)
|
||||
payload = append(payload, compressedPayload...)
|
||||
|
||||
// Prefix with MsgReplyChannelRange.
|
||||
payload = prefixWithMsgType(payload, lnwire.MsgReplyChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(payload)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_reply_short_chan_ids_end is used by go-fuzz.
|
||||
func Fuzz_reply_short_chan_ids_end(data []byte) int {
|
||||
// Prefix with MsgReplyShortChanIDsEnd.
|
||||
data = prefixWithMsgType(data, lnwire.MsgReplyShortChanIDsEnd)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_revoke_and_ack is used by go-fuzz.
|
||||
func Fuzz_revoke_and_ack(data []byte) int {
|
||||
// Prefix with MsgRevokeAndAck.
|
||||
data = prefixWithMsgType(data, lnwire.MsgRevokeAndAck)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_shutdown is used by go-fuzz.
|
||||
func Fuzz_shutdown(data []byte) int {
|
||||
// Prefix with MsgShutdown.
|
||||
data = prefixWithMsgType(data, lnwire.MsgShutdown)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_update_add_htlc is used by go-fuzz.
|
||||
func Fuzz_update_add_htlc(data []byte) int {
|
||||
// Prefix with MsgUpdateAddHTLC.
|
||||
data = prefixWithMsgType(data, lnwire.MsgUpdateAddHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_update_fail_htlc is used by go-fuzz.
|
||||
func Fuzz_update_fail_htlc(data []byte) int {
|
||||
// Prefix with MsgUpdateFailHTLC.
|
||||
data = prefixWithMsgType(data, lnwire.MsgUpdateFailHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_update_fail_malformed_htlc is used by go-fuzz.
|
||||
func Fuzz_update_fail_malformed_htlc(data []byte) int {
|
||||
// Prefix with MsgUpdateFailMalformedHTLC.
|
||||
data = prefixWithMsgType(data, lnwire.MsgUpdateFailMalformedHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_update_fee is used by go-fuzz.
|
||||
func Fuzz_update_fee(data []byte) int {
|
||||
// Prefix with MsgUpdateFee.
|
||||
data = prefixWithMsgType(data, lnwire.MsgUpdateFee)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package lnwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// Fuzz_update_fulfill_htlc is used by go-fuzz.
|
||||
func Fuzz_update_fulfill_htlc(data []byte) int {
|
||||
// Prefix with MsgUpdateFulfillHTLC.
|
||||
data = prefixWithMsgType(data, lnwire.MsgUpdateFulfillHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_create_session is used by go-fuzz.
|
||||
func Fuzz_create_session(data []byte) int {
|
||||
// Prefix with MsgCreateSession.
|
||||
data = prefixWithMsgType(data, wtwire.MsgCreateSession)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.CreateSession{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_create_session_reply is used by go-fuzz.
|
||||
func Fuzz_create_session_reply(data []byte) int {
|
||||
// Prefix with MsgCreateSessionReply.
|
||||
data = prefixWithMsgType(data, wtwire.MsgCreateSessionReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.CreateSessionReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_delete_session is used by go-fuzz.
|
||||
func Fuzz_delete_session(data []byte) int {
|
||||
// Prefix with MsgDeleteSession.
|
||||
data = prefixWithMsgType(data, wtwire.MsgDeleteSession)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.DeleteSession{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_delete_session_reply is used by go-fuzz.
|
||||
func Fuzz_delete_session_reply(data []byte) int {
|
||||
// Prefix with MsgDeleteSessionReply.
|
||||
data = prefixWithMsgType(data, wtwire.MsgDeleteSessionReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.DeleteSessionReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_error is used by go-fuzz.
|
||||
func Fuzz_error(data []byte) int {
|
||||
// Prefix with MsgError.
|
||||
data = prefixWithMsgType(data, wtwire.MsgError)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.Error{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// prefixWithMsgType takes []byte and adds a wire protocol prefix
|
||||
// to make the []byte into an actual message to be used in fuzzing.
|
||||
func prefixWithMsgType(data []byte, prefix wtwire.MessageType) []byte {
|
||||
var prefixBytes [2]byte
|
||||
binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix))
|
||||
data = append(prefixBytes[:], data...)
|
||||
return data
|
||||
}
|
||||
|
||||
// harness performs the actual fuzz testing of the appropriate wire message.
|
||||
// This function will check that the passed-in message passes wire length checks,
|
||||
// is a valid message once deserialized, and passes a sequence of serialization
|
||||
// and deserialization checks. Returns an int that determines whether the input
|
||||
// is unique or not.
|
||||
func harness(data []byte, emptyMsg wtwire.Message) int {
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message type) is
|
||||
// less than max payload size for the wire message. We check this because
|
||||
// otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage
|
||||
// due to a large message size.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > emptyMsg.MaxPayloadLength(0) {
|
||||
// Ignore this input - max payload constraint violated.
|
||||
return 1
|
||||
}
|
||||
|
||||
msg, err := wtwire.ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
// go-fuzz generated []byte that cannot be represented as a
|
||||
// wire message but we will return 0 so go-fuzz can modify the
|
||||
// input.
|
||||
return 1
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := wtwire.WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := wtwire.ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(msg, newMsg) {
|
||||
// Deserialized message and original message are not
|
||||
// deeply equal.
|
||||
panic(fmt.Errorf("deserialized message and original message " +
|
||||
"are not deeply equal."))
|
||||
}
|
||||
|
||||
// Add this input to the corpus.
|
||||
return 1
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_init is used by go-fuzz.
|
||||
func Fuzz_init(data []byte) int {
|
||||
// Prefix with MsgInit.
|
||||
data = prefixWithMsgType(data, wtwire.MsgInit)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.Init{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_state_update is used by go-fuzz.
|
||||
func Fuzz_state_update(data []byte) int {
|
||||
// Prefix with MsgStateUpdate.
|
||||
data = prefixWithMsgType(data, wtwire.MsgStateUpdate)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.StateUpdate{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package wtwirefuzz
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
)
|
||||
|
||||
// Fuzz_state_update_reply is used by go-fuzz.
|
||||
func Fuzz_state_update_reply(data []byte) int {
|
||||
// Prefix with MsgStateUpdateReply.
|
||||
data = prefixWithMsgType(data, wtwire.MsgStateUpdateReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can check if the
|
||||
// max payload constraint is violated.
|
||||
emptyMsg := wtwire.StateUpdateReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire messages!
|
||||
return harness(data, &emptyMsg)
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package zpay32fuzz
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/lightningnetwork/lnd/zpay32"
|
||||
)
|
||||
|
||||
// Fuzz_decode is used by go-fuzz.
|
||||
func Fuzz_decode(data []byte) int {
|
||||
inv, err := zpay32.Decode(string(data), &chaincfg.TestNet3Params)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Call these functions as a sanity check to make sure the invoice
|
||||
// is well-formed.
|
||||
_ = inv.MinFinalCLTVExpiry()
|
||||
_ = inv.Expiry()
|
||||
return 1
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
package zpay32fuzz
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/zpay32"
|
||||
)
|
||||
|
||||
// Fuzz_encode is used by go-fuzz.
|
||||
func Fuzz_encode(data []byte) int {
|
||||
inv, err := zpay32.Decode(string(data), &chaincfg.TestNet3Params)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Call these functions as a sanity check to make sure the invoice
|
||||
// is well-formed.
|
||||
_ = inv.MinFinalCLTVExpiry()
|
||||
_ = inv.Expiry()
|
||||
|
||||
// Initialize the static key we will be using for this fuzz test.
|
||||
testPrivKeyBytes, _ := hex.DecodeString("e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734")
|
||||
testPrivKey, _ := btcec.PrivKeyFromBytes(testPrivKeyBytes)
|
||||
|
||||
// Then, initialize the testMessageSigner so we can encode out
|
||||
// invoices with this private key.
|
||||
testMessageSigner := zpay32.MessageSigner{
|
||||
SignCompact: func(msg []byte) ([]byte, error) {
|
||||
hash := chainhash.HashB(msg)
|
||||
sig, err := ecdsa.SignCompact(testPrivKey, hash, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't sign the "+
|
||||
"message: %v", err)
|
||||
}
|
||||
return sig, nil
|
||||
},
|
||||
}
|
||||
_, err = inv.Encode(testMessageSigner)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
798
lnwire/fuzz_test.go
Normal file
798
lnwire/fuzz_test.go
Normal file
@ -0,0 +1,798 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// prefixWithMsgType takes []byte and adds a wire protocol prefix
|
||||
// to make the []byte into an actual message to be used in fuzzing.
|
||||
func prefixWithMsgType(data []byte, prefix MessageType) []byte {
|
||||
var prefixBytes [2]byte
|
||||
binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix))
|
||||
data = append(prefixBytes[:], data...)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// harness performs the actual fuzz testing of the appropriate wire message.
|
||||
// This function will check that the passed-in message passes wire length
|
||||
// checks, is a valid message once deserialized, and passes a sequence of
|
||||
// serialization and deserialization checks.
|
||||
func harness(t *testing.T, data []byte) {
|
||||
t.Helper()
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Check that the created message is not greater than the maximum
|
||||
// message size.
|
||||
if len(data) > MaxSliceLength {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(msg, newMsg) {
|
||||
// Deserialized message and original message are not deeply
|
||||
// equal.
|
||||
t.Fatal("original message and deserialized message are not " +
|
||||
"deeply equal")
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzAcceptChannel(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
data = prefixWithMsgType(data, MsgAcceptChannel)
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message
|
||||
// type) is less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > MaxMsgBody {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and
|
||||
// then assert that the original message is equal to the newly
|
||||
// deserialized message.
|
||||
newMsg, err := ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer,
|
||||
// panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual.
|
||||
// For UpfrontShutdownScript, we only compare bytes. This
|
||||
// probably takes up more branches than necessary, but that's
|
||||
// fine for now.
|
||||
var shouldPanic bool
|
||||
first, ok := msg.(*AcceptChannel)
|
||||
if !ok {
|
||||
t.Fatal("message was not AcceptChannel")
|
||||
}
|
||||
second, ok := newMsg.(*AcceptChannel)
|
||||
if !ok {
|
||||
t.Fatal("new message was not AcceptChannel")
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.PendingChannelID[:],
|
||||
second.PendingChannelID[:]) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.DustLimit != second.DustLimit {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxValueInFlight != second.MaxValueInFlight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelReserve != second.ChannelReserve {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.HtlcMinimum != second.HtlcMinimum {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MinAcceptDepth != second.MinAcceptDepth {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.CsvDelay != second.CsvDelay {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FundingKey.IsEqual(second.FundingKey) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.RevocationPoint.IsEqual(second.RevocationPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.PaymentPoint.IsEqual(second.PaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.DelayedPaymentPoint.IsEqual(
|
||||
second.DelayedPaymentPoint) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.HtlcPoint.IsEqual(second.HtlcPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FirstCommitmentPoint.IsEqual(
|
||||
second.FirstCommitmentPoint) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.UpfrontShutdownScript,
|
||||
second.UpfrontShutdownScript) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
t.Fatal("original message and deseralized message " +
|
||||
"are not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzAnnounceSignatures(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgAnnounceSignatures.
|
||||
data = prefixWithMsgType(data, MsgAnnounceSignatures)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzChannelAnnouncement(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgChannelAnnouncement.
|
||||
data = prefixWithMsgType(data, MsgChannelAnnouncement)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzChannelReestablish(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgChannelReestablish.
|
||||
data = prefixWithMsgType(data, MsgChannelReestablish)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzChannelUpdate(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgChannelUpdate.
|
||||
data = prefixWithMsgType(data, MsgChannelUpdate)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzClosingSigned(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgClosingSigned.
|
||||
data = prefixWithMsgType(data, MsgClosingSigned)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzCommitSig(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgCommitSig.
|
||||
data = prefixWithMsgType(data, MsgCommitSig)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzError(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgError.
|
||||
data = prefixWithMsgType(data, MsgError)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzFundingCreated(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgFundingCreated.
|
||||
data = prefixWithMsgType(data, MsgFundingCreated)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzFundingLocked(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgFundingLocked.
|
||||
data = prefixWithMsgType(data, MsgFundingLocked)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzFundingSigned(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgFundingSigned.
|
||||
data = prefixWithMsgType(data, MsgFundingSigned)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzGossipTimestampRange(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgGossipTimestampRange.
|
||||
data = prefixWithMsgType(data, MsgGossipTimestampRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzInit(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgInit.
|
||||
data = prefixWithMsgType(data, MsgInit)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzNodeAnnouncement(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgNodeAnnouncement.
|
||||
data = prefixWithMsgType(data, MsgNodeAnnouncement)
|
||||
|
||||
// We have to do this here instead of in harness so that
|
||||
// reflect.DeepEqual isn't called. Address (de)serialization
|
||||
// messes up the fuzzing assertions.
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message
|
||||
// type) is less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > MaxMsgBody {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and
|
||||
// then assert that the original message is equal to the newly
|
||||
// deserialized message.
|
||||
newMsg, err := ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer,
|
||||
// panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual
|
||||
// for the Addresses field.
|
||||
var shouldPanic bool
|
||||
first, ok := msg.(*NodeAnnouncement)
|
||||
if !ok {
|
||||
t.Fatal("message was not NodeAnnouncement")
|
||||
}
|
||||
second, ok := newMsg.(*NodeAnnouncement)
|
||||
if !ok {
|
||||
t.Fatal("new message was not NodeAnnouncement")
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.Signature[:], second.Signature[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.Features, second.Features) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.Timestamp != second.Timestamp {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.NodeID[:], second.NodeID[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.RGBColor, second.RGBColor) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.Alias[:], second.Alias[:]) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if len(first.Addresses) != len(second.Addresses) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
for i := range first.Addresses {
|
||||
if first.Addresses[i].String() !=
|
||||
second.Addresses[i].String() {
|
||||
|
||||
shouldPanic = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(first.ExtraOpaqueData,
|
||||
second.ExtraOpaqueData) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
t.Fatal("original message and deserialized message " +
|
||||
"are not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzOpenChannel(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgOpenChannel.
|
||||
data = prefixWithMsgType(data, MsgOpenChannel)
|
||||
|
||||
// We have to do this here instead of in harness so that
|
||||
// reflect.DeepEqual isn't called. Because of the
|
||||
// UpfrontShutdownScript encoding, the first message and second
|
||||
// message aren't deeply equal since the first has a nil slice
|
||||
// and the other has an empty slice.
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message
|
||||
// type) is less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > MaxMsgBody {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and
|
||||
// then assert that the original message is equal to the newly
|
||||
// deserialized message.
|
||||
newMsg, err := ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer,
|
||||
// panic
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Now compare every field instead of using reflect.DeepEqual.
|
||||
// For UpfrontShutdownScript, we only compare bytes. This
|
||||
// probably takes up more branches than necessary, but that's
|
||||
// fine for now.
|
||||
var shouldPanic bool
|
||||
first, ok := msg.(*OpenChannel)
|
||||
if !ok {
|
||||
t.Fatal("message was not OpenChannel")
|
||||
}
|
||||
second, ok := newMsg.(*OpenChannel)
|
||||
if !ok {
|
||||
t.Fatal("new message was not OpenChannel")
|
||||
}
|
||||
|
||||
if !first.ChainHash.IsEqual(&second.ChainHash) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.PendingChannelID[:],
|
||||
second.PendingChannelID[:]) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.FundingAmount != second.FundingAmount {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.PushAmount != second.PushAmount {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.DustLimit != second.DustLimit {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxValueInFlight != second.MaxValueInFlight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelReserve != second.ChannelReserve {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.HtlcMinimum != second.HtlcMinimum {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.FeePerKiloWeight != second.FeePerKiloWeight {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.CsvDelay != second.CsvDelay {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FundingKey.IsEqual(second.FundingKey) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.RevocationPoint.IsEqual(second.RevocationPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.PaymentPoint.IsEqual(second.PaymentPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.DelayedPaymentPoint.IsEqual(
|
||||
second.DelayedPaymentPoint) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.HtlcPoint.IsEqual(second.HtlcPoint) {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !first.FirstCommitmentPoint.IsEqual(
|
||||
second.FirstCommitmentPoint) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if first.ChannelFlags != second.ChannelFlags {
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if !bytes.Equal(first.UpfrontShutdownScript,
|
||||
second.UpfrontShutdownScript) {
|
||||
|
||||
shouldPanic = true
|
||||
}
|
||||
|
||||
if shouldPanic {
|
||||
t.Fatal("original message and deserialized message " +
|
||||
"are not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzPing(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgPing.
|
||||
data = prefixWithMsgType(data, MsgPing)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzPong(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgPong.
|
||||
data = prefixWithMsgType(data, MsgPong)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzQueryChannelRange(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgQueryChannelRange.
|
||||
data = prefixWithMsgType(data, MsgQueryChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzZlibQueryShortChanIDs(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
var buf bytes.Buffer
|
||||
zlibWriter := zlib.NewWriter(&buf)
|
||||
_, err := zlibWriter.Write(data)
|
||||
if err != nil {
|
||||
// Zlib bug?
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := zlibWriter.Close(); err != nil {
|
||||
// Zlib bug?
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
compressedPayload := buf.Bytes()
|
||||
|
||||
chainhash := []byte("00000000000000000000000000000000")
|
||||
numBytesInBody := len(compressedPayload) + 1
|
||||
zlibByte := []byte("\x01")
|
||||
|
||||
bodyBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody))
|
||||
|
||||
payload := chainhash
|
||||
payload = append(payload, bodyBytes...)
|
||||
payload = append(payload, zlibByte...)
|
||||
payload = append(payload, compressedPayload...)
|
||||
|
||||
// Prefix with MsgQueryShortChanIDs.
|
||||
payload = prefixWithMsgType(payload, MsgQueryShortChanIDs)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, payload)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzQueryShortChanIDs(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgQueryShortChanIDs.
|
||||
data = prefixWithMsgType(data, MsgQueryShortChanIDs)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzZlibReplyChannelRange(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
var buf bytes.Buffer
|
||||
zlibWriter := zlib.NewWriter(&buf)
|
||||
_, err := zlibWriter.Write(data)
|
||||
if err != nil {
|
||||
// Zlib bug?
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := zlibWriter.Close(); err != nil {
|
||||
// Zlib bug?
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
compressedPayload := buf.Bytes()
|
||||
|
||||
// Initialize some []byte vars which will prefix our payload
|
||||
chainhash := []byte("00000000000000000000000000000000")
|
||||
firstBlockHeight := []byte("\x00\x00\x00\x00")
|
||||
numBlocks := []byte("\x00\x00\x00\x00")
|
||||
completeByte := []byte("\x00")
|
||||
|
||||
numBytesInBody := len(compressedPayload) + 1
|
||||
zlibByte := []byte("\x01")
|
||||
|
||||
bodyBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody))
|
||||
|
||||
payload := chainhash
|
||||
payload = append(payload, firstBlockHeight...)
|
||||
payload = append(payload, numBlocks...)
|
||||
payload = append(payload, completeByte...)
|
||||
payload = append(payload, bodyBytes...)
|
||||
payload = append(payload, zlibByte...)
|
||||
payload = append(payload, compressedPayload...)
|
||||
|
||||
// Prefix with MsgReplyChannelRange.
|
||||
payload = prefixWithMsgType(payload, MsgReplyChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, payload)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzReplyChannelRange(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgReplyChannelRange.
|
||||
data = prefixWithMsgType(data, MsgReplyChannelRange)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzReplyShortChanIDsEnd(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgReplyShortChanIDsEnd.
|
||||
data = prefixWithMsgType(data, MsgReplyShortChanIDsEnd)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzRevokeAndAck(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgRevokeAndAck.
|
||||
data = prefixWithMsgType(data, MsgRevokeAndAck)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzShutdown(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgShutdown.
|
||||
data = prefixWithMsgType(data, MsgShutdown)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzUpdateAddHTLC(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgUpdateAddHTLC.
|
||||
data = prefixWithMsgType(data, MsgUpdateAddHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzUpdateFailHTLC(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgUpdateFailHTLC.
|
||||
data = prefixWithMsgType(data, MsgUpdateFailHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzUpdateFailMalformedHTLC(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgUpdateFailMalformedHTLC.
|
||||
data = prefixWithMsgType(data, MsgUpdateFailMalformedHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzUpdateFee(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgUpdateFee.
|
||||
data = prefixWithMsgType(data, MsgUpdateFee)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzUpdateFulfillHTLC(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgUpdateFulFillHTLC.
|
||||
data = prefixWithMsgType(data, MsgUpdateFulfillHTLC)
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data)
|
||||
})
|
||||
}
|
186
watchtower/wtwire/fuzz_test.go
Normal file
186
watchtower/wtwire/fuzz_test.go
Normal file
@ -0,0 +1,186 @@
|
||||
package wtwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// prefixWithMsgType takes []byte and adds a wire protocol prefix
|
||||
// to make the []byte into an actual message to be used in fuzzing.
|
||||
func prefixWithMsgType(data []byte, prefix MessageType) []byte {
|
||||
var prefixBytes [2]byte
|
||||
binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix))
|
||||
data = append(prefixBytes[:], data...)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// harness performs the actual fuzz testing of the appropriate wire message.
|
||||
// This function will check that the passed-in message passes wire length
|
||||
// checks, is a valid message once deserialized, and passes a sequence of
|
||||
// serialization and deserialization checks. Returns an int that determines
|
||||
// whether the input is unique or not.
|
||||
func harness(t *testing.T, data []byte, emptyMsg Message) {
|
||||
t.Helper()
|
||||
|
||||
// Create a reader with the byte array.
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
// Make sure byte array length (excluding 2 bytes for message type) is
|
||||
// less than max payload size for the wire message.
|
||||
payloadLen := uint32(len(data)) - 2
|
||||
if payloadLen > emptyMsg.MaxPayloadLength(0) {
|
||||
// Ignore this input - max payload constraint violated.
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := ReadMessage(r, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We will serialize the message into a new bytes buffer.
|
||||
var b bytes.Buffer
|
||||
if _, err := WriteMessage(&b, msg, 0); err != nil {
|
||||
// Could not serialize message into bytes buffer, panic.
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deserialize the message from the serialized bytes buffer, and then
|
||||
// assert that the original message is equal to the newly deserialized
|
||||
// message.
|
||||
newMsg, err := ReadMessage(&b, 0)
|
||||
if err != nil {
|
||||
// Could not deserialize message from bytes buffer, panic.
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(msg, newMsg) {
|
||||
// Deserialized message and original message are not
|
||||
// deeply equal.
|
||||
t.Fatal("deserialized message and original message " +
|
||||
"are not deeply equal.")
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzCreateSessionReply(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgCreateSessionReply.
|
||||
data = prefixWithMsgType(data, MsgCreateSessionReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := CreateSessionReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzCreateSession(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgCreateSession.
|
||||
data = prefixWithMsgType(data, MsgCreateSession)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := CreateSession{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzDeleteSessionReply(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgDeleteSessionReply.
|
||||
data = prefixWithMsgType(data, MsgDeleteSessionReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := DeleteSessionReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzDeleteSession(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgDeleteSession.
|
||||
data = prefixWithMsgType(data, MsgDeleteSession)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := DeleteSession{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzError(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgError.
|
||||
data = prefixWithMsgType(data, MsgError)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := Error{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzInit(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgInit.
|
||||
data = prefixWithMsgType(data, MsgInit)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := Init{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzStateUpdateReply(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgStateUpdateReply.
|
||||
data = prefixWithMsgType(data, MsgStateUpdateReply)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := StateUpdateReply{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzStateUpdate(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Prefix with MsgStateUpdate.
|
||||
data = prefixWithMsgType(data, MsgStateUpdate)
|
||||
|
||||
// Create an empty message so that the FuzzHarness func can
|
||||
// check if the max payload constraint is violated.
|
||||
emptyMsg := StateUpdate{}
|
||||
|
||||
// Pass the message into our general fuzz harness for wire
|
||||
// messages!
|
||||
harness(t, data, &emptyMsg)
|
||||
})
|
||||
}
|
66
zpay32/fuzz_test.go
Normal file
66
zpay32/fuzz_test.go
Normal file
@ -0,0 +1,66 @@
|
||||
package zpay32
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
func FuzzDecode(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data string) {
|
||||
inv, err := Decode(data, &chaincfg.TestNet3Params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Call these functions as a sanity check to make sure the
|
||||
// invoice is well-formed.
|
||||
_ = inv.MinFinalCLTVExpiry()
|
||||
_ = inv.Expiry()
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzEncode(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data string) {
|
||||
inv, err := Decode(data, &chaincfg.TestNet3Params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Call these functions as a sanity check to make sure the
|
||||
// invoice is well-formed.
|
||||
_ = inv.MinFinalCLTVExpiry()
|
||||
_ = inv.Expiry()
|
||||
|
||||
// Initialize the static key we will be using for this fuzz
|
||||
// test.
|
||||
testPrivKeyBytes, _ := hex.DecodeString("e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734") // nolint:lll
|
||||
testPrivKey, _ := btcec.PrivKeyFromBytes(testPrivKeyBytes)
|
||||
|
||||
// Then, initialize the testMessageSigner so we can encode out
|
||||
// invoices with this private key.
|
||||
testMessageSigner := MessageSigner{
|
||||
SignCompact: func(msg []byte) ([]byte, error) {
|
||||
hash := chainhash.HashB(msg)
|
||||
sig, err := ecdsa.SignCompact(testPrivKey, hash,
|
||||
true)
|
||||
if err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("can't sign the "+
|
||||
"message: %v", err)
|
||||
}
|
||||
|
||||
return sig, nil
|
||||
},
|
||||
}
|
||||
_, err = inv.Encode(testMessageSigner)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user