From 8c752cccfda00b858a9102a3ef9b499a10d5a12c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 15:17:45 +0100 Subject: [PATCH 1/5] accounts/keystore: Fix geth account new to operate directly on a keystore file --- accounts/keystore/keystore_passphrase.go | 18 ++++++++++++++ cmd/geth/accountcmd.go | 23 ++++++++++++++---- node/config.go | 30 ++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 535608a6002..164da653bc6 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -28,6 +28,7 @@ package keystore import ( "bytes" "crypto/aes" + crand "crypto/rand" "crypto/sha256" "encoding/hex" "encoding/json" @@ -90,6 +91,23 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) return key, nil } +func StoreKey(dir, auth string, scryptN, scryptP int) (error, common.Address) { + key, err := newKey(crand.Reader) + if err != nil { + return err, common.Address{} + } + keyjson, err := EncryptKey(key, auth, scryptN, scryptP) + if err != nil { + return err, common.Address{} + } + fullpath := filepath.Join(dir, keyFileName(key.Address)) + err = writeKeyFile(fullpath, keyjson) + if err != nil { + return err, common.Address{} + } + return nil, key.Address +} + func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP) if err != nil { diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 0f53c92b0a3..30e50a520fb 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/console" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" "gopkg.in/urfave/cli.v1" ) @@ -291,15 +292,29 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr // accountCreate creates a new account into the keystore defined by the CLI flags. func accountCreate(ctx *cli.Context) error { - stack, _ := makeConfigNode(ctx) + + cfg := gethConfig{} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + scryptN, scryptP, keydir, err := node.ResolveAccountConfig(&cfg.Node) + + if err != nil { + utils.Fatalf("Failed to create account: %v", err) + } + password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - account, err := ks.NewAccount(password) + err, address := keystore.StoreKey(keydir, password, scryptN, scryptP) + if err != nil { utils.Fatalf("Failed to create account: %v", err) } - fmt.Printf("Address: {%x}\n", account.Address) + fmt.Printf("Address: {%x}\n", address) return nil } diff --git a/node/config.go b/node/config.go index be9e21b4fa7..b8f88989311 100644 --- a/node/config.go +++ b/node/config.go @@ -359,6 +359,36 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node { } return nodes } +// ResolveAccountConfig determines the settings for scrypt and keydirectory +func ResolveAccountConfig(conf *Config) (int, int, string, error) { + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if conf.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } + + var ( + keydir string + err error + ) + switch { + case filepath.IsAbs(conf.KeyStoreDir): + keydir = conf.KeyStoreDir + case conf.DataDir != "": + if conf.KeyStoreDir == "" { + keydir = filepath.Join(conf.DataDir, datadirDefaultKeyStore) + } else { + keydir, err = filepath.Abs(conf.KeyStoreDir) + } + case conf.KeyStoreDir != "": + keydir, err = filepath.Abs(conf.KeyStoreDir) + default: + // There is no datadir. + keydir, err = ioutil.TempDir("", "go-ethereum-keystore") + } + return scryptN, scryptP, keydir, err +} func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { scryptN := keystore.StandardScryptN From 1adadea16101208bd14fda13ecc2007ba3f5bc95 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 15:19:35 +0100 Subject: [PATCH 2/5] node: Remove superfluous code --- node/config.go | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/node/config.go b/node/config.go index b8f88989311..89efe1911c7 100644 --- a/node/config.go +++ b/node/config.go @@ -359,6 +359,7 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node { } return nodes } + // ResolveAccountConfig determines the settings for scrypt and keydirectory func ResolveAccountConfig(conf *Config) (int, int, string, error) { scryptN := keystore.StandardScryptN @@ -391,34 +392,8 @@ func ResolveAccountConfig(conf *Config) (int, int, string, error) { } func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { - scryptN := keystore.StandardScryptN - scryptP := keystore.StandardScryptP - if conf.UseLightweightKDF { - scryptN = keystore.LightScryptN - scryptP = keystore.LightScryptP - } + scryptN, scryptP, keydir, err := ResolveAccountConfig(conf) - var ( - keydir string - ephemeral string - err error - ) - switch { - case filepath.IsAbs(conf.KeyStoreDir): - keydir = conf.KeyStoreDir - case conf.DataDir != "": - if conf.KeyStoreDir == "" { - keydir = filepath.Join(conf.DataDir, datadirDefaultKeyStore) - } else { - keydir, err = filepath.Abs(conf.KeyStoreDir) - } - case conf.KeyStoreDir != "": - keydir, err = filepath.Abs(conf.KeyStoreDir) - default: - // There is no datadir. - keydir, err = ioutil.TempDir("", "go-ethereum-keystore") - ephemeral = keydir - } if err != nil { return nil, "", err } @@ -443,5 +418,5 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { backends = append(backends, trezorhub) } } - return accounts.NewManager(backends...), ephemeral, nil + return accounts.NewManager(backends...), keydir, nil } From bb22dfe02fe3ea5bda44353b87b1777d68d0da45 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 15:42:49 +0100 Subject: [PATCH 3/5] accounts/keystore: address review-feedback --- accounts/keystore/keystore_passphrase.go | 19 +++---------- cmd/geth/accountcmd.go | 6 ++-- node/config.go | 35 +++++++++++++----------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 164da653bc6..eaec39f7df2 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -91,21 +91,10 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) return key, nil } -func StoreKey(dir, auth string, scryptN, scryptP int) (error, common.Address) { - key, err := newKey(crand.Reader) - if err != nil { - return err, common.Address{} - } - keyjson, err := EncryptKey(key, auth, scryptN, scryptP) - if err != nil { - return err, common.Address{} - } - fullpath := filepath.Join(dir, keyFileName(key.Address)) - err = writeKeyFile(fullpath, keyjson) - if err != nil { - return err, common.Address{} - } - return nil, key.Address +// StoreKey generates a key, encrypts with 'auth' and stores in the given directory +func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) { + _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, crand.Reader, auth) + return a.Address, err } func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 30e50a520fb..846c679a4a2 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/console" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" "gopkg.in/urfave/cli.v1" ) @@ -292,7 +291,6 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr // accountCreate creates a new account into the keystore defined by the CLI flags. func accountCreate(ctx *cli.Context) error { - cfg := gethConfig{} // Load config file. if file := ctx.GlobalString(configFileFlag.Name); file != "" { @@ -301,7 +299,7 @@ func accountCreate(ctx *cli.Context) error { } } utils.SetNodeConfig(ctx, &cfg.Node) - scryptN, scryptP, keydir, err := node.ResolveAccountConfig(&cfg.Node) + scryptN, scryptP, keydir, err := cfg.Node.AccountConfig() if err != nil { utils.Fatalf("Failed to create account: %v", err) @@ -309,7 +307,7 @@ func accountCreate(ctx *cli.Context) error { password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - err, address := keystore.StoreKey(keydir, password, scryptN, scryptP) + address, err := keystore.StoreKey(keydir, password, scryptN, scryptP) if err != nil { utils.Fatalf("Failed to create account: %v", err) diff --git a/node/config.go b/node/config.go index 89efe1911c7..1ee02d89635 100644 --- a/node/config.go +++ b/node/config.go @@ -360,11 +360,11 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node { return nodes } -// ResolveAccountConfig determines the settings for scrypt and keydirectory -func ResolveAccountConfig(conf *Config) (int, int, string, error) { +// AccountConfig determines the settings for scrypt and keydirectory +func (c *Config) AccountConfig() (int, int, string, error) { scryptN := keystore.StandardScryptN scryptP := keystore.StandardScryptP - if conf.UseLightweightKDF { + if c.UseLightweightKDF { scryptN = keystore.LightScryptN scryptP = keystore.LightScryptP } @@ -374,25 +374,28 @@ func ResolveAccountConfig(conf *Config) (int, int, string, error) { err error ) switch { - case filepath.IsAbs(conf.KeyStoreDir): - keydir = conf.KeyStoreDir - case conf.DataDir != "": - if conf.KeyStoreDir == "" { - keydir = filepath.Join(conf.DataDir, datadirDefaultKeyStore) + case filepath.IsAbs(c.KeyStoreDir): + keydir = c.KeyStoreDir + case c.DataDir != "": + if c.KeyStoreDir == "" { + keydir = filepath.Join(c.DataDir, datadirDefaultKeyStore) } else { - keydir, err = filepath.Abs(conf.KeyStoreDir) + keydir, err = filepath.Abs(c.KeyStoreDir) } - case conf.KeyStoreDir != "": - keydir, err = filepath.Abs(conf.KeyStoreDir) - default: - // There is no datadir. - keydir, err = ioutil.TempDir("", "go-ethereum-keystore") + case c.KeyStoreDir != "": + keydir, err = filepath.Abs(c.KeyStoreDir) } return scryptN, scryptP, keydir, err } func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { - scryptN, scryptP, keydir, err := ResolveAccountConfig(conf) + scryptN, scryptP, keydir, err := conf.AccountConfig() + var ephemeral string + if keydir == "" { + // There is no datadir. + keydir, err = ioutil.TempDir("", "go-ethereum-keystore") + ephemeral = keydir + } if err != nil { return nil, "", err @@ -418,5 +421,5 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { backends = append(backends, trezorhub) } } - return accounts.NewManager(backends...), keydir, nil + return accounts.NewManager(backends...), ephemeral, nil } From f4c3ee1a52460263f76846bf9ade3feca2190a1d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 15:45:30 +0100 Subject: [PATCH 4/5] cmd/geth : make use of correct default datadir for geth account new --- cmd/geth/accountcmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 846c679a4a2..602eb1d6422 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -291,7 +291,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr // accountCreate creates a new account into the keystore defined by the CLI flags. func accountCreate(ctx *cli.Context) error { - cfg := gethConfig{} + cfg := gethConfig{Node: defaultNodeConfig()} // Load config file. if file := ctx.GlobalString(configFileFlag.Name); file != "" { if err := loadConfig(file, &cfg); err != nil { From fcc3212103dd713cf09f07def94f4be059686bae Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 16:13:51 +0100 Subject: [PATCH 5/5] cmd/geth: fix error message --- cmd/geth/accountcmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 602eb1d6422..0db5c4ce0f8 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -302,7 +302,7 @@ func accountCreate(ctx *cli.Context) error { scryptN, scryptP, keydir, err := cfg.Node.AccountConfig() if err != nil { - utils.Fatalf("Failed to create account: %v", err) + utils.Fatalf("Failed to read configuration: %v", err) } password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))