Skip to content
Snippets Groups Projects
Commit f8a39121 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

finished fact stringification

parent 833aa242
No related branches found
No related tags found
No related merge requests found
package auth
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/crypto/cyclic"
)
const saltSize = 32
type format struct {
data []byte
pubkey []byte
salt []byte
ecrPayload []byte
}
func newFormat(payloadSize, pubkeySize uint, pubkey *cyclic.Int,
salt []byte) format {
if len(salt) != saltSize {
jww.FATAL.Panicf("Salt is wrong size, should be %v, is %v",
saltSize, len(salt))
}
if payloadSize < pubkeySize+saltSize {
jww.FATAL.Panicf("Size of format is too small, must be big " +
"enough to contain public key and salt")
}
f := buildFormat(make([]byte, payloadSize), pubkeySize)
copy(f.pubkey, pubkey.LeftpadBytes(uint64(pubkeySize)))
copy(f.salt, salt)
return f
}
func buildFormat(data []byte, pubkeySize uint) format {
f := format{
data: data,
}
f.pubkey = f.data[:pubkeySize]
f.salt = f.data[pubkeySize : pubkeySize+saltSize]
f.ecrPayload = f.data[pubkeySize+saltSize:]
return f
}
func unmarshalFormat(b []byte, pubkeySize uint) (format, error) {
if uint(len(b)) < pubkeySize+saltSize {
return format{}, errors.New("Received format too small")
}
return buildFormat(b, pubkeySize), nil
}
func (f format) Marshal() []byte {
return f.data
}
func (f format) GetPubKey(grp *cyclic.Group) *cyclic.Int {
return grp.NewIntFromBytes(f.pubkey)
}
func (f format) GetSalt() []byte {
return f.salt
}
func (f format) GetEcrPayload() []byte {
return f.ecrPayload
}
func (f format) GetEcrPayloadLen() int {
return len(f.ecrPayload)
}
func (f format) SetEcrPayload(ecr []byte) {
if len(ecr) != len(f.ecrPayload) {
jww.FATAL.Panicf("Passed ecr payload incorrect lengh. Expected:"+
" %v, Recieved: %v", len(f.ecrPayload), len(ecr))
}
copy(f.ecrPayload, ecr)
}
package auth
import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
)
const ownershipSize = 32
type ecrFormat struct {
data []byte
ownership []byte
payload []byte
}
func newEcrFormat(size uint, ownership []byte) ecrFormat {
if size < ownershipSize {
jww.FATAL.Panicf("Size too small to hold")
}
if len(ownership) != ownershipSize {
jww.FATAL.Panicf("ownership proof is the wrong size")
}
f := buildEcrFormat(make([]byte, size))
copy(f.ownership, ownership)
return f
}
func buildEcrFormat(data []byte) ecrFormat {
f := ecrFormat{
data: data,
}
f.ownership = f.data[:ownershipSize]
f.payload = f.data[ownershipSize:]
return f
}
func unmarshalEcrFormat(b []byte) (ecrFormat, error) {
if len(b) < ownershipSize {
return ecrFormat{}, errors.New("Received ecr format too small")
}
return buildEcrFormat(b), nil
}
func (f ecrFormat) Marshal() []byte {
return f.data
}
func (f ecrFormat) GetOwnership() []byte {
return f.ownership
}
func (f ecrFormat) GetPayload() []byte {
return f.payload
}
func (f ecrFormat) GetPayloadSize() int {
return len(f.payload)
}
func (f ecrFormat) SetPayload(p []byte) {
if len(p) != len(f.payload) {
jww.FATAL.Panicf("Payload is the wrong length")
}
copy(f.payload, p)
}
package auth
type requestFormat struct {
ecrFormat
id []byte
facts []byte
message []byte
}
...@@ -6,8 +6,14 @@ import ( ...@@ -6,8 +6,14 @@ import (
"gitlab.com/elixxir/client/interfaces" "gitlab.com/elixxir/client/interfaces"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"strings"
jww "github.com/spf13/jwalterweatherman"
) )
const factDelimiter = ","
const factBreak = ";"
// Contact implements the Contact interface defined in interface/contact.go, // Contact implements the Contact interface defined in interface/contact.go,
// in go, the structure is meant to be edited directly, the functions are for // in go, the structure is meant to be edited directly, the functions are for
// bindings compatibility // bindings compatibility
...@@ -38,10 +44,22 @@ func (c Contact) GetFactList() interfaces.FactList { ...@@ -38,10 +44,22 @@ func (c Contact) GetFactList() interfaces.FactList {
return FactList{source: &c} return FactList{source: &c}
} }
// json marshals the contact
func (c Contact) Marshal() ([]byte, error) { func (c Contact) Marshal() ([]byte, error) {
return json.Marshal(&c) return json.Marshal(&c)
} }
// converts facts to a delineated string with an ending character for transfer
// over the network
func (c Contact) StringifyFacts() string {
stringList := make([]string, len(c.Facts))
for index, f := range c.Facts {
stringList[index] = f.Stringify()
}
return strings.Join(stringList, factDelimiter) + factBreak
}
func Unmarshal(b []byte) (Contact, error) { func Unmarshal(b []byte) (Contact, error) {
c := Contact{} c := Contact{}
err := json.Unmarshal(b, &c) err := json.Unmarshal(b, &c)
...@@ -56,3 +74,26 @@ func Unmarshal(b []byte) (Contact, error) { ...@@ -56,3 +74,26 @@ func Unmarshal(b []byte) (Contact, error) {
} }
return c, nil return c, nil
} }
// splits the "facts" portion of the payload from the rest and returns them as
// facts
func UnstringifyFacts(s string) ([]Fact, string, error) {
parts := strings.SplitN(s, factBreak, 1)
if len(parts) != 2 {
return nil, "", errors.New("Invalid fact string passed")
}
factStrings := strings.Split(parts[0], factDelimiter)
var factList []Fact
for _, fString := range factStrings {
fact, err := UnstringifyFact(fString)
if err != nil {
jww.WARN.Printf("Fact failed to unstringify, dropped: %s",
err)
} else {
factList = append(factList, fact)
}
}
return factList, parts[1], nil
}
package contact package contact
import (
"github.com/pkg/errors"
)
type Fact struct { type Fact struct {
Fact string Fact string
T FactType T FactType
} }
func NewFact(ft FactType, fact string) (Fact, error) {
//todo: filter the fact string
return Fact{
Fact: fact,
T: ft,
}, nil
}
func (f Fact) Get() string { func (f Fact) Get() string {
return f.Fact return f.Fact
} }
...@@ -18,25 +22,15 @@ func (f Fact) Type() int { ...@@ -18,25 +22,15 @@ func (f Fact) Type() int {
} }
// marshal is for transmission for UDB, not a part of the fact interface // marshal is for transmission for UDB, not a part of the fact interface
func (f Fact) Marshal() []byte { func (f Fact) Stringify() string {
serial := []byte(f.Fact) return f.T.Stringify() + f.Fact
b := make([]byte, len(serial)+1)
b[0] = byte(f.T)
copy(b[1:len(serial)-1], serial)
return b
} }
func UnmarshalFact(b []byte) (Fact, error) { func UnstringifyFact(s string) (Fact, error) {
t := FactType(b[0]) ft, err := UnstringifyFactType(s)
if !t.IsValid() { if err != nil {
return Fact{}, errors.Errorf("Fact is not a valid type: %s", t) return Fact{}, err
} }
f := string(b[1:]) return NewFact(ft, s)
return Fact{
Fact: f,
T: t,
}, nil
} }
...@@ -22,9 +22,11 @@ func (fl FactList) Add(fact string, factType int) error { ...@@ -22,9 +22,11 @@ func (fl FactList) Add(fact string, factType int) error {
if !ft.IsValid() { if !ft.IsValid() {
return errors.New("Invalid fact type") return errors.New("Invalid fact type")
} }
fl.source.Facts = append(fl.source.Facts, Fact{ f, err := NewFact(ft, fact)
Fact: fact, if err != nil {
T: ft, return err
}) }
fl.source.Facts = append(fl.source.Facts, f)
return nil return nil
} }
package contact package contact
import "fmt" import (
"fmt"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
)
type FactType uint8 type FactType uint8
...@@ -23,6 +27,31 @@ func (t FactType) String() string { ...@@ -23,6 +27,31 @@ func (t FactType) String() string {
} }
} }
func (t FactType) Stringify() string {
switch t {
case Username:
return "U"
case Email:
return "E"
case Phone:
return "P"
}
jww.FATAL.Panicf("Unknown Fact FactType: %d", t)
return "error"
}
func UnstringifyFactType(s string) (FactType, error) {
switch s {
case "U":
return Username, nil
case "E":
return Email, nil
case "P":
return Phone, nil
}
return 3, errors.Errorf("Unknown Fact FactType: %s", s)
}
func (t FactType) IsValid() bool { func (t FactType) IsValid() bool {
return t == Username || t == Email || t == Phone return t == Username || t == Email || t == Phone
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment