diff --git a/bindings/autheticatedConnection.go b/bindings/autheticatedConnection.go index cca735d0af05a84bd99240f4cfc495e19b255dce..d62357dfef5b9703298751500c935034715ab760 100644 --- a/bindings/autheticatedConnection.go +++ b/bindings/autheticatedConnection.go @@ -28,7 +28,7 @@ func (c *Client) ConnectWithAuthentication(recipientContact []byte, myIdentity [ if err != nil { return nil, err } - myID, rsaPriv, salt, myDHPriv, err := unmarshalIdentity(myIdentity) + myID, rsaPriv, salt, myDHPriv, err := c.unmarshalIdentity(myIdentity) if err != nil { return nil, err } diff --git a/bindings/connect.go b/bindings/connect.go index f1248ac66f7efb0f461eb109226241425a4cbb76..530aa13e5f1e90c655adf30eb3f24d274a092ffe 100644 --- a/bindings/connect.go +++ b/bindings/connect.go @@ -35,7 +35,7 @@ func (c *Client) Connect(recipientContact []byte, myIdentity []byte) ( if err != nil { return nil, err } - myID, _, _, myDHPriv, err := unmarshalIdentity(myIdentity) + myID, _, _, myDHPriv, err := c.unmarshalIdentity(myIdentity) if err != nil { return nil, err } diff --git a/bindings/contact.go b/bindings/contact.go index 14544785602449b934693ea38656eebde8476136..c0c9dfe9e66fcf6e5c7d996541e58647c922dbf4 100644 --- a/bindings/contact.go +++ b/bindings/contact.go @@ -2,8 +2,10 @@ package bindings import ( "encoding/json" + "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/diffieHellman" + "gitlab.com/elixxir/primitives/fact" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/xx" "gitlab.com/xx_network/primitives/id" @@ -16,11 +18,6 @@ type Identity struct { DHKeyPrivate []byte } -type Fact struct { - Fact string - Type string -} - // MakeIdentity generates a new cryptographic identity for receving // messages func (c *Client) MakeIdentity() ([]byte, error) { @@ -46,7 +43,11 @@ func (c *Client) MakeIdentity() ([]byte, error) { //make the ID id, err := xx.NewID(rsaKey.GetPublic(), salt, id.User) + if err != nil { + return nil, err + } + dhPrivJson, err := privkey.MarshalJSON() if err != nil { return nil, err } @@ -56,35 +57,125 @@ func (c *Client) MakeIdentity() ([]byte, error) { ID: id.Marshal(), RSAPrivatePem: rsa.CreatePrivateKeyPem(rsaKey), Salt: salt, - DHKeyPrivate: privkey.Bytes(), + DHKeyPrivate: dhPrivJson, } return json.Marshal(&I) } -func GetContactFromIdentity(identity string) []byte { - I := Identity{} +func (c *Client) GetContactFromIdentity(identity []byte) ([]byte, error) { + uID, _, _, dhKey, err := c.unmarshalIdentity(identity) + if err != nil { + return nil, err + } + + grp := c.api.GetStorage().GetE2EGroup() + + dhPub := grp.ExpG(dhKey, grp.NewInt(1)) + + ct := contact.Contact{ + ID: uID, + DhPubKey: dhPub, + OwnershipProof: nil, + Facts: nil, + } + + return ct.Marshal(), nil } -func unmarshalIdentity(marshaled []byte) (*id.ID, *rsa.PrivateKey, []byte, +func (c *Client) unmarshalIdentity(marshaled []byte) (*id.ID, *rsa.PrivateKey, []byte, *cyclic.Int, error) { - return nil, nil, nil, nil, nil + I := Identity{} + err := json.Unmarshal(marshaled, &I) + if err != nil { + return nil, nil, nil, nil, err + } + + uID, err := id.Unmarshal(I.ID) + if err != nil { + return nil, nil, nil, nil, err + } + + dhkey := c.api.GetStorage().GetE2EGroup().NewInt(1) + err = dhkey.UnmarshalJSON(I.DHKeyPrivate) + if err != nil { + return nil, nil, nil, nil, err + } + + rsaPriv, err := rsa.LoadPrivateKeyFromPem(I.RSAPrivatePem) + if err != nil { + return nil, nil, nil, nil, err + } + + return uID, rsaPriv, I.Salt, dhkey, nil } -// SetFactsOnContact replaces the facts on the contact with the passed in facts -// pass in empty facts in order to clear the facts -func SetFactsOnContact(contact []byte, facts []byte) []byte { - I := Identity{} +func GetIDFromContact(marshaled []byte) ([]byte, error) { + cnt, err := contact.Unmarshal(marshaled) + if err != nil { + return nil, err + } + + return cnt.ID.Marshal(), nil } -func GetIDFromContact(contact []byte) []byte { +func GetPubkeyFromContact(marshaled []byte) ([]byte, error) { + cnt, err := contact.Unmarshal(marshaled) + if err != nil { + return nil, err + } + return cnt.ID.Marshal(), nil } -func GetPubkeyFromContact(contact []byte) []byte { +type Fact struct { + Fact string + Type int +} +// SetFactsOnContact replaces the facts on the contact with the passed in facts +// pass in empty facts in order to clear the facts +func SetFactsOnContact(marshaled []byte, facts []byte) ([]byte, error) { + cnt, err := contact.Unmarshal(marshaled) + if err != nil { + return nil, err + } + + factsList := make([]Fact, 0) + err = json.Unmarshal(facts, &factsList) + if err != nil { + return nil, err + } + + realFactList := make(fact.FactList, 0, len(factsList)) + for i := range factsList { + realFactList = append(realFactList, fact.Fact{ + Fact: factsList[i].Fact, + T: fact.FactType(factsList[i].Type), + }) + } + + cnt.Facts = realFactList + return cnt.Marshal(), nil } -func GetFactsFromContact(contact []byte) []byte { +func GetFactsFromContact(marshaled []byte) ([]byte, error) { + cnt, err := contact.Unmarshal(marshaled) + if err != nil { + return nil, err + } + + factsList := make([]Fact, len(cnt.Facts)) + for i := range cnt.Facts { + factsList = append(factsList, Fact{ + Fact: cnt.Facts[i].Fact, + Type: int(cnt.Facts[i].T), + }) + } + factsListMarshaled, err := json.Marshal(&factsList) + if err != nil { + return nil, err + } + return factsListMarshaled, nil } diff --git a/bindings/delivery.go b/bindings/delivery.go index 1c5b2d01a8c43741cccab422398248c5192d5075..36a1f72652f0a2ef58576d4e7ff7821b2f463f9f 100644 --- a/bindings/delivery.go +++ b/bindings/delivery.go @@ -1,27 +1,50 @@ package bindings import ( + "encoding/json" "fmt" + "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/cmix" "gitlab.com/xx_network/primitives/id" "time" ) -type roundsList struct { - rounds []int +type roundsList []int + +func (rl roundsList) Marshal() ([]byte, error) { + return json.Marshal(&rl) } -func (rl roundsList) Marshal() []byte { +func unmarshalRoundsList(marshaled []byte) ([]id.Round, error) { + rl := roundsList{} + err := json.Unmarshal(marshaled, &rl) + if err != nil { + return nil, err + } -} + realRl := make([]id.Round, len(rl)) -func unmarshalRoundsList(marshaled []byte) []id.Round { + for _, rid := range rl { + realRl = append(realRl, id.Round(rid)) + } + + return realRl, nil } func makeRoundsList(rounds []id.Round) roundsList { + rl := make(roundsList, 0, len(rounds)) + for _, rid := range rounds { + rl = append(rl, int(rid)) + } + return rl +} +// MessageDeliveryCallback gets called on the determination if all events +// related to a message send were successful. +type MessageDeliveryCallback interface { + EventCallback(delivered, timedOut bool, roundResults []byte) } // WaitForMessageDelivery allows the caller to get notified if the rounds a @@ -34,39 +57,39 @@ func makeRoundsList(rounds []id.Round) roundsList { // This function takes the marshaled send report to ensure a memory leak does // not occur as a result of both sides of the bindings holding a reference to // the same pointer. -func (c *Client) WaitForMessageDelivery(marshaledSendReport []byte, +func (c *Client) WaitForMessageDelivery(roundList []byte, mdc MessageDeliveryCallback, timeoutMS int) error { jww.INFO.Printf("WaitForMessageDelivery(%v, _, %v)", - marshaledSendReport, timeoutMS) - sr, err := UnmarshalSendReport(marshaledSendReport) + roundList, timeoutMS) + rl, err := unmarshalRoundsList(roundList) if err != nil { return errors.New(fmt.Sprintf("Failed to "+ "WaitForMessageDelivery callback due to bad Send Report: %+v", err)) } - if sr == nil || sr.rl == nil || len(sr.rl.list) == 0 { + if rl == nil || len(rl) == 0 { return errors.New(fmt.Sprintf("Failed to "+ "WaitForMessageDelivery callback due to invalid Send Report "+ - "unmarshal: %s", string(marshaledSendReport))) + "unmarshal: %s", string(roundList))) } - f := func(allRoundsSucceeded, timedOut bool, rounds map[id.Round]cmix.RoundLookupStatus) { - results := make([]byte, len(sr.rl.list)) + f := func(allRoundsSucceeded, timedOut bool, rounds map[id.Round]cmix.RoundResult) { + results := make([]byte, len(rl)) jww.INFO.Printf("Processing WaitForMessageDelivery report "+ - "for %v, success: %v, timedout: %v", sr.mid, allRoundsSucceeded, + "success: %v, timedout: %v", allRoundsSucceeded, timedOut) - for i, r := range sr.rl.list { + for i, r := range rl { if result, exists := rounds[r]; exists { - results[i] = byte(result) + results[i] = byte(result.Status) } } - mdc.EventCallback(sr.mid.Marshal(), allRoundsSucceeded, timedOut, results) + mdc.EventCallback(allRoundsSucceeded, timedOut, results) } timeout := time.Duration(timeoutMS) * time.Millisecond - err = c.api.GetRoundResults(sr.rl.list, timeout, f) + err = c.api.GetCmix().GetRoundResults(timeout, f, rl...) return err }