Bare auth

This commit is contained in:
Jae Kwon 2017-11-25 01:36:45 -08:00
parent 83b43f3378
commit fdc7834dae
4 changed files with 29 additions and 226 deletions

View File

@ -1,37 +1,23 @@
package auth
import (
crypto "github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/errors"
)
//nolint
const (
NameSigs = "sigs"
)
type CheckSignatures struct{}
// Signatures parses out go-crypto signatures and adds permissions to the
// context for use inside the application
type Signatures struct{}
var _ sdk.Decorator = Signatures{}
// SigPerm takes the binary address from PubKey.Address and makes it an Actor
func SigPerm(addr []byte) sdk.Actor {
return sdk.NewActor(NameSigs, addr)
}
var _ sdk.Decorator = CheckSignatures{}
// CheckTx verifies the signatures are correct - fulfills Middlware interface
func (Signatures) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Checker) (res sdk.CheckResult, err error) {
sigs, err := getSigners(tx)
if err != nil {
return res, err
}
ctx2 := addSigners(ctx, sigs)
// Check that signatures match
// TODO
// Add info to context
// TODO
return next.CheckTx(ctx2, store, tx)
}
@ -39,28 +25,11 @@ func (Signatures) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
func (Signatures) DeliverTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Deliverer) (res sdk.DeliverResult, err error) {
sigs, err := getSigners(tx)
if err != nil {
return res, err
}
ctx2 := addSigners(ctx, sigs)
// Check that signatures match
// TODO
// Add info to context
// TODO
return next.DeliverTx(ctx2, store, tx)
}
func addSigners(ctx sdk.Context, sigs []crypto.PubKey) sdk.Context {
perms := make([]sdk.Actor, len(sigs))
for i, s := range sigs {
perms[i] = SigPerm(s.Address())
}
// add the signers to the context and continue
return ctx.WithPermissions(perms...)
}
func getSigners(tx interface{}) ([]crypto.PubKey, error) {
stx, ok := tx.(Signable)
if !ok {
return nil, errors.ErrUnauthorized()
}
sig, err := stx.Signers()
return sig, err
}

View File

@ -1,84 +0,0 @@
package auth
import (
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-crypto/keys"
wire "github.com/tendermint/go-wire"
sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/util"
)
type oneSig struct {
// Data is the payload
Data util.RawTx
// NamedSig holds credentials and exposes Sign
*NamedSig
}
var _ Signable = oneSig{}
var _ sdk.Msg = oneSig{}
var _ keys.Signable = oneSig{}
func (o oneSig) SignBytes() []byte {
return wire.BinaryBytes(o.Data)
}
func (o oneSig) TxBytes() ([]byte, error) {
// if o.NamedSig.Empty() {
// return nil, errors.ErrMissingSignature()
// }
return wire.BinaryBytes(o), nil
}
func (o oneSig) Signers() ([]crypto.PubKey, error) {
return o.NamedSig.Signers(o.SignBytes())
}
func (o oneSig) GetTx() interface{} {
return o.Data
}
func newSingle(data []byte) oneSig {
return oneSig{
Data: util.NewRawTx(data),
NamedSig: NewSig(),
}
}
type multiSig struct {
// Data is the payload
Data util.RawTx
// NamedSig holds credentials and exposes Sign
*NamedSigs
}
var _ Signable = oneSig{}
var _ sdk.Msg = oneSig{}
var _ keys.Signable = oneSig{}
func (m multiSig) SignBytes() []byte {
return wire.BinaryBytes(m.Data)
}
func (m multiSig) TxBytes() ([]byte, error) {
// if m.NamedSigs.Empty() {
// return nil, errors.ErrMissingSignature()
// }
return wire.BinaryBytes(m), nil
}
func (m multiSig) Signers() ([]crypto.PubKey, error) {
return m.NamedSigs.Signers(m.SignBytes())
}
func (m multiSig) GetTx() interface{} {
return m.Data
}
func newMulti(data []byte) multiSig {
return multiSig{
Data: util.NewRawTx(data),
NamedSigs: NewMultiSig(),
}
}

View File

@ -1,97 +0,0 @@
package auth
import (
"strconv"
"testing"
"github.com/stretchr/testify/assert"
crypto "github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/state"
"github.com/cosmos/cosmos-sdk/util"
)
func TestSignatureChecks(t *testing.T) {
assert := assert.New(t)
// generic args
ctx := util.MockContext("test-chain", 100)
store := state.NewMemKVStore()
raw := []byte{1, 2, 3, 4}
// let's make some keys....
priv1 := crypto.GenPrivKeyEd25519().Wrap()
actor1 := SigPerm(priv1.PubKey().Address())
priv2 := crypto.GenPrivKeySecp256k1().Wrap()
actor2 := SigPerm(priv2.PubKey().Address())
// test cases to make sure signature checks are solid
cases := []struct {
useMultiSig bool
keys []crypto.PrivKey
check sdk.Actor
valid bool
}{
// test with single sigs
{false, []crypto.PrivKey{priv1}, actor1, true},
{false, []crypto.PrivKey{priv1}, actor2, false},
{false, []crypto.PrivKey{priv2}, actor2, true},
{false, []crypto.PrivKey{}, actor2, false},
// same with multi sigs
{true, []crypto.PrivKey{priv1}, actor1, true},
{true, []crypto.PrivKey{priv1}, actor2, false},
{true, []crypto.PrivKey{priv2}, actor2, true},
{true, []crypto.PrivKey{}, actor2, false},
// make sure both match on a multisig
{true, []crypto.PrivKey{priv1, priv2}, actor1, true},
{true, []crypto.PrivKey{priv1, priv2}, actor2, true},
}
for i, tc := range cases {
idx := strconv.Itoa(i)
// make the stack check for the given permission
app := sdk.ChainDecorators(
Signatures{},
util.CheckDecorator{Required: tc.check},
).WithHandler(
util.OKHandler{},
)
var tx interface{}
// this does the signing as needed
if tc.useMultiSig {
mtx := newMulti(raw)
for _, k := range tc.keys {
err := Sign(mtx, k)
assert.Nil(err, "%d: %+v", i, err)
}
tx = mtx
} else {
otx := newSingle(raw)
for _, k := range tc.keys {
err := Sign(otx, k)
assert.Nil(err, "%d: %+v", i, err)
}
tx = otx
}
_, err := app.CheckTx(ctx, store, tx)
if tc.valid {
assert.Nil(err, "%d: %+v", i, err)
} else {
assert.NotNil(err, idx)
}
_, err = app.DeliverTx(ctx, store, tx)
if tc.valid {
assert.Nil(err, "%d: %+v", i, err)
} else {
assert.NotNil(err, idx)
}
}
}

15
x/auth/types.go Normal file
View File

@ -0,0 +1,15 @@
package auth
import crypto "github.com/tendermint/go-crypto"
type Account interface {
Get(key interface{}) (value interface{})
Address() []byte
PubKey() crypto.PubKey
}
type AccountStore interface {
GetAccount(addr []byte) Account
SetAccount(acc Account)
}