Skip to content

Commit

Permalink
Merge pull request #2943 from ipfs/fix/dht-key-handling
Browse files Browse the repository at this point in the history
fix handling of dht records and local fixups
  • Loading branch information
whyrusleeping authored Jul 5, 2016
2 parents ad5730d + b56d481 commit 1f3b3c5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
7 changes: 7 additions & 0 deletions routing/dht/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key key.Key) ([]byte, error) {
// if someone sent us a different 'less-valid' record, lets correct them
if !bytes.Equal(v.Val, best) {
go func(v routing.RecvdVal) {
if v.From == dht.self {
err := dht.putLocal(key, fixupRec)
if err != nil {
log.Error("Error correcting local dht entry:", err)
}
return
}
ctx, cancel := context.WithTimeout(dht.Context(), time.Second*30)
defer cancel()
err := dht.putValueToPeer(ctx, v.From, key, fixupRec)
Expand Down
19 changes: 15 additions & 4 deletions routing/record/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package record
import (
"bytes"
"errors"
"fmt"

key "github.com/ipfs/go-ipfs/blocks/key"
path "github.com/ipfs/go-ipfs/path"
pb "github.com/ipfs/go-ipfs/routing/dht/pb"
ci "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
)

Expand Down Expand Up @@ -73,13 +75,22 @@ func (v Validator) IsSigned(k key.Key) (bool, error) {
// verifies that the passed in record value is the PublicKey
// that matches the passed in key.
func ValidatePublicKeyRecord(k key.Key, val []byte) error {
keyparts := bytes.Split([]byte(k), []byte("/"))
if len(keyparts) < 3 {
return errors.New("invalid key")
if len(k) < 5 {
return errors.New("invalid public key record key")
}

prefix := string(k[:4])
if prefix != "/pk/" {
return errors.New("key was not prefixed with /pk/")
}

keyhash := []byte(k[4:])
if _, err := mh.Cast(keyhash); err != nil {
return fmt.Errorf("key did not contain valid multihash: %s", err)
}

pkh := u.Hash(val)
if !bytes.Equal(keyparts[2], pkh) {
if !bytes.Equal(keyhash, pkh) {
return errors.New("public key does not match storage key")
}
return nil
Expand Down
35 changes: 35 additions & 0 deletions routing/record/validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package record

import (
"encoding/base64"
"testing"

key "github.com/ipfs/go-ipfs/blocks/key"
ci "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
)

var OffensiveKey = "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDjXAQQMal4SB2tSnX6NJIPmC69/BT8A8jc7/gDUZNkEhdhYHvc7k7S4vntV/c92nJGxNdop9fKJyevuNMuXhhHAgMBAAE="

func TestValidatePublicKey(t *testing.T) {
pkb, err := base64.StdEncoding.DecodeString(OffensiveKey)
if err != nil {
t.Fatal(err)
}

pubk, err := ci.UnmarshalPublicKey(pkb)
if err != nil {
t.Fatal(err)
}

pkh, err := pubk.Hash()
if err != nil {
t.Fatal(err)
}

k := key.Key("/pk/" + string(pkh))

err = ValidatePublicKeyRecord(k, pkb)
if err != nil {
t.Fatal(err)
}
}

0 comments on commit 1f3b3c5

Please sign in to comment.