fix handling of dht records and local fixups
License: MIT Signed-off-by: Jeromy <why@ipfs.io>
Jeromy committed
Jul 5, 2016 at 12:19 UTC
3e54fb47a910e71b96a21495f9134d12d0f00970
3 files changed
+52
-4
routing/dht/routing.go
+7
@@ -122,6 +122,13 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key key.Key) ([]byte, error) {
122
// if someone sent us a different 'less-valid' record, lets correct them
123
if !bytes.Equal(v.Val, best) {
124
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
+ }
132
ctx, cancel := context.WithTimeout(dht.Context(), time.Second*30)
133
defer cancel()
134
err := dht.putValueToPeer(ctx, v.From, key, fixupRec)
routing/record/validation.go
+10
-4
@@ -73,13 +73,19 @@ func (v Validator) IsSigned(k key.Key) (bool, error) {
73
// verifies that the passed in record value is the PublicKey
74
// that matches the passed in key.
75
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")
76
+ if len(k) != 38 {
77
+ return errors.New("invalid public key record key")
78
}
79
80
+ prefix := string(k[:4])
81
+ if prefix != "/pk/" {
82
+ return errors.New("key was not prefixed with /pk/")
83
+ }
84
+
85
+ keyhash := []byte(k[4:])
86
+
87
pkh := u.Hash(val)
82
- if !bytes.Equal(keyparts[2], pkh) {
88
+ if !bytes.Equal(keyhash, pkh) {
89
return errors.New("public key does not match storage key")
90
}
91
return nil
routing/record/validation_test.go
new
+35
@@ -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
+}