Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit 94f7508

Browse files
committed
restructured non-verifiying monitor
1 parent b881c04 commit 94f7508

File tree

10 files changed

+265
-127
lines changed

10 files changed

+265
-127
lines changed

cmd/keytransparency-monitor/main.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ import (
3535
"google.golang.org/grpc/credentials"
3636
"google.golang.org/grpc/reflection"
3737

38+
"github.com/google/keytransparency/core/monitor/storage"
3839
cmon "github.com/google/keytransparency/core/monitor"
3940
kpb "github.com/google/keytransparency/core/proto/keytransparency_v1_types"
41+
"github.com/google/keytransparency/impl/monitor/client"
4042
spb "github.com/google/keytransparency/impl/proto/keytransparency_v1_service"
4143
mopb "github.com/google/keytransparency/impl/proto/monitor_v1_service"
4244
mupb "github.com/google/keytransparency/impl/proto/mutation_v1_service"
45+
_ "github.com/google/trillian/merkle/coniks" // Register coniks
46+
_ "github.com/google/trillian/merkle/objhasher" // Register objhasher
4347
)
4448

4549
var (
@@ -121,12 +125,8 @@ func main() {
121125
glog.Fatalf("Could not read domain info %v:", err)
122126
}
123127

124-
srv := monitor.New(mcc, crypto.NewSHA256Signer(key), logTree, mapTree, *pollPeriod)
125-
mon, err := cmon.New(logTree, mapTree, crypto.NewSHA256Signer(key))
126-
if err != nil {
127-
glog.Exitf("Failed setting up REST proxy: %v", err)
128-
}
129-
128+
store := storage.New()
129+
srv := monitor.New(store)
130130
mopb.RegisterMonitorServiceServer(grpcServer, srv)
131131
reflection.Register(grpcServer)
132132
grpc_prometheus.Register(grpcServer)
@@ -142,6 +142,31 @@ func main() {
142142
mux := http.NewServeMux()
143143
mux.Handle("/", gwmux)
144144

145+
// initialize the mutations API client and feed the responses it got
146+
// into the monitor:
147+
mon, err := cmon.New(logTree, mapTree, crypto.NewSHA256Signer(key), store)
148+
if err != nil {
149+
glog.Exitf("Failed to initialize monitor: %v", err)
150+
}
151+
mutCli := client.New(mcc, *pollPeriod)
152+
responses, errs := mutCli.StartPolling(1)
153+
go func() {
154+
for {
155+
select {
156+
case mutResp := <-responses:
157+
glog.Infof("Received mutations response: %v", mutResp.Epoch)
158+
if err := mon.Process(mutResp); err != nil {
159+
glog.Infof("Error processing mutations response: %v", err)
160+
}
161+
case err := <-errs:
162+
// this is OK if there were no mutations in between:
163+
// TODO(ismail): handle the case when the known maxDuration has
164+
// passed and no epoch was issued?
165+
glog.Infof("Could not retrieve mutations API response %v", err)
166+
}
167+
}
168+
}()
169+
145170
// Serve HTTP2 server over TLS.
146171
glog.Infof("Listening on %v", *addr)
147172
if err := http.ListenAndServeTLS(*addr, *certFile, *keyFile,
@@ -190,7 +215,7 @@ func transportCreds(ktURL string, ktCert string, insecure bool) (credentials.Tra
190215
}
191216

192217
// config selects a source for and returns the client configuration.
193-
func getTrees(ctx context.Context, cc *grpc.ClientConn) (mapTree *trillian.Tree, logTree *trillian.Tree, err error) {
218+
func getTrees(ctx context.Context, cc *grpc.ClientConn) (logTree *trillian.Tree, mapTree *trillian.Tree, err error) {
194219
ktClient := spb.NewKeyTransparencyServiceClient(cc)
195220
resp, err2 := ktClient.GetDomainInfo(ctx, &kpb.GetDomainInfoRequest{})
196221
if err2 != nil {

core/monitor/monitor.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ package monitor
1717
import (
1818
"crypto"
1919
"fmt"
20+
"time"
21+
22+
"github.com/golang/glog"
23+
24+
"github.com/google/keytransparency/core/monitor/storage"
25+
ktpb "github.com/google/keytransparency/core/proto/keytransparency_v1_types"
2026

2127
"github.com/google/trillian"
2228
"github.com/google/trillian/merkle"
2329
"github.com/google/trillian/merkle/hashers"
24-
2530
tcrypto "github.com/google/trillian/crypto"
2631
)
2732

@@ -35,10 +40,11 @@ type Monitor struct {
3540
signer *tcrypto.Signer
3641
// TODO(ismail): update last trusted signed log root
3742
//trusted trillian.SignedLogRoot
43+
store *storage.Storage
3844
}
3945

4046
// New creates a new instance of the monitor.
41-
func New(logTree, mapTree *trillian.Tree, signer *tcrypto.Signer) (*Monitor, error) {
47+
func New(logTree, mapTree *trillian.Tree, signer *tcrypto.Signer, store *storage.Storage) (*Monitor, error) {
4248
logHasher, err := hashers.NewLogHasher(logTree.GetHashStrategy())
4349
if err != nil {
4450
return nil, fmt.Errorf("Failed creating LogHasher: %v", err)
@@ -53,5 +59,26 @@ func New(logTree, mapTree *trillian.Tree, signer *tcrypto.Signer) (*Monitor, err
5359
logPubKey: logTree.GetPublicKey(),
5460
mapPubKey: mapTree.GetPublicKey(),
5561
signer: signer,
62+
store: store,
5663
}, nil
5764
}
65+
66+
func (m *Monitor) Process(resp *ktpb.GetMutationsResponse) error {
67+
var smr *trillian.SignedMapRoot
68+
var err error
69+
seen := time.Now().Unix()
70+
errs := m.VerifyMutationsResponse(resp)
71+
if len(errs) == 0 {
72+
glog.Infof("Successfully verified mutations response for epoch: %v", resp.Epoch)
73+
smr, err = m.signMapRoot(resp)
74+
if err != nil {
75+
glog.Errorf("Failed to sign map root for epoch %v: %v", resp.Epoch, err)
76+
return fmt.Errorf("m.signMapRoot(_): %v", err)
77+
}
78+
}
79+
if err := m.store.Set(resp.Epoch, seen, smr, resp, errs); err != nil {
80+
glog.Errorf("m.store.Set(%v, %v, _, _, %v): %v", resp.Epoch, seen, errs, err)
81+
return err
82+
}
83+
return nil
84+
}

core/monitor/response.go

Lines changed: 0 additions & 42 deletions
This file was deleted.

impl/monitor/process.go renamed to core/monitor/sign.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,26 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Package monitor implements the monitor service. A monitor repeatedly polls a
16-
// key-transparency server's Mutations API and signs Map Roots if it could
17-
// reconstruct
18-
// clients can query.
1915
package monitor
2016

2117
import (
22-
"errors"
23-
)
18+
"fmt"
19+
20+
ktpb "github.com/google/keytransparency/core/proto/keytransparency_v1_types"
2421

25-
var (
26-
// ErrNothingProcessed occurs when the monitor did not process any mutations /
27-
// smrs yet.
28-
ErrNothingProcessed = errors.New("did not process any mutations yet")
22+
"github.com/google/trillian"
2923
)
3024

31-
// TODO(ismail): call the client, actually process the mutations by calling API
32-
// in core
25+
func (m *Monitor) signMapRoot(in *ktpb.GetMutationsResponse) (*trillian.SignedMapRoot, error) {
26+
// copy of received SMR:
27+
smr := *in.Smr
28+
smr.Signature = nil
29+
30+
sig, err := m.signer.SignObject(smr)
31+
if err != nil {
32+
return nil, fmt.Errorf("SignObject(): %v", err)
33+
}
34+
smr.Signature = sig
35+
36+
return &smr, nil
37+
}

core/monitor/storage/storage.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2017 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package storage
16+
17+
import (
18+
"errors"
19+
20+
ktpb "github.com/google/keytransparency/core/proto/keytransparency_v1_types"
21+
"github.com/google/trillian"
22+
)
23+
24+
var (
25+
ErrAlreadyStored = errors.New("already stored epoch")
26+
ErrNotFound = errors.New("data for epoch not found")
27+
)
28+
29+
type MonitoringResult struct {
30+
// in case of success this contains the map root signed by the monitor
31+
Smr *trillian.SignedMapRoot
32+
// response contains the original mutations API response from the server
33+
// in case at least one verification step failed
34+
Response *ktpb.GetMutationsResponse
35+
Seen int64
36+
Errors []error
37+
}
38+
39+
type Storage struct {
40+
store map[int64]*MonitoringResult
41+
latest int64
42+
}
43+
44+
func New() *Storage {
45+
return &Storage{
46+
store: make(map[int64]*MonitoringResult),
47+
}
48+
}
49+
50+
func (s *Storage) Set(epoch int64,
51+
seenNanos int64,
52+
smr *trillian.SignedMapRoot,
53+
response *ktpb.GetMutationsResponse,
54+
errorList []error) error {
55+
// see if we already processed this epoch:
56+
if _, ok := s.store[epoch]; ok {
57+
return ErrAlreadyStored
58+
}
59+
// if not we just store the value:
60+
s.store[epoch] = &MonitoringResult{
61+
Smr: smr,
62+
Seen: seenNanos,
63+
Response: response,
64+
Errors: errorList,
65+
}
66+
s.latest=epoch
67+
return nil
68+
}
69+
70+
func (s *Storage) Get(epoch int64) (*MonitoringResult, error) {
71+
if result, ok := s.store[epoch]; ok {
72+
return result, nil
73+
}
74+
return nil, ErrNotFound
75+
}
76+
77+
func (s *Storage) LatestEpoch() int64 {
78+
return s.latest
79+
}

core/monitor/verify.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
// of received mutations may differ from those included in the initial response
2727
// because of the max. page size. If any verification check failed it returns
2828
// an error.
29-
// TODO(ismail): make this return a list of errors
30-
func (m *Monitor) VerifyMutationsResponse(in *ktpb.GetMutationsResponse, allMuts []*ktpb.Mutation) error {
29+
func (m *Monitor) VerifyMutationsResponse(in *ktpb.GetMutationsResponse) []error {
3130
return nil
3231
}

core/proto/monitor_v1_types/monitor_v1_types.pb.go

Lines changed: 37 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)