mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-30 19:51:58 +00:00
Add codec to keys.Manager, recovery test passes
This commit is contained in:
@@ -1,19 +1,26 @@
|
||||
package cryptostore
|
||||
|
||||
import keys "github.com/tendermint/go-crypto/keys"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
keys "github.com/tendermint/go-crypto/keys"
|
||||
)
|
||||
|
||||
// Manager combines encyption and storage implementation to provide
|
||||
// a full-featured key manager
|
||||
type Manager struct {
|
||||
es encryptedStorage
|
||||
es encryptedStorage
|
||||
codec keys.Codec
|
||||
}
|
||||
|
||||
func New(coder Encoder, store keys.Storage) Manager {
|
||||
func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager {
|
||||
return Manager{
|
||||
es: encryptedStorage{
|
||||
coder: coder,
|
||||
store: store,
|
||||
},
|
||||
codec: codec,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +46,29 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error
|
||||
}
|
||||
key := gen.Generate()
|
||||
err = s.es.Put(name, passphrase, key)
|
||||
// TODO
|
||||
return info(name, key), "", err
|
||||
if err != nil {
|
||||
return keys.Info{}, "", err
|
||||
}
|
||||
seed, err := s.codec.BytesToWords(key.Bytes())
|
||||
phrase := strings.Join(seed, " ")
|
||||
return info(name, key), phrase, err
|
||||
}
|
||||
|
||||
func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) {
|
||||
// TODO
|
||||
return keys.Info{}, nil
|
||||
words := strings.Split(strings.TrimSpace(seedphrase), " ")
|
||||
data, err := s.codec.WordsToBytes(words)
|
||||
if err != nil {
|
||||
return keys.Info{}, err
|
||||
}
|
||||
|
||||
key, err := crypto.PrivKeyFromBytes(data)
|
||||
if err != nil {
|
||||
return keys.Info{}, err
|
||||
}
|
||||
|
||||
// d00d, it worked! create the bugger....
|
||||
err = s.es.Put(name, passphrase, key)
|
||||
return info(name, key), err
|
||||
}
|
||||
|
||||
// List loads the keys from the storage and enforces alphabetical order
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-crypto/keys"
|
||||
"github.com/tendermint/go-crypto/keys/cryptostore"
|
||||
"github.com/tendermint/go-crypto/keys/storage/memstorage"
|
||||
)
|
||||
@@ -18,6 +19,7 @@ func TestKeyManagement(t *testing.T) {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
|
||||
algo := crypto.NameEd25519
|
||||
@@ -154,6 +156,7 @@ func TestAdvancedKeyManagement(t *testing.T) {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
|
||||
algo := crypto.NameSecp256k1
|
||||
@@ -199,6 +202,41 @@ func TestAdvancedKeyManagement(t *testing.T) {
|
||||
assertPassword(assert, cstore, n2, p3, pt)
|
||||
}
|
||||
|
||||
// TestSeedPhrase verifies restoring from a seed phrase
|
||||
func TestSeedPhrase(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// make the storage with reasonable defaults
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
|
||||
algo := crypto.NameEd25519
|
||||
n1, n2 := "lost-key", "found-again"
|
||||
p1, p2 := "1234", "foobar"
|
||||
|
||||
// make sure key works with initial password
|
||||
info, seed, err := cstore.Create(n1, p1, algo)
|
||||
require.Nil(err, "%+v", err)
|
||||
assert.Equal(n1, info.Name)
|
||||
assert.NotEmpty(seed)
|
||||
|
||||
// now, let us delete this key
|
||||
err = cstore.Delete(n1, p1)
|
||||
require.Nil(err, "%+v", err)
|
||||
_, err = cstore.Get(n1)
|
||||
require.NotNil(err)
|
||||
|
||||
// let us re-create it from the seed-phrase
|
||||
newInfo, err := cstore.Recover(n2, p2, seed)
|
||||
require.Nil(err, "%+v", err)
|
||||
assert.Equal(n2, newInfo.Name)
|
||||
assert.Equal(info.Address, newInfo.Address)
|
||||
assert.Equal(info.PubKey, newInfo.PubKey)
|
||||
}
|
||||
|
||||
// func ExampleStore() {
|
||||
// // Select the encryption and storage for your cryptostore
|
||||
// cstore := cryptostore.New(
|
||||
|
@@ -91,6 +91,7 @@ func setupServer() http.Handler {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
|
||||
// build your http server
|
||||
|
@@ -18,6 +18,7 @@ func TestMultiSig(t *testing.T) {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
n, p := "foo", "bar"
|
||||
n2, p2 := "other", "thing"
|
||||
|
@@ -18,6 +18,7 @@ func TestOneSig(t *testing.T) {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
n, p := "foo", "bar"
|
||||
n2, p2 := "other", "thing"
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-crypto/keys"
|
||||
"github.com/tendermint/go-crypto/keys/cryptostore"
|
||||
"github.com/tendermint/go-crypto/keys/storage/memstorage"
|
||||
data "github.com/tendermint/go-wire/data"
|
||||
@@ -18,6 +19,7 @@ func TestReader(t *testing.T) {
|
||||
cstore := cryptostore.New(
|
||||
cryptostore.SecretBox,
|
||||
memstorage.New(),
|
||||
keys.MustLoadCodec("english"),
|
||||
)
|
||||
type sigs struct{ name, pass string }
|
||||
u := sigs{"alice", "1234"}
|
||||
|
@@ -40,6 +40,7 @@ func NewCodec(words []string) (codec *WordCodec, err error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// LoadCodec loads a pre-compiled language file
|
||||
func LoadCodec(bank string) (codec *WordCodec, err error) {
|
||||
words, err := loadBank(bank)
|
||||
if err != nil {
|
||||
@@ -48,6 +49,15 @@ func LoadCodec(bank string) (codec *WordCodec, err error) {
|
||||
return NewCodec(words)
|
||||
}
|
||||
|
||||
// MustLoadCodec panics if word bank is missing, only for tests
|
||||
func MustLoadCodec(bank string) *WordCodec {
|
||||
codec, err := LoadCodec(bank)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return codec
|
||||
}
|
||||
|
||||
// loadBank opens a wordlist file and returns all words inside
|
||||
func loadBank(bank string) ([]string, error) {
|
||||
filename := "keys/wordlist/" + bank + ".txt"
|
||||
|
Reference in New Issue
Block a user