Skip to content
Snippets Groups Projects
Select Git revision
  • b73aabf6b35dcac6228febb75c0413ceba4009cc
  • release default protected
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • hotfix/TestHostPool_UpdateNdf_AddFilter
  • XX-4719/announcementChannels
  • xx-4717/logLevel
  • jonah/noob-channel
  • master protected
  • XX-4707/tagDiskJson
  • xx-4698/notification-retry
  • hotfix/notifylockup
  • syncNodes
  • hotfix/localCB
  • XX-4677/NewChanManagerMobile
  • XX-4689/DmSync
  • duplicatePrefix
  • XX-4601/HavenInvites
  • finalizedUICallbacks
  • XX-4673/AdminKeySync
  • debugNotifID
  • anne/test
  • v4.7.5
  • v4.7.4
  • v4.7.3
  • v4.7.2
  • v4.7.1
  • v4.6.3
  • v4.6.1
  • v4.5.0
  • v4.4.4
  • v4.3.11
  • v4.3.8
  • v4.3.7
  • v4.3.6
  • v4.3.5
  • v4.2.0
  • v4.3.0
  • v4.3.4
  • v4.3.3
  • v4.3.2
  • v4.3.1
41 results

messenger.go

Blame
  • messenger.go 5.76 KiB
    package messenger
    
    import (
    	"encoding/binary"
    	"encoding/json"
    
    	"github.com/pkg/errors"
    	jww "github.com/spf13/jwalterweatherman"
    	"gitlab.com/elixxir/client/api"
    	"gitlab.com/elixxir/client/auth"
    	"gitlab.com/elixxir/client/e2e"
    	"gitlab.com/elixxir/client/e2e/rekey"
    	"gitlab.com/elixxir/client/storage/user"
    	"gitlab.com/elixxir/crypto/cyclic"
    	"gitlab.com/elixxir/crypto/diffieHellman"
    	"gitlab.com/xx_network/primitives/id"
    )
    
    type Client struct {
    	*api.Client
    	auth   auth.State
    	e2e    e2e.Handler
    	backup *Container
    }
    
    func Login(client *api.Client, callbacks auth.Callbacks) (m *Client, err error) {
    	m = &Client{
    		Client: client,
    		backup: &Container{},
    	}
    
    	m.e2e, err = LoadOrInitE2e(client)
    	if err != nil {
    		return nil, err
    	}
    
    	m.auth, err = auth.NewState(client.GetStorage().GetKV(), client.GetCmix(),
    		m.e2e, client.GetRng(), client.GetEventReporter(),
    		auth.GetDefaultParams(), callbacks, m.backup.TriggerBackup)
    	if err != nil {
    		return nil, err
    	}
    
    	return m, err
    }
    
    // LoadOrInitE2e loads the e2e handler or makes a new one, generating a new
    // e2e private key. It attempts to load via a legacy construction, then tries
    // to load the modern one, creating a new modern ID if neither can be found
    func LoadOrInitE2e(client *api.Client) (e2e.Handler, error) {
    	usr := client.GetUser()
    	e2eGrp := client.GetStorage().GetE2EGroup()
    	kv := client.GetStorage().GetKV()
    
    	//try to load a legacy e2e hander
    	e2eHandler, err := e2e.LoadLegacy(kv,
    		client.GetCmix(), usr.ReceptionID, e2eGrp, client.GetRng(),
    		client.GetEventReporter(), rekey.GetDefaultParams())
    	if err != nil {
    		//if no legacy e2e handler exists, try to load a new one
    		e2eHandler, err = e2e.Load(kv,
    			client.GetCmix(), usr.ReceptionID, e2eGrp, client.GetRng(),
    			client.GetEventReporter())
    		//if no new e2e handler exists, initilize an e2e user
    		if err != nil {
    			jww.WARN.Printf("Failed to load e2e instance for %s, "+
    				"creating a new one", usr.ReceptionID)
    
    			//generate the key
    			var privkey *cyclic.Int
    			if client.GetStorage().IsPrecanned() {
    				jww.WARN.Printf("Using Precanned DH key")
    				precannedID := binary.BigEndian.Uint64(
    					client.GetStorage().GetReceptionID()[:])
    				privkey = generatePrecanDHKeypair(
    					uint(precannedID),
    					client.GetStorage().GetE2EGroup())
    			} else if usr.E2eDhPrivateKey != nil {
    				jww.INFO.Printf("Using pre-existing DH key")
    				privkey = usr.E2eDhPrivateKey
    			} else {
    				jww.INFO.Printf("Generating new DH key")
    				rngStream := client.GetRng().GetStream()
    				privkey = diffieHellman.GeneratePrivateKey(
    					len(e2eGrp.GetPBytes()),
    					e2eGrp, rngStream)
    				rngStream.Close()
    			}
    
    			//initialize the e2e storage
    			err = e2e.Init(kv, usr.ReceptionID, privkey, e2eGrp,
    				rekey.GetDefaultParams())
    			if err != nil {
    				return nil, err
    			}
    
    			//load the new e2e storage
    			e2eHandler, err = e2e.Load(kv,
    				client.GetCmix(), usr.ReceptionID, e2eGrp, client.GetRng(),
    				client.GetEventReporter())
    			if err != nil {
    				return nil, errors.WithMessage(err, "Failed to load a "+
    					"newly created e2e store")
    			}
    		} else {
    			jww.INFO.Printf("Loaded a modern e2e instance for %s",
    				usr.ReceptionID)
    		}
    	} else {
    		jww.INFO.Printf("Loaded a legacy e2e instance for %s",
    			usr.ReceptionID)
    	}
    	return e2eHandler, nil
    }
    
    // GetUser replaces api.Client's GetUser with one which includes the e2e dh
    // private keys
    func (m *Client) GetUser() user.Info {
    	u := m.Client.GetUser()
    	u.E2eDhPrivateKey = m.e2e.GetHistoricalDHPrivkey()
    	u.E2eDhPublicKey = m.e2e.GetHistoricalDHPubkey()
    	return u
    }
    
    // ConstructProtoUserFile is a helper function which is used for proto
    // client testing.  This is used for development testing.
    func (m *Client) ConstructProtoUserFile() ([]byte, error) {
    
    	//load the registration code
    	regCode, err := m.GetStorage().GetRegCode()
    	if err != nil {
    		return nil, errors.WithMessage(err, "failed to register with "+
    			"permissioning")
    	}
    
    	Usr := user.Proto{
    		TransmissionID:               m.GetUser().TransmissionID,
    		TransmissionSalt:             m.GetUser().TransmissionSalt,
    		TransmissionRSA:              m.GetUser().TransmissionRSA,
    		ReceptionID:                  m.GetUser().ReceptionID,
    		ReceptionSalt:                m.GetUser().ReceptionSalt,
    		ReceptionRSA:                 m.GetUser().ReceptionRSA,
    		Precanned:                    m.GetUser().Precanned,
    		RegistrationTimestamp:        m.GetUser().RegistrationTimestamp,
    		RegCode:                      regCode,
    		TransmissionRegValidationSig: m.GetStorage().GetTransmissionRegistrationValidationSignature(),
    		ReceptionRegValidationSig:    m.GetStorage().GetReceptionRegistrationValidationSignature(),
    		E2eDhPrivateKey:              m.e2e.GetHistoricalDHPrivkey(),
    		E2eDhPublicKey:               m.e2e.GetHistoricalDHPubkey(),
    	}
    
    	jsonBytes, err := json.Marshal(Usr)
    	if err != nil {
    		return nil, errors.WithMessage(err, "failed to register with "+
    			"permissioning")
    	}
    
    	return jsonBytes, nil
    }
    
    func (m *Client) GetAuth() auth.State {
    	return m.auth
    }
    
    func (m *Client) GetE2E() e2e.Handler {
    	return m.e2e
    }
    
    func (m *Client) GetBackupContainer() *Container {
    	return m.backup
    }
    
    // DeleteContact is a function which removes a partner from Client's storage
    func (m *Client) DeleteContact(partnerId *id.ID) error {
    	jww.DEBUG.Printf("Deleting contact with ID %s", partnerId)
    
    	_, err := m.e2e.GetPartner(partnerId)
    	if err != nil {
    		return errors.WithMessagef(err, "Could not delete %s because "+
    			"they could not be found", partnerId)
    	}
    
    	if err = m.e2e.DeletePartner(partnerId); err != nil {
    		return err
    	}
    
    	m.backup.TriggerBackup("contact deleted")
    
    	// FIXME: Do we need this?
    	// c.e2e.Conversations().Delete(partnerId)
    
    	// call delete requests to make sure nothing is lingering.
    	// this is for saftey to ensure the contact can be readded
    	// in the future
    	_ = m.auth.DeleteRequest(partnerId)
    
    	return nil
    }