aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--handler.go20
-rw-r--r--instance.go2
-rw-r--r--reqres.go11
-rw-r--r--trillian.go32
4 files changed, 46 insertions, 19 deletions
diff --git a/handler.go b/handler.go
index ae91bef..7b3edf9 100644
--- a/handler.go
+++ b/handler.go
@@ -80,11 +80,11 @@ func addEntry(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.R
// getEntries provides 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")
- request, err := NewGetEntriesRequest(r)
+ glog.Info("handling get-entries request")
+ request, err := NewGetEntriesRequest(i.LogParameters, r)
if err != nil {
return http.StatusBadRequest, err
- } // request can be decoded and is valid
+ } // request can be decoded and is mostly valid (range not cmp vs tree size)
trillianRequest := trillian.GetLeavesByRangeRequest{
LogId: i.LogParameters.TreeId,
@@ -95,19 +95,9 @@ func getEntries(ctx context.Context, i *Instance, w http.ResponseWriter, r *http
if err != nil {
return http.StatusInternalServerError, fmt.Errorf("backend GetLeavesByRange request failed: %v", err)
}
-
- // Santity check
- if len(trillianResponse.Leaves) > int(request.End-request.Start+1) {
- return http.StatusInternalServerError, fmt.Errorf("backend GetLeavesByRange returned too many leaves: %d for [%d,%d]", len(trillianResponse.Leaves), request.Start, request.End)
- }
- for i, leaf := range trillianResponse.Leaves {
- if leaf.LeafIndex != request.Start+int64(i) {
- return http.StatusInternalServerError, fmt.Errorf("backend GetLeavesByRange returned unexpected leaf index: wanted %d, got %d", request.Start+int64(i), leaf.LeafIndex)
- }
-
- glog.Infof("Leaf(%d) => %v", request.Start+int64(i), leaf.GetLeafValue())
+ if status, err := checkGetLeavesByRange(trillianResponse, request); err != nil {
+ return status, err
}
- // TODO: use the returned root for tree_size santity checking against start?
response, err := NewGetEntriesResponse(trillianResponse.Leaves)
if err != nil {
diff --git a/instance.go b/instance.go
index 6b67096..b13bdbe 100644
--- a/instance.go
+++ b/instance.go
@@ -27,6 +27,7 @@ type LogParameters struct {
LogId []byte // used externally by everyone
TreeId int64 // used internally by Trillian
Prefix string
+ MaxRange int64 // max entries per get-entries request
AnchorPool *x509.CertPool // for chain verification
AnchorList []*x509.Certificate // for access to the raw certificates
Signer crypto.Signer
@@ -68,6 +69,7 @@ func NewLogParameters(treeId int64, prefix string, anchorPath, keyPath string) (
LogId: logId,
TreeId: treeId,
Prefix: prefix,
+ MaxRange: 2, // TODO: allow configuration
AnchorPool: anchorPool,
AnchorList: anchorList,
Signer: key,
diff --git a/reqres.go b/reqres.go
index 59709cf..598503d 100644
--- a/reqres.go
+++ b/reqres.go
@@ -93,8 +93,10 @@ func NewAddEntryRequest(lp *LogParameters, r *http.Request) ([]byte, []byte, err
}
// NewGetEntriesRequest parses and sanitizes the URL-encoded get-entries
-// parameters from an incoming HTTP request.
-func NewGetEntriesRequest(httpRequest *http.Request) (GetEntriesRequest, error) {
+// parameters from an incoming HTTP request. Too large ranges are truncated
+// based on the log's configured max range, but without taking the log's
+// current tree size into consideration (because it is not know at this point).
+func NewGetEntriesRequest(lp *LogParameters, httpRequest *http.Request) (GetEntriesRequest, error) {
start, err := strconv.ParseInt(httpRequest.FormValue("start"), 10, 64)
if err != nil {
return GetEntriesRequest{}, fmt.Errorf("bad start parameter: %v", err)
@@ -110,8 +112,9 @@ func NewGetEntriesRequest(httpRequest *http.Request) (GetEntriesRequest, error)
if start > end {
return GetEntriesRequest{}, fmt.Errorf("bad parameters: start(%v) must be less than or equal to end(%v)", start, end)
}
- // TODO: check that range is not larger than the max range. Yes -> truncate
- // TODO: check that end is not past the most recent STH. Yes -> truncate
+ if end-start+1 > lp.MaxRange {
+ end = start + lp.MaxRange - 1
+ }
return GetEntriesRequest{Start: start, End: end}, nil
}
diff --git a/trillian.go b/trillian.go
new file mode 100644
index 0000000..e5117da
--- /dev/null
+++ b/trillian.go
@@ -0,0 +1,32 @@
+package stfe
+
+import (
+ "fmt"
+
+ "net/http"
+
+ "github.com/google/trillian"
+ "github.com/google/trillian/types"
+)
+
+// checkGetLeavesByRange does santity-checking on a Trillian response
+func checkGetLeavesByRange(rsp *trillian.GetLeavesByRangeResponse, req GetEntriesRequest) (int, error) {
+ if len(rsp.Leaves) > int(req.End-req.Start+1) {
+ return http.StatusInternalServerError, fmt.Errorf("backend GetLeavesByRange returned too many leaves: %d for [%d,%d]", len(rsp.Leaves), req.Start, req.End)
+ }
+
+ var lr types.LogRootV1
+ if err := lr.UnmarshalBinary(rsp.GetSignedLogRoot().GetLogRoot()); err != nil {
+ return http.StatusInternalServerError, fmt.Errorf("failed unmarshaling log root: %v", err)
+ }
+ if uint64(req.Start) >= lr.TreeSize {
+ return http.StatusBadRequest, fmt.Errorf("invalid start(%d): tree size is %d", req.Start, lr.TreeSize)
+ }
+
+ for i, leaf := range rsp.Leaves {
+ if leaf.LeafIndex != req.Start+int64(i) {
+ return http.StatusInternalServerError, fmt.Errorf("backend GetLeavesByRange returned unexpected leaf index: wanted %d, got %d", req.Start+int64(i), leaf.LeafIndex)
+ }
+ }
+ return 0, nil
+}