diff options
author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-10-30 18:10:49 +0100 |
---|---|---|
committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2020-10-30 18:10:49 +0100 |
commit | 24eb746adec654637f88ae185012dc984cf9b2dc (patch) | |
tree | 44c40f7466f7e2051c9963198c8af1ea38f7a77e /trillian.go | |
parent | a2acb248fb11db24fb0e77022de7e8b54c527bbc (diff) |
added sanity checks on Trillian responses
Based on the sanity checks that CTFE does.
Diffstat (limited to 'trillian.go')
-rw-r--r-- | trillian.go | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/trillian.go b/trillian.go index e5117da..147c5bd 100644 --- a/trillian.go +++ b/trillian.go @@ -5,28 +5,83 @@ import ( "net/http" + "github.com/golang/glog" "github.com/google/trillian" "github.com/google/trillian/types" + "google.golang.org/grpc/codes" ) -// checkGetLeavesByRange does santity-checking on a Trillian response -func checkGetLeavesByRange(rsp *trillian.GetLeavesByRangeResponse, req GetEntriesRequest) (int, error) { +func checkQueueLeaf(rsp *trillian.QueueLeafResponse) (int, error) { + if codes.Code(rsp.QueuedLeaf.GetStatus().GetCode()) == codes.AlreadyExists { + // no need to report this as an invalid request, just (re)issue sdi + glog.V(3).Infof("queued leaf is a duplicate => %X", rsp.QueuedLeaf.Leaf.LeafValue) + } else { + glog.V(3).Infof("queued leaf => %X", rsp.QueuedLeaf.Leaf.LeafValue) + } + return 0, nil +} + +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) } + // Ensure that a bad start parameter results in an error 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) + return http.StatusNotFound, fmt.Errorf("invalid start(%d): tree size is %d", req.Start, lr.TreeSize) } + // Ensure that we got and return expected leaf indices 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 http.StatusInternalServerError, fmt.Errorf("invalid leaf index: wanted %d, got %d", req.Start+int64(i), leaf.LeafIndex) } } return 0, nil } + +func checkGetInclusionProofByHash(rsp *trillian.GetInclusionProofByHashResponse, lp *LogParameters) (int, error) { + if rsp.Proof == nil || len(rsp.Proof) == 0 { + return http.StatusNotFound, fmt.Errorf("incomplete backend response") + } // maybe redundant, but better safe than sorry + return checkHashPath(lp.HashType.Size(), rsp.Proof[0].Hashes) +} + +func checkGetConsistencyProofResponse(rsp *trillian.GetConsistencyProofResponse, lp *LogParameters) (int, error) { + if rsp.Proof == nil { + return http.StatusNotFound, fmt.Errorf("incomplete backend response") + } // not redundant, out-of-range parameters yield an empty proof w/o error + return checkHashPath(lp.HashType.Size(), rsp.Proof.Hashes) +} + +func checkTrillianGetLatestSignedLogRoot(rsp *trillian.GetLatestSignedLogRootResponse, lp *LogParameters) (int, error) { + if rsp.SignedLogRoot == nil { + return http.StatusInternalServerError, fmt.Errorf("incomplete backend response") + } // maybe redundant + + 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 len(lr.RootHash) != lp.HashType.Size() { + return http.StatusInternalServerError, fmt.Errorf("invalid root hash: %v", lr.RootHash) + } // maybe redundant, but would not necessarily be caught by marshal error + return 0, nil +} + +func checkHashPath(hashSize int, path [][]byte) (int, error) { + for _, hash := range path { + if len(hash) != hashSize { + return http.StatusInternalServerError, fmt.Errorf("invalid proof: %v", path) + } + } // maybe redundant, but would not necessarily be caught by marshal error + return 0, nil +} + +func checkLogRoot(hashSize int, rootHash []byte) (int, error) { + return 0, nil +} |