Skip to content
Snippets Groups Projects
Commit 391bf128 authored by Josh Brooks's avatar Josh Brooks
Browse files

Merge branch 'Josh/ProtoClient' into 'release'

Modify Login_Unsafe for pregenerated user JSON

See merge request !47
parents d7671cab 2c2c1ef6
Branches
Tags
2 merge requests!67Release,!47Modify Login_Unsafe for pregenerated user JSON
...@@ -145,59 +145,49 @@ Usage: ...@@ -145,59 +145,49 @@ Usage:
client [command] client [command]
Available Commands: Available Commands:
generate Generates version and dependency information for the generate Generates version and dependency information for the Elixxir binary
Elixxir binary getndf Download the network definition file from the network and print it.
group Group commands for cMix client
help Help about any command help Help about any command
version Print the version and dependency information for the init Initialize a user ID but do not connect to the network
Elixxir binary proto Load client with a proto client JSON file.
single Send and respond to single-use messages.
ud Register for and search users using the xx network user discovery service.
version Print the version and dependency information for the Elixxir binary
Flags: Flags:
--accept-channel Accept the channel request for the --accept-channel Accept the channel request for the corresponding recipient ID
corresponding recipient ID --auth-timeout uint The number of seconds to wait for an authentication channelto confirm (default 120)
--delete-channel Delete the channel information for the --delete-channel Delete the channel information for the corresponding recipient ID
corresponding recipient ID
--destfile string Read this contact file for the destination id --destfile string Read this contact file for the destination id
-d, --destid string ID to send message to (if below 40, will be -d, --destid string ID to send message to (if below 40, will be precanned. Use '0x' or 'b64:' for hex and base64 representations) (default "0")
precanned. Use '0x' or 'b64:' for hex and --e2eMaxKeys uint Max keys used before blocking until a rekey completes (default 800)
base64 representations) (default "0") --e2eMinKeys uint Minimum number of keys used before requesting rekey (default 500)
--forceHistoricalRounds Force all rounds to be sent to historical --e2eNumReKeys uint Number of rekeys reserved for rekey operations (default 16)
round retrieval --forceHistoricalRounds Force all rounds to be sent to historical round retrieval
--forceMessagePickupRetry Enable a mechanism which forces a 50% chance --forceMessagePickupRetry Enable a mechanism which forces a 50% chance of no message pickup, instead triggering the message pickup retry mechanism
of no message pickup, instead triggering the
message pickup retry mechanism
-h, --help help for client -h, --help help for client
-l, --log string Path to the log output path (- is stdout) -l, --log string Path to the log output path (- is stdout) (default "-")
(default "-") -v, --logLevel uint Verbose mode for debugging
-m, --message string Message to send -m, --message string Message to send
-n, --ndf string Path to the network definition JSON file -n, --ndf string Path to the network definition JSON file (default "ndf.json")
(default "ndf.json")
-p, --password string Password to the session file -p, --password string Password to the session file
--receiveCount uint How many messages we should wait for before --profile-cpu string Enable cpu profiling to this file
quitting (default 1) --protoUserOut string Path to which a normally constructed client will write proto user JSON file (default "protoUser.json")
--regcode string Registration code (optional) --protoUserPath string Path to proto user JSON file containing cryptographic primitives the client will load (default "protoUser.json")
--sendCount uint The number of times to send the message --receiveCount uint How many messages we should wait for before quitting (default 1)
(default 1) --regcode string Identity code (optional)
--sendDelay uint The delay between sending the messages in ms --send-auth-request Send an auth request to the specified destination and waitfor confirmation
(default 500) --sendCount uint The number of times to send the message (default 1)
--sendid uint Use precanned user id (must be between 1 and --sendDelay uint The delay between sending the messages in ms (default 500)
40, inclusive) --sendid uint Use precanned user id (must be between 1 and 40, inclusive)
--slowPolling bool Enables polling for all network updates and RSA signed rounds. -s, --session string Sets the initial storage directory for client session data
Defaults to true (filtered updates with ECC signed rounds) if not set --slowPolling Enables polling for unfiltered network updates with RSA signatures
--unsafe Send raw, unsafe messages without e2e encryption.
-s, --session string Sets the initial directory for client storage --unsafe-channel-creation Turns off the user identity authenticated channel check, automatically approving authenticated channels
--unsafe Send raw, unsafe messages without e2e --verboseRoundTracking Verbose round tracking, keeps track and prints all rounds the client was aware of while running. Defaults to false if not set.
encryption. --waitTimeout uint The number of seconds to wait for messages to arrive (default 15)
--unsafe-channel-creation Turns off the user identity authenticated -w, --writeContact string Write contact information, if any, to this file, defaults to stdout (default "-")
channel check, automatically approving
authenticated channels
--verboseRoundTracking Verbose round tracking, keeps track and prints
all rounds the client was aware of while running.
Defaults to false if not set.
-v, --logLevel uint Level of debugging to print (0 = info,
1 = debug, >1 = trace). (Default info)
--waitTimeout uint The number of seconds to wait for messages to
arrive (default 15)
-w, --writeContact string Write the contact file for this user to this
file file
Use "client [command] --help" for more information about a command. Use "client [command] --help" for more information about a command.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
package api package api
import ( import (
"encoding/json"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/auth" "gitlab.com/elixxir/client/auth"
...@@ -74,7 +75,8 @@ type Client struct { ...@@ -74,7 +75,8 @@ type Client struct {
// with the network. Note that this does not register a username/identity, but // with the network. Note that this does not register a username/identity, but
// merely creates a new cryptographic identity for adding such information // merely creates a new cryptographic identity for adding such information
// at a later date. // at a later date.
func NewClient(ndfJSON, storageDir string, password []byte, registrationCode string) error { func NewClient(ndfJSON, storageDir string, password []byte,
registrationCode string) error {
jww.INFO.Printf("NewClient(dir: %s)", storageDir) jww.INFO.Printf("NewClient(dir: %s)", storageDir)
// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG)
...@@ -90,7 +92,7 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str ...@@ -90,7 +92,7 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str
protoUser := createNewUser(rngStreamGen, cmixGrp, e2eGrp) protoUser := createNewUser(rngStreamGen, cmixGrp, e2eGrp)
jww.DEBUG.Printf("User generation took: %s", time.Now().Sub(start)) jww.DEBUG.Printf("User generation took: %s", time.Now().Sub(start))
err = checkVersionAndSetupStorage(def, storageDir, password, protoUser, _, err = checkVersionAndSetupStorage(def, storageDir, password, protoUser,
cmixGrp, e2eGrp, rngStreamGen, false, registrationCode) cmixGrp, e2eGrp, rngStreamGen, false, registrationCode)
if err != nil { if err != nil {
return err return err
...@@ -105,7 +107,8 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str ...@@ -105,7 +107,8 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str
// with the network. Note that this does not register a username/identity, but // with the network. Note that this does not register a username/identity, but
// merely creates a new cryptographic identity for adding such information // merely creates a new cryptographic identity for adding such information
// at a later date. // at a later date.
func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password []byte) error { func NewPrecannedClient(precannedID uint, defJSON, storageDir string,
password []byte) error {
jww.INFO.Printf("NewPrecannedClient()") jww.INFO.Printf("NewPrecannedClient()")
// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG)
...@@ -120,7 +123,7 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [ ...@@ -120,7 +123,7 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [
protoUser := createPrecannedUser(precannedID, rngStream, cmixGrp, e2eGrp) protoUser := createPrecannedUser(precannedID, rngStream, cmixGrp, e2eGrp)
err = checkVersionAndSetupStorage(def, storageDir, password, protoUser, _, err = checkVersionAndSetupStorage(def, storageDir, password, protoUser,
cmixGrp, e2eGrp, rngStreamGen, true, "") cmixGrp, e2eGrp, rngStreamGen, true, "")
if err != nil { if err != nil {
return err return err
...@@ -134,7 +137,8 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [ ...@@ -134,7 +137,8 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [
// with the network. Note that this does not register a username/identity, but // with the network. Note that this does not register a username/identity, but
// merely creates a new cryptographic identity for adding such information // merely creates a new cryptographic identity for adding such information
// at a later date. // at a later date.
func NewVanityClient(ndfJSON, storageDir string, password []byte, registrationCode string, userIdPrefix string) error { func NewVanityClient(ndfJSON, storageDir string, password []byte,
registrationCode string, userIdPrefix string) error {
jww.INFO.Printf("NewVanityClient()") jww.INFO.Printf("NewVanityClient()")
// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG)
...@@ -149,7 +153,7 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte, registrationCo ...@@ -149,7 +153,7 @@ func NewVanityClient(ndfJSON, storageDir string, password []byte, registrationCo
protoUser := createNewVanityUser(rngStream, cmixGrp, e2eGrp, userIdPrefix) protoUser := createNewVanityUser(rngStream, cmixGrp, e2eGrp, userIdPrefix)
err = checkVersionAndSetupStorage(def, storageDir, password, protoUser, _, err = checkVersionAndSetupStorage(def, storageDir, password, protoUser,
cmixGrp, e2eGrp, rngStreamGen, false, registrationCode) cmixGrp, e2eGrp, rngStreamGen, false, registrationCode)
if err != nil { if err != nil {
return err return err
...@@ -195,6 +199,55 @@ func OpenClient(storageDir string, password []byte, parameters params.Network) ( ...@@ -195,6 +199,55 @@ func OpenClient(storageDir string, password []byte, parameters params.Network) (
return c, nil return c, nil
} }
// NewProtoClient_Unsafe initializes a client object from a JSON containing
// predefined cryptographic which defines a user. This is designed for some
// specific deployment procedures and is generally unsafe.
func NewProtoClient_Unsafe(ndfJSON, storageDir string, password,
protoClientJSON []byte) error {
jww.INFO.Printf("NewProtoClient_Unsafe")
// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG)
// Parse the NDF
def, err := parseNDF(ndfJSON)
if err != nil {
return err
}
cmixGrp, e2eGrp := decodeGroups(def)
// Pull the proto user from the JSON
protoUser := &user.Proto{}
err = json.Unmarshal(protoClientJSON, protoUser)
if err != nil {
return err
}
// Initialize a user object for storage set up
usr := user.NewUserFromProto(protoUser)
// Set up storage
storageSess, err := checkVersionAndSetupStorage(def, storageDir, password, usr,
cmixGrp, e2eGrp, rngStreamGen, false, protoUser.RegCode)
if err != nil {
return err
}
// Set registration values in storage
storageSess.User().SetReceptionRegistrationValidationSignature(protoUser.ReceptionRegValidationSig)
storageSess.User().SetTransmissionRegistrationValidationSignature(protoUser.TransmissionRegValidationSig)
storageSess.User().SetRegistrationTimestamp(protoUser.RegistrationTimestamp)
//move the registration state to indicate registered with registration on proto client
err = storageSess.ForwardRegistrationStatus(storage.PermissioningComplete)
if err != nil {
return err
}
return nil
}
// Login initializes a client object from existing storage. // Login initializes a client object from existing storage.
func Login(storageDir string, password []byte, parameters params.Network) (*Client, error) { func Login(storageDir string, password []byte, parameters params.Network) (*Client, error) {
jww.INFO.Printf("Login()") jww.INFO.Printf("Login()")
...@@ -236,7 +289,8 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie ...@@ -236,7 +289,8 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie
hp.KaClientOpts.Time = time.Duration(math.MaxInt64) hp.KaClientOpts.Time = time.Duration(math.MaxInt64)
hp.AuthEnabled = false hp.AuthEnabled = false
hp.MaxRetries = 5 hp.MaxRetries = 5
_, err = c.comms.AddHost(&id.NotificationBot, def.Notification.Address, []byte(def.Notification.TlsCertificate), hp) _, err = c.comms.AddHost(&id.NotificationBot, def.Notification.Address,
[]byte(def.Notification.TlsCertificate), hp)
if err != nil { if err != nil {
jww.WARN.Printf("Failed adding host for notifications: %+v", err) jww.WARN.Printf("Failed adding host for notifications: %+v", err)
} }
...@@ -382,7 +436,9 @@ func (c *Client) registerFollower() error { ...@@ -382,7 +436,9 @@ func (c *Client) registerFollower() error {
} }
//register the core follower service //register the core follower service
err = c.followerServices.add(func() (stoppable.Stoppable, error) { return c.network.Follow(cer) }) err = c.followerServices.add(func() (stoppable.Stoppable, error) {
return c.network.Follow(cer)
})
if err != nil { if err != nil {
return errors.WithMessage(err, "Failed to start following "+ return errors.WithMessage(err, "Failed to start following "+
"the network") "the network")
...@@ -698,13 +754,15 @@ func decodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) { ...@@ -698,13 +754,15 @@ func decodeGroups(ndf *ndf.NetworkDefinition) (cmixGrp, e2eGrp *cyclic.Group) {
// checkVersionAndSetupStorage is common code shared by NewClient, NewPrecannedClient and NewVanityClient // checkVersionAndSetupStorage is common code shared by NewClient, NewPrecannedClient and NewVanityClient
// it checks client version and creates a new storage for user data // it checks client version and creates a new storage for user data
func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, storageDir string, password []byte, func checkVersionAndSetupStorage(def *ndf.NetworkDefinition,
protoUser user.User, cmixGrp, e2eGrp *cyclic.Group, rngStreamGen *fastRNG.StreamGenerator, storageDir string, password []byte,
isPrecanned bool, registrationCode string) error { protoUser user.User,
cmixGrp, e2eGrp *cyclic.Group, rngStreamGen *fastRNG.StreamGenerator,
isPrecanned bool, registrationCode string) (*storage.Session, error) {
// Get current client version // Get current client version
currentVersion, err := version.ParseVersion(SEMVER) currentVersion, err := version.ParseVersion(SEMVER)
if err != nil { if err != nil {
return errors.WithMessage(err, "Could not parse version string.") return nil, errors.WithMessage(err, "Could not parse version string.")
} }
// Create Storage // Create Storage
...@@ -712,7 +770,7 @@ func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, storageDir string, ...@@ -712,7 +770,7 @@ func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, storageDir string,
storageSess, err := storage.New(storageDir, passwordStr, protoUser, storageSess, err := storage.New(storageDir, passwordStr, protoUser,
currentVersion, cmixGrp, e2eGrp, rngStreamGen) currentVersion, cmixGrp, e2eGrp, rngStreamGen)
if err != nil { if err != nil {
return err return nil, err
} }
// Save NDF to be used in the future // Save NDF to be used in the future
...@@ -736,9 +794,9 @@ func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, storageDir string, ...@@ -736,9 +794,9 @@ func checkVersionAndSetupStorage(def *ndf.NetworkDefinition, storageDir string,
}, protoUser.ReceptionID) }, protoUser.ReceptionID)
if err != nil { if err != nil {
return errors.WithMessage(err, "Failed to denote state "+ return nil, errors.WithMessage(err, "Failed to denote state "+
"change in session") "change in session")
} }
return nil return storageSess, nil
} }
...@@ -43,7 +43,7 @@ func (c *Client) RegisterForNotifications(token string) error { ...@@ -43,7 +43,7 @@ func (c *Client) RegisterForNotifications(token string) error {
TransmissionSalt: c.GetUser().TransmissionSalt, TransmissionSalt: c.GetUser().TransmissionSalt,
TransmissionRsaSig: c.GetStorage().User().GetTransmissionRegistrationValidationSignature(), TransmissionRsaSig: c.GetStorage().User().GetTransmissionRegistrationValidationSignature(),
IIDTransmissionRsaSig: sig, IIDTransmissionRsaSig: sig,
RegistrationTimestamp: c.GetUser().RegistrationTimestamp.UnixNano(), RegistrationTimestamp: c.GetUser().RegistrationTimestamp,
}) })
if err != nil { if err != nil {
err := errors.Errorf( err := errors.Errorf(
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
package api package api
import ( import (
"encoding/json"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/client/interfaces/user"
"gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage"
) )
...@@ -47,3 +49,41 @@ func (c *Client) registerWithPermissioning() error { ...@@ -47,3 +49,41 @@ func (c *Client) registerWithPermissioning() error {
} }
return nil return nil
} }
// ConstructProtoUerFile is a helper function which is used for proto client testing.
// This is used for development testing.
func (c *Client) ConstructProtoUerFile() ([]byte, error) {
//load the registration code
regCode, err := c.storage.GetRegCode()
if err != nil {
return nil, errors.WithMessage(err, "failed to register with "+
"permissioning")
}
Usr := user.Proto{
TransmissionID: c.GetUser().TransmissionID,
TransmissionSalt: c.GetUser().TransmissionSalt,
TransmissionRSA: c.GetUser().TransmissionRSA,
ReceptionID: c.GetUser().ReceptionID,
ReceptionSalt: c.GetUser().ReceptionSalt,
ReceptionRSA: c.GetUser().ReceptionRSA,
Precanned: c.GetUser().Precanned,
RegistrationTimestamp: c.GetUser().RegistrationTimestamp,
RegCode: regCode,
TransmissionRegValidationSig: c.storage.User().GetTransmissionRegistrationValidationSignature(),
ReceptionRegValidationSig: c.storage.User().GetReceptionRegistrationValidationSignature(),
CmixDhPrivateKey: c.GetStorage().Cmix().GetDHPrivateKey(),
CmixDhPublicKey: c.GetStorage().Cmix().GetDHPublicKey(),
E2eDhPrivateKey: c.GetStorage().E2e().GetDHPrivateKey(),
E2eDhPublicKey: c.GetStorage().E2e().GetDHPublicKey(),
}
jsonBytes, err := json.Marshal(Usr)
if err != nil {
return nil, errors.WithMessage(err, "failed to register with "+
"permissioning")
}
return jsonBytes, nil
}
...@@ -36,6 +36,62 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U ...@@ -36,6 +36,62 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U
var cMixKeyBytes, e2eKeyBytes, transmissionSalt, receptionSalt []byte var cMixKeyBytes, e2eKeyBytes, transmissionSalt, receptionSalt []byte
cMixKeyBytes, e2eKeyBytes, transmissionSalt, receptionSalt,
transmissionRsaKey, receptionRsaKey = createDhKeys(rng, cmix, e2e)
// Salt, UID, etc gen
stream := rng.GetStream()
transmissionSalt = make([]byte, SaltSize)
n, err := stream.Read(transmissionSalt)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
if n != SaltSize {
jww.FATAL.Panicf("transmissionSalt size too small: %d", n)
}
receptionSalt = make([]byte, SaltSize)
n, err = stream.Read(receptionSalt)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
if n != SaltSize {
jww.FATAL.Panicf("transmissionSalt size too small: %d", n)
}
stream.Close()
transmissionID, err := xx.NewID(transmissionRsaKey.GetPublic(), transmissionSalt, id.User)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
receptionID, err := xx.NewID(receptionRsaKey.GetPublic(), receptionSalt, id.User)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
return user.User{
TransmissionID: transmissionID.DeepCopy(),
TransmissionSalt: transmissionSalt,
TransmissionRSA: transmissionRsaKey,
ReceptionID: receptionID.DeepCopy(),
ReceptionSalt: receptionSalt,
ReceptionRSA: receptionRsaKey,
Precanned: false,
CmixDhPrivateKey: cmix.NewIntFromBytes(cMixKeyBytes),
E2eDhPrivateKey: e2e.NewIntFromBytes(e2eKeyBytes),
}
}
func createDhKeys(rng *fastRNG.StreamGenerator,
cmix, e2e *cyclic.Group) (cMixKeyBytes, e2eKeyBytes,
transmissionSalt, receptionSalt []byte,
transmissionRsaKey, receptionRsaKey *rsa.PrivateKey) {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(4) wg.Add(4)
...@@ -93,53 +149,8 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U ...@@ -93,53 +149,8 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U
}() }()
wg.Wait() wg.Wait()
// Salt, UID, etc gen return
stream := rng.GetStream()
transmissionSalt = make([]byte, SaltSize)
n, err := stream.Read(transmissionSalt)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
if n != SaltSize {
jww.FATAL.Panicf("transmissionSalt size too small: %d", n)
}
receptionSalt = make([]byte, SaltSize)
n, err = stream.Read(receptionSalt)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
if n != SaltSize {
jww.FATAL.Panicf("transmissionSalt size too small: %d", n)
}
stream.Close()
transmissionID, err := xx.NewID(transmissionRsaKey.GetPublic(), transmissionSalt, id.User)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
receptionID, err := xx.NewID(receptionRsaKey.GetPublic(), receptionSalt, id.User)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
return user.User{
TransmissionID: transmissionID.DeepCopy(),
TransmissionSalt: transmissionSalt,
TransmissionRSA: transmissionRsaKey,
ReceptionID: receptionID.DeepCopy(),
ReceptionSalt: receptionSalt,
ReceptionRSA: receptionRsaKey,
Precanned: false,
CmixDhPrivateKey: cmix.NewIntFromBytes(cMixKeyBytes),
E2eDhPrivateKey: e2e.NewIntFromBytes(e2eKeyBytes),
}
} }
// TODO: Add precanned user code structures here. // TODO: Add precanned user code structures here.
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"gitlab.com/elixxir/client/switchboard" "gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/contact"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/utils"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
...@@ -382,6 +383,8 @@ func createClient() *api.Client { ...@@ -382,6 +383,8 @@ func createClient() *api.Client {
regCode := viper.GetString("regcode") regCode := viper.GetString("regcode")
precannedID := viper.GetUint("sendid") precannedID := viper.GetUint("sendid")
userIDprefix := viper.GetString("userid-prefix") userIDprefix := viper.GetString("userid-prefix")
protoUserPath := viper.GetString("protoUserPath")
//create a new client if none exist //create a new client if none exist
if _, err := os.Stat(storeDir); os.IsNotExist(err) { if _, err := os.Stat(storeDir); os.IsNotExist(err) {
// Load NDF // Load NDF
...@@ -394,15 +397,20 @@ func createClient() *api.Client { ...@@ -394,15 +397,20 @@ func createClient() *api.Client {
if precannedID != 0 { if precannedID != 0 {
err = api.NewPrecannedClient(precannedID, err = api.NewPrecannedClient(precannedID,
string(ndfJSON), storeDir, []byte(pass)) string(ndfJSON), storeDir, []byte(pass))
} else { } else if protoUserPath != "" {
if userIDprefix != "" { protoUserJson, err := utils.ReadFile(protoUserPath)
if err != nil {
jww.FATAL.Panicf("%v", err)
}
err = api.NewProtoClient_Unsafe(string(ndfJSON), storeDir,
[]byte(pass), protoUserJson)
} else if userIDprefix != "" {
err = api.NewVanityClient(string(ndfJSON), storeDir, err = api.NewVanityClient(string(ndfJSON), storeDir,
[]byte(pass), regCode, userIDprefix) []byte(pass), regCode, userIDprefix)
} else { } else {
err = api.NewClient(string(ndfJSON), storeDir, err = api.NewClient(string(ndfJSON), storeDir,
[]byte(pass), regCode) []byte(pass), regCode)
} }
}
if err != nil { if err != nil {
jww.FATAL.Panicf("%+v", err) jww.FATAL.Panicf("%+v", err)
...@@ -431,7 +439,7 @@ func initClient() *api.Client { ...@@ -431,7 +439,7 @@ func initClient() *api.Client {
pass := viper.GetString("password") pass := viper.GetString("password")
storeDir := viper.GetString("session") storeDir := viper.GetString("session")
jww.DEBUG.Printf("sessionDur: %v", storeDir)
netParams := params.GetDefaultNetwork() netParams := params.GetDefaultNetwork()
netParams.E2EParams.MinKeys = uint16(viper.GetUint("e2eMinKeys")) netParams.E2EParams.MinKeys = uint16(viper.GetUint("e2eMinKeys"))
netParams.E2EParams.MaxKeys = uint16(viper.GetUint("e2eMaxKeys")) netParams.E2EParams.MaxKeys = uint16(viper.GetUint("e2eMaxKeys"))
...@@ -453,6 +461,20 @@ func initClient() *api.Client { ...@@ -453,6 +461,20 @@ func initClient() *api.Client {
jww.FATAL.Panicf("%+v", err) jww.FATAL.Panicf("%+v", err)
} }
if protoUser := viper.GetString("protoUserOut"); protoUser != "" {
jsonBytes, err := client.ConstructProtoUerFile()
if err != nil {
jww.FATAL.Panicf("Failed to construct proto user file: %v", err)
}
err = utils.WriteFileDef(protoUser, jsonBytes)
if err != nil {
jww.FATAL.Panicf("Failed to write proto user to file: %v", err)
}
}
return client return client
} }
...@@ -823,30 +845,30 @@ func init() { ...@@ -823,30 +845,30 @@ func init() {
rootCmd.Flags().UintP("receiveCount", rootCmd.Flags().UintP("receiveCount",
"", 1, "How many messages we should wait for before quitting") "", 1, "How many messages we should wait for before quitting")
viper.BindPFlag("receiveCount", rootCmd.Flags().Lookup("receiveCount")) viper.BindPFlag("receiveCount", rootCmd.Flags().Lookup("receiveCount"))
rootCmd.Flags().UintP("waitTimeout", "", 15, rootCmd.PersistentFlags().UintP("waitTimeout", "", 15,
"The number of seconds to wait for messages to arrive") "The number of seconds to wait for messages to arrive")
viper.BindPFlag("waitTimeout", viper.BindPFlag("waitTimeout",
rootCmd.Flags().Lookup("waitTimeout")) rootCmd.PersistentFlags().Lookup("waitTimeout"))
rootCmd.Flags().BoolP("unsafe", "", false, rootCmd.Flags().BoolP("unsafe", "", false,
"Send raw, unsafe messages without e2e encryption.") "Send raw, unsafe messages without e2e encryption.")
viper.BindPFlag("unsafe", rootCmd.Flags().Lookup("unsafe")) viper.BindPFlag("unsafe", rootCmd.Flags().Lookup("unsafe"))
rootCmd.Flags().BoolP("unsafe-channel-creation", "", false, rootCmd.PersistentFlags().BoolP("unsafe-channel-creation", "", false,
"Turns off the user identity authenticated channel check, "+ "Turns off the user identity authenticated channel check, "+
"automatically approving authenticated channels") "automatically approving authenticated channels")
viper.BindPFlag("unsafe-channel-creation", viper.BindPFlag("unsafe-channel-creation",
rootCmd.Flags().Lookup("unsafe-channel-creation")) rootCmd.PersistentFlags().Lookup("unsafe-channel-creation"))
rootCmd.Flags().BoolP("accept-channel", "", false, rootCmd.Flags().BoolP("accept-channel", "", false,
"Accept the channel request for the corresponding recipient ID") "Accept the channel request for the corresponding recipient ID")
viper.BindPFlag("accept-channel", viper.BindPFlag("accept-channel",
rootCmd.Flags().Lookup("accept-channel")) rootCmd.Flags().Lookup("accept-channel"))
rootCmd.Flags().Bool("delete-channel", false, rootCmd.PersistentFlags().Bool("delete-channel", false,
"Delete the channel information for the corresponding recipient ID") "Delete the channel information for the corresponding recipient ID")
viper.BindPFlag("delete-channel", viper.BindPFlag("delete-channel",
rootCmd.Flags().Lookup("delete-channel")) rootCmd.PersistentFlags().Lookup("delete-channel"))
rootCmd.Flags().BoolP("send-auth-request", "", false, rootCmd.Flags().BoolP("send-auth-request", "", false,
"Send an auth request to the specified destination and wait"+ "Send an auth request to the specified destination and wait"+
...@@ -893,6 +915,17 @@ func init() { ...@@ -893,6 +915,17 @@ func init() {
rootCmd.Flags().String("profile-cpu", "", rootCmd.Flags().String("profile-cpu", "",
"Enable cpu profiling to this file") "Enable cpu profiling to this file")
viper.BindPFlag("profile-cpu", rootCmd.Flags().Lookup("profile-cpu")) viper.BindPFlag("profile-cpu", rootCmd.Flags().Lookup("profile-cpu"))
// Proto user flags
rootCmd.Flags().String("protoUserPath", "",
"Path to proto user JSON file containing cryptographic primitives "+
"the client will load")
viper.BindPFlag("protoUserPath", rootCmd.Flags().Lookup("protoUserPath"))
rootCmd.Flags().String("protoUserOut", "",
"Path to which a normally constructed client "+
"will write proto user JSON file")
viper.BindPFlag("protoUserOut", rootCmd.Flags().Lookup("protoUserOut"))
} }
// initConfig reads in config file and ENV variables if set. // initConfig reads in config file and ENV variables if set.
......
package user
import (
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id"
)
type Proto struct {
//General Identity
TransmissionID *id.ID
TransmissionSalt []byte
TransmissionRSA *rsa.PrivateKey
ReceptionID *id.ID
ReceptionSalt []byte
ReceptionRSA *rsa.PrivateKey
Precanned bool
// Timestamp in which user has registered with the network
RegistrationTimestamp int64
RegCode string
TransmissionRegValidationSig []byte
ReceptionRegValidationSig []byte
//cmix Identity
CmixDhPrivateKey *cyclic.Int
CmixDhPublicKey *cyclic.Int
//e2e Identity
E2eDhPrivateKey *cyclic.Int
E2eDhPublicKey *cyclic.Int
}
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
"gitlab.com/elixxir/primitives/fact" "gitlab.com/elixxir/primitives/fact"
"gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"time"
) )
type User struct { type User struct {
...@@ -26,7 +25,7 @@ type User struct { ...@@ -26,7 +25,7 @@ type User struct {
ReceptionRSA *rsa.PrivateKey ReceptionRSA *rsa.PrivateKey
Precanned bool Precanned bool
// Timestamp in which user has registered with the network // Timestamp in which user has registered with the network
RegistrationTimestamp time.Time RegistrationTimestamp int64
//cmix Identity //cmix Identity
CmixDhPrivateKey *cyclic.Int CmixDhPrivateKey *cyclic.Int
...@@ -44,3 +43,20 @@ func (u User) GetContact() contact.Contact { ...@@ -44,3 +43,20 @@ func (u User) GetContact() contact.Contact {
Facts: make([]fact.Fact, 0), Facts: make([]fact.Fact, 0),
} }
} }
func NewUserFromProto(proto *Proto) User {
return User{
TransmissionID: proto.TransmissionID,
TransmissionSalt: proto.TransmissionSalt,
TransmissionRSA: proto.TransmissionRSA,
ReceptionID: proto.ReceptionID,
ReceptionSalt: proto.ReceptionSalt,
ReceptionRSA: proto.ReceptionRSA,
Precanned: proto.Precanned,
RegistrationTimestamp: proto.RegistrationTimestamp,
CmixDhPrivateKey: proto.CmixDhPrivateKey,
CmixDhPublicKey: proto.CmixDhPublicKey,
E2eDhPrivateKey: proto.E2eDhPrivateKey,
E2eDhPublicKey: proto.E2eDhPublicKey,
}
}
...@@ -94,7 +94,7 @@ func New(baseDir, password string, u userInterface.User, currentVersion version. ...@@ -94,7 +94,7 @@ func New(baseDir, password string, u userInterface.User, currentVersion version.
s, err := initStore(baseDir, password) s, err := initStore(baseDir, password)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "Failed to create session") return nil, errors.WithMessagef(err, "Failed to create session for %s", baseDir)
} }
err = s.newRegStatus() err = s.newRegStatus()
...@@ -103,7 +103,8 @@ func New(baseDir, password string, u userInterface.User, currentVersion version. ...@@ -103,7 +103,8 @@ func New(baseDir, password string, u userInterface.User, currentVersion version.
"Create new session") "Create new session")
} }
s.user, err = user.NewUser(s.kv, u.TransmissionID, u.ReceptionID, u.TransmissionSalt, u.ReceptionSalt, u.TransmissionRSA, u.ReceptionRSA, u.Precanned) s.user, err = user.NewUser(s.kv, u.TransmissionID, u.ReceptionID, u.TransmissionSalt,
u.ReceptionSalt, u.TransmissionRSA, u.ReceptionRSA, u.Precanned)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "Failed to create user") return nil, errors.WithMessage(err, "Failed to create user")
} }
......
...@@ -16,9 +16,9 @@ func (s *Session) GetUser() user.User { ...@@ -16,9 +16,9 @@ func (s *Session) GetUser() user.User {
return user.User{ return user.User{
TransmissionID: ci.GetTransmissionID().DeepCopy(), TransmissionID: ci.GetTransmissionID().DeepCopy(),
TransmissionSalt: copySlice(ci.GetTransmissionSalt()), TransmissionSalt: copySlice(ci.GetTransmissionSalt()),
TransmissionRSA: ci.GetReceptionRSA(), TransmissionRSA: ci.GetTransmissionRSA(),
ReceptionID: ci.GetReceptionID().DeepCopy(), ReceptionID: ci.GetReceptionID().DeepCopy(),
RegistrationTimestamp: s.user.GetRegistrationTimestamp(), RegistrationTimestamp: s.user.GetRegistrationTimestamp().UnixNano(),
ReceptionSalt: copySlice(ci.GetReceptionSalt()), ReceptionSalt: copySlice(ci.GetReceptionSalt()),
ReceptionRSA: ci.GetReceptionRSA(), ReceptionRSA: ci.GetReceptionRSA(),
Precanned: ci.IsPrecanned(), Precanned: ci.IsPrecanned(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment