diff options
| -rw-r--r-- | doc.go | 3 | ||||
| -rw-r--r-- | handler.go | 78 | ||||
| -rw-r--r-- | instance.go | 50 | ||||
| -rw-r--r-- | server/main.go | 52 | ||||
| -rwxr-xr-x | server/server | bin | 0 -> 14361514 bytes | |||
| -rw-r--r-- | type.go | 3 | 
6 files changed, 186 insertions, 0 deletions
| @@ -0,0 +1,3 @@ +// Package stfe implements a System Transparency Front-End (STFE) personality +// for the Trillian log server gRPC API. +package stfe diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..90dbc27 --- /dev/null +++ b/handler.go @@ -0,0 +1,78 @@ +package stfe + +import ( +	"context" +	"fmt" + +	"net/http" + +	"github.com/golang/glog" +) + +// appHandler implements the http.Handler interface, and contains a reference +// to an STFE server instance as well as a function that uses it. +type appHandler struct { +	instance *instance // STFE server instance +	endpoint string    // e.g., add-entry +	method   string    // e.g., GET +	handler  func(context.Context, *instance, http.ResponseWriter, *http.Request) (int, error) +} + +// ServeHTTP docdoc +func (a appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +	ctx, cancel := context.WithDeadline(r.Context(), a.instance.timesource.Now().Add(a.instance.deadline)) +	defer cancel() + +	if r.Method != a.method { +		glog.Warningf("%s: got HTTP %s, wanted HTTP %s", a.instance.prefix+a.endpoint, r.Method, a.method) +		a.sendHTTPError(w, http.StatusMethodNotAllowed, fmt.Errorf("method not allowed: %s", r.Method)) +		return +	} + +	statusCode, err := a.handler(ctx, a.instance, w, r) +	if err != nil { +		glog.Warningf("handler error %s: %v", a.instance.prefix+a.endpoint, err) +		a.sendHTTPError(w, statusCode, err) +	} +} + +// sendHTTPError replies to a request with an error message and a status code. +func (a appHandler) sendHTTPError(w http.ResponseWriter, statusCode int, err error) { +	http.Error(w, http.StatusText(statusCode), statusCode) +} + +// addEntry adds an entry to the Trillian backend +func addEntry(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in addEntry") +	return http.StatusOK, nil // TODO +} + +// getEntries provides with a list of entries from the Trillian backend +func getEntries(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in getEntries") +	return http.StatusOK, nil // TODO +} + +// getAnchors provides a list of configured trust anchors +func getAnchors(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in getAnchors") +	return http.StatusOK, nil // TODO +} + +// getProofByHash provides an inclusion proof based on a given leaf hash +func getProofByHash(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in getProofByHash") +	return http.StatusOK, nil // TODO +} + +// getConsistencyProof provides a consistency proof between two STHs +func getConsistencyProof(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in getConsistencyProof") +	return http.StatusOK, nil // TODO +} + +// getSth provides the most recent STH +func getSth(ctx context.Context, i *instance, w http.ResponseWriter, r *http.Request) (int, error) { +	glog.Info("in getSth") +	return http.StatusOK, nil // TODO +} diff --git a/instance.go b/instance.go new file mode 100644 index 0000000..5fa1b6c --- /dev/null +++ b/instance.go @@ -0,0 +1,50 @@ +package stfe + +import ( +	"time" + +	"net/http" + +	"github.com/golang/glog" +	"github.com/google/trillian" + +	ctutil "github.com/google/certificate-transparency-go/trillian/util" +) + +// instance groups information about a specific STFE instance. +type instance struct { +	prefix     string +	logID      int64 +	client     trillian.TrillianLogClient +	deadline   time.Duration +	timesource ctutil.TimeSource +} + +// NewInstance returns a new STFE instance +func NewInstance(prefix string, id int64, client trillian.TrillianLogClient, deadline time.Duration, timesource ctutil.TimeSource) *instance { +	return &instance{ +		prefix:     prefix, +		logID:      id, +		client:     client, +		deadline:   deadline, +		timesource: timesource, +	} +} + +// addEndpoints registers STFE handler functions for the respective HTTP paths +func (i *instance) AddEndpoints(mux *http.ServeMux) { +	for _, endpoint := range []struct { +		path    string +		handler appHandler +	}{ +		{i.prefix + "/add-entry", appHandler{instance: i, handler: addEntry, endpoint: "add-entry", method: http.MethodPost}}, +		{i.prefix + "/get-entries", appHandler{instance: i, handler: getEntries, endpoint: "get-entries", method: http.MethodGet}}, +		{i.prefix + "/get-anchors", appHandler{instance: i, handler: getAnchors, endpoint: "get-anchors", method: http.MethodGet}}, +		{i.prefix + "/get-proof-by-hash", appHandler{instance: i, handler: getProofByHash, endpoint: "get-proof-by-hash", method: http.MethodGet}}, +		{i.prefix + "/get-consistency-proof", appHandler{instance: i, handler: getConsistencyProof, endpoint: "get-consistency-proof", method: http.MethodGet}}, +		{i.prefix + "/get-sth", appHandler{instance: i, handler: getSth, endpoint: "get-sth", method: http.MethodGet}}, +	} { +		glog.Infof("adding handler for %v", endpoint.path) +		mux.Handle(endpoint.path, endpoint.handler) +	} +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..53ac8e6 --- /dev/null +++ b/server/main.go @@ -0,0 +1,52 @@ +// Package main provides an STFE binary +package main + +import ( +	"flag" +	"time" + +	"net/http" + +	"github.com/golang/glog" +	"github.com/google/trillian" +	"github.com/system-transparency/stfe" +	"google.golang.org/grpc" + +	ctutil "github.com/google/certificate-transparency-go/trillian/util" +) + +var ( +	httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients") +	rpcBackend   = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients") +	prefix       = flag.String("prefix", "/st/v1", "a prefix that proceeds each endpoint path") +	trillianID   = flag.Int64("trillianID", 5991359069696313945, "log identifier in the Trillian database") +	rpcDeadline  = flag.Duration("rpc_deadline", time.Second*10, "deadline for backend RPC requests") +) + +func main() { +	flag.Parse() + +	glog.Info("Dialling Trillian gRPC log server") +	dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(*rpcDeadline)} +	conn, err := grpc.Dial(*rpcBackend, dialOpts...) +	if err != nil { +		glog.Fatal(err) +	} + +	glog.Info("Creating HTTP request multiplexer") +	mux := http.NewServeMux() +	http.Handle("/", mux) + +	glog.Info("Creating STFE server instance") +	stfe_server := stfe.NewInstance(*prefix, *trillianID, trillian.NewTrillianLogClient(conn), *rpcDeadline, new(ctutil.SystemTimeSource)) +	stfe_server.AddEndpoints(mux) + +	glog.Infof("Serving on %v%v", *httpEndpoint, *prefix) +	srv := http.Server{Addr: *httpEndpoint} +	err = srv.ListenAndServe() +	if err != http.ErrServerClosed { +		glog.Warningf("Server exited: %v", err) +	} + +	glog.Flush() +} diff --git a/server/server b/server/serverBinary files differ new file mode 100755 index 0000000..466879e --- /dev/null +++ b/server/server @@ -0,0 +1,3 @@ +package stfe + +// Leaf definition and such goes here | 
