Documentation

Overview

Package sigs provides basic authentication middleware to verify the signatures on the transaction, and maintain nonces for replay protection.

Index

Constants

View Source
const BucketName = "sigs"

BucketName is where we store the accounts

Variables

View Source
var (
	ErrInvalidLengthCodec = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowCodec   = fmt.Errorf("proto: integer overflow")
)
View Source
var (
	ErrInvalidSequence = errors.Register(120, "invalid sequence number")
)
View Source
var SignCodeV1 = []byte{0, 0xCA, 0xFE, 0}

SignCodeV1 is the current way to prefix the bytes we use to build a signature

Functions

func BuildSignBytes

func BuildSignBytes(signBytes []byte, chainID string, seq int64) ([]byte, error)

BuildSignBytes combines all info on the actual tx before signing

As specified in https://github.com/iov-one/weave/issues/70, we use the following format:

version | len(chainID) | chainID | nonce | signBytes 4bytes | uint8 | ascii string | int64 (bigendian) | serialized transaction

This is then prehashed with sha512 before fed into the public key signing/verification step

func BuildSignBytesTx

func BuildSignBytesTx(tx SignedTx, chainID string, seq int64) ([]byte, error)

BuildSignBytesTx calculates the sign bytes given a tx

func NewUser

func NewUser(pubkey *crypto.PublicKey) orm.Object

NewUser constructs an object from an address and pubkey

func NextNonce

func NextNonce(db weave.ReadOnlyKVStore, signer weave.Address) (int64, error)

NextNonce returns the next numeric nonce value that should be used during a transaction signing. Any address can contain a nonce. In practice you always want to acquire a nonce for the signer. You can get the signers address by calling

address := <crypto.Signer>.PublicKey().Address()

func RegisterQuery

func RegisterQuery(qr weave.QueryRouter)

RegisterQuery will register this bucket as "/auth"

func RegisterRoutes

func RegisterRoutes(r weave.Registry, auth x.Authenticator)

func VerifySignature

func VerifySignature(db weave.KVStore, sig *StdSignature,
	signBytes []byte, chainID string) (weave.Condition, error)

VerifySignature checks one signature against signbytes, check chain and updates state in the store

func VerifyTxSignatures

func VerifyTxSignatures(store weave.KVStore, tx SignedTx,
	chainID string) ([]weave.Condition, error)

VerifyTxSignatures checks all the signatures on the tx, which must have at least one.

returns list of signer addresses (possibly empty), or error if any signature is invalid

Types

type Authenticate

type Authenticate struct{}

Authenticate implements x.Authenticator and provides authentication based on public-key signatures.

func (Authenticate) GetConditions

func (a Authenticate) GetConditions(ctx weave.Context) []weave.Condition

GetConditions returns who signed the current Context. May be empty

func (Authenticate) HasAddress

func (a Authenticate) HasAddress(ctx weave.Context, addr weave.Address) bool

HasAddress returns true if the given address had signed in the current Context.

type Bucket

type Bucket struct {
	orm.Bucket
}

Bucket extends orm.Bucket with GetOrCreate

func NewBucket

func NewBucket() Bucket

NewBucket creates the proper bucket for this extension

func (Bucket) GetOrCreate

func (b Bucket) GetOrCreate(db weave.KVStore, pubkey *crypto.PublicKey) (orm.Object, error)

GetOrCreate initializes a UserData if none exist for that key

type BumpSequenceMsg

type BumpSequenceMsg struct {
	Metadata *weave.Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
	// Increment represents the value by which a sequence value will be
	// increased. Minumum value is one and maxium value must not be greater than
	// 1000.
	// Each transaction increments the sequence by one. This value represents the
	// total increment value, including the default increment.
	Increment uint32 `protobuf:"varint,2,opt,name=increment,proto3" json:"increment,omitempty"`
	// User is the address of a user that sequence is to be incremented for.
	User github_com_iov_one_weave.Address `protobuf:"bytes,3,opt,name=user,proto3,casttype=github.com/iov-one/weave.Address" json:"user,omitempty"`
}

BumpSequenceMsg increments a sequence counter by given amount for a user.

func (*BumpSequenceMsg) Descriptor

func (*BumpSequenceMsg) Descriptor() ([]byte, []int)

func (*BumpSequenceMsg) GetIncrement

func (m *BumpSequenceMsg) GetIncrement() uint32

func (*BumpSequenceMsg) GetMetadata

func (m *BumpSequenceMsg) GetMetadata() *weave.Metadata

func (*BumpSequenceMsg) GetUser

func (*BumpSequenceMsg) Marshal

func (m *BumpSequenceMsg) Marshal() (dAtA []byte, err error)

func (*BumpSequenceMsg) MarshalTo

func (m *BumpSequenceMsg) MarshalTo(dAtA []byte) (int, error)

func (BumpSequenceMsg) Path

func (BumpSequenceMsg) Path() string

func (*BumpSequenceMsg) ProtoMessage

func (*BumpSequenceMsg) ProtoMessage()

func (*BumpSequenceMsg) Reset

func (m *BumpSequenceMsg) Reset()

func (*BumpSequenceMsg) Size

func (m *BumpSequenceMsg) Size() (n int)

func (*BumpSequenceMsg) String

func (m *BumpSequenceMsg) String() string

func (*BumpSequenceMsg) Unmarshal

func (m *BumpSequenceMsg) Unmarshal(dAtA []byte) error

func (*BumpSequenceMsg) Validate

func (msg *BumpSequenceMsg) Validate() error

func (*BumpSequenceMsg) XXX_DiscardUnknown

func (m *BumpSequenceMsg) XXX_DiscardUnknown()

func (*BumpSequenceMsg) XXX_Marshal

func (m *BumpSequenceMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*BumpSequenceMsg) XXX_Merge

func (m *BumpSequenceMsg) XXX_Merge(src proto.Message)

func (*BumpSequenceMsg) XXX_Size

func (m *BumpSequenceMsg) XXX_Size() int

func (*BumpSequenceMsg) XXX_Unmarshal

func (m *BumpSequenceMsg) XXX_Unmarshal(b []byte) error

type Decorator

type Decorator struct {
	// contains filtered or unexported fields
}

Decorator verifies the signatures and adds them to the context

func NewDecorator

func NewDecorator() Decorator

NewDecorator returns a default authentication decorator, which appends the chainID before checking the signature, and requires at least one signature to be present

func (Decorator) AllowMissingSigs

func (d Decorator) AllowMissingSigs() Decorator

AllowMissingSigs allows us to pass along items with no signatures

func (Decorator) Check

func (d Decorator) Check(ctx weave.Context, store weave.KVStore, tx weave.Tx, next weave.Checker) (*weave.CheckResult, error)

Check verifies signatures before calling down the stack.

func (Decorator) Deliver

func (d Decorator) Deliver(ctx weave.Context, store weave.KVStore, tx weave.Tx, next weave.Deliverer) (*weave.DeliverResult, error)

Deliver verifies signatures before calling down the stack.

type SignedTx

type SignedTx interface {
	// GetSignBytes returns the canonical byte representation of the Msg.
	// Equivalent to weave.MustMarshal(tx.GetMsg()) if Msg has a deterministic
	// serialization.
	//
	// Helpful to store original, unparsed bytes here, just in case.
	GetSignBytes() ([]byte, error)

	// Signatures returns the signature of signers who signed the Msg.
	GetSignatures() []*StdSignature
}

SignedTx represents a transaction that contains signatures, which can be verified by the auth.Decorator

type StdSignature

type StdSignature struct {
	Sequence int64             `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"`
	Pubkey   *crypto.PublicKey `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty"`
	// Removed Address, Pubkey is more powerful
	Signature *crypto.Signature `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
}

StdSignature represents the signature, the identity of the signer (the Pubkey), and a sequence number to prevent replay attacks.

A given signer must submit transactions with the sequence number increasing by 1 each time (starting at 0)

func SignTx

func SignTx(signer crypto.Signer, tx SignedTx, chainID string,
	seq int64) (*StdSignature, error)

SignTx creates a signature for the given tx

func (*StdSignature) Descriptor

func (*StdSignature) Descriptor() ([]byte, []int)

func (*StdSignature) GetPubkey

func (m *StdSignature) GetPubkey() *crypto.PublicKey

func (*StdSignature) GetSequence

func (m *StdSignature) GetSequence() int64

func (*StdSignature) GetSignature

func (m *StdSignature) GetSignature() *crypto.Signature

func (*StdSignature) Marshal

func (m *StdSignature) Marshal() (dAtA []byte, err error)

func (*StdSignature) MarshalTo

func (m *StdSignature) MarshalTo(dAtA []byte) (int, error)

func (*StdSignature) ProtoMessage

func (*StdSignature) ProtoMessage()

func (*StdSignature) Reset

func (m *StdSignature) Reset()

func (*StdSignature) Size

func (m *StdSignature) Size() (n int)

func (*StdSignature) String

func (m *StdSignature) String() string

func (*StdSignature) Unmarshal

func (m *StdSignature) Unmarshal(dAtA []byte) error

func (*StdSignature) Validate

func (s *StdSignature) Validate() error

Validate ensures the StdSignature meets basic standards

func (*StdSignature) XXX_DiscardUnknown

func (m *StdSignature) XXX_DiscardUnknown()

func (*StdSignature) XXX_Marshal

func (m *StdSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*StdSignature) XXX_Merge

func (m *StdSignature) XXX_Merge(src proto.Message)

func (*StdSignature) XXX_Size

func (m *StdSignature) XXX_Size() int

func (*StdSignature) XXX_Unmarshal

func (m *StdSignature) XXX_Unmarshal(b []byte) error

type UserData

type UserData struct {
	Metadata *weave.Metadata   `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
	Pubkey   *crypto.PublicKey `protobuf:"bytes,2,opt,name=pubkey,proto3" json:"pubkey,omitempty"`
	Sequence int64             `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
}

UserData just stores the data and is used for serialization. Key is the Address (PubKey.Permission().Address())

Note: This should not be created from outside the module, User is the entry point you want

func AsUser

func AsUser(obj orm.Object) *UserData

AsUser will safely type-cast any value from Bucket to a UserData

func (*UserData) CheckAndIncrementSequence

func (u *UserData) CheckAndIncrementSequence(expected int64) error

CheckAndIncrementSequence implements check and increment operation. If current sequence value is the same as given expected value then it is incremented. Otherwise an error is returned. Before incrementing the sequence, this function is testing for a value overflow.

func (*UserData) Descriptor

func (*UserData) Descriptor() ([]byte, []int)

func (*UserData) GetMetadata

func (m *UserData) GetMetadata() *weave.Metadata

func (*UserData) GetPubkey

func (m *UserData) GetPubkey() *crypto.PublicKey

func (*UserData) GetSequence

func (m *UserData) GetSequence() int64

func (*UserData) Marshal

func (m *UserData) Marshal() (dAtA []byte, err error)

func (*UserData) MarshalTo

func (m *UserData) MarshalTo(dAtA []byte) (int, error)

func (*UserData) ProtoMessage

func (*UserData) ProtoMessage()

func (*UserData) Reset

func (m *UserData) Reset()

func (*UserData) SetPubkey

func (u *UserData) SetPubkey(pubkey *crypto.PublicKey)

SetPubkey will try to set the Pubkey or panic on an illegal operation. It is illegal to reset an already set key Otherwise, we don't control (although we could verify the hash, we leave that to the controller)

func (*UserData) Size

func (m *UserData) Size() (n int)

func (*UserData) String

func (m *UserData) String() string

func (*UserData) Unmarshal

func (m *UserData) Unmarshal(dAtA []byte) error

func (*UserData) Validate

func (u *UserData) Validate() error

func (*UserData) XXX_DiscardUnknown

func (m *UserData) XXX_DiscardUnknown()

func (*UserData) XXX_Marshal

func (m *UserData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*UserData) XXX_Merge

func (m *UserData) XXX_Merge(src proto.Message)

func (*UserData) XXX_Size

func (m *UserData) XXX_Size() int

func (*UserData) XXX_Unmarshal

func (m *UserData) XXX_Unmarshal(b []byte) error