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

Conversation

@liamsi
Copy link
Contributor

@liamsi liamsi commented Jul 18, 2017

This will be split up into small separate PRs (related to #679).
As discussed with Gary this will be merge as a single PR.

After further offline discussion this will be split up into two parts:

  1. A monitor "skeleton" which does everything besides the verification
  2. the verification logic and other changes to core (like to the protos)

Implemented:

  • fetch mutations from server
  • main function
  • Docker/docker-compose
  • basic HTTP/grpc API (will be renamed according to this)
  • signing and publishing result/"gossiping"
  • verification (of mutations, SMHs); untested

Missing:

  • "cleanup" (impl vs core)
  • proper storage of received SMH

@liamsi liamsi added the WIP label Jul 18, 2017
@liamsi liamsi added this to the Build Monitor milestone Jul 18, 2017

ENV VERBOSITY=1

ADD keytransparency/genfiles/* /kt/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try following rob's example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I opened an issue for our other Dockerfiles (#712)

ktURL = flag.String("kt-url", "localhost:8080", "URL of key-server.")
ktPEM = flag.String("kt-key", "genfiles/server.crt", "Path to kt-server's public key")
// TODO(ismail): are the IDs actually needed for verification operations?
mapID = flag.Int64("map-id", 0, "Trillian map ID")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove mapID and logID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapID is currently needed by the verifier. I've added a TODO to remove it as soon as the verifier is updated (similar to #708)

"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO for a prometheus variable that tracks Valid / Invalid for each Tree Head

// limitations under the License.

//go:generate protoc -I=. -I=$GOPATH/src/ -I=$GOPATH/src/github.com/google/trillian/ -I=$GOPATH/src/github.com/googleapis/googleapis --go_out=:. keytransparency_v1_types.proto
//go:generate protoc -I=. -I=$GOPATH/src/ -I=$GOPATH/src/github.com/google/trillian/vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/ -I=$GOPATH/src/github.com/google/trillian/ --go_out=:. keytransparency_v1_types.proto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert local changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try rebasing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

message GetMonitoringResponse {
// smr contains the map root for the sparse Merkle Tree signed with the
Copy link
Contributor

@gdbelvin gdbelvin Jul 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For convenience: a pass / fail field.

Proof fields for each type of failure.

  • Invalid root sig
  • Invalid mutation from epoch e to e+1 (current interval)
    • inclusion to leaf at epoch e
    • inclusion to leaf at epoch e+1
  • Set of mutations does not produce new map root
    • map root A
    • inclusion proofs for changed leaves.

TODO: put this in a markdown document

Copy link
Contributor Author

@liamsi liamsi Jul 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've updated your comment to clarify that the "invalid mutations" case is only from epoch e to e+1. My understanding still is that the "storage-less" monitor doesn't have all information if it doesn't additionally store the inclusion proofs (and the corresponding index) at each epoch e. As the monitor can not know in advance (at epoch e) if there will be an error at e+1. Is that correct or do I miss sth?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gdbelvin I've added documenting this in a markdown document to the issue's TODO list so we won't forget about it.

Note to myself: the new inclusion proof (e+1) can be computed using the mutations and the old inclusion proof.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added proto messages for the above cases here: 5ed5f8a

Let me know what you think.

}

// GetSignedMapRootStream is a streaming API similar to GetSignedMapRoot.
func (s *server) GetSignedMapRootStream(in *ktpb.GetMonitoringRequest, stream mspb.MonitorService_GetSignedMapRootStreamServer) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove functions that you don't want to implement. -- including from proto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the stream API as I'm definitely not finishing with this PR.

got.GetMapRevision() == want.GetMapRevision() {
// We already processed this SMR. Do not update seen SMRs. Do not scroll
// pages for further mutations. Return empty mutations list.
glog.Info("Already processed this SMR. Continuing.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include revision number

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return nil, nil
}

mutations := make([]*ktpb.Mutation, pageSize*2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the code to iterate through pages in a function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// Verify the mutation’s validity against the previous leaf.
// Compute the new leaf and store the intermediate hashes locally.
// Compute the new root using local intermediate hashes from epoch e.
for _, m := range mutations {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put verification code in it's own function too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. though, the verification code does not really verify anything yet


tree *tv.Verifier
// TODO(ismail) abstract this into a storage interface and have an in-memory version
seenSMRs []*trillian.SignedMapRoot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create a struct for this:

  • SMR
  • Was it valid? / Error type / status
  • Time observed

@liamsi liamsi mentioned this pull request Jul 28, 2017
12 tasks
@liamsi liamsi force-pushed the mvp_monitor branch 6 times, most recently from a7bcc64 to 96723ec Compare July 31, 2017 14:36
"strings"
"time"

mopb "github.com/google/keytransparency/impl/proto/monitor_v1_service"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please place this import group at the bottom of import(


var (
addr = flag.String("addr", ":8099", "The ip:port combination to listen on")
keyFile = flag.String("key", "genfiles/server.key", "TLS private key file")
Copy link
Contributor

@gdbelvin gdbelvin Jul 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Key and cert are slightly ambiguous. Should we use tls-key and tls-cert?

ktURL = flag.String("kt-url", "localhost:8080", "URL of key-server.")
ktPEM = flag.String("kt-key", "genfiles/server.crt", "Path to kt-server's public key")
// TODO(ismail): remove mapID
mapID = flag.Int64("map-id", 0, "Trillian map ID")
Copy link
Contributor

@gdbelvin gdbelvin Jul 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need the public key of the map and log

// smr will be empty. The epochs are encoded into the smr map_revision.
trillian.SignedMapRoot smr = 1;

// seen_timestamp_nanos contains the time in nanoseconds where this particular
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to create a signed version of this, but let's discuss that in the design document

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might reuse SignedEntryTimestamp in trillian.proto

Copy link
Contributor

@gdbelvin gdbelvin Aug 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brainstorming a few options:

  • Update the signature field in SMR to be a set of signature timestamps.
  • Defining an equals method on SignedMapRoot to determine that signatures of of the same object.
  • Possible further ideas from RoughTime

}

func (s *Server) pollMutations(ctx context.Context, opts ...grpc.CallOption) ([]*ktpb.Mutation, error) {
req := &ktpb.GetMutationsRequest{PageSize: pageSize, Epoch: s.nextRevToQuery()}
Copy link
Contributor

@gdbelvin gdbelvin Jul 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When creating protobufs, consider putting each item on it's own line, or even creating the request proto inside the GetMutation line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


mutations := make([]*ktpb.Mutation, pageSize*2)
mutations = append(mutations, resp.GetMutations()...)
if err := s.pageMutations(ctx, resp, mutations, opts...); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason pageMutations isn't creating and returning the list of mutations inside of it?
In Go, we try to avoid returning values through arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// Update seen/processed signed map roots:
s.proccessedSMRs = append(s.proccessedSMRs,
&ktpb.GetMonitoringResponse{
Smr: &trillian.SignedMapRoot{
Copy link
Contributor

@gdbelvin gdbelvin Jul 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this just be resp.GetSmr() with an updated sig field?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed there will be 2 PRs. One monitor that doesn't do anything and just signs what it sees and a separate pull for the verification logic.

return mutations, nil
}

func (s *Server) verifyMutations(ms []*ktpb.Mutation, expectedRoot []byte) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the verification logic probably deserves it's own file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

for _, m := range ms {
idx := m.GetProof().GetLeaf().GetIndex()
nbrs := m.GetProof().GetInclusion()
if err := s.tree.VerifyProof(nbrs, idx, m.GetProof().GetLeaf().GetLeafValue(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try using the trillian verification logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be moved out of this PR. But done

return nil
}

func (s *Server) lastSeenSMR() *trillian.SignedMapRoot {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions that implement the proto interface also probably deserve their own file

liamsi added 4 commits August 14, 2017 14:48
# Conflicts:
#	core/client/kt/requests.go
#	core/mutator/entry/entry.go
#	core/mutator/entry/entry_test.go
#	impl/proto/monitor_v1_service/gen.go
return nil, err
}
var creds credentials.TransportCredentials
if caFile != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow the example in the key transparency client, splitting up getTransportCreds

trusted trillian.SignedLogRoot
}

func New(hasher hashers.MapHasher, mapPubKey, logPubKey crypto.PublicKey, logVerifier merkle.LogVerifier) *Monitor {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe pass in the tree structs and compute the rest locally

newLeaves := make([]merkle.HStar2LeafHash, 0, len(muts))
mutator := entry.New()
oldProofNodes := make(map[string][]byte)
hasher := coniks.Default
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull from tree config

// store the proof hashes locally to recompute the tree below:
sibIDs := newLeafnID.Siblings()
for level, proof := range m.GetProof().GetInclusion() {
pID := sibIDs[level]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try iterating over sibIDs

@liamsi liamsi mentioned this pull request Aug 21, 2017
@liamsi
Copy link
Contributor Author

liamsi commented Sep 1, 2017

Closing this PR in favor of #776 and #768

@liamsi liamsi closed this Sep 1, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants