Browse Source

Add codec to keys.Manager, recovery test passes

pull/1782/head
Ethan Frey 8 years ago
parent
commit
53e19e3dfa
7 changed files with 83 additions and 7 deletions
  1. +30
    -7
      keys/cryptostore/holder.go
  2. +38
    -0
      keys/cryptostore/holder_test.go
  3. +1
    -0
      keys/server/keys_test.go
  4. +1
    -0
      keys/tx/multi_test.go
  5. +1
    -0
      keys/tx/one_test.go
  6. +2
    -0
      keys/tx/reader_test.go
  7. +10
    -0
      keys/wordcodec.go

+ 30
- 7
keys/cryptostore/holder.go View File

@ -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


+ 38
- 0
keys/cryptostore/holder_test.go View File

@ -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(


+ 1
- 0
keys/server/keys_test.go View File

@ -91,6 +91,7 @@ func setupServer() http.Handler {
cstore := cryptostore.New(
cryptostore.SecretBox,
memstorage.New(),
keys.MustLoadCodec("english"),
)
// build your http server


+ 1
- 0
keys/tx/multi_test.go View File

@ -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"


+ 1
- 0
keys/tx/one_test.go View File

@ -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"


+ 2
- 0
keys/tx/reader_test.go View File

@ -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"}


+ 10
- 0
keys/wordcodec.go View File

@ -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"


Loading…
Cancel
Save