diff --git a/bindings/contact.go b/bindings/contact.go index 251c810f40c6e31a6212b8e2eaee770c86724d00..82631bf6e64b1ecb87d55f17b833b76ea682f103 100644 --- a/bindings/contact.go +++ b/bindings/contact.go @@ -5,7 +5,6 @@ import ( "gitlab.com/elixxir/client/xxdk" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/primitives/fact" - "gitlab.com/xx_network/crypto/signature/rsa" ) // ReceptionIdentity struct @@ -27,23 +26,12 @@ type ReceptionIdentity struct { // MakeIdentity generates a new cryptographic identity for receiving messages func (c *Cmix) MakeIdentity() ([]byte, error) { - s := c.api.GetRng().GetStream() - defer s.Close() - ident, err := xxdk.MakeReceptionIdentity(s, c.api.GetStorage().GetE2EGroup()) - - dhPrivJson, err := ident.DHKeyPrivate.MarshalJSON() + ident, err := xxdk.MakeReceptionIdentity(c.api) if err != nil { return nil, err } - //create the identity object - I := ReceptionIdentity{ - ID: ident.ID.Marshal(), - RSAPrivatePem: rsa.CreatePrivateKeyPem(ident.RSAPrivatePem), - Salt: ident.Salt, - DHKeyPrivate: dhPrivJson, - } - return json.Marshal(&I) + return ident.Marshal() } // GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object diff --git a/bindings/e2e.go b/bindings/e2e.go index dffc2560f4842e610a9eefe5f75f37d572776041..8820d59f9fed3ae4c3f120dec040b7c857ddfa94 100644 --- a/bindings/e2e.go +++ b/bindings/e2e.go @@ -7,15 +7,11 @@ package bindings import ( - "encoding/json" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/xxdk" "gitlab.com/elixxir/crypto/contact" - "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/xx_network/crypto/signature/rsa" - "gitlab.com/xx_network/primitives/id" ) // e2eTrackerSingleton is used to track E2e objects so that @@ -46,7 +42,7 @@ func LoginE2e(cmixId int, callbacks AuthCallbacks, identity []byte) (*E2e, error return nil, err } - newIdentity, err := unmarshalIdentity(identity, cmix.api.GetStorage().GetE2EGroup()) + newIdentity, err := xxdk.UnmarshalReceptionIdentity(identity) if err != nil { return nil, err } @@ -75,7 +71,7 @@ func LoginE2eEphemeral(cmixId int, callbacks AuthCallbacks, identity []byte) (*E return nil, err } - newIdentity, err := unmarshalIdentity(identity, cmix.api.GetStorage().GetE2EGroup()) + newIdentity, err := xxdk.UnmarshalReceptionIdentity(identity) if err != nil { return nil, err } @@ -121,38 +117,7 @@ func LoginE2eLegacy(cmixId int, callbacks AuthCallbacks) (*E2e, error) { // GetContact returns a marshalled contact.Contact object for the E2e ReceptionIdentity func (e *E2e) GetContact() []byte { - return e.api.GetReceptionIdentity().GetContact(e.api.GetStorage().GetE2EGroup()).Marshal() -} - -// unmarshalIdentity is a helper function for taking in a marshalled xxdk.ReceptionIdentity and making it an object -func unmarshalIdentity(marshaled []byte, e2eGrp *cyclic.Group) (xxdk.ReceptionIdentity, error) { - newIdentity := xxdk.ReceptionIdentity{} - - // Unmarshal given identity into ReceptionIdentity object - givenIdentity := ReceptionIdentity{} - err := json.Unmarshal(marshaled, &givenIdentity) - if err != nil { - return xxdk.ReceptionIdentity{}, err - } - - newIdentity.ID, err = id.Unmarshal(givenIdentity.ID) - if err != nil { - return xxdk.ReceptionIdentity{}, err - } - - newIdentity.DHKeyPrivate = e2eGrp.NewInt(1) - err = newIdentity.DHKeyPrivate.UnmarshalJSON(givenIdentity.DHKeyPrivate) - if err != nil { - return xxdk.ReceptionIdentity{}, err - } - - newIdentity.RSAPrivatePem, err = rsa.LoadPrivateKeyFromPem(givenIdentity.RSAPrivatePem) - if err != nil { - return xxdk.ReceptionIdentity{}, err - } - - newIdentity.Salt = givenIdentity.Salt - return newIdentity, nil + return e.api.GetReceptionIdentity().GetContact().Marshal() } // AuthCallbacks is the bindings-specific interface for auth.Callbacks methods. diff --git a/cmd/broadcast.go b/cmd/broadcast.go index 8b9ae2358d5e4b6b51d2dd15bc6b6e22e74e5c05..c4c1209e95bb462b808adc79947bf8237988f99c 100644 --- a/cmd/broadcast.go +++ b/cmd/broadcast.go @@ -26,9 +26,8 @@ var broadcastCmd = &cobra.Command{ client := initClient() // Write user contact to file - user := client.GetUser() - jww.INFO.Printf("User: %s", user.ReceptionID) - jww.INFO.Printf("User Transmission: %s", user.TransmissionID) + user := client.GetReceptionIdentity() + jww.INFO.Printf("User: %s", user.ID) writeContact(user.GetContact()) err := client.StartNetworkFollower(5 * time.Second) @@ -39,8 +38,8 @@ var broadcastCmd = &cobra.Command{ // Wait until connected or crash on timeout connected := make(chan bool, 10) client.GetCmix().AddHealthCallback( - func(isconnected bool) { - connected <- isconnected + func(isConnected bool) { + connected <- isConnected }) waitUntilConnected(connected) @@ -69,10 +68,10 @@ var broadcastCmd = &cobra.Command{ jww.FATAL.Panicf("description cannot be empty") } - var channel *crypto.Channel + var cryptChannel *crypto.Channel if viper.GetBool("new") { // Create a new broadcast channel - channel, pk, err = crypto.NewChannel(name, desc, client.GetRng().GetStream()) + cryptChannel, pk, err = crypto.NewChannel(name, desc, client.GetRng().GetStream()) if err != nil { jww.FATAL.Panicf("Failed to create new channel: %+v", err) } @@ -99,7 +98,7 @@ var broadcastCmd = &cobra.Command{ jww.FATAL.Panicf("Failed to generate channel ID: %+v", err) } - channel = &crypto.Channel{ + cryptChannel = &crypto.Channel{ ReceptionID: rid, Name: name, Description: desc, @@ -126,7 +125,7 @@ var broadcastCmd = &cobra.Command{ } // Save channel to disk - cBytes, err := channel.Marshal() + cBytes, err := cryptChannel.Marshal() if err != nil { jww.ERROR.Printf("Failed to marshal channel to bytes: %+v", err) } diff --git a/cmd/init.go b/cmd/init.go index 6c42b9cfc6a887d5f1dd3aacec85eb36ab47fb9e..f5c7483d088ae7bb42c2ee9ceac7ad471bc841d8 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -9,14 +9,15 @@ package cmd import ( - "fmt" + jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/xxdk" "github.com/spf13/cobra" - jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" ) +const identityStorageKey = "identityStorageKey" + // initCmd creates a new user object with the given NDF var initCmd = &cobra.Command{ Use: "init", @@ -24,16 +25,19 @@ var initCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { client := createClient() - e2e, err := xxdk.LoadOrInitE2e(client) + + identity, err := xxdk.MakeReceptionIdentity(client) + if err != nil { + return + } + + err = xxdk.StoreReceptionIdentity(identityStorageKey, identity, client) if err != nil { - jww.FATAL.Panicf("%+v", err) + return } - user := client.GetUser() - user.E2eDhPublicKey = e2e.GetHistoricalDHPubkey() - jww.INFO.Printf("User: %s", user.ReceptionID) - writeContact(user.GetContact()) - fmt.Printf("%s\n", user.ReceptionID) + jww.INFO.Printf("User: %s", identity.ID) + writeContact(identity.GetContact()) }, } diff --git a/groupChat/groupStore/store_test.go b/groupChat/groupStore/store_test.go index a41439b730f46285f39f9a960e6fe6bd94bbce77..e5549f06b1afadeceb44dd3a8bb3d2ac3c0ce7d1 100644 --- a/groupChat/groupStore/store_test.go +++ b/groupChat/groupStore/store_test.go @@ -558,7 +558,7 @@ func TestStore_GetUser(t *testing.T) { } if !user.Equal(store.GetUser()) { - t.Errorf("GetUser() failed to return the expected member."+ + t.Errorf("GetTransmissionIdentity() failed to return the expected member."+ "\nexpected: %#v\nreceived: %#v", user, store.GetUser()) } } diff --git a/groupChat/manager_test.go b/groupChat/manager_test.go index 374062ea83700854b222aaea55d70483304c8d30..de32491e49f2b7555783abc49d26d131c81a877e 100644 --- a/groupChat/manager_test.go +++ b/groupChat/manager_test.go @@ -170,26 +170,26 @@ func TestNewManager_LoadError(t *testing.T) { // m2, _ := newTestManagerWithStore(prng, 10, 0, requestFunc2, receiveFunc2, t) // m3, _ := newTestManagerWithStore(prng, 10, 0, requestFunc3, receiveFunc3, t) // -// membership, err := group.NewMembership(m1.store.GetUser().Contact(), -// m2.store.GetUser().Contact(), m3.store.GetUser().Contact()) +// membership, err := group.NewMembership(m1.store.GetTransmissionIdentity().Contact(), +// m2.store.GetTransmissionIdentity().Contact(), m3.store.GetTransmissionIdentity().Contact()) // if err != nil { // t.Errorf("Failed to generate new membership: %+v", err) // } // -// dhKeys := gs.GenerateDhKeyList(m1.gs.GetUser().ID, -// m1.store.GetUser().E2eDhPrivateKey, membership, m1.store.E2e().GetGroup()) +// dhKeys := gs.GenerateDhKeyList(m1.gs.GetTransmissionIdentity().ID, +// m1.store.GetTransmissionIdentity().E2eDhPrivateKey, membership, m1.store.E2e().GetGroup()) // -// grp1 := newTestGroup(m1.store.E2e().GetGroup(), m1.store.GetUser().E2eDhPrivateKey, prng, t) +// grp1 := newTestGroup(m1.store.E2e().GetGroup(), m1.store.GetTransmissionIdentity().E2eDhPrivateKey, prng, t) // grp1.Members = membership // grp1.DhKeys = dhKeys // grp1.ID = group.NewID(grp1.IdPreimage, grp1.Members) // grp1.Key = group.NewKey(grp1.KeyPreimage, grp1.Members) // grp2 := grp1.DeepCopy() -// grp2.DhKeys = gs.GenerateDhKeyList(m2.gs.GetUser().ID, -// m2.store.GetUser().E2eDhPrivateKey, membership, m2.store.E2e().GetGroup()) +// grp2.DhKeys = gs.GenerateDhKeyList(m2.gs.GetTransmissionIdentity().ID, +// m2.store.GetTransmissionIdentity().E2eDhPrivateKey, membership, m2.store.E2e().GetGroup()) // grp3 := grp1.DeepCopy() -// grp3.DhKeys = gs.GenerateDhKeyList(m3.gs.GetUser().ID, -// m3.store.GetUser().E2eDhPrivateKey, membership, m3.store.E2e().GetGroup()) +// grp3.DhKeys = gs.GenerateDhKeyList(m3.gs.GetTransmissionIdentity().ID, +// m3.store.GetTransmissionIdentity().E2eDhPrivateKey, membership, m3.store.E2e().GetGroup()) // // err = m1.gs.Add(grp1) // if err != nil { @@ -222,7 +222,7 @@ func TestNewManager_LoadError(t *testing.T) { // msg := message.Receive{ // Payload: requestMarshaled, // MessageType: message.GroupCreationRequest, -// Sender: m1.gs.GetUser().ID, +// Sender: m1.gs.GetTransmissionIdentity().ID, // } // // m2.swb.(*switchboard.Switchboard).Speak(msg) @@ -252,14 +252,14 @@ func TestNewManager_LoadError(t *testing.T) { // timestamp := netTime.Now() // // // Create cMix message and get public message -// cMixMsg, err := m1.newCmixMsg(grp1, contents, timestamp, m2.gs.GetUser(), prng) +// cMixMsg, err := m1.newCmixMsg(grp1, contents, timestamp, m2.gs.GetTransmissionIdentity(), prng) // if err != nil { // t.Errorf("Failed to create new cMix message: %+v", err) // } // // internalMsg, _ := newInternalMsg(cMixMsg.ContentsSize() - publicMinLen) // internalMsg.SetTimestamp(timestamp) -// internalMsg.SetSenderID(m1.gs.GetUser().ID) +// internalMsg.SetSenderID(m1.gs.GetTransmissionIdentity().ID) // internalMsg.SetPayload(contents) // expectedMsgID := group.NewMessageID(grp1.ID, internalMsg.Marshal()) // @@ -267,14 +267,14 @@ func TestNewManager_LoadError(t *testing.T) { // GroupID: grp1.ID, // ID: expectedMsgID, // Payload: contents, -// SenderID: m1.gs.GetUser().ID, +// SenderID: m1.gs.GetTransmissionIdentity().ID, // RoundTimestamp: timestamp.Local(), // } // // msg = message.Receive{ // Payload: cMixMsg.Marshal(), // MessageType: message.Raw, -// Sender: m1.gs.GetUser().ID, +// Sender: m1.gs.GetTransmissionIdentity().ID, // RoundTimestamp: timestamp.Local(), // } // m2.swb.(*switchboard.Switchboard).Speak(msg) diff --git a/storage/user/info.go b/storage/user/info.go index 62603c2225f0921f54684299f140fb33bfb6d182..3da77bb13935d863e382e26ad55aa529f1b63b6b 100644 --- a/storage/user/info.go +++ b/storage/user/info.go @@ -9,9 +9,7 @@ package user import ( "gitlab.com/elixxir/crypto/backup" - "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" - "gitlab.com/elixxir/primitives/fact" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" ) @@ -55,14 +53,6 @@ type Info struct { E2eDhPublicKey *cyclic.Int } -func (u Info) GetContact() contact.Contact { - return contact.Contact{ - ID: u.ReceptionID.DeepCopy(), - DhPubKey: u.E2eDhPublicKey, - Facts: make([]fact.Fact, 0), - } -} - func NewUserFromProto(proto *Proto) Info { return Info{ TransmissionID: proto.TransmissionID, diff --git a/xxdk/cmix.go b/xxdk/cmix.go index 059c9d061ffa8b83db87cf30db140f05d5311f7f..54aa051cbd8c22b0e7205e7e3c4d06822d5c5c39 100644 --- a/xxdk/cmix.go +++ b/xxdk/cmix.go @@ -392,7 +392,6 @@ func (c *Cmix) StopNetworkFollower() error { // NetworkFollowerStatus Gets the state of the network follower. Returns: // Stopped - 0 -// Starting - 1000 // Running - 2000 // Stopping - 3000 func (c *Cmix) NetworkFollowerStatus() Status { @@ -421,12 +420,11 @@ func (c *Cmix) AddService(sp Service) error { return c.followerServices.add(sp) } -// GetUser returns the current user Identity for this client. This -// can be serialized into a byte stream for out-of-band sharing. -func (c *Cmix) GetUser() user.Info { - jww.INFO.Printf("GetUser()") +// GetTransmissionIdentity returns the current TransmissionIdentity for this client +func (c *Cmix) GetTransmissionIdentity() TransmissionIdentity { + jww.INFO.Printf("GetTransmissionIdentity()") cMixUser := c.storage.PortableUserInfo() - return cMixUser + return buildTransmissionIdentity(cMixUser) } // GetComms returns the client comms object diff --git a/xxdk/e2e.go b/xxdk/e2e.go index e528c63352d167cc5b90016b56ae7200b0b921b4..34271b2092203b14feb7b8efe6d44499221a9597 100644 --- a/xxdk/e2e.go +++ b/xxdk/e2e.go @@ -76,7 +76,9 @@ func LoginLegacy(client *Cmix, callbacks AuthCallbacks) (m *E2e, err error) { if err != nil { return nil, err } - client.GetCmix().AddIdentity(client.GetUser().ReceptionID, time.Time{}, true) + + userInfo := client.GetStorage().PortableUserInfo() + client.GetCmix().AddIdentity(userInfo.ReceptionID, time.Time{}, true) err = client.AddService(m.e2e.StartProcesses) if err != nil { @@ -91,14 +93,7 @@ func LoginLegacy(client *Cmix, callbacks AuthCallbacks) (m *E2e, err error) { return nil, err } - u := m.Cmix.GetUser() - m.e2eIdentity = ReceptionIdentity{ - ID: u.TransmissionID, - RSAPrivatePem: u.TransmissionRSA, - Salt: u.TransmissionSalt, - DHKeyPrivate: u.E2eDhPrivateKey, - } - + m.e2eIdentity, err = buildReceptionIdentity(userInfo, m.e2e.GetGroup(), m.e2e.GetHistoricalDHPrivkey()) return m, err } @@ -183,12 +178,9 @@ func LoginWithProtoClient(storageDir string, password []byte, return nil, err } - return Login(c, callbacks, ReceptionIdentity{ - ID: protoUser.ReceptionID, - RSAPrivatePem: protoUser.ReceptionRSA, - Salt: protoUser.ReceptionSalt, - DHKeyPrivate: protoUser.E2eDhPrivateKey, - }) + userInfo := c.GetStorage().PortableUserInfo() + receptionIdentity, err := buildReceptionIdentity(userInfo, c.GetStorage().GetE2EGroup(), protoUser.E2eDhPrivateKey) + return Login(c, callbacks, receptionIdentity) } // login creates a new xxdk.E2e backed by the given versioned.KV @@ -196,7 +188,11 @@ func login(client *Cmix, callbacks AuthCallbacks, identity ReceptionIdentity, kv *versioned.KV) (m *E2e, err error) { // Verify the passed-in ReceptionIdentity matches its properties - generatedId, err := xx.NewID(identity.RSAPrivatePem.GetPublic(), identity.Salt, id.User) + privatePem, err := identity.GetRSAPrivatePem() + if err != nil { + return nil, err + } + generatedId, err := xx.NewID(privatePem.GetPublic(), identity.Salt, id.User) if err != nil { return nil, err } @@ -215,7 +211,11 @@ func login(client *Cmix, callbacks AuthCallbacks, client.network.AddIdentity(identity.ID, time.Time{}, true) //initialize the e2e storage - err = e2e.Init(kv, identity.ID, identity.DHKeyPrivate, e2eGrp, + dhPrivKey, err := identity.GetDHKeyPrivate() + if err != nil { + return nil, err + } + err = e2e.Init(kv, identity.ID, dhPrivKey, e2eGrp, rekey.GetDefaultEphemeralParams()) if err != nil { return nil, err @@ -250,7 +250,7 @@ func login(client *Cmix, callbacks AuthCallbacks, // e2e private key. It attempts to load via a legacy construction, then tries // to load the modern one, creating a new modern ID if neither can be found func LoadOrInitE2e(client *Cmix) (e2e.Handler, error) { - usr := client.GetUser() + usr := client.GetStorage().PortableUserInfo() e2eGrp := client.GetStorage().GetE2EGroup() kv := client.GetStorage().GetKV() @@ -314,15 +314,6 @@ func LoadOrInitE2e(client *Cmix) (e2e.Handler, error) { return e2eHandler, nil } -// GetUser replaces xxdk.Cmix's GetUser with one which includes the e2e dh -// private keys -func (m *E2e) GetUser() user.Info { - u := m.Cmix.GetUser() - u.E2eDhPrivateKey = m.e2e.GetHistoricalDHPrivkey() - u.E2eDhPublicKey = m.e2e.GetHistoricalDHPubkey() - return u -} - // GetReceptionIdentity returns a safe copy of the E2e ReceptionIdentity func (m *E2e) GetReceptionIdentity() ReceptionIdentity { return m.e2eIdentity.DeepCopy() @@ -339,15 +330,22 @@ func (m *E2e) ConstructProtoUserFile() ([]byte, error) { "permissioning") } + transIdentity := m.Cmix.GetTransmissionIdentity() + receptionIdentity := m.GetReceptionIdentity() + privatePem, err := receptionIdentity.GetRSAPrivatePem() + if err != nil { + return nil, err + } + Usr := user.Proto{ - TransmissionID: m.GetUser().TransmissionID, - TransmissionSalt: m.GetUser().TransmissionSalt, - TransmissionRSA: m.GetUser().TransmissionRSA, - ReceptionID: m.GetUser().ReceptionID, - ReceptionSalt: m.GetUser().ReceptionSalt, - ReceptionRSA: m.GetUser().ReceptionRSA, - Precanned: m.GetUser().Precanned, - RegistrationTimestamp: m.GetUser().RegistrationTimestamp, + TransmissionID: transIdentity.ID, + TransmissionSalt: transIdentity.Salt, + TransmissionRSA: transIdentity.RSAPrivatePem, + ReceptionID: receptionIdentity.ID, + ReceptionSalt: receptionIdentity.Salt, + ReceptionRSA: privatePem, + Precanned: m.GetStorage().IsPrecanned(), + RegistrationTimestamp: transIdentity.RegistrationTimestamp, RegCode: regCode, TransmissionRegValidationSig: m.GetStorage(). GetTransmissionRegistrationValidationSignature(), diff --git a/xxdk/identity.go b/xxdk/identity.go index 923bf3d5c6704284360d319c2d7e2483df77acd2..566ed4f19c2d2ba0c26676c2abcd42d81ff3fd49 100644 --- a/xxdk/identity.go +++ b/xxdk/identity.go @@ -7,26 +7,87 @@ package xxdk import ( + "encoding/json" + "gitlab.com/elixxir/client/storage/user" + "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/diffieHellman" - "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/xx" "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/netTime" ) +const idVersion = 0 + +// ReceptionIdentity is used by the E2e object for managing +// identities used for message pickup type ReceptionIdentity struct { ID *id.ID - RSAPrivatePem *rsa.PrivateKey + RSAPrivatePem []byte Salt []byte - DHKeyPrivate *cyclic.Int + DHKeyPrivate []byte + E2eGrp []byte +} + +// StoreReceptionIdentity stores the given identity in Cmix storage with the given key +// This is the ideal way to securely store identities, as the caller of this function +// is only required to store the given key separately rather than the keying material +func StoreReceptionIdentity(key string, identity ReceptionIdentity, client *Cmix) error { + marshalledIdentity, err := identity.Marshal() + if err != nil { + return err + } + + return client.GetStorage().Set(key, &versioned.Object{ + Version: idVersion, + Timestamp: netTime.Now(), + Data: marshalledIdentity, + }) +} + +// LoadReceptionIdentity loads the given identity in Cmix storage with the given key +func LoadReceptionIdentity(key string, client *Cmix) (ReceptionIdentity, error) { + storageObj, err := client.GetStorage().Get(key) + if err != nil { + return ReceptionIdentity{}, err + } + + return UnmarshalReceptionIdentity(storageObj.Data) +} + +// Marshal returns the JSON representation of a ReceptionIdentity +func (r ReceptionIdentity) Marshal() ([]byte, error) { + return json.Marshal(&r) +} + +// UnmarshalReceptionIdentity takes in a marshalled ReceptionIdentity +// and converts it to an object +func UnmarshalReceptionIdentity(marshaled []byte) (ReceptionIdentity, error) { + newIdentity := ReceptionIdentity{} + return newIdentity, json.Unmarshal(marshaled, &newIdentity) +} + +// GetDHKeyPrivate returns the DHKeyPrivate in go format +func (r ReceptionIdentity) GetDHKeyPrivate() (*cyclic.Int, error) { + dhKeyPriv := &cyclic.Int{} + err := dhKeyPriv.UnmarshalJSON(r.DHKeyPrivate) + return dhKeyPriv, err +} + +// GetRSAPrivatePem returns the RSAPrivatePem in go format +func (r ReceptionIdentity) GetRSAPrivatePem() (*rsa.PrivateKey, error) { + return rsa.LoadPrivateKeyFromPem(r.RSAPrivatePem) } // MakeReceptionIdentity generates a new cryptographic identity // for receiving messages. -func MakeReceptionIdentity(rng csprng.Source, - grp *cyclic.Group) (ReceptionIdentity, error) { +func MakeReceptionIdentity(client *Cmix) (ReceptionIdentity, error) { + rng := client.GetRng().GetStream() + defer rng.Close() + grp := client.GetStorage().GetE2EGroup() + //make RSA Key rsaKey, err := rsa.GenerateKey(rng, rsa.DefaultRSABitLen) @@ -50,12 +111,24 @@ func MakeReceptionIdentity(rng csprng.Source, return ReceptionIdentity{}, err } + privKeyBytes, err := privKey.MarshalJSON() + if err != nil { + return ReceptionIdentity{}, err + } + + grpBytes, err := grp.MarshalJSON() + if err != nil { + return ReceptionIdentity{}, err + } + //create the identity object + rsaPem := rsa.CreatePrivateKeyPem(rsaKey) I := ReceptionIdentity{ ID: newId, - RSAPrivatePem: rsaKey, + RSAPrivatePem: rsaPem, Salt: salt, - DHKeyPrivate: privKey, + DHKeyPrivate: privKeyBytes, + E2eGrp: grpBytes, } return I, nil @@ -65,18 +138,24 @@ func MakeReceptionIdentity(rng csprng.Source, func (r ReceptionIdentity) DeepCopy() ReceptionIdentity { saltCopy := make([]byte, len(r.Salt)) copy(saltCopy, r.Salt) + + dhKeyCopy := make([]byte, len(r.DHKeyPrivate)) + copy(dhKeyCopy, r.DHKeyPrivate) return ReceptionIdentity{ ID: r.ID.DeepCopy(), RSAPrivatePem: r.RSAPrivatePem, Salt: saltCopy, - DHKeyPrivate: r.DHKeyPrivate.DeepCopy(), + DHKeyPrivate: dhKeyCopy, } } // GetContact accepts a xxdk.ReceptionIdentity object and returns a contact.Contact object -func (r ReceptionIdentity) GetContact(grp *cyclic.Group) contact.Contact { - dhPub := grp.ExpG(r.DHKeyPrivate, grp.NewInt(1)) +func (r ReceptionIdentity) GetContact() contact.Contact { + grp := &cyclic.Group{} + _ = grp.UnmarshalJSON(r.E2eGrp) + dhKeyPriv, _ := r.GetDHKeyPrivate() + dhPub := grp.ExpG(dhKeyPriv, grp.NewInt(1)) ct := contact.Contact{ ID: r.ID, DhPubKey: dhPub, @@ -85,3 +164,62 @@ func (r ReceptionIdentity) GetContact(grp *cyclic.Group) contact.Contact { } return ct } + +// buildReceptionIdentity creates a new ReceptionIdentity +// from the given user.Info +func buildReceptionIdentity(userInfo user.Info, e2eGrp *cyclic.Group, dHPrivkey *cyclic.Int) (ReceptionIdentity, error) { + saltCopy := make([]byte, len(userInfo.TransmissionSalt)) + copy(saltCopy, userInfo.TransmissionSalt) + + grp, err := e2eGrp.MarshalJSON() + if err != nil { + return ReceptionIdentity{}, err + } + privKey, err := dHPrivkey.MarshalJSON() + if err != nil { + return ReceptionIdentity{}, err + } + + return ReceptionIdentity{ + ID: userInfo.ReceptionID.DeepCopy(), + RSAPrivatePem: rsa.CreatePrivateKeyPem(userInfo.ReceptionRSA), + Salt: saltCopy, + DHKeyPrivate: privKey, + E2eGrp: grp, + }, nil +} + +// TransmissionIdentity represents the identity +// used to transmit over the network via a specific Cmix object +type TransmissionIdentity struct { + ID *id.ID + RSAPrivatePem *rsa.PrivateKey + Salt []byte + // Timestamp in which user has registered with the network + RegistrationTimestamp int64 +} + +// DeepCopy produces a safe copy of a TransmissionIdentity +func (t TransmissionIdentity) DeepCopy() TransmissionIdentity { + saltCopy := make([]byte, len(t.Salt)) + copy(saltCopy, t.Salt) + return TransmissionIdentity{ + ID: t.ID.DeepCopy(), + RSAPrivatePem: t.RSAPrivatePem, + Salt: saltCopy, + RegistrationTimestamp: t.RegistrationTimestamp, + } +} + +// buildTransmissionIdentity creates a new TransmissionIdentity +// from the given user.Info +func buildTransmissionIdentity(userInfo user.Info) TransmissionIdentity { + saltCopy := make([]byte, len(userInfo.TransmissionSalt)) + copy(saltCopy, userInfo.TransmissionSalt) + return TransmissionIdentity{ + ID: userInfo.TransmissionID.DeepCopy(), + RSAPrivatePem: userInfo.TransmissionRSA, + Salt: saltCopy, + RegistrationTimestamp: userInfo.RegistrationTimestamp, + } +} diff --git a/xxdk/permissioning.go b/xxdk/permissioning.go index 2e1d735e1236c410bfb473e7d02bad87b6f73536..e3327d8a875c33885c3194013434e0b8d7037252 100644 --- a/xxdk/permissioning.go +++ b/xxdk/permissioning.go @@ -63,15 +63,16 @@ func (c *Cmix) ConstructProtoUserFile() ([]byte, error) { "permissioning") } + userInfo := c.GetStorage().PortableUserInfo() Usr := user.Proto{ - TransmissionID: c.GetUser().TransmissionID, - TransmissionSalt: c.GetUser().TransmissionSalt, - TransmissionRSA: c.GetUser().TransmissionRSA, - ReceptionID: c.GetUser().ReceptionID, - ReceptionSalt: c.GetUser().ReceptionSalt, - ReceptionRSA: c.GetUser().ReceptionRSA, - Precanned: c.GetUser().Precanned, - RegistrationTimestamp: c.GetUser().RegistrationTimestamp, + TransmissionID: userInfo.TransmissionID, + TransmissionSalt: userInfo.TransmissionSalt, + TransmissionRSA: userInfo.TransmissionRSA, + ReceptionID: userInfo.ReceptionID, + ReceptionSalt: userInfo.ReceptionSalt, + ReceptionRSA: userInfo.ReceptionRSA, + Precanned: userInfo.Precanned, + RegistrationTimestamp: userInfo.RegistrationTimestamp, RegCode: regCode, TransmissionRegValidationSig: c.storage.GetTransmissionRegistrationValidationSignature(), ReceptionRegValidationSig: c.storage.GetReceptionRegistrationValidationSignature(),