Skip to content
Snippets Groups Projects
Commit 2e58aa11 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

Merge remote-tracking branch 'origin/peppa/newClient' into peppa/newClient

parents 0f3f9a9f be893f58
No related branches found
No related tags found
No related merge requests found
Showing
with 1046 additions and 19 deletions
...@@ -23,8 +23,8 @@ update_release: ...@@ -23,8 +23,8 @@ update_release:
GOFLAGS="" go get -u gitlab.com/elixxir/primitives@peppa/newClient GOFLAGS="" go get -u gitlab.com/elixxir/primitives@peppa/newClient
GOFLAGS="" go get -u gitlab.com/elixxir/crypto@peppa/newClient GOFLAGS="" go get -u gitlab.com/elixxir/crypto@peppa/newClient
GOFLAGS="" go get -u gitlab.com/xx_network/crypto@release GOFLAGS="" go get -u gitlab.com/xx_network/crypto@release
GOFLAGS="" go get -u gitlab.com/elixxir/comms@release GOFLAGS="" go get -u gitlab.com/elixxir/comms@hotfix/TestingFunction
GOFLAGS="" go get -u gitlab.com/xx_network/comms@release GOFLAGS="" go get -u gitlab.com/xx_network/comms@hotfix/TestingFunction
GOFLAGS="" go get -u gitlab.com/xx_network/primitives@release GOFLAGS="" go get -u gitlab.com/xx_network/primitives@release
update_master: update_master:
......
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
jww "github.com/spf13/jwalterweatherman"
"io"
"io/ioutil"
"log"
"os"
)
// Log is logging everything to this notepad so that the CUI can replace it
// with its own notepad and get logging statements from the client
var Log = jww.NewNotepad(jww.LevelInfo, jww.LevelInfo, os.Stdout,
ioutil.Discard, "CLIENT", log.Ldate|log.Ltime)
// InitLog initializes logging thresholds and the log path.
// verbose turns on debug logging, setting the log path to nil
// uses std out.
func InitLog(verbose bool, logPath string) *jww.Notepad {
logLevel := jww.LevelInfo
logFlags := (log.Ldate | log.Ltime)
stdOut := io.Writer(os.Stdout)
logFile := ioutil.Discard
// If the verbose flag is set, print all logs and
// print microseconds as well
if verbose {
logLevel = jww.LevelDebug
logFlags = (log.Ldate | log.Ltime | log.Lmicroseconds)
}
// If the logpath is empty or not set to - (stdout),
// set up the log file and do not log to stdout
if logPath != "" && logPath != "-" {
// Create log file, overwrites if existing
lF, err := os.OpenFile(logPath,
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
Log.WARN.Println("Invalid or missing log path," +
" stdout used.")
} else {
logFile = io.Writer(lF)
stdOut = ioutil.Discard
}
}
return jww.NewNotepad(logLevel, logLevel, stdOut, logFile,
"CLIENT", logFlags)
}
package globals
//Registration
const REG_KEYGEN = 1 //Generating Cryptographic Keys
const REG_PRECAN = 2 //Doing a Precanned Registration (Not Secure)
const REG_UID_GEN = 3 //Generating User ID
const REG_PERM = 4 //Validating User Identity With Permissioning Server
const REG_NODE = 5 //Registering with Nodes
const REG_FAIL = 6 //Failed to Register with Nodes
const REG_SECURE_STORE = 7 //Creating Local Secure Session
const REG_SAVE = 8 //Storing Session
//UDB registration
const UDB_REG_PUSHKEY = 9 //Pushing Cryptographic Material to the User Discovery Bot
const UDB_REG_PUSHUSER = 10 //Registering User with the User Discovery Bot
//UDB Search
const UDB_SEARCH_LOOK = 11 //Searching for User in User Discovery
const UDB_SEARCH_GETKEY = 12 //Getting Keying Material From User Discovery
const UDB_SEARCH_BUILD_CREDS = 13 //Building secure end to end relationship
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"os"
"sync"
)
const (
NoSave uint8 = iota
LocationA
LocationB
)
type Storage interface {
SetLocation(string, string) error
GetLocation() (string, string)
SaveA([]byte) error
SaveB([]byte) error
LoadA() []byte
LoadB() []byte
IsEmpty() bool
}
type DefaultStorage struct {
locationA string
locationB string
sync.Mutex
}
func (ds *DefaultStorage) SetLocation(locationA, locationB string) error {
ds.Lock()
ds.locationA = locationA
ds.locationB = locationB
ds.Unlock()
return nil
}
func (ds *DefaultStorage) GetLocation() (string, string) {
ds.Lock()
defer ds.Unlock()
return ds.locationA, ds.locationB
}
func (ds *DefaultStorage) IsEmpty() bool {
_, err := os.Stat(ds.locationA)
firstEmpty := err != nil && os.IsNotExist(err)
_, err = os.Stat(ds.locationB)
secondEmpty := err != nil && os.IsNotExist(err)
return firstEmpty && secondEmpty
}
func (ds *DefaultStorage) SaveA(data []byte) error {
return dsSaveHelper(ds.locationA, data)
}
func (ds *DefaultStorage) LoadA() []byte {
return dsLoadHelper(ds.locationA)
}
func (ds *DefaultStorage) SaveB(data []byte) error {
return dsSaveHelper(ds.locationB, data)
}
func (ds *DefaultStorage) LoadB() []byte {
return dsLoadHelper(ds.locationB)
}
type RamStorage struct {
DataA []byte
DataB []byte
}
func (rs *RamStorage) SetLocation(string, string) error {
return nil
}
func (rs *RamStorage) GetLocation() (string, string) {
return "", ""
}
func (rs *RamStorage) SaveA(data []byte) error {
rs.DataA = make([]byte, len(data))
copy(rs.DataA, data)
return nil
}
func (rs *RamStorage) SaveB(data []byte) error {
rs.DataB = make([]byte, len(data))
copy(rs.DataB, data)
return nil
}
func (rs *RamStorage) LoadA() []byte {
b := make([]byte, len(rs.DataA))
copy(b, rs.DataA)
return b
}
func (rs *RamStorage) LoadB() []byte {
b := make([]byte, len(rs.DataB))
copy(b, rs.DataB)
return b
}
func (rs *RamStorage) IsEmpty() bool {
return (rs.DataA == nil || len(rs.DataA) == 0) && (rs.DataB == nil || len(rs.DataB) == 0)
}
func dsLoadHelper(loc string) []byte {
// Check if the file exists, return nil if it does not
finfo, err1 := os.Stat(loc)
if err1 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file check: \n %v", err1.Error())
return nil
}
b := make([]byte, finfo.Size())
// Open the file, return nil if it cannot be opened
f, err2 := os.Open(loc)
defer func() {
if f != nil {
f.Close()
} else {
Log.WARN.Println("Could not close file, file is nil")
}
}()
if err2 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file open: \n %v", err2.Error())
return nil
}
// Read the data from the file, return nil if read fails
_, err3 := f.Read(b)
if err3 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file read: \n %v", err3.Error())
return nil
}
return b
}
func dsSaveHelper(loc string, data []byte) error {
//check if the file exists, delete if it does
_, err1 := os.Stat(loc)
if err1 == nil {
errRmv := os.Remove(loc)
if errRmv != nil {
Log.WARN.Printf("Could not remove Storage File B: %s", errRmv)
}
} else if !os.IsNotExist(err1) {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file check: \n %v",
err1.Error())
return err1
}
//create new file
f, err2 := os.Create(loc)
defer func() {
if f != nil {
f.Close()
} else {
Log.WARN.Println("Could not close file, file is nil")
}
}()
if err2 != nil {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file creation: \n %v", err2.Error())
return err2
}
//Save to file
_, err3 := f.Write(data)
if err3 != nil {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file write: \n %v", err3.Error())
return err3
}
return nil
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"os"
"reflect"
"testing"
)
func TestInitStorage(t *testing.T) {
TestDataA := []byte{12, 14, 54}
TestDataB := []byte{69, 42, 32}
TestSaveLocA := "testStorageA.data"
TestSaveLocB := "testStorageB.data"
// Test DefaultStorage initialization without existing storage
storage := &DefaultStorage{}
//Check that storage is empty prior to any Save calls
if !storage.IsEmpty() {
t.Errorf("ds.IsEmpty failed to detect an empty storage")
}
storage.SetLocation(TestSaveLocA, TestSaveLocB)
// Test DS saveA
err := storage.SaveA(TestDataA)
if err != nil {
t.Errorf("ds.Save failed to create a save file A at: %v",
TestSaveLocA)
}
// Check that save file was made
if !exists(TestSaveLocA) {
t.Errorf("ds.Save failed to create a save file A at: %v",
TestSaveLocA)
}
//Check that the storage is not empty after a saveA call
if storage.IsEmpty() {
t.Errorf("ds.IsEmpty failed to detect a non-empty storage")
}
// Test DS loadA
actualData := storage.LoadA()
if reflect.DeepEqual(actualData, TestDataA) != true {
t.Errorf("ds.Load failed to load expected data on A. Expected:%v Actual:%v",
TestDataA, actualData)
}
// Test DS saveB
err = storage.SaveB(TestDataB)
if err != nil {
t.Errorf("ds.Save failed to create a save file B at: %v",
TestSaveLocB)
}
// Check that save file was made
if !exists(TestSaveLocB) {
t.Errorf("ds.Save failed to create a save file B at: %v",
TestSaveLocB)
}
// Test DS loadA
actualData = storage.LoadB()
if reflect.DeepEqual(actualData, TestDataB) != true {
t.Errorf("ds.Load failed to load expected data on B. Expected:%v Actual:%v",
TestDataB, actualData)
}
// Test RamStorage
store := RamStorage{}
actualData = nil
// Test A
store.SaveA(TestDataA)
actualData = store.LoadA()
if reflect.DeepEqual(actualData, TestDataA) != true {
t.Errorf("rs.Load failed to load expected data A. Expected:%v Actual:%v",
TestDataA, actualData)
}
//Test B
store.SaveB(TestDataB)
actualData = store.LoadB()
if reflect.DeepEqual(actualData, TestDataB) != true {
t.Errorf("rs.Load failed to load expected data B. Expected:%v Actual:%v",
TestDataB, actualData)
}
os.Remove(TestSaveLocA)
os.Remove(TestSaveLocB)
}
// exists returns whether the given file or directory exists or not
func exists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return true
}
func TestDefaultStorage_GetLocation(t *testing.T) {
locationA := "hi"
locationB := "hi2"
ds := DefaultStorage{locationA: locationA, locationB: locationB}
recievedLocA, recievedLocB := ds.GetLocation()
if recievedLocA != locationA {
t.Errorf("defaultStorage.GetLocation returned incorrect location A. Expected:%v Actual:%v",
locationA, recievedLocA)
}
if recievedLocB != locationB {
t.Errorf("defaultStorage.GetLocation returned incorrect location B. Expected:%v Actual:%v",
locationB, recievedLocB)
}
}
func TestRamStorage_GetLocation(t *testing.T) {
ds := RamStorage{}
a, b := ds.GetLocation()
if a != "" && b != "" {
t.Errorf("RamStorage.GetLocation returned incorrect location. Actual: '', ''; Expected:'%v','%v'",
a, b)
}
}
func Test_dsLoadHelper_LocError(t *testing.T) {
testLoc := "~a/test"
result := dsLoadHelper(testLoc)
if result != nil {
t.Errorf("dsLoadHelper() did not error on invalid path.")
}
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"time"
)
type ThreadTerminator chan chan bool
func NewThreadTerminator() ThreadTerminator {
t := make(chan chan bool, 1)
return t
}
func (t ThreadTerminator) Terminate() {
t <- nil
}
// Try's to kill a thread controlled by a termination channel for the length of
// the timeout, returns its success. pass 0 for no timeout
func (t ThreadTerminator) BlockingTerminate(timeout uint64) bool {
killNotify := make(chan bool)
defer close(killNotify)
if timeout != 0 {
timer := time.NewTimer(time.Duration(timeout) * time.Millisecond)
defer timer.Stop()
t <- killNotify
select {
case _ = <-killNotify:
return true
case <-timer.C:
return false
}
} else {
_ = <-killNotify
return true
}
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"testing"
"time"
)
func TestNewThreadTerminator(t *testing.T) {
term := NewThreadTerminator()
var success bool
go func(term ThreadTerminator) {
term <- nil
}(term)
timer := time.NewTimer(time.Duration(1000) * time.Millisecond)
defer timer.Stop()
select {
case _ = <-term:
success = true
case <-timer.C:
success = false
}
if !success {
t.Errorf("NewThreadTerminator: Could not use the ThreadTerminator to" +
" stop a thread")
}
}
func TestBlockingTerminate(t *testing.T) {
term := NewThreadTerminator()
go func(term ThreadTerminator) {
var killNotify chan<- bool
q := false
for !q {
select {
case killNotify = <-term:
q = true
}
close(term)
killNotify <- true
}
}(term)
success := term.BlockingTerminate(1000)
if !success {
t.Errorf("BlockingTerminate: Thread did not terminate in time")
}
}
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-08-10 10:05:18.2662998 -0700 PDT m=+0.116012701
package globals
const GITVERSION = `127a946 Merge branch 'XX-2415/NodeKeys' into 'Optimus/ClientStorage'`
const SEMVER = "1.4.0"
const DEPENDENCIES = `module gitlab.com/elixxir/client
go 1.13
require (
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
github.com/golang/protobuf v1.4.2
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
gitlab.com/elixxir/comms v0.0.0-20200805174832-240bba97beaa
gitlab.com/elixxir/crypto v0.0.0-20200805174804-bdf909f2a16d
gitlab.com/elixxir/ekv v0.1.1
gitlab.com/elixxir/primitives v0.0.0-20200805174810-86b366d1dd2d
gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023
gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/sys v0.0.0-20200806125547-5acd03effb82 // indirect
gopkg.in/ini.v1 v1.52.0 // indirect
)
replace google.golang.org/grpc => github.com/grpc/grpc-go v1.27.1
`
...@@ -5,23 +5,19 @@ go 1.13 ...@@ -5,23 +5,19 @@ go 1.13
require ( require (
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/magiconair/properties v1.8.4 // indirect github.com/magiconair/properties v1.8.4 // indirect
github.com/mitchellh/mapstructure v1.3.3 // indirect github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect github.com/pelletier/go-toml v1.8.1 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/spf13/afero v1.4.0 // indirect github.com/spf13/afero v1.4.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.0.0 github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.1 github.com/spf13/viper v1.7.1
gitlab.com/elixxir/comms v0.0.0-20200924210331-d7903c023fa6 gitlab.com/elixxir/comms v0.0.0-20200924225440-76e02f95fb92
gitlab.com/elixxir/crypto v0.0.0-20200921195205-bca0178268ec gitlab.com/elixxir/crypto v0.0.0-20200921195205-bca0178268ec
gitlab.com/elixxir/ekv v0.1.3 gitlab.com/elixxir/ekv v0.1.3
gitlab.com/elixxir/primitives v0.0.0-20200915190719-f4586ec93f50 gitlab.com/elixxir/primitives v0.0.0-20200915190719-f4586ec93f50
gitlab.com/xx_network/comms v0.0.0-20200924172734-1124191b69ee gitlab.com/xx_network/comms v0.0.0-20200924225518-0c867207b1e6
gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686 gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686
gitlab.com/xx_network/primitives v0.0.0-20200915204206-eb0287ed0031 gitlab.com/xx_network/primitives v0.0.0-20200915204206-eb0287ed0031
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect
......
package keyExchange
import (
"github.com/golang/protobuf/proto"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/storage/e2e"
"gitlab.com/xx_network/primitives/id"
"testing"
"time"
)
// Smoke test for handleTrigger
func TestHandleConfirm(t *testing.T) {
// Generate alice and bob's session
aliceSession, _ := InitTestingContextGeneric(t)
bobSession, _ := InitTestingContextGeneric(t)
// Maintain an ID for bob
bobID := id.NewIdFromBytes([]byte("test"), t)
// Pull the keys for Alice and Bob
alicePrivKey := aliceSession.E2e().GetDHPrivateKey()
bobPubKey := bobSession.E2e().GetDHPublicKey()
// Add bob as a partner
aliceSession.E2e().AddPartner(bobID, bobPubKey,
e2e.GetDefaultSessionParams(), e2e.GetDefaultSessionParams())
// Generate a session ID, bypassing some business logic here
sessionID := GeneratePartnerID(alicePrivKey, bobPubKey, genericGroup)
// Generate the message
rekey, _ := proto.Marshal(&RekeyConfirm{
SessionID: sessionID.Marshal(),
})
payload := make([]byte, 0)
payload = append(payload, rekey...)
receiveMsg := message.Receive{
Payload: payload,
MessageType: message.NoType,
Sender: bobID,
Timestamp: time.Now(),
Encryption: message.E2E,
}
// Handle the confirmation
handleConfirm(aliceSession, receiveMsg)
}
package keyExchange
import (
"github.com/golang/protobuf/proto"
"gitlab.com/elixxir/client/interfaces"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/e2e"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/xx_network/primitives/id"
"testing"
"time"
)
var exchangeAliceId, exchangeBobId *id.ID
var aliceSession, bobSession *storage.Session
var aliceSwitchboard, bobSwitchboard *switchboard.Switchboard
var aliceManager, bobManager interfaces.NetworkManager
func TestFullExchange(t *testing.T) {
// Initialzie alice's and bob's session, switchboard and network managers
aliceSession, aliceSwitchboard, aliceManager = InitTestingContextFullExchange(t)
bobSession, bobSwitchboard, bobManager = InitTestingContextFullExchange(t)
// Assign ID's to alice and bob
exchangeAliceId = id.NewIdFromBytes([]byte("1234"), t)
exchangeBobId = id.NewIdFromBytes([]byte("test"), t)
// Pull alice's and bob's keys for later use
alicePrivKey := aliceSession.E2e().GetDHPrivateKey()
alicePubKey := aliceSession.E2e().GetDHPublicKey()
bobPubKey := bobSession.E2e().GetDHPublicKey()
// Add Alice and Bob as partners
aliceSession.E2e().AddPartner(exchangeBobId, bobPubKey,
e2e.GetDefaultSessionParams(), e2e.GetDefaultSessionParams())
bobSession.E2e().AddPartner(exchangeAliceId, alicePubKey,
e2e.GetDefaultSessionParams(), e2e.GetDefaultSessionParams())
// Start the listeners for alice and bob
Start(aliceSwitchboard, aliceSession, aliceManager)
Start(bobSwitchboard, bobSession, bobManager)
// Generate a session ID, bypassing some business logic here
sessionID := GeneratePartnerID(alicePrivKey, bobPubKey, genericGroup)
// Generate the message
rekeyTrigger, _ := proto.Marshal(&RekeyTrigger{
SessionID: sessionID.Marshal(),
PublicKey: bobPubKey.Bytes(),
})
payload := make([]byte, 0)
payload = append(payload, rekeyTrigger...)
triggerMsg := message.Receive{
Payload: payload,
MessageType: message.KeyExchangeTrigger,
Sender: exchangeBobId,
Timestamp: time.Now(),
Encryption: message.E2E,
}
// Speak the message to Bob, triggers the SendE2E in utils_test
aliceSwitchboard.Speak(triggerMsg)
// Allow the test time to work it's goroutines
time.Sleep(1 * time.Second)
}
...@@ -67,8 +67,9 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager, ...@@ -67,8 +67,9 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager,
//get the old session which triggered the exchange //get the old session which triggered the exchange
oldSession := partner.GetSendSession(oldSessionID) oldSession := partner.GetSendSession(oldSessionID)
if oldSession == nil { if oldSession == nil {
jww.ERROR.Printf("no session %s for partner %s: %s", err := errors.Errorf("no session %s for partner %s: %s",
oldSession, request.Sender, err) oldSession, request.Sender, err)
jww.ERROR.Printf(err.Error())
return err return err
} }
...@@ -124,10 +125,8 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager, ...@@ -124,10 +125,8 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager,
roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute, roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute,
states.COMPLETED, states.FAILED) states.COMPLETED, states.FAILED)
} }
//Wait until the result tracking responds //Wait until the result tracking responds
success, numTimeOut, numRoundFail := utility.TrackResults(sendResults, len(rounds)) success, numTimeOut, numRoundFail := utility.TrackResults(sendResults, len(rounds))
// If a single partition of the Key Negotiation request does not // If a single partition of the Key Negotiation request does not
// transmit, the partner will not be able to read the confirmation. If // transmit, the partner will not be able to read the confirmation. If
// such a failure occurs // such a failure occurs
...@@ -159,6 +158,7 @@ func unmarshalSource(grp *cyclic.Group, payload []byte) (e2e.SessionID, ...@@ -159,6 +158,7 @@ func unmarshalSource(grp *cyclic.Group, payload []byte) (e2e.SessionID,
} }
oldSessionID := e2e.SessionID{} oldSessionID := e2e.SessionID{}
if err := oldSessionID.Unmarshal(msg.SessionID); err != nil { if err := oldSessionID.Unmarshal(msg.SessionID); err != nil {
return e2e.SessionID{}, nil, errors.Errorf("Failed to unmarshal"+ return e2e.SessionID{}, nil, errors.Errorf("Failed to unmarshal"+
" sessionID: %s", err) " sessionID: %s", err)
......
package keyExchange
import (
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/storage/e2e"
"gitlab.com/xx_network/primitives/id"
"google.golang.org/protobuf/proto"
"testing"
"time"
)
// Smoke test for handleTrigger
func TestHandleTrigger(t *testing.T) {
// Generate alice and bob's session
aliceSession, aliceManager := InitTestingContextGeneric(t)
bobSession, _ := InitTestingContextGeneric(t)
// Pull the keys for Alice and Bob
alicePrivKey := aliceSession.E2e().GetDHPrivateKey()
bobPubKey := bobSession.E2e().GetDHPublicKey()
// Maintain an ID for bob
bobID := id.NewIdFromBytes([]byte("test"), t)
// Add bob as a partner
aliceSession.E2e().AddPartner(bobID, bobSession.E2e().GetDHPublicKey(),
e2e.GetDefaultSessionParams(), e2e.GetDefaultSessionParams())
// Generate a session ID, bypassing some business logic here
sessionID := GeneratePartnerID(alicePrivKey, bobPubKey, genericGroup)
// Generate the message
rekey, _ := proto.Marshal(&RekeyTrigger{
SessionID: sessionID.Marshal(),
PublicKey: bobPubKey.Bytes(),
})
payload := make([]byte, 0)
payload = append(payload, rekey...)
receiveMsg := message.Receive{
Payload: payload,
MessageType: message.NoType,
Sender: bobID,
Timestamp: time.Now(),
Encryption: message.E2E,
}
// Handle the trigger and check for an error
err := handleTrigger(aliceSession, aliceManager, receiveMsg)
if err != nil {
t.Errorf("Handle trigger error: %v", err)
}
}
package keyExchange
import (
"github.com/golang/protobuf/proto"
"gitlab.com/elixxir/client/globals"
"gitlab.com/elixxir/client/interfaces"
"gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/interfaces/params"
"gitlab.com/elixxir/client/stoppable"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/e2e"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/comms/network"
"gitlab.com/elixxir/crypto/cyclic"
dh "gitlab.com/elixxir/crypto/diffieHellman"
"gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/crypto/large"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/ndf"
"testing"
"time"
)
// Generate partner ID for two people, used for smoke tests
func GeneratePartnerID(aliceKey, bobKey *cyclic.Int,
group *cyclic.Group) e2e.SessionID {
baseKey := dh.GenerateSessionKey(aliceKey, bobKey, group)
h, _ := hash.NewCMixHash()
h.Write(baseKey.Bytes())
sid := e2e.SessionID{}
copy(sid[:], h.Sum(nil))
return sid
}
// Contains a test implementation of the networkManager interface. Used to bypass actual sending
// between test clients in testing key exchange
type testNetworkManagerGeneric struct {
instance *network.Instance
}
func (t *testNetworkManagerGeneric) GetHealthTracker() interfaces.HealthTracker {
panic("implement me")
}
func (t *testNetworkManagerGeneric) Follow() (stoppable.Stoppable, error) {
panic("implement me")
}
func (t *testNetworkManagerGeneric) CheckGarbledMessages() {
panic("implement me")
}
func (t *testNetworkManagerGeneric) SendE2E(m message.Send, p params.E2E) ([]id.Round, error) {
rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)}
return rounds, nil
}
func (t *testNetworkManagerGeneric) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) {
return nil, nil
}
func (t *testNetworkManagerGeneric) SendCMIX(message format.Message, p params.CMIX) (id.Round, error) {
return id.Round(0), nil
}
func (t *testNetworkManagerGeneric) GetInstance() *network.Instance {
return t.instance
}
func (t *testNetworkManagerGeneric) RegisterWithPermissioning(string) ([]byte, error) {
return nil, nil
}
func (t *testNetworkManagerGeneric) GetRemoteVersion() (string, error) {
return "test", nil
}
func (t *testNetworkManagerGeneric) GetStoppable() stoppable.Stoppable {
return &stoppable.Multi{}
}
func InitTestingContextGeneric(i interface{}) (*storage.Session, interfaces.NetworkManager) {
switch i.(type) {
case *testing.T:
break
case *testing.M:
break
case *testing.B:
break
default:
globals.Log.FATAL.Panicf("InitTestingSession is restricted to testing only. Got %T", i)
}
thisSession := storage.InitTestingSession(i)
commsManager := connect.NewManagerTesting(i)
instanceComms := &connect.ProtoComms{
Manager: commsManager,
}
_, err := instanceComms.AddHost(&id.Permissioning, "0.0.0.0:420", []byte(pub), connect.GetDefaultHostParams())
if err != nil {
return nil, nil
}
thisInstance, err := network.NewInstanceTesting(instanceComms, def, def, nil, nil, i)
if err != nil {
return nil, nil
}
thisManager := &testNetworkManagerGeneric{instance: thisInstance}
return thisSession, thisManager
}
// Contains a test implementation of the networkManager interface. Used to bypass actual sending
// between test clients in testing key exchange
// Separated from Generic to allow for a full stack test that doesn't impact the generic one used in smoke tests
type testNetworkManagerFullExchange struct {
instance *network.Instance
}
func (t *testNetworkManagerFullExchange) GetHealthTracker() interfaces.HealthTracker {
panic("implement me")
}
func (t *testNetworkManagerFullExchange) Follow() (stoppable.Stoppable, error) {
panic("implement me")
}
func (t *testNetworkManagerFullExchange) CheckGarbledMessages() {
panic("implement me")
}
// Intended for alice to send to bob. Trigger's Bob's confirmation, chaining the operation
// together
func (t *testNetworkManagerFullExchange) SendE2E(m message.Send, p params.E2E) ([]id.Round, error) {
rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)}
alicePrivKey := aliceSession.E2e().GetDHPrivateKey()
bobPubKey := bobSession.E2e().GetDHPublicKey()
sessionID := GeneratePartnerID(alicePrivKey, bobPubKey, genericGroup)
rekeyConfirm, _ := proto.Marshal(&RekeyConfirm{
SessionID: sessionID.Marshal(),
})
payload := make([]byte, 0)
payload = append(payload, rekeyConfirm...)
confirmMessage := message.Receive{
Payload: payload,
MessageType: message.KeyExchangeConfirm,
Sender: exchangeAliceId,
Timestamp: time.Now(),
Encryption: message.E2E,
}
bobSwitchboard.Speak(confirmMessage)
return rounds, nil
}
func (t *testNetworkManagerFullExchange) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) {
return nil, nil
}
func (t *testNetworkManagerFullExchange) SendCMIX(message format.Message, p params.CMIX) (id.Round, error) {
return id.Round(0), nil
}
func (t *testNetworkManagerFullExchange) GetInstance() *network.Instance {
return t.instance
}
func (t *testNetworkManagerFullExchange) RegisterWithPermissioning(string) ([]byte, error) {
return nil, nil
}
func (t *testNetworkManagerFullExchange) GetRemoteVersion() (string, error) {
return "test", nil
}
func (t *testNetworkManagerFullExchange) GetStoppable() stoppable.Stoppable {
return &stoppable.Multi{}
}
func InitTestingContextFullExchange(i interface{}) (*storage.Session, *switchboard.Switchboard, interfaces.NetworkManager) {
switch i.(type) {
case *testing.T:
break
case *testing.M:
break
case *testing.B:
break
default:
globals.Log.FATAL.Panicf("InitTestingSession is restricted to testing only. Got %T", i)
}
thisSession := storage.InitTestingSession(i)
commsManager := connect.NewManagerTesting(i)
instanceComms := &connect.ProtoComms{
Manager: commsManager,
}
_, err := instanceComms.AddHost(&id.Permissioning, "0.0.0.0:420", []byte(pub), connect.GetDefaultHostParams())
if err != nil {
return nil, nil, nil
}
thisInstance, err := network.NewInstanceTesting(instanceComms, def, def, nil, nil, i)
if err != nil {
return nil, nil, nil
}
thisManager := &testNetworkManagerFullExchange{instance: thisInstance}
return thisSession, switchboard.New(), thisManager
}
var pub = "-----BEGIN CERTIFICATE-----\n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\n-----END CERTIFICATE-----\n"
var def = getNDF()
var genericGroup = cyclic.NewGroup(
large.NewIntFromString("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"+
"C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"+
"FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"+
"B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"+
"35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"+
"F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"+
"92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"+
"3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B", 16),
large.NewIntFromString("5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"+
"D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"+
"6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"+
"085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"+
"AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"+
"3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"+
"BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"+
"DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7", 16))
func getNDF() *ndf.NetworkDefinition {
return &ndf.NetworkDefinition{
E2E: ndf.Group{
Prime: "E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B" +
"7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AE" +
"DF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F" +
"8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041" +
"023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF45" +
"3B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE9209" +
"6EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29" +
"A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E" +
"37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F2" +
"78DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696" +
"015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E" +
"6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873" +
"847AEF49F66E43873",
Generator: "2",
},
CMIX: ndf.Group{
Prime: "9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48" +
"C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F" +
"FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5" +
"B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2" +
"35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41" +
"F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE" +
"92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15" +
"3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B",
Generator: "5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613" +
"D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4" +
"6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472" +
"085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5" +
"AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA" +
"3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71" +
"BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0" +
"DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7",
},
}
}
...@@ -129,4 +129,3 @@ func (m *manager) follow(rng csprng.Source, comms followNetworkComms) { ...@@ -129,4 +129,3 @@ func (m *manager) follow(rng csprng.Source, comms followNetworkComms) {
checkedRounds.RangeUncheckedMasked(gwRoundsState, roundChecker, checkedRounds.RangeUncheckedMasked(gwRoundsState, roundChecker,
int(m.param.MaxCheckedRounds)) int(m.param.MaxCheckedRounds))
} }
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
package rounds package rounds
import ( import (
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/network/gateway" "gitlab.com/elixxir/client/network/gateway"
pb "gitlab.com/elixxir/comms/mixmessages" pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"time" "time"
jww "github.com/spf13/jwalterweatherman"
) )
// Historical Rounds looks up the round history via random gateways. // Historical Rounds looks up the round history via random gateways.
......
...@@ -50,7 +50,6 @@ func TestRoundKeys_Encrypt_Consistency(t *testing.T) { ...@@ -50,7 +50,6 @@ func TestRoundKeys_Encrypt_Consistency(t *testing.T) {
28, 227, 140, 81, 202, 212, 140, 63, 12, 82, 214, 222, 76, 13, 194, 28, 227, 140, 81, 202, 212, 140, 63, 12, 82, 214, 222, 76, 13, 194,
141, 75, 17, 37, 145, 27, 155, 162, 165, 234} 141, 75, 17, 37, 145, 27, 155, 162, 165, 234}
expectedKmacs := [][]byte{ expectedKmacs := [][]byte{
{241, 132, 2, 131, 104, 92, 89, 120, 177, 8, 201, {241, 132, 2, 131, 104, 92, 89, 120, 177, 8, 201,
194, 41, 63, 99, 30, 82, 44, 125, 204, 55, 145, 29, 62, 228, 57, 194, 41, 63, 99, 30, 82, 44, 125, 204, 55, 145, 29, 62, 228, 57,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment