From 0285454c34b0b3003bc8ede3e304b843ad949be8 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sun, 6 Jun 2021 11:06:17 +0200 Subject: added state manager with tests --- state/state_manager.go | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) (limited to 'state/state_manager.go') diff --git a/state/state_manager.go b/state/state_manager.go index 21c3eda..3199e61 100644 --- a/state/state_manager.go +++ b/state/state_manager.go @@ -3,7 +3,6 @@ package stfe import ( "context" "crypto" - "crypto/ed25519" "fmt" "reflect" "sync" @@ -20,14 +19,14 @@ type StateManager interface { Latest(context.Context) (*types.SignedTreeHead, error) ToSign(context.Context) (*types.SignedTreeHead, error) Cosigned(context.Context) (*types.SignedTreeHead, error) - AddCosignature(context.Context, ed25519.PublicKey, *[types.SignatureSize]byte) error + AddCosignature(context.Context, *[types.VerificationKeySize]byte, *[types.SignatureSize]byte) error Run(context.Context) } // StateManagerSingle implements the StateManager interface. It is assumed that // the log server is running on a single-instance machine. So, no coordination. type StateManagerSingle struct { - client *trillian.Client + client trillian.Client signer crypto.Signer interval time.Duration deadline time.Duration @@ -43,7 +42,7 @@ type StateManagerSingle struct { cosignature map[[types.HashSize]byte]*types.SigIdent } -func NewStateManagerSingle(client *trillian.Client, signer crypto.Signer, interval, deadline time.Duration) (*StateManagerSingle, error) { +func NewStateManagerSingle(client trillian.Client, signer crypto.Signer, interval, deadline time.Duration) (*StateManagerSingle, error) { sm := &StateManagerSingle{ client: client, signer: signer, @@ -59,7 +58,9 @@ func NewStateManagerSingle(client *trillian.Client, signer crypto.Signer, interv sm.cosigned = *sth sm.tosign = *sth - sm.cosignature = make(map[[types.HashSize]byte]*types.SigIdent) + sm.cosignature = map[[types.HashSize]byte]*types.SigIdent{ + *sth.SigIdent[0].KeyHash: sth.SigIdent[0], // log signature + } return sm, nil } @@ -83,7 +84,7 @@ func (sm *StateManagerSingle) Latest(ctx context.Context) (*types.SignedTreeHead if err != nil { return nil, fmt.Errorf("LatestTreeHead: %v", err) } - sth, err := sign(sm.signer, th) + sth, err := th.Sign(sm.signer) if err != nil { return nil, fmt.Errorf("sign: %v", err) } @@ -102,12 +103,12 @@ func (sm *StateManagerSingle) Cosigned(_ context.Context) (*types.SignedTreeHead return &sm.cosigned, nil } -func (sm *StateManagerSingle) AddCosignature(_ context.Context, vk ed25519.PublicKey, sig *[types.SignatureSize]byte) error { +func (sm *StateManagerSingle) AddCosignature(_ context.Context, vk *[types.VerificationKeySize]byte, sig *[types.SignatureSize]byte) error { sm.Lock() defer sm.Unlock() - if msg := sm.tosign.TreeHead.Marshal(); !ed25519.Verify(vk, msg, sig[:]) { - return fmt.Errorf("invalid signature for tree head with timestamp: %d", sm.tosign.Timestamp) + if err := sm.tosign.TreeHead.Verify(vk, sig); err != nil { + return fmt.Errorf("Verify: %v", err) } witness := types.Hash(vk[:]) if _, ok := sm.cosignature[*witness]; ok { @@ -126,13 +127,15 @@ func (sm *StateManagerSingle) AddCosignature(_ context.Context, vk ed25519.Publi // source's read-write lock if there are concurrent reads and/or writes. func (sm *StateManagerSingle) rotate(next *types.SignedTreeHead) { if reflect.DeepEqual(sm.cosigned.TreeHead, sm.tosign.TreeHead) { - for _, sigident := range sm.cosigned.SigIdent[1:] { // skip log sigident + // cosigned and tosign are the same. So, we need to merge all + // cosignatures that we already had with the new collected ones. + for _, sigident := range sm.cosigned.SigIdent { if _, ok := sm.cosignature[*sigident.KeyHash]; !ok { sm.cosignature[*sigident.KeyHash] = sigident } } + glog.V(3).Infof("cosigned tree head repeated, merged signatures") } - // cosignatures will contain all cosignatures (even if repeated tree head) var cosignatures []*types.SigIdent for _, sigident := range sm.cosignature { cosignatures = append(cosignatures, sigident) @@ -140,29 +143,12 @@ func (sm *StateManagerSingle) rotate(next *types.SignedTreeHead) { // Update cosigned tree head sm.cosigned.TreeHead = sm.tosign.TreeHead - sm.cosigned.SigIdent = append(sm.tosign.SigIdent, cosignatures...) + sm.cosigned.SigIdent = cosignatures // Update to-sign tree head sm.tosign = *next - sm.cosignature = make(map[[types.HashSize]byte]*types.SigIdent) - glog.V(3).Infof("rotated sth") -} - -func sign(signer crypto.Signer, th *types.TreeHead) (*types.SignedTreeHead, error) { - sig, err := signer.Sign(nil, th.Marshal(), crypto.Hash(0)) - if err != nil { - return nil, fmt.Errorf("Sign: %v", err) - } - - sigident := types.SigIdent{ - KeyHash: types.Hash(signer.Public().(ed25519.PublicKey)[:]), - Signature: &[types.SignatureSize]byte{}, + sm.cosignature = map[[types.HashSize]byte]*types.SigIdent{ + *next.SigIdent[0].KeyHash: next.SigIdent[0], // log signature } - copy(sigident.Signature[:], sig) - return &types.SignedTreeHead{ - TreeHead: *th, - SigIdent: []*types.SigIdent{ - &sigident, - }, - }, nil + glog.V(3).Infof("rotated tree heads") } -- cgit v1.2.3