From 54260853d55178ce90c10f2c8b76327386403d9a Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 29 Aug 2017 20:42:50 +0200 Subject: [PATCH] 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) +}