From 94b8bc07eabce9cee0c1b6cce32cdb9b7c2202fb Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 08:39:24 -0700 Subject: [PATCH 01/13] Export NewTestKeyringKeybase --- crypto/keys/lazy_keybase_keyring.go | 13 ++++++++++ crypto/keys/lazy_keybase_keyring_test.go | 31 ++++++------------------ 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/crypto/keys/lazy_keybase_keyring.go b/crypto/keys/lazy_keybase_keyring.go index 311ed29517d6..0bdd4fc00725 100644 --- a/crypto/keys/lazy_keybase_keyring.go +++ b/crypto/keys/lazy_keybase_keyring.go @@ -45,6 +45,19 @@ func NewKeybaseKeyring(name string, dir string, userInput io.Reader, test bool) return lazyKeybaseKeyring{name: name, dir: dir, userInput: userInput, test: test} } +// New creates a new instance of a lazy keybase. +func NewTestKeybaseKeyring(name string, dir string) Keybase { + if _, err := keyring.Open(keyring.Config{ + AllowedBackends: []keyring.BackendType{"file"}, + ServiceName: name, + FileDir: dir, + }); err != nil { + panic(err) + } + + return lazyKeybaseKeyring{name: name, dir: dir, test: true} +} + func (lkb lazyKeybaseKeyring) lkbToKeyringConfig() keyring.Config { if lkb.test { return keyring.Config{ diff --git a/crypto/keys/lazy_keybase_keyring_test.go b/crypto/keys/lazy_keybase_keyring_test.go index e2866141be44..a57398e9d632 100644 --- a/crypto/keys/lazy_keybase_keyring_test.go +++ b/crypto/keys/lazy_keybase_keyring_test.go @@ -9,30 +9,15 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/99designs/keyring" - "github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" ) -// New creates a new instance of a lazy keybase. -func newTestKeybaseKeyring(name string, dir string) Keybase { - if _, err := keyring.Open(keyring.Config{ - AllowedBackends: []keyring.BackendType{"file"}, - ServiceName: name, - FileDir: dir, - }); err != nil { - panic(err) - } - - return lazyKeybaseKeyring{name: name, dir: dir, test: true} -} - func TestNewTestKeybaseKeyring(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) lazykb, ok := kb.(lazyKeybaseKeyring) require.True(t, ok) require.Equal(t, lazykb.name, "keybasename") @@ -41,7 +26,7 @@ func TestNewTestKeybaseKeyring(t *testing.T) { func TestLazyKeyManagementKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) algo := Secp256k1 n1, n2, n3 := "personal", "business", "other" @@ -124,7 +109,7 @@ func TestLazyKeyManagementKeyRing(t *testing.T) { func TestLazySignVerifyKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) algo := Secp256k1 n1, n2, n3 := "some dude", "a dudette", "dude-ish" @@ -199,7 +184,7 @@ func TestLazySignVerifyKeyRing(t *testing.T) { func TestLazyExportImportKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) require.NoError(t, err) @@ -227,7 +212,7 @@ func TestLazyExportImportKeyRing(t *testing.T) { func TestLazyExportImportPubKeyKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) // CreateMnemonic a private-public key pair and ensure consistency notPasswd := "n9y25ah7" @@ -266,7 +251,7 @@ func TestLazyExportImportPubKeyKeyRing(t *testing.T) { func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) require.NoError(t, err) @@ -281,7 +266,7 @@ func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) { func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) algo := Secp256k1 n1, n2 := "old-name", "new name" @@ -314,7 +299,7 @@ func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) { func TestLazySeedPhraseKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := newTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeybaseKeyring("keybasename", dir) algo := Secp256k1 n1, n2 := "lost-key", "found-again" From 3942d28ceb0fbe9eeae8d1229062384e665745b9 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 08:40:14 -0700 Subject: [PATCH 02/13] Add keys migrate command --- client/keys/migrate.go | 84 +++++++++++++++++++++++++++++++++++++ client/keys/migrate_test.go | 36 ++++++++++++++++ client/keys/root.go | 1 + types/config.go | 20 ++++++++- 4 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 client/keys/migrate.go create mode 100644 client/keys/migrate_test.go diff --git a/client/keys/migrate.go b/client/keys/migrate.go new file mode 100644 index 000000000000..73f2169339e6 --- /dev/null +++ b/client/keys/migrate.go @@ -0,0 +1,84 @@ +package keys + +import ( + "bufio" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/crypto/keys" + "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func migrateCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "migrate", + Short: "Migrate key information from the lagacy key database to the OS secret store, or encrypted file store as a fall-back and save it", + Long: `Migrate keys from the legacy on-disk secret store to the OS keyring. +The command asks for every passphrase. If the passphrase is incorrect, it skips the respective key. +`, + Args: cobra.ExactArgs(0), + RunE: runMigrateCmd, + } + + cmd.Flags().Bool(flags.FlagDryRun, false, "Do everything which is supposed to be done, but don't write any changes to the keyring.") + return cmd +} + +func runMigrateCmd(cmd *cobra.Command, args []string) error { + // instantiate legacy keybase + rootDir := viper.GetString(flags.FlagHome) + legacykb, err := NewKeyBaseFromDir(rootDir) + if err != nil { + return err + } + + // fetch list of keys from legacy keybase + oldKeys, err := legacykb.List() + if err != nil { + return err + } + + // instantiate keyring + var keyring keys.Keybase + buf := bufio.NewReader(cmd.InOrStdin()) + if viper.GetBool(flags.FlagDryRun) { + keyring = keys.NewTestKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir) + } else { + keyring = keys.NewKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf, false) + } + + for _, key := range oldKeys { + legKeyInfo, err := legacykb.Export(key.GetName()) + if err != nil { + return err + } + + keyName := key.GetName() + keyType := key.GetType() + cmd.PrintErrf("Migrating %s (%s) ...\n", key.GetName(), keyType) + if keyType != keys.TypeLocal { + if err := keyring.Import(keyName, legKeyInfo); err != nil { + return err + } + continue + } + + passwd, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) + if err != nil { + return err + } + + armoredPriv, err := legacykb.ExportPrivKey(keyName, passwd, "abc") + if err != nil { + return err + } + + if err := keyring.ImportPrivKey(keyName, armoredPriv, "abc"); err != nil { + return err + } + } + + return err +} diff --git a/client/keys/migrate_test.go b/client/keys/migrate_test.go new file mode 100644 index 000000000000..794680d819de --- /dev/null +++ b/client/keys/migrate_test.go @@ -0,0 +1,36 @@ +package keys + +import ( + "testing" + + "github.com/spf13/viper" + "github.com/tendermint/tendermint/libs/cli" + + "github.com/stretchr/testify/assert" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/tests" +) + +func Test_runMigrateCmd(t *testing.T) { + cmd := addKeyCommand() + assert.NotNil(t, cmd) + mockIn, _, _ := tests.ApplyMockIO(cmd) + + kbHome, kbCleanUp := tests.NewTestCaseDir(t) + assert.NotNil(t, kbHome) + defer kbCleanUp() + viper.Set(flags.FlagHome, kbHome) + + viper.Set(cli.OutputFlag, OutputFormatText) + + mockIn.Reset("test1234\ntest1234\n") + err := runAddCmd(cmd, []string{"keyname1"}) + assert.NoError(t, err) + + viper.Set(flags.FlagDryRun, true) + cmd = migrateCommand() + mockIn, _, _ = tests.ApplyMockIO(cmd) + mockIn.Reset("test1234\n") + assert.NoError(t, runMigrateCmd(cmd, []string{})) +} diff --git a/client/keys/root.go b/client/keys/root.go index bd22f3194322..b95740a2c036 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -29,6 +29,7 @@ func Commands() *cobra.Command { deleteKeyCommand(), updateKeyCommand(), parseKeyStringCommand(), + migrateCommand(), ) return cmd } diff --git a/types/config.go b/types/config.go index ce116352f2bb..51c5b74bca2f 100644 --- a/types/config.go +++ b/types/config.go @@ -4,6 +4,9 @@ import ( "sync" ) +// DefaultKeyringServiceName defines a default service name for the keyring. +const DefaultKeyringServiceName = "cosmos" + // Config is the structure that holds the SDK configuration parameters. // This could be used to initialize certain configuration parameters for the SDK. type Config struct { @@ -14,6 +17,7 @@ type Config struct { fullFundraiserPath string txEncoder TxEncoder addressVerifier func([]byte) error + keyringServiceName string } var ( @@ -31,6 +35,7 @@ var ( coinType: CoinType, fullFundraiserPath: FullFundraiserPath, txEncoder: nil, + keyringServiceName: DefaultKeyringServiceName, } ) @@ -97,6 +102,12 @@ func (config *Config) SetFullFundraiserPath(fullFundraiserPath string) { config.fullFundraiserPath = fullFundraiserPath } +// Set the keyringServiceName (BIP44Prefix) on the config +func (config *Config) SetKeyringServiceName(keyringServiceName string) { + config.assertNotSealed() + config.keyringServiceName = keyringServiceName +} + // Seal seals the config such that the config state could not be modified further func (config *Config) Seal() *Config { config.mtx.Lock() @@ -146,12 +157,17 @@ func (config *Config) GetAddressVerifier() func([]byte) error { return config.addressVerifier } -// Get the BIP-0044 CoinType code on the config +// GetCoinType returns the BIP-0044 CoinType code on the config. func (config *Config) GetCoinType() uint32 { return config.coinType } -// Get the FullFundraiserPath (BIP44Prefix) on the config +// GetFullFundraiserPath returns the BIP44Prefix. func (config *Config) GetFullFundraiserPath() string { return config.fullFundraiserPath } + +// GetKeyringServiceName returns the keyring service name from the config. +func (config *Config) GetKeyringServiceName() string { + return config.keyringServiceName +} From a05514038ea9d9f9e41c49831c8a6da4c21a293f Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 08:48:00 -0700 Subject: [PATCH 03/13] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b25f03ed77..58c970175969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,9 @@ the following [issue](https://github.com/keybase/go-keychain/issues/47) with the you encounter this issue, you must upgrade your xcode command line tools to version >= `10.2`. You can upgrade via: `sudo rm -rf /Library/Developer/CommandLineTools; xcode-select --install`. Verify the correct version via: `pkgutil --pkg-info=com.apple.pkg.CLTools_Executables`. +* (keys) [\#5097](https://github.com/cosmos/cosmos-sdk/pull/5097) New `keys migrate` command to assist users migrate their keys +to the new keyring. + ### Improvements From e4c3483f9c79527079ddafc3be38eab51efd8455 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 08:50:12 -0700 Subject: [PATCH 04/13] Goimports --- client/keys/migrate.go | 1 + client/keys/migrate_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index 73f2169339e6..8e7e0a36d101 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" "github.com/spf13/viper" ) diff --git a/client/keys/migrate_test.go b/client/keys/migrate_test.go index 794680d819de..61a55ef90804 100644 --- a/client/keys/migrate_test.go +++ b/client/keys/migrate_test.go @@ -3,13 +3,13 @@ package keys import ( "testing" - "github.com/spf13/viper" - "github.com/tendermint/tendermint/libs/cli" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/tests" + "github.com/spf13/viper" "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/tests" + "github.com/tendermint/tendermint/libs/cli" ) func Test_runMigrateCmd(t *testing.T) { From dcf9754a4b377023e6d6bf3e8a846e9ea8f59d29 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 09:36:57 -0700 Subject: [PATCH 05/13] remove test boolean flag from NewKeybaseKeyring --- client/keys/migrate.go | 2 +- crypto/keys/lazy_keybase_keyring.go | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index 8e7e0a36d101..238c72f8a341 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -47,7 +47,7 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error { if viper.GetBool(flags.FlagDryRun) { keyring = keys.NewTestKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir) } else { - keyring = keys.NewKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf, false) + keyring = keys.NewKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf) } for _, key := range oldKeys { diff --git a/crypto/keys/lazy_keybase_keyring.go b/crypto/keys/lazy_keybase_keyring.go index 0bdd4fc00725..7f9224e0250b 100644 --- a/crypto/keys/lazy_keybase_keyring.go +++ b/crypto/keys/lazy_keybase_keyring.go @@ -34,7 +34,7 @@ type lazyKeybaseKeyring struct { // NewKeybaseKeyring creates a new instance of a lazy keybase using a Keyring as // the persistence layer. -func NewKeybaseKeyring(name string, dir string, userInput io.Reader, test bool) Keybase { +func NewKeybaseKeyring(name string, dir string, userInput io.Reader) Keybase { _, err := keyring.Open(keyring.Config{ ServiceName: name, }) @@ -42,10 +42,11 @@ func NewKeybaseKeyring(name string, dir string, userInput io.Reader, test bool) panic(err) } - return lazyKeybaseKeyring{name: name, dir: dir, userInput: userInput, test: test} + return lazyKeybaseKeyring{name: name, dir: dir, userInput: userInput, test: false} } -// New creates a new instance of a lazy keybase. +// NewTestKeybaseKeyring creates a new instance of a keyring keybase +// for testing purposes that does not prompt users for password. func NewTestKeybaseKeyring(name string, dir string) Keybase { if _, err := keyring.Open(keyring.Config{ AllowedBackends: []keyring.BackendType{"file"}, From 5ab4d2a90e6d2dbe5e57496993c2c00fe580d2d9 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 10:19:08 -0700 Subject: [PATCH 06/13] Fix keys command tests --- client/keys/root_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 6a81d0c12aaf..6794d725e6f0 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -11,5 +11,5 @@ func TestCommands(t *testing.T) { assert.NotNil(t, rootCommands) // Commands are registered - assert.Equal(t, 10, len(rootCommands.Commands())) + assert.Equal(t, 11, len(rootCommands.Commands())) } From 35b538008e8573c34fae8db4ce0c128d825c0896 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 11:29:56 -0700 Subject: [PATCH 07/13] Remove sdkConfig singleton --- types/config.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/types/config.go b/types/config.go index 51c5b74bca2f..f01593afaced 100644 --- a/types/config.go +++ b/types/config.go @@ -20,9 +20,9 @@ type Config struct { keyringServiceName string } -var ( - // Initializing an instance of Config - sdkConfig = &Config{ +// GetConfig returns the config instance for the SDK. +func GetConfig() *Config { + return &Config{ sealed: false, bech32AddressPrefix: map[string]string{ "account_addr": Bech32PrefixAccAddr, @@ -37,11 +37,6 @@ var ( txEncoder: nil, keyringServiceName: DefaultKeyringServiceName, } -) - -// GetConfig returns the config instance for the SDK. -func GetConfig() *Config { - return sdkConfig } func (config *Config) assertNotSealed() { From b5d4517a3a00962f0a610912d8ae50a58fd03ef7 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 13:18:50 -0700 Subject: [PATCH 08/13] Revert "Remove sdkConfig singleton" This reverts commit 35b538008e8573c34fae8db4ce0c128d825c0896. --- types/config.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/types/config.go b/types/config.go index f01593afaced..51c5b74bca2f 100644 --- a/types/config.go +++ b/types/config.go @@ -20,9 +20,9 @@ type Config struct { keyringServiceName string } -// GetConfig returns the config instance for the SDK. -func GetConfig() *Config { - return &Config{ +var ( + // Initializing an instance of Config + sdkConfig = &Config{ sealed: false, bech32AddressPrefix: map[string]string{ "account_addr": Bech32PrefixAccAddr, @@ -37,6 +37,11 @@ func GetConfig() *Config { txEncoder: nil, keyringServiceName: DefaultKeyringServiceName, } +) + +// GetConfig returns the config instance for the SDK. +func GetConfig() *Config { + return sdkConfig } func (config *Config) assertNotSealed() { From d4b58d70668b49770d48b491a868a3f92db6837d Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 24 Sep 2019 16:09:44 -0700 Subject: [PATCH 09/13] Rework sdkConfig singleton --- types/config.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/types/config.go b/types/config.go index 51c5b74bca2f..b3e569bcb82f 100644 --- a/types/config.go +++ b/types/config.go @@ -20,8 +20,14 @@ type Config struct { keyringServiceName string } -var ( - // Initializing an instance of Config +// cosmos-sdk wide global singleton +var sdkConfig *Config + +// GetConfig returns the config instance for the SDK. +func GetConfig() *Config { + if sdkConfig != nil { + return sdkConfig + } sdkConfig = &Config{ sealed: false, bech32AddressPrefix: map[string]string{ @@ -37,10 +43,6 @@ var ( txEncoder: nil, keyringServiceName: DefaultKeyringServiceName, } -) - -// GetConfig returns the config instance for the SDK. -func GetConfig() *Config { return sdkConfig } From acbabb2cf363d7bae297c7ffda1adeea68226445 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 25 Sep 2019 13:29:03 -0700 Subject: [PATCH 10/13] Rename KeyringKeybase -> Keyring to avoid ambiguity --- client/keys/migrate.go | 4 ++-- crypto/keys/lazy_keybase_keyring.go | 8 ++++---- crypto/keys/lazy_keybase_keyring_test.go | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index 238c72f8a341..d44cbbb6ef1d 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -45,9 +45,9 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error { var keyring keys.Keybase buf := bufio.NewReader(cmd.InOrStdin()) if viper.GetBool(flags.FlagDryRun) { - keyring = keys.NewTestKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir) + keyring = keys.NewTestKeyring(types.GetConfig().GetKeyringServiceName(), rootDir) } else { - keyring = keys.NewKeybaseKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf) + keyring = keys.NewKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf) } for _, key := range oldKeys { diff --git a/crypto/keys/lazy_keybase_keyring.go b/crypto/keys/lazy_keybase_keyring.go index 7f9224e0250b..966a97dadbfc 100644 --- a/crypto/keys/lazy_keybase_keyring.go +++ b/crypto/keys/lazy_keybase_keyring.go @@ -32,9 +32,9 @@ type lazyKeybaseKeyring struct { userInput io.Reader } -// NewKeybaseKeyring creates a new instance of a lazy keybase using a Keyring as +// NewKeyring creates a new instance of a lazy keybase using a Keyring as // the persistence layer. -func NewKeybaseKeyring(name string, dir string, userInput io.Reader) Keybase { +func NewKeyring(name string, dir string, userInput io.Reader) Keybase { _, err := keyring.Open(keyring.Config{ ServiceName: name, }) @@ -45,9 +45,9 @@ func NewKeybaseKeyring(name string, dir string, userInput io.Reader) Keybase { return lazyKeybaseKeyring{name: name, dir: dir, userInput: userInput, test: false} } -// NewTestKeybaseKeyring creates a new instance of a keyring keybase +// NewTestKeyring creates a new instance of a keyring keybase // for testing purposes that does not prompt users for password. -func NewTestKeybaseKeyring(name string, dir string) Keybase { +func NewTestKeyring(name string, dir string) Keybase { if _, err := keyring.Open(keyring.Config{ AllowedBackends: []keyring.BackendType{"file"}, ServiceName: name, diff --git a/crypto/keys/lazy_keybase_keyring_test.go b/crypto/keys/lazy_keybase_keyring_test.go index a57398e9d632..ebba4f7df858 100644 --- a/crypto/keys/lazy_keybase_keyring_test.go +++ b/crypto/keys/lazy_keybase_keyring_test.go @@ -17,7 +17,7 @@ import ( func TestNewTestKeybaseKeyring(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) lazykb, ok := kb.(lazyKeybaseKeyring) require.True(t, ok) require.Equal(t, lazykb.name, "keybasename") @@ -26,7 +26,7 @@ func TestNewTestKeybaseKeyring(t *testing.T) { func TestLazyKeyManagementKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) algo := Secp256k1 n1, n2, n3 := "personal", "business", "other" @@ -109,7 +109,7 @@ func TestLazyKeyManagementKeyRing(t *testing.T) { func TestLazySignVerifyKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) algo := Secp256k1 n1, n2, n3 := "some dude", "a dudette", "dude-ish" @@ -184,7 +184,7 @@ func TestLazySignVerifyKeyRing(t *testing.T) { func TestLazyExportImportKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) require.NoError(t, err) @@ -212,7 +212,7 @@ func TestLazyExportImportKeyRing(t *testing.T) { func TestLazyExportImportPubKeyKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) // CreateMnemonic a private-public key pair and ensure consistency notPasswd := "n9y25ah7" @@ -251,7 +251,7 @@ func TestLazyExportImportPubKeyKeyRing(t *testing.T) { func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) require.NoError(t, err) @@ -266,7 +266,7 @@ func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) { func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) algo := Secp256k1 n1, n2 := "old-name", "new name" @@ -299,7 +299,7 @@ func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) { func TestLazySeedPhraseKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) defer cleanup() - kb := NewTestKeybaseKeyring("keybasename", dir) + kb := NewTestKeyring("keybasename", dir) algo := Secp256k1 n1, n2 := "lost-key", "found-again" From 72aed3589856cb3aefed657057e95ffb127a1367 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 25 Sep 2019 16:34:21 -0700 Subject: [PATCH 11/13] Rework comments --- crypto/keys/lazy_keybase_keyring.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crypto/keys/lazy_keybase_keyring.go b/crypto/keys/lazy_keybase_keyring.go index 966a97dadbfc..2c869f351325 100644 --- a/crypto/keys/lazy_keybase_keyring.go +++ b/crypto/keys/lazy_keybase_keyring.go @@ -32,8 +32,7 @@ type lazyKeybaseKeyring struct { userInput io.Reader } -// NewKeyring creates a new instance of a lazy keybase using a Keyring as -// the persistence layer. +// NewKeyring creates a new instance of a keyring. func NewKeyring(name string, dir string, userInput io.Reader) Keybase { _, err := keyring.Open(keyring.Config{ ServiceName: name, @@ -45,8 +44,8 @@ func NewKeyring(name string, dir string, userInput io.Reader) Keybase { return lazyKeybaseKeyring{name: name, dir: dir, userInput: userInput, test: false} } -// NewTestKeyring creates a new instance of a keyring keybase -// for testing purposes that does not prompt users for password. +// NewTestKeyring creates a new instance of a keyring for +// testing purposes that does not prompt users for password. func NewTestKeyring(name string, dir string) Keybase { if _, err := keyring.Open(keyring.Config{ AllowedBackends: []keyring.BackendType{"file"}, From 413daec83406d35949322c9dbfab41ba97182b57 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 30 Sep 2019 11:30:34 -0400 Subject: [PATCH 12/13] Clarify passphrase usage --- client/keys/migrate.go | 8 +++++--- crypto/keys/keybase_keyring.go | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index d44cbbb6ef1d..beb3ddb7d4e8 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -66,17 +66,19 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error { continue } - passwd, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) + password, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) if err != nil { return err } - armoredPriv, err := legacykb.ExportPrivKey(keyName, passwd, "abc") + // NOTE: A passphrase is not actually needed here as when the key information + // is imported into the Keyring keystore it only needs the password (see: writeLocalKey). + armoredPriv, err := legacykb.ExportPrivKey(keyName, password, "NOOP_PASSPHRASE") if err != nil { return err } - if err := keyring.ImportPrivKey(keyName, armoredPriv, "abc"); err != nil { + if err := keyring.ImportPrivKey(keyName, armoredPriv, "NOOP_PASSPHRASE"); err != nil { return err } } diff --git a/crypto/keys/keybase_keyring.go b/crypto/keys/keybase_keyring.go index b89671b0b934..1336a77b965e 100644 --- a/crypto/keys/keybase_keyring.go +++ b/crypto/keys/keybase_keyring.go @@ -310,10 +310,11 @@ func (kb keyringKeybase) ImportPrivKey(name, armor, passphrase string) error { privKey, err := mintkey.UnarmorDecryptPrivKey(armor, passphrase) if err != nil { - return errors.Wrap(err, "failed to import private key") + return errors.Wrap(err, "failed to decrypt private key") } - kb.writeLocalKey(name, privKey, passphrase) + // NOTE: The keyring keystore has no need for a passphrase. + kb.writeLocalKey(name, privKey, "") return nil } @@ -406,7 +407,7 @@ func (kb keyringKeybase) Update(name, oldpass string, getNewpass func() (string, // CloseDB releases the lock and closes the storage backend. func (kb keyringKeybase) CloseDB() {} -func (kb keyringKeybase) writeLocalKey(name string, priv tmcrypto.PrivKey, passphrase string) Info { +func (kb keyringKeybase) writeLocalKey(name string, priv tmcrypto.PrivKey, _ string) Info { // encrypt private key using keyring pub := priv.PubKey() info := newLocalInfo(name, pub, string(priv.Bytes())) From 98aff61ec21e70f450f18c22e907a417313fbb51 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 30 Sep 2019 11:33:55 -0400 Subject: [PATCH 13/13] Update godoc --- client/keys/migrate.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index beb3ddb7d4e8..ae9c6e6b7804 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -12,6 +12,10 @@ import ( "github.com/spf13/viper" ) +// migratePassphrase is used as a no-op migration key passphrase as a passphrase +// is not needed for importing into the Keyring keystore. +const migratePassphrase = "NOOP_PASSPHRASE" + func migrateCommand() *cobra.Command { cmd := &cobra.Command{ Use: "migrate", @@ -73,12 +77,12 @@ func runMigrateCmd(cmd *cobra.Command, args []string) error { // NOTE: A passphrase is not actually needed here as when the key information // is imported into the Keyring keystore it only needs the password (see: writeLocalKey). - armoredPriv, err := legacykb.ExportPrivKey(keyName, password, "NOOP_PASSPHRASE") + armoredPriv, err := legacykb.ExportPrivKey(keyName, password, migratePassphrase) if err != nil { return err } - if err := keyring.ImportPrivKey(keyName, armoredPriv, "NOOP_PASSPHRASE"); err != nil { + if err := keyring.ImportPrivKey(keyName, armoredPriv, migratePassphrase); err != nil { return err } }