From 54260853d55178ce90c10f2c8b76327386403d9a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 29 Aug 2017 20:42:50 +0200 Subject: [PATCH 1/2] encoder accepts empty string as unencoded bytes --- keys/cryptostore/encoder.go | 18 ++++++++++----- keys/cryptostore/encoder_test.go | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/keys/cryptostore/encoder.go b/keys/cryptostore/encoder.go index 12792813c..31cbc2e54 100644 --- a/keys/cryptostore/encoder.go +++ b/keys/cryptostore/encoder.go @@ -28,18 +28,24 @@ func secret(passphrase string) []byte { type secretbox struct{} func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + if pass == "" { + return key.Bytes(), nil + } s := secret(pass) cipher := crypto.EncryptSymmetric(key.Bytes(), s) return cipher, nil } -func (e secretbox) Decrypt(data []byte, pass string) (crypto.PrivKey, error) { - s := secret(pass) - private, err := crypto.DecryptSymmetric(data, s) - if err != nil { - return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") +func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { + private := data + if pass != "" { + s := secret(pass) + private, err = crypto.DecryptSymmetric(data, s) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") + } } - key, err := crypto.PrivKeyFromBytes(private) + key, err = crypto.PrivKeyFromBytes(private) return key, errors.Wrap(err, "Invalid Passphrase") } diff --git a/keys/cryptostore/encoder_test.go b/keys/cryptostore/encoder_test.go index 945e19865..f468591f3 100644 --- a/keys/cryptostore/encoder_test.go +++ b/keys/cryptostore/encoder_test.go @@ -60,3 +60,42 @@ func TestSecretBox(t *testing.T) { require.Nil(err) assert.Equal(key, pk) } + +func TestSecretBoxNoPass(t *testing.T) { + assert, require := assert.New(t), require.New(t) + enc := cryptostore.SecretBox + + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + + cases := []struct { + encode string + decode string + valid bool + }{ + {"foo", "foo", true}, + {"foo", "food", false}, + {"", "", true}, + {"", "a", false}, + {"a", "", false}, + } + + for i, tc := range cases { + b, err := enc.Encrypt(key, tc.encode) + require.Nil(err, "%d: %+v", i, err) + assert.NotEmpty(b, "%d", i) + + pk, err := enc.Decrypt(b, tc.decode) + if tc.valid { + require.Nil(err, "%d: %+v", i, err) + assert.Equal(key, pk, "%d", i) + } else { + require.NotNil(err, "%d", i) + } + } + + // now let's make sure raw bytes also work... + b := key.Bytes() + pk, err := enc.Decrypt(b, "") + require.Nil(err, "%+v", err) + assert.Equal(key, pk) +} From e283f580b79a18c535efafa11588b641f0017931 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 29 Aug 2017 20:49:04 +0200 Subject: [PATCH 2/2] Test importing raw private key --- keys/cryptostore/holder_test.go | 39 ++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/keys/cryptostore/holder_test.go b/keys/cryptostore/holder_test.go index c17eef24b..434966f46 100644 --- a/keys/cryptostore/holder_test.go +++ b/keys/cryptostore/holder_test.go @@ -5,6 +5,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + cmn "github.com/tendermint/tmlibs/common" + crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/cryptostore" @@ -148,6 +151,32 @@ func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, assert.Nil(err, "%+v", err) } +// TestImportUnencrypted tests accepting raw priv keys bytes as input +func TestImportUnencrypted(t *testing.T) { + require := require.New(t) + + // make the storage with reasonable defaults + cstore := cryptostore.New( + cryptostore.SecretBox, + memstorage.New(), + keys.MustLoadCodec("english"), + ) + + key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16)) + addr := key.PubKey().Address() + name := "john" + pass := "top-secret" + + // import raw bytes + err := cstore.Import(name, pass, "", key.Bytes()) + require.Nil(err, "%+v", err) + + // make sure the address matches + info, err := cstore.Get(name) + require.Nil(err, "%+v", err) + require.EqualValues(addr, info.Address) +} + // TestAdvancedKeyManagement verifies update, import, export functionality func TestAdvancedKeyManagement(t *testing.T) { assert, require := assert.New(t), require.New(t) @@ -190,16 +219,6 @@ func TestAdvancedKeyManagement(t *testing.T) { // import fails on bad transfer pass err = cstore.Import(n2, p3, p2, exported) assert.NotNil(err) - // import cannot overwrite existing keys - err = cstore.Import(n1, p3, pt, exported) - assert.NotNil(err) - // we can now import under another name - err = cstore.Import(n2, p3, pt, exported) - require.Nil(err, "%+v", err) - - // make sure both passwords are now properly set (not to the transfer pass) - assertPassword(assert, cstore, n1, p2, pt) - assertPassword(assert, cstore, n2, p3, pt) } // TestSeedPhrase verifies restoring from a seed phrase