Skip to content
Snippets Groups Projects
Commit a2a7cf0a authored by Jonah Husson's avatar Jonah Husson
Browse files

Merge branch 'restructure' into api2.0

parents 903777ee 16d746d2
No related branches found
No related tags found
3 merge requests!510Release,!226WIP: Api2.0,!207WIP: Client Restructure
...@@ -51,7 +51,8 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) ( ...@@ -51,7 +51,8 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) (
var sentRound id.Round var sentRound id.Round
//run the handler //run the handler
err := s.store.HandleReceivedRequest(partner.ID, func(rr *store.ReceivedRequest) error { err := s.store.HandleReceivedRequest(partner.ID,
func(rr *store.ReceivedRequest) error {
// verify the passed contact matches what is stored // verify the passed contact matches what is stored
if rr.GetContact().DhPubKey.Cmp(partner.DhPubKey) != 0 { if rr.GetContact().DhPubKey.Cmp(partner.DhPubKey) != 0 {
return errors.New("pending Auth Request has different " + return errors.New("pending Auth Request has different " +
...@@ -75,8 +76,8 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) ( ...@@ -75,8 +76,8 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) (
rng.Close() rng.Close()
/*construct message*/ /*construct message*/
// we build the payload before we save because it is technically fallible // we build the payload before we save because it is technically
// which can get into a bricked state if it fails // fallible which can get into a bricked state if it fails
baseFmt := newBaseFormat(s.net.GetMaxMessageLength(), baseFmt := newBaseFormat(s.net.GetMaxMessageLength(),
s.e2e.GetGroup().GetP().ByteLen()) s.e2e.GetGroup().GetP().ByteLen())
ecrFmt := newEcrFormat(baseFmt.GetEcrPayloadLen()) ecrFmt := newEcrFormat(baseFmt.GetEcrPayloadLen())
...@@ -104,9 +105,9 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) ( ...@@ -104,9 +105,9 @@ func (s *state) confirm(partner contact.Contact, serviceTag string) (
jww.TRACE.Printf("SendConfirm ECRPAYLOAD: %v", baseFmt.GetEcrPayload()) jww.TRACE.Printf("SendConfirm ECRPAYLOAD: %v", baseFmt.GetEcrPayload())
jww.TRACE.Printf("SendConfirm MAC: %v", mac) jww.TRACE.Printf("SendConfirm MAC: %v", mac)
// warning: channel can get into a bricked state if the first save occurs and // warning: channel can get into a bricked state if the first save
// the second does not or the two occur and the storage into critical // occurs and the second does not or the two occur and the storage
// messages does not occur // into critical messages does not occur
// create local relationship // create local relationship
p := session.GetDefaultParams() p := session.GetDefaultParams()
......
package auth package auth
import ( import (
"github.com/cloudflare/circl/dh/sidh"
"gitlab.com/elixxir/client/cmix"
"gitlab.com/elixxir/client/cmix/identity"
"gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/cmix/message"
"gitlab.com/elixxir/client/cmix/rounds"
"gitlab.com/elixxir/client/e2e" "gitlab.com/elixxir/client/e2e"
"gitlab.com/elixxir/client/e2e/ratchet/partner"
"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
"gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/primitives/fact" "gitlab.com/elixxir/primitives/fact"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/id/ephemeral"
) )
type State interface { type State interface {
...@@ -84,3 +95,47 @@ type State interface { ...@@ -84,3 +95,47 @@ type State interface {
// VerifyOwnership checks if the received ownership proof is valid // VerifyOwnership checks if the received ownership proof is valid
VerifyOwnership(received, verified contact.Contact, e2e e2e.Handler) bool VerifyOwnership(received, verified contact.Contact, e2e e2e.Handler) bool
} }
// Callbacks is the interface for auth callback methods.
type Callbacks interface {
Request(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
Confirm(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
Reset(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
}
// cmixClient is a sub-interface of cmix.Client with
// methods relevant to this package.
type cmixClient interface {
IsHealthy() bool
GetMaxMessageLength() int
AddService(clientID *id.ID, newService message.Service,
response message.Processor)
DeleteService(clientID *id.ID, toDelete message.Service,
processor message.Processor)
GetIdentity(get *id.ID) (identity.TrackedID, error)
AddFingerprint(identity *id.ID, fingerprint format.Fingerprint,
mp message.Processor) error
DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint)
Send(recipient *id.ID, fingerprint format.Fingerprint,
service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (
id.Round, ephemeral.Id, error)
}
// e2eHandler is a sub-interface of e2e.Handler containing
// methods relevant to this package.
type e2eHandler interface {
GetHistoricalDHPubkey() *cyclic.Int
GetHistoricalDHPrivkey() *cyclic.Int
GetGroup() *cyclic.Group
AddPartner(partnerID *id.ID,
partnerPubKey, myPrivKey *cyclic.Int,
partnerSIDHPubKey *sidh.PublicKey,
mySIDHPrivKey *sidh.PrivateKey, sendParams,
receiveParams session.Params) (partner.Manager, error)
GetPartner(partnerID *id.ID) (partner.Manager, error)
DeletePartner(partnerId *id.ID) error
GetReceptionID() *id.ID
}
...@@ -10,27 +10,19 @@ package auth ...@@ -10,27 +10,19 @@ package auth
import ( import (
"encoding/base64" "encoding/base64"
"github.com/cloudflare/circl/dh/sidh"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/client/auth/store" "gitlab.com/elixxir/client/auth/store"
"gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix"
"gitlab.com/elixxir/client/cmix/identity"
"gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/identity/receptionID"
"gitlab.com/elixxir/client/cmix/message" "gitlab.com/elixxir/client/cmix/message"
"gitlab.com/elixxir/client/cmix/rounds"
"gitlab.com/elixxir/client/e2e" "gitlab.com/elixxir/client/e2e"
"gitlab.com/elixxir/client/e2e/ratchet/partner"
"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
"gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/event"
"gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/elixxir/crypto/contact"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/id/ephemeral"
) )
// state is an implementation of the State interface.
type state struct { type state struct {
callbacks Callbacks callbacks Callbacks
...@@ -46,45 +38,6 @@ type state struct { ...@@ -46,45 +38,6 @@ type state struct {
backupTrigger func(reason string) backupTrigger func(reason string)
} }
type cmixClient interface {
IsHealthy() bool
GetMaxMessageLength() int
AddService(clientID *id.ID, newService message.Service,
response message.Processor)
DeleteService(clientID *id.ID, toDelete message.Service,
processor message.Processor)
GetIdentity(get *id.ID) (identity.TrackedID, error)
AddFingerprint(identity *id.ID, fingerprint format.Fingerprint,
mp message.Processor) error
DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint)
Send(recipient *id.ID, fingerprint format.Fingerprint,
service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (
id.Round, ephemeral.Id, error)
}
type e2eHandler interface {
GetHistoricalDHPubkey() *cyclic.Int
GetHistoricalDHPrivkey() *cyclic.Int
GetGroup() *cyclic.Group
AddPartner(partnerID *id.ID,
partnerPubKey, myPrivKey *cyclic.Int,
partnerSIDHPubKey *sidh.PublicKey,
mySIDHPrivKey *sidh.PrivateKey, sendParams,
receiveParams session.Params) (partner.Manager, error)
GetPartner(partnerID *id.ID) (partner.Manager, error)
DeletePartner(partnerId *id.ID) error
GetReceptionID() *id.ID
}
type Callbacks interface {
Request(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
Confirm(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
Reset(partner contact.Contact, receptionID receptionID.EphemeralIdentity,
round rounds.Round)
}
// NewState loads the auth state or creates new auth state if one cannot be // NewState loads the auth state or creates new auth state if one cannot be
// found. // found.
// Bases its reception identity and keys off of what is found in e2e. // Bases its reception identity and keys off of what is found in e2e.
...@@ -92,8 +45,8 @@ type Callbacks interface { ...@@ -92,8 +45,8 @@ type Callbacks interface {
// Parameters: // Parameters:
// The params object passed in determines the services that will be used // The params object passed in determines the services that will be used
// to pick up requests and signal notifications. These are unique to an // to pick up requests and signal notifications. These are unique to an
// identity, so multiple auth states with the same service tags with different // identity, so multiple auth states with the same service tags with
// identities can run simultaneously. // different identities can run simultaneously.
// Default parameters can be retrieved via GetDefaultParameters() // Default parameters can be retrieved via GetDefaultParameters()
// Temporary: // Temporary:
// In some cases, for example client <-> server communications, connections // In some cases, for example client <-> server communications, connections
...@@ -108,10 +61,9 @@ func NewState(kv *versioned.KV, net cmix.Client, e2e e2e.Handler, ...@@ -108,10 +61,9 @@ func NewState(kv *versioned.KV, net cmix.Client, e2e e2e.Handler,
kv, net, e2e, rng, event, params, callbacks, backupTrigger) kv, net, e2e, rng, event, params, callbacks, backupTrigger)
} }
// NewStateLegacy loads the auth state or creates new auth state if one cannot be // NewStateLegacy loads the auth state or creates new auth state if one cannot
// found. // be found. Bases its reception identity and keys off of what is found in e2e.
// Bases its reception identity and keys off of what is found in e2e. // Does not modify the kv prefix for backwards compatibility.
// Does not modify the kv prefix for backwards compatibility
// Otherwise, acts the same as NewState // Otherwise, acts the same as NewState
func NewStateLegacy(kv *versioned.KV, net cmix.Client, e2e e2e.Handler, func NewStateLegacy(kv *versioned.KV, net cmix.Client, e2e e2e.Handler,
rng *fastRNG.StreamGenerator, event event.Reporter, params Params, rng *fastRNG.StreamGenerator, event event.Reporter, params Params,
...@@ -152,13 +104,14 @@ func NewStateLegacy(kv *versioned.KV, net cmix.Client, e2e e2e.Handler, ...@@ -152,13 +104,14 @@ func NewStateLegacy(kv *versioned.KV, net cmix.Client, e2e e2e.Handler,
return s, nil return s, nil
} }
// CallAllReceivedRequests will iterate through all pending contact requests and replay // CallAllReceivedRequests will iterate through all pending contact requests
// them on the callbacks. // and replay them on the callbacks.
func (s *state) CallAllReceivedRequests() { func (s *state) CallAllReceivedRequests() {
rrList := s.store.GetAllReceivedRequests() rrList := s.store.GetAllReceivedRequests()
for i := range rrList { for i := range rrList {
rr := rrList[i] rr := rrList[i]
eph := receptionID.BuildIdentityFromRound(rr.GetContact().ID, rr.GetRound()) eph := receptionID.BuildIdentityFromRound(rr.GetContact().ID,
rr.GetRound())
s.callbacks.Request(rr.GetContact(), eph, rr.GetRound()) s.callbacks.Request(rr.GetContact(), eph, rr.GetRound())
} }
} }
......
package store package store
// SentRequestHandler allows the lower fevel to assign and remove services // SentRequestHandler allows the lower level to assign and remove services
type SentRequestHandler interface { type SentRequestHandler interface {
Add(sr *SentRequest) Add(sr *SentRequest)
Delete(sr *SentRequest) Delete(sr *SentRequest)
......
...@@ -48,3 +48,30 @@ const ( ...@@ -48,3 +48,30 @@ const (
// (see the connect/ package) // (see the connect/ package)
ConnectionAuthenticationRequest = 60 ConnectionAuthenticationRequest = 60
) )
func (mt MessageType) String() string {
switch mt {
case NoType:
return "NoType"
case XxMessage:
return "XxMessage"
case KeyExchangeTrigger:
return "KeyExchangeTrigger"
case KeyExchangeConfirm:
return "KeyExchangeConfirm"
case KeyExchangeTriggerEphemeral:
return "KeyExchangeTriggerEphemeral"
case KeyExchangeConfirmEphemeral:
return "KeyExchangeConfirmEphemeral"
case GroupCreationRequest:
return "GroupCreationRequest"
case NewFileTransfer:
return "NewFileTransfer"
case EndFileTransfer:
return "EndFileTransfer"
case ConnectionAuthenticationRequest:
return "ConnectionAuthenticationRequest"
default:
return "UNKNOWN TYPE"
}
}
...@@ -418,16 +418,16 @@ func (h *HostPool) UpdateNdf(ndf *ndf.NetworkDefinition) { ...@@ -418,16 +418,16 @@ func (h *HostPool) UpdateNdf(ndf *ndf.NetworkDefinition) {
return return
} }
// Lock order is extremely important here
h.hostMux.Lock()
h.ndfMux.Lock() h.ndfMux.Lock()
h.ndf = ndf.DeepCopy() h.ndf = ndf.DeepCopy()
h.hostMux.Lock()
err := h.updateConns() err := h.updateConns()
h.hostMux.Unlock()
if err != nil { if err != nil {
jww.ERROR.Printf("Unable to updateConns: %+v", err) jww.ERROR.Printf("Unable to updateConns: %+v", err)
} }
h.ndfMux.Unlock() h.ndfMux.Unlock()
h.hostMux.Unlock()
} }
// SetGatewayFilter sets the filter used to filter gateways from the ID map. // SetGatewayFilter sets the filter used to filter gateways from the ID map.
...@@ -566,8 +566,9 @@ func (h *HostPool) checkReplace(hostId *id.ID, hostErr error) (bool, error) { ...@@ -566,8 +566,9 @@ func (h *HostPool) checkReplace(hostId *id.ID, hostErr error) (bool, error) {
} }
} }
if doReplace {
// If the Host is still in the pool // If the Host is still in the pool
if doReplace {
// Lock order is extremely important here
h.hostMux.Lock() h.hostMux.Lock()
if oldPoolIndex, ok := h.hostMap[*hostId]; ok { if oldPoolIndex, ok := h.hostMap[*hostId]; ok {
// Replace it // Replace it
......
...@@ -58,7 +58,7 @@ func registerNodes(r *registrar, s session, stop *stoppable.Single, ...@@ -58,7 +58,7 @@ func registerNodes(r *registrar, s session, stop *stoppable.Single,
// Check if the registrar has this node already // Check if the registrar has this node already
if r.HasNode(nid) { if r.HasNode(nid) {
jww.INFO.Printf( jww.TRACE.Printf(
"Not registering node %s, already registered", nid) "Not registering node %s, already registered", nid)
} }
...@@ -95,7 +95,7 @@ func registerNodes(r *registrar, s session, stop *stoppable.Single, ...@@ -95,7 +95,7 @@ func registerNodes(r *registrar, s session, stop *stoppable.Single,
// Process the result // Process the result
if err != nil { if err != nil {
jww.ERROR.Printf("Failed to register nodes: %+v", err) jww.ERROR.Printf("Failed to register nodes: %s", err.Error())
// If we have not reached the attempt limit for this gateway, // If we have not reached the attempt limit for this gateway,
// then send it back into the channel to retry // then send it back into the channel to retry
if numAttempts < maxAttempts { if numAttempts < maxAttempts {
...@@ -149,7 +149,7 @@ func registerWithNode(sender gateway.Sender, comms RegisterNodeCommsInterface, ...@@ -149,7 +149,7 @@ func registerWithNode(sender gateway.Sender, comms RegisterNodeCommsInterface,
sender, comms, ngw, s, r, rng, stop) sender, comms, ngw, s, r, rng, stop)
if err != nil { if err != nil {
return errors.Errorf("Failed to request key: %+v", err) return errors.Errorf("Failed to request key: %v", err)
} }
} }
......
///////////////////////////////////////////////////////////////////////////////
// Copyright © 2020 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
///////////////////////////////////////////////////////////////////////////////
package e2e
import (
"gitlab.com/elixxir/client/catalog"
"gitlab.com/elixxir/client/e2e/parse"
"gitlab.com/elixxir/client/e2e/ratchet"
"gitlab.com/elixxir/client/e2e/receive"
"gitlab.com/elixxir/client/e2e/rekey"
"gitlab.com/elixxir/client/storage/versioned"
dh "gitlab.com/elixxir/crypto/diffieHellman"
"gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/ekv"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/id"
"testing"
)
func TestManager_SendUnsafe(t *testing.T) {
streamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG)
rng := streamGen.GetStream()
defer rng.Close()
netHandler := newMockCmixHandler()
// Generate new E2E manager
myKv := versioned.NewKV(ekv.MakeMemstore())
myID := id.NewIdFromString("myID", id.User, t)
myNet := newMockCmix(myID, netHandler, t)
m1 := &manager{
Switchboard: receive.New(),
partitioner: parse.NewPartitioner(myKv, myNet.GetMaxMessageLength()),
net: myNet,
myID: myID,
events: mockEventsManager{},
grp: myNet.GetInstance().GetE2EGroup(),
rekeyParams: rekey.GetDefaultParams(),
}
myPrivKey := dh.GeneratePrivateKey(
dh.DefaultPrivateKeyLength, m1.grp, rng)
err := ratchet.New(myKv, myID, myPrivKey, m1.grp)
if err != nil {
t.Errorf("Failed to generate new ratchet: %+v", err)
}
myFpGen := &fpGenerator{m1}
myServices := newMockServices()
m1.Ratchet, err = ratchet.Load(
myKv, myID, m1.grp, myFpGen, myServices, streamGen)
// Generate new E2E manager
partnerKv := versioned.NewKV(ekv.MakeMemstore())
partnerID := id.NewIdFromString("partnerID", id.User, t)
partnerNet := newMockCmix(partnerID, netHandler, t)
m2 := &manager{
Switchboard: receive.New(),
partitioner: parse.NewPartitioner(partnerKv, partnerNet.GetMaxMessageLength()),
net: partnerNet,
myID: partnerID,
events: mockEventsManager{},
grp: partnerNet.GetInstance().GetE2EGroup(),
rekeyParams: rekey.GetDefaultParams(),
}
receiveChan := make(chan receive.Message, 10)
m2.Switchboard.RegisterListener(partnerID, catalog.NoType, &mockListener{receiveChan})
partnerPrivKey := dh.GeneratePrivateKey(
dh.DefaultPrivateKeyLength, m2.grp, rng)
err = ratchet.New(partnerKv, partnerID, partnerPrivKey, m2.grp)
if err != nil {
t.Errorf("Failed to generate new ratchet: %+v", err)
}
partnerFpGen := &fpGenerator{m2}
partnerServices := newMockServices()
m1.Ratchet, err = ratchet.Load(
partnerKv, partnerID, m2.grp, partnerFpGen, partnerServices, streamGen)
// Generate partner identity and add partner
partnerPubKey, partnerSidhPubKey, mySidhPrivKey, sessionParams :=
genPartnerKeys(partnerPrivKey, m1.grp, rng, t)
_, err = m1.Ratchet.AddPartner(partnerID, partnerPubKey, myPrivKey,
partnerSidhPubKey, mySidhPrivKey, sessionParams, sessionParams)
if err != nil {
t.Errorf("Failed to add partner: %+v", err)
}
payload := []byte("My Payload")
p := GetDefaultParams()
_, _, err = m1.sendUnsafe(catalog.NoType, partnerID, payload, p)
if err != nil {
t.Fatalf("sendUnsafe error: %v", err)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment