Re-enable signing tests with cryptostore

This commit is contained in:
Ethan Frey 2017-09-13 13:13:38 +02:00
parent 8c98c4fdf4
commit 34b9309f24
2 changed files with 106 additions and 51 deletions

View File

@ -84,65 +84,69 @@ func TestKeyManagement(t *testing.T) {
// TestSignVerify does some detailed checks on how we sign and validate // TestSignVerify does some detailed checks on how we sign and validate
// signatures // signatures
// func TestSignVerify(t *testing.T) { func TestSignVerify(t *testing.T) {
// assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
// // make the storage with reasonable defaults // make the storage with reasonable defaults
// cstore := cryptostore.New( cstore := cryptostore.New(
// cryptostore.GenSecp256k1, cryptostore.SecretBox,
// cryptostore.SecretBox, memstorage.New(),
// memstorage.New(), keys.MustLoadCodec("english"),
// ) )
algo := crypto.NameSecp256k1
// n1, n2 := "some dude", "a dudette" n1, n2 := "some dude", "a dudette"
// p1, p2 := "1234", "foobar" p1, p2 := "1234", "foobar"
// // create two users and get their info // create two users and get their info
// err := cstore.Create(n1, p1) i1, _, err := cstore.Create(n1, p1, algo)
// require.Nil(err) require.Nil(err)
// i1, err := cstore.Get(n1)
// require.Nil(err)
// err = cstore.Create(n2, p2) i2, _, err := cstore.Create(n2, p2, algo)
// require.Nil(err) require.Nil(err)
// i2, err := cstore.Get(n2)
// require.Nil(err)
// // let's try to sign some messages // let's try to sign some messages
// d1 := []byte("my first message") d1 := []byte("my first message")
// d2 := []byte("some other important info!") d2 := []byte("some other important info!")
// // try signing both data with both keys... // try signing both data with both keys...
// s11, err := cstore.Signature(n1, p1, d1) s11 := keys.NewMockSignable(d1)
// require.Nil(err) err = cstore.Sign(n1, p1, s11)
// s12, err := cstore.Signature(n1, p1, d2) require.Nil(err)
// require.Nil(err) s12 := keys.NewMockSignable(d2)
// s21, err := cstore.Signature(n2, p2, d1) err = cstore.Sign(n1, p1, s12)
// require.Nil(err) require.Nil(err)
// s22, err := cstore.Signature(n2, p2, d2) s21 := keys.NewMockSignable(d1)
// require.Nil(err) err = cstore.Sign(n2, p2, s21)
require.Nil(err)
s22 := keys.NewMockSignable(d2)
err = cstore.Sign(n2, p2, s22)
require.Nil(err)
// // let's try to validate and make sure it only works when everything is proper // let's try to validate and make sure it only works when everything is proper
// keys := [][]byte{i1.PubKey, i2.PubKey} cases := []struct {
// data := [][]byte{d1, d2} key crypto.PubKey
// sigs := [][]byte{s11, s12, s21, s22} data []byte
sig crypto.Signature
valid bool
}{
// proper matches
{i1.PubKey, d1, s11.Signature, true},
// change data, pubkey, or signature leads to fail
{i1.PubKey, d2, s11.Signature, false},
{i2.PubKey, d1, s11.Signature, false},
{i1.PubKey, d1, s21.Signature, false},
// make sure other successes
{i1.PubKey, d2, s12.Signature, true},
{i2.PubKey, d1, s21.Signature, true},
{i2.PubKey, d2, s22.Signature, true},
}
// // loop over keys and data for i, tc := range cases {
// for k := 0; k < 2; k++ { valid := tc.key.VerifyBytes(tc.data, tc.sig)
// for d := 0; d < 2; d++ { assert.Equal(tc.valid, valid, "%d", i)
// // make sure only the proper sig works }
// good := 2*k + d }
// for s := 0; s < 4; s++ {
// err = cstore.Verify(data[d], sigs[s], keys[k])
// if s == good {
// assert.Nil(err, "%+v", err)
// } else {
// assert.NotNil(err)
// }
// }
// }
// }
// }
func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) { func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) {
err := cstore.Update(name, badpass, pass) err := cstore.Update(name, badpass, pass)

View File

@ -1,9 +1,11 @@
package keys package keys
import ( import (
"fmt"
"sort" "sort"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
wire "github.com/tendermint/go-wire"
data "github.com/tendermint/go-wire/data" data "github.com/tendermint/go-wire/data"
) )
@ -72,3 +74,52 @@ type Manager interface {
Update(name, oldpass, newpass string) error Update(name, oldpass, newpass string) error
Delete(name, passphrase string) error Delete(name, passphrase string) error
} }
/**** MockSignable allows us to view data ***/
// MockSignable lets us wrap arbitrary data with a go-crypto signature
type MockSignable struct {
Data []byte
PubKey crypto.PubKey
Signature crypto.Signature
}
var _ Signable = &MockSignable{}
// NewMockSignable sets the data to sign
func NewMockSignable(data []byte) *MockSignable {
return &MockSignable{Data: data}
}
// TxBytes returns the full data with signatures
func (s *MockSignable) TxBytes() ([]byte, error) {
return wire.BinaryBytes(s), nil
}
// SignBytes returns the original data passed into `NewSig`
func (s *MockSignable) SignBytes() []byte {
return s.Data
}
// Sign will add a signature and pubkey.
//
// Depending on the Signable, one may be able to call this multiple times for multisig
// Returns error if called with invalid data or too many times
func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
s.PubKey = pubkey
s.Signature = sig
return nil
}
// Signers will return the public key(s) that signed if the signature
// is valid, or an error if there is any issue with the signature,
// including if there are no signatures
func (s *MockSignable) Signers() ([]crypto.PubKey, error) {
if s.PubKey.Empty() {
return nil, fmt.Errorf("no signers")
}
if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) {
return nil, fmt.Errorf("invalid signature")
}
return []crypto.PubKey{s.PubKey}, nil
}