enr.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. // Package enr implements Ethereum Node Records as defined in EIP-778. A node record holds
  17. // arbitrary information about a node on the peer-to-peer network.
  18. //
  19. // Records contain named keys. To store and retrieve key/values in a record, use the Entry
  20. // interface.
  21. //
  22. // Records must be signed before transmitting them to another node. Decoding a record verifies
  23. // its signature. When creating a record, set the entries you want, then call Sign to add the
  24. // signature. Modifying a record invalidates the signature.
  25. //
  26. // Package enr supports the "secp256k1-keccak" identity scheme.
  27. package enr
  28. import (
  29. "bytes"
  30. "crypto/ecdsa"
  31. "errors"
  32. "fmt"
  33. "io"
  34. "sort"
  35. "github.com/ethereum/go-ethereum/crypto"
  36. "github.com/ethereum/go-ethereum/crypto/sha3"
  37. "github.com/ethereum/go-ethereum/rlp"
  38. )
  39. const SizeLimit = 300 // maximum encoded size of a node record in bytes
  40. const ID_SECP256k1_KECCAK = ID("secp256k1-keccak") // the default identity scheme
  41. var (
  42. errNoID = errors.New("unknown or unspecified identity scheme")
  43. errInvalidSig = errors.New("invalid signature")
  44. errNotSorted = errors.New("record key/value pairs are not sorted by key")
  45. errDuplicateKey = errors.New("record contains duplicate key")
  46. errIncompletePair = errors.New("record contains incomplete k/v pair")
  47. errTooBig = fmt.Errorf("record bigger than %d bytes", SizeLimit)
  48. errEncodeUnsigned = errors.New("can't encode unsigned record")
  49. errNotFound = errors.New("no such key in record")
  50. )
  51. // Record represents a node record. The zero value is an empty record.
  52. type Record struct {
  53. seq uint64 // sequence number
  54. signature []byte // the signature
  55. raw []byte // RLP encoded record
  56. pairs []pair // sorted list of all key/value pairs
  57. }
  58. // pair is a key/value pair in a record.
  59. type pair struct {
  60. k string
  61. v rlp.RawValue
  62. }
  63. // Signed reports whether the record has a valid signature.
  64. func (r *Record) Signed() bool {
  65. return r.signature != nil
  66. }
  67. // Seq returns the sequence number.
  68. func (r *Record) Seq() uint64 {
  69. return r.seq
  70. }
  71. // SetSeq updates the record sequence number. This invalidates any signature on the record.
  72. // Calling SetSeq is usually not required because signing the redord increments the
  73. // sequence number.
  74. func (r *Record) SetSeq(s uint64) {
  75. r.signature = nil
  76. r.raw = nil
  77. r.seq = s
  78. }
  79. // Load retrieves the value of a key/value pair. The given Entry must be a pointer and will
  80. // be set to the value of the entry in the record.
  81. //
  82. // Errors returned by Load are wrapped in KeyError. You can distinguish decoding errors
  83. // from missing keys using the IsNotFound function.
  84. func (r *Record) Load(e Entry) error {
  85. i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() })
  86. if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() {
  87. if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil {
  88. return &KeyError{Key: e.ENRKey(), Err: err}
  89. }
  90. return nil
  91. }
  92. return &KeyError{Key: e.ENRKey(), Err: errNotFound}
  93. }
  94. // Set adds or updates the given entry in the record.
  95. // It panics if the value can't be encoded.
  96. func (r *Record) Set(e Entry) {
  97. r.signature = nil
  98. r.raw = nil
  99. blob, err := rlp.EncodeToBytes(e)
  100. if err != nil {
  101. panic(fmt.Errorf("enr: can't encode %s: %v", e.ENRKey(), err))
  102. }
  103. i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() })
  104. if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() {
  105. // element is present at r.pairs[i]
  106. r.pairs[i].v = blob
  107. return
  108. } else if i < len(r.pairs) {
  109. // insert pair before i-th elem
  110. el := pair{e.ENRKey(), blob}
  111. r.pairs = append(r.pairs, pair{})
  112. copy(r.pairs[i+1:], r.pairs[i:])
  113. r.pairs[i] = el
  114. return
  115. }
  116. // element should be placed at the end of r.pairs
  117. r.pairs = append(r.pairs, pair{e.ENRKey(), blob})
  118. }
  119. // EncodeRLP implements rlp.Encoder. Encoding fails if
  120. // the record is unsigned.
  121. func (r Record) EncodeRLP(w io.Writer) error {
  122. if !r.Signed() {
  123. return errEncodeUnsigned
  124. }
  125. _, err := w.Write(r.raw)
  126. return err
  127. }
  128. // DecodeRLP implements rlp.Decoder. Decoding verifies the signature.
  129. func (r *Record) DecodeRLP(s *rlp.Stream) error {
  130. raw, err := s.Raw()
  131. if err != nil {
  132. return err
  133. }
  134. if len(raw) > SizeLimit {
  135. return errTooBig
  136. }
  137. // Decode the RLP container.
  138. dec := Record{raw: raw}
  139. s = rlp.NewStream(bytes.NewReader(raw), 0)
  140. if _, err := s.List(); err != nil {
  141. return err
  142. }
  143. if err = s.Decode(&dec.signature); err != nil {
  144. return err
  145. }
  146. if err = s.Decode(&dec.seq); err != nil {
  147. return err
  148. }
  149. // The rest of the record contains sorted k/v pairs.
  150. var prevkey string
  151. for i := 0; ; i++ {
  152. var kv pair
  153. if err := s.Decode(&kv.k); err != nil {
  154. if err == rlp.EOL {
  155. break
  156. }
  157. return err
  158. }
  159. if err := s.Decode(&kv.v); err != nil {
  160. if err == rlp.EOL {
  161. return errIncompletePair
  162. }
  163. return err
  164. }
  165. if i > 0 {
  166. if kv.k == prevkey {
  167. return errDuplicateKey
  168. }
  169. if kv.k < prevkey {
  170. return errNotSorted
  171. }
  172. }
  173. dec.pairs = append(dec.pairs, kv)
  174. prevkey = kv.k
  175. }
  176. if err := s.ListEnd(); err != nil {
  177. return err
  178. }
  179. // Verify signature.
  180. if err = dec.verifySignature(); err != nil {
  181. return err
  182. }
  183. *r = dec
  184. return nil
  185. }
  186. type s256raw []byte
  187. func (s256raw) ENRKey() string { return "secp256k1" }
  188. // NodeAddr returns the node address. The return value will be nil if the record is
  189. // unsigned.
  190. func (r *Record) NodeAddr() []byte {
  191. var entry s256raw
  192. if r.Load(&entry) != nil {
  193. return nil
  194. }
  195. return crypto.Keccak256(entry)
  196. }
  197. // Sign signs the record with the given private key. It updates the record's identity
  198. // scheme, public key and increments the sequence number. Sign returns an error if the
  199. // encoded record is larger than the size limit.
  200. func (r *Record) Sign(privkey *ecdsa.PrivateKey) error {
  201. r.seq = r.seq + 1
  202. r.Set(ID_SECP256k1_KECCAK)
  203. r.Set(Secp256k1(privkey.PublicKey))
  204. return r.signAndEncode(privkey)
  205. }
  206. func (r *Record) appendPairs(list []interface{}) []interface{} {
  207. list = append(list, r.seq)
  208. for _, p := range r.pairs {
  209. list = append(list, p.k, p.v)
  210. }
  211. return list
  212. }
  213. func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
  214. // Put record elements into a flat list. Leave room for the signature.
  215. list := make([]interface{}, 1, len(r.pairs)*2+2)
  216. list = r.appendPairs(list)
  217. // Sign the tail of the list.
  218. h := sha3.NewKeccak256()
  219. rlp.Encode(h, list[1:])
  220. sig, err := crypto.Sign(h.Sum(nil), privkey)
  221. if err != nil {
  222. return err
  223. }
  224. sig = sig[:len(sig)-1] // remove v
  225. // Put signature in front.
  226. r.signature, list[0] = sig, sig
  227. r.raw, err = rlp.EncodeToBytes(list)
  228. if err != nil {
  229. return err
  230. }
  231. if len(r.raw) > SizeLimit {
  232. return errTooBig
  233. }
  234. return nil
  235. }
  236. func (r *Record) verifySignature() error {
  237. // Get identity scheme, public key, signature.
  238. var id ID
  239. var entry s256raw
  240. if err := r.Load(&id); err != nil {
  241. return err
  242. } else if id != ID_SECP256k1_KECCAK {
  243. return errNoID
  244. }
  245. if err := r.Load(&entry); err != nil {
  246. return err
  247. } else if len(entry) != 33 {
  248. return fmt.Errorf("invalid public key")
  249. }
  250. // Verify the signature.
  251. list := make([]interface{}, 0, len(r.pairs)*2+1)
  252. list = r.appendPairs(list)
  253. h := sha3.NewKeccak256()
  254. rlp.Encode(h, list)
  255. if !crypto.VerifySignature(entry, h.Sum(nil), r.signature) {
  256. return errInvalidSig
  257. }
  258. return nil
  259. }