aboutsummaryrefslogtreecommitdiff
path: root/handler.go
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-10-21 18:18:43 +0200
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-10-21 18:18:43 +0200
commitec4741e374beeb085579ba896fdee2cd6f0f8848 (patch)
treea2c3b971469e8a1d2230a4bc220a1e0a602aa128 /handler.go
parent3296d1013c54ff336ce43fab835489305f23cb01 (diff)
added start on addEntry code path
If the POSTed StItem can be parsed without errors it is handed over to the Trillian back-end.
Diffstat (limited to 'handler.go')
-rw-r--r--handler.go71
1 files changed, 68 insertions, 3 deletions
diff --git a/handler.go b/handler.go
index 90dbc27..7b986c1 100644
--- a/handler.go
+++ b/handler.go
@@ -4,9 +4,13 @@ import (
"context"
"fmt"
+ "encoding/json"
+ "io/ioutil"
"net/http"
"github.com/golang/glog"
+ "github.com/google/certificate-transparency-go/tls"
+ "github.com/google/trillian"
)
// appHandler implements the http.Handler interface, and contains a reference
@@ -31,7 +35,7 @@ func (a appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
statusCode, err := a.handler(ctx, a.instance, w, r)
if err != nil {
- glog.Warningf("handler error %s: %v", a.instance.prefix+a.endpoint, err)
+ glog.Warningf("handler error %s/%s: %v", a.instance.prefix, a.endpoint, err)
a.sendHTTPError(w, statusCode, err)
}
}
@@ -41,10 +45,71 @@ func (a appHandler) sendHTTPError(w http.ResponseWriter, statusCode int, err err
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
+ var request AddEntryRequest
+ if err := unpackRequest(r, &request); err != nil {
+ return http.StatusBadRequest, err
+ }
+
+ item, err := verifyAddEntryRequest(request)
+ if err != nil {
+ return http.StatusBadRequest, err
+ }
+ glog.Infof("got item: %s", item)
+
+ serializedItem, err := tls.Marshal(*item)
+ if err != nil {
+ return http.StatusInternalServerError, fmt.Errorf("tls marshal failed: %v", err)
+ }
+ trillianRequest := trillian.QueueLeafRequest{
+ LogId: i.logID,
+ Leaf: &trillian.LogLeaf{
+ LeafValue: serializedItem,
+ //TODO: add appendix here w/ chain + signature
+ },
+ }
+
+ trillianResponse, err := i.client.QueueLeaf(ctx, &trillianRequest)
+ if err != nil {
+ return http.StatusInternalServerError, fmt.Errorf("backend QueueLeaf request failed: %v", err)
+ }
+ if trillianResponse == nil {
+ return http.StatusInternalServerError, fmt.Errorf("missing QueueLeaf response")
+ }
+ // TODO: check that we got gRPC OK as specified in Trillian's API doc
+
+ queuedLeaf := trillianResponse.QueuedLeaf
+ glog.Infof("Queued leaf: %v", queuedLeaf.Leaf.LeafValue)
+ // TODO: respond with an SDI
+
+ return http.StatusOK, nil
+}
+
+// verifyAddEntryRequest
+func verifyAddEntryRequest(r AddEntryRequest) (*StItem, error) {
+ item, err := StItemFromB64(r.Item)
+ if err != nil {
+ return nil, fmt.Errorf("failed decoding StItem: %v", err)
+ }
+ if item.Format != StFormatChecksumV1 {
+ return nil, fmt.Errorf("invalid StItem format: %s", item.Format)
+ }
+ // TODO: verify checksum length
+ // TODO: verify r.Signature and r.Certificate
+ return item, nil
+}
+
+// unpackRequest tries to unpack a json-encoded HTTP POST request into `unpack`
+func unpackRequest(r *http.Request, unpack interface{}) error {
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ return fmt.Errorf("failed reading request body: %v", err)
+ }
+ if err := json.Unmarshal(body, &unpack); err != nil {
+ return fmt.Errorf("failed parsing json body: %v", err)
+ }
+ return nil
}
// getEntries provides with a list of entries from the Trillian backend