diff --git a/api/user.go b/api/user.go index b1d9c2628613154d5c60349a7d3b8f780bc0aa1c..654381b3f6d9a6addcc4a8cfa3c3f08bdc2bc243 100644 --- a/api/user.go +++ b/api/user.go @@ -104,6 +104,8 @@ func createKeys(rng *fastRNG.StreamGenerator) ( stream := rng.GetStream() transmissionRsaKey, err = rsa.GenerateKey(stream, rsa.DefaultRSABitLen) + transmissionSalt = make([]byte, 32) + _, err = stream.Read(receptionSalt) stream.Close() if err != nil { jww.FATAL.Panicf(err.Error()) @@ -116,6 +118,8 @@ func createKeys(rng *fastRNG.StreamGenerator) ( stream := rng.GetStream() receptionRsaKey, err = rsa.GenerateKey(stream, rsa.DefaultRSABitLen) + receptionSalt = make([]byte, 32) + _, err = stream.Read(receptionSalt) stream.Close() if err != nil { jww.FATAL.Panicf(err.Error()) diff --git a/bindings/authenticatedConnectionTracker.go b/bindings/authenticatedConnectionTracker.go new file mode 100644 index 0000000000000000000000000000000000000000..57e260dc7c037b5cd82d5aebbb404d9b8b4ca751 --- /dev/null +++ b/bindings/authenticatedConnectionTracker.go @@ -0,0 +1,56 @@ +package bindings + +import ( + "github.com/pkg/errors" + "gitlab.com/elixxir/client/connect" + "sync" +) + +// connectionTracker is a singleton used to keep track of extant clients, allowing +// for race condition free passing over the bindings + +type authenticatedConnectionTracker struct { + connections map[int]*AuthenticatedConnection + count int + mux sync.RWMutex +} + +// make makes a client from an API client, assigning it a unique ID +func (act *authenticatedConnectionTracker) make(c connect.AuthenticatedConnection) *AuthenticatedConnection { + act.mux.Lock() + defer act.mux.Unlock() + + id := act.count + act.count++ + + act.connections[id] = &AuthenticatedConnection{ + Connection: Connection{ + connection: c, + id: id, + }, + } + + return act.connections[id] +} + +//get returns a client given its ID +func (act *authenticatedConnectionTracker) get(id int) (*AuthenticatedConnection, error) { + act.mux.RLock() + defer act.mux.RUnlock() + + c, exist := act.connections[id] + if !exist { + return nil, errors.Errorf("Cannot get client for id %d, client "+ + "does not exist", id) + } + + return c, nil +} + +//deletes a client if it exists +func (act *authenticatedConnectionTracker) delete(id int) { + act.mux.Lock() + defer act.mux.Unlock() + + delete(act.connections, id) +} diff --git a/bindings/autheticatedConnection.go b/bindings/autheticatedConnection.go new file mode 100644 index 0000000000000000000000000000000000000000..cca735d0af05a84bd99240f4cfc495e19b255dce --- /dev/null +++ b/bindings/autheticatedConnection.go @@ -0,0 +1,39 @@ +package bindings + +import ( + "gitlab.com/elixxir/client/connect" + "gitlab.com/elixxir/crypto/contact" +) + +//connection tracker singleton, used to track connections so they can be +//referenced by id back over the bindings +var authenticatedConnectionTrackerSingleton = &authenticatedConnectionTracker{ + connections: make(map[int]*AuthenticatedConnection), + count: 0, +} + +type AuthenticatedConnection struct { + Connection +} + +func (_ *AuthenticatedConnection) IsAuthenticated() bool { + return true +} + +// ConnectWithAuthentication is called by the client, ie the one establishing +// connection with the server. Once a connect.Connection has been established +// with the server and then authenticate their identity to the server. +func (c *Client) ConnectWithAuthentication(recipientContact []byte, myIdentity []byte) (*AuthenticatedConnection, error) { + cont, err := contact.Unmarshal(recipientContact) + if err != nil { + return nil, err + } + myID, rsaPriv, salt, myDHPriv, err := unmarshalIdentity(myIdentity) + if err != nil { + return nil, err + } + + connection, err := connect.ConnectWithAuthentication(cont, myID, salt, rsaPriv, myDHPriv, c.api.GetRng(), + c.api.GetStorage().GetE2EGroup(), c.api.GetCmix(), connect.GetDefaultParams()) + return authenticatedConnectionTrackerSingleton.make(connection), nil +} diff --git a/bindings/connect.go b/bindings/connect.go index 05bfd2afe5394f7bd517e96326e01d0f0ebcd929..3a8ee5dca8878c53abe3d39282ee38ae55bb665d 100644 --- a/bindings/connect.go +++ b/bindings/connect.go @@ -19,7 +19,7 @@ var connectionTrackerSingleton = &connectionTracker{ // type Connection struct { - connection connect.AuthenticatedConnection + connection connect.Connection id int } @@ -48,24 +48,6 @@ func (c *Client) Connect(recipientContact []byte, myIdentity []byte) ( return connectionTrackerSingleton.make(connection), nil } -// ConnectWithAuthentication is called by the client, ie the one establishing -// connection with the server. Once a connect.Connection has been established -// with the server and then authenticate their identity to the server. -func (c *Client) ConnectWithAuthentication(recipientContact []byte, myIdentity []byte) (*Connection, error) { - cont, err := contact.Unmarshal(recipientContact) - if err != nil { - return nil, err - } - myID, rsaPriv, salt, myDHPriv, err := unmarshalIdentity(myIdentity) - if err != nil { - return nil, err - } - - connection, err := connect.ConnectWithAuthentication(cont, myID, salt, rsaPriv, myDHPriv, c.api.GetRng(), - c.api.GetStorage().GetE2EGroup(), c.api.GetCmix(), connect.GetDefaultParams()) - return connectionTrackerSingleton.make(connection), nil -} - // type E2ESendReport struct { roundsList @@ -98,8 +80,8 @@ func (c *Connection) Close() { } // GetPartner returns the partner.Manager for this Connection -func (c *Connection) GetPartner() partner.Manager { - +func (c *Connection) GetPartner() []byte { + return c.connection.GetPartner().PartnerId().Marshal() } // RegisterListener is used for E2E reception diff --git a/bindings/contact.go b/bindings/contact.go index 3f96d3b07b797006bb29a3eb38537c41f9e8e4f0..14544785602449b934693ea38656eebde8476136 100644 --- a/bindings/contact.go +++ b/bindings/contact.go @@ -3,7 +3,9 @@ package bindings import ( "encoding/json" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/xx_network/crypto/xx" "gitlab.com/xx_network/primitives/id" ) @@ -22,7 +24,41 @@ type Fact struct { // MakeIdentity generates a new cryptographic identity for receving // messages func (c *Client) MakeIdentity() ([]byte, error) { - I := Identity{} + stream := c.api.GetRng().GetStream() + defer stream.Close() + + //make RSA Key + rsaKey, err := rsa.GenerateKey(stream, + rsa.DefaultRSABitLen) + if err != nil { + return nil, err + } + + //make salt + salt := make([]byte, 32) + _, err = stream.Read(salt) + + //make dh private key + privkey := diffieHellman.GeneratePrivateKey( + len(c.api.GetStorage().GetE2EGroup().GetPBytes()), + c.api.GetStorage().GetE2EGroup(), stream) + + //make the ID + id, err := xx.NewID(rsaKey.GetPublic(), + salt, id.User) + + if err != nil { + return nil, err + } + + //create the identity object + I := Identity{ + ID: id.Marshal(), + RSAPrivatePem: rsa.CreatePrivateKeyPem(rsaKey), + Salt: salt, + DHKeyPrivate: privkey.Bytes(), + } + return json.Marshal(&I) }