Skip to content
Snippets Groups Projects
Select Git revision
  • 9cf9bf61c7e4c67c53faa469bb2c252d4b092d79
  • 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

sendE2E.go

Blame
  • sendE2E.go 2.88 KiB
    ////////////////////////////////////////////////////////////////////////////////
    // Copyright © 2020 Privategrity Corporation                                   /
    //                                                                             /
    // All rights reserved.                                                        /
    ////////////////////////////////////////////////////////////////////////////////
    
    package message
    
    import (
    	"github.com/pkg/errors"
    	"gitlab.com/elixxir/client/interfaces/message"
    	"gitlab.com/elixxir/client/interfaces/params"
    	"gitlab.com/elixxir/client/keyExchange"
    	"gitlab.com/elixxir/crypto/e2e"
    	"gitlab.com/elixxir/primitives/format"
    	"gitlab.com/xx_network/primitives/id"
    	"sync"
    	"time"
    )
    
    func (m *Manager) SendE2E(msg message.Send, param params.E2E) ([]id.Round, e2e.MessageID, error) {
    
    	//timestamp the message
    	ts := time.Now()
    
    	//partition the message
    	partitions, internalMsgId, err := m.partitioner.Partition(msg.Recipient, msg.MessageType, ts,
    		msg.Payload)
    	if err != nil {
    		return nil, e2e.MessageID{}, errors.WithMessage(err, "failed to send unsafe message")
    	}
    
    	//encrypt then send the partitions over cmix
    	roundIds := make([]id.Round, len(partitions))
    	errCh := make(chan error, len(partitions))
    
    	// get the key manager for the partner
    	partner, err := m.Session.E2e().GetPartner(msg.Recipient)
    	if err != nil {
    		return nil, e2e.MessageID{}, errors.WithMessagef(err, "Could not send End to End encrypted "+
    			"message, no relationship found with %v", partner)
    	}
    
    	wg := sync.WaitGroup{}
    
    	for i, p := range partitions {
    		//create the cmix message
    		msgCmix := format.NewMessage(m.Session.Cmix().GetGroup().GetP().ByteLen())
    		msgCmix.SetContents(p)
    		msgCmix.SetRecipientID(msg.Recipient)
    
    		//get a key to end to end encrypt
    		key, err := partner.GetKeyForSending(param.Type)
    		if err != nil {
    			return nil, e2e.MessageID{}, errors.WithMessagef(err, "Failed to get key "+
    				"for end to end encryption")
    		}
    
    		//end to end encrypt the cmix message
    		msgEnc := key.Encrypt(msgCmix)
    
    		//send the cmix message, each partition in its own thread
    		wg.Add(1)
    		go func(i int) {
    			var err error
    			roundIds[i], err = m.SendCMIX(msgEnc, param.CMIX)
    			if err != nil {
    				errCh <- err
    			}
    			wg.Done()
    		}(i)
    	}
    
    	// while waiting check if any rekeys need to happen and trigger them. This
    	// can happen now because the key popping happens in this thread,
    	// only the sending is parallelized
    	keyExchange.CheckKeyExchanges(m.Instance, m.SendE2E, m.Session, partner, 1*time.Minute)
    
    	wg.Wait()
    
    	//see if any parts failed to send
    	numFail, errRtn := getSendErrors(errCh)
    	if numFail > 0 {
    		return nil, e2e.MessageID{}, errors.Errorf("Failed to E2E send %v/%v sub payloads:"+
    			" %s", numFail, len(partitions), errRtn)
    	}
    
    	//return the rounds if everything send successfully
    	msgID := e2e.NewMessageID(partner.GetSendRelationshipFingerprint(), internalMsgId)
    	return roundIds, msgID, nil
    }