Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch secret store to the keyring secret store #4754

Closed
wants to merge 120 commits into from
Closed
Show file tree
Hide file tree
Changes from 115 commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
28859d2
initial work on keyringKeybase
poldsam Apr 28, 2019
10fcf0c
Created a keybase implmentation based on keyring
poldsam May 2, 2019
aa0441f
Added the lazykey keybase for keyring
poldsam May 3, 2019
3455769
First test. Not yet working
poldsam May 3, 2019
75e4272
Temporary bandaid fix for testing
zmanian May 8, 2019
20d26e3
fixes for keybase tests passed
poldsam May 8, 2019
df118b2
adding another tests passed
poldsam May 8, 2019
12cd140
adding another tests passed
poldsam May 8, 2019
040f3a4
adding another tests passed
poldsam May 8, 2019
3e36d53
adding more tests passed
poldsam May 8, 2019
7381a97
sorting keys in alphabetical order
poldsam May 9, 2019
49ef05d
Merge commit with master
zmanian Jul 10, 2019
650ef8b
Apply Formating
zmanian Jul 10, 2019
630aec0
implementing updated to the keybase interface
poldsam Jul 10, 2019
f82f871
implementing interface for the lazy keybase keyring
poldsam Jul 10, 2019
c4bf95d
started migration command
poldsam Jul 11, 2019
43e4d6c
changing variable name to camel case format
poldsam Jul 11, 2019
0b9995d
starting migrate command testing
poldsam Jul 11, 2019
98caf12
Fix tests for migration
zmanian Jul 11, 2019
a0e18dd
Fixed test harnesses
zmanian Jul 11, 2019
ca275a2
adding FlagSecretStore to all key commands
poldsam Jul 12, 2019
4283079
adding FlagSecretStore to all key commands
poldsam Jul 12, 2019
3fb144a
fixing a typo in FlagSecretStore
poldsam Jul 12, 2019
4511c5f
adding conditional for FlagSecretStore value; if set to false use new…
poldsam Jul 13, 2019
9186212
Fixing testing errors for new keyring keybase
poldsam Jul 15, 2019
66ba136
Fixing update_test to run only on legacy secret store, test irrelevan…
poldsam Jul 15, 2019
cbe6b34
Merge commit
poldsam Jul 15, 2019
54ee067
Expected fix for the Import issue
zmanian Jul 16, 2019
73f0188
Merge branch 'kristi/keyringKeybase' of github.com:Proof-Of-Audit/cos…
poldsam Jul 16, 2019
2ab5885
Fixing migrate to point to the same keyring service
poldsam Jul 16, 2019
5b5f483
Allowing signing for legacy key store
poldsam Jul 17, 2019
8155784
adding migrate command to the changelog
poldsam Jul 17, 2019
14053ee
deleting testing data after test finishes
poldsam Jul 17, 2019
4ae6295
Updating migrate command in the changelog
poldsam Jul 17, 2019
374b636
Don't ask for password when using keyring secret store
poldsam Jul 17, 2019
02c146a
Detect if running on server
poldsam Jul 18, 2019
41706eb
Add a print statement
poldsam Jul 18, 2019
c5fde86
Print backends
poldsam Jul 18, 2019
395d008
Fix for backend detection
poldsam Jul 18, 2019
9f6c0fb
update test password
poldsam Jul 18, 2019
e02969d
enter password twice
poldsam Jul 18, 2019
2a56062
Productionizes the prompt using keyring file backend to be much more …
zmanian Jul 18, 2019
669fa30
add some error handling
zmanian Jul 18, 2019
fb6c357
Print Bcrypt errors
zmanian Jul 18, 2019
e92e489
Fix the salt length
zmanian Jul 18, 2019
878145f
Switch to random salt
zmanian Jul 18, 2019
528df97
Switch to using the cobra provided input for getinng the keyring pass…
zmanian Jul 19, 2019
17067ee
Fix tests so they compile
zmanian Jul 19, 2019
f6d5ff4
Hopefully fix add test
poldsam Jul 19, 2019
f8b78ae
Improve the delete command for servers
poldsam Jul 19, 2019
a224259
Delete_tests improvements
poldsam Jul 19, 2019
04589a6
Another passphrase input
poldsam Jul 19, 2019
f379cfc
improving export_test
poldsam Jul 19, 2019
a7344d8
Fixing migrate_test
poldsam Jul 19, 2019
ce6806b
Massive refactor to pipe input through to the Keybase to handle the f…
zmanian Jul 19, 2019
f8867e4
Fixed for the add_test
poldsam Jul 20, 2019
dfef9ba
Fixing delete_test file
poldsam Jul 20, 2019
010c4ec
Fixing add_test
poldsam Jul 20, 2019
253f8ed
Fixing add file to pass password when using keyring to default storin…
poldsam Jul 20, 2019
9539583
Fixing export_test
poldsam Jul 20, 2019
c21bd0c
Fixing export_test
poldsam Jul 20, 2019
8b900c3
Fixing export_test
poldsam Jul 20, 2019
d49c4a0
Fixing export_tests
poldsam Jul 20, 2019
9e2aa00
Add a debug print line
poldsam Jul 20, 2019
17f023c
Switch buffer was passed to keybase for Add
poldsam Jul 20, 2019
96b4b94
Switch the buffer we use in delete
poldsam Jul 20, 2019
75e1acf
Fix test input
poldsam Jul 20, 2019
c182e14
Add mock input
poldsam Jul 20, 2019
bef4778
Switch the command buffer
poldsam Jul 20, 2019
7c497d8
Fix passphase setting for import test
poldsam Jul 20, 2019
c474bef
Fixing list_tests
poldsam Jul 20, 2019
2e8e881
Put the MockIn inside the loop
poldsam Jul 20, 2019
d1a013c
Count failures when using the file backend and eventually error
poldsam Jul 20, 2019
7a78786
Fixing migrate_test
poldsam Jul 20, 2019
e66b8ce
Handle input buffer correctly
poldsam Jul 20, 2019
c6b537b
Fixing show_test
poldsam Jul 20, 2019
e98f309
Fixing show_test
poldsam Jul 20, 2019
9f47a91
Fixing update_test
poldsam Jul 20, 2019
4069283
Fixes for multiple password entries are needed
poldsam Jul 20, 2019
6e6f1a3
Adding InBuf reader to show_test
poldsam Jul 21, 2019
effd2dd
Adding InBuf reader to tests
poldsam Jul 21, 2019
f3de484
Build deps update
poldsam Jul 21, 2019
0b7ecd9
Kristi/keyring keybase (#1)
poldsam Jul 21, 2019
e8cf6c9
Try to cache passwords in the keyring so that they don't have to ente…
zmanian Jul 21, 2019
9c4cf7e
Merge pull request #3 from Proof-Of-Audit/zaki/CachedPasswords
zmanian Jul 21, 2019
09cc23f
Fixing error checking
poldsam Jul 23, 2019
507cdcf
Removing unnecessary print statements
poldsam Jul 23, 2019
2717800
Fixing fnt Print to redirect to stderr
poldsam Jul 23, 2019
c2338a7
Merge commit
poldsam Jul 23, 2019
5207c7b
Deleting keys data
poldsam Jul 23, 2019
af7dece
Merge branch 'master' of github.com:cosmos/cosmos-sdk into kristi/key…
poldsam Jul 23, 2019
8f66659
Removing unnecessary println statement
poldsam Jul 29, 2019
cfb4dd3
Removing println statement, moving this to Stderr
poldsam Jul 29, 2019
9f73d8f
Merge branch 'master' of github.com:cosmos/cosmos-sdk into kristi/key…
poldsam Jul 29, 2019
52a0bd9
Fixing package import error in list.go
poldsam Jul 29, 2019
4ab875b
Merge branch 'master' of github.com:cosmos/cosmos-sdk into kristi/key…
poldsam Jul 30, 2019
d0f676e
Apply suggestions from code review
poldsam Aug 14, 2019
a9c3573
Merge branch 'kristi/keyringKeybase2' of github.com:Proof-Of-Audit/co…
poldsam Aug 14, 2019
e4417a1
Resolved comments from code review
poldsam Aug 15, 2019
1cea42c
Merge commit
poldsam Aug 15, 2019
777bbb0
Fix for build error
poldsam Aug 15, 2019
7e348ae
Fixing print statement
poldsam Aug 15, 2019
096f56c
Merge commit
poldsam Aug 16, 2019
bfc3b55
Refactor Clicontext constructor to better fit the builder pattern
poldsam Aug 16, 2019
acf6b17
updating changelog with Unreleased entry
poldsam Aug 20, 2019
803d2eb
Fixing error handling and typos
poldsam Sep 4, 2019
788f762
Fixing update_test
poldsam Sep 4, 2019
2e74282
Fixing migrate_test
poldsam Sep 4, 2019
54d2326
fixing conflicts
poldsam Sep 5, 2019
bbc3ea2
fixing conflicting changes
poldsam Sep 5, 2019
9065a01
fixing make build error
poldsam Sep 5, 2019
f7c39a9
Fixing print errorrs
poldsam Sep 5, 2019
d83f189
removing keys
poldsam Sep 5, 2019
cda535e
Fixing tupos and errors
poldsam Sep 5, 2019
553ef29
Fixing gobot typeSwitch error
poldsam Sep 5, 2019
cbb43ab
Update crypto/keys/keybase_keyring.go
poldsam Sep 5, 2019
c408e67
Update x/nft/client/cli/tx.go
poldsam Sep 5, 2019
27fa3eb
Fixing gobot errors
poldsam Sep 5, 2019
d59bfd7
Fixing gobot errors
poldsam Sep 5, 2019
3e1a2f3
Merge branch 'kristi/keyringKeybase2' of github.com:Proof-Of-Audit/co…
poldsam Sep 6, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ dependency-graph.png
*.aux
*.out
*.synctex.gz
.clog.yml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undo + merge master 👍

12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking Changes

* (store) [\#4748](https://github.com/cosmos/cosmos-sdk/pull/4748) The `CommitMultiStore` interface
now requires a `SetInterBlockCache` method. Applications that do not wish to support this can simply
have this method perform a no-op.
* (sdk) [\#4754](https://github.com/cosmos/cosmos-sdk/issues/4754) Switching back-end to new secret store using library [Keyring](https://github.com/99designs/keyring)
* This is intended to provide stronger security guarantees by using the OS built-in secret store instead of the legacy key database which was designed to single user computers
* Security audit recommendation was to use the OS secret store
* Existing users are expected to migrate their keys using the migrate command:
* `gaiacli keys migrate`
* Support for legacy keystore is available through the secret store flag:
* `gaiacli keys add <key_name> --legacy`
* Signing transactions is allowed on the legacy store if you pass in the legacy secret store flag
* Running the tests locally may require entering your user password to access your keystore large amount of times (if anyone has a workaround, please leave a comment, thanks)
* (modules) [\#4665](https://github.com/cosmos/cosmos-sdk/issues/4665) Refactored `x/gov` module structure and dev-UX:
* Prepare for module spec integration
* Update gov keys to use big endian encoding instead of little endian
Expand Down
2 changes: 0 additions & 2 deletions client/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ const (
)

var (
// functions aliases
NewCLIContextWithFrom = context.NewCLIContextWithFrom
NewCLIContext = context.NewCLIContext
GetFromFields = context.GetFromFields
ErrInvalidAccount = context.ErrInvalidAccount
Expand Down
76 changes: 57 additions & 19 deletions client/context/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package context

import (
"bufio"
"bytes"
"fmt"
"io"
Expand Down Expand Up @@ -36,6 +37,7 @@ type CLIContext struct {
Client rpcclient.Client
Keybase cryptokeys.Keybase
Output io.Writer
Input io.Reader
OutputFormat string
Height int64
NodeURI string
Expand All @@ -51,22 +53,17 @@ type CLIContext struct {
FromName string
Indent bool
SkipConfirm bool
SecretStore bool
}

// NewCLIContextWithFrom returns a new initialized CLIContext with parameters from the
// command line using Viper. It takes a key name or address and populates the FromName and
// FromAddress field accordingly.
func NewCLIContextWithFrom(from string) CLIContext {
func NewCLIContext() CLIContext {
var nodeURI string
var rpc rpcclient.Client

genOnly := viper.GetBool(flags.FlagGenerateOnly)
fromAddress, fromName, err := GetFromFields(from, genOnly)
alessio marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
fmt.Printf("failed to get from fields: %v", err)
os.Exit(1)
}

if !genOnly {
nodeURI = viper.GetString(flags.FlagNode)
if nodeURI != "" {
Expand All @@ -80,7 +77,7 @@ func NewCLIContextWithFrom(from string) CLIContext {
verifierHome = viper.GetString(flags.FlagHome)
}

return CLIContext{
return CLIContext{ //assign value to new boolean var based on parsing the flag
Client: rpc,
Output: os.Stdout,
NodeURI: nodeURI,
Expand All @@ -93,17 +90,12 @@ func NewCLIContextWithFrom(from string) CLIContext {
Verifier: verifier,
Simulate: viper.GetBool(flags.FlagDryRun),
GenerateOnly: genOnly,
FromAddress: fromAddress,
FromName: fromName,
Indent: viper.GetBool(flags.FlagIndentResponse),
SkipConfirm: viper.GetBool(flags.FlagSkipConfirmation),
SecretStore: viper.GetBool(flags.FlagLegacy),
}
}

// NewCLIContext returns a new initialized CLIContext with parameters from the
// command line using Viper.
func NewCLIContext() CLIContext { return NewCLIContextWithFrom(viper.GetString(flags.FlagFrom)) }

func createVerifier() tmlite.Verifier {
trustNodeDefined := viper.IsSet(flags.FlagTrustNode)
if !trustNodeDefined {
Expand Down Expand Up @@ -238,6 +230,29 @@ func (ctx CLIContext) WithBroadcastMode(mode string) CLIContext {
return ctx
}

// WithInput returns a copy of the context with an updated input.
func (ctx CLIContext) WithInput(input io.Reader) CLIContext {
ctx.Input = bufio.NewReader(input)
return ctx

}

// WithSecretStore returns a copy of the context with an updated SecretStore flag.
func (ctx CLIContext) WithSecretStore() CLIContext {
ctx.SecretStore = viper.GetBool(flags.FlagLegacy)

if ctx.SecretStore {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to switch statement and add a comment that case ctx.SecretStore is for the legacy keybase

var err error
ctx.Keybase, err = keys.NewKeyBaseFromHomeFlag()
if err != nil {
panic(err)
}
} else {
ctx.Keybase = keys.NewKeyringKeybase(ctx.Input) //if flag is set, add flag to struct, then boolean variable.
}
return ctx
}

// PrintOutput prints output while respecting output and indent flags
// NOTE: pass in marshalled structs that have been unmarshaled
// because this function will panic on marshaling errors
Expand All @@ -264,14 +279,32 @@ func (ctx CLIContext) PrintOutput(toPrint fmt.Stringer) (err error) {
return
}

// WithFromFields returns a copy of the context with an updated FromName and FromAddres flag.
func (ctx CLIContext) WithFromFields() CLIContext {
from := viper.GetString(flags.FlagFrom)

fromAddress, fromName, err := GetFromFields(from, ctx.GenerateOnly, ctx.Input)

if err != nil {
panic(err)
}

ctx.FromAddress = fromAddress
ctx.FromName = fromName
return ctx

}

// GetFromFields returns a from account address and Keybase name given either
// an address or key name. If genOnly is true, only a valid Bech32 cosmos
// address is returned.
func GetFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) {
func GetFromFields(from string, genOnly bool, input io.Reader) (sdk.AccAddress, string, error) {
if from == "" {
return nil, "", nil
}

legacySecretStore := viper.GetBool(flags.FlagLegacy)

if genOnly {
addr, err := sdk.AccAddressFromBech32(from)
if err != nil {
Expand All @@ -281,11 +314,16 @@ func GetFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) {
return addr, "", nil
}

keybase, err := keys.NewKeyBaseFromHomeFlag()
if err != nil {
return nil, "", err
var keybase cryptokeys.Keybase
if legacySecretStore {
var err error
keybase, err = keys.NewKeyBaseFromHomeFlag()
if err != nil {
return nil, "", err
}
} else {
keybase = keys.NewKeyringKeybase(input) //if flag is set, add flag to struct, then boolean variable.
}

var info cryptokeys.Info
if addr, err := sdk.AccAddressFromBech32(from); err == nil {
info, err = keybase.GetByAddress(addr)
Expand Down
2 changes: 2 additions & 0 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const (
FlagRPCWriteTimeout = "write-timeout"
FlagOutputDocument = "output-document" // inspired by wget -O
FlagSkipConfirmation = "yes"
FlagLegacy = "legacy"
)

// LineBreak can be included in a command list to provide a blank line
Expand Down Expand Up @@ -99,6 +100,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
c.Flags().Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it")
c.Flags().Bool(FlagGenerateOnly, false, "Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase is not accessible and the node operates offline)")
c.Flags().BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
c.Flags().Bool(FlagLegacy, false, "Use legacy secret store")

// --gas can accept integers and "simulate"
c.Flags().Var(&GasFlagVar, "gas", fmt.Sprintf(
Expand Down
17 changes: 12 additions & 5 deletions client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ the flag --nosort is set.
cmd.Flags().Uint32(flagAccount, 0, "Account number for HD derivation")
cmd.Flags().Uint32(flagIndex, 0, "Address index number for HD derivation")
cmd.Flags().Bool(flags.FlagIndentResponse, false, "Add indent to JSON response")
cmd.Flags().Bool(flags.FlagLegacy, false, "Use legacy secret store")
return cmd
}

Expand Down Expand Up @@ -101,11 +102,15 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
kb = keys.NewInMemory()
encryptPassword = DefaultKeyPass
} else {
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
return err
if viper.GetBool(flags.FlagLegacy) {
cmd.PrintErrf("IMPORTANT: using deprecated secret store. This will be removed in a future release.")
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
return err
}
} else {
kb = NewKeyringKeybase(inBuf)
}

_, err = kb.Get(name)
if err == nil {
// account exists, ask for user confirmation
Expand Down Expand Up @@ -152,13 +157,15 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
}

// ask for a password when generating a local key
if viper.GetString(FlagPublicKey) == "" && !viper.GetBool(flags.FlagUseLedger) {
if viper.GetString(FlagPublicKey) == "" && !viper.GetBool(flags.FlagUseLedger) && viper.GetBool(flags.FlagLegacy) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

split line

encryptPassword, err = input.GetCheckPassword(
"Enter a passphrase to encrypt your key to disk:",
"Repeat the passphrase:", inBuf)
if err != nil {
return err
}
} else {
encryptPassword = DefaultKeyPass
}
}

Expand Down
7 changes: 5 additions & 2 deletions client/keys/add_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ func Test_runAddCmdLedger(t *testing.T) {
assert.NoError(t, runAddCmd(cmd, []string{"keyname1"}))

// Now check that it has been stored properly
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
kb := NewKeyringKeybase(mockIn)
defer func() {
alessio marked this conversation as resolved.
Show resolved Hide resolved
kb.Delete("keyname1", "", false)
}()

assert.NotNil(t, kb)
key1, err := kb.Get("keyname1")
assert.NoError(t, err)
Expand Down
46 changes: 42 additions & 4 deletions client/keys/add_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package keys

import (
"fmt"
"testing"

"github.com/99designs/keyring"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"

Expand All @@ -13,8 +15,17 @@ import (
)

func Test_runAddCmdBasic(t *testing.T) {

backends := keyring.AvailableBackends()

runningOnServer := false

if len(backends) == 2 && backends[1] == keyring.BackendType("file") {
runningOnServer = true
}
cmd := addKeyCommand()
assert.NotNil(t, cmd)

mockIn, _, _ := tests.ApplyMockIO(cmd)

kbHome, kbCleanUp := tests.NewTestCaseDir(t)
Expand All @@ -24,25 +35,52 @@ func Test_runAddCmdBasic(t *testing.T) {

viper.Set(cli.OutputFlag, OutputFormatText)

mockIn.Reset("test1234\ntest1234\n")
if runningOnServer {
mockIn.Reset("testpass1\ntestpass1\n")

} else {
mockIn.Reset("y\n")
kb := NewKeyringKeybase(mockIn)
defer func() {
kb.Delete("keyname1", "", false)
kb.Delete("keyname2", "", false)
}()
}
err := runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)

viper.Set(cli.OutputFlag, OutputFormatText)

mockIn.Reset("test1234\ntest1234\n")
if runningOnServer {
mockIn.Reset("testpass1\nN\n")

} else {
mockIn.Reset("N\n")
}
err = runAddCmd(cmd, []string{"keyname1"})
fmt.Println(err)
assert.Error(t, err)

viper.Set(cli.OutputFlag, OutputFormatText)

mockIn.Reset("y\ntest1234\ntest1234\n")
if runningOnServer {
mockIn.Reset("testpass1\ny\ntestpass1\n")

} else {
mockIn.Reset("y\n")
}
err = runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)

viper.Set(cli.OutputFlag, OutputFormatJSON)

mockIn.Reset("test1234\ntest1234\n")
if runningOnServer {
mockIn.Reset("testpass1\n")

} else {
mockIn.Reset("y\n")
}
err = runAddCmd(cmd, []string{"keyname2"})
assert.NoError(t, err)

}
Loading