aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-03-15 20:18:29 +0100
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-03-15 20:18:29 +0100
commite2959d506de6067afe494315c3621b33613b5414 (patch)
treedb51eb9917760717156f8e9cfebccdd6e1d51a1c
parent864031a77981d970f7e3fd89380a7bdb42d70d33 (diff)
added option to run with unregistered namespaces
Also a few minor fixes such that server binary starts again.
-rw-r--r--instance.go11
-rw-r--r--instance_test.go4
-rw-r--r--log_parameters.go56
-rw-r--r--log_parameters_test.go7
-rw-r--r--request.go29
-rw-r--r--request_test.go4
-rw-r--r--server/main.go24
7 files changed, 83 insertions, 52 deletions
diff --git a/instance.go b/instance.go
index 6f1314b..67336f8 100644
--- a/instance.go
+++ b/instance.go
@@ -41,16 +41,21 @@ type Handler struct {
Handler func(context.Context, *Instance, http.ResponseWriter, *http.Request) (int, error)
}
+// Path returns a path that should be configured for this handler
+func (h Handler) Path() string {
+ return h.Endpoint.Path("", h.Instance.LogParameters.Prefix)
+}
+
// ServeHTTP is part of the http.Handler interface
func (a Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// export prometheus metrics
var now time.Time = time.Now()
var statusCode int
defer func() {
- rspcnt.Inc(string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint), fmt.Sprintf("%d", statusCode))
- latency.Observe(time.Now().Sub(now).Seconds(), string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint), fmt.Sprintf("%d", statusCode))
+ rspcnt.Inc(a.Instance.LogParameters.LogIdStr, string(a.Endpoint), fmt.Sprintf("%d", statusCode))
+ latency.Observe(time.Now().Sub(now).Seconds(), a.Instance.LogParameters.LogIdStr, string(a.Endpoint), fmt.Sprintf("%d", statusCode))
}()
- reqcnt.Inc(string(a.Instance.LogParameters.LogIdBytes), string(a.Endpoint))
+ reqcnt.Inc(a.Instance.LogParameters.LogIdStr, string(a.Endpoint))
ctx, cancel := context.WithDeadline(r.Context(), now.Add(a.Instance.LogParameters.Deadline))
defer cancel()
diff --git a/instance_test.go b/instance_test.go
index 21ef808..de539a1 100644
--- a/instance_test.go
+++ b/instance_test.go
@@ -153,3 +153,7 @@ func TestPostHandlersRejectGet(t *testing.T) {
})
}
}
+
+// TODO: TestHandlerPath
+func TestHandlerPath(t *testing.T) {
+}
diff --git a/log_parameters.go b/log_parameters.go
index 86ac0cc..9c23fa6 100644
--- a/log_parameters.go
+++ b/log_parameters.go
@@ -12,37 +12,43 @@ import (
// LogParameters is a collection of log parameters
type LogParameters struct {
- LogId *types.Namespace // log identifier
- LogIdBytes []byte // serialized log id
- TreeId int64 // used internally by Trillian
- Prefix string // e.g., "test" for <base>/test
- MaxRange int64 // max entries per get-entries request
- Submitters *types.NamespacePool // trusted submitters
- Witnesses *types.NamespacePool // trusted witnesses
- Deadline time.Duration // gRPC deadline
- Interval time.Duration // cosigning sth frequency
- HashType crypto.Hash // hash function used by Trillian
- Signer crypto.Signer // access to Ed25519 private key
+ LogId *types.Namespace // log identifier
+ LogIdBytes []byte // serialized log id
+ LogIdStr string // serialized log id (hex)
+ TreeId int64 // used internally by Trillian
+ Prefix string // e.g., "test" for <base>/test
+ MaxRange int64 // max entries per get-entries request
+ SubmitterPolicy bool // if we have a submitter policy (true means that namespaces must be registered)
+ WitnessPolicy bool // if we have a witness policy (true means that namespaces must be registered)
+ Submitters *types.NamespacePool // trusted submitters
+ Witnesses *types.NamespacePool // trusted witnesses
+ Deadline time.Duration // gRPC deadline
+ Interval time.Duration // cosigning sth frequency
+ HashType crypto.Hash // hash function used by Trillian
+ Signer crypto.Signer // access to Ed25519 private key
}
// NewLogParameters creates newly initialized log parameters
-func NewLogParameters(signer crypto.Signer, logId *types.Namespace, treeId int64, prefix string, submitters, witnesses *types.NamespacePool, maxRange int64, interval, deadline time.Duration) (*LogParameters, error) {
+func NewLogParameters(signer crypto.Signer, logId *types.Namespace, treeId int64, prefix string, submitters, witnesses *types.NamespacePool, maxRange int64, interval, deadline time.Duration, submitterPolicy, witnessPolicy bool) (*LogParameters, error) {
logIdBytes, err := types.Marshal(*logId)
if err != nil {
return nil, fmt.Errorf("Marshal failed for log identifier: %v", err)
}
return &LogParameters{
- LogId: logId,
- TreeId: treeId,
- Prefix: prefix,
- MaxRange: maxRange,
- Submitters: submitters,
- Witnesses: witnesses,
- Deadline: deadline,
- Interval: interval,
- HashType: crypto.SHA256,
- Signer: signer,
- LogIdBytes: logIdBytes,
+ LogId: logId,
+ LogIdBytes: logIdBytes,
+ LogIdStr: fmt.Sprintf("%x", logIdBytes),
+ TreeId: treeId,
+ Prefix: prefix,
+ MaxRange: maxRange,
+ SubmitterPolicy: submitterPolicy,
+ WitnessPolicy: witnessPolicy,
+ Submitters: submitters,
+ Witnesses: witnesses,
+ Deadline: deadline,
+ Interval: interval,
+ HashType: crypto.SHA256,
+ Signer: signer,
}, nil
}
@@ -56,8 +62,8 @@ func (lp *LogParameters) SignTreeHeadV1(th *types.TreeHeadV1) (*types.StItem, er
if err != nil {
return nil, fmt.Errorf("Sign failed: %v", err)
}
- lastSthTimestamp.Set(float64(time.Now().Unix()), string(lp.LogIdBytes))
- lastSthSize.Set(float64(th.TreeSize), string(lp.LogIdBytes))
+ lastSthTimestamp.Set(float64(time.Now().Unix()), lp.LogIdStr)
+ lastSthSize.Set(float64(th.TreeSize), lp.LogIdStr)
return &types.StItem{
Format: types.StFormatSignedTreeHeadV1,
SignedTreeHeadV1: &types.SignedTreeHeadV1{
diff --git a/log_parameters_test.go b/log_parameters_test.go
index cec7674..88e83ad 100644
--- a/log_parameters_test.go
+++ b/log_parameters_test.go
@@ -15,7 +15,8 @@ import (
// based on the parameters in "github.com/system-transparency/stfe/testdata".
// The log's namespace is initialized with testdata.LogEd25519Vk, the submmiter
// namespace list is initialized with testdata.SubmmiterEd25519, and the witness
-// namespace list is initialized with testdata.WitnessEd25519Vk.
+// namespace list is initialized with testdata.WitnessEd25519Vk. The log's
+// submitter and witness policies are set to reject unregistered namespace.
func newLogParameters(t *testing.T, signer crypto.Signer) *LogParameters {
t.Helper()
logId := testdata.NewNamespace(t, testdata.Ed25519VkLog)
@@ -25,7 +26,7 @@ func newLogParameters(t *testing.T, signer crypto.Signer) *LogParameters {
submitPool := testdata.NewNamespacePool(t, []*types.Namespace{
testdata.NewNamespace(t, testdata.Ed25519VkSubmitter),
})
- lp, err := NewLogParameters(signer, logId, testdata.TreeId, testdata.Prefix, submitPool, witnessPool, testdata.MaxRange, testdata.Interval, testdata.Deadline)
+ lp, err := NewLogParameters(signer, logId, testdata.TreeId, testdata.Prefix, submitPool, witnessPool, testdata.MaxRange, testdata.Interval, testdata.Deadline, true, true)
if err != nil {
t.Fatalf("must create new log parameters: %v", err)
}
@@ -50,7 +51,7 @@ func TestNewLogParameters(t *testing.T) {
logId: testdata.NewNamespace(t, testdata.Ed25519VkLog),
},
} {
- _, err := NewLogParameters(nil, table.logId, testdata.TreeId, testdata.Prefix, nil, nil, testdata.MaxRange, testdata.Interval, testdata.Deadline)
+ _, err := NewLogParameters(nil, table.logId, testdata.TreeId, testdata.Prefix, nil, nil, testdata.MaxRange, testdata.Interval, testdata.Deadline, true, true)
if got, want := err != nil, table.wantErr; got != want {
t.Errorf("got error %v but wanted %v in test %q: %v", got, want, table.description, err)
}
diff --git a/request.go b/request.go
index 5bee672..7c95f34 100644
--- a/request.go
+++ b/request.go
@@ -19,9 +19,15 @@ func (lp *LogParameters) parseAddEntryV1Request(r *http.Request) (*types.StItem,
}
// Check that submitter namespace is valid
- if namespace, ok := lp.Submitters.Find(&item.SignedChecksumV1.Signature.Namespace); !ok {
- return nil, fmt.Errorf("unknown namespace: %v", item.SignedChecksumV1.Signature.Namespace)
- } else if msg, err := types.Marshal(item.SignedChecksumV1.Data); err != nil {
+ namespace := &item.SignedChecksumV1.Signature.Namespace
+ if lp.SubmitterPolicy {
+ var ok bool
+ if namespace, ok = lp.Submitters.Find(namespace); !ok {
+ return nil, fmt.Errorf("unknown submitter namespace: %v", namespace)
+ }
+ }
+ // Check that namespace signed add-entry request
+ if msg, err := types.Marshal(item.SignedChecksumV1.Data); err != nil {
return nil, fmt.Errorf("Marshal: %v", err) // should never happen
} else if err := namespace.Verify(msg, item.SignedChecksumV1.Signature.Signature); err != nil {
return nil, fmt.Errorf("Verify: %v", err)
@@ -37,13 +43,20 @@ func (lp *LogParameters) parseAddCosignatureV1Request(r *http.Request) (*types.S
if item.Format != types.StFormatCosignedTreeHeadV1 {
return nil, fmt.Errorf("invalid StItem format: %v", item.Format)
}
-
- // Check that witness namespace is valid
if got, want := len(item.CosignedTreeHeadV1.Cosignatures), 1; got != want {
return nil, fmt.Errorf("invalid number of cosignatures: %d", got)
- } else if namespace, ok := lp.Witnesses.Find(&item.CosignedTreeHeadV1.Cosignatures[0].Namespace); !ok {
- return nil, fmt.Errorf("unknown witness: %v", item.CosignedTreeHeadV1.Cosignatures[0].Namespace)
- } else if msg, err := types.Marshal(*types.NewSignedTreeHeadV1(&item.CosignedTreeHeadV1.SignedTreeHead.TreeHead, &item.CosignedTreeHeadV1.SignedTreeHead.Signature).SignedTreeHeadV1); err != nil {
+ }
+
+ // Check that witness namespace is valid
+ namespace := &item.CosignedTreeHeadV1.Cosignatures[0].Namespace
+ if lp.WitnessPolicy {
+ var ok bool
+ if namespace, ok = lp.Witnesses.Find(namespace); !ok {
+ return nil, fmt.Errorf("unknown witness namespace: %v", namespace)
+ }
+ }
+ // Check that namespace signed add-cosignature request
+ if msg, err := types.Marshal(*types.NewSignedTreeHeadV1(&item.CosignedTreeHeadV1.SignedTreeHead.TreeHead, &item.CosignedTreeHeadV1.SignedTreeHead.Signature).SignedTreeHeadV1); err != nil {
return nil, fmt.Errorf("Marshal: %v", err) // should never happen
} else if err := namespace.Verify(msg, item.CosignedTreeHeadV1.Cosignatures[0].Signature); err != nil {
return nil, fmt.Errorf("Verify: %v", err)
diff --git a/request_test.go b/request_test.go
index b0e5da1..0bf68ad 100644
--- a/request_test.go
+++ b/request_test.go
@@ -45,7 +45,7 @@ func TestParseAddEntryV1Request(t *testing.T) {
{
description: "valid",
breq: testdata.AddSignedChecksumBuffer(t, testdata.Ed25519SkSubmitter, testdata.Ed25519VkSubmitter),
- },
+ }, // TODO: add test case that disables submitter policy (i.e., unregistered namespaces are accepted)
} {
url := EndpointAddEntry.Path("http://example.com", lp.Prefix)
req, err := http.NewRequest("POST", url, table.breq)
@@ -96,7 +96,7 @@ func TestParseAddCosignatureV1Request(t *testing.T) {
{
description: "valid",
breq: testdata.AddCosignatureBuffer(t, testdata.DefaultSth(t, testdata.Ed25519VkLog), &testdata.Ed25519SkWitness, &testdata.Ed25519VkWitness),
- },
+ }, // TODO: add test case that disables witness policy (i.e., unregistered namespaces are accepted)
} {
url := EndpointAddCosignature.Path("http://example.com", lp.Prefix)
req, err := http.NewRequest("POST", url, table.breq)
diff --git a/server/main.go b/server/main.go
index a00758e..d45079b 100644
--- a/server/main.go
+++ b/server/main.go
@@ -25,16 +25,18 @@ import (
)
var (
- httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients")
- rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients")
- prefix = flag.String("prefix", "st/v1", "a prefix that proceeds each endpoint path")
- trillianID = flag.Int64("trillian_id", 5991359069696313945, "log identifier in the Trillian database")
- deadline = flag.Duration("deadline", time.Second*10, "deadline for backend requests")
- key = flag.String("key", "8gzezwrU/2eTrO6tEYyLKsoqn5V54URvKIL9cTE7jUYUqXVX4neJvcBq/zpSAYPsZFG1woh0OGBzQbi9UP9MZw==", "base64-encoded Ed25519 signing key")
- submitters = flag.String("submitters", "AAEgHOQFUkKNWpjYAhNKTyWCzahlI7RDtf5123kHD2LACj0=,AAEgLqrWb9JwQUTk/SwTNDdMH8aRmy3mbmhwEepO5WSgb+A=", "comma-separated list of trusted submitter namespaces in base64 (default: testdata.Ed25519{Vk,Vk2})") // TODO: update to valid submitter namespaces
- witnesses = flag.String("witnesses", "", "comma-separated list of trusted submitter namespaces in base64 (default: none") // TODO: update to valid witness namespaces
- maxRange = flag.Int64("max_range", 2, "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")
+ httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients")
+ rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients")
+ prefix = flag.String("prefix", "st/v1", "a prefix that proceeds each endpoint path")
+ trillianID = flag.Int64("trillian_id", 5991359069696313945, "log identifier in the Trillian database")
+ deadline = flag.Duration("deadline", time.Second*10, "deadline for backend requests")
+ key = flag.String("key", "8gzezwrU/2eTrO6tEYyLKsoqn5V54URvKIL9cTE7jUYUqXVX4neJvcBq/zpSAYPsZFG1woh0OGBzQbi9UP9MZw==", "base64-encoded Ed25519 signing key")
+ submitterPolicy = flag.Bool("submitter_policy", false, "whether there is any submitter namespace policy (default: none, accept unregistered submitter namespaces)")
+ witnessPolicy = flag.Bool("witness_policy", false, "whether there is any witness namespace policy (default: none, accept unregistered witness namespaces)")
+ submitters = flag.String("submitters", "", "comma-separated list of trusted submitter namespaces in base64 (default: none)")
+ witnesses = flag.String("witnesses", "", "comma-separated list of trusted submitter namespaces in base64 (default: none)")
+ maxRange = flag.Int64("max_range", 2, "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")
)
func main() {
@@ -118,7 +120,7 @@ func setupInstanceFromFlags() (*stfe.Instance, error) {
return nil, fmt.Errorf("NewNamespaceEd25519V1: %v", err)
}
// Setup log parameters
- lp, err := stfe.NewLogParameters(signer, logId, *trillianID, *prefix, submitters, witnesses, *maxRange, *interval, *deadline)
+ lp, err := stfe.NewLogParameters(signer, logId, *trillianID, *prefix, submitters, witnesses, *maxRange, *interval, *deadline, *submitterPolicy, *witnessPolicy)
if err != nil {
return nil, fmt.Errorf("NewLogParameters: %v", err)
}