aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/descriptor/descriptor.go40
-rw-r--r--server/descriptor/descriptor_test.go96
-rw-r--r--server/descriptor/stfe.json18
3 files changed, 154 insertions, 0 deletions
diff --git a/server/descriptor/descriptor.go b/server/descriptor/descriptor.go
new file mode 100644
index 0000000..ba90289
--- /dev/null
+++ b/server/descriptor/descriptor.go
@@ -0,0 +1,40 @@
+package descriptor
+
+import (
+ "bytes"
+ "fmt"
+
+ "crypto/tls"
+ "encoding/base64"
+)
+
+const (
+ // Location is an url to a json-encoded list of stfe log operators
+ Location = "https://github.com/system-transparency/stfe/tree/main/server/descriptor/stfe.json"
+)
+
+// Operator is an stfe log operator that runs zero or more logs
+type Operator struct {
+ Name string `json:"name"`
+ Email string `json:"email"`
+ Logs []*Log `json:"logs"`
+}
+
+// Log is a collection of immutable stfe log parameters
+type Log struct {
+ Id []byte `json:"id"` // H(PublicKey)
+ PublicKey []byte `json:"public_key"` // DER-encoded SubjectPublicKeyInfo
+ Scheme tls.SignatureScheme `json:"signature_scheme"` // Signature schemes used by the log (RFC 8446, §4.2.3)
+ Schemes []tls.SignatureScheme `json:"signature_schemes"` // Signature schemes that submitters can use (RFC 8446, §4.2.3)
+ MaxChain uint8 `json:"max_chain"` // maximum certificate chain length
+ BaseUrl string `json:"base_url"` // E.g., example.com/st/v1
+}
+
+func (op *Operator) FindLog(logId []byte) (*Log, error) {
+ for _, log := range op.Logs {
+ if bytes.Equal(logId, log.Id) {
+ return log, nil
+ }
+ }
+ return nil, fmt.Errorf("no such log: %s", base64.StdEncoding.EncodeToString(logId))
+}
diff --git a/server/descriptor/descriptor_test.go b/server/descriptor/descriptor_test.go
new file mode 100644
index 0000000..e461f88
--- /dev/null
+++ b/server/descriptor/descriptor_test.go
@@ -0,0 +1,96 @@
+package descriptor
+
+import (
+ "fmt"
+ "testing"
+
+ "crypto/sha256"
+ "crypto/tls"
+ "encoding/base64"
+ "encoding/json"
+)
+
+const (
+ operatorListJson = `[{"name":"Test operator","email":"test@example.com","logs":[{"id":"B9oCJk4XIOMXba8dBM5yUj+NLtqTE6xHwbvR9dYkHPM=","public_key":"MCowBQYDK2VwAyEAqM4b/SHOCRId9xgiCPn8D8r6+Nrk9JTZZqW6vj7TGa0=","signature_scheme":2055,"signature_schemes":[2055],"max_chain":3,"base_url":"example.com/st/v1"}]}]`
+)
+
+func TestMarshal(t *testing.T) {
+ for _, table := range []struct {
+ in []Operator
+ want string
+ }{
+ {makeOperatorList(), operatorListJson},
+ } {
+ b, err := json.Marshal(table.in)
+ if err != nil {
+ t.Errorf("operator list marshaling failed: %v", err)
+ }
+ if string(b) != table.want {
+ t.Errorf("\nwant %s\n got %s", table.want, string(b))
+ }
+ }
+
+}
+
+func TestUnmarshal(t *testing.T) {
+ for _, table := range []struct {
+ in []byte
+ want error
+ }{
+ {[]byte(operatorListJson), nil},
+ } {
+ var op []Operator
+ if err := json.Unmarshal(table.in, &op); err != table.want {
+ t.Errorf("wanted err=%v, got %v", table.want, err)
+ }
+ }
+}
+
+func TestFindLog(t *testing.T) {
+ for _, table := range []struct {
+ op Operator
+ logId []byte
+ wantError bool
+ }{
+ {makeOperatorList()[0], deb64("B9oCJk4XIOMXba8dBM5yUj+NLtqTE6xHwbvR9dYkHPM="), false},
+ {makeOperatorList()[0], []byte{0, 1, 2, 3}, true},
+ } {
+ _, err := table.op.FindLog(table.logId)
+ if (err != nil) != table.wantError {
+ t.Errorf("wanted log not found for id: %v", table.logId)
+ }
+ }
+}
+
+func makeOperatorList() []Operator {
+ pub := deb64("MCowBQYDK2VwAyEAqM4b/SHOCRId9xgiCPn8D8r6+Nrk9JTZZqW6vj7TGa0=")
+ h := sha256.New()
+ h.Write(pub)
+ id := h.Sum(nil)
+ return []Operator{
+ Operator{
+ Name: "Test operator",
+ Email: "test@example.com",
+ Logs: []*Log{
+ &Log{
+ Id: id,
+ PublicKey: pub,
+ Scheme: tls.Ed25519,
+ Schemes: []tls.SignatureScheme{
+ tls.Ed25519,
+ },
+ MaxChain: 3,
+ BaseUrl: "example.com/st/v1",
+ },
+ },
+ },
+ }
+}
+
+func deb64(s string) []byte {
+ b, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ panic(fmt.Sprintf("failed decoding base64: %v", err))
+ }
+ return b
+}
diff --git a/server/descriptor/stfe.json b/server/descriptor/stfe.json
new file mode 100644
index 0000000..69e84a0
--- /dev/null
+++ b/server/descriptor/stfe.json
@@ -0,0 +1,18 @@
+[
+ {
+ "name": "Test operator",
+ "email": "test@example.com",
+ "logs": [
+ {
+ "max_chain": 3,
+ "log_id": "B9oCJk4XIOMXba8dBM5yUj+NLtqTE6xHwbvR9dYkHPM=",
+ "signature_schemes": [
+ 2055
+ ],
+ "base_url": "example.com/st/v1",
+ "signature_scheme": 2055,
+ "public_key": "MCowBQYDK2VwAyEAqM4b/SHOCRId9xgiCPn8D8r6+Nrk9JTZZqW6vj7TGa0="
+ }
+ ]
+ }
+]