package stfe import ( "context" "crypto/ed25519" "fmt" "net/http" "github.com/golang/glog" "github.com/google/trillian" "github.com/system-transparency/stfe/types" ) func addEntry(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.Request) (int, error) { glog.V(3).Info("handling add-entry request") leaf, err := i.LogParameters.parseAddEntryV1Request(r) if err != nil { return http.StatusBadRequest, fmt.Errorf("parseAddEntryV1Request: %v", err) } trsp, err := i.Client.QueueLeaf(ctx, &trillian.QueueLeafRequest{ LogId: i.LogParameters.TreeId, Leaf: &trillian.LogLeaf{ LeafValue: leaf.Marshal(), ExtraData: nil, }, }) if errInner := checkQueueLeaf(trsp, err); errInner != nil { return http.StatusInternalServerError, fmt.Errorf("bad QueueLeafResponse: %v", errInner) } return http.StatusOK, nil } func addCosignature(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.Request) (int, error) { glog.V(3).Info("handling add-cosignature request") req, err := i.LogParameters.parseAddCosignatureRequest(r) if err != nil { return http.StatusBadRequest, fmt.Errorf("parseAddCosignatureRequest: %v", err) } vk := i.LogParameters.Witnesses[*req.KeyHash] if err := i.SthSource.AddCosignature(ctx, ed25519.PublicKey(vk[:]), req.Signature); err != nil { return http.StatusBadRequest, fmt.Errorf("AddCosignature: %v", err) } return http.StatusOK, nil } func getLatestSth(ctx context.Context, i *Instance, w http.ResponseWriter, _ *http.Request) (int, error) { glog.V(3).Info("handling get-latest-sth request") sth, err := i.SthSource.Latest(ctx) if err != nil { return http.StatusInternalServerError, fmt.Errorf("Latest: %v", err) } if err := sth.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } return http.StatusOK, nil } func getStableSth(ctx context.Context, i *Instance, w http.ResponseWriter, _ *http.Request) (int, error) { glog.V(3).Info("handling get-stable-sth request") sth, err := i.SthSource.Stable(ctx) if err != nil { return http.StatusInternalServerError, fmt.Errorf("Latest: %v", err) } if err := sth.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } return http.StatusOK, nil } func getCosignedSth(ctx context.Context, i *Instance, w http.ResponseWriter, _ *http.Request) (int, error) { glog.V(3).Info("handling get-cosigned-sth request") sth, err := i.SthSource.Cosigned(ctx) if err != nil { return http.StatusInternalServerError, fmt.Errorf("Cosigned: %v", err) } if err := sth.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } return http.StatusOK, nil } func getConsistencyProof(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.Request) (int, error) { glog.V(3).Info("handling get-consistency-proof request") req, err := i.LogParameters.parseGetConsistencyProofRequest(r) if err != nil { return http.StatusBadRequest, err } trsp, err := i.Client.GetConsistencyProof(ctx, &trillian.GetConsistencyProofRequest{ LogId: i.LogParameters.TreeId, FirstTreeSize: int64(req.OldSize), SecondTreeSize: int64(req.NewSize), }) if errInner := checkGetConsistencyProof(i.LogParameters, trsp, err); errInner != nil { return http.StatusInternalServerError, fmt.Errorf("bad GetConsistencyProofResponse: %v", errInner) } proof := &types.ConsistencyProof{ NewSize: req.NewSize, OldSize: req.OldSize, Path: NodePathFromHashes(trsp.Proof.Hashes), } if err := proof.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } return http.StatusOK, nil } func getProofByHash(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.Request) (int, error) { glog.V(3).Info("handling get-proof-by-hash request") req, err := i.LogParameters.parseGetProofByHashRequest(r) if err != nil { return http.StatusBadRequest, err } trsp, err := i.Client.GetInclusionProofByHash(ctx, &trillian.GetInclusionProofByHashRequest{ LogId: i.LogParameters.TreeId, LeafHash: req.LeafHash[:], TreeSize: int64(req.TreeSize), OrderBySequence: true, }) if errInner := checkGetInclusionProofByHash(i.LogParameters, trsp, err); errInner != nil { return http.StatusInternalServerError, fmt.Errorf("bad GetInclusionProofByHashResponse: %v", errInner) } proof := &types.InclusionProof{ TreeSize: req.TreeSize, LeafIndex: uint64(trsp.Proof[0].LeafIndex), Path: NodePathFromHashes(trsp.Proof[0].Hashes), } if err := proof.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } return http.StatusOK, nil } func getEntries(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.Request) (int, error) { glog.V(3).Info("handling get-entries request") req, err := i.LogParameters.parseGetEntriesRequest(r) if err != nil { return http.StatusBadRequest, err } trsp, err := i.Client.GetLeavesByRange(ctx, &trillian.GetLeavesByRangeRequest{ LogId: i.LogParameters.TreeId, StartIndex: int64(req.StartSize), Count: int64(req.EndSize-req.StartSize) + 1, }) if errInner := checkGetLeavesByRange(req, trsp, err); errInner != nil { return http.StatusInternalServerError, fmt.Errorf("checkGetLeavesByRangeResponse: %v", errInner) // there is one StatusBadRequest in here tho.. } for _, serialized := range trsp.Leaves { var leaf types.Leaf if err := leaf.Unmarshal(serialized.LeafValue); err != nil { return http.StatusInternalServerError, fmt.Errorf("Unmarshal: %v", err) } if err := leaf.MarshalASCII(w); err != nil { return http.StatusInternalServerError, fmt.Errorf("MarshalASCII: %v", err) } } return http.StatusOK, nil }