aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-09-27 23:29:05 +0200
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-09-27 23:31:42 +0200
commit621865f5707eaca22d4a0d162a5390b8440f6b40 (patch)
treecea907f137d29caddaba14884aec999aa51bdc20
parent0b0320d8f295394e2afc5f0cf012422e8625518b (diff)
added shard_hint enforcement
-rw-r--r--cmd/sigsum_log_go/main.go10
-rw-r--r--pkg/instance/endpoint_test.go80
-rw-r--r--pkg/instance/instance.go21
3 files changed, 77 insertions, 34 deletions
diff --git a/cmd/sigsum_log_go/main.go b/cmd/sigsum_log_go/main.go
index 786504d..13bb54d 100644
--- a/cmd/sigsum_log_go/main.go
+++ b/cmd/sigsum_log_go/main.go
@@ -37,6 +37,8 @@ var (
witnesses = flag.String("witnesses", "", "comma-separated list of trusted witness verification keys in hex")
maxRange = flag.Int64("max_range", 10, "maximum number of entries that can be retrived in a single request")
interval = flag.Duration("interval", time.Second*30, "interval used to rotate the log's cosigned STH")
+ shardStart = flag.Int64("shard_interval_start", 0, "start of shard interval since the UNIX epoch in seconds")
+ shardEnd = flag.Int64("shard_interval_end", 0, "end of shard interval since the UNIX epoch in seconds")
gitCommit = "unknown"
)
@@ -102,6 +104,14 @@ func setupInstanceFromFlags() (*sigsum.Instance, error) {
i.MaxRange = *maxRange
i.Deadline = *deadline
i.Interval = *interval
+ i.ShardStart = uint64(*shardStart)
+ if *shardStart < 0 {
+ return nil, fmt.Errorf("shard start must be larger than zero")
+ }
+ i.ShardEnd = uint64(*shardEnd)
+ if *shardEnd < *shardStart {
+ return nil, fmt.Errorf("shard end must be larger than shard start")
+ }
i.Witnesses, err = newWitnessMap(*witnesses)
if err != nil {
return nil, fmt.Errorf("newWitnessMap: %v", err)
diff --git a/pkg/instance/endpoint_test.go b/pkg/instance/endpoint_test.go
index 95b71d3..20f4ba3 100644
--- a/pkg/instance/endpoint_test.go
+++ b/pkg/instance/endpoint_test.go
@@ -18,12 +18,14 @@ import (
var (
testWitVK = [types.VerificationKeySize]byte{}
testConfig = Config{
- LogID: hex.EncodeToString(types.Hash([]byte("logid"))[:]),
- TreeID: 0,
- Prefix: "testonly",
- MaxRange: 3,
- Deadline: 10,
- Interval: 10,
+ LogID: hex.EncodeToString(types.Hash([]byte("logid"))[:]),
+ TreeID: 0,
+ Prefix: "testonly",
+ MaxRange: 3,
+ Deadline: 10,
+ Interval: 10,
+ ShardStart: 10,
+ ShardEnd: 20,
Witnesses: map[[types.HashSize]byte][types.VerificationKeySize]byte{
*types.Hash(testWitVK[:]): testWitVK,
},
@@ -58,14 +60,14 @@ func mustHandle(t *testing.T, i Instance, e types.Endpoint) Handler {
}
func TestAddLeaf(t *testing.T) {
- buf := func() io.Reader {
+ buf := func(shard uint64, sum, sig, vf string) io.Reader {
// A valid leaf request that was created manually
return bytes.NewBufferString(fmt.Sprintf(
- "%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s",
- types.ShardHint, types.Delim, "0", types.EOL,
- types.Checksum, types.Delim, "0000000000000000000000000000000000000000000000000000000000000000", types.EOL,
- types.Signature, types.Delim, "4cb410a4d48f52f761a7c01abcc28fd71811b84ded5403caed5e21b374f6aac9637cecd36828f17529fd503413d30ab66d7bb37a31dbf09a90d23b9241c45009", types.EOL,
- types.VerificationKey, types.Delim, "f2b7a00b625469d32502e06e8b7fad1ef258d4ad0c6cd87b846142ab681957d5", types.EOL,
+ "%s%s%d%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s",
+ types.ShardHint, types.Delim, shard, types.EOL,
+ types.Checksum, types.Delim, sum, types.EOL,
+ types.Signature, types.Delim, sig, types.EOL,
+ types.VerificationKey, types.Delim, vf, types.EOL,
types.DomainHint, types.Delim, "example.com", types.EOL,
))
}
@@ -76,6 +78,7 @@ func TestAddLeaf(t *testing.T) {
err error // error from Trillian client
wantCode int // HTTP status ok
}{
+ // XXX introduce helper so that test params are not hardcoded
{
description: "invalid: bad request (parser error)",
ascii: bytes.NewBufferString("key=value\n"),
@@ -83,28 +86,51 @@ func TestAddLeaf(t *testing.T) {
},
{
description: "invalid: bad request (signature error)",
- ascii: bytes.NewBufferString(fmt.Sprintf(
- "%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s"+"%s%s%s%s",
- types.ShardHint, types.Delim, "1", types.EOL,
- types.Checksum, types.Delim, "1111111111111111111111111111111111111111111111111111111111111111", types.EOL,
- types.Signature, types.Delim, "4cb410a4d48f52f761a7c01abcc28fd71811b84ded5403caed5e21b374f6aac9637cecd36828f17529fd503413d30ab66d7bb37a31dbf09a90d23b9241c45009", types.EOL,
- types.VerificationKey, types.Delim, "f2b7a00b625469d32502e06e8b7fad1ef258d4ad0c6cd87b846142ab681957d5", types.EOL,
- types.DomainHint, types.Delim, "example.com", types.EOL,
- )),
+ ascii: buf(10,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
+ "f6eef8e94ddf1396682871257e670a1d9b627cf460daade7c36d218b2866befb",
+ ),
+ wantCode: http.StatusBadRequest,
+ },
+ {
+ description: "invalid: bad request (shard hint is before shard start)",
+ ascii: buf(9,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "20876ac8bf2c32d0c7f9b51b57f2de2f454c82c6b189ee30d5275361b657299b3e4e4d677646ec2586927a5a015ad349ae1ca4440e1bf6efbec875144d3a4009",
+ "a70f95f1739834190ec9a2a2fcee8ba8e70eddeb825c9856edfb2d8c5dfda595",
+ ),
+ wantCode: http.StatusBadRequest,
+ },
+ {
+ description: "invalid: bad request (shard hint is before shard start)",
+ ascii: buf(21,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "79c14f0ad9ab24ab98fe9d5ff59c3b91348789758aa092c6bfab2ac8890b41fb1d44d985e723184f9de42edb82b5ada14f494a96e361914d5366dd92379a1d04",
+ "91347ef525e149765225d1341ae2e07ce0f2256a44ae20f04f143f11285c8031",
+ ),
wantCode: http.StatusBadRequest,
},
{
description: "invalid: backend failure",
- ascii: buf(),
- expect: true,
- err: fmt.Errorf("something went wrong"),
- wantCode: http.StatusInternalServerError,
+ ascii: buf(10,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "7df253d2578c6c20b90832245ad6f981077454667796b3d507336a89ee878a2eae6b96e6d8de84fe8c1acf4b3aaffd482b657b65d94ed5e6be6320492147f90c",
+ "f6eef8e94ddf1396682871257e670a1d9b627cf460daade7c36d218b2866befb",
+ ),
+ expect: true,
+ err: fmt.Errorf("something went wrong"),
+ wantCode: http.StatusInternalServerError,
},
{
description: "valid",
- ascii: buf(),
- expect: true,
- wantCode: http.StatusOK,
+ ascii: buf(10,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "7df253d2578c6c20b90832245ad6f981077454667796b3d507336a89ee878a2eae6b96e6d8de84fe8c1acf4b3aaffd482b657b65d94ed5e6be6320492147f90c",
+ "f6eef8e94ddf1396682871257e670a1d9b627cf460daade7c36d218b2866befb",
+ ),
+ expect: true,
+ wantCode: http.StatusOK,
},
} {
// Run deferred functions at the end of each iteration
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go
index 809349c..2f5dd4c 100644
--- a/pkg/instance/instance.go
+++ b/pkg/instance/instance.go
@@ -16,12 +16,14 @@ import (
// Config is a collection of log parameters
type Config struct {
- LogID string // H(public key), then hex-encoded
- TreeID int64 // Merkle tree identifier used by Trillian
- Prefix string // The portion between base URL and st/v0 (may be "")
- MaxRange int64 // Maximum number of leaves per get-leaves request
- Deadline time.Duration // Deadline used for gRPC requests
- Interval time.Duration // Cosigning frequency
+ LogID string // H(public key), then hex-encoded
+ TreeID int64 // Merkle tree identifier used by Trillian
+ Prefix string // The portion between base URL and st/v0 (may be "")
+ MaxRange int64 // Maximum number of leaves per get-leaves request
+ Deadline time.Duration // Deadline used for gRPC requests
+ Interval time.Duration // Cosigning frequency
+ ShardStart uint64 // Shard interval start (num seconds since UNIX epoch)
+ ShardEnd uint64 // Shard interval end (num seconds since UNIX epoch)
// Witnesses map trusted witness identifiers to public verification keys
Witnesses map[[types.HashSize]byte][types.VerificationKeySize]byte
@@ -102,7 +104,12 @@ func (i *Instance) leafRequestFromHTTP(r *http.Request) (*types.LeafRequest, err
if !ed25519.Verify(vk, msg, sig) {
return nil, fmt.Errorf("invalid signature")
}
- // TODO: check shard hint
+ if req.ShardHint < i.ShardStart {
+ return nil, fmt.Errorf("invalid shard hint: %d not in [%d, %d]", req.ShardHint, i.ShardStart, i.ShardEnd)
+ }
+ if req.ShardHint > i.ShardEnd {
+ return nil, fmt.Errorf("invalid shard hint: %d not in [%d, %d]", req.ShardHint, i.ShardStart, i.ShardEnd)
+ }
// TODO: check domain hint
return &req, nil
}