diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ec567c930ca36acff12a23f223f1bcc45dd5e4d6..61bc3bfe8c5400f557e390044ce8efd2d6652f72 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,7 +4,7 @@ variables:
REPO_DIR: gitlab.com/elixxir
REPO_NAME: client
DOCKER_IMAGE: elixxirlabs/cuda-go:latest
- MIN_CODE_COVERAGE: "75"
+ MIN_CODE_COVERAGE: "74"
before_script:
##
diff --git a/api/client.go b/api/client.go
index b5639a701870805f53a884949d3cc5306f83f61e..ba3506e95d3a11cb7c5b86e73457081a2ff0886b 100644
--- a/api/client.go
+++ b/api/client.go
@@ -121,7 +121,7 @@ func newClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit
}
// LoadSession loads the session object for the UID
-func (cl *Client) Login(password string) (*id.User, error) {
+func (cl *Client) Login(password string) (*id.ID, error) {
var session user.Session
var err error
@@ -158,7 +158,7 @@ func (cl *Client) Login(password string) (*id.User, error) {
}
cl.session = session
- newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User.String(),
+ newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User,
rsa.CreatePrivateKeyPem(cl.session.GetRSAPrivateKey()),
rsa.CreatePublicKeyPem(cl.session.GetRSAPublicKey()),
cl.session.GetSalt())
@@ -306,14 +306,19 @@ var sessionFileError = errors.New("Session file cannot be loaded and " +
"is possibly corrupt. Please contact support@xxmessenger.io")
func (cl *Client) InitListeners() error {
- transmitGateway := id.NewNodeFromBytes(cl.ndf.Nodes[0].ID).NewGateway()
- transmissionHost, ok := cl.receptionManager.Comms.GetHost(transmitGateway.String())
+ transmitGateway, err := id.Unmarshal(cl.ndf.Gateways[0].ID)
+ if err != nil {
+ globals.Log.DEBUG.Printf("%s: Gateways are: %+v", err.Error(),
+ cl.ndf.Gateways)
+ return err
+ }
+ transmissionHost, ok := cl.receptionManager.Comms.GetHost(transmitGateway)
if !ok {
return errors.New("Failed to retrieve host for transmission")
}
// Initialize UDB and nickname "bot" stuff here
- bots.InitBots(cl.session, cl.receptionManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID), transmissionHost)
+ bots.InitBots(cl.session, cl.receptionManager, cl.topology, transmissionHost)
// Initialize Rekey listeners
rekey.InitRekey(cl.session, cl.receptionManager, cl.topology, transmissionHost, cl.rekeyChan)
return nil
@@ -325,8 +330,11 @@ func (cl *Client) StartMessageReceiver(callback func(error)) error {
pollWaitTimeMillis := 500 * time.Millisecond
// TODO Don't start the message receiver if it's already started.
// Should be a pretty rare occurrence except perhaps for mobile.
- receptionGateway := id.NewNodeFromBytes(cl.ndf.Nodes[len(cl.ndf.Nodes)-1].ID).NewGateway()
- receptionHost, ok := cl.receptionManager.Comms.GetHost(receptionGateway.String())
+ receptionGateway, err := id.Unmarshal(cl.ndf.Gateways[len(cl.ndf.Gateways)-1].ID)
+ if err != nil {
+ return err
+ }
+ receptionHost, ok := cl.receptionManager.Comms.GetHost(receptionGateway)
if !ok {
return errors.New("Failed to retrieve host for transmission")
}
@@ -349,8 +357,12 @@ func (cl *Client) StartMessageReceiver(callback func(error)) error {
// Default send function, can be overridden for testing
func (cl *Client) Send(message parse.MessageInterface) error {
- transmitGateway := id.NewNodeFromBytes(cl.ndf.Nodes[0].ID).NewGateway()
- host, ok := cl.receptionManager.Comms.GetHost(transmitGateway.String())
+ transmitGateway, err := id.Unmarshal(cl.ndf.Gateways[0].ID)
+ if err != nil {
+ return err
+ }
+ transmitGateway.SetType(id.Gateway)
+ host, ok := cl.receptionManager.Comms.GetHost(transmitGateway)
if !ok {
return errors.New("Failed to retrieve host for transmission")
}
@@ -377,7 +389,7 @@ func (cl *Client) SetRateLimiting(limit uint32) {
cl.receptionManager.SetRateLimit(time.Duration(limit) * time.Millisecond)
}
-func (cl *Client) Listen(user *id.User, messageType int32, newListener switchboard.Listener) string {
+func (cl *Client) Listen(user *id.ID, messageType int32, newListener switchboard.Listener) string {
listenerId := cl.session.GetSwitchboard().
Register(user, messageType, newListener)
globals.Log.INFO.Printf("Listening now: user %v, message type %v, id %v",
@@ -393,7 +405,7 @@ func (cl *Client) GetSwitchboard() *switchboard.Switchboard {
return cl.session.GetSwitchboard()
}
-func (cl *Client) GetCurrentUser() *id.User {
+func (cl *Client) GetCurrentUser() *id.ID {
return cl.session.GetCurrentUser().User
}
@@ -467,7 +479,7 @@ type NickLookupCallback interface {
Callback(nick string, err error)
}
-func (cl *Client) DeleteUser(u *id.User) (string, error) {
+func (cl *Client) DeleteUser(u *id.ID) (string, error) {
//delete from session
v, err1 := cl.session.DeleteContact(u)
@@ -499,7 +511,7 @@ func (cl *Client) DeleteUser(u *id.User) (string, error) {
// Nickname lookup API
// Non-blocking, once the API call completes, the callback function
// passed as argument is called
-func (cl *Client) LookupNick(user *id.User,
+func (cl *Client) LookupNick(user *id.ID,
cb NickLookupCallback) {
go func() {
nick, err := bots.LookupNick(user)
diff --git a/api/client_test.go b/api/client_test.go
index b77ea2c6fe1709a1b115a8e8a8166c35df98b2cd..bebd23da966c191ed8c45900a0626f25c54b4932 100644
--- a/api/client_test.go
+++ b/api/client_test.go
@@ -128,8 +128,8 @@ func TestParse(t *testing.T) {
ms := parse.Message{}
ms.Body = []byte{0, 1, 2}
ms.MessageType = int32(cmixproto.Type_NO_TYPE)
- ms.Receiver = id.ZeroID
- ms.Sender = id.ZeroID
+ ms.Receiver = &id.ZeroUser
+ ms.Sender = &id.ZeroUser
messagePacked := ms.Pack()
@@ -158,8 +158,8 @@ func TestRegisterUserE2E(t *testing.T) {
rng := csprng.NewSystemRNG()
cmixGrp, e2eGrp := getGroups()
- userID := id.NewUserFromUint(18, t)
- partner := id.NewUserFromUint(14, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
myPrivKeyCyclic := e2eGrp.RandomCoprime(e2eGrp.NewMaxInt())
myPubKeyCyclic := e2eGrp.ExpG(myPrivKeyCyclic, e2eGrp.NewMaxInt())
@@ -247,8 +247,8 @@ func TestRegisterUserE2E_CheckAllKeys(t *testing.T) {
}
cmixGrp, e2eGrp := getGroups()
- userID := id.NewUserFromUint(18, t)
- partner := id.NewUserFromUint(14, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
rng := csprng.NewSystemRNG()
myPrivKeyCyclic := e2eGrp.RandomCoprime(e2eGrp.NewMaxInt())
@@ -401,7 +401,7 @@ func TestClient_precannedRegister(t *testing.T) {
t.Error(err)
}
- _, _, _, err = testClient.precannedRegister("UAV6IWD6")
+ _, _, _, err = testClient.precannedRegister("WTROXJ33")
if err != nil {
t.Errorf("Error during precannedRegister: %+v", err)
}
@@ -428,7 +428,7 @@ func TestClient_sendRegistrationMessage(t *testing.T) {
privateKeyRSA, _ := rsa.GenerateKey(rng, TestKeySize)
publicKeyRSA := rsa.PublicKey{PublicKey: privateKeyRSA.PublicKey}
- _, err = testClient.sendRegistrationMessage("UAV6IWD6", &publicKeyRSA)
+ _, err = testClient.sendRegistrationMessage("WTROXJ33", &publicKeyRSA)
if err != nil {
t.Errorf("Error during sendRegistrationMessage: %+v", err)
}
@@ -462,7 +462,11 @@ func TestClient_requestNonce(t *testing.T) {
t.Errorf("Unable to generate salt! %s", err)
}
- gwID := id.NewNodeFromBytes(testClient.ndf.Nodes[0].ID).NewGateway()
+ gwID, err := id.Unmarshal(testClient.ndf.Gateways[0].ID)
+ if err != nil {
+ t.Fatal(err)
+ }
+ gwID.SetType(id.Gateway)
_, _, err = testClient.requestNonce(salt, []byte("test"), publicKeyDH, &publicKeyRSA, privateKeyRSA, gwID)
if err != nil {
t.Errorf("Error during requestNonce: %+v", err)
@@ -485,7 +489,11 @@ func TestClient_confirmNonce(t *testing.T) {
}
rng := csprng.NewSystemRNG()
privateKeyRSA, _ := rsa.GenerateKey(rng, TestKeySize)
- gwID := id.NewNodeFromBytes(testClient.ndf.Nodes[0].ID).NewGateway()
+ gwID, err := id.Unmarshal(testClient.ndf.Gateways[0].ID)
+ if err != nil {
+ t.Fatal(err)
+ }
+ gwID.SetType(id.Gateway)
err = testClient.confirmNonce([]byte("user"), []byte("test"), privateKeyRSA, gwID)
if err != nil {
t.Errorf("Error during confirmNonce: %+v", err)
@@ -567,7 +575,8 @@ func TestClient_LogoutHappyPath(t *testing.T) {
d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}}
tc, _ := NewClient(&d, "", "", def)
- tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil)
+ uid := id.NewIdFromString("kk", id.User, t)
+ tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, uid, nil, nil, nil)
err := tc.InitNetwork()
if err != nil {
@@ -642,7 +651,8 @@ func TestClient_LogoutTimeout(t *testing.T) {
d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}}
tc, _ := NewClient(&d, "", "", def)
- tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil)
+ uid := id.NewIdFromString("kk", id.User, t)
+ tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, uid, nil, nil, nil)
err := tc.InitNetwork()
if err != nil {
@@ -705,7 +715,8 @@ func TestClient_LogoutAndLoginAgain(t *testing.T) {
storage := globals.RamStorage{}
tc, initialId := NewClient(&storage, "", "", def)
- tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, "kk", nil, nil, nil)
+ uid := id.NewIdFromString("kk", id.User, t)
+ tc.receptionManager, _ = io.NewReceptionManager(tc.rekeyChan, uid, nil, nil, nil)
err := tc.InitNetwork()
if err != nil {
diff --git a/api/connect.go b/api/connect.go
index 5feebdb09b2262f04e04a205ce7558b1d92ba126..7a4a9b2bd2b438544612ff6cbedccbec49fcc91c 100644
--- a/api/connect.go
+++ b/api/connect.go
@@ -24,7 +24,8 @@ var ErrNoPermissioning = errors.New("No Permissioning In NDF")
func (cl *Client) InitNetwork() error {
var err error
if cl.receptionManager == nil {
- cl.receptionManager, err = io.NewReceptionManager(cl.rekeyChan, "client", nil, nil, nil)
+ // Start reception manager with a dummy user, so we can connect to things
+ cl.receptionManager, err = io.NewReceptionManager(cl.rekeyChan, &id.DummyUser, nil, nil, nil)
if err != nil {
return errors.Wrap(err, "Failed to create reception manager")
}
@@ -53,7 +54,10 @@ func (cl *Client) InitNetwork() error {
}
// InitNetwork to nodes
- cl.topology = BuildNodeTopology(cl.ndf)
+ cl.topology, err = BuildNodeTopology(cl.ndf)
+ if err != nil {
+ return err
+ }
err = addNotificationBotHost(cl.receptionManager, cl.ndf)
if err != nil {
@@ -66,7 +70,7 @@ func (cl *Client) InitNetwork() error {
// AddNotificationBotHost adds notification bot as a host within the reception manager
func addNotificationBotHost(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error {
- err := addHost(rm, id.NOTIFICATION_BOT, definition.Notification.Address,
+ err := addHost(rm, &id.NotificationBot, definition.Notification.Address,
definition.Notification.TlsCertificate, false, true)
if err != nil {
return errors.Errorf("Failed to connect to notification bot at %+v",
@@ -77,14 +81,18 @@ func addNotificationBotHost(rm *io.ReceptionManager, definition *ndf.NetworkDefi
// BuildNodeTopology is a helper function which goes through the ndf and
// builds a circuit for all the node's in the definition
-func BuildNodeTopology(definition *ndf.NetworkDefinition) *connect.Circuit {
+func BuildNodeTopology(definition *ndf.NetworkDefinition) (*connect.Circuit, error) {
//build the topology
- nodeIDs := make([]*id.Node, len(definition.Nodes))
+ nodeIDs := make([]*id.ID, len(definition.Nodes))
+ var err error
for i, node := range definition.Nodes {
- nodeIDs[i] = id.NewNodeFromBytes(node.ID)
+ nodeIDs[i], err = id.Unmarshal(node.ID)
+ if err != nil {
+ return nil, err
+ }
}
- return connect.NewCircuit(nodeIDs)
+ return connect.NewCircuit(nodeIDs), nil
}
// DisableTls disables tls for communications
@@ -148,8 +156,18 @@ func addGatewayHosts(rm *io.ReceptionManager, definition *ndf.NetworkDefinition)
// connect to all gateways
var errs error = nil
for i, gateway := range definition.Gateways {
- gwID := id.NewNodeFromBytes(definition.Nodes[i].ID).NewGateway()
- err := addHost(rm, gwID.String(), gateway.Address, gateway.TlsCertificate, false, false)
+ gwID, err := id.Unmarshal(definition.Gateways[i].ID)
+ if err != nil {
+ err = errors.Errorf("Failed to unmarshal gateway ID %s at index %v: %+v",
+ definition.Gateways[i].ID, i, err)
+ if errs != nil {
+ errs = err
+ } else {
+ errs = errors.Wrap(errs, err.Error())
+ }
+ continue
+ }
+ err = addHost(rm, gwID, gateway.Address, gateway.TlsCertificate, false, false)
if err != nil {
err = errors.Errorf("Failed to create host for gateway %s at %s: %+v",
gwID.String(), gateway.Address, err)
@@ -163,7 +181,7 @@ func addGatewayHosts(rm *io.ReceptionManager, definition *ndf.NetworkDefinition)
return errs
}
-func addHost(rm *io.ReceptionManager, id, address, cert string, disableTimeout, enableAuth bool) error {
+func addHost(rm *io.ReceptionManager, id *id.ID, address, cert string, disableTimeout, enableAuth bool) error {
var creds []byte
if cert != "" && rm.Tls {
creds = []byte(cert)
@@ -180,7 +198,7 @@ func addHost(rm *io.ReceptionManager, id, address, cert string, disableTimeout,
// to permissioning is needed
func addPermissioningHost(rm *io.ReceptionManager, definition *ndf.NetworkDefinition) error {
if definition.Registration.Address != "" {
- err := addHost(rm, PermissioningAddrID, definition.Registration.Address,
+ err := addHost(rm, &id.Permissioning, definition.Registration.Address,
definition.Registration.TlsCertificate, false, false)
if err != nil {
return errors.New(fmt.Sprintf(
diff --git a/api/mockserver.go b/api/mockserver.go
index c77de57be32e75d6b8c73fbb5c4d1d2a49cde249..12bcd5e6d7fdd84080c2720fb8553077fb0dee74 100644
--- a/api/mockserver.go
+++ b/api/mockserver.go
@@ -37,15 +37,15 @@ const BatchSize = 10
// easy to use from Go
type APIMessage struct {
Payload []byte
- SenderID *id.User
- RecipientID *id.User
+ SenderID *id.ID
+ RecipientID *id.ID
}
-func (m APIMessage) GetSender() *id.User {
+func (m APIMessage) GetSender() *id.ID {
return m.SenderID
}
-func (m APIMessage) GetRecipient() *id.User {
+func (m APIMessage) GetRecipient() *id.ID {
return m.RecipientID
}
@@ -141,7 +141,7 @@ type MockRegistration struct {
//LastReceivedMessage pb.CmixMessage
}
-func (s *MockRegistration) RegisterNode(ID []byte,
+func (s *MockRegistration) RegisterNode(ID *id.ID,
NodeTLSCert, GatewayTLSCert, RegistrationCode, Addr, Addr2 string) error {
return nil
}
@@ -265,7 +265,7 @@ type GatewayHandler struct {
LastReceivedMessage pb.Slot
}
-func (m *GatewayHandler) PollForNotifications(auth *connect.Auth) ([]string, error) {
+func (m *GatewayHandler) PollForNotifications(auth *connect.Auth) ([]*id.ID, error) {
return nil, nil
}
@@ -276,13 +276,13 @@ func (m *GatewayHandler) Poll(*pb.GatewayPoll) (*pb.GatewayPollResponse, error)
// Returns message contents for MessageID, or a null/randomized message
// if that ID does not exist of the same size as a regular message
-func (m *GatewayHandler) GetMessage(userId *id.User,
+func (m *GatewayHandler) GetMessage(userId *id.ID,
msgId, ipaddr string) (*pb.Slot, error) {
return &pb.Slot{}, nil
}
// Return any MessageIDs in the globals for this User
-func (m *GatewayHandler) CheckMessages(userId *id.User,
+func (m *GatewayHandler) CheckMessages(userId *id.ID,
messageID, ipAddress string) ([]string, error) {
return make([]string, 0), nil
}
@@ -315,7 +315,7 @@ type GatewayHandlerMultipleMessages struct {
LastReceivedMessage []pb.Slot
}
-func (m *GatewayHandlerMultipleMessages) GetMessage(userId *id.User,
+func (m *GatewayHandlerMultipleMessages) GetMessage(userId *id.ID,
msgId, ipaddr string) (*pb.Slot, error) {
msg := []byte("Hello")
payload, err := e2e.Pad(msg, format.PayloadLen)
@@ -328,7 +328,7 @@ func (m *GatewayHandlerMultipleMessages) GetMessage(userId *id.User,
}, nil
}
-func (m *GatewayHandlerMultipleMessages) PollForNotifications(auth *connect.Auth) ([]string, error) {
+func (m *GatewayHandlerMultipleMessages) PollForNotifications(auth *connect.Auth) ([]*id.ID, error) {
return nil, nil
}
@@ -337,7 +337,7 @@ func (s *GatewayHandlerMultipleMessages) Poll(*pb.GatewayPoll) (*pb.GatewayPollR
}
// Return any MessageIDs in the globals for this User
-func (m *GatewayHandlerMultipleMessages) CheckMessages(userId *id.User,
+func (m *GatewayHandlerMultipleMessages) CheckMessages(userId *id.ID,
messageID, ipaddr string) ([]string, error) {
msgs := []string{"a", "b", "c", "d", "e", "f", "g"}
return msgs, nil
diff --git a/api/mockserver_test.go b/api/mockserver_test.go
index a407aa3b8b18e1ebaa1e55b60721d850b0e5fe3f..86a26bf01b7db1641ea79003bdfbb33e6782a86f 100644
--- a/api/mockserver_test.go
+++ b/api/mockserver_test.go
@@ -38,7 +38,7 @@ var RegComms *registration.Comms
var NDFErrorReg = MockPermNdfErrorCase{}
var ErrorDef *ndf.NetworkDefinition
-const ValidRegCode = "UAV6IWD6"
+const ValidRegCode = "WTROXJ33"
const InvalidRegCode = "INVALID_REG_CODE_"
var RegGWHandlers [3]*GatewayHandler = [NumGWs]*GatewayHandler{
@@ -67,11 +67,13 @@ func TestClient_StartMessageReceiver_MultipleMessages(t *testing.T) {
// Initialize client with dummy storage
testDef := getNDF()
for i := 0; i < NumNodes; i++ {
+ gwID := id.NewIdFromString("testGateway", id.Gateway, t)
gw := ndf.Gateway{
Address: string(fmtAddress(GWErrorPort + i)),
+ ID: gwID.Marshal(),
}
testDef.Gateways = append(testDef.Gateways, gw)
- GWErrComms[i] = gateway.StartGateway("testGateway", gw.Address,
+ GWErrComms[i] = gateway.StartGateway(gwID, gw.Address,
&GatewayHandlerMultipleMessages{}, nil, nil)
}
@@ -163,7 +165,7 @@ func TestRegister_ValidPrecannedRegCodeReturnsZeroID(t *testing.T) {
t.Errorf("Registration failed: %s", err.Error())
}
- if *regRes == *id.ZeroID {
+ if regRes.Cmp(&id.ZeroUser) {
t.Errorf("Invalid registration number received: %v", *regRes)
}
disconnectServers()
@@ -254,8 +256,8 @@ func TestRegister_DeletedUserReturnsErr(t *testing.T) {
}
// ...
- tempUser, _ := user.Users.GetUser(id.NewUserFromUint(5, t))
- user.Users.DeleteUser(id.NewUserFromUint(5, t))
+ tempUser, _ := user.Users.GetUser(id.NewIdFromUInt(5, id.User, t))
+ user.Users.DeleteUser(id.NewIdFromUInt(5, id.User, t))
err = client.GenerateKeys(nil, "")
if err != nil {
t.Errorf("Could not generate Keys: %+v", err)
@@ -327,7 +329,7 @@ func TestSend(t *testing.T) {
// Test send with invalid sender ID
err = client.Send(
APIMessage{
- SenderID: id.NewUserFromUint(12, t),
+ SenderID: id.NewIdFromUInt(12, id.User, t),
Payload: []byte("test"),
RecipientID: userID,
},
@@ -447,10 +449,11 @@ func testMainWrapper(m *testing.M) int {
}
for i := 0; i < NumNodes; i++ {
- nIdBytes := make([]byte, id.NodeIdLen)
- nIdBytes[0] = byte(i)
+ nId := new(id.ID)
+ nId[0] = byte(i)
+ nId.SetType(id.Node)
n := ndf.Node{
- ID: nIdBytes,
+ ID: nId[:],
}
def.Nodes = append(def.Nodes, n)
ErrorDef.Nodes = append(ErrorDef.Nodes, n)
@@ -512,22 +515,28 @@ func getNDF() *ndf.NetworkDefinition {
}
func startServers() {
- //func StartRegistrationServer(id, localServer string, handler Handler, certPEMblock, keyPEMblock []byte) *Comms {
- RegComms = registration.StartRegistrationServer("testServer", def.Registration.Address, &RegHandler, nil, nil)
+ regId := new(id.ID)
+ copy(regId[:], "testServer")
+ regId.SetType(id.Generic)
+ RegComms = registration.StartRegistrationServer(regId, def.Registration.Address, &RegHandler, nil, nil)
def.Gateways = make([]ndf.Gateway, 0)
//Start up gateways
for i, handler := range RegGWHandlers {
+ gwID := new(id.ID)
+ copy(gwID[:], "testGateway")
+ gwID.SetType(id.Gateway)
gw := ndf.Gateway{
Address: fmtAddress(GWsStartPort + i),
+ ID: gwID.Marshal(),
}
def.Gateways = append(def.Gateways, gw)
- GWComms[i] = gateway.StartGateway("testGateway", gw.Address, handler, nil, nil)
+ GWComms[i] = gateway.StartGateway(gwID, gw.Address, handler, nil, nil)
}
- NotificationBotComms = notificationBot.StartNotificationBot(id.NOTIFICATION_BOT, def.Notification.Address, &NotificationBotHandler, nil, nil)
+ NotificationBotComms = notificationBot.StartNotificationBot(&id.NotificationBot, def.Notification.Address, &NotificationBotHandler, nil, nil)
}
diff --git a/api/notifications.go b/api/notifications.go
index 663daa315379e88496d186f027377978dda0c80f..5d27bf73d22387c378b66f738478dfb927c6ba0f 100644
--- a/api/notifications.go
+++ b/api/notifications.go
@@ -10,7 +10,7 @@ import (
// is registering for notifications
func (cl *Client) RegisterForNotifications(notificationToken []byte) error {
// Pull the host from the manage
- notificationBotHost, ok := cl.receptionManager.Comms.GetHost(id.NOTIFICATION_BOT)
+ notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
if !ok {
return errors.New("Failed to retrieve host for notification bot")
}
@@ -34,7 +34,7 @@ func (cl *Client) RegisterForNotifications(notificationToken []byte) error {
// no longer wants to be registered for notifications
func (cl *Client) UnregisterForNotifications() error {
// Pull the host from the manage
- notificationBotHost, ok := cl.receptionManager.Comms.GetHost(id.NOTIFICATION_BOT)
+ notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
if !ok {
return errors.New("Failed to retrieve host for notification bot")
}
diff --git a/api/private.go b/api/private.go
index 2e6dcb6a9e950a3d6e8a5fc69dc9aecb62dfaa05..528dedea53517c15747b5d1868b050aca488f6d4 100644
--- a/api/private.go
+++ b/api/private.go
@@ -20,8 +20,8 @@ import (
"gitlab.com/elixxir/crypto/diffieHellman"
"gitlab.com/elixxir/crypto/e2e"
"gitlab.com/elixxir/crypto/large"
- "gitlab.com/elixxir/crypto/registration"
"gitlab.com/elixxir/crypto/signature/rsa"
+ "gitlab.com/elixxir/crypto/xx"
"gitlab.com/elixxir/primitives/id"
"gitlab.com/elixxir/primitives/ndf"
)
@@ -30,13 +30,13 @@ const PermissioningAddrID = "Permissioning"
// precannedRegister is a helper function for Register
// It handles the precanned registration case
-func (cl *Client) precannedRegister(registrationCode string) (*user.User, *id.User, map[id.Node]user.NodeKeys, error) {
+func (cl *Client) precannedRegister(registrationCode string) (*user.User, *id.ID, map[id.ID]user.NodeKeys, error) {
var successLook bool
- var UID *id.User
+ var UID *id.ID
var u *user.User
var err error
- nk := make(map[id.Node]user.NodeKeys)
+ nk := make(map[id.ID]user.NodeKeys)
UID, successLook = user.Users.LookupUser(registrationCode)
@@ -82,7 +82,7 @@ func (cl *Client) sendRegistrationMessage(registrationCode string,
regValidationSignature := make([]byte, 0)
// Send registration code and public key to RegistrationServer
- host, ok := cl.receptionManager.Comms.GetHost(PermissioningAddrID)
+ host, ok := cl.receptionManager.Comms.GetHost(&id.Permissioning)
if !ok {
return nil, errors.New("Failed to find permissioning host")
}
@@ -110,7 +110,7 @@ func (cl *Client) sendRegistrationMessage(registrationCode string,
// Returns nonce if successful
func (cl *Client) requestNonce(salt, regHash []byte,
publicKeyDH *cyclic.Int, publicKeyRSA *rsa.PublicKey,
- privateKeyRSA *rsa.PrivateKey, gwID *id.Gateway) ([]byte, []byte, error) {
+ privateKeyRSA *rsa.PrivateKey, gwID *id.ID) ([]byte, []byte, error) {
dhPub := publicKeyDH.Bytes()
sha := crypto.SHA256
opts := rsa.NewDefaultOptions()
@@ -127,7 +127,7 @@ func (cl *Client) requestNonce(salt, regHash []byte,
}
// Send signed public key and salt for UserID to Server
- host, ok := cl.receptionManager.Comms.GetHost(gwID.String())
+ host, ok := cl.receptionManager.Comms.GetHost(gwID)
if !ok {
return nil, nil, errors.Errorf("Failed to find host with ID %s", gwID.String())
}
@@ -163,7 +163,7 @@ func (cl *Client) requestNonce(salt, regHash []byte,
// It signs a nonce and sends it for confirmation
// Returns nil if successful, error otherwise
func (cl *Client) confirmNonce(UID, nonce []byte,
- privateKeyRSA *rsa.PrivateKey, gwID *id.Gateway) error {
+ privateKeyRSA *rsa.PrivateKey, gwID *id.ID) error {
sha := crypto.SHA256
opts := rsa.NewDefaultOptions()
opts.Hash = sha
@@ -188,7 +188,7 @@ func (cl *Client) confirmNonce(UID, nonce []byte,
},
}
- host, ok := cl.receptionManager.Comms.GetHost(gwID.String())
+ host, ok := cl.receptionManager.Comms.GetHost(gwID)
if !ok {
return errors.Errorf("Failed to find host with ID %s", gwID.String())
}
@@ -207,7 +207,7 @@ func (cl *Client) confirmNonce(UID, nonce []byte,
return nil
}
-func (cl *Client) registerUserE2E(partnerID *id.User,
+func (cl *Client) registerUserE2E(partnerID *id.ID,
partnerPubKey []byte) error {
// Check that the returned user is valid
@@ -303,7 +303,7 @@ func (cl *Client) GenerateKeys(rsaPrivKey *rsa.PrivateKey,
cl.session = user.NewSession(cl.storage, usr, pubKey, privKey, cmixPubKey,
cmixPrivKey, e2ePubKey, e2ePrivKey, salt, cmixGrp, e2eGrp, password)
- newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User.String(),
+ newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User,
rsa.CreatePrivateKeyPem(privKey), rsa.CreatePublicKeyPem(pubKey), salt)
if err != nil {
return errors.Wrap(err, "Failed to create new reception manager")
@@ -392,7 +392,7 @@ func generateE2eKeys(cmixGrp, e2eGrp *cyclic.Group) (e2ePrivateKey, e2ePublicKey
//generateUserInformation serves as a helper function for RegisterUser.
// It generates a salt s.t. it can create a user and their ID
-func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.User, *user.User, error) {
+func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.ID, *user.User, error) {
//Generate salt for UserID
salt := make([]byte, SaltSize)
_, err := csprng.NewSystemRNG().Read(salt)
@@ -402,7 +402,10 @@ func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.User, *us
}
//Generate UserID by hashing salt and public key
- userId := registration.GenUserID(publicKeyRSA, salt)
+ userId, err := xx.NewID(publicKeyRSA, salt, id.User)
+ if err != nil {
+ return nil, nil, nil, err
+ }
usr := user.Users.NewUser(userId, "")
user.Users.UpsertUser(usr)
diff --git a/api/register.go b/api/register.go
index afbefd0ad10d5f27783712877328913fb0314b5a..921738be22150f4fa06a187a0f375a622ce2aaa7 100644
--- a/api/register.go
+++ b/api/register.go
@@ -24,11 +24,11 @@ import (
"time"
)
-const SaltSize = 256
+const SaltSize = 32
//RegisterWithPermissioning registers the user and returns the User ID.
// Returns an error if registration fails.
-func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string) (*id.User, error) {
+func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string) (*id.ID, error) {
//Check the regState is in proper state for registration
if cl.session.GetRegState() != user.KeyGenComplete {
return nil, errors.Errorf("Attempting to register before key generation!")
@@ -45,11 +45,11 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
// Either perform a precanned registration for a precanned user
cl.opStatus(globals.REG_PRECAN)
globals.Log.INFO.Printf("Registering precanned user...")
- var nodeKeyMap map[id.Node]user.NodeKeys
+ var nodeKeyMap map[id.ID]user.NodeKeys
usr, UID, nodeKeyMap, err = cl.precannedRegister(registrationCode)
if err != nil {
globals.Log.ERROR.Printf("Unable to complete precanned registration: %+v", err)
- return id.ZeroID, err
+ return &id.ZeroUser, err
}
//overwrite the user object
@@ -70,7 +70,7 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
regValidationSignature, err = cl.registerWithPermissioning(registrationCode, cl.session.GetRSAPublicKey())
if err != nil {
globals.Log.INFO.Printf(err.Error())
- return id.ZeroID, err
+ return &id.ZeroUser, err
}
//update the session with the registration
err = cl.session.RegisterPermissioningSignature(regValidationSignature)
@@ -217,9 +217,12 @@ func (cl *Client) RegisterWithNodes() error {
for i := range cl.ndf.Gateways {
localI := i
- nodeID := *id.NewNodeFromBytes(cl.ndf.Nodes[i].ID)
+ nodeID, err := id.Unmarshal(cl.ndf.Nodes[i].ID)
+ if err != nil {
+ return err
+ }
//Register with node if the node has not been registered with already
- if _, ok := registeredNodes[nodeID]; !ok {
+ if _, ok := registeredNodes[*nodeID]; !ok {
wg.Add(1)
newRegistrations = true
go func() {
@@ -264,12 +267,16 @@ func (cl *Client) RegisterWithNodes() error {
//registerWithNode serves as a helper for RegisterWithNodes
// It registers a user with a specific in the client's ndf.
-func (cl *Client) registerWithNode(index int, salt, registrationValidationSignature []byte, UID *id.User,
+func (cl *Client) registerWithNode(index int, salt, registrationValidationSignature []byte, UID *id.ID,
publicKeyRSA *rsa.PublicKey, privateKeyRSA *rsa.PrivateKey,
cmixPublicKeyDH, cmixPrivateKeyDH *cyclic.Int,
cmixGrp *cyclic.Group, errorChan chan error) {
- gatewayID := id.NewNodeFromBytes(cl.ndf.Nodes[index].ID).NewGateway()
+ gatewayID, err := id.Unmarshal(cl.ndf.Gateways[index].ID)
+ if err != nil {
+ errorChan <- err
+ return
+ }
// Initialise blake2b hash for transmission keys and sha256 for reception
// keys
diff --git a/api/register_test.go b/api/register_test.go
index b36b0f93c39b0fa4e793f52594730f47ec0a98a1..f53dca59aaffbcf23d8dd9c1156efac166d6e0f2 100644
--- a/api/register_test.go
+++ b/api/register_test.go
@@ -11,7 +11,6 @@ import (
"gitlab.com/elixxir/client/user"
"gitlab.com/elixxir/comms/connect"
"gitlab.com/elixxir/primitives/id"
- "reflect"
"testing"
)
@@ -33,7 +32,7 @@ func TestRegistrationGob(t *testing.T) {
}
// populate a gob in the store
- _, err = testClient.RegisterWithPermissioning(true, "UAV6IWD6")
+ _, err = testClient.RegisterWithPermissioning(true, "WTROXJ33")
if err != nil {
t.Error(err)
}
@@ -76,7 +75,7 @@ func TestClient_Register(t *testing.T) {
}
// populate a gob in the store
- _, err = testClient.RegisterWithPermissioning(true, "UAV6IWD6")
+ _, err = testClient.RegisterWithPermissioning(true, "WTROXJ33")
if err != nil {
t.Error(err)
}
@@ -102,10 +101,10 @@ func TestClient_Register(t *testing.T) {
//Verify the user from the session make in the registration above matches expected user
func VerifyRegisterGobUser(session user.Session, t *testing.T) {
- expectedUser := id.NewUserFromUint(5, t)
+ expectedUser := id.NewIdFromUInt(5, id.User, t)
- if reflect.DeepEqual(session.GetCurrentUser().User, &expectedUser) {
- t.Errorf("Incorrect User ID; \n expected %q \n recieved: %q",
+ if !session.GetCurrentUser().User.Cmp(expectedUser) {
+ t.Errorf("Incorrect User ID; \n expected: %q \n recieved: %q",
expectedUser, session.GetCurrentUser().User)
}
}
@@ -153,7 +152,7 @@ func TestRegister_ValidRegParams___(t *testing.T) {
t.Errorf("Registration failed: %s", err.Error())
}
- if *regRes == *id.ZeroID {
+ if *regRes == *&id.ZeroUser {
t.Errorf("Invalid registration number received: %+v", *regRes)
}
err = client.RegisterWithNodes()
diff --git a/bindings/client.go b/bindings/client.go
index 746843b824a3c0e42c8f192adbc92d93ab91ef77..480a55fe8ec810be1e112cb91265b90f8e99d13f 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -35,12 +35,15 @@ type Client struct {
// messages sent from all users.
// If you pass the zero type (just zero) to Listen() you will hear messages of
// all types.
-func (cl *Client) Listen(userId []byte, messageType int32, newListener Listener) string {
- typedUserId := id.NewUserFromBytes(userId)
+func (cl *Client) Listen(userId []byte, messageType int32, newListener Listener) (string, error) {
+ typedUserId, err := id.Unmarshal(userId)
+ if err != nil {
+ return "", err
+ }
listener := &listenerProxy{proxy: newListener}
- return cl.client.Listen(typedUserId, messageType, listener)
+ return cl.client.Listen(typedUserId, messageType, listener), nil
}
// Pass the listener handle that Listen() returned to delete the listener
@@ -132,7 +135,7 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
UID, err := cl.client.RegisterWithPermissioning(preCan, registrationCode)
if err != nil {
- return id.ZeroID[:], err
+ return id.ZeroUser[:], err
}
return UID[:], nil
@@ -285,8 +288,14 @@ func (cl *Client) Send(m Message, encrypt bool) (int64, error) {
"MessageTye: %v", m.GetSender(), m.GetPayload(),
m.GetRecipient(), m.GetMessageType())
- sender := id.NewUserFromBytes(m.GetSender())
- recipient := id.NewUserFromBytes(m.GetRecipient())
+ sender, err := id.Unmarshal(m.GetSender())
+ if err != nil {
+ return 0, err
+ }
+ recipient, err := id.Unmarshal(m.GetRecipient())
+ if err != nil {
+ return 0, err
+ }
var cryptoType parse.CryptoType
if encrypt {
@@ -370,7 +379,10 @@ func (cl *Client) SearchForUser(username string,
func (cl *Client) DeleteContact(uid []byte) (string, error) {
globals.Log.INFO.Printf("Binding call: DeleteContact()\n"+
" uid: %v\n", uid)
- u := id.NewUserFromBytes(uid)
+ u, err := id.Unmarshal(uid)
+ if err != nil {
+ return "", err
+ }
return cl.client.DeleteUser(u)
}
@@ -379,10 +391,14 @@ func (cl *Client) DeleteContact(uid []byte) (string, error) {
// Non-blocking, once the API call completes, the callback function
// passed as argument is called
func (cl *Client) LookupNick(user []byte,
- cb NickLookupCallback) {
+ cb NickLookupCallback) error {
proxy := &nickCallbackProxy{cb}
- userID := id.NewUserFromBytes(user)
+ userID, err := id.Unmarshal(user)
+ if err != nil {
+ return err
+ }
cl.client.LookupNick(userID, proxy)
+ return nil
}
// Parses a passed message. Allows a message to be parsed using the internal parser
diff --git a/bindings/client_test.go b/bindings/client_test.go
index d578702bd67f978fbfc4ea34c139556086720b7b..360e7bbbafb445b41d60c7ff60b6dc869cb05a0d 100644
--- a/bindings/client_test.go
+++ b/bindings/client_test.go
@@ -36,7 +36,7 @@ const NumNodes = 3
const NumGWs = NumNodes
const GWsStartPort = 7950
const RegPort = 5100
-const ValidRegCode = "UAV6IWD6"
+const ValidRegCode = "WTROXJ33"
var RegHandler = MockRegistration{}
var RegComms *registration.Comms
@@ -52,7 +52,7 @@ func (i *MockRegistration) RegisterUser(registrationCode, test string) (hash []b
return nil, nil
}
-func (i *MockRegistration) RegisterNode(ID []byte, ServerAddr, ServerTlsCert,
+func (i *MockRegistration) RegisterNode(ID *id.ID, ServerAddr, ServerTlsCert,
GatewayAddr, GatewayTlsCert, RegistrationCode string) error {
return nil
}
@@ -358,12 +358,14 @@ func TestClient_Send(t *testing.T) {
t.Errorf("Could not start message reception: %+v", err)
}
+ receiverID := id.NewIdFromBytes(userID, t)
+ receiverID.SetType(id.User)
// Test send with invalid sender ID
_, err = testClient.Send(
mockMesssage{
- Sender: id.NewUserFromUint(12, t),
+ Sender: id.NewIdFromUInt(12, id.User, t),
TypedBody: parse.TypedBody{Body: []byte("test")},
- Receiver: id.NewUserFromBytes(userID),
+ Receiver: receiverID,
}, false)
if err != nil {
@@ -375,7 +377,7 @@ func TestClient_Send(t *testing.T) {
// Test send with valid inputs
_, err = testClient.Send(
mockMesssage{
- Sender: id.NewUserFromBytes(userID),
+ Sender: id.NewIdFromBytes(userID, t),
TypedBody: parse.TypedBody{Body: []byte("test")},
Receiver: testClient.client.GetCurrentUser(),
}, false)
@@ -468,13 +470,13 @@ func TestListen(t *testing.T) {
}
listener := MockListener(false)
- client.Listen(id.ZeroID[:], int32(cmixproto.Type_NO_TYPE), &listener)
+ client.Listen(id.ZeroUser[:], int32(cmixproto.Type_NO_TYPE), &listener)
client.client.GetSwitchboard().Speak(&parse.Message{
TypedBody: parse.TypedBody{
MessageType: 0,
Body: []byte("stuff"),
},
- Sender: id.ZeroID,
+ Sender: &id.ZeroUser,
Receiver: client.client.GetCurrentUser(),
})
time.Sleep(time.Second)
@@ -513,15 +515,18 @@ func TestStopListening(t *testing.T) {
}
listener := MockListener(false)
- handle := client.Listen(id.ZeroID[:], int32(cmixproto.Type_NO_TYPE), &listener)
+ handle, err := client.Listen(id.ZeroUser[:], int32(cmixproto.Type_NO_TYPE), &listener)
+ if err != nil {
+ t.Fatal(err)
+ }
client.StopListening(handle)
client.client.GetSwitchboard().Speak(&parse.Message{
TypedBody: parse.TypedBody{
MessageType: 0,
Body: []byte("stuff"),
},
- Sender: id.ZeroID,
- Receiver: id.ZeroID,
+ Sender: &id.ZeroUser,
+ Receiver: &id.ZeroUser,
})
if listener {
t.Error("Message was received after we stopped listening for it")
@@ -551,8 +556,8 @@ func TestParse(t *testing.T) {
ms := parse.Message{}
ms.Body = []byte{0, 1, 2}
ms.MessageType = int32(cmixproto.Type_NO_TYPE)
- ms.Receiver = id.ZeroID
- ms.Sender = id.ZeroID
+ ms.Receiver = &id.ZeroUser
+ ms.Sender = &id.ZeroUser
messagePacked := ms.Pack()
@@ -604,20 +609,29 @@ func testMainWrapper(m *testing.M) int {
def = getNDF()
// Initialize permissioning server
+ // TODO(nan) We shouldn't need to start registration servers twice, right?
pAddr := def.Registration.Address
- RegComms = registration.StartRegistrationServer("testRegServer", pAddr, &RegHandler, nil, nil)
+ regId := new(id.ID)
+ copy(regId[:], "testRegServer")
+ regId.SetType(id.Generic)
+ RegComms = registration.StartRegistrationServer(regId, pAddr,
+ &RegHandler, nil, nil)
// Start mock gateways used by registration and defer their shutdown (may not be needed)
//the ports used are colliding between tests in GoLand when running full suite, this is a dumb fix
bump := rand.Intn(10) * 10
for i := 0; i < NumGWs; i++ {
+ gwId := new(id.ID)
+ copy(gwId[:], "testGateway")
+ gwId.SetType(id.Gateway)
gw := ndf.Gateway{
+ ID: gwId.Marshal(),
Address: fmtAddress(GWsStartPort + i + bump),
}
def.Gateways = append(def.Gateways, gw)
- GWComms[i] = gateway.StartGateway("testGateway", gw.Address,
+ GWComms[i] = gateway.StartGateway(gwId, gw.Address,
gateway.NewImplementation(), nil, nil)
}
@@ -625,14 +639,15 @@ func testMainWrapper(m *testing.M) int {
def.Registration = ndf.Registration{
Address: fmtAddress(RegPort),
}
- RegComms = registration.StartRegistrationServer("testRegServer", def.Registration.Address,
+ RegComms = registration.StartRegistrationServer(regId, def.Registration.Address,
&RegHandler, nil, nil)
for i := 0; i < NumNodes; i++ {
- nIdBytes := make([]byte, id.NodeIdLen)
- nIdBytes[0] = byte(i)
+ nId := new(id.ID)
+ nId[0] = byte(i)
+ nId.SetType(id.Node)
n := ndf.Node{
- ID: nIdBytes,
+ ID: nId[:],
}
def.Nodes = append(def.Nodes, n)
}
@@ -749,8 +764,8 @@ type mockMesssage struct {
parse.TypedBody
// The crypto type is inferred from the message's contents
InferredType parse.CryptoType
- Sender *id.User
- Receiver *id.User
+ Sender *id.ID
+ Receiver *id.ID
Nonce []byte
Timestamp time.Time
}
diff --git a/bots/bots.go b/bots/bots.go
index b40537aa4beba5ad0f60caa04fff2a2ab57e600b..ed67cf578bf376836f0f17eb67f975c6a6f1c8d4 100644
--- a/bots/bots.go
+++ b/bots/bots.go
@@ -16,9 +16,6 @@ var topology *connect.Circuit
var comms io.Communications
var transmissionHost *connect.Host
-// UdbID is the ID of the user discovery bot, which is always 3
-var UdbID *id.User
-
type channelResponseListener chan string
func (l *channelResponseListener) Hear(msg switchboard.Item, isHeardElsewhere bool, i ...interface{}) {
@@ -50,9 +47,7 @@ func (l *nickReqListener) Hear(msg switchboard.Item, isHeardElsewhere bool, i ..
var nicknameRequestListener nickReqListener
// InitBots is called internally by the Login API
-func InitBots(s user.Session, m io.Communications, top *connect.Circuit, udbID *id.User, host *connect.Host) {
- UdbID = udbID
-
+func InitBots(s user.Session, m io.Communications, top *connect.Circuit, host *connect.Host) {
// FIXME: these all need to be used in non-blocking threads if we are
// going to do it this way...
msgBufSize := 100
@@ -70,30 +65,30 @@ func InitBots(s user.Session, m io.Communications, top *connect.Circuit, udbID *
l := session.GetSwitchboard()
- l.Register(UdbID, int32(cmixproto.Type_UDB_PUSH_KEY_RESPONSE),
+ l.Register(&id.UDB, int32(cmixproto.Type_UDB_PUSH_KEY_RESPONSE),
&pushKeyResponseListener)
- l.Register(UdbID, int32(cmixproto.Type_UDB_GET_KEY_RESPONSE),
+ l.Register(&id.UDB, int32(cmixproto.Type_UDB_GET_KEY_RESPONSE),
&getKeyResponseListener)
- l.Register(UdbID, int32(cmixproto.Type_UDB_REGISTER_RESPONSE),
+ l.Register(&id.UDB, int32(cmixproto.Type_UDB_REGISTER_RESPONSE),
®isterResponseListener)
- l.Register(UdbID, int32(cmixproto.Type_UDB_SEARCH_RESPONSE),
+ l.Register(&id.UDB, int32(cmixproto.Type_UDB_SEARCH_RESPONSE),
&searchResponseListener)
- l.Register(id.ZeroID,
+ l.Register(&id.ZeroUser,
int32(cmixproto.Type_NICKNAME_REQUEST), &nicknameRequestListener)
- l.Register(id.ZeroID,
+ l.Register(&id.ZeroUser,
int32(cmixproto.Type_NICKNAME_RESPONSE), &nicknameResponseListener)
}
// sendCommand sends a command to the udb. This doesn't block.
// Callers that need to wait on a response should implement waiting with a
// listener.
-func sendCommand(botID *id.User, command []byte) error {
+func sendCommand(botID *id.ID, command []byte) error {
return comms.SendMessage(session, topology, botID,
parse.Unencrypted, command, transmissionHost)
}
// Nickname Lookup function
-func LookupNick(user *id.User) (string, error) {
+func LookupNick(user *id.ID) (string, error) {
globals.Log.DEBUG.Printf("Sending nickname request to user %v", *user)
msg := parse.Pack(&parse.TypedBody{
MessageType: int32(cmixproto.Type_NICKNAME_REQUEST),
diff --git a/bots/bots_test.go b/bots/bots_test.go
index c6628b29a78cb425298a2c25b60df832a40f9b52..e381417c7f671f2dfe45f371d07d2ddca97a1e10 100644
--- a/bots/bots_test.go
+++ b/bots/bots_test.go
@@ -9,6 +9,7 @@ package bots
import (
"encoding/base64"
+ "encoding/binary"
"fmt"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
@@ -36,7 +37,7 @@ type dummyMessaging struct {
// SendMessage to the server
func (d *dummyMessaging) SendMessage(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
jww.INFO.Printf("Sending: %s", string(message))
@@ -46,7 +47,7 @@ func (d *dummyMessaging) SendMessage(sess user.Session,
// SendMessage without partitions to the server
func (d *dummyMessaging) SendMessageNoPartition(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
jww.INFO.Printf("Sending: %s", string(message))
@@ -64,9 +65,11 @@ var pubKey []byte
func TestMain(m *testing.M) {
u := &user.User{
- User: id.NewUserFromUints(&[4]uint64{0, 0, 0, 18}),
+ User: new(id.ID),
Username: "Bernie",
}
+ binary.BigEndian.PutUint64(u.User[:], 18)
+ u.User.SetType(id.User)
cmixGrp, e2eGrp := getGroups()
@@ -78,9 +81,11 @@ func TestMain(m *testing.M) {
listener: ListenCh,
}
h := connect.Host{}
- topology := connect.NewCircuit([]*id.Node{id.NewNodeFromBytes(make([]byte, id.NodeIdLen))})
+ nodeID := new(id.ID)
+ nodeID.SetType(id.Node)
+ topology := connect.NewCircuit([]*id.ID{nodeID})
- InitBots(fakeSession, fakeComm, topology, id.NewUserFromBytes([]byte("testid")), &h)
+ InitBots(fakeSession, fakeComm, topology, &h)
// Make the reception channels buffered for this test
// which overwrites the channels registered in InitBots
@@ -121,9 +126,14 @@ func TestRegister(t *testing.T) {
// TestSearch smoke tests the search function
func TestSearch(t *testing.T) {
publicKeyString := base64.StdEncoding.EncodeToString(pubKey)
+ //uid := id.NewIdFromUInt(26, id.User, t)
+ //serRetUid := base64.StdEncoding.EncodeToString(uid[:])
+ //result, _ := base64.StdEncoding.DecodeString(serRetUid)
+ //t.Fatal(serRetUid)
+ //t.Fatal(len(result))
// Send response messages from fake UDB in advance
- searchResponseListener <- "blah@elixxir.io FOUND UR69db14ZyicpZVqJ1HFC5rk9UZ8817aV6+VHmrJpGc= AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABo= 8oKh7TYG4KxQcBAymoXPBHSD/uga9pX3Mn/jKhvcD8M="
+ searchResponseListener <- "blah@elixxir.io FOUND UR69db14ZyicpZVqJ1HFC5rk9UZ8817aV6+VHmrJpGc= AAAAAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD 8oKh7TYG4KxQcBAymoXPBHSD/uga9pX3Mn/jKhvcD8M="
getKeyResponseListener <- fmt.Sprintf("GETKEY %s %s", keyFingerprint,
publicKeyString)
@@ -136,8 +146,8 @@ func TestSearch(t *testing.T) {
if err != nil {
t.Errorf("Error on Search: %s", err.Error())
}
- if *searchedUser != *id.NewUserFromUint(26, t) {
- t.Errorf("Search did not return user ID 26! returned %v", string(searchedUser.Bytes()))
+ if !searchedUser.Cmp(id.NewIdFromUInt(26, id.User, t)) {
+ t.Errorf("Search did not return user ID 26! returned %s", searchedUser)
}
//Test the timeout capabilities
searchedUser, _, err = Search("EMAIL", "blah@elixxir.io", dummySearchState, 1*time.Millisecond)
@@ -190,7 +200,7 @@ type errorMessaging struct{}
// SendMessage that just errors out
func (e *errorMessaging) SendMessage(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
return errors.New("This is an error")
@@ -199,7 +209,7 @@ func (e *errorMessaging) SendMessage(sess user.Session,
// SendMessage no partition that just errors out
func (e *errorMessaging) SendMessageNoPartition(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
return errors.New("This is an error")
diff --git a/bots/userDiscovery.go b/bots/userDiscovery.go
index 35cd3970051e04839b5fb406536147f804d18b90..d84976c955d24e3814939419a7d3c8541dae07fc 100644
--- a/bots/userDiscovery.go
+++ b/bots/userDiscovery.go
@@ -46,7 +46,7 @@ func Register(valueType, value string, publicKey []byte, regStatus func(int), ti
regStatus(globals.UDB_REG_PUSHKEY)
// push key and error if it already exists
- err = pushKey(UdbID, keyFP, publicKey)
+ err = pushKey(keyFP, publicKey)
if err != nil {
return errors.Wrap(err, "Could not PUSHKEY")
@@ -84,7 +84,7 @@ func Register(valueType, value string, publicKey []byte, regStatus func(int), ti
// Send register command
// Send register command
- err = sendCommand(UdbID, msgBody)
+ err = sendCommand(&id.UDB, msgBody)
if err != nil {
return errors.Wrap(err, "Could not Push User")
}
@@ -114,7 +114,7 @@ func Register(valueType, value string, publicKey []byte, regStatus func(int), ti
// Search returns a userID and public key based on the search criteria
// it accepts a valueType of EMAIL and value of an e-mail address, and
// returns a map of userid -> public key
-func Search(valueType, value string, searchStatus func(int), timeout time.Duration) (*id.User, []byte, error) {
+func Search(valueType, value string, searchStatus func(int), timeout time.Duration) (*id.ID, []byte, error) {
globals.Log.DEBUG.Printf("Running search for %v, %v", valueType, value)
searchTimeout := time.NewTimer(timeout)
@@ -133,7 +133,7 @@ func Search(valueType, value string, searchStatus func(int), timeout time.Durati
MessageType: int32(cmixproto.Type_UDB_SEARCH),
Body: []byte(fmt.Sprintf("%s %s", valueType, value)),
})
- err = sendCommand(UdbID, msgBody)
+ err = sendCommand(&id.UDB, msgBody)
if err != nil {
return nil, nil, err
}
@@ -160,9 +160,9 @@ func Search(valueType, value string, searchStatus func(int), timeout time.Durati
}
// While search returns more than 1 result, we only process the first
- cMixUID, keyFP := parseSearch(response)
- if *cMixUID == *id.ZeroID {
- return nil, nil, fmt.Errorf("%s", keyFP)
+ cMixUID, keyFP, err := parseSearch(response)
+ if err != nil {
+ return nil, nil, err
}
searchStatus(globals.UDB_SEARCH_GETKEY)
@@ -172,7 +172,7 @@ func Search(valueType, value string, searchStatus func(int), timeout time.Durati
MessageType: int32(cmixproto.Type_UDB_GET_KEY),
Body: []byte(keyFP),
})
- err = sendCommand(UdbID, msgBody)
+ err = sendCommand(&id.UDB, msgBody)
if err != nil {
return nil, nil, err
}
@@ -221,20 +221,23 @@ func hashAndEncode(s string) (string, error) {
// parseSearch parses the responses from SEARCH. It returns the user's id and
// the user's public key fingerprint
-func parseSearch(msg string) (*id.User, string) {
+func parseSearch(msg string) (*id.ID, string, error) {
globals.Log.DEBUG.Printf("Parsing search response: %v", msg)
resParts := strings.Split(msg, " ")
if len(resParts) != 5 {
- return id.ZeroID, fmt.Sprintf("Invalid response from search: %s", msg)
+ return &id.ZeroUser, "", errors.WithMessagef(errors.New("Invalid response from search"), ": %s", msg)
}
cMixUIDBytes, err := base64.StdEncoding.DecodeString(resParts[3])
if err != nil {
- return id.ZeroID, fmt.Sprintf("Couldn't parse search cMix UID: %s", msg)
+ return &id.ZeroUser, "", errors.WithMessagef(errors.New("Couldn't parse search cMix UID"), ": %s", msg)
+ }
+ cMixUID, err := id.Unmarshal(cMixUIDBytes)
+ if err != nil {
+ return &id.ZeroUser, "", err
}
- cMixUID := id.NewUserFromBytes(cMixUIDBytes)
- return cMixUID, resParts[4]
+ return cMixUID, resParts[4], nil
}
// parseGetKey parses the responses from GETKEY. It returns the
@@ -254,14 +257,14 @@ func parseGetKey(msg string) []byte {
}
// pushKey uploads the users' public key
-func pushKey(udbID *id.User, keyFP string, publicKey []byte) error {
+func pushKey(keyFP string, publicKey []byte) error {
publicKeyString := base64.StdEncoding.EncodeToString(publicKey)
- globals.Log.DEBUG.Printf("Running pushkey for %q, %v, %v", *udbID, keyFP,
+ globals.Log.DEBUG.Printf("Running pushkey for %v, %v, %v", id.UDB, keyFP,
publicKeyString)
pushKeyMsg := fmt.Sprintf("%s %s", keyFP, publicKeyString)
- return sendCommand(udbID, parse.Pack(&parse.TypedBody{
+ return sendCommand(&id.UDB, parse.Pack(&parse.TypedBody{
MessageType: int32(cmixproto.Type_UDB_PUSH_KEY),
Body: []byte(pushKeyMsg),
}))
diff --git a/cmd/root.go b/cmd/root.go
index cb96a47e6beb53eab7f7a32220b25040a8f4bdc2..51365f25d5f59c4d7d580bd5ccc87af1b90912cc 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -9,13 +9,13 @@ package cmd
import (
"encoding/base64"
+ "encoding/binary"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper"
"gitlab.com/elixxir/client/api"
- "gitlab.com/elixxir/client/bots"
"gitlab.com/elixxir/client/cmixproto"
"gitlab.com/elixxir/client/globals"
"gitlab.com/elixxir/client/parse"
@@ -69,7 +69,7 @@ func Execute() {
}
}
-func sessionInitialization() (*id.User, string, *api.Client) {
+func sessionInitialization() (*id.ID, string, *api.Client) {
var err error
register := false
@@ -111,7 +111,7 @@ func sessionInitialization() (*id.User, string, *api.Client) {
if err != nil {
globals.Log.ERROR.Printf("Could Not Initialize Ram Storage: %s\n",
err.Error())
- return id.ZeroID, "", nil
+ return &id.ZeroUser, "", nil
}
globals.Log.INFO.Println("Initialized Ram Storage")
register = true
@@ -141,14 +141,14 @@ func sessionInitialization() (*id.User, string, *api.Client) {
//Fail if any other error is received
globals.Log.ERROR.Printf("Error with file paths: %s %s",
err1, err2)
- return id.ZeroID, "", nil
+ return &id.ZeroUser, "", nil
}
}
//Initialize client with OS Storage
client, err = api.NewClient(nil, sessionA, sessionB, ndfJSON)
if err != nil {
globals.Log.ERROR.Printf("Could Not Initialize OS Storage: %s\n", err.Error())
- return id.ZeroID, "", nil
+ return &id.ZeroUser, "", nil
}
globals.Log.INFO.Println("Initialized OS Storage")
@@ -169,7 +169,7 @@ func sessionInitialization() (*id.User, string, *api.Client) {
// No gateways in config file or passed via command line
globals.Log.ERROR.Printf("Error: No gateway specified! Add to" +
" configuration file or pass via command line using -g!\n")
- return id.ZeroID, "", nil
+ return &id.ZeroUser, "", nil
}*/
if noTLS {
@@ -185,7 +185,7 @@ func sessionInitialization() (*id.User, string, *api.Client) {
client.SetRateLimiting(rateLimiting)
// Holds the User ID
- var uid *id.User
+ var uid *id.ID
// Register a new user if requested
if register {
@@ -195,7 +195,10 @@ func sessionInitialization() (*id.User, string, *api.Client) {
// If precanned user, use generated code instead
if userId != 0 {
precanned = true
- regCode = id.NewUserFromUints(&[4]uint64{0, 0, 0, userId}).RegistrationCode()
+ uid := new(id.ID)
+ binary.BigEndian.PutUint64(uid[:], userId)
+ uid.SetType(id.User)
+ regCode = user.RegistrationCode(uid)
}
globals.Log.INFO.Printf("Building keys...")
@@ -248,7 +251,9 @@ func sessionInitialization() (*id.User, string, *api.Client) {
} else {
// hack for session persisting with cmd line
// doesn't support non pre canned users
- uid = id.NewUserFromUints(&[4]uint64{0, 0, 0, userId})
+ uid := new(id.ID)
+ binary.BigEndian.PutUint64(uid[:], userId)
+ uid.SetType(id.User)
globals.Log.INFO.Printf("Skipped Registration, user: %v", uid)
}
@@ -406,11 +411,11 @@ var rootCmd = &cobra.Command{
// the integration test
// Normal text messages
text := TextListener{}
- client.Listen(id.ZeroID, int32(cmixproto.Type_TEXT_MESSAGE),
+ client.Listen(&id.ZeroUser, int32(cmixproto.Type_TEXT_MESSAGE),
&text)
// All other messages
fallback := FallbackListener{}
- client.Listen(id.ZeroID, int32(cmixproto.Type_NO_TYPE),
+ client.Listen(&id.ZeroUser, int32(cmixproto.Type_NO_TYPE),
&fallback)
// Log the user in, for now using the first gateway specified
@@ -422,7 +427,7 @@ var rootCmd = &cobra.Command{
err = client.InitListeners()
if err != nil {
- globals.Log.FATAL.Panicf("Could not initialize receivers: %s\n", err)
+ globals.Log.FATAL.Panicf("Could not initialize receivers: %+v\n", err)
}
err = client.StartMessageReceiver(cb)
@@ -447,7 +452,7 @@ var rootCmd = &cobra.Command{
cryptoType = parse.E2E
}
- var recipientId *id.User
+ var recipientId *id.ID
if destinationUserId != 0 && destinationUserIDBase64 != "" {
globals.Log.FATAL.Panicf("Two destiantions set for the message, can only have one")
@@ -460,10 +465,15 @@ var rootCmd = &cobra.Command{
if err != nil {
globals.Log.FATAL.Panic("Could not decode the destination user ID")
}
- recipientId = id.NewUserFromBytes(recipientIdBytes)
-
+ recipientId, err = id.Unmarshal(recipientIdBytes)
+ if err != nil {
+ // Destination user ID must be 33 bytes and include the id type
+ globals.Log.FATAL.Panicf("Could not unmarshal destination user ID: %v", err)
+ }
} else {
- recipientId = id.NewUserFromUints(&[4]uint64{0, 0, 0, destinationUserId})
+ recipientId = new(id.ID)
+ binary.BigEndian.PutUint64(recipientId[:], destinationUserId)
+ recipientId.SetType(id.User)
}
if message != "" {
@@ -475,7 +485,7 @@ var rootCmd = &cobra.Command{
}
// Handle sending to UDB
- if *recipientId == *bots.UdbID {
+ if recipientId.Cmp(&id.UDB) {
parseUdbMessage(message, client)
} else {
// Handle sending to any other destination
@@ -579,7 +589,7 @@ var rootCmd = &cobra.Command{
}
func isValidUser(usr []byte) bool {
- if len(usr) != id.UserLen {
+ if len(usr) != id.ArrIDLen {
return false
}
for _, b := range usr {
diff --git a/cmd/udb.go b/cmd/udb.go
index 3b234d6e06ff687e219ccfff9c4c22e4ab1a1e83..ed39e5d8be21880cc3b3540c64d214c8f6e87b12 100644
--- a/cmd/udb.go
+++ b/cmd/udb.go
@@ -22,8 +22,12 @@ func (cs callbackSearch) Callback(userID, pubKey []byte, err error) {
} else if len(pubKey) == 0 {
globals.Log.INFO.Printf("Public Key returned is empty\n")
} else {
+ userID, err := id.Unmarshal(userID)
+ if err != nil {
+ globals.Log.ERROR.Printf("Malformed user ID from successful UDB search: %v", err)
+ }
globals.Log.INFO.Printf("UDB search successful. Returned user %v\n",
- *id.NewUserFromBytes(userID))
+ userID)
}
}
diff --git a/crypto/encryptdecrypt_test.go b/crypto/encryptdecrypt_test.go
index b94d74a3d5b720ca85259f8e9eaf1fcbbd3a31c3..6e899bfe3f1fe8902e4f24339ed95ad115788518 100644
--- a/crypto/encryptdecrypt_test.go
+++ b/crypto/encryptdecrypt_test.go
@@ -8,6 +8,7 @@ package crypto
import (
"bytes"
+ "encoding/binary"
"gitlab.com/elixxir/client/user"
"gitlab.com/elixxir/comms/connect"
pb "gitlab.com/elixxir/comms/mixmessages"
@@ -40,16 +41,21 @@ func setup() {
user.InitUserRegistry(cmixGrp)
- UID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 18})
- u, _ := user.Users.GetUser(UID)
+ UID := new(id.ID)
+ binary.BigEndian.PutUint64(UID[:], 18)
+ UID.SetType(id.User)
+ u, ok := user.Users.GetUser(UID)
+ if !ok {
+ panic("Didn't get user 18 from registry")
+ }
- var nodeSlice []*id.Node
+ var nodeSlice []*id.ID
//build topology
for i := 0; i < numNodes; i++ {
- nodeBytes := make([]byte, id.NodeIdLen)
- nodeBytes[0] = byte(i)
- nodeId := id.NewNodeFromBytes(nodeBytes)
+ nodeId := new(id.ID)
+ nodeId[0] = byte(i)
+ nodeId.SetType(id.Node)
nodeSlice = append(nodeSlice, nodeId)
}
@@ -93,8 +99,8 @@ func TestMain(m *testing.M) {
func TestFullEncryptDecrypt(t *testing.T) {
cmixGrp, e2eGrp := getGroups()
- sender := id.NewUserFromUint(38, t)
- recipient := id.NewUserFromUint(29, t)
+ sender := id.NewIdFromUInt(38, id.User, t)
+ recipient := id.NewIdFromUInt(29, id.User, t)
msg := format.NewMessage()
msg.SetRecipient(recipient)
msgPayload := []byte("help me, i'm stuck in an" +
@@ -141,9 +147,14 @@ func TestFullEncryptDecrypt(t *testing.T) {
t.Errorf("E2EDecrypt returned error: %v", err.Error())
}
- if *decMsg.GetRecipient() != *recipient {
+ decryptedRecipient, err := decMsg.GetRecipient()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !decryptedRecipient.Cmp(recipient) {
t.Errorf("Recipient differed from expected: Got %q, expected %q",
- decMsg.GetRecipient(), sender)
+ decryptedRecipient, sender)
}
if !bytes.Equal(decMsg.Contents.GetRightAligned(), msgPayload) {
t.Errorf("Decrypted payload differed from expected: Got %q, "+
@@ -155,8 +166,8 @@ func TestFullEncryptDecrypt(t *testing.T) {
// to be sent occupies the whole payload structure, i.e. 256 bytes
func TestFullEncryptDecrypt_Unsafe(t *testing.T) {
cmixGrp, e2eGrp := getGroups()
- sender := id.NewUserFromUint(38, t)
- recipient := id.NewUserFromUint(29, t)
+ sender := id.NewIdFromUInt(38, id.User, t)
+ recipient := id.NewIdFromUInt(29, id.User, t)
msg := format.NewMessage()
msg.SetRecipient(recipient)
msgPayload := []byte(
@@ -212,9 +223,14 @@ func TestFullEncryptDecrypt_Unsafe(t *testing.T) {
t.Errorf("E2EDecryptUnsafe returned error: %v", err.Error())
}
- if *decMsg.GetRecipient() != *recipient {
+ decryptedRecipient, err := decMsg.GetRecipient()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !decryptedRecipient.Cmp(recipient) {
t.Errorf("Recipient differed from expected: Got %q, expected %q",
- decMsg.GetRecipient(), sender)
+ decryptedRecipient, sender)
}
if !bytes.Equal(decMsg.Contents.Get(), msgPayload[:format.ContentsLen]) {
t.Errorf("Decrypted payload differed from expected: Got %q, "+
@@ -225,7 +241,7 @@ func TestFullEncryptDecrypt_Unsafe(t *testing.T) {
// Test that E2EEncrypt panics if the payload is too big (can't be padded)
func TestE2EEncrypt_Panic(t *testing.T) {
_, e2eGrp := getGroups()
- recipient := id.NewUserFromUint(29, t)
+ recipient := id.NewIdFromUInt(29, id.User, t)
msg := format.NewMessage()
msg.SetRecipient(recipient)
msgPayload := []byte("help me, i'm stuck in an" +
@@ -258,7 +274,7 @@ func TestE2EEncrypt_Panic(t *testing.T) {
// Test that E2EDecrypt and E2EDecryptUnsafe handle errors correctly
func TestE2EDecrypt_Errors(t *testing.T) {
_, e2eGrp := getGroups()
- recipient := id.NewUserFromUint(29, t)
+ recipient := id.NewIdFromUInt(29, id.User, t)
msg := format.NewMessage()
msg.SetRecipient(recipient)
msgPayload := []byte("help me, i'm stuck in an EnterpriseTextLabelDescriptorSetPipelineStateFactoryBeanFactory ")
diff --git a/go.mod b/go.mod
index 66bd3d8f52c113ae6b159c607bc9083ec9911673..bc2fcec747168b37f3414ca3e0896a03b56ec403 100644
--- a/go.mod
+++ b/go.mod
@@ -15,9 +15,9 @@ require (
github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
- gitlab.com/elixxir/comms v0.0.0-20200513163847-4975a4118ac6
- gitlab.com/elixxir/crypto v0.0.0-20200513163659-38b6079db0b2
- gitlab.com/elixxir/primitives v0.0.0-20200513162412-ef77445c0ab7
+ gitlab.com/elixxir/comms v0.0.0-20200513205425-e2f1a300e61b
+ gitlab.com/elixxir/crypto v0.0.0-20200513205206-8be446a9ccbe
+ gitlab.com/elixxir/primitives v0.0.0-20200514163806-e7b4d77801d8
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
gopkg.in/ini.v1 v1.52.0 // indirect
)
diff --git a/go.sum b/go.sum
index b54504a99cf65ac325e04fe1b1d731412f212dd7..f03ddb59ece241b418692274b381330ec08eea8a 100644
--- a/go.sum
+++ b/go.sum
@@ -149,15 +149,23 @@ gitlab.com/elixxir/comms v0.0.0-20200415204952-6d63dd94a0ea h1:LVQuXjq26hjnuw2is
gitlab.com/elixxir/comms v0.0.0-20200415204952-6d63dd94a0ea/go.mod h1:EeRHiSIfVYqTaMZGb6eE2kz1Rw5zGXuuBow4Pi2VFg0=
gitlab.com/elixxir/comms v0.0.0-20200513163847-4975a4118ac6 h1:k+loYgTu4fN12Dmypu8OSZ8mQCBUxJQI29In5gaDHo4=
gitlab.com/elixxir/comms v0.0.0-20200513163847-4975a4118ac6/go.mod h1:zuYjqakP4b5rYtgeAra5SAHV87FRym9eEa8dwDVdNuU=
+gitlab.com/elixxir/comms v0.0.0-20200513205425-e2f1a300e61b h1:Qw79tx+dZdvwMUGyet1+6d0dqltSX96aAH9E1NkM2fQ=
+gitlab.com/elixxir/comms v0.0.0-20200513205425-e2f1a300e61b/go.mod h1:+RnENZCq2ca+Z/16CVUgzWUcuSLYJ7Q0L0zaBTbmOCQ=
gitlab.com/elixxir/crypto v0.0.0-20200410231849-90e859940f5d h1:+g7tGMO3g20Su3pdTJg30n5XhEGZ3avEd4ccN33CtdU=
gitlab.com/elixxir/crypto v0.0.0-20200410231849-90e859940f5d/go.mod h1:QPClJr3F90ejz6iHaCZuhexytd6PP97dDnt93iRCTDo=
gitlab.com/elixxir/crypto v0.0.0-20200513163659-38b6079db0b2 h1:dqWdpifXovXXk2egHeh3FQFqB3IlcIurL+A+ziFFbU0=
gitlab.com/elixxir/crypto v0.0.0-20200513163659-38b6079db0b2/go.mod h1:9BCEQtgddrCHt/QONWD+nU1n6iZ+qfc89GnzSVHA97I=
+gitlab.com/elixxir/crypto v0.0.0-20200513205206-8be446a9ccbe h1:+/HzwQH5JpQegzi/K1qeUSTwkaIYiT3V3rKb3uq5WO4=
+gitlab.com/elixxir/crypto v0.0.0-20200513205206-8be446a9ccbe/go.mod h1:zs5oaFHiZEcKBR2O5cuG3Wip4Nozl60MVhsw1X44bDU=
gitlab.com/elixxir/primitives v0.0.0-20200218211222-4193179f359c/go.mod h1:REJMcwIcyxh74VSHqy4S9yYiaEsQYObOPglRExDpk14=
gitlab.com/elixxir/primitives v0.0.0-20200410231944-a57d71d577c9 h1:KP/BQqOrLcoCah24VHzQBY8EbQHvBcsrhz/Yjs6vn4Y=
gitlab.com/elixxir/primitives v0.0.0-20200410231944-a57d71d577c9/go.mod h1:nqC90Tt1jLDd2e35hVWCmTynTXBBEt3UfaSsIhHevmc=
gitlab.com/elixxir/primitives v0.0.0-20200513162412-ef77445c0ab7 h1:XY7jcsaqkM60c0TFrPyxfPam1hlM1oYGq/wlCk1GKUM=
gitlab.com/elixxir/primitives v0.0.0-20200513162412-ef77445c0ab7/go.mod h1:uc1rmOIN/Cg6WsTtIz7vu/ezxHqqFRiDEvBeFM/tMjM=
+gitlab.com/elixxir/primitives v0.0.0-20200513204643-8f8798f26218 h1:DYJfIK6xSAbAgKrHhCG0BJwadb1csueo881KLuRiw3I=
+gitlab.com/elixxir/primitives v0.0.0-20200513204643-8f8798f26218/go.mod h1:uc1rmOIN/Cg6WsTtIz7vu/ezxHqqFRiDEvBeFM/tMjM=
+gitlab.com/elixxir/primitives v0.0.0-20200514163806-e7b4d77801d8 h1:0lfMMEgILkkdmOPDEl2zGzx9i7LbG0zVS1NdLrmcBNU=
+gitlab.com/elixxir/primitives v0.0.0-20200514163806-e7b4d77801d8/go.mod h1:uc1rmOIN/Cg6WsTtIz7vu/ezxHqqFRiDEvBeFM/tMjM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
diff --git a/io/collate.go b/io/collate.go
index 0f4ec1e49cdbe270b03538719e8ee94412b613a9..c2d74635ed915576f807767f4f17d065e5b928aa 100644
--- a/io/collate.go
+++ b/io/collate.go
@@ -47,16 +47,19 @@ func NewCollator() *Collator {
// TODO this takes too many types. i should split it up.
// This method returns a byte slice with the assembled message if it's
// received a completed message.
-func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
- timeout time.Duration) *parse.Message {
+func (mb *Collator) AddMessage(message *format.Message, sender *id.ID,
+ timeout time.Duration) (*parse.Message, error) {
payload := message.Contents.GetRightAligned()
- recipient := message.GetRecipient()
+ recipient, err := message.GetRecipient()
+ if err != nil {
+ return nil, err
+ }
//get the time
timestamp := time.Time{}
- err := timestamp.UnmarshalBinary(message.GetTimestamp()[:len(message.GetTimestamp())-1])
+ err = timestamp.UnmarshalBinary(message.GetTimestamp()[:len(message.GetTimestamp())-1])
if err != nil {
globals.Log.WARN.Printf("Failed to parse timestamp for message %v: %+v",
@@ -65,15 +68,16 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
partition, err := parse.ValidatePartition(payload)
- if err == nil {
+ if err != nil {
+ return nil, errors.WithMessage(err, "Received an invalid partition: ")
+ } else {
if partition.MaxIndex == 0 {
//this is the only part of the message. we should take the fast
//path and skip putting it in the map
typedBody, err := parse.Parse(partition.Body)
// Log an error if the message is malformed and return nothing
if err != nil {
- globals.Log.ERROR.Printf("Malformed message received")
- return nil
+ return nil, errors.WithMessage(err, "Malformed message received")
}
msg := parse.Message{
@@ -84,7 +88,7 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
Timestamp: timestamp,
}
- return &msg
+ return &msg, nil
} else {
// assemble the map key into a new chunk of memory
var key PendingMessageKey
@@ -95,6 +99,7 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
copy(key[:], keyHash[:PendingMessageKeyLen])
mb.mux.Lock()
+ defer mb.mux.Unlock()
message, ok := mb.pendingMessages[key]
if !ok {
// this is a multi-part message we haven't seen before.
@@ -113,11 +118,11 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
// TODO vary timeout depending on number of messages?
time.AfterFunc(timeout, func() {
mb.mux.Lock()
+ defer mb.mux.Unlock()
_, ok := mb.pendingMessages[key]
if ok {
delete(mb.pendingMessages, key)
}
- mb.mux.Unlock()
})
} else {
// append to array for this key
@@ -129,17 +134,13 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
fullMsg, err := parse.Assemble(message.parts)
if err != nil {
delete(mb.pendingMessages, key)
- mb.mux.Unlock()
- globals.Log.ERROR.Printf("Malformed message: Padding error, %v", err.Error())
- return nil
+ return nil, errors.WithMessage(err, "Malformed message: padding error, ")
}
typedBody, err := parse.Parse(fullMsg)
// Log an error if the message is malformed and return nothing
if err != nil {
delete(mb.pendingMessages, key)
- mb.mux.Unlock()
- globals.Log.ERROR.Printf("Malformed message Received")
- return nil
+ return nil, errors.WithMessage(err, "Malformed message received")
}
msg := parse.Message{
@@ -151,16 +152,13 @@ func (mb *Collator) AddMessage(message *format.Message, sender *id.User,
}
delete(mb.pendingMessages, key)
- mb.mux.Unlock()
- return &msg
+ return &msg, nil
+ } else {
+ // need more parts
+ return nil, nil
}
- mb.mux.Unlock()
}
- } else {
- globals.Log.ERROR.Printf("Received an invalid partition: %v\n", err.Error())
}
- globals.Log.DEBUG.Printf("Message collator: %v", mb.dump())
- return nil
}
// Debug: dump all messages that are currently in the map
diff --git a/io/collate_test.go b/io/collate_test.go
index 6bf301fb530803bc1586639ab798bb07b4584220..274497f2519a478511de3c8f24ceffd1d2bb5195 100644
--- a/io/collate_test.go
+++ b/io/collate_test.go
@@ -19,7 +19,7 @@ import (
func TestCollator_AddMessage(t *testing.T) {
- uid := id.NewUserFromUint(69, t)
+ uid := id.NewIdFromUInt(69, id.User, t)
collator := &Collator{
pendingMessages: make(map[PendingMessageKey]*multiPartMessage),
@@ -44,10 +44,13 @@ func TestCollator_AddMessage(t *testing.T) {
for j := range partitions {
fm := format.NewMessage()
- fm.SetRecipient(id.NewUserFromUint(6, t))
+ fm.SetRecipient(id.NewIdFromUInt(6, id.User, t))
fm.Contents.SetRightAligned(partitions[j])
- result = collator.AddMessage(fm, uid, time.Minute)
+ result, err = collator.AddMessage(fm, uid, time.Minute)
+ if err != nil {
+ t.Fatal(err)
+ }
}
typedBody, err := parse.Parse(bodies[i])
@@ -66,7 +69,7 @@ func TestCollator_AddMessage(t *testing.T) {
func TestCollator_AddMessage_Timeout(t *testing.T) {
- uid := id.NewUserFromUint(69, t)
+ uid := id.NewIdFromUInt(69, id.User, t)
collator := &Collator{
pendingMessages: make(map[PendingMessageKey]*multiPartMessage),
@@ -84,10 +87,13 @@ func TestCollator_AddMessage_Timeout(t *testing.T) {
nowBytes, _ := now.MarshalBinary()
nowBytes = append(nowBytes, make([]byte, format.TimestampLen-len(nowBytes))...)
fm.SetTimestamp(nowBytes)
- fm.SetRecipient(id.NewUserFromUint(6, t))
+ fm.SetRecipient(id.NewIdFromUInt(6, id.User, t))
fm.Contents.SetRightAligned(partitions[i])
- result = collator.AddMessage(fm, uid, 80*time.Millisecond)
+ result, err = collator.AddMessage(fm, uid, 80*time.Millisecond)
+ if err != nil {
+ t.Fatal(err)
+ }
if result != nil {
t.Error("Got a result from collator when it should be timing out" +
" submessages")
diff --git a/io/interface.go b/io/interface.go
index 1aaf3ce3b57bec5b6ba485da40fe69e906c0e591..c0e0673e7bde79e83486efe9c87ace3de7a8b102 100644
--- a/io/interface.go
+++ b/io/interface.go
@@ -20,12 +20,12 @@ type Communications interface {
// TODO(nen) Can we get rid of the crypto type param here?
SendMessage(session user.Session, topology *connect.Circuit,
- recipientID *id.User, cryptoType parse.CryptoType, message []byte,
+ recipientID *id.ID, cryptoType parse.CryptoType, message []byte,
transmissionHost *connect.Host) error
// SendMessage without partitions to the server
// This is used to send rekey messages
SendMessageNoPartition(session user.Session, topology *connect.Circuit,
- recipientID *id.User, cryptoType parse.CryptoType, message []byte,
+ recipientID *id.ID, cryptoType parse.CryptoType, message []byte,
transmissionHost *connect.Host) error
// MessageReceiver thread to get new messages
MessageReceiver(session user.Session, delay time.Duration,
diff --git a/io/receive.go b/io/receive.go
index 49c1cddd7f888bc3785a27aa64eeb0adbec425ad..a59d2498a18e32db04db943180cd78f5f5aaf03c 100644
--- a/io/receive.go
+++ b/io/receive.go
@@ -100,8 +100,11 @@ func (rm *ReceptionManager) MessageReceiver(session user.Session, delay time.Dur
if decryptedMessages != nil {
for i := range decryptedMessages {
// TODO Handle messages that do not need partitioning
- assembledMessage := rm.collator.AddMessage(decryptedMessages[i],
+ assembledMessage, err := rm.collator.AddMessage(decryptedMessages[i],
senders[i], time.Minute)
+ if err != nil {
+ go callback(err)
+ }
if assembledMessage != nil {
// we got a fully assembled message. let's broadcast it
broadcastMessageReception(assembledMessage, session.GetSwitchboard())
@@ -113,7 +116,7 @@ func (rm *ReceptionManager) MessageReceiver(session user.Session, delay time.Dur
}
func handleE2EReceiving(session user.Session,
- message *format.Message) (*id.User, bool, error) {
+ message *format.Message) (*id.ID, bool, error) {
keyFingerprint := message.GetKeyFP()
// Lookup reception key
@@ -249,11 +252,11 @@ func (rm *ReceptionManager) receiveMessagesFromGateway(session user.Session,
}
func (rm *ReceptionManager) decryptMessages(session user.Session,
- encryptedMessages []*format.Message) ([]*format.Message, []*id.User,
+ encryptedMessages []*format.Message) ([]*format.Message, []*id.ID,
[]*format.Message) {
messages := make([]*format.Message, len(encryptedMessages))
- senders := make([]*id.User, len(encryptedMessages))
+ senders := make([]*id.ID, len(encryptedMessages))
messagesSendersLoc := 0
garbledMessages := make([]*format.Message, len(encryptedMessages))
@@ -263,7 +266,7 @@ func (rm *ReceptionManager) decryptMessages(session user.Session,
var err error = nil
var rekey bool
var unpadded []byte
- var sender *id.User
+ var sender *id.ID
garbled := false
// If message is E2E, handle decryption
@@ -275,7 +278,7 @@ func (rm *ReceptionManager) decryptMessages(session user.Session,
}
keyFP := msg.AssociatedData.GetKeyFP()
- sender = id.NewUserFromBytes(keyFP[:])
+ sender, err = makeUserID(keyFP[:])
} else {
sender, rekey, err = handleE2EReceiving(session, msg)
@@ -311,6 +314,17 @@ func broadcastMessageReception(message *parse.Message,
listeners.Speak(message)
}
+// Put a sender ID in a byte slice and set its type to user
+func makeUserID(senderID []byte) (*id.ID, error) {
+ senderIDBytes := make([]byte, id.ArrIDLen)
+ copy(senderIDBytes, senderID[:])
+ userID, err := id.Unmarshal(senderIDBytes)
+ if userID != nil {
+ userID.SetType(id.User)
+ }
+ return userID, err
+}
+
// skipErrChecker checks checks if the error is fatal or should be ignored
func skipErrChecker(err error) bool {
if strings.Contains(err.Error(), "Could not find any message IDs for this user") {
diff --git a/io/receptionManager.go b/io/receptionManager.go
index 53b70ee3ba7fb8949f6db4fe25785afe14b53b40..467ab0ebd069c22dcad1600d90e5e9967afd1205 100644
--- a/io/receptionManager.go
+++ b/io/receptionManager.go
@@ -13,12 +13,11 @@ import (
"github.com/pkg/errors"
"gitlab.com/elixxir/client/parse"
"gitlab.com/elixxir/comms/client"
+ "gitlab.com/elixxir/primitives/id"
"sync"
"time"
)
-const PermissioningAddrID = "Permissioning"
-
type ConnAddr string
func (a ConnAddr) String() string {
@@ -51,7 +50,7 @@ type ReceptionManager struct {
}
// Build a new reception manager object using inputted key fields
-func NewReceptionManager(rekeyChan chan struct{}, uid string, privKey, pubKey, salt []byte) (*ReceptionManager, error) {
+func NewReceptionManager(rekeyChan chan struct{}, uid *id.ID, privKey, pubKey, salt []byte) (*ReceptionManager, error) {
comms, err := client.NewClientComms(uid, pubKey, privKey, salt)
if err != nil {
return nil, errors.Wrap(err, "Failed to get client comms using constructor: %+v")
@@ -74,9 +73,9 @@ func NewReceptionManager(rekeyChan chan struct{}, uid string, privKey, pubKey, s
// Connects to the permissioning server, if we know about it, to get the latest
// version from it
func (rm *ReceptionManager) GetRemoteVersion() (string, error) {
- permissioningHost, ok := rm.Comms.GetHost(PermissioningAddrID)
+ permissioningHost, ok := rm.Comms.GetHost(&id.Permissioning)
if !ok {
- return "", errors.Errorf("Failed to find permissioning host with id %s", PermissioningAddrID)
+ return "", errors.Errorf("Failed to find permissioning host with id %s", id.Permissioning)
}
registrationVersion, err := rm.Comms.
SendGetCurrentClientVersionMessage(permissioningHost)
diff --git a/io/send.go b/io/send.go
index 1d0821e9e94814ade332ce1995bcca33963904a4..d123f946960ace5f71ae4a984a02536cc4b68e3e 100644
--- a/io/send.go
+++ b/io/send.go
@@ -31,7 +31,7 @@ import (
// TODO This method would be cleaner if it took a parse.Message (particularly
// w.r.t. generating message IDs for multi-part messages.)
func (rm *ReceptionManager) SendMessage(session user.Session, topology *connect.Circuit,
- recipientID *id.User, cryptoType parse.CryptoType,
+ recipientID *id.ID, cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
// FIXME: We should really bring the plaintext parts of the NewMessage logic
// into this module, then have an EncryptedMessage type that is sent to/from
@@ -77,7 +77,7 @@ func (rm *ReceptionManager) SendMessage(session user.Session, topology *connect.
// This function will be needed for example to send a Rekey
// message, where a new public key will take up the whole message
func (rm *ReceptionManager) SendMessageNoPartition(session user.Session,
- topology *connect.Circuit, recipientID *id.User, cryptoType parse.CryptoType,
+ topology *connect.Circuit, recipientID *id.ID, cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
size := len(message)
if size > format.TotalLen {
@@ -132,14 +132,14 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
}
message.Contents.Set(padded)
e2e.SetUnencrypted(message)
- message.SetKeyFP(*format.NewFingerprint(session.GetCurrentUser().User.Bytes()))
+ message.SetKeyFP(*format.NewFingerprint(session.GetCurrentUser().User.Marshal()[:32]))
}
// CMIX Encryption
salt := cmix.NewSalt(csprng.Source(&csprng.SystemRNG{}), 32)
encMsg, kmacs := crypto.CMIXEncrypt(session, topology, salt, message)
msgPacket := &pb.Slot{
- SenderID: session.GetCurrentUser().User.Bytes(),
+ SenderID: session.GetCurrentUser().User.Marshal(),
PayloadA: encMsg.GetPayloadA(),
PayloadB: encMsg.GetPayloadB(),
Salt: salt,
@@ -152,7 +152,10 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
func handleE2ESending(session user.Session,
message *format.Message,
rekey bool) {
- recipientID := message.GetRecipient()
+ recipientID, err := message.GetRecipient()
+ if err != nil {
+ globals.Log.ERROR.Panic(err)
+ }
var key *keyStore.E2EKey
var action keyStore.Action
diff --git a/keyStore/keyManager.go b/keyStore/keyManager.go
index d6d58634521ac62aea3e8c8865a971cd7ca4043e..a6938702fa624f69145c159f74a883ae46da1e7e 100644
--- a/keyStore/keyManager.go
+++ b/keyStore/keyManager.go
@@ -34,7 +34,7 @@ type KeyManager struct {
pubKey *cyclic.Int
// Designates end-to-end partner
- partner *id.User
+ partner *id.ID
// True if key manager tracks send keys, false if receive keys
sendOrRecv bool
@@ -76,7 +76,7 @@ type KeyManager struct {
// All internal states are forced to 0 for safety purposes
func NewManager(baseKey *cyclic.Int,
privKey *cyclic.Int, pubKey *cyclic.Int,
- partner *id.User, sendOrRecv bool,
+ partner *id.ID, sendOrRecv bool,
numKeys uint32, ttl uint16, numReKeys uint16) *KeyManager {
km := new(KeyManager)
@@ -117,7 +117,7 @@ func (km *KeyManager) GetPubKey() *cyclic.Int {
}
// Get the partner ID from the Key Manager
-func (km *KeyManager) GetPartner() *id.User {
+func (km *KeyManager) GetPartner() *id.ID {
return km.partner
}
@@ -263,7 +263,7 @@ func (km *KeyManager) checkRecvStateBit(rekey bool, keyNum uint32) bool {
// E2E relationship is established, and also to generate all previously
// unused keys based on KeyManager state, when reloading an user session
// The function returns modifications that need to be independently made to the keystore.
-func (km *KeyManager) GenerateKeys(grp *cyclic.Group, userID *id.User) []*E2EKey {
+func (km *KeyManager) GenerateKeys(grp *cyclic.Group, userID *id.ID) []*E2EKey {
var recE2EKeys []*E2EKey
if km.sendOrRecv {
@@ -538,6 +538,12 @@ func (km *KeyManager) GobDecode(in []byte) error {
return err
}
+ partner, err := id.Unmarshal(s.Partner)
+ if err != nil {
+ return err
+ }
+ km.partner = partner
+
// Convert decoded bytes and put into key manager structure
km.baseKey = new(cyclic.Int)
err = km.baseKey.GobDecode(s.BaseKey)
@@ -566,7 +572,6 @@ func (km *KeyManager) GobDecode(in []byte) error {
km.sendOrRecv = false
}
- km.partner = id.NewUserFromBytes(s.Partner)
km.sendState = new(uint64)
*km.sendState = binary.BigEndian.Uint64(s.State)
km.ttl = binary.BigEndian.Uint16(s.TTL)
diff --git a/keyStore/keyManager_test.go b/keyStore/keyManager_test.go
index 72fc65533ac1ed3588724a9aba4ea8ab7fefa1ff..3851e03e3e978539768f1d759ada70c3017b5ca0 100644
--- a/keyStore/keyManager_test.go
+++ b/keyStore/keyManager_test.go
@@ -47,7 +47,7 @@ func initGroup() *cyclic.Group {
func TestKeyManager_New(t *testing.T) {
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, nil, nil,
partner, true, 12, 10, 10)
@@ -63,7 +63,7 @@ func TestKeyManager_GetBaseKey(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, privKey, pubKey,
partner, true, 12, 10, 10)
@@ -83,7 +83,7 @@ func TestKeyManager_GetPrivKey(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, privKey, pubKey,
partner, true, 12, 10, 10)
@@ -103,7 +103,7 @@ func TestKeyManager_GetPubKey(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, privKey, pubKey,
partner, true, 12, 10, 10)
@@ -123,7 +123,7 @@ func TestKeyManager_GetPartner(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, privKey, pubKey,
partner, true, 12, 10, 10)
@@ -141,7 +141,7 @@ func TestKeyManager_GetPartner(t *testing.T) {
func TestKeyManager_Rekey(t *testing.T) {
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, nil, nil,
partner, true, 12, 10, 10)
@@ -166,7 +166,7 @@ func TestKeyManager_Rekey(t *testing.T) {
func TestKeyManager_Purge(t *testing.T) {
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, nil, nil,
partner, true, 12, 10, 10)
@@ -198,7 +198,7 @@ func TestKeyManager_Purge(t *testing.T) {
func TestKeyManager_UpdateRecvState(t *testing.T) {
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
km := NewManager(baseKey, nil, nil,
partner, false, 12, 10, 10)
@@ -230,8 +230,8 @@ func TestKeyManager_UpdateRecvState(t *testing.T) {
func TestKeyManager_GenerateKeys(t *testing.T) {
grp := initGroup()
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
ks := NewStore()
kmSend := NewManager(baseKey, nil, nil,
@@ -291,8 +291,8 @@ func TestKeyManager_GenerateKeys(t *testing.T) {
func TestKeyManager_Destroy(t *testing.T) {
grp := initGroup()
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
ks := NewStore()
km := NewManager(baseKey, nil, nil,
@@ -365,7 +365,7 @@ func TestKeyManager_GobSimple(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
var byteBuf bytes.Buffer
@@ -471,8 +471,8 @@ func TestKeyManager_Gob(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
ks := NewStore()
km := NewManager(baseKey, privKey, pubKey,
diff --git a/keyStore/keyStore.go b/keyStore/keyStore.go
index a08a9938d450955d735427245cae614d8f4ab96c..8256cbde527b7025ea1842974b6c62df2b9de427 100644
--- a/keyStore/keyStore.go
+++ b/keyStore/keyStore.go
@@ -18,12 +18,12 @@ type keyManMap sync.Map
type inKeyMap sync.Map
// Stores a KeyManager entry for given user
-func (m *keyManMap) Store(user *id.User, km *KeyManager) {
+func (m *keyManMap) Store(user *id.ID, km *KeyManager) {
(*sync.Map)(m).Store(*user, km)
}
// Loads a KeyManager entry for given user
-func (m *keyManMap) Load(user *id.User) *KeyManager {
+func (m *keyManMap) Load(user *id.ID) *KeyManager {
val, ok := (*sync.Map)(m).Load(*user)
if !ok {
return nil
@@ -33,7 +33,7 @@ func (m *keyManMap) Load(user *id.User) *KeyManager {
}
// Deletes a KeyManager entry for given user
-func (m *keyManMap) Delete(user *id.User) {
+func (m *keyManMap) Delete(user *id.ID) {
(*sync.Map)(m).Delete(*user)
}
@@ -50,10 +50,10 @@ func (m *keyManMap) values() []*KeyManager {
// Internal helper function to get a list of all keys
// contained in a KeyManMap
-func (m *keyManMap) keys() []id.User {
- keyList := make([]id.User, 0)
+func (m *keyManMap) keys() []id.ID {
+ keyList := make([]id.ID, 0)
(*sync.Map)(m).Range(func(key, value interface{}) bool {
- keyList = append(keyList, key.(id.User))
+ keyList = append(keyList, key.(id.ID))
return true
})
return keyList
@@ -114,7 +114,7 @@ type KeyStore struct {
params *KeyParams
// Transmission Keys map
- // Maps id.User to *KeyManager
+ // Maps id.ID to *KeyManager
sendKeyManagers *keyManMap
// Reception Keys map
@@ -122,7 +122,7 @@ type KeyStore struct {
receptionKeys *inKeyMap
// Reception Key Managers map
- recvKeyManagers map[id.User]*ReceptionKeyManagerBuffer
+ recvKeyManagers map[id.ID]*ReceptionKeyManagerBuffer
lock sync.Mutex
}
@@ -140,11 +140,11 @@ func NewStore() *KeyStore {
}
ks.sendKeyManagers = new(keyManMap)
ks.receptionKeys = new(inKeyMap)
- ks.recvKeyManagers = make(map[id.User]*ReceptionKeyManagerBuffer)
+ ks.recvKeyManagers = make(map[id.ID]*ReceptionKeyManagerBuffer)
return ks
}
-func (ks *KeyStore) DeleteContactKeys(id *id.User) error {
+func (ks *KeyStore) DeleteContactKeys(id *id.ID) error {
ks.lock.Lock()
defer ks.lock.Unlock()
@@ -177,18 +177,18 @@ func (ks *KeyStore) AddSendManager(km *KeyManager) {
// Get a Send KeyManager from respective map in KeyStore
// based on partner ID
-func (ks *KeyStore) GetSendManager(partner *id.User) *KeyManager {
+func (ks *KeyStore) GetSendManager(partner *id.ID) *KeyManager {
return ks.sendKeyManagers.Load(partner)
}
// GetPartners returns the list of partners we have keys for
-func (ks *KeyStore) GetPartners() []id.User {
+func (ks *KeyStore) GetPartners() []id.ID {
return ks.sendKeyManagers.keys()
}
// Delete a Send KeyManager from respective map in KeyStore
// based on partner ID
-func (ks *KeyStore) DeleteSendManager(partner *id.User) {
+func (ks *KeyStore) DeleteSendManager(partner *id.ID) {
ks.sendKeyManagers.Delete(partner)
}
@@ -225,14 +225,14 @@ func (ks *KeyStore) AddRecvManager(km *KeyManager) {
// Gets the Key manager at the current location on the ReceptionKeyManagerBuffer
// based on partner ID
-func (ks *KeyStore) GetRecvManager(partner *id.User) *KeyManager {
+func (ks *KeyStore) GetRecvManager(partner *id.ID) *KeyManager {
ks.lock.Lock()
defer ks.lock.Unlock()
return ks.recvKeyManagers[*partner].getCurrentReceptionKeyManager()
}
// Delete a Receive KeyManager based on partner ID from respective map in KeyStore
-func (ks *KeyStore) DeleteRecvManager(partner *id.User) {
+func (ks *KeyStore) DeleteRecvManager(partner *id.ID) {
ks.lock.Lock()
defer ks.lock.Unlock()
delete(ks.recvKeyManagers, *partner)
@@ -316,7 +316,7 @@ func (ks *KeyStore) GobDecode(in []byte) error {
// ReconstructKeys loops through all key managers and
// calls GenerateKeys on each of them, in order to rebuild
// the key maps
-func (ks *KeyStore) ReconstructKeys(grp *cyclic.Group, userID *id.User) {
+func (ks *KeyStore) ReconstructKeys(grp *cyclic.Group, userID *id.ID) {
kmList := ks.sendKeyManagers.values()
for _, km := range kmList {
diff --git a/keyStore/keyStore_test.go b/keyStore/keyStore_test.go
index 35077a3817b679626172ea162f827fa1424e40c3..ee334ff3ad7147cb1d6ba2f02423f4f5f1705b4a 100644
--- a/keyStore/keyStore_test.go
+++ b/keyStore/keyStore_test.go
@@ -40,8 +40,8 @@ func TestKeyStore_Gob(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
ks := NewStore()
km := NewManager(baseKey, privKey, pubKey,
@@ -126,8 +126,8 @@ func TestKeyStore_DeleteContactKeys(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
ks := NewStore()
km := NewManager(baseKey, privKey, pubKey,
diff --git a/keyStore/recieveKeyManagerBuffer_test.go b/keyStore/recieveKeyManagerBuffer_test.go
index 18b7bdbe02569cd56d0c492f2e068588f3e6a45a..a9caec7d1dba38af6a53253a26b64b518df0688b 100644
--- a/keyStore/recieveKeyManagerBuffer_test.go
+++ b/keyStore/recieveKeyManagerBuffer_test.go
@@ -13,8 +13,8 @@ func TestPush(t *testing.T) {
grp := initGroup()
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
//Generate twice the amount of keymanagers so we can test the circularness of the buffer as well
kmArray := []KeyManager{}
@@ -110,8 +110,8 @@ func TestReceptionKeyManagerBuffer_Gob(t *testing.T) {
aBuffer := NewReceptionKeyManagerBuffer()
grp := initGroup()
baseKey := grp.NewInt(57)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
newKm := *NewManager(baseKey, nil,
nil, partner,
diff --git a/keyStore/rekeyManager.go b/keyStore/rekeyManager.go
index f83ace69887ad9fd5fb2a6db5a87e07ca5cb26ef..cfb0442141a2ac3f93c871d1d35decb953e4afb0 100644
--- a/keyStore/rekeyManager.go
+++ b/keyStore/rekeyManager.go
@@ -29,51 +29,51 @@ func (k *RekeyKeys) RotateKeysIfReady() {
}
type RekeyManager struct {
- Ctxs map[id.User]*RekeyContext
- Keys map[id.User]*RekeyKeys
+ Ctxs map[id.ID]*RekeyContext
+ Keys map[id.ID]*RekeyKeys
lock sync.Mutex
}
func NewRekeyManager() *RekeyManager {
return &RekeyManager{
- Ctxs: make(map[id.User]*RekeyContext),
- Keys: make(map[id.User]*RekeyKeys),
+ Ctxs: make(map[id.ID]*RekeyContext),
+ Keys: make(map[id.ID]*RekeyKeys),
}
}
-func (rkm *RekeyManager) AddCtx(partner *id.User,
+func (rkm *RekeyManager) AddCtx(partner *id.ID,
ctx *RekeyContext) {
rkm.lock.Lock()
defer rkm.lock.Unlock()
rkm.Ctxs[*partner] = ctx
}
-func (rkm *RekeyManager) GetCtx(partner *id.User) *RekeyContext {
+func (rkm *RekeyManager) GetCtx(partner *id.ID) *RekeyContext {
rkm.lock.Lock()
defer rkm.lock.Unlock()
return rkm.Ctxs[*partner]
}
-func (rkm *RekeyManager) DeleteCtx(partner *id.User) {
+func (rkm *RekeyManager) DeleteCtx(partner *id.ID) {
rkm.lock.Lock()
defer rkm.lock.Unlock()
delete(rkm.Ctxs, *partner)
}
-func (rkm *RekeyManager) AddKeys(partner *id.User,
+func (rkm *RekeyManager) AddKeys(partner *id.ID,
keys *RekeyKeys) {
rkm.lock.Lock()
defer rkm.lock.Unlock()
rkm.Keys[*partner] = keys
}
-func (rkm *RekeyManager) GetKeys(partner *id.User) *RekeyKeys {
+func (rkm *RekeyManager) GetKeys(partner *id.ID) *RekeyKeys {
rkm.lock.Lock()
defer rkm.lock.Unlock()
return rkm.Keys[*partner]
}
-func (rkm *RekeyManager) DeleteKeys(partner *id.User) {
+func (rkm *RekeyManager) DeleteKeys(partner *id.ID) {
rkm.lock.Lock()
defer rkm.lock.Unlock()
delete(rkm.Keys, *partner)
diff --git a/keyStore/rekeyManager_test.go b/keyStore/rekeyManager_test.go
index 648b0d6a08d23f80c7c7daaa15a27d77602ea329..87072da6f788bbc5c7e6aae38fea5e7e0c8d6b96 100644
--- a/keyStore/rekeyManager_test.go
+++ b/keyStore/rekeyManager_test.go
@@ -22,8 +22,8 @@ func TestRekeyManager_Ctx(t *testing.T) {
baseKey := grp.NewInt(57)
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
rkm := NewRekeyManager()
val := &RekeyContext{
@@ -70,8 +70,8 @@ func TestRekeyManager_Keys(t *testing.T) {
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
privKey := grp.NewInt(5)
pubKey := grp.NewInt(42)
- partner := id.NewUserFromUint(14, t)
- userID := id.NewUserFromUint(18, t)
+ partner := id.NewIdFromUInt(14, id.User, t)
+ userID := id.NewIdFromUInt(18, id.User, t)
rkm := NewRekeyManager()
val := &RekeyKeys{
diff --git a/parse/message.go b/parse/message.go
index 898d7e5e77244eccecfcf7cd96dd803cefeb84df..9e626dc2c524e9660275ee74854769b0852cd689 100644
--- a/parse/message.go
+++ b/parse/message.go
@@ -21,8 +21,8 @@ type Message struct {
TypedBody
// The crypto type is inferred from the message's contents
InferredType CryptoType
- Sender *id.User
- Receiver *id.User
+ Sender *id.ID
+ Receiver *id.ID
Nonce []byte
Timestamp time.Time
}
@@ -46,12 +46,12 @@ func (ct CryptoType) String() string {
type MessageInterface interface {
// Returns the message's sender ID
// (uint64) BigEndian serialized into a byte slice
- GetSender() *id.User
+ GetSender() *id.ID
// Returns the message payload, without packed type
GetPayload() []byte
// Returns the message's recipient ID
// (uint64) BigEndian serialized into a byte slice
- GetRecipient() *id.User
+ GetRecipient() *id.ID
// Return the message's inner type
GetMessageType() int32
// Returns the message's outer type
@@ -81,11 +81,11 @@ func (m Message) Hash() MessageHash {
return mh
}
-func (m *Message) GetSender() *id.User {
+func (m *Message) GetSender() *id.ID {
return m.Sender
}
-func (m *Message) GetRecipient() *id.User {
+func (m *Message) GetRecipient() *id.ID {
return m.Receiver
}
diff --git a/parse/message_test.go b/parse/message_test.go
index 92746eff493349b1fa6a4d0c3e252040aeabce91..15933f84cfa7c526a2b4cf1dd33af1c63eca751f 100644
--- a/parse/message_test.go
+++ b/parse/message_test.go
@@ -18,8 +18,8 @@ func TestMessage_Hash(t *testing.T) {
m := Message{}
m.MessageType = 0
m.Body = []byte{0, 0}
- m.Sender = id.ZeroID
- m.Receiver = id.ZeroID
+ m.Sender = &id.ZeroUser
+ m.Receiver = &id.ZeroUser
m.Nonce = []byte{0, 0}
baseHash := m.Hash()
@@ -44,7 +44,7 @@ func TestMessage_Hash(t *testing.T) {
m.Body = []byte{0, 0}
- newID := id.NewUserFromUint(1, t)
+ newID := id.NewIdFromUInt(1, id.User, t)
oldID := m.Sender
m.Sender = newID
diff --git a/rekey/rekey.go b/rekey/rekey.go
index 710cd6e658a4f2e9d37fc30620648eb88c7a2699..044e428a5ad77443f663e1bb6dd20d2c1f42e57f 100644
--- a/rekey/rekey.go
+++ b/rekey/rekey.go
@@ -110,10 +110,10 @@ func InitRekey(s user.Session, m io.Communications, t *connect.Circuit, host *co
// messages that have a type that includes the outer type if that's not
// possible
// in short, switchboard should be the package that includes outer
- l.Register(id.ZeroID,
+ l.Register(&id.ZeroUser,
int32(cmixproto.Type_NO_TYPE),
&rekeyList)
- l.Register(id.ZeroID,
+ l.Register(&id.ZeroUser,
int32(cmixproto.Type_REKEY_CONFIRM),
&rekeyConfirmList)
}
@@ -127,7 +127,7 @@ const (
RekeyConfirm
)
-func rekeyProcess(rt rekeyType, partner *id.User, data []byte) error {
+func rekeyProcess(rt rekeyType, partner *id.ID, data []byte) error {
rkm := session.GetRekeyManager()
e2egrp := session.GetE2EGroup()
diff --git a/rekey/rekey_test.go b/rekey/rekey_test.go
index 9c217871d430bdc524c957b7f3152e15874f424a..7112b3386942b27f138c87ea2a1329ce6ba26049 100644
--- a/rekey/rekey_test.go
+++ b/rekey/rekey_test.go
@@ -2,6 +2,7 @@ package rekey
import (
"bytes"
+ "encoding/binary"
"fmt"
"gitlab.com/elixxir/client/cmixproto"
"gitlab.com/elixxir/client/globals"
@@ -31,7 +32,7 @@ type dummyMessaging struct {
// SendMessage to the server
func (d *dummyMessaging) SendMessage(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
d.listener <- message
@@ -41,7 +42,7 @@ func (d *dummyMessaging) SendMessage(sess user.Session,
// SendMessage without partitions to the server
func (d *dummyMessaging) SendMessageNoPartition(sess user.Session,
topology *connect.Circuit,
- recipientID *id.User,
+ recipientID *id.ID,
cryptoType parse.CryptoType,
message []byte, transmissionHost *connect.Host) error {
d.listener <- message
@@ -59,14 +60,18 @@ func TestMain(m *testing.M) {
user.InitUserRegistry(grp)
rng := csprng.NewSystemRNG()
u := &user.User{
- User: id.NewUserFromUints(&[4]uint64{0, 0, 0, 18}),
+ User: new(id.ID),
Username: "Bernie",
}
+ binary.BigEndian.PutUint64(u.User[:], 18)
+ u.User.SetType(id.User)
myPrivKeyCyclicCMIX := grp.RandomCoprime(grp.NewMaxInt())
myPubKeyCyclicCMIX := grp.ExpG(myPrivKeyCyclicCMIX, grp.NewInt(1))
myPrivKeyCyclicE2E := e2eGrp.RandomCoprime(e2eGrp.NewMaxInt())
myPubKeyCyclicE2E := e2eGrp.ExpG(myPrivKeyCyclicE2E, e2eGrp.NewInt(1))
- partnerID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 12})
+ partnerID := new(id.ID)
+ binary.BigEndian.PutUint64(partnerID[:], 12)
+ partnerID.SetType(id.User)
partnerPubKeyCyclic := e2eGrp.RandomCoprime(e2eGrp.NewMaxInt())
@@ -83,7 +88,9 @@ func TestMain(m *testing.M) {
}
rekeyChan2 := make(chan struct{}, 50)
- InitRekey(session, fakeComm, connect.NewCircuit([]*id.Node{id.NewNodeFromBytes(make([]byte, id.NodeIdLen))}), nil, rekeyChan2)
+ nodeID := new(id.ID)
+ nodeID.SetType(id.Node)
+ InitRekey(session, fakeComm, connect.NewCircuit([]*id.ID{nodeID}), nil, rekeyChan2)
// Create E2E relationship with partner
// Generate baseKey
@@ -129,7 +136,9 @@ func TestMain(m *testing.M) {
// Test RekeyTrigger
func TestRekeyTrigger(t *testing.T) {
- partnerID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 12})
+ partnerID := new(id.ID)
+ binary.BigEndian.PutUint64(partnerID[:], 12)
+ partnerID.SetType(id.User)
km := session.GetKeyStore().GetRecvManager(partnerID)
partnerPubKey := km.GetPubKey()
// Test receiving a RekeyTrigger message
@@ -185,7 +194,9 @@ func TestRekeyTrigger(t *testing.T) {
// Test RekeyConfirm
func TestRekeyConfirm(t *testing.T) {
- partnerID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 12})
+ partnerID := new(id.ID)
+ binary.BigEndian.PutUint64(partnerID[:], 12)
+ partnerID.SetType(id.User)
rekeyCtx := session.GetRekeyManager().GetCtx(partnerID)
baseKey := rekeyCtx.BaseKey
// Test receiving a RekeyConfirm message with wrong H(baseKey)
@@ -253,7 +264,9 @@ func TestRekeyConfirm(t *testing.T) {
// Test Rekey
func TestRekey(t *testing.T) {
- partnerID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 12})
+ partnerID := new(id.ID)
+ binary.BigEndian.PutUint64(partnerID[:], 12)
+ partnerID.SetType(id.User)
km := session.GetKeyStore().GetSendManager(partnerID)
// Generate new partner public key
_, grp := getGroups()
@@ -312,7 +325,9 @@ func TestRekey(t *testing.T) {
// Test Rekey errors
func TestRekey_Errors(t *testing.T) {
- partnerID := id.NewUserFromUints(&[4]uint64{0, 0, 0, 12})
+ partnerID := new(id.ID)
+ binary.BigEndian.PutUint64(partnerID[:], 12)
+ partnerID.SetType(id.User)
km := session.GetKeyStore().GetRecvManager(partnerID)
partnerPubKey := km.GetPubKey()
// Delete RekeyKeys so that RekeyTrigger and rekey error out
diff --git a/user/regCode.go b/user/regCode.go
new file mode 100644
index 0000000000000000000000000000000000000000..65094ad616ef680f8ea7a193d505c45e00cc1dc8
--- /dev/null
+++ b/user/regCode.go
@@ -0,0 +1,21 @@
+package user
+
+import (
+ "encoding/base32"
+ "gitlab.com/elixxir/primitives/id"
+ "golang.org/x/crypto/blake2b"
+)
+
+const RegCodeLen = 5
+
+func RegistrationCode(id *id.ID) string {
+ return base32.StdEncoding.EncodeToString(userHash(id))
+}
+
+func userHash(id *id.ID) []byte {
+ h, _ := blake2b.New256(nil)
+ h.Write(id.Marshal())
+ huid := h.Sum(nil)
+ huid = huid[len(huid)-RegCodeLen:]
+ return huid
+}
diff --git a/user/session.go b/user/session.go
index 325db8c2db4c2eb13658903d8e69b67859f42a85..342bffb3afaf5f8d8e471acbc384ce28994c1f0a 100644
--- a/user/session.go
+++ b/user/session.go
@@ -36,7 +36,7 @@ var ErrQuery = errors.New("element not in map")
type Session interface {
GetCurrentUser() (currentUser *User)
GetNodeKeys(topology *connect.Circuit) []NodeKeys
- PushNodeKey(id *id.Node, key NodeKeys)
+ PushNodeKey(id *id.ID, key NodeKeys)
GetRSAPrivateKey() *rsa.PrivateKey
GetRSAPublicKey() *rsa.PublicKey
GetCMIXDHPrivateKey() *cyclic.Int
@@ -60,7 +60,7 @@ type Session interface {
UnlockStorage()
GetSessionData() ([]byte, error)
GetRegistrationValidationSignature() []byte
- GetNodes() map[id.Node]int
+ GetNodes() map[id.ID]int
AppendGarbledMessage(messages ...*format.Message)
PopGarbledMessages() []*format.Message
GetSalt() []byte
@@ -68,9 +68,9 @@ type Session interface {
GetRegState() uint32
ChangeUsername(string) error
StorageIsEmpty() bool
- GetContactByValue(string) (*id.User, []byte)
- StoreContactByValue(string, *id.User, []byte)
- DeleteContact(*id.User) (string, error)
+ GetContactByValue(string) (*id.ID, []byte)
+ StoreContactByValue(string, *id.ID, []byte)
+ DeleteContact(*id.ID) (string, error)
GetSessionLocation() uint8
LoadEncryptedSession(store globals.Storage) ([]byte, error)
RegisterPermissioningSignature(sig []byte) error
@@ -96,7 +96,7 @@ func NewSession(store globals.Storage,
regState := uint32(KeyGenComplete)
// With an underlying Session data structure
return Session(&SessionObj{
- NodeKeys: make(map[id.Node]NodeKeys),
+ NodeKeys: make(map[id.ID]NodeKeys),
CurrentUser: u,
RSAPublicKey: publicKeyRSA,
RSAPrivateKey: privateKeyRSA,
@@ -173,7 +173,7 @@ func LoadSession(store globals.Storage, password string) (Session, error) {
session.password = password
if session.NodeKeys == nil {
- session.NodeKeys = make(map[id.Node]NodeKeys)
+ session.NodeKeys = make(map[id.ID]NodeKeys)
}
return &session, nil
@@ -246,7 +246,7 @@ type SessionObj struct {
// Currently authenticated user
CurrentUser *User
- NodeKeys map[id.Node]NodeKeys
+ NodeKeys map[id.ID]NodeKeys
RSAPrivateKey *rsa.PrivateKey
RSAPublicKey *rsa.PublicKey
CMIXDHPrivateKey *cyclic.Int
@@ -325,7 +325,7 @@ func (s *SessionObj) LoadEncryptedSession(store globals.Storage) ([]byte, error)
}
type SearchedUserRecord struct {
- Id id.User
+ Id id.ID
Pk []byte
}
@@ -348,10 +348,10 @@ func (s *SessionObj) SetLastMessageID(id string) {
s.UnlockStorage()
}
-func (s *SessionObj) GetNodes() map[id.Node]int {
+func (s *SessionObj) GetNodes() map[id.ID]int {
s.LockStorage()
defer s.UnlockStorage()
- nodes := make(map[id.Node]int, 0)
+ nodes := make(map[id.ID]int, 0)
for node := range s.NodeKeys {
nodes[node] = 1
}
@@ -379,7 +379,7 @@ func (s *SessionObj) GetNodeKeys(topology *connect.Circuit) []NodeKeys {
return keys
}
-func (s *SessionObj) PushNodeKey(id *id.Node, key NodeKeys) {
+func (s *SessionObj) PushNodeKey(id *id.ID, key NodeKeys) {
s.LockStorage()
defer s.UnlockStorage()
@@ -731,7 +731,7 @@ func (s *SessionObj) PopGarbledMessages() []*format.Message {
return tempBuffer
}
-func (s *SessionObj) GetContactByValue(v string) (*id.User, []byte) {
+func (s *SessionObj) GetContactByValue(v string) (*id.ID, []byte) {
s.LockStorage()
defer s.UnlockStorage()
u, ok := s.ContactsByValue[v]
@@ -741,7 +741,7 @@ func (s *SessionObj) GetContactByValue(v string) (*id.User, []byte) {
return &(u.Id), u.Pk
}
-func (s *SessionObj) StoreContactByValue(v string, uid *id.User, pk []byte) {
+func (s *SessionObj) StoreContactByValue(v string, uid *id.ID, pk []byte) {
s.LockStorage()
defer s.UnlockStorage()
u, ok := s.ContactsByValue[v]
@@ -756,7 +756,7 @@ func (s *SessionObj) StoreContactByValue(v string, uid *id.User, pk []byte) {
}
}
-func (s *SessionObj) DeleteContact(uid *id.User) (string, error) {
+func (s *SessionObj) DeleteContact(uid *id.ID) (string, error) {
s.LockStorage()
defer s.UnlockStorage()
diff --git a/user/session_test.go b/user/session_test.go
index 59068c9a7fa83d9668bb9502ce85eed2a30d42b3..370dc25374039cd38a042a14d080c2dcd758df46 100644
--- a/user/session_test.go
+++ b/user/session_test.go
@@ -34,14 +34,14 @@ func TestUserSession(t *testing.T) {
// sure that the gob contains the user ID
UID := uint64(65)
- u.User = id.NewUserFromUint(UID, t)
+ u.User = id.NewIdFromUInt(UID, id.User, t)
u.Username = "Mario"
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
- nodeID := id.NewNodeFromUInt(1, t)
+ nodeID := id.NewIdFromUInt(1, id.Node, t)
- topology := connect.NewCircuit([]*id.Node{nodeID})
+ topology := connect.NewCircuit([]*id.ID{nodeID})
// Storage
storage := &globals.RamStorage{}
@@ -220,12 +220,12 @@ func TestSessionObj_DeleteContact(t *testing.T) {
// sure that the gob contains the user ID
UID := uint64(65)
- u.User = id.NewUserFromUint(UID, t)
+ u.User = id.NewIdFromUInt(UID, id.User, t)
u.Username = "Mario"
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
- nodeID := id.NewNodeFromUInt(1, t)
+ nodeID := id.NewIdFromUInt(1, id.Node, t)
// Storage
storage := &globals.RamStorage{}
@@ -261,9 +261,10 @@ func TestSessionObj_DeleteContact(t *testing.T) {
ReceptionKey: grp.NewInt(2),
})
- ses.StoreContactByValue("test", id.NewUserFromBytes([]byte("test")), []byte("test"))
+ testContact := id.NewIdFromString("test", id.User, t)
+ ses.StoreContactByValue("test", testContact, []byte("test"))
- _, err = ses.DeleteContact(id.NewUserFromBytes([]byte("test")))
+ _, err = ses.DeleteContact(testContact)
if err != nil {
t.Errorf("Failed to delete contact: %+v", err)
}
@@ -271,7 +272,7 @@ func TestSessionObj_DeleteContact(t *testing.T) {
func TestGetPubKey(t *testing.T) {
u := new(User)
- UID := id.NewUserFromUint(1, t)
+ UID := id.NewIdFromUInt(1, id.User, t)
u.User = UID
u.Username = "Mario"
@@ -304,7 +305,7 @@ func TestGetPubKey(t *testing.T) {
err.Error())
}
- ses.PushNodeKey(id.NewNodeFromUInt(1, t), NodeKeys{
+ ses.PushNodeKey(id.NewIdFromUInt(1, id.Node, t), NodeKeys{
TransmissionKey: grp.NewInt(2),
ReceptionKey: grp.NewInt(2),
})
@@ -323,12 +324,12 @@ func TestSessionObj_StorageIsEmpty(t *testing.T) {
// sure that the gob contains the user ID
UID := uint64(65)
- u.User = id.NewUserFromUint(UID, t)
+ u.User = id.NewIdFromUInt(UID, id.User, t)
u.Username = "Mario"
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
- nodeID := id.NewNodeFromUInt(1, t)
+ nodeID := id.NewIdFromUInt(1, id.Node, t)
// Storage
storage := &globals.RamStorage{}
@@ -381,12 +382,12 @@ func TestSessionObj_GetContactByValue(t *testing.T) {
// sure that the gob contains the user ID
UID := uint64(65)
- u.User = id.NewUserFromUint(UID, t)
+ u.User = id.NewIdFromUInt(UID, id.User, t)
u.Username = "Mario"
grp := cyclic.NewGroup(large.NewInt(107), large.NewInt(2))
- nodeID := id.NewNodeFromUInt(1, t)
+ nodeID := id.NewIdFromUInt(1, id.Node, t)
// Storage
storage := &globals.RamStorage{}
@@ -420,7 +421,9 @@ func TestSessionObj_GetContactByValue(t *testing.T) {
ReceptionKey: grp.NewInt(2),
})
- ses.StoreContactByValue("value", id.NewUserFromBytes([]byte("test")), []byte("test"))
+ userId := id.NewIdFromBytes([]byte("test"), t)
+
+ ses.StoreContactByValue("value", userId, []byte("test"))
observedUser, observedPk := ses.GetContactByValue("value")
@@ -429,7 +432,7 @@ func TestSessionObj_GetContactByValue(t *testing.T) {
"Expected: %+v\n\tRecieved: %+v", privateKey.PublicKey.N.Bytes(), observedPk)
}
- if !observedUser.Cmp(id.NewUserFromBytes([]byte("test"))) {
+ if !observedUser.Cmp(userId) {
t.Errorf("Failed to retrieve user using GetContactByValue;"+
"Expected: %+v\n\tRecieved: %+v", u.User, observedUser)
}
@@ -437,7 +440,7 @@ func TestSessionObj_GetContactByValue(t *testing.T) {
func TestGetPrivKey(t *testing.T) {
u := new(User)
- UID := id.NewUserFromUint(1, t)
+ UID := id.NewIdFromUInt(1, id.User, t)
u.User = UID
u.Username = "Mario"
@@ -470,7 +473,7 @@ func TestGetPrivKey(t *testing.T) {
err.Error())
}
- ses.PushNodeKey(id.NewNodeFromUInt(1, t), NodeKeys{
+ ses.PushNodeKey(id.NewIdFromUInt(1, id.Node, t), NodeKeys{
TransmissionKey: grp.NewInt(2),
ReceptionKey: grp.NewInt(2),
})
@@ -637,7 +640,7 @@ func GenerateTestMessages(size int) []*format.Message {
// Happy path
func TestConvertSessionV1toV2(t *testing.T) {
u := new(User)
- UID := id.NewUserFromUint(1, t)
+ UID := id.NewIdFromUInt(1, id.Node, t)
u.User = UID
u.Username = "Bernie"
diff --git a/user/sessionv1.go b/user/sessionv1.go
index 0496913de013df8972cc45d0c5fb7dc88e785bb5..3f470aa558447c8edf0aad156db45e6a23d52d21 100644
--- a/user/sessionv1.go
+++ b/user/sessionv1.go
@@ -20,7 +20,7 @@ type SessionObjV1 struct {
// Currently authenticated user
CurrentUser *UserV1
- Keys map[id.Node]NodeKeys
+ Keys map[id.ID]NodeKeys
RSAPrivateKey *rsa.PrivateKey
RSAPublicKey *rsa.PublicKey
CMIXDHPrivateKey *cyclic.Int
@@ -73,7 +73,7 @@ type SessionObjV1 struct {
// Struct representing a User in the system
type UserV1 struct {
- User *id.User
+ User *id.ID
Nick string
Email string
}
diff --git a/user/user.go b/user/user.go
index 209f039c94751cb6a11d8d8b42ba877d6fd4daac..45e0bc65cf265247df30e08c830ee87d958f006c 100644
--- a/user/user.go
+++ b/user/user.go
@@ -8,6 +8,7 @@ package user
import (
"crypto/sha256"
+ "encoding/binary"
"gitlab.com/elixxir/client/globals"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/primitives/id"
@@ -31,25 +32,25 @@ func InitUserRegistry(grp *cyclic.Group) {
// Interface for User Registry operations
type Registry interface {
- NewUser(id *id.User, nickname string) *User
- DeleteUser(id *id.User)
- GetUser(id *id.User) (user *User, ok bool)
+ NewUser(id *id.ID, nickname string) *User
+ DeleteUser(id *id.ID)
+ GetUser(id *id.ID) (user *User, ok bool)
UpsertUser(user *User)
CountUsers() int
- LookupUser(hid string) (uid *id.User, ok bool)
- LookupKeys(uid *id.User) (*NodeKeys, bool)
+ LookupUser(hid string) (uid *id.ID, ok bool)
+ LookupKeys(uid *id.ID) (*NodeKeys, bool)
}
type UserMap struct {
// Map acting as the User Registry containing User -> ID mapping
- userCollection map[id.User]*User
+ userCollection map[id.ID]*User
// Increments sequentially for User.ID values
idCounter uint64
// Temporary map acting as a lookup table for demo user registration codes
// Key type is string because keys must implement == and []byte doesn't
- userLookup map[string]*id.User
+ userLookup map[string]*id.ID
//Temporary placed to store the keys for each user
- keysLookup map[id.User]*NodeKeys
+ keysLookup map[id.ID]*NodeKeys
}
// newRegistry creates a new Registry interface
@@ -57,21 +58,22 @@ func newRegistry(grp *cyclic.Group) Registry {
if len(DemoChannelNames) > 10 || len(DemoUserNicks) > 30 {
globals.Log.ERROR.Print("Not enough demo users have been hardcoded.")
}
- userUserIdMap := make(map[id.User]*User)
- userRegCodeMap := make(map[string]*id.User)
- nk := make(map[id.User]*NodeKeys)
+ userUserIdMap := make(map[id.ID]*User)
+ userRegCodeMap := make(map[string]*id.ID)
+ nk := make(map[id.ID]*NodeKeys)
// Deterministically create NumDemoUsers users
// TODO Replace this with real user registration/discovery
for i := uint64(1); i <= NumDemoUsers; i++ {
- currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, i})
+ currentID := new(id.ID)
+ binary.BigEndian.PutUint64(currentID[:], i)
+ currentID.SetType(id.User)
newUsr := new(User)
nodeKey := new(NodeKeys)
// Generate user parameters
newUsr.User = currentID
newUsr.Precan = true
- currentID.RegistrationCode()
// TODO We need a better way to generate base/recursive keys
h := sha256.New()
h.Write([]byte(string(40000 + i)))
@@ -83,23 +85,27 @@ func newRegistry(grp *cyclic.Group) Registry {
// Add user to collection and lookup table
userUserIdMap[*newUsr.User] = newUsr
// Detect collisions in the registration code
- if _, ok := userRegCodeMap[newUsr.User.RegistrationCode()]; ok {
+ if _, ok := userRegCodeMap[RegistrationCode(newUsr.User)]; ok {
globals.Log.ERROR.Printf(
"Collision in demo user list creation at %v. "+
"Please fix ASAP (include more bits to the reg code.", i)
}
- userRegCodeMap[newUsr.User.RegistrationCode()] = newUsr.User
+ userRegCodeMap[RegistrationCode(newUsr.User)] = newUsr.User
nk[*newUsr.User] = nodeKey
}
// Channels have been hardcoded to users starting with 31
for i := 0; i < len(DemoUserNicks); i++ {
- currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, uint64(i) + 1})
+ currentID := new(id.ID)
+ binary.BigEndian.PutUint64(currentID[:], uint64(i)+1)
+ currentID.SetType(id.User)
userUserIdMap[*currentID].Username = DemoUserNicks[i]
}
for i := 0; i < len(DemoChannelNames); i++ {
- currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, uint64(i) + 31})
+ currentID := new(id.ID)
+ binary.BigEndian.PutUint64(currentID[:], uint64(i)+31)
+ currentID.SetType(id.User)
userUserIdMap[*currentID].Username = DemoChannelNames[i]
}
@@ -112,7 +118,7 @@ func newRegistry(grp *cyclic.Group) Registry {
// Struct representing a User in the system
type User struct {
- User *id.User
+ User *id.ID
Username string
Precan bool
}
@@ -130,20 +136,20 @@ func (u *User) DeepCopy() *User {
}
// NewUser creates a new User object with default fields and given address.
-func (m *UserMap) NewUser(id *id.User, username string) *User {
+func (m *UserMap) NewUser(id *id.ID, username string) *User {
return &User{User: id, Username: username}
}
// GetUser returns a user with the given ID from userCollection
// and a boolean for whether the user exists
-func (m *UserMap) GetUser(id *id.User) (user *User, ok bool) {
+func (m *UserMap) GetUser(id *id.ID) (user *User, ok bool) {
user, ok = m.userCollection[*id]
user = user.DeepCopy()
return
}
// DeleteContactKeys deletes a user with the given ID from userCollection.
-func (m *UserMap) DeleteUser(id *id.User) {
+func (m *UserMap) DeleteUser(id *id.ID) {
// If key does not exist, do nothing
delete(m.userCollection, *id)
}
@@ -160,13 +166,13 @@ func (m *UserMap) CountUsers() int {
}
// LookupUser returns the user id corresponding to the demo registration code
-func (m *UserMap) LookupUser(hid string) (*id.User, bool) {
+func (m *UserMap) LookupUser(hid string) (*id.ID, bool) {
uid, ok := m.userLookup[hid]
return uid, ok
}
// LookupKeys returns the keys for the given user from the temporary key map
-func (m *UserMap) LookupKeys(uid *id.User) (*NodeKeys, bool) {
+func (m *UserMap) LookupKeys(uid *id.ID) (*NodeKeys, bool) {
nk, t := m.keysLookup[*uid]
return nk, t
}
diff --git a/user/user_test.go b/user/user_test.go
index fd2a0cfe78c38c60de115d574128805049495cb4..52d303e432c7c0a686b30406db2b130a7b46ce73 100644
--- a/user/user_test.go
+++ b/user/user_test.go
@@ -24,16 +24,16 @@ func TestUserRegistry(t *testing.T) {
}
// Test the integration of the LookupUser, UserHash and GetUser functions
for i := 0; i < len(DemoUserNicks); i++ {
- currentID := id.NewUserFromUint(uint64(i+1), t)
- reg, ok := Users.LookupUser(currentID.RegistrationCode())
+ currentID := id.NewIdFromUInt(uint64(i+1), id.User, t)
+ reg, ok := Users.LookupUser(RegistrationCode(currentID))
if !ok {
t.Errorf("Couldn't lookup user %q with code %v", *currentID,
- currentID.RegistrationCode())
+ RegistrationCode(currentID))
}
usr, ok := Users.GetUser(reg)
if !ok {
- t.Logf("Reg codes of both: %v, %v", reg.RegistrationCode(),
- currentID.RegistrationCode())
+ t.Logf("Reg codes of both: %v, %v", RegistrationCode(reg),
+ RegistrationCode(currentID))
t.Errorf("Couldn't get user %q corresponding to user %q",
*reg, *currentID)
}
@@ -43,7 +43,7 @@ func TestUserRegistry(t *testing.T) {
}
}
// Test the NewUser function
- newID := id.NewUserFromUint(2002, t)
+ newID := id.NewIdFromUInt(2002, id.User, t)
usr := Users.NewUser(newID, "Will I am")
if usr.Username != "Will I am" {
@@ -71,7 +71,7 @@ func TestUserRegistry(t *testing.T) {
grp := InitGroup()
// Test LookupKeys
- keys, suc := Users.LookupKeys(id.NewUserFromUint(1, t))
+ keys, suc := Users.LookupKeys(id.NewIdFromUInt(1, id.User, t))
if !suc {
t.Errorf("LookupKeys failed to find a valid user.")
}
@@ -85,9 +85,9 @@ func TestUserRegistry(t *testing.T) {
}
// Test delete user
- Users.DeleteUser(id.NewUserFromUint(2, t))
+ Users.DeleteUser(id.NewIdFromUInt(2, id.User, t))
- _, ok := Users.GetUser(id.NewUserFromUint(2, t))
+ _, ok := Users.GetUser(id.NewIdFromUInt(2, id.User, t))
if ok {
t.Errorf("User %v has not been deleted succesfully!", usr.Username)
}
@@ -97,8 +97,8 @@ func TestUserRegistry(t *testing.T) {
// the first several users
func TestPrintRegCodes(t *testing.T) {
for i := 1; i <= NumDemoUsers; i++ {
- currentID := id.NewUserFromUint(uint64(i), t)
- t.Logf("%v:\t%v", i, currentID.RegistrationCode())
+ currentID := id.NewIdFromUInt(uint64(i), id.User, t)
+ t.Logf("%v:\t%v", i, RegistrationCode(currentID))
}
}