diff options
author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-02-25 14:36:35 +0100 |
---|---|---|
committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-02-25 14:36:35 +0100 |
commit | c05c22ddbc771e7713849cae40f9d91bfafa0503 (patch) | |
tree | b97d11ab2a914806e6f671f9aff1cab9767b2eab /sth.go | |
parent | c9b4b43654f0ff26207cc63449f13298cd3c56e8 (diff) |
major refactor based on README.md and TODOs
Updated types, improved units tests, isolated most test data to have
it in one place, renamed and created new files to improve readability,
and fixed a bunch of minor TODOs.
Diffstat (limited to 'sth.go')
-rw-r--r-- | sth.go | 90 |
1 files changed, 49 insertions, 41 deletions
@@ -9,21 +9,22 @@ import ( "github.com/golang/glog" "github.com/google/certificate-transparency-go/schedule" "github.com/google/trillian" - "github.com/google/trillian/types" + ttypes "github.com/google/trillian/types" + "github.com/system-transparency/stfe/types" ) // SthSource provides access to the log's STHs. type SthSource interface { // Latest returns the most reccent signed_tree_head_v*. - Latest(context.Context) (*StItem, error) + Latest(context.Context) (*types.StItem, error) // Stable returns the most recent signed_tree_head_v* that is stable for // some period of time, e.g., 10 minutes. - Stable(context.Context) (*StItem, error) + Stable(context.Context) (*types.StItem, error) // Cosigned returns the most recent cosigned_tree_head_v*. - Cosigned(context.Context) (*StItem, error) + Cosigned(context.Context) (*types.StItem, error) // AddCosignature attempts to add a cosignature to the stable STH. The // passed cosigned_tree_head_v* must have a single verified cosignature. - AddCosignature(context.Context, *StItem) error + AddCosignature(context.Context, *types.StItem) error // Run keeps the STH source updated until cancelled Run(context.Context) } @@ -33,9 +34,9 @@ type SthSource interface { type ActiveSthSource struct { client trillian.TrillianLogClient logParameters *LogParameters - currCosth *StItem // current cosigned_tree_head_v1 (already finalized) - nextCosth *StItem // next cosigned_tree_head_v1 (under preparation) - cosignatureFrom map[string]bool // track who we got cosignatures from in nextCosth + currCosth *types.StItem // current cosigned_tree_head_v1 (already finalized) + nextCosth *types.StItem // next cosigned_tree_head_v1 (under preparation) + cosignatureFrom map[[types.NamespaceFingerprintSize]byte]bool // track who we got cosignatures from in nextCosth mutex sync.RWMutex } @@ -51,10 +52,11 @@ func NewActiveSthSource(cli trillian.TrillianLogClient, lp *LogParameters) (*Act if err != nil { return nil, fmt.Errorf("Latest: %v", err) } + // TODO: load persisted cosigned STH? - s.currCosth = NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil) - s.nextCosth = NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil) - s.cosignatureFrom = make(map[string]bool) + s.currCosth = types.NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil) + s.nextCosth = types.NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil) + s.cosignatureFrom = make(map[[types.NamespaceFingerprintSize]byte]bool) return &s, nil } @@ -70,78 +72,84 @@ func (s *ActiveSthSource) Run(ctx context.Context) { // rotate s.mutex.Lock() defer s.mutex.Unlock() - s.rotate(sth) + if err := s.rotate(sth); err != nil { + glog.Warningf("rotate failed: %v", err) + } // TODO: persist cosigned STH? }) } -func (s *ActiveSthSource) Latest(ctx context.Context) (*StItem, error) { +func (s *ActiveSthSource) Latest(ctx context.Context) (*types.StItem, error) { trsp, err := s.client.GetLatestSignedLogRoot(ctx, &trillian.GetLatestSignedLogRootRequest{ LogId: s.logParameters.TreeId, }) - var lr types.LogRootV1 + var lr ttypes.LogRootV1 if errInner := checkGetLatestSignedLogRoot(s.logParameters, trsp, err, &lr); errInner != nil { return nil, fmt.Errorf("invalid signed log root response: %v", errInner) } - return s.logParameters.genV1Sth(NewTreeHeadV1(&lr)) + return s.logParameters.SignTreeHeadV1(NewTreeHeadV1FromLogRoot(&lr)) } -func (s *ActiveSthSource) Stable(_ context.Context) (*StItem, error) { +func (s *ActiveSthSource) Stable(_ context.Context) (*types.StItem, error) { s.mutex.RLock() defer s.mutex.RUnlock() if s.nextCosth == nil { return nil, fmt.Errorf("no stable sth available") } - return &StItem{ - Format: StFormatSignedTreeHeadV1, - SignedTreeHeadV1: &s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1, - }, nil + return types.NewSignedTreeHeadV1(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHead.TreeHead, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHead.Signature), nil } -func (s *ActiveSthSource) Cosigned(_ context.Context) (*StItem, error) { +func (s *ActiveSthSource) Cosigned(_ context.Context) (*types.StItem, error) { s.mutex.RLock() defer s.mutex.RUnlock() - if s.currCosth == nil || len(s.currCosth.CosignedTreeHeadV1.SignatureV1) == 0 { + if s.currCosth == nil || len(s.currCosth.CosignedTreeHeadV1.Cosignatures) == 0 { return nil, fmt.Errorf("no cosigned sth available") } return s.currCosth, nil } -func (s *ActiveSthSource) AddCosignature(_ context.Context, costh *StItem) error { +func (s *ActiveSthSource) AddCosignature(_ context.Context, costh *types.StItem) error { s.mutex.Lock() defer s.mutex.Unlock() - if !reflect.DeepEqual(s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1, costh.CosignedTreeHeadV1.SignedTreeHeadV1) { + if !reflect.DeepEqual(s.nextCosth.CosignedTreeHeadV1.SignedTreeHead, costh.CosignedTreeHeadV1.SignedTreeHead) { return fmt.Errorf("cosignature covers a different tree head") } - witness := costh.CosignedTreeHeadV1.SignatureV1[0].Namespace.String() - if _, ok := s.cosignatureFrom[witness]; ok { + witness, err := costh.CosignedTreeHeadV1.Cosignatures[0].Namespace.Fingerprint() + if err != nil { + return fmt.Errorf("namespace without fingerprint: %v", err) + } + if _, ok := s.cosignatureFrom[*witness]; ok { return nil // duplicate } - s.cosignatureFrom[witness] = true - s.nextCosth.CosignedTreeHeadV1.SignatureV1 = append(s.nextCosth.CosignedTreeHeadV1.SignatureV1, costh.CosignedTreeHeadV1.SignatureV1[0]) + s.cosignatureFrom[*witness] = true + s.nextCosth.CosignedTreeHeadV1.Cosignatures = append(s.nextCosth.CosignedTreeHeadV1.Cosignatures, costh.CosignedTreeHeadV1.Cosignatures[0]) return nil } // rotate rotates the log's cosigned and stable STH. The caller must aquire the // source's read-write lock if there are concurrent reads and/or writes. -func (s *ActiveSthSource) rotate(fixedSth *StItem) { +func (s *ActiveSthSource) rotate(fixedSth *types.StItem) error { // rotate stable -> cosigned - if reflect.DeepEqual(&s.currCosth.CosignedTreeHeadV1.SignedTreeHeadV1, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1) { - for _, sigv1 := range s.currCosth.CosignedTreeHeadV1.SignatureV1 { - witness := sigv1.Namespace.String() - if _, ok := s.cosignatureFrom[witness]; !ok { - s.cosignatureFrom[witness] = true - s.nextCosth.CosignedTreeHeadV1.SignatureV1 = append(s.nextCosth.CosignedTreeHeadV1.SignatureV1, sigv1) + if reflect.DeepEqual(&s.currCosth.CosignedTreeHeadV1.SignedTreeHead, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHead) { + for _, sigv1 := range s.currCosth.CosignedTreeHeadV1.Cosignatures { + witness, err := sigv1.Namespace.Fingerprint() + if err != nil { + return fmt.Errorf("namespace without fingerprint: %v", err) + } + if _, ok := s.cosignatureFrom[*witness]; !ok { + s.cosignatureFrom[*witness] = true + s.nextCosth.CosignedTreeHeadV1.Cosignatures = append(s.nextCosth.CosignedTreeHeadV1.Cosignatures, sigv1) } } } - s.currCosth.CosignedTreeHeadV1.SignedTreeHeadV1 = s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1 - s.currCosth.CosignedTreeHeadV1.SignatureV1 = make([]SignatureV1, len(s.nextCosth.CosignedTreeHeadV1.SignatureV1)) - copy(s.currCosth.CosignedTreeHeadV1.SignatureV1, s.nextCosth.CosignedTreeHeadV1.SignatureV1) + s.currCosth.CosignedTreeHeadV1.SignedTreeHead = s.nextCosth.CosignedTreeHeadV1.SignedTreeHead + s.currCosth.CosignedTreeHeadV1.Cosignatures = make([]types.SignatureV1, len(s.nextCosth.CosignedTreeHeadV1.Cosignatures)) + copy(s.currCosth.CosignedTreeHeadV1.Cosignatures, s.nextCosth.CosignedTreeHeadV1.Cosignatures) // rotate new stable -> stable - if !reflect.DeepEqual(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1, fixedSth.SignedTreeHeadV1) { - s.nextCosth = NewCosignedTreeHeadV1(fixedSth.SignedTreeHeadV1, nil) - s.cosignatureFrom = make(map[string]bool) + if !reflect.DeepEqual(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHead, fixedSth.SignedTreeHeadV1) { + s.nextCosth = types.NewCosignedTreeHeadV1(fixedSth.SignedTreeHeadV1, nil) + s.cosignatureFrom = make(map[[types.NamespaceFingerprintSize]byte]bool) } + return nil } |