2017-03-27 20:25:44 +03:00
|
|
|
package discovery
|
|
|
|
|
|
|
|
import (
|
2017-08-23 21:30:50 +03:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
2017-03-27 20:25:44 +03:00
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
|
|
"github.com/roasbeef/btcd/btcec"
|
|
|
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
|
|
|
)
|
|
|
|
|
|
|
|
// validateChannelAnn validates the channel announcement message and checks
|
2017-04-01 15:33:17 +03:00
|
|
|
// that node signatures covers the announcement message, and that the bitcoin
|
|
|
|
// signatures covers the node keys.
|
|
|
|
func (d *AuthenticatedGossiper) validateChannelAnn(a *lnwire.ChannelAnnouncement) error {
|
2017-08-22 09:15:16 +03:00
|
|
|
// First, we'll compute the digest (h) which is to be signed by each of
|
|
|
|
// the keys included within the node announcement message. This hash
|
|
|
|
// digest includes all the keys, so the (up to 4 signatures) will
|
|
|
|
// attest to the validity of each of the keys.
|
|
|
|
data, err := a.DataToSign()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
dataHash := chainhash.DoubleHashB(data)
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// First we'll verify that the passed bitcoin key signature is indeed a
|
2017-08-22 09:15:16 +03:00
|
|
|
// signature over the computed hash digest.
|
|
|
|
if !a.BitcoinSig1.Verify(dataHash, copyPubKey(a.BitcoinKey1)) {
|
2017-03-27 20:25:44 +03:00
|
|
|
return errors.New("can't verify first bitcoin signature")
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// If that checks out, then we'll verify that the second bitcoin
|
2017-08-22 09:15:16 +03:00
|
|
|
// signature is a valid signature of the bitcoin public key over hash
|
|
|
|
// digest as well.
|
|
|
|
if !a.BitcoinSig2.Verify(dataHash, copyPubKey(a.BitcoinKey2)) {
|
2017-03-27 20:25:44 +03:00
|
|
|
return errors.New("can't verify second bitcoin signature")
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// Both node signatures attached should indeed be a valid signature
|
|
|
|
// over the selected digest of the channel announcement signature.
|
2017-03-27 20:25:44 +03:00
|
|
|
if !a.NodeSig1.Verify(dataHash, copyPubKey(a.NodeID1)) {
|
|
|
|
return errors.New("can't verify data in first node signature")
|
|
|
|
}
|
|
|
|
if !a.NodeSig2.Verify(dataHash, copyPubKey(a.NodeID2)) {
|
|
|
|
return errors.New("can't verify data in second node signature")
|
|
|
|
}
|
2017-04-01 15:33:17 +03:00
|
|
|
|
2017-03-27 20:25:44 +03:00
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// validateNodeAnn validates the node announcement by ensuring that the
|
|
|
|
// attached signature is needed a signature of the node announcement under the
|
|
|
|
// specified node public key.
|
|
|
|
func (d *AuthenticatedGossiper) validateNodeAnn(a *lnwire.NodeAnnouncement) error {
|
|
|
|
// Reconstruct the data of announcement which should be covered by the
|
|
|
|
// signature so we can verify the signature shortly below
|
2017-03-27 20:25:44 +03:00
|
|
|
data, err := a.DataToSign()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:33:17 +03:00
|
|
|
// Finally ensure that the passed signature is valid, if not we'll
|
|
|
|
// return an error so this node announcement can be rejected.
|
2017-03-27 20:25:44 +03:00
|
|
|
dataHash := chainhash.DoubleHashB(data)
|
|
|
|
if !a.Signature.Verify(dataHash, copyPubKey(a.NodeID)) {
|
2017-04-02 11:13:00 +03:00
|
|
|
return errors.New("signature on node announcement is invalid")
|
2017-03-27 20:25:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// validateChannelUpdateAnn validates the channel update announcement by
|
2017-04-01 15:33:17 +03:00
|
|
|
// checking that the included signature covers he announcement and has been
|
|
|
|
// signed by the node's private key.
|
|
|
|
func (d *AuthenticatedGossiper) validateChannelUpdateAnn(pubKey *btcec.PublicKey,
|
2017-04-20 02:20:46 +03:00
|
|
|
a *lnwire.ChannelUpdate) error {
|
2017-03-27 20:25:44 +03:00
|
|
|
|
|
|
|
data, err := a.DataToSign()
|
|
|
|
if err != nil {
|
2017-04-01 15:33:17 +03:00
|
|
|
return errors.Errorf("unable to reconstruct message: %v", err)
|
2017-03-27 20:25:44 +03:00
|
|
|
}
|
|
|
|
dataHash := chainhash.DoubleHashB(data)
|
|
|
|
|
|
|
|
if !a.Signature.Verify(dataHash, copyPubKey(pubKey)) {
|
2017-08-23 21:30:50 +03:00
|
|
|
return errors.Errorf("invalid signature for channel "+
|
|
|
|
"update %v", spew.Sdump(a))
|
2017-03-27 20:25:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|