From cf0da18831151a587b9e2d0743444cf0c27269a4 Mon Sep 17 00:00:00 2001 From: josh <josh@elixxir.io> Date: Fri, 15 Oct 2021 13:19:11 -0700 Subject: [PATCH] Modify Login_Unsafe for pregenerated user JSON --- api/client.go | 69 ++++++++++++++++++-------- api/user.go | 103 ++++++++++++++++++++++----------------- interfaces/user/proto.go | 35 +++++++++++++ interfaces/user/user.go | 17 +++++++ storage/session.go | 3 +- 5 files changed, 161 insertions(+), 66 deletions(-) create mode 100644 interfaces/user/proto.go diff --git a/api/client.go b/api/client.go index bc460a17d..a6cf414bc 100644 --- a/api/client.go +++ b/api/client.go @@ -8,6 +8,7 @@ package api import ( + "encoding/json" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/auth" @@ -72,7 +73,8 @@ type Client struct { // with the network. Note that this does not register a username/identity, but // merely creates a new cryptographic identity for adding such information // 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) // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) @@ -103,7 +105,8 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str // with the network. Note that this does not register a username/identity, but // merely creates a new cryptographic identity for adding such information // 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()") // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) @@ -132,7 +135,8 @@ func NewPrecannedClient(precannedID uint, defJSON, storageDir string, password [ // with the network. Note that this does not register a username/identity, but // merely creates a new cryptographic identity for adding such information // 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()") // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) @@ -193,6 +197,45 @@ func OpenClient(storageDir string, password []byte, parameters params.Network) ( 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(storageDir string, password []byte, + protoClientJSON []byte, + parameters params.Network, def *ndf.NetworkDefinition) (*Client, error) { + // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) + rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) + + cmixGrp, e2eGrp := decodeGroups(def) + + // Pull the proto user from the JSON + protoUser := &user.Proto{} + err := json.Unmarshal(protoClientJSON, protoUser) + if err != nil { + return nil, err + } + + // Initialize a user object for storage set up + usr := user.NewUserFromProto(protoUser) + + // Set up storage + err = checkVersionAndSetupStorage(def, storageDir, password, usr, + cmixGrp, e2eGrp, rngStreamGen, false, protoUser.RegCode) + + //Open the client + c, err := OpenClient(storageDir, password, parameters) + if err != nil { + return nil, err + } + + // Set registration values in storage + c.GetStorage().User().SetReceptionRegistrationValidationSignature(protoUser.ReceptionRegValidationSig) + c.GetStorage().User().SetTransmissionRegistrationValidationSignature(protoUser.TransmissionRegValidationSig) + c.GetStorage().User().SetRegistrationTimestamp(protoUser.RegistrationTimestamp.UnixNano()) + + return c, nil +} + // Login initializes a client object from existing storage. func Login(storageDir string, password []byte, parameters params.Network) (*Client, error) { jww.INFO.Printf("Login()") @@ -234,7 +277,8 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie hp.KaClientOpts.Time = time.Duration(math.MaxInt64) hp.AuthEnabled = false 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 { jww.WARN.Printf("Failed adding host for notifications: %+v", err) } @@ -262,7 +306,7 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie // LoginWithNewBaseNDF_UNSAFE initializes a client object from existing storage // while replacing the base NDF. This is designed for some specific deployment // procedures and is generally unsafe. -func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, +func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, protoClientJSON []byte, newBaseNdf string, parameters params.Network) (*Client, error) { jww.INFO.Printf("LoginWithNewBaseNDF_UNSAFE()") @@ -273,8 +317,7 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, } //Open the client - c, err := OpenClient(storageDir, password, parameters) - + c, err := NewProtoClient_Unsafe(storageDir, password, protoClientJSON, parameters, def) if err != nil { return nil, err } @@ -288,18 +331,6 @@ func LoginWithNewBaseNDF_UNSAFE(storageDir string, password []byte, //store the updated base NDF c.storage.SetNDF(def) - //initialize registration - if def.Registration.Address != "" { - err = c.initPermissioning(def) - if err != nil { - return nil, err - } - } else { - jww.WARN.Printf("Registration with permissioning skipped due to " + - "blank permissionign address. Client will not be able to register " + - "or track network.") - } - // Initialize network and link it to context c.network, err = network.NewManager(c.storage, c.switchboard, c.rng, c.events, c.comms, parameters, def) diff --git a/api/user.go b/api/user.go index ef8eb1092..1b22a0877 100644 --- a/api/user.go +++ b/api/user.go @@ -36,6 +36,62 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U 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.Add(4) @@ -93,53 +149,8 @@ func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.U }() wg.Wait() - // 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 - 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. diff --git a/interfaces/user/proto.go b/interfaces/user/proto.go new file mode 100644 index 000000000..8eff94714 --- /dev/null +++ b/interfaces/user/proto.go @@ -0,0 +1,35 @@ +package user + +import ( + "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/xx_network/primitives/id" + "time" +) + +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 time.Time + + Username string + RegCode string + + TransmissionRegValidationSig []byte + ReceptionRegValidationSig []byte + + //cmix Identity + CmixDhPrivateKey *cyclic.Int + CmixDhPublicKey *cyclic.Int + + //e2e Identity + E2eDhPrivateKey *cyclic.Int + E2eDhPublicKey *cyclic.Int +} diff --git a/interfaces/user/user.go b/interfaces/user/user.go index 8788856b4..c3f5875aa 100644 --- a/interfaces/user/user.go +++ b/interfaces/user/user.go @@ -44,3 +44,20 @@ func (u User) GetContact() contact.Contact { 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, + } +} diff --git a/storage/session.go b/storage/session.go index fd98a85c2..9b949f240 100644 --- a/storage/session.go +++ b/storage/session.go @@ -101,7 +101,8 @@ func New(baseDir, password string, u userInterface.User, currentVersion version. "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 { return nil, errors.WithMessage(err, "Failed to create user") } -- GitLab