p2p/enr: check for size limit in Sign; WithKey(k, v) for adding random key/values

This commit is contained in:
Anton Evangelatov 2017-12-06 12:43:08 +01:00 committed by Felix Lange
parent 172ff10d40
commit 301ac8b8fd
3 changed files with 68 additions and 1 deletions

View file

@ -40,6 +40,7 @@ var (
errNotSorted = errors.New("record key/value pairs are not sorted by key") errNotSorted = errors.New("record key/value pairs are not sorted by key")
errDuplicateKey = errors.New("record contains duplicate key") errDuplicateKey = errors.New("record contains duplicate key")
errIncompletePair = errors.New("record contains incomplete k/v pair") errIncompletePair = errors.New("record contains incomplete k/v pair")
errTooBig = errors.New("record bigger than 300 bytes")
) )
// Key is implemented by known node record key types. // Key is implemented by known node record key types.
@ -221,7 +222,15 @@ func (r *Record) signAndEncode(privkey *ecdsa.PrivateKey) error {
r.signature = encodeCompactSignature(sig) r.signature = encodeCompactSignature(sig)
list[0] = r.signature list[0] = r.signature
r.raw, err = rlp.EncodeToBytes(list) r.raw, err = rlp.EncodeToBytes(list)
if err != nil {
return err return err
}
if len(r.raw) > 300 {
return errTooBig
}
return nil
} }
func (r *Record) verifySignature() error { func (r *Record) verifySignature() error {

View file

@ -19,9 +19,11 @@ package enr
import ( import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"math/rand"
"net" "net"
"reflect" "reflect"
"testing" "testing"
"time"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -268,3 +270,38 @@ func TestPythonInterop(t *testing.T) {
} }
} }
} }
func TestRecordTooBig(t *testing.T) {
privkey, err := crypto.HexToECDSA(privkeyHex)
if err != nil {
t.Fatal(err)
}
var r Record
key := randomString(10)
// set a big value for random key, expect error
r.Set(WithKey(key, randomString(300)))
err = r.Sign(privkey)
if err != errTooBig {
t.Fatalf("expected to get errTooBig, got %#v", err)
}
// set an acceptable value for random key, expect no error
r.Set(WithKey(key, randomString(100)))
err = r.Sign(privkey)
if err != nil {
t.Fatal(err)
}
}
func randomString(strlen int) string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
result := make([]byte, strlen)
for i := range result {
result[i] = chars[r.Intn(len(chars))]
}
return string(result)
}

View file

@ -26,6 +26,27 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
type generic struct {
key string
value interface{}
}
func (g generic) ENRKey() string {
return g.key
}
func (g generic) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, g.value)
}
func (g *generic) DecodeRLP(s *rlp.Stream) error {
return s.Decode(&g.value)
}
func WithKey(k string, v interface{}) Key {
return &generic{key: k, value: v}
}
// DiscPort represents an UDP port for discovery v5. // DiscPort represents an UDP port for discovery v5.
type DiscPort uint16 type DiscPort uint16