Skip to content

Commit

Permalink
fix: added fixed identities in tests, missing public key field of ide…
Browse files Browse the repository at this point in the history
…ntities
  • Loading branch information
glouvigny authored and aeddi committed Jun 12, 2019
1 parent bcda92c commit acac910
Show file tree
Hide file tree
Showing 20 changed files with 703 additions and 248 deletions.
140 changes: 102 additions & 38 deletions entry/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package entry
import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"math"
"sort"
Expand All @@ -14,7 +15,6 @@ import (
"github.com/ipfs/go-cid"
cbornode "github.com/ipfs/go-ipld-cbor"
ic "github.com/libp2p/go-libp2p-crypto"
mh "github.com/multiformats/go-multihash"
"github.com/pkg/errors"
_ "github.com/polydawn/refmt"
"github.com/polydawn/refmt/obj/atlas"
Expand All @@ -25,8 +25,8 @@ type Entry struct {
LogID string
Next []cid.Cid
V uint64
Key *ic.Secp256k1PublicKey
Sig mh.Multihash
Key []byte
Sig []byte
Identity *identityprovider.Identity
Hash cid.Cid
Clock *lamportclock.LamportClock
Expand All @@ -39,6 +39,7 @@ type EntryToHash struct {
Next []cid.Cid
V uint64
Clock *lamportclock.LamportClock
Key []byte
}

var AtlasEntryToHash = atlas.BuildEntry(EntryToHash{}).
Expand All @@ -51,17 +52,78 @@ var AtlasEntryToHash = atlas.BuildEntry(EntryToHash{}).
AddField("Clock", atlas.StructMapEntry{SerialName: "clock"}).
Complete()


type CborEntry struct {
V uint64
LogID string
Key string
Sig string
Hash interface{}
Next []cid.Cid
Clock *lamportclock.CborLamportClock
Payload string
Identity *identityprovider.CborIdentity
}

func (c *CborEntry) ToEntry(provider identityprovider.Interface) (*Entry, error) {
key, err := hex.DecodeString(c.Key)
if err != nil {
return nil, err
}

sig, err := hex.DecodeString(c.Sig)
if err != nil {
return nil, err
}

clock, err := c.Clock.ToLamportClock()
if err != nil {
return nil, err
}

identity, err := c.Identity.ToIdentity(provider)
if err != nil {
return nil, err
}

return &Entry{
V: c.V,
LogID: c.LogID,
Key: key,
Sig: sig,
Next: c.Next,
Clock: clock,
Payload: []byte(c.Payload),
Identity: identity,
}, nil
}

func (e *Entry) ToCborEntry() *CborEntry {
return &CborEntry{
V: e.V,
LogID: e.LogID,
Key: hex.EncodeToString(e.Key),
Sig: hex.EncodeToString(e.Sig),
Hash: nil,
Next: e.Next,
Clock: e.Clock.ToCborLamportClock(),
Payload: string(e.Payload),
Identity: e.Identity.ToCborIdentity(),
}
}

func init() {
AtlasEntry := atlas.BuildEntry(Entry{}).
AtlasEntry := atlas.BuildEntry(CborEntry{}).
StructMap().
AddField("Clock", atlas.StructMapEntry{SerialName: "clock"}).
AddField("Identity", atlas.StructMapEntry{SerialName: "identity"}).
AddField("Key", atlas.StructMapEntry{SerialName: "key"}).
AddField("V", atlas.StructMapEntry{SerialName: "v"}).
AddField("LogID", atlas.StructMapEntry{SerialName: "id"}).
AddField("Key", atlas.StructMapEntry{SerialName: "key", }).
AddField("Sig", atlas.StructMapEntry{SerialName: "sig"}).
AddField("Hash", atlas.StructMapEntry{SerialName: "hash"}).
AddField("Next", atlas.StructMapEntry{SerialName: "next"}).
AddField("V", atlas.StructMapEntry{SerialName: "v"}).
AddField("Clock", atlas.StructMapEntry{SerialName: "clock"}).
AddField("Payload", atlas.StructMapEntry{SerialName: "payload"}).
AddField("Sig", atlas.StructMapEntry{SerialName: "sig"}).
AddField("Identity", atlas.StructMapEntry{SerialName: "identity"}).
Complete()

cbornode.RegisterCborType(AtlasEntry)
Expand Down Expand Up @@ -97,7 +159,8 @@ func CreateEntry(ipfsInstance *io.IpfsServices, identity *identityprovider.Ident
return nil, err
}

signature, err := identity.PrivateKey.Sign(jsonBytes)
signature, err := identity.Provider.Sign(identity, jsonBytes)

if err != nil {
return nil, err
}
Expand All @@ -111,7 +174,7 @@ func CreateEntry(ipfsInstance *io.IpfsServices, identity *identityprovider.Ident
return nil, err
}

nd, err := cbornode.WrapObject(data, math.MaxUint64, -1)
nd, err := cbornode.WrapObject(data.ToCborEntry(), math.MaxUint64, -1)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -160,19 +223,14 @@ func ToBuffer(e *EntryToHash) ([]byte, error) {
return nil, errors.New("entry is not defined")
}

clockBytes, err := e.Clock.ID.Bytes()
if err != nil {
return nil, err
}

jsonBytes, err := json.Marshal(map[string]interface{}{
"hash": nil,
"id": e.ID,
"payload": e.Payload,
"payload": string(e.Payload),
"next": e.Next,
"v": e.V,
"clock": map[string]interface{}{
"id": clockBytes,
"id": hex.EncodeToString(e.Clock.ID),
"time": e.Clock.Time,
},
})
Expand All @@ -191,6 +249,7 @@ func (e *Entry) ToHashable() *EntryToHash {
Next: e.Next,
V: e.V,
Clock: e.Clock,
Key: e.Key,
}
}

Expand All @@ -206,10 +265,18 @@ func Verify(identity identityprovider.Interface, entry *Entry) error {
// TODO: Check against trusted keys

jsonBytes, err := ToBuffer(entry.ToHashable())
if err != nil {
return errors.Wrap(err, "unable to build string buffer")
}

ok, err := entry.Key.Verify(jsonBytes, entry.Sig)
pubKey, err := ic.UnmarshalSecp256k1PublicKey(entry.Key)
if err != nil {
return err
return errors.Wrap(err, "unable to unmarshal public key")
}

ok, err := pubKey.Verify(jsonBytes, entry.Sig)
if err != nil {
return errors.Wrap(err, "error whild verifying signature")
}

if !ok {
Expand Down Expand Up @@ -249,30 +316,35 @@ func ToMultihash(ipfsInstance *io.IpfsServices, entry *Entry) (cid.Cid, error) {
e.Sig = entry.Sig
}

entryCID, err := io.WriteCBOR(ipfsInstance, e)
entryCID, err := io.WriteCBOR(ipfsInstance, e.ToCborEntry())

return entryCID, err
}

func FromMultihash(ipfs *io.IpfsServices, hash cid.Cid) (*Entry, error) {
if ipfs == nil {
return nil, errors.New("ipfs instance not defined")
}
func FromMultihash(ipfs *io.IpfsServices, hash cid.Cid, provider identityprovider.Interface) (*Entry, error) {
if ipfs == nil {
return nil, errors.New("ipfs instance not defined")
}

result, err := io.ReadCBOR(ipfs, hash)
if err != nil {
return nil, err
}

obj := &Entry{}
obj := &CborEntry{}
err = cbornode.DecodeInto(result.RawData(), obj)
if err != nil {
return nil, err
}

obj.Hash = hash

return obj, nil
entry, err := obj.ToEntry(provider)
if err != nil {
return nil, err
}

return entry, nil
}

func SortEntries(entries []*Entry) {
Expand All @@ -297,19 +369,11 @@ func Compare(a, b *Entry) (int, error) {
}

if distance == 0 {
aClockBytes, err := a.Clock.ID.Bytes()
if err != nil {
return 0, err
}

bClockBytes, err := b.Clock.ID.Bytes()
if err != nil {
return 0, err
}
diff := bytes.Compare(a.Clock.ID, b.Clock.ID)

if bytes.Compare(aClockBytes, bClockBytes) < 0 {
if diff < 0 {
return -1, nil
} else {
} else if diff > 0 {
return 1, nil
}
}
Expand Down
8 changes: 7 additions & 1 deletion entry/entry_io.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package entry

import (
"context"
"fmt"
"github.com/berty/go-ipfs-log/identityprovider"
"github.com/berty/go-ipfs-log/io"
"github.com/ipfs/go-cid"
"time"
Expand All @@ -13,6 +15,7 @@ type FetchOptions struct {
Concurrency int
Timeout time.Duration
ProgressChan chan *Entry
Provider identityprovider.Interface
}

func FetchAll (ipfs *io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []*Entry {
Expand Down Expand Up @@ -61,11 +64,14 @@ func FetchAll (ipfs *io.IpfsServices, hashes []cid.Cid, options *FetchOptions) [
ctx, _ = context.WithTimeout(ctx, options.Timeout)
}

entry, err := FromMultihash(ipfs, hash)
entry, err := FromMultihash(ipfs, hash, options.Provider)
if err != nil {
fmt.Printf("unable to fetch entry %s, %+v\n", hash, err)
return
}

entry.Hash = hash

if entry.IsValid() {
addToResults(entry)
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/berty/go-ipfs-log
go 1.12

require (
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect
github.com/hashicorp/golang-lru v0.5.1
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0
Expand Down
Loading

0 comments on commit acac910

Please sign in to comment.