From 8c752cccfda00b858a9102a3ef9b499a10d5a12c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Nov 2017 15:17:45 +0100 Subject: [PATCH] accounts/keystore: Fix geth account new to operate directly on a keystore file --- accounts/keystore/keystore_passphrase.go | 18 ++++++++++++++ cmd/geth/accountcmd.go | 25 ++++++++++++++++---- node/config.go | 30 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 535608a600..164da653bc 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 0f53c92b0a..30e50a520f 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) - 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) + 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) } - fmt.Printf("Address: {%x}\n", account.Address) + + 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) + + if err != nil { + utils.Fatalf("Failed to create account: %v", err) + } + fmt.Printf("Address: {%x}\n", address) return nil } diff --git a/node/config.go b/node/config.go index be9e21b4fa..b8f8898931 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