github.com/decred/dcrlnd@v0.7.6/routing/ann_validation.go (about) 1 package routing 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/davecgh/go-spew/spew" 8 "github.com/decred/dcrd/chaincfg/chainhash" 9 "github.com/decred/dcrd/dcrec/secp256k1/v4" 10 "github.com/decred/dcrd/dcrutil/v4" 11 "github.com/decred/dcrlnd/lnwire" 12 "github.com/go-errors/errors" 13 ) 14 15 // ValidateChannelAnn validates the channel announcement message and checks 16 // that node signatures covers the announcement message, and that the bitcoin 17 // signatures covers the node keys. 18 func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error { 19 // First, we'll compute the digest (h) which is to be signed by each of 20 // the keys included within the node announcement message. This hash 21 // digest includes all the keys, so the (up to 4 signatures) will 22 // attest to the validity of each of the keys. 23 data, err := a.DataToSign() 24 if err != nil { 25 return err 26 } 27 dataHash := chainhash.HashB(data) 28 29 // First we'll verify that the passed bitcoin key signature is indeed a 30 // signature over the computed hash digest. 31 decredSig1, err := a.DecredSig1.ToSignature() 32 if err != nil { 33 return err 34 } 35 bitcoinKey1, err := secp256k1.ParsePubKey(a.DecredKey1[:]) 36 if err != nil { 37 return err 38 } 39 if !decredSig1.Verify(dataHash, bitcoinKey1) { 40 return errors.New("can't verify first bitcoin signature") 41 } 42 43 // If that checks out, then we'll verify that the second bitcoin 44 // signature is a valid signature of the bitcoin public key over hash 45 // digest as well. 46 decredSig2, err := a.DecredSig2.ToSignature() 47 if err != nil { 48 return err 49 } 50 bitcoinKey2, err := secp256k1.ParsePubKey(a.DecredKey2[:]) 51 if err != nil { 52 return err 53 } 54 if !decredSig2.Verify(dataHash, bitcoinKey2) { 55 return errors.New("can't verify second bitcoin signature") 56 } 57 58 // Both node signatures attached should indeed be a valid signature 59 // over the selected digest of the channel announcement signature. 60 nodeSig1, err := a.NodeSig1.ToSignature() 61 if err != nil { 62 return err 63 } 64 nodeKey1, err := secp256k1.ParsePubKey(a.NodeID1[:]) 65 if err != nil { 66 return err 67 } 68 if !nodeSig1.Verify(dataHash, nodeKey1) { 69 return errors.New("can't verify data in first node signature") 70 } 71 72 nodeSig2, err := a.NodeSig2.ToSignature() 73 if err != nil { 74 return err 75 } 76 nodeKey2, err := secp256k1.ParsePubKey(a.NodeID2[:]) 77 if err != nil { 78 return err 79 } 80 if !nodeSig2.Verify(dataHash, nodeKey2) { 81 return errors.New("can't verify data in second node signature") 82 } 83 84 return nil 85 86 } 87 88 // ValidateNodeAnn validates the node announcement by ensuring that the 89 // attached signature is needed a signature of the node announcement under the 90 // specified node public key. 91 func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error { 92 // Reconstruct the data of announcement which should be covered by the 93 // signature so we can verify the signature shortly below 94 data, err := a.DataToSign() 95 if err != nil { 96 return err 97 } 98 99 nodeSig, err := a.Signature.ToSignature() 100 if err != nil { 101 return err 102 } 103 nodeKey, err := secp256k1.ParsePubKey(a.NodeID[:]) 104 if err != nil { 105 return err 106 } 107 108 // Finally ensure that the passed signature is valid, if not we'll 109 // return an error so this node announcement can be rejected. 110 dataHash := chainhash.HashB(data) 111 if !nodeSig.Verify(dataHash, nodeKey) { 112 var msgBuf bytes.Buffer 113 if _, err := lnwire.WriteMessage(&msgBuf, a, 0); err != nil { 114 return err 115 } 116 117 return errors.Errorf("signature on NodeAnnouncement(%x) is "+ 118 "invalid: %x", nodeKey.SerializeCompressed(), 119 msgBuf.Bytes()) 120 } 121 122 return nil 123 } 124 125 // ValidateChannelUpdateAnn validates the channel update announcement by 126 // checking (1) that the included signature covers the announcement and has 127 // been signed by the node's private key, and (2) that the announcement's 128 // message flags and optional fields are sane. 129 func ValidateChannelUpdateAnn(pubKey *secp256k1.PublicKey, capacity dcrutil.Amount, 130 a *lnwire.ChannelUpdate) error { 131 132 if err := validateOptionalFields(capacity, a); err != nil { 133 return err 134 } 135 136 return VerifyChannelUpdateSignature(a, pubKey) 137 } 138 139 // VerifyChannelUpdateSignature verifies that the channel update message was 140 // signed by the party with the given node public key. 141 func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate, 142 pubKey *secp256k1.PublicKey) error { 143 144 data, err := msg.DataToSign() 145 if err != nil { 146 return fmt.Errorf("unable to reconstruct message data: %v", err) 147 } 148 dataHash := chainhash.HashB(data) 149 150 nodeSig, err := msg.Signature.ToSignature() 151 if err != nil { 152 return err 153 } 154 155 if !nodeSig.Verify(dataHash, pubKey) { 156 return fmt.Errorf("invalid signature for channel update %v", 157 spew.Sdump(msg)) 158 } 159 160 return nil 161 } 162 163 // validateOptionalFields validates a channel update's message flags and 164 // corresponding update fields. 165 func validateOptionalFields(capacity dcrutil.Amount, 166 msg *lnwire.ChannelUpdate) error { 167 168 if msg.MessageFlags.HasMaxHtlc() { 169 maxHtlc := msg.HtlcMaximumMAtoms 170 if maxHtlc == 0 || maxHtlc < msg.HtlcMinimumMAtoms { 171 return errors.Errorf("invalid max htlc for channel "+ 172 "update %v", spew.Sdump(msg)) 173 } 174 175 // For light clients, the capacity will not be set so we'll skip 176 // checking whether the MaxHTLC value respects the channel's 177 // capacity. 178 capacityMat := lnwire.NewMAtomsFromAtoms(capacity) 179 if capacityMat != 0 && maxHtlc > capacityMat { 180 return errors.Errorf("max_htlc(%v) for channel "+ 181 "update greater than capacity(%v)", maxHtlc, 182 capacityMat) 183 } 184 } 185 186 return nil 187 }