diff options
Diffstat (limited to 'namespace/namespace_test.go')
-rw-r--r-- | namespace/namespace_test.go | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/namespace/namespace_test.go b/namespace/namespace_test.go new file mode 100644 index 0000000..10c0bf0 --- /dev/null +++ b/namespace/namespace_test.go @@ -0,0 +1,218 @@ +package namespace + +import ( + "bytes" + "testing" + + "crypto/ed25519" + + "github.com/system-transparency/stfe/namespace/testdata" +) + +func TestNewNamespaceEd25519V1(t *testing.T) { + for _, table := range []struct { + description string + vk []byte + wantErr bool + }{ + { + description: "invalid", + vk: append(testdata.Ed25519Vk, 0x00), + wantErr: true, + }, + { + description: "valid", + vk: testdata.Ed25519Vk, + }, + } { + n, err := NewNamespaceEd25519V1(table.vk) + 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) + } + if err != nil { + continue + } + if got, want := n.Format, NamespaceFormatEd25519V1; got != want { + t.Errorf("got namespace format %v but wanted %v in test %q", got, want, table.description) + continue + } + if got, want := n.NamespaceEd25519V1.Namespace, table.vk; !bytes.Equal(got, want) { + t.Errorf("got namespace %X but wanted %X in test %q", got, want, table.description) + } + } +} + +func TestVerify(t *testing.T) { + testMsg := []byte("msg") + for _, table := range []struct { + description string + namespace *Namespace + msg, sig []byte + wantErr bool + }{ + { + description: "invalid: unsupported namespace", + namespace: &Namespace{Format: NamespaceFormatReserved}, + msg: testMsg, + sig: []byte("sig"), + wantErr: true, + }, + { + description: "invalid: bad ed25519 verification key", + namespace: mustNewNamespaceEd25519V1(t, testdata.Ed25519Sk[:32]), + msg: testMsg, + sig: ed25519.Sign(ed25519.PrivateKey(testdata.Ed25519Sk), testMsg), + wantErr: true, + }, + { + description: "invalid: ed25519 signature is not over message", + namespace: mustNewNamespaceEd25519V1(t, testdata.Ed25519Vk), + msg: append(testMsg, 0x00), + sig: ed25519.Sign(ed25519.PrivateKey(testdata.Ed25519Sk), testMsg), + wantErr: true, + }, + { + description: "valid: ed25519", + namespace: mustNewNamespaceEd25519V1(t, testdata.Ed25519Vk), + msg: testMsg, + sig: ed25519.Sign(ed25519.PrivateKey(testdata.Ed25519Sk), testMsg), + }, + } { + err := table.namespace.Verify(table.msg, table.sig) + 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) + } + } +} + +func TestMarshal(t *testing.T) { + for _, table := range []struct { + description string + namespace *Namespace + wantErr bool + wantBytes []byte + }{ + { + description: "invalid ed25519: namespace size too small", + namespace: &Namespace{ + Format: NamespaceFormatEd25519V1, + NamespaceEd25519V1: &NamespaceEd25519V1{ + Namespace: testdata.Ed25519Vk[:len(testdata.Ed25519Vk)-1], + }, + }, + wantErr: true, + }, + { + description: "invalid ed25519: namespace size too large", + namespace: &Namespace{ + Format: NamespaceFormatEd25519V1, + NamespaceEd25519V1: &NamespaceEd25519V1{ + Namespace: append(testdata.Ed25519Vk, 0x00), + }, + }, + wantErr: true, + }, + { + description: "valid: ed25519", + namespace: mustNewNamespaceEd25519V1(t, testdata.Ed25519Vk), + // TODO: wantBytes + }, + } { + _, err := table.namespace.Marshal() + 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) + } + if err != nil { + continue + } + // TODO: add check that we got the bytes we wanted also + } +} + +func TestUnmarshal(t *testing.T) { + // TODO +} + +func TestNewNamespacePool(t *testing.T) { + ns1, _ := NewNamespaceEd25519V1(testdata.Ed25519Vk) + ns2, _ := NewNamespaceEd25519V1(make([]byte, 32)) + nsr := &Namespace{Format: NamespaceFormatReserved} + for _, table := range []struct { + description string + namespaces []*Namespace + wantErr bool + }{ + { + description: "invalid: duplicate namespace", + namespaces: []*Namespace{ns1, ns1, ns2}, + wantErr: true, + }, + { + description: "invalid: namespace without key", + namespaces: []*Namespace{ns1, nsr, ns2}, + wantErr: true, + }, + { + description: "valid: empty", + namespaces: []*Namespace{}, + }, + { + description: "valid: one namespace", + namespaces: []*Namespace{ns1}, + }, + { + description: "valid: two namespaces", + namespaces: []*Namespace{ns1, ns2}, + }, + } { + _, err := NewNamespacePool(table.namespaces) + 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) + } + } +} + +func TestFind(t *testing.T) { + ns1 := mustNewNamespaceEd25519V1(t, testdata.Ed25519Vk) + ns2 := mustNewNamespaceEd25519V1(t, make([]byte, 32)) + pool, _ := NewNamespacePool(nil) + _, got := pool.Find(ns1) + if want := false; got != want { + t.Errorf("got %v but wanted %v in test %q", got, want, "empty pool") + } + + pool, _ = NewNamespacePool([]*Namespace{ns1}) + _, got = pool.Find(ns1) + if want := true; got != want { + t.Errorf("got %v but wanted %v in test %q", got, want, "non-empty pool: looking for member") + } + _, got = pool.Find(ns2) + if want := false; got != want { + t.Errorf("got %v but wanted %v in test %q", got, want, "non-empty pool: looking for non-member") + } +} + +func TestList(t *testing.T) { + ns1 := mustNewNamespaceEd25519V1(t, testdata.Ed25519Vk) + ns2 := mustNewNamespaceEd25519V1(t, make([]byte, 32)) + namespaces := []*Namespace{ns1, ns2} + pool, _ := NewNamespacePool(namespaces) + l1 := pool.List() + if got, want := len(l1), len(namespaces); got != want { + t.Errorf("got len %v but wanted %v", got, want) + } + + l1[0] = ns2 + l2 := pool.List() + if bytes.Equal(l1[0].NamespaceEd25519V1.Namespace, l2[0].NamespaceEd25519V1.Namespace) { + t.Errorf("returned list is not a copy") + } +} + +func mustNewNamespaceEd25519V1(t *testing.T, vk []byte) *Namespace { + namespace, err := NewNamespaceEd25519V1(vk) + if err != nil { + t.Fatalf("must make ed25519 namespace: %v", err) + } + return namespace +} |