aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc.go3
-rw-r--r--handler.go78
-rw-r--r--instance.go50
-rw-r--r--server/main.go52
-rwxr-xr-xserver/serverbin0 -> 14361514 bytes
-rw-r--r--type.go3
6 files changed, 186 insertions, 0 deletions
diff --git a/doc.go b/doc.go
new file mode 100644
index 0000000..4e86552
--- /dev/null
+++ b/doc.go
@@ -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/server
new file mode 100755
index 0000000..466879e
--- /dev/null
+++ b/server/server
Binary files differ
diff --git a/type.go b/type.go
new file mode 100644
index 0000000..140a698
--- /dev/null
+++ b/type.go
@@ -0,0 +1,3 @@
+package stfe
+
+// Leaf definition and such goes here