Do not publish public keys extractable from ID (with tests)
License: MIT Signed-off-by: Justin Drake <drakefjustin@gmail.com>
Justin Drake committed
Jun 28, 2017 at 11:18 UTC
cf5618c2114f9b4aa8af8e31b4d02253a29d3518
2 files changed
+127
-6
namesys/publisher.go
+12
-6
@@ -150,18 +150,24 @@ func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqn
150
entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds()))
151
}
152
153
- errs := make(chan error, 2)
153
+ errs := make(chan error, 2) // At most two errors (IPNS, and public key)
154
+
155
+ // Attempt to extract the public key from the ID
156
+ extractedPublicKey := id.ExtractPublicKey()
157
158
go func() {
159
errs <- PublishEntry(ctx, r, ipnskey, entry)
160
}()
161
159
- go func() {
160
- errs <- PublishPublicKey(ctx, r, namekey, k.GetPublic())
161
- }()
162
+ // Publish the public key if a public key cannot be extracted from the ID
163
+ if extractedPublicKey == nil {
164
+ go func() {
165
+ errs <- PublishPublicKey(ctx, r, namekey, k.GetPublic())
166
+ }()
167
163
- if err := waitOnErrChan(ctx, errs); err != nil {
164
- return err
168
+ if err := waitOnErrChan(ctx, errs); err != nil {
169
+ return err
170
+ }
171
}
172
173
return waitOnErrChan(ctx, errs)
namesys/publisher_test.go
new
+115
@@ -0,0 +1,115 @@
1
+package namesys
2
+
3
+import (
4
+ "context"
5
+ "crypto/rand"
6
+ "testing"
7
+ "time"
8
+
9
+ path "github.com/ipfs/go-ipfs/path"
10
+ mockrouting "github.com/ipfs/go-ipfs/routing/mock"
11
+ dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help"
12
+ testutil "github.com/ipfs/go-ipfs/thirdparty/testutil"
13
+
14
+ ds "gx/ipfs/QmVSase1JP7cq9QkPT46oNwdp9pT6kBkG3oqS14y3QcZjG/go-datastore"
15
+ dssync "gx/ipfs/QmVSase1JP7cq9QkPT46oNwdp9pT6kBkG3oqS14y3QcZjG/go-datastore/sync"
16
+ ma "gx/ipfs/QmXY77cVe7rVRQXZZQRioukUM7aRW3BTcAgJe12MCtb3Ji/go-multiaddr"
17
+ peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
18
+ ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
19
+)
20
+
21
+type identity struct {
22
+ testutil.PeerNetParams
23
+}
24
+
25
+func (p *identity) ID() peer.ID {
26
+ return p.PeerNetParams.ID
27
+}
28
+
29
+func (p *identity) Address() ma.Multiaddr {
30
+ return p.Addr
31
+}
32
+
33
+func (p *identity) PrivateKey() ci.PrivKey {
34
+ return p.PrivKey
35
+}
36
+
37
+func (p *identity) PublicKey() ci.PubKey {
38
+ return p.PubKey
39
+}
40
+
41
+func testNamekeyPublisher(t *testing.T, keyType int, expectedErr error, expectedExistence bool) {
42
+ // Context
43
+ ctx := context.Background()
44
+
45
+ // Private key
46
+ privKey, pubKey, err := ci.GenerateKeyPairWithReader(keyType, 2048, rand.Reader)
47
+ if err != nil {
48
+ t.Fatal(err)
49
+ }
50
+
51
+ // ID
52
+ var id peer.ID
53
+ switch keyType {
54
+ case ci.Ed25519:
55
+ id, err = peer.IDFromEd25519PublicKey(pubKey)
56
+ default:
57
+ id, err = peer.IDFromPublicKey(pubKey)
58
+ }
59
+
60
+ if err != nil {
61
+ t.Fatal(err)
62
+ }
63
+
64
+ // Value
65
+ value := path.Path("ipfs/TESTING")
66
+
67
+ // Seqnum
68
+ seqnum := uint64(0)
69
+
70
+ // Eol
71
+ eol := time.Now().Add(24 * time.Hour)
72
+
73
+ // Routing value store
74
+ p := testutil.PeerNetParams{
75
+ ID: id,
76
+ PrivKey: privKey,
77
+ PubKey: pubKey,
78
+ Addr: testutil.ZeroLocalTCPAddress,
79
+ }
80
+
81
+ dstore := dssync.MutexWrap(ds.NewMapDatastore())
82
+ serv := mockrouting.NewServer()
83
+ r := serv.ClientWithDatastore(context.Background(), &identity{p}, dstore)
84
+
85
+ err = PutRecordToRouting(ctx, privKey, value, seqnum, eol, r, id)
86
+ if err != nil {
87
+ t.Fatal(err)
88
+ }
89
+
90
+ // Check for namekey existence in value store
91
+ namekey, _ := IpnsKeysForID(id)
92
+ _, err = r.GetValue(ctx, namekey)
93
+ if err != expectedErr {
94
+ t.Fatal(err)
95
+ }
96
+
97
+ // Also check datastore for completeness
98
+ key := dshelp.NewKeyFromBinary([]byte(namekey))
99
+ exists, err := dstore.Has(key)
100
+ if err != nil {
101
+ t.Fatal(err)
102
+ }
103
+
104
+ if exists != expectedExistence {
105
+ t.Fatal("Unexpected key existence in datastore")
106
+ }
107
+}
108
+
109
+func TestRSAPublisher(t *testing.T) {
110
+ testNamekeyPublisher(t, ci.RSA, nil, true)
111
+}
112
+
113
+func TestEd22519Publisher(t *testing.T) {
114
+ testNamekeyPublisher(t, ci.Ed25519, ds.ErrNotFound, false)
115
+}