Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Author and Signature fields from Record #15

Merged
merged 4 commits into from
Feb 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions pb/record.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pb/record.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ message Record {
// The actual value this record is storing
optional bytes value = 2;

// Note: These fields were removed from the Record message
// hash of the authors public key
optional string author = 3;

//optional string author = 3;
// A PKI signature for the key+value+author
optional bytes signature = 4;
//optional bytes signature = 4;

// Time the record was received, set by receiver
optional string timeReceived = 5;
Expand Down
38 changes: 3 additions & 35 deletions record.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,14 @@
package record

import (
"bytes"

proto "github.com/gogo/protobuf/proto"
u "github.com/ipfs/go-ipfs-util"
ci "github.com/libp2p/go-libp2p-crypto"
pb "github.com/libp2p/go-libp2p-record/pb"
)

// MakePutRecord creates and signs a dht record for the given key/value pair
func MakePutRecord(sk ci.PrivKey, key string, value []byte, sign bool) (*pb.Record, error) {
// MakePutRecord creates a dht record for the given key/value pair
func MakePutRecord(key string, value []byte) *pb.Record {
record := new(pb.Record)

record.Key = proto.String(string(key))
record.Value = value

pkb, err := sk.GetPublic().Bytes()
if err != nil {
return nil, err
}

pkh := u.Hash(pkb)

record.Author = proto.String(string(pkh))
if sign {
blob := RecordBlobForSig(record)

sig, err := sk.Sign(blob)
if err != nil {
return nil, err
}

record.Signature = sig
}
return record, nil
}

// RecordBlobForSig returns the blob protected by the record signature
func RecordBlobForSig(r *pb.Record) []byte {
k := []byte(r.GetKey())
v := []byte(r.GetValue())
a := []byte(r.GetAuthor())
return bytes.Join([][]byte{k, v, a}, []byte{})
return record
}
61 changes: 5 additions & 56 deletions validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (

u "github.com/ipfs/go-ipfs-util"
logging "github.com/ipfs/go-log"
ci "github.com/libp2p/go-libp2p-crypto"
peer "github.com/libp2p/go-libp2p-peer"
pb "github.com/libp2p/go-libp2p-record/pb"
mh "github.com/multiformats/go-multihash"
)
Expand All @@ -28,9 +26,6 @@ type ValidationRecord struct {
Namespace string
Key string
Value []byte
// Note: author is only present if the source record is signed
// Otherwise it will be ""
Author peer.ID
}

// ValidatorFunc is a function that is called to validate a given
Expand All @@ -40,12 +35,7 @@ type ValidatorFunc func(*ValidationRecord) error
// Validator is an object that helps ensure routing records are valid.
// It is a collection of validator functions, each of which implements
// its own notion of validity.
type Validator map[string]*ValidChecker

type ValidChecker struct {
Func ValidatorFunc
Sign bool
}
type Validator map[string]ValidatorFunc

func splitPath(key string) (string, string, error) {
if len(key) == 0 || key[0] != '/' {
Expand All @@ -68,61 +58,33 @@ func parseRecord(r *pb.Record) (*ValidationRecord, error) {
return nil, err
}

// Note that the caller is responsible for verifying the
// signature
author := peer.ID("")
if len(r.GetSignature()) > 0 {
pid, err := peer.IDFromString(r.GetAuthor())
if err != nil {
log.Warningf("Could not parse author to peer ID: %s", r.GetAuthor())
return nil, ErrInvalidRecordType
}
author = pid
}
return &ValidationRecord{
Namespace: namespace,
Key: key,
Value: r.GetValue(),
Author: author,
}, nil
}

// VerifyRecord checks a record and ensures it is still valid.
// It runs needed validators.
// Note that VerifyRecord does not perform signature verification,
// the signature must be verified by the caller.
// Note that VerifyRecord does not perform signature verification.
func (v Validator) VerifyRecord(r *pb.Record) error {
vr, err := parseRecord(r)
if err != nil {
return err
}
val, ok := v[vr.Namespace]
f, ok := v[vr.Namespace]
if !ok {
log.Infof("Unrecognized key prefix: %s", vr.Namespace)
return ErrInvalidRecordType
}
return val.Func(vr)
}

func (v Validator) IsSigned(k string) (bool, error) {
namespace, _, err := splitPath(k)
if err != nil {
return false, err
}

val, ok := v[namespace]
if !ok {
log.Infof("Unrecognized key prefix: %s", namespace)
return false, ErrInvalidRecordType
}

return val.Sign, nil
return f(vr)
}

// ValidatePublicKeyRecord implements ValidatorFunc and
// verifies that the passed in record value is the PublicKey
// that matches the passed in key.
func ValidatePublicKeyRecord(r *ValidationRecord) error {
func PublicKeyValidator(r *ValidationRecord) error {
if r.Namespace != "pk" {
return errors.New("namespace not 'pk'")
}
Expand All @@ -138,16 +100,3 @@ func ValidatePublicKeyRecord(r *ValidationRecord) error {
}
return nil
}

var PublicKeyValidator = &ValidChecker{
Func: ValidatePublicKeyRecord,
Sign: false,
}

func CheckRecordSig(r *pb.Record, pk ci.PubKey) error {
blob := RecordBlobForSig(r)
if good, err := pk.Verify(blob, r.Signature); err != nil || !good {
return errors.New("invalid record signature")
}
return nil
}
Loading