Skip to content

Commit

Permalink
Do not publish public keys extractable from ID (with tests)
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Justin Drake <drakefjustin@gmail.com>
  • Loading branch information
JustinDrake committed Aug 17, 2017
1 parent 06c567d commit cf5618c
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 6 deletions.
18 changes: 12 additions & 6 deletions namesys/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,24 @@ func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqn
entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds()))
}

errs := make(chan error, 2)
errs := make(chan error, 2) // At most two errors (IPNS, and public key)

// Attempt to extract the public key from the ID
extractedPublicKey := id.ExtractPublicKey()

go func() {
errs <- PublishEntry(ctx, r, ipnskey, entry)
}()

go func() {
errs <- PublishPublicKey(ctx, r, namekey, k.GetPublic())
}()
// Publish the public key if a public key cannot be extracted from the ID
if extractedPublicKey == nil {
go func() {
errs <- PublishPublicKey(ctx, r, namekey, k.GetPublic())
}()

if err := waitOnErrChan(ctx, errs); err != nil {
return err
if err := waitOnErrChan(ctx, errs); err != nil {
return err
}
}

return waitOnErrChan(ctx, errs)
Expand Down
115 changes: 115 additions & 0 deletions namesys/publisher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package namesys

import (
"context"
"crypto/rand"
"testing"
"time"

path "github.com/ipfs/go-ipfs/path"
mockrouting "github.com/ipfs/go-ipfs/routing/mock"
dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help"
testutil "github.com/ipfs/go-ipfs/thirdparty/testutil"

ds "gx/ipfs/QmVSase1JP7cq9QkPT46oNwdp9pT6kBkG3oqS14y3QcZjG/go-datastore"
dssync "gx/ipfs/QmVSase1JP7cq9QkPT46oNwdp9pT6kBkG3oqS14y3QcZjG/go-datastore/sync"
ma "gx/ipfs/QmXY77cVe7rVRQXZZQRioukUM7aRW3BTcAgJe12MCtb3Ji/go-multiaddr"
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
)

type identity struct {
testutil.PeerNetParams
}

func (p *identity) ID() peer.ID {
return p.PeerNetParams.ID
}

func (p *identity) Address() ma.Multiaddr {
return p.Addr
}

func (p *identity) PrivateKey() ci.PrivKey {
return p.PrivKey
}

func (p *identity) PublicKey() ci.PubKey {
return p.PubKey
}

func testNamekeyPublisher(t *testing.T, keyType int, expectedErr error, expectedExistence bool) {
// Context
ctx := context.Background()

// Private key
privKey, pubKey, err := ci.GenerateKeyPairWithReader(keyType, 2048, rand.Reader)
if err != nil {
t.Fatal(err)
}

// ID
var id peer.ID
switch keyType {
case ci.Ed25519:
id, err = peer.IDFromEd25519PublicKey(pubKey)
default:
id, err = peer.IDFromPublicKey(pubKey)
}

if err != nil {
t.Fatal(err)
}

// Value
value := path.Path("ipfs/TESTING")

// Seqnum
seqnum := uint64(0)

// Eol
eol := time.Now().Add(24 * time.Hour)

// Routing value store
p := testutil.PeerNetParams{
ID: id,
PrivKey: privKey,
PubKey: pubKey,
Addr: testutil.ZeroLocalTCPAddress,
}

dstore := dssync.MutexWrap(ds.NewMapDatastore())
serv := mockrouting.NewServer()
r := serv.ClientWithDatastore(context.Background(), &identity{p}, dstore)

err = PutRecordToRouting(ctx, privKey, value, seqnum, eol, r, id)
if err != nil {
t.Fatal(err)
}

// Check for namekey existence in value store
namekey, _ := IpnsKeysForID(id)
_, err = r.GetValue(ctx, namekey)
if err != expectedErr {
t.Fatal(err)
}

// Also check datastore for completeness
key := dshelp.NewKeyFromBinary([]byte(namekey))
exists, err := dstore.Has(key)
if err != nil {
t.Fatal(err)
}

if exists != expectedExistence {
t.Fatal("Unexpected key existence in datastore")
}
}

func TestRSAPublisher(t *testing.T) {
testNamekeyPublisher(t, ci.RSA, nil, true)
}

func TestEd22519Publisher(t *testing.T) {
testNamekeyPublisher(t, ci.Ed25519, ds.ErrNotFound, false)
}

0 comments on commit cf5618c

Please sign in to comment.