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

auth.go

Blame
  • auth.go 6.33 KiB
    ///////////////////////////////////////////////////////////////////////////////
    // Copyright © 2020 xx network SEZC                                          //
    //                                                                           //
    // Use of this source code is governed by a license that can be found in the //
    // LICENSE file                                                              //
    ///////////////////////////////////////////////////////////////////////////////
    
    package api
    
    import (
    	"encoding/binary"
    	"gitlab.com/elixxir/client/e2e/ratchet/partner"
    	"math/rand"
    
    	"github.com/cloudflare/circl/dh/sidh"
    	"github.com/pkg/errors"
    	jww "github.com/spf13/jwalterweatherman"
    	"gitlab.com/elixxir/client/auth"
    	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
    	util "gitlab.com/elixxir/client/storage/utility"
    	"gitlab.com/elixxir/crypto/contact"
    	"gitlab.com/elixxir/primitives/fact"
    	"gitlab.com/xx_network/primitives/id"
    )
    
    // RequestAuthenticatedChannel sends a request to another party to establish an
    // authenticated channel
    // It will not run if the network state is not healthy
    // An error will be returned if a channel already exists or if a request was
    // already received
    // When a confirmation occurs, the channel will be created and the callback
    // will be called
    // Can be retried.
    func (c *Client) RequestAuthenticatedChannel(recipient, me contact.Contact,
    	message string) (id.Round, error) {
    	jww.INFO.Printf("RequestAuthenticatedChannel(%s)", recipient.ID)
    
    	if !c.network.IsHealthy() {
    		return 0, errors.New("Cannot request authenticated channel " +
    			"creation when the network is not healthy")
    	}
    
    	return c.auth.Request(recipient, c.GetUser().GetContact().Facts)
    }
    
    // ResetSession resets an authenticate channel that already exists
    func (c *Client) ResetSession(recipient, me contact.Contact,
    	message string) (id.Round, error) {
    	jww.INFO.Printf("ResetSession(%s)", recipient.ID)
    
    	if !c.network.IsHealthy() {
    		return 0, errors.New("Cannot request authenticated channel " +
    			"creation when the network is not healthy")
    	}
    
    	return c.auth.Reset(recipient)
    }
    
    // GetAuthRegistrar gets the object which allows the registration of auth
    // callbacks
    func (c *Client) GetAuthRegistrar() auth.State {
    	jww.INFO.Printf("GetAuthRegistrar(...)")
    
    	return c.auth
    }
    
    // GetAuthenticatedChannelRequest returns the contact received in a request if
    // one exists for the given userID.  Returns an error if no contact is found.
    func (c *Client) GetAuthenticatedChannelRequest(partner *id.ID) (contact.Contact, error) {
    	jww.INFO.Printf("GetAuthenticatedChannelRequest(%s)", partner)
    
    	return c.auth.GetReceivedRequest(partner)
    }
    
    // ConfirmAuthenticatedChannel creates an authenticated channel out of a valid
    // received request and sends a message to the requestor that the request has
    // been confirmed
    // It will not run if the network state is not healthy
    // An error will be returned if a channel already exists, if a request doest
    // exist, or if the passed in contact does not exactly match the received
    // request
    // Can be retried.
    func (c *Client) ConfirmAuthenticatedChannel(recipient contact.Contact) (id.Round, error) {
    	jww.INFO.Printf("ConfirmAuthenticatedChannel(%s)", recipient.ID)
    
    	if !c.network.IsHealthy() {
    		return 0, errors.New("Cannot request authenticated channel " +
    			"creation when the network is not healthy")
    	}
    
    	return c.auth.Confirm(recipient)
    }
    
    // VerifyOwnership checks if the ownership proof on a passed contact matches the
    // identity in a verified contact
    func (c *Client) VerifyOwnership(received, verified contact.Contact) bool {
    	jww.INFO.Printf("VerifyOwnership(%s)", received.ID)
    
    	return c.auth.VerifyOwnership(received, verified, c.e2e)
    }
    
    // HasAuthenticatedChannel returns true if an authenticated channel exists for
    // the partner
    func (c *Client) HasAuthenticatedChannel(partner *id.ID) bool {
    	m, err := c.e2e.GetPartner(partner)
    	return m != nil && err == nil
    }
    
    // Create an insecure e2e relationship with a precanned user
    func (c *Client) MakePrecannedAuthenticatedChannel(precannedID uint) (
    	contact.Contact, error) {
    
    	precan := c.MakePrecannedContact(precannedID)
    
    	myID := binary.BigEndian.Uint64(c.GetUser().GetContact().ID[:])
    	// Pick a variant based on if their ID is bigger than mine.
    	myVariant := sidh.KeyVariantSidhA
    	theirVariant := sidh.KeyVariant(sidh.KeyVariantSidhB)
    	if myID > uint64(precannedID) {
    		myVariant = sidh.KeyVariantSidhB
    		theirVariant = sidh.KeyVariantSidhA
    	}
    	prng1 := rand.New(rand.NewSource(int64(precannedID)))
    	theirSIDHPrivKey := util.NewSIDHPrivateKey(theirVariant)
    	theirSIDHPubKey := util.NewSIDHPublicKey(theirVariant)
    	theirSIDHPrivKey.Generate(prng1)
    	theirSIDHPrivKey.GeneratePublicKey(theirSIDHPubKey)
    
    	prng2 := rand.New(rand.NewSource(int64(myID)))
    	mySIDHPrivKey := util.NewSIDHPrivateKey(myVariant)
    	mySIDHPubKey := util.NewSIDHPublicKey(myVariant)
    	mySIDHPrivKey.Generate(prng2)
    	mySIDHPrivKey.GeneratePublicKey(mySIDHPubKey)
    
    	// add the precanned user as a e2e contact
    	// FIXME: these params need to be threaded through...
    	sesParam := session.GetDefaultParams()
    	_, err := c.e2e.AddPartner(precan.ID, precan.DhPubKey,
    		c.e2e.GetHistoricalDHPrivkey(), theirSIDHPubKey,
    		mySIDHPrivKey, sesParam, sesParam)
    
    	// check garbled messages in case any messages arrived before creating
    	// the channel
    	c.network.CheckInProgressMessages()
    
    	return precan, err
    }
    
    // Create an insecure e2e contact object for a precanned user
    func (c *Client) MakePrecannedContact(precannedID uint) contact.Contact {
    
    	e2eGrp := c.storage.GetE2EGroup()
    
    	precanned := createPrecannedUser(precannedID, c.rng.GetStream(),
    		c.storage.GetCmixGroup(), e2eGrp)
    
    	// compute their public e2e key
    	partnerPubKey := e2eGrp.ExpG(precanned.E2eDhPrivateKey,
    		e2eGrp.NewInt(1))
    
    	return contact.Contact{
    		ID:             precanned.ReceptionID,
    		DhPubKey:       partnerPubKey,
    		OwnershipProof: nil,
    		Facts:          make([]fact.Fact, 0),
    	}
    }
    
    // GetRelationshipFingerprint returns a unique 15 character fingerprint for an
    // E2E relationship. An error is returned if no relationship with the partner
    // is found.
    func (c *Client) GetRelationshipFingerprint(p *id.ID) (string, error) {
    	m, err := c.e2e.GetPartner(p)
    	if err != nil {
    		return "", errors.Errorf("could not get partner %s: %+v",
    			partner.ConnectionFp{}, err)
    	} else if m == nil {
    		return "", errors.Errorf("manager for partner %s is nil.",
    			p)
    	}
    
    	return m.ConnectionFingerprint().String(), nil
    }