-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge PR #5097: Add keys migrate command
Add new command to assist users migrate their keys from the legacy on-disk keybase to the new OS keyring-based implementation. Ref #4754
- Loading branch information
1 parent
d010b68
commit 3e6562c
Showing
9 changed files
with
187 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
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" | ||
) | ||
|
||
// 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", | ||
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.NewTestKeyring(types.GetConfig().GetKeyringServiceName(), rootDir) | ||
} else { | ||
keyring = keys.NewKeyring(types.GetConfig().GetKeyringServiceName(), rootDir, buf) | ||
} | ||
|
||
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 | ||
} | ||
|
||
password, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// 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, migratePassphrase) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := keyring.ImportPrivKey(keyName, armoredPriv, migratePassphrase); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package keys | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/cosmos/cosmos-sdk/tests" | ||
|
||
"github.com/spf13/viper" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/tendermint/tendermint/libs/cli" | ||
) | ||
|
||
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{})) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters