diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index 2d7e79710f5b..cabdae9c19be 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -2,6 +2,8 @@ package keys import ( "fmt" + "io" + "os" "reflect" "strings" @@ -68,23 +70,27 @@ var ( // // NOTE: dbKeybase will be deprecated in favor of keyringKeybase. type dbKeybase struct { - base baseKeybase - db dbm.DB + base baseKeybase + db dbm.DB + input io.Reader } // newDBKeybase creates a new dbKeybase instance using the provided DB for // reading and writing keys. -func newDBKeybase(db dbm.DB, opts ...KeybaseOption) Keybase { +func newDBKeybase(db dbm.DB, input io.Reader, opts ...KeybaseOption) Keybase { return dbKeybase{ - base: newBaseKeybase(opts...), - db: db, + base: newBaseKeybase(opts...), + db: db, + input: input, } } // NewInMemory creates a transient keybase on top of in-memory storage // instance useful for testing purposes and on-the-fly key generation. // Keybase options can be applied when generating this new Keybase. -func NewInMemory(opts ...KeybaseOption) Keybase { return newDBKeybase(dbm.NewMemDB(), opts...) } +func NewInMemory(opts ...KeybaseOption) Keybase { + return newDBKeybase(dbm.NewMemDB(), os.Stdin, opts...) +} // CreateMnemonic generates a new key and persists it to storage, encrypted // using the provided password. It returns the generated mnemonic and the key Info. @@ -215,7 +221,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t return SignWithLedger(info, msg) case offlineInfo, multiInfo: - return kb.base.DecodeSignature(info, msg) + return nil, info.GetPubKey(), errors.New("cannot sign with offline keys") } sig, err = priv.Sign(msg) diff --git a/crypto/keys/keybase_base.go b/crypto/keys/keybase_base.go index 47c7e60d729a..2947949e273b 100644 --- a/crypto/keys/keybase_base.go +++ b/crypto/keys/keybase_base.go @@ -1,10 +1,6 @@ package keys import ( - "bufio" - "fmt" - "os" - "github.com/cosmos/go-bip39" "github.com/pkg/errors" tmcrypto "github.com/tendermint/tendermint/crypto" @@ -104,33 +100,6 @@ func SecpPrivKeyGen(bz []byte) tmcrypto.PrivKey { return secp256k1.PrivKeySecp256k1(bzArr) } -// DecodeSignature decodes a an length-prefixed binary signature from standard input -// and return it as a byte slice. -func (kb baseKeybase) DecodeSignature(info Info, msg []byte) (sig []byte, pub tmcrypto.PubKey, err error) { - _, err = fmt.Fprintf(os.Stderr, "Message to sign:\n\n%s\n", msg) - if err != nil { - return nil, nil, err - } - - buf := bufio.NewReader(os.Stdin) - _, err = fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n") - if err != nil { - return nil, nil, err - } - - // will block until user inputs the signature - signed, err := buf.ReadString('\n') - if err != nil { - return nil, nil, err - } - - if err := CryptoCdc.UnmarshalBinaryLengthPrefixed([]byte(signed), sig); err != nil { - return nil, nil, errors.Wrap(err, "failed to decode signature") - } - - return sig, info.GetPubKey(), nil -} - // CreateAccount creates an account Info object. func (kb baseKeybase) CreateAccount( keyWriter keyWriter, name, mnemonic, bip39Passphrase, encryptPasswd, hdPath string, algo SigningAlgo, diff --git a/crypto/keys/keyring.go b/crypto/keys/keyring.go index 726b44e781f2..05cec87c4409 100644 --- a/crypto/keys/keyring.go +++ b/crypto/keys/keyring.go @@ -41,16 +41,18 @@ var _ Keybase = keyringKeybase{} // keyringKeybase implements the Keybase interface by using the Keyring library // for account key persistence. type keyringKeybase struct { - base baseKeybase - db keyring.Keyring + base baseKeybase + db keyring.Keyring + input io.Reader } var maxPassphraseEntryAttempts = 3 -func newKeyringKeybase(db keyring.Keyring, opts ...KeybaseOption) Keybase { +func newKeyringKeybase(db keyring.Keyring, input io.Reader, opts ...KeybaseOption) Keybase { return keyringKeybase{ - db: db, - base: newBaseKeybase(opts...), + db: db, + base: newBaseKeybase(opts...), + input: input, } } @@ -82,7 +84,7 @@ func NewKeyring( return nil, err } - return newKeyringKeybase(db, opts...), nil + return newKeyringKeybase(db, userInput, opts...), nil } // CreateMnemonic generates a new key and persists it to storage, encrypted @@ -219,7 +221,7 @@ func (kb keyringKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, return SignWithLedger(info, msg) case offlineInfo, multiInfo: - return kb.base.DecodeSignature(info, msg) + return nil, info.GetPubKey(), errors.New("cannot sign with offline keys") } sig, err = priv.Sign(msg) diff --git a/crypto/keys/keyring_test.go b/crypto/keys/keyring_test.go index afa726321de0..be283a2fe0c8 100644 --- a/crypto/keys/keyring_test.go +++ b/crypto/keys/keyring_test.go @@ -138,7 +138,8 @@ func TestLazySignVerifyKeyRingWithLedger(t *testing.T) { func TestLazySignVerifyKeyRing(t *testing.T) { dir, cleanup := tests.NewTestCaseDir(t) t.Cleanup(cleanup) - kb, err := NewKeyring("keybasename", "test", dir, nil) + buf := bytes.NewBufferString("") + kb, err := NewKeyring("keybasename", "test", dir, buf) require.NoError(t, err) algo := Secp256k1 diff --git a/crypto/keys/lazy_keybase.go b/crypto/keys/lazy_keybase.go index 3ee7e2c16b2b..a0bc90c3828d 100644 --- a/crypto/keys/lazy_keybase.go +++ b/crypto/keys/lazy_keybase.go @@ -2,6 +2,7 @@ package keys import ( "fmt" + "os" "github.com/tendermint/tendermint/crypto" tmos "github.com/tendermint/tendermint/libs/os" @@ -34,7 +35,7 @@ func (lkb lazyKeybase) List() ([]Info, error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).List() + return newDBKeybase(db, os.Stdin, lkb.options...).List() } func (lkb lazyKeybase) Get(name string) (Info, error) { @@ -44,7 +45,7 @@ func (lkb lazyKeybase) Get(name string) (Info, error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).Get(name) + return newDBKeybase(db, os.Stdin, lkb.options...).Get(name) } func (lkb lazyKeybase) GetByAddress(address sdk.AccAddress) (Info, error) { @@ -54,7 +55,7 @@ func (lkb lazyKeybase) GetByAddress(address sdk.AccAddress) (Info, error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).GetByAddress(address) + return newDBKeybase(db, os.Stdin, lkb.options...).GetByAddress(address) } func (lkb lazyKeybase) Delete(name, passphrase string, skipPass bool) error { @@ -64,7 +65,7 @@ func (lkb lazyKeybase) Delete(name, passphrase string, skipPass bool) error { } defer db.Close() - return newDBKeybase(db, lkb.options...).Delete(name, passphrase, skipPass) + return newDBKeybase(db, os.Stdin, lkb.options...).Delete(name, passphrase, skipPass) } func (lkb lazyKeybase) Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) { @@ -74,7 +75,7 @@ func (lkb lazyKeybase) Sign(name, passphrase string, msg []byte) ([]byte, crypto } defer db.Close() - return newDBKeybase(db, lkb.options...).Sign(name, passphrase, msg) + return newDBKeybase(db, os.Stdin, lkb.options...).Sign(name, passphrase, msg) } func (lkb lazyKeybase) CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) { @@ -84,7 +85,7 @@ func (lkb lazyKeybase) CreateMnemonic(name string, language Language, passwd str } defer db.Close() - return newDBKeybase(db, lkb.options...).CreateMnemonic(name, language, passwd, algo) + return newDBKeybase(db, os.Stdin, lkb.options...).CreateMnemonic(name, language, passwd, algo) } func (lkb lazyKeybase) CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath string, algo SigningAlgo) (Info, error) { @@ -94,8 +95,7 @@ func (lkb lazyKeybase) CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, } defer db.Close() - return newDBKeybase(db, - lkb.options...).CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath, algo) + return newDBKeybase(db, os.Stdin, lkb.options...).CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath, algo) } func (lkb lazyKeybase) CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error) { @@ -105,7 +105,7 @@ func (lkb lazyKeybase) CreateLedger(name string, algo SigningAlgo, hrp string, a } defer db.Close() - return newDBKeybase(db, lkb.options...).CreateLedger(name, algo, hrp, account, index) + return newDBKeybase(db, os.Stdin, lkb.options...).CreateLedger(name, algo, hrp, account, index) } func (lkb lazyKeybase) CreateOffline(name string, pubkey crypto.PubKey, algo SigningAlgo) (info Info, err error) { @@ -115,7 +115,7 @@ func (lkb lazyKeybase) CreateOffline(name string, pubkey crypto.PubKey, algo Sig } defer db.Close() - return newDBKeybase(db, lkb.options...).CreateOffline(name, pubkey, algo) + return newDBKeybase(db, os.Stdin, lkb.options...).CreateOffline(name, pubkey, algo) } func (lkb lazyKeybase) CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error) { @@ -125,7 +125,7 @@ func (lkb lazyKeybase) CreateMulti(name string, pubkey crypto.PubKey) (info Info } defer db.Close() - return newDBKeybase(db, lkb.options...).CreateMulti(name, pubkey) + return newDBKeybase(db, os.Stdin, lkb.options...).CreateMulti(name, pubkey) } func (lkb lazyKeybase) Update(name, oldpass string, getNewpass func() (string, error)) error { @@ -135,7 +135,7 @@ func (lkb lazyKeybase) Update(name, oldpass string, getNewpass func() (string, e } defer db.Close() - return newDBKeybase(db, lkb.options...).Update(name, oldpass, getNewpass) + return newDBKeybase(db, os.Stdin, lkb.options...).Update(name, oldpass, getNewpass) } func (lkb lazyKeybase) Import(name string, armor string) (err error) { @@ -145,7 +145,7 @@ func (lkb lazyKeybase) Import(name string, armor string) (err error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).Import(name, armor) + return newDBKeybase(db, os.Stdin, lkb.options...).Import(name, armor) } func (lkb lazyKeybase) ImportPrivKey(name string, armor string, passphrase string) error { @@ -155,7 +155,7 @@ func (lkb lazyKeybase) ImportPrivKey(name string, armor string, passphrase strin } defer db.Close() - return newDBKeybase(db, lkb.options...).ImportPrivKey(name, armor, passphrase) + return newDBKeybase(db, os.Stdin, lkb.options...).ImportPrivKey(name, armor, passphrase) } func (lkb lazyKeybase) ImportPubKey(name string, armor string) (err error) { @@ -165,7 +165,7 @@ func (lkb lazyKeybase) ImportPubKey(name string, armor string) (err error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).ImportPubKey(name, armor) + return newDBKeybase(db, os.Stdin, lkb.options...).ImportPubKey(name, armor) } func (lkb lazyKeybase) Export(name string) (armor string, err error) { @@ -175,7 +175,7 @@ func (lkb lazyKeybase) Export(name string) (armor string, err error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).Export(name) + return newDBKeybase(db, os.Stdin, lkb.options...).Export(name) } func (lkb lazyKeybase) ExportPubKey(name string) (armor string, err error) { @@ -185,7 +185,7 @@ func (lkb lazyKeybase) ExportPubKey(name string) (armor string, err error) { } defer db.Close() - return newDBKeybase(db, lkb.options...).ExportPubKey(name) + return newDBKeybase(db, os.Stdin, lkb.options...).ExportPubKey(name) } func (lkb lazyKeybase) ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error) { @@ -195,7 +195,7 @@ func (lkb lazyKeybase) ExportPrivateKeyObject(name string, passphrase string) (c } defer db.Close() - return newDBKeybase(db, lkb.options...).ExportPrivateKeyObject(name, passphrase) + return newDBKeybase(db, os.Stdin, lkb.options...).ExportPrivateKeyObject(name, passphrase) } func (lkb lazyKeybase) ExportPrivKey(name string, decryptPassphrase string, @@ -207,7 +207,7 @@ func (lkb lazyKeybase) ExportPrivKey(name string, decryptPassphrase string, } defer db.Close() - return newDBKeybase(db, lkb.options...).ExportPrivKey(name, decryptPassphrase, encryptPassphrase) + return newDBKeybase(db, os.Stdin, lkb.options...).ExportPrivKey(name, decryptPassphrase, encryptPassphrase) } // SupportedAlgos returns a list of supported signing algorithms.