diff --git a/api/client.go b/api/client.go index e6e46ca13160a5cfc9f2160fcbdc74ac765ccbbc..5f1acd194ddefb65cfbe69673e9837e4451f7103 100644 --- a/api/client.go +++ b/api/client.go @@ -212,7 +212,7 @@ func (cl *Client) Connect() error { // Registers user and returns the User ID. // Returns an error if registration fails. -func (cl *Client) Register(preCan bool, registrationCode, nick, email string) (*id.User, error) { +func (cl *Client) Register(preCan bool, registrationCode, nick, email string, privateKeyRSA *rsa.PrivateKey) (*id.User, error) { var err error var u *user.User var UID *id.User @@ -233,10 +233,13 @@ func (cl *Client) Register(preCan bool, registrationCode, nick, email string) (* nk := make(map[id.Node]user.NodeKeys) // GENERATE CLIENT RSA KEYS - privateKeyRSA, err := rsa.GenerateKey(rand.Reader, rsa.DefaultRSABitLen) - if err != nil { - return nil, err + if privateKeyRSA == nil { + privateKeyRSA, err = rsa.GenerateKey(rand.Reader, rsa.DefaultRSABitLen) + if err != nil { + return nil, err + } } + publicKeyRSA := privateKeyRSA.GetPublic() privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewMaxInt()) diff --git a/api/client_test.go b/api/client_test.go index 21839c58048681a5f76a00d9bdef881331696690..e692d96c6d0dbd6328f23222a8e403832b3ffc43 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -47,7 +47,7 @@ func TestRegistrationGob(t *testing.T) { } // populate a gob in the store - _, err = testClient.Register(true, "UAV6IWD6", "", "") + _, err = testClient.Register(true, "UAV6IWD6", "", "", nil) if err != nil { t.Error(err) } diff --git a/api/mockserver_test.go b/api/mockserver_test.go index e8ea78e55d6efed36f15fe32c70f81f5f1ebdef4..55c79e352ce50543c0a25f88cc3aee49e52a3c40 100644 --- a/api/mockserver_test.go +++ b/api/mockserver_test.go @@ -71,7 +71,7 @@ func TestRegister_ValidPrecannedRegCodeReturnsZeroID(t *testing.T) { // Register precanned user with all gateways regRes, err := client.Register(true, ValidRegCode, - "", "") + "", "", nil) // Verify registration succeeds with valid precanned registration code if err != nil { @@ -101,7 +101,7 @@ func TestRegister_ValidRegParams___(t *testing.T) { } // Register precanned user with all gateways - regRes, err := client.Register(false, ValidRegCode, "", "") + regRes, err := client.Register(false, ValidRegCode, "", "", nil) if err != nil { t.Errorf("Registration failed: %s", err.Error()) } @@ -129,7 +129,7 @@ func TestRegister_InvalidPrecannedRegCodeReturnsError(t *testing.T) { } // Register with invalid reg code - uid, err := client.Register(true, InvalidRegCode, "", "") + uid, err := client.Register(true, InvalidRegCode, "", "", nil) if err == nil { t.Errorf("Registration worked with invalid registration code! UID: %v", uid) } @@ -156,7 +156,7 @@ func TestRegister_DeletedUserReturnsErr(t *testing.T) { user.Users.DeleteUser(id.NewUserFromUint(5, t)) // Register - _, err = client.Register(true, ValidRegCode, "", "") + _, err = client.Register(true, ValidRegCode, "", "", nil) if err == nil { t.Errorf("Registration worked with a deleted user: %s", err.Error()) } @@ -181,7 +181,7 @@ func TestSend(t *testing.T) { } // Register with a valid registration code - userID, err := client.Register(true, ValidRegCode, "", "") + userID, err := client.Register(true, ValidRegCode, "", "", nil) if err != nil { t.Errorf("Register failed: %s", err.Error()) @@ -255,7 +255,7 @@ func TestLogout(t *testing.T) { } // Register with a valid registration code - userID, err := client.Register(true, ValidRegCode, "", "") + userID, err := client.Register(true, ValidRegCode, "", "", nil) if err != nil { t.Errorf("Register failed: %s", err.Error()) diff --git a/bindings/client.go b/bindings/client.go index 8ed69931771d40959a1842e02c696801fd257d6e..196efc6aec41079df2da3ab6de944991d6db3225 100644 --- a/bindings/client.go +++ b/bindings/client.go @@ -137,7 +137,7 @@ func (cl *Client) Register(preCan bool, registrationCode, nick, email, password " preCan: %v\n registrationCode: %s\n nick: %s\n email: %s\n"+ " Password: ********", preCan, registrationCode, nick, email) fmt.Println("calling client reg") - UID, err := cl.client.Register(preCan, registrationCode, nick, email) + UID, err := cl.client.Register(preCan, registrationCode, nick, email, nil) if err != nil { return id.ZeroID[:], err diff --git a/cmd/root.go b/cmd/root.go index ec524fd6aa166a76545bf79de0c60eb3e07a17b6..f827de7f7b1457fe2598b660a029c729135233a8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,7 +20,9 @@ import ( "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/utils" "gitlab.com/elixxir/crypto/large" + "gitlab.com/elixxir/crypto/signature/rsa" "gitlab.com/elixxir/primitives/id" "gitlab.com/elixxir/primitives/switchboard" "io/ioutil" @@ -34,7 +36,9 @@ import ( var verbose bool var userId uint64 +var sourcePublicKeyPath string var destinationUserId uint64 +var destinationUserIDBase64 string var message string var sessionFile string var dummyFrequency float64 @@ -165,14 +169,27 @@ func sessionInitialization() (*id.User, string, *api.Client) { globals.Log.INFO.Printf("Attempting to register with code %s...", regCode) - uid, err = client.Register(userId != 0, regCode, userNick, userEmail) + var privKey *rsa.PrivateKey + + if sourcePublicKeyPath != "" { + pubKeyBytes, err := ioutil.ReadFile(utils.GetFullPath(sourcePublicKeyPath)) + jww.FATAL.Panicf("Could not load user public key PEM from "+ + "path %s: %+v", sourcePublicKeyPath, err) + privKey, err = rsa.LoadPrivateKeyFromPem(pubKeyBytes) + jww.FATAL.Panicf("Could not public key from "+ + "PEM: %+v", err) + } + + uid, err = client.Register(userId != 0, regCode, userNick, userEmail, privKey) if err != nil { globals.Log.FATAL.Panicf("Could Not Register User: %s\n", err.Error()) return id.ZeroID, "", nil } - globals.Log.INFO.Printf("Successfully registered user %v!", uid) + userbase64 := base64.StdEncoding.EncodeToString(uid[:]) + + globals.Log.INFO.Printf("Successfully registered user %s!", userbase64) } else { // hack for session persisting with cmd line @@ -378,8 +395,19 @@ var rootCmd = &cobra.Command{ var recipientId *id.User - if destinationUserId == 0 { + if destinationUserId != 0 && destinationUserIDBase64 != "" { + jww.FATAL.Panicf("Two destiantions set for the message, can only have one") + } + + if destinationUserId == 0 && destinationUserIDBase64 == "" { recipientId = userID + } else if destinationUserIDBase64 != "" { + recipientIdBytes, err := base64.StdEncoding.DecodeString(destinationUserIDBase64) + if err != nil { + jww.FATAL.Panic("Could not decode the destination user ID") + } + recipientId = id.NewUserFromBytes(recipientIdBytes) + } else { recipientId = id.NewUserFromUints(&[4]uint64{0, 0, 0, destinationUserId}) } @@ -569,6 +597,13 @@ func init() { rootCmd.Flags().BoolVarP(&noTLS, "noTLS", "", false, "Set to ignore TLS") + + rootCmd.Flags().StringVar(&sourcePublicKeyPath, "pubKey", "", + "The path for a PEM encoded public key which will be used "+ + "to create the user") + + rootCmd.Flags().StringVar(&destinationUserIDBase64, "dest64", "", + "Sets the destination user id encoded in base 64") } // initConfig reads in config file and ENV variables if set.