Skip to content

Commit 1f3b3c5

Browse files
Merge pull request #2943 from ipfs/fix/dht-key-handling
fix handling of dht records and local fixups
2 parents ad5730d + b56d481 commit 1f3b3c5

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

routing/dht/routing.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key key.Key) ([]byte, error) {
122122
// if someone sent us a different 'less-valid' record, lets correct them
123123
if !bytes.Equal(v.Val, best) {
124124
go func(v routing.RecvdVal) {
125+
if v.From == dht.self {
126+
err := dht.putLocal(key, fixupRec)
127+
if err != nil {
128+
log.Error("Error correcting local dht entry:", err)
129+
}
130+
return
131+
}
125132
ctx, cancel := context.WithTimeout(dht.Context(), time.Second*30)
126133
defer cancel()
127134
err := dht.putValueToPeer(ctx, v.From, key, fixupRec)

routing/record/validation.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package record
33
import (
44
"bytes"
55
"errors"
6+
"fmt"
67

78
key "github.com/ipfs/go-ipfs/blocks/key"
89
path "github.com/ipfs/go-ipfs/path"
910
pb "github.com/ipfs/go-ipfs/routing/dht/pb"
1011
ci "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
12+
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
1113
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
1214
)
1315

@@ -73,13 +75,22 @@ func (v Validator) IsSigned(k key.Key) (bool, error) {
7375
// verifies that the passed in record value is the PublicKey
7476
// that matches the passed in key.
7577
func ValidatePublicKeyRecord(k key.Key, val []byte) error {
76-
keyparts := bytes.Split([]byte(k), []byte("/"))
77-
if len(keyparts) < 3 {
78-
return errors.New("invalid key")
78+
if len(k) < 5 {
79+
return errors.New("invalid public key record key")
80+
}
81+
82+
prefix := string(k[:4])
83+
if prefix != "/pk/" {
84+
return errors.New("key was not prefixed with /pk/")
85+
}
86+
87+
keyhash := []byte(k[4:])
88+
if _, err := mh.Cast(keyhash); err != nil {
89+
return fmt.Errorf("key did not contain valid multihash: %s", err)
7990
}
8091

8192
pkh := u.Hash(val)
82-
if !bytes.Equal(keyparts[2], pkh) {
93+
if !bytes.Equal(keyhash, pkh) {
8394
return errors.New("public key does not match storage key")
8495
}
8596
return nil

routing/record/validation_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package record
2+
3+
import (
4+
"encoding/base64"
5+
"testing"
6+
7+
key "github.com/ipfs/go-ipfs/blocks/key"
8+
ci "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
9+
)
10+
11+
var OffensiveKey = "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDjXAQQMal4SB2tSnX6NJIPmC69/BT8A8jc7/gDUZNkEhdhYHvc7k7S4vntV/c92nJGxNdop9fKJyevuNMuXhhHAgMBAAE="
12+
13+
func TestValidatePublicKey(t *testing.T) {
14+
pkb, err := base64.StdEncoding.DecodeString(OffensiveKey)
15+
if err != nil {
16+
t.Fatal(err)
17+
}
18+
19+
pubk, err := ci.UnmarshalPublicKey(pkb)
20+
if err != nil {
21+
t.Fatal(err)
22+
}
23+
24+
pkh, err := pubk.Hash()
25+
if err != nil {
26+
t.Fatal(err)
27+
}
28+
29+
k := key.Key("/pk/" + string(pkh))
30+
31+
err = ValidatePublicKeyRecord(k, pkb)
32+
if err != nil {
33+
t.Fatal(err)
34+
}
35+
}

0 commit comments

Comments
 (0)