aboutsummaryrefslogtreecommitdiff
path: root/request_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'request_test.go')
-rw-r--r--request_test.go318
1 files changed, 318 insertions, 0 deletions
diff --git a/request_test.go b/request_test.go
new file mode 100644
index 0000000..b0e5da1
--- /dev/null
+++ b/request_test.go
@@ -0,0 +1,318 @@
+package stfe
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "testing"
+ "testing/iotest"
+
+ "net/http"
+
+ "github.com/system-transparency/stfe/testdata"
+ "github.com/system-transparency/stfe/types"
+)
+
+func TestParseAddEntryV1Request(t *testing.T) {
+ lp := newLogParameters(t, nil)
+ for _, table := range []struct {
+ description string
+ breq *bytes.Buffer
+ wantErr bool
+ }{
+ {
+ description: "invalid: nothing to unpack",
+ breq: bytes.NewBuffer(nil),
+ wantErr: true,
+ },
+ {
+ description: "invalid: not a signed checksum entry",
+ breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness, &testdata.Ed25519VkWitness),
+ wantErr: true,
+ },
+ {
+ description: "invalid: untrusted submitter", // only testdata.Ed25519VkSubmitter is registered by default in newLogParameters()
+
+ breq: testdata.AddSignedChecksumBuffer(t, testdata.Ed25519SkSubmitter2, testdata.Ed25519VkSubmitter2),
+ wantErr: true,
+ },
+ {
+ description: "invalid: signature does not cover message",
+
+ breq: testdata.AddSignedChecksumBuffer(t, testdata.Ed25519SkSubmitter2, testdata.Ed25519VkSubmitter),
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ breq: testdata.AddSignedChecksumBuffer(t, testdata.Ed25519SkSubmitter, testdata.Ed25519VkSubmitter),
+ },
+ } {
+ url := EndpointAddEntry.Path("http://example.com", lp.Prefix)
+ req, err := http.NewRequest("POST", url, table.breq)
+ if err != nil {
+ t.Fatalf("failed creating http request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ _, err = lp.parseAddEntryV1Request(req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got errror %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ }
+}
+
+func TestParseAddCosignatureV1Request(t *testing.T) {
+ lp := newLogParameters(t, nil)
+ for _, table := range []struct {
+ description string
+ breq *bytes.Buffer
+ wantErr bool
+ }{
+ {
+ description: "invalid: nothing to unpack",
+ breq: bytes.NewBuffer(nil),
+ wantErr: true,
+ },
+ {
+ description: "invalid: not a cosigned sth",
+ breq: testdata.AddSignedChecksumBuffer(t, testdata.Ed25519SkSubmitter, testdata.Ed25519VkSubmitter),
+ wantErr: true,
+ },
+ {
+ description: "invalid: no cosignature",
+ breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness, nil),
+ wantErr: true,
+ },
+ {
+ description: "invalid: untrusted witness", // only testdata.Ed25519VkWitness is registered by default in newLogParameters()
+ breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness2, &testdata.Ed25519VkWitness2),
+ wantErr: true,
+ },
+ {
+ description: "invalid: signature does not cover message",
+ breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness2, &testdata.Ed25519VkWitness),
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness, &testdata.Ed25519VkWitness),
+ },
+ } {
+ url := EndpointAddCosignature.Path("http://example.com", lp.Prefix)
+ req, err := http.NewRequest("POST", url, table.breq)
+ if err != nil {
+ t.Fatalf("failed creating http request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ _, err = lp.parseAddCosignatureV1Request(req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got errror %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ }
+}
+
+func TestNewGetConsistencyProofRequest(t *testing.T) {
+ lp := newLogParameters(t, nil)
+ for _, table := range []struct {
+ description string
+ req *types.GetConsistencyProofV1
+ wantErr bool
+ }{
+ {
+ description: "invalid: nothing to unpack",
+ req: nil,
+ wantErr: true,
+ },
+ {
+ description: "invalid: first must be larger than zero",
+ req: &types.GetConsistencyProofV1{First: 0, Second: 0},
+ wantErr: true,
+ },
+ {
+ description: "invalid: second must be larger than first",
+ req: &types.GetConsistencyProofV1{First: 2, Second: 1},
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ req: &types.GetConsistencyProofV1{First: 1, Second: 2},
+ },
+ } {
+ var buf *bytes.Buffer
+ if table.req == nil {
+ buf = bytes.NewBuffer(nil)
+ } else {
+ buf = bytes.NewBuffer(marshal(t, *table.req))
+ }
+
+ url := EndpointGetConsistencyProof.Path("http://example.com", lp.Prefix)
+ req, err := http.NewRequest("POST", url, buf)
+ if err != nil {
+ t.Fatalf("failed creating http request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ _, err = lp.parseGetConsistencyProofV1Request(req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got errror %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ }
+}
+
+func TestNewGetProofByHashRequest(t *testing.T) {
+ lp := newLogParameters(t, nil)
+ for _, table := range []struct {
+ description string
+ req *types.GetProofByHashV1
+ wantErr bool
+ }{
+ {
+ description: "invalid: nothing to unpack",
+ req: nil,
+ wantErr: true,
+ },
+ {
+ description: "invalid: no entry in an empty tree",
+ req: &types.GetProofByHashV1{TreeSize: 0, Hash: testdata.LeafHash},
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ req: &types.GetProofByHashV1{TreeSize: 1, Hash: testdata.LeafHash},
+ },
+ } {
+ var buf *bytes.Buffer
+ if table.req == nil {
+ buf = bytes.NewBuffer(nil)
+ } else {
+ buf = bytes.NewBuffer(marshal(t, *table.req))
+ }
+
+ url := EndpointGetProofByHash.Path("http://example.com", lp.Prefix)
+ req, err := http.NewRequest("POST", url, buf)
+ if err != nil {
+ t.Fatalf("failed creating http request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ _, err = lp.parseGetProofByHashV1Request(req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got errror %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ }
+}
+
+func TestParseGetEntriesV1Request(t *testing.T) {
+ lp := newLogParameters(t, nil)
+ for _, table := range []struct {
+ description string
+ req *types.GetEntriesV1
+ wantErr bool
+ wantReq *types.GetEntriesV1
+ }{
+ {
+ description: "invalid: nothing to unpack",
+ req: nil,
+ wantErr: true,
+ },
+ {
+ description: "invalid: start must be larger than end",
+ req: &types.GetEntriesV1{Start: 1, End: 0},
+ wantErr: true,
+ },
+ {
+ description: "valid: want truncated range",
+ req: &types.GetEntriesV1{Start: 0, End: uint64(testdata.MaxRange)},
+ wantReq: &types.GetEntriesV1{Start: 0, End: uint64(testdata.MaxRange) - 1},
+ },
+ {
+ description: "valid",
+ req: &types.GetEntriesV1{Start: 0, End: 0},
+ wantReq: &types.GetEntriesV1{Start: 0, End: 0},
+ },
+ } {
+ var buf *bytes.Buffer
+ if table.req == nil {
+ buf = bytes.NewBuffer(nil)
+ } else {
+ buf = bytes.NewBuffer(marshal(t, *table.req))
+ }
+
+ url := EndpointGetEntries.Path("http://example.com", lp.Prefix)
+ req, err := http.NewRequest("POST", url, buf)
+ if err != nil {
+ t.Fatalf("failed creating http request: %v", err)
+ }
+ req.Header.Set("Content-Type", "application/octet-stream")
+
+ output, err := lp.parseGetEntriesV1Request(req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got errror %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ if err != nil {
+ continue
+ }
+ if got, want := output, table.wantReq; !reflect.DeepEqual(got, want) {
+ t.Errorf("got request\n%v\n\tbut wanted\n%v\n\t in test %q", got, want, table.description)
+ }
+ }
+}
+
+func TestUnpackOctetPost(t *testing.T) {
+ for _, table := range []struct {
+ description string
+ req *http.Request
+ out interface{}
+ wantErr bool
+ }{
+ {
+ description: "invalid: cannot read request body",
+ req: func() *http.Request {
+ req, err := http.NewRequest(http.MethodPost, "", iotest.ErrReader(fmt.Errorf("bad reader")))
+ if err != nil {
+ t.Fatalf("must make new http request: %v", err)
+ }
+ return req
+ }(),
+ out: &types.StItem{},
+ wantErr: true,
+ },
+ {
+ description: "invalid: cannot unmarshal",
+ req: func() *http.Request {
+ req, err := http.NewRequest(http.MethodPost, "", bytes.NewBuffer(nil))
+ if err != nil {
+ t.Fatalf("must make new http request: %v", err)
+ }
+ return req
+ }(),
+ out: &types.StItem{},
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ req: func() *http.Request {
+ req, err := http.NewRequest(http.MethodPost, "", bytes.NewBuffer([]byte{0}))
+ if err != nil {
+ t.Fatalf("must make new http request: %v", err)
+ }
+ return req
+ }(),
+ out: &struct{ SomeUint8 uint8 }{},
+ },
+ } {
+ err := unpackOctetPost(table.req, table.out)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got error %v but wanted %v in test %q", got, want, table.description)
+ }
+ }
+}
+
+func marshal(t *testing.T, out interface{}) []byte {
+ b, err := types.Marshal(out)
+ if err != nil {
+ t.Fatalf("must marshal: %v", err)
+ }
+ return b
+}