diff options
Diffstat (limited to 'types')
-rw-r--r-- | types/cmd/new-namespace/main.go | 56 | ||||
-rw-r--r-- | types/namespace.go | 91 | ||||
-rw-r--r-- | types/namespace_pool.go | 69 | ||||
-rw-r--r-- | types/namespace_pool_test.go | 91 | ||||
-rw-r--r-- | types/namespace_test.go | 200 | ||||
-rw-r--r-- | types/serialize.go | 50 | ||||
-rw-r--r-- | types/serialize_test.go | 736 | ||||
-rw-r--r-- | types/stitem.go | 192 | ||||
-rw-r--r-- | types/stitem_test.go | 64 |
9 files changed, 0 insertions, 1549 deletions
diff --git a/types/cmd/new-namespace/main.go b/types/cmd/new-namespace/main.go deleted file mode 100644 index e338d7c..0000000 --- a/types/cmd/new-namespace/main.go +++ /dev/null @@ -1,56 +0,0 @@ -// Package main outputs the private and public parts of a new namespace -package main - -import ( - "flag" - "fmt" - - "crypto/ed25519" - "crypto/rand" - "encoding/base64" - - "github.com/golang/glog" - "github.com/system-transparency/stfe/types" -) - -var ( - format = flag.String("format", string(types.NamespaceFormatEd25519V1), "namespace format") -) - -func main() { - flag.Parse() - defer glog.Flush() - - switch *format { - case string(types.NamespaceFormatEd25519V1): - glog.Infof("generating new ed25519_v1 namespace") - sk, vk, namespace, err := genEd25519V1Namespace() - if err != nil { - glog.Errorf("genEd25519V1Namespace: %v", err) - break - } - fmt.Printf("sk: %s\n", base64.StdEncoding.EncodeToString(sk)) - fmt.Printf("vk: %s\n", base64.StdEncoding.EncodeToString(vk)) - fmt.Printf("ed25519_v1: %s\n", base64.StdEncoding.EncodeToString(namespace)) - default: - glog.Errorf("unsupported namespace format: %s", format) - } -} - -// genEd25519V1Namespace generates an Ed25519 secret key, verification key, and -// serialized ed25519_v1 namespace. -func genEd25519V1Namespace() ([]byte, []byte, []byte, error) { - vk, sk, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, nil, nil, fmt.Errorf("ed25519.GenerateKey: %v", err) - } - namespace, err := types.NewNamespaceEd25519V1(vk[:]) - if err != nil { - return nil, nil, nil, fmt.Errorf("types.NewNamespaceEd25519V1: %v", err) - } - serialized, err := types.Marshal(*namespace) - if err != nil { - fmt.Errorf("types.Marshal: %v", err) - } - return sk, vk, serialized, nil -} diff --git a/types/namespace.go b/types/namespace.go deleted file mode 100644 index 376ebcd..0000000 --- a/types/namespace.go +++ /dev/null @@ -1,91 +0,0 @@ -package types - -import ( - "fmt" - - "crypto/ed25519" - - "github.com/google/certificate-transparency-go/tls" -) - -// NamespaceFormat defines a particular namespace type that is versioend -type NamespaceFormat tls.Enum - -const ( - NamespaceFormatReserved NamespaceFormat = 0 - NamespaceFormatEd25519V1 NamespaceFormat = 1 - - NamespaceFingerprintSize = 32 -) - -// Namespace references a versioned namespace based on a given format specifier -type Namespace struct { - Format NamespaceFormat `tls:"maxval:65535"` - Ed25519V1 *Ed25519V1 `tls:"selector:Format,val:1"` -} - -// Ed25519V1 uses an Ed25519 verification key as namespace. Encoding, -// signing, and verification operations are defined by RFC 8032. -type Ed25519V1 struct { - Namespace [32]byte -} - -func (f NamespaceFormat) String() string { - switch f { - case NamespaceFormatReserved: - return "reserved" - case NamespaceFormatEd25519V1: - return "ed25519_v1" - default: - return fmt.Sprintf("unknown NamespaceFormat: %d", f) - } -} - -func (n Namespace) String() string { - switch n.Format { - case NamespaceFormatReserved: - return fmt.Sprintf("Format(%s)", n.Format) - case NamespaceFormatEd25519V1: - return fmt.Sprintf("Format(%s): %+v", n.Format, n.Ed25519V1) - default: - return fmt.Sprintf("unknown Namespace: %v", n.Format) - } -} - -// Fingerprint returns a fixed-size namespace fingerprint that is unique. -func (n *Namespace) Fingerprint() (*[NamespaceFingerprintSize]byte, error) { - switch n.Format { - case NamespaceFormatEd25519V1: - return &n.Ed25519V1.Namespace, nil - default: - return nil, fmt.Errorf("unsupported NamespaceFormat: %v", n.Format) - } -} - -// Verify checks that signature is valid over message for this namespace -func (ns *Namespace) Verify(message, signature []byte) error { - switch ns.Format { - case NamespaceFormatEd25519V1: - if !ed25519.Verify(ed25519.PublicKey(ns.Ed25519V1.Namespace[:]), message, signature) { - return fmt.Errorf("ed25519 signature verification failed") - } - default: - return fmt.Errorf("namespace not supported: %v", ns.Format) - } - return nil -} - -// NewNamespaceEd25519V1 returns an new Ed25519V1 namespace based on a -// verification key. -func NewNamespaceEd25519V1(vk []byte) (*Namespace, error) { - if len(vk) != 32 { - return nil, fmt.Errorf("invalid verification key: must be 32 bytes") - } - - var ed25519v1 Ed25519V1 - copy(ed25519v1.Namespace[:], vk) - return &Namespace{ - Format: NamespaceFormatEd25519V1, - Ed25519V1: &ed25519v1, - }, nil -} diff --git a/types/namespace_pool.go b/types/namespace_pool.go deleted file mode 100644 index 1e9e8f6..0000000 --- a/types/namespace_pool.go +++ /dev/null @@ -1,69 +0,0 @@ -package types - -import ( - "fmt" -) - -// NamespacePool is a pool of namespaces that contain complete verification keys -type NamespacePool struct { - pool map[[NamespaceFingerprintSize]byte]*Namespace - list []*Namespace - // If we need to update this structure without a restart => add mutex. -} - -// NewNameSpacePool creates a new namespace pool from a list of namespaces. An -// error is returned if there are duplicate namespaces or namespaces without a -// complete verification key. The latter is determined by namespaceWithKey(). -func NewNamespacePool(namespaces []*Namespace) (*NamespacePool, error) { - np := &NamespacePool{ - pool: make(map[[NamespaceFingerprintSize]byte]*Namespace), - list: make([]*Namespace, 0), - } - for _, namespace := range namespaces { - if !namespaceWithKey(namespace.Format) { - return nil, fmt.Errorf("need verification key in namespace pool: %v", namespace.Format) - } - fpr, err := namespace.Fingerprint() - if err != nil { - return nil, fmt.Errorf("need fingerprint in namespace pool: %v", err) - } - if _, ok := np.pool[*fpr]; ok { - return nil, fmt.Errorf("duplicate namespace: %v", namespace.String()) - } - np.pool[*fpr] = namespace - np.list = append(np.list, namespace) - } - return np, nil -} - -// Find checks if namespace is a member of the namespace pool. -func (np *NamespacePool) Find(namespace *Namespace) (*Namespace, bool) { - fpr, err := namespace.Fingerprint() - if err != nil { - return nil, false - } - if _, ok := np.pool[*fpr]; !ok { - return nil, false - } - // If the passed namespace is a key fingerprint the actual key needs to be - // attached before returning. Not applicable for Ed25519. Docdoc later. - return namespace, true -} - -// List returns a copied list of namespaces that is used by this pool. -func (np *NamespacePool) List() []*Namespace { - namespaces := make([]*Namespace, len(np.list)) - copy(namespaces, np.list) - return namespaces -} - -// namespaceWithKey returns true if a namespace format contains a complete -// verification key. I.e., some formats might have a key fingerprint instead. -func namespaceWithKey(format NamespaceFormat) bool { - switch format { - case NamespaceFormatEd25519V1: - return true - default: - return false - } -} diff --git a/types/namespace_pool_test.go b/types/namespace_pool_test.go deleted file mode 100644 index f5810a2..0000000 --- a/types/namespace_pool_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package types - -import ( - "bytes" - "reflect" - "testing" -) - -func TestNewNamespacePool(t *testing.T) { - ns1 := mustInitNamespaceEd25519V1(t, 0x00) - ns2 := mustInitNamespaceEd25519V1(t, 0xff) - 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 := mustInitNamespaceEd25519V1(t, 0x00) - ns2 := mustInitNamespaceEd25519V1(t, 0xff) - - // Empty pool - pool, err := NewNamespacePool(nil) - if err != nil { - t.Fatalf("must create new namespace pool: %v", err) - } - if _, ok := pool.Find(ns1); ok { - t.Errorf("found namespace in empty pool") - } - - // Pool with one namespace - pool, err = NewNamespacePool([]*Namespace{ns1}) - if err != nil { - t.Fatalf("must create new namespace pool: %v", err) - } - if ns, ok := pool.Find(ns1); !ok { - t.Errorf("could not find namespace that is a member of the pool") - } else if !reflect.DeepEqual(ns, ns1) { - t.Errorf("found namespace but it is wrong") - } - if _, ok := pool.Find(ns2); ok { - t.Errorf("found namespace although it is not a member of the pool") - } -} - -func TestList(t *testing.T) { - ns1 := mustInitNamespaceEd25519V1(t, 0x00) - ns2 := mustInitNamespaceEd25519V1(t, 0xff) - namespaces := []*Namespace{ns1, ns2} - pool, err := NewNamespacePool(namespaces) - if err != nil { - t.Fatalf("must create new namespace pool: %v", err) - } - if got, want := len(pool.List()), len(namespaces); got != want { - t.Errorf("got len %v but wanted %v", got, want) - } - pool.List()[0] = ns2 - if got, want := pool.List()[0].Ed25519V1.Namespace[:], ns1.Ed25519V1.Namespace[:]; !bytes.Equal(got, want) { - t.Errorf("returned list is not a copy") - } -} diff --git a/types/namespace_test.go b/types/namespace_test.go deleted file mode 100644 index a5847ef..0000000 --- a/types/namespace_test.go +++ /dev/null @@ -1,200 +0,0 @@ -package types - -import ( - "bytes" - "strings" - "testing" - - "crypto/ed25519" -) - -// TestNamespaceString checks that the String() function prints the right -// format, and that the body is printed without a nil-pointer panic. -func TestNamespaceString(t *testing.T) { - wantPrefix := map[NamespaceFormat]string{ - NamespaceFormatReserved: "Format(reserved)", - NamespaceFormatEd25519V1: "Format(ed25519_v1): &{Namespace", - NamespaceFormat(1<<16 - 1): "unknown Namespace: unknown NamespaceFormat: 65535", - } - tests := append(test_cases_namespace(t), testCaseSerialize{ - description: "valid: unknown Namespace", - item: Namespace{ - Format: NamespaceFormat(1<<16 - 1), - }, - }) - for _, table := range tests { - namespace, ok := table.item.(Namespace) - if !ok { - t.Fatalf("must cast to Namespace in test %q", table.description) - } - - prefix, ok := wantPrefix[namespace.Format] - if !ok { - t.Fatalf("must have prefix for StFormat %v in test %q", namespace.Format, table.description) - } - if got, want := namespace.String(), prefix; !strings.HasPrefix(got, want) { - t.Errorf("got %q but wanted prefix %q in test %q", got, want, table.description) - } - } -} - -func TestFingerprint(t *testing.T) { - for _, table := range []struct { - description string - namespace *Namespace - wantErr bool - wantFpr [NamespaceFingerprintSize]byte - }{ - { - description: "invalid: no fingerprint for type", - namespace: &Namespace{ - Format: NamespaceFormatReserved, - }, - wantErr: true, - }, - { - description: "valid: ed25519_v1", - namespace: mustInitNamespaceEd25519V1(t, 0xaf), - wantFpr: func() (ret [NamespaceFingerprintSize]byte) { - for i, _ := range ret { - ret[i] = 0xaf - } - return - }(), - }, - } { - fpr, err := table.namespace.Fingerprint() - 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 := *fpr, table.wantFpr; !bytes.Equal(got[:], want[:]) { - t.Errorf("got fpr %v but wanted %v in test %q", got, want, table.description) - } - } -} - -func TestVerify(t *testing.T) { - var tests []testCaseNamespace - tests = append(tests, test_cases_verify(t)...) - tests = append(tests, test_cases_verify_ed25519v1(t)...) - for _, table := range tests { - 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 TestNewNamespaceEd25519V1(t *testing.T) { - size := 32 // verification key size - for _, table := range []struct { - description string - vk []byte - wantErr bool - }{ - { - description: "invalid", - vk: make([]byte, size+1), - wantErr: true, - }, - { - description: "valid", - vk: make([]byte, size), - }, - } { - 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.Ed25519V1.Namespace[:], table.vk; !bytes.Equal(got, want) { - t.Errorf("got namespace %X but wanted %X in test %q", got, want, table.description) - } - } -} - -// testCaseNamespace is a common test case used for Namespace.Verify() tests -type testCaseNamespace struct { - description string - namespace *Namespace - msg, sig []byte - wantErr bool -} - -// test_cases_verify returns basic namespace.Verify() tests -func test_cases_verify(t *testing.T) []testCaseNamespace { - return []testCaseNamespace{ - { - description: "test_cases_verify: invalid: unsupported namespace", - namespace: &Namespace{Format: NamespaceFormatReserved}, - msg: []byte("msg"), - sig: []byte("sig"), - wantErr: true, - }, - } -} - -// test_cases_verify_ed25519v1 returns ed25519_v1 Namespace.Verify() tests -func test_cases_verify_ed25519v1(t *testing.T) []testCaseNamespace { - testEd25519Sk := [64]byte{230, 122, 195, 152, 194, 195, 147, 153, 80, 120, 153, 79, 102, 27, 52, 187, 136, 218, 150, 234, 107, 9, 167, 4, 92, 21, 11, 113, 42, 29, 129, 69, 75, 60, 249, 150, 229, 93, 75, 32, 103, 126, 244, 37, 53, 182, 68, 82, 249, 109, 49, 94, 10, 19, 146, 244, 58, 191, 169, 107, 78, 37, 45, 210} - testEd25519Vk := [32]byte{75, 60, 249, 150, 229, 93, 75, 32, 103, 126, 244, 37, 53, 182, 68, 82, 249, 109, 49, 94, 10, 19, 146, 244, 58, 191, 169, 107, 78, 37, 45, 210} - return []testCaseNamespace{ - { - description: "test_cases_verify_ed25519v1: invalid: sk signed message, but vk is not for sk", - namespace: &Namespace{ - Format: NamespaceFormatEd25519V1, - Ed25519V1: &Ed25519V1{ - Namespace: [32]byte{}, - }, - }, - msg: []byte("message"), - sig: ed25519.Sign(ed25519.PrivateKey(testEd25519Sk[:]), []byte("message")), - wantErr: true, - }, - { - description: "test_cases_verify_ed25519v1: invalid: vk is for sk, but sk did not sign message", - namespace: &Namespace{ - Format: NamespaceFormatEd25519V1, - Ed25519V1: &Ed25519V1{ - Namespace: testEd25519Vk, - }, - }, - msg: []byte("some message"), - sig: ed25519.Sign(ed25519.PrivateKey(testEd25519Sk[:]), []byte("another message")), - wantErr: true, - }, - { - description: "test_cases_verify_ed25519v1: valid", - namespace: &Namespace{ - Format: NamespaceFormatEd25519V1, - Ed25519V1: &Ed25519V1{ - Namespace: testEd25519Vk, - }, - }, - msg: []byte("message"), - sig: ed25519.Sign(ed25519.PrivateKey(testEd25519Sk[:]), []byte("message")), - }, - } -} - -func mustInitNamespaceEd25519V1(t *testing.T, initByte byte) *Namespace { - t.Helper() - buf := make([]byte, 32) - for i := 0; i < len(buf); i++ { - buf[i] = initByte - } - ns, err := NewNamespaceEd25519V1(buf) - if err != nil { - t.Fatalf("must make Ed25519v1 namespace: %v", err) - } - return ns -} diff --git a/types/serialize.go b/types/serialize.go deleted file mode 100644 index fd93336..0000000 --- a/types/serialize.go +++ /dev/null @@ -1,50 +0,0 @@ -package types - -import ( - "fmt" - - "github.com/google/certificate-transparency-go/tls" -) - -const ( - HashSizeV1 = 32 -) - -// GetProofByHashV1 is a serializable get-proof-by-hash request -type GetProofByHashV1 struct { - Hash [HashSizeV1]byte - TreeSize uint64 -} - -// GetConsistencyProofV1 is a serializable get-consistency-proof request -type GetConsistencyProofV1 struct { - First uint64 - Second uint64 -} - -// GetEntriesV1 is a serializable get-entries request -type GetEntriesV1 struct { - Start uint64 - End uint64 -} - -// Marshal marshals a TLS-encodable structure -func Marshal(item interface{}) ([]byte, error) { - serialized, err := tls.Marshal(item) - if err != nil { - return nil, fmt.Errorf("tls.Marshal: %v", err) - } - return serialized, nil -} - -// Unmarshal unmarshals a TLS-encoded structure -func Unmarshal(serialized []byte, out interface{}) error { - extra, err := tls.Unmarshal(serialized, out) - if err != nil { - return fmt.Errorf("tls.Unmarshal: %v", err) - } - if len(extra) > 0 { - return fmt.Errorf("tls.Unmarshal: extra data: %X", extra) - } - return nil -} diff --git a/types/serialize_test.go b/types/serialize_test.go deleted file mode 100644 index a06effe..0000000 --- a/types/serialize_test.go +++ /dev/null @@ -1,736 +0,0 @@ -package types - -import ( - "bytes" - "testing" - - "encoding/binary" -) - -// testCaseSerialize is a common test case used for ST log types -type testCaseSerialize struct { - description string - item interface{} - wantErr bool - wantBytes []byte // only used if no error and not equal to nil -} - -// TestMarshalUnmarshal tests that valid ST log structures can be marshalled and -// then unmarshalled without error, and that invalid ST log structures cannot be -// marshalled. If wantBytes is non-nil the marshalled result must also match. -func TestMarshalUnmarshal(t *testing.T) { - var tests []testCaseSerialize - tests = append(tests, test_cases_stitemlist(t)...) - tests = append(tests, test_cases_stitem(t)...) - tests = append(tests, test_cases_sthv1(t)...) - tests = append(tests, test_cases_costhv1(t)...) - tests = append(tests, test_cases_cpv1(t)...) - tests = append(tests, test_cases_ipv1(t)...) - tests = append(tests, test_cases_signed_checksumv1(t)...) - tests = append(tests, test_cases_checksumv1(t)...) - tests = append(tests, test_cases_thv1(t)...) - tests = append(tests, test_cases_nh(t)...) - tests = append(tests, test_cases_sigv1(t)...) - tests = append(tests, test_cases_namespace(t)...) - tests = append(tests, test_cases_ed25519v1(t)...) - tests = append(tests, test_cases_requests(t)...) - for _, table := range tests { - b, err := Marshal(table.item) - 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 // nothing to unmarshal - } - if got, want := b, table.wantBytes; want != nil && !bytes.Equal(got, want) { - t.Errorf("got bytes \n%v\n\tbut wanted\n%v\n\t in test %q: %v", got, want, table.description, err) - } - - switch table.item.(type) { - case StItemList: - var item StItemList - err = Unmarshal(b, &item) - case StItem: - var item StItem - err = Unmarshal(b, &item) - case SignedTreeHeadV1: - var item SignedTreeHeadV1 - err = Unmarshal(b, &item) - case CosignedTreeHeadV1: - var item CosignedTreeHeadV1 - err = Unmarshal(b, &item) - case ConsistencyProofV1: - var item ConsistencyProofV1 - err = Unmarshal(b, &item) - case InclusionProofV1: - var item InclusionProofV1 - err = Unmarshal(b, &item) - case SignedChecksumV1: - var item SignedChecksumV1 - err = Unmarshal(b, &item) - case ChecksumV1: - var item ChecksumV1 - err = Unmarshal(b, &item) - case TreeHeadV1: - var item TreeHeadV1 - err = Unmarshal(b, &item) - case NodeHash: - var item NodeHash - err = Unmarshal(b, &item) - case SignatureV1: - var item SignatureV1 - err = Unmarshal(b, &item) - case Namespace: - var item Namespace - err = Unmarshal(b, &item) - case Ed25519V1: - var item Ed25519V1 - err = Unmarshal(b, &item) - case GetProofByHashV1: - var item GetProofByHashV1 - err = Unmarshal(b, &item) - case GetConsistencyProofV1: - var item GetConsistencyProofV1 - err = Unmarshal(b, &item) - case GetEntriesV1: - var item GetEntriesV1 - err = Unmarshal(b, &item) - default: - t.Errorf("unhandled type in test %q", table.description) - } - if err != nil { - t.Errorf("unmarshal failed but wanted success in test %q: %v", table.description, err) - } - } -} - -// TestUnmarshalStItem tests that invalid StItems cannot be unmarshalled -func TestUnmarshalStItem(t *testing.T) { - tests := test_cases_stitem(t)[1:] // skip reserved type - for _, table := range tests { - description := table.description[7:] // skip "valid: " prefix - b, err := Marshal(table.item) - if err != nil { - t.Fatalf("must marshal in test %q: %v", description, err) - } - - var item StItem - if err := Unmarshal(append(b[:], []byte{0}...), &item); err == nil { - t.Errorf("unmarshal suceeded with one extra byte in test %q", description) - } - if err := Unmarshal(b[:len(b)-1], &item); err == nil { - t.Errorf("unmarshal suceeded with one byte short in test %q", description) - } - if err := Unmarshal(append(b[:], b[:]...), &item); err == nil { - t.Errorf("unmarshal succeeded with appended StItem in test %q", description) - } - if err := Unmarshal([]byte{0}, &item); err == nil { - t.Errorf("unmarshal succeeded with a single byte in test %q", description) - } - } -} - -// test_cases_stitemlist returns test cases for the StItemList type -func test_cases_stitemlist(t *testing.T) []testCaseSerialize { - t.Helper() - return []testCaseSerialize{ - testCaseSerialize{ - description: "test_cases_stitemlist: valid: StItemList: empty", - item: StItemList{}, - wantBytes: []byte{0x00, 0x00, 0x00, 0x00}, - }, // skip max len check because it is huge - testCaseSerialize{ - description: "test_cases_stitemlist: valid: mixed content", - item: testStItemList, - wantBytes: testStItemListBytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_stitem returns test cases for the different StItem types -func test_cases_stitem(t *testing.T) []testCaseSerialize { - t.Helper() - return []testCaseSerialize{ - { - description: "invalid: StItem: reserved", - item: testStItemReserved, - wantErr: true, - }, - { - description: "valid: StItem: signed_tree_head_v1", - item: testStItemSignedTreeHeadV1, - wantBytes: testStItemSignedTreeHeadV1Bytes, - }, - { - description: "valid: StItem: cosigned_tree_head_v1", - item: testStItemCosignedTreeHeadV1, - wantBytes: testStItemCosignedTreeHeadV1Bytes, - }, - { - description: "valid: StItem: consistency_proof_v1", - item: testStItemConsistencyProofV1, - wantBytes: testStItemConsistencyProofV1Bytes, - }, - { - description: "valid: StItem: inclusion_proof_v1", - item: testStItemInclusionProofV1, - wantBytes: testStItemInclusionProofV1Bytes, - }, - { - description: "valid: StItem: signed_checksum_v1", - item: testStItemSignedChecksumV1, - wantBytes: testStItemSignedChecksumV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_sthv1 returns test cases for the SignedTreeHeadV1 structure -func test_cases_sthv1(t *testing.T) []testCaseSerialize { - t.Helper() - return []testCaseSerialize{ - { - description: "valid: testSignedTreeHeadV1", - item: testSignedTreeHeadV1, - wantBytes: testSignedTreeHeadV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_costhv1 returns test cases for the CosignedTreeHeadV1 structure -func test_cases_costhv1(t *testing.T) []testCaseSerialize { - t.Helper() - return []testCaseSerialize{ - { - description: "test_cases_costhv1: valid: min", - item: CosignedTreeHeadV1{ - SignedTreeHead: testSignedTreeHeadV1, - Cosignatures: make([]SignatureV1, 0), - }, - }, // skipping "valid: max" because it is huge - { - description: "test_cases_costhv1: testCosignedTreeHeadV1", - item: testCosignedTreeHeadV1, - wantBytes: testCosignedTreeHeadV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_cpv1 returns test cases for the ConsistencyProofV1 structure -func test_cases_cpv1(t *testing.T) []testCaseSerialize { - t.Helper() - max := 65535 // max consistency proof - return []testCaseSerialize{ - { - description: "test_cases_cpv1: invalid: >max", - item: ConsistencyProofV1{ - LogId: testNamespace, - TreeSize1: 0, - TreeSize2: 0, - ConsistencyPath: func() []NodeHash { - var path []NodeHash - for sum := 0; sum < max+1; sum += 1 + len(testNodeHash.Data) { - path = append(path, testNodeHash) - } - return path - }(), - }, - wantErr: true, - }, - { - description: "test_cases_cpv1: valid: min", - item: ConsistencyProofV1{ - LogId: testNamespace, - TreeSize1: 0, - TreeSize2: 0, - ConsistencyPath: make([]NodeHash, 0), - }, - }, - { - description: "test_cases_cpv1: valid: testConsistencyProofV1", - item: testConsistencyProofV1, - wantBytes: testConsistencyProofV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_ipv1 returns test cases for the InclusionProofV1 structure -func test_cases_ipv1(t *testing.T) []testCaseSerialize { - t.Helper() - max := 65535 // max inclusion proof - return []testCaseSerialize{ - { - description: "test_cases_ipv1: invalid: >max", - item: InclusionProofV1{ - LogId: testNamespace, - TreeSize: 0, - LeafIndex: 0, - InclusionPath: func() []NodeHash { - var path []NodeHash - for sum := 0; sum < max+1; sum += 1 + len(testNodeHash.Data) { - path = append(path, testNodeHash) - } - return path - }(), - }, - wantErr: true, - }, - { - description: "test_cases_ipv1: valid: min", - item: InclusionProofV1{ - LogId: testNamespace, - TreeSize: 0, - LeafIndex: 0, - InclusionPath: make([]NodeHash, 0), - }, - }, - { - description: "test_cases_ipv1: valid: testInclusionProofV1", - item: testInclusionProofV1, - wantBytes: testInclusionProofV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_signed_checksumv1 returns test cases for the SignedChecksumV1 structure -func test_cases_signed_checksumv1(t *testing.T) []testCaseSerialize { - t.Helper() - return []testCaseSerialize{ - { - description: "test_cases_signed_checksumv1: valid: testSignedChecksumV1", - item: testSignedChecksumV1, - wantBytes: testSignedChecksumV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_checksumv1 returns test cases for the ChecksumV1 structure -func test_cases_checksumv1(t *testing.T) []testCaseSerialize { - t.Helper() - minIdentifier, maxIdentifier, identifier := 1, 128, []byte("foobar-1-2-3") - minChecksum, maxChecksum, checksum := 1, 64, make([]byte, 32) - return []testCaseSerialize{ - { - description: "test_cases_checksumv1: invalid: identifier: min", - item: ChecksumV1{ - Identifier: make([]byte, minIdentifier-1), - Checksum: checksum, - }, - wantErr: true, - }, - { - description: "test_cases_checksumv1: invalid: identifier: max", - item: ChecksumV1{ - Identifier: make([]byte, maxIdentifier+1), - Checksum: checksum, - }, - wantErr: true, - }, - { - description: "test_cases_checksumv1: invalid: checksum: min", - item: ChecksumV1{ - Identifier: identifier, - Checksum: make([]byte, minChecksum-1), - }, - wantErr: true, - }, - { - description: "test_cases_checksumv1: invalid: checksum: max", - item: ChecksumV1{ - Identifier: identifier, - Checksum: make([]byte, maxChecksum+1), - }, - wantErr: true, - }, - { - description: "test_cases_checksumv1: valid: testChecksumV1", - item: testChecksumV1, - wantBytes: testChecksumV1Bytes, - }, - } -} - -// test_cases_thv1 returns test cases for the TreeHeadV1 structure -func test_cases_thv1(t *testing.T) []testCaseSerialize { - t.Helper() - min, max := 0, 1<<16-1 // extensions min and max - return []testCaseSerialize{ - { - description: "test_cases_thv1: invalid: max", - item: TreeHeadV1{ - Timestamp: 0, - TreeSize: 0, - RootHash: testNodeHash, - Extension: make([]byte, max+1), - }, - wantErr: true, - }, - { - description: "test_cases_thv1: valid: min", - item: TreeHeadV1{ - Timestamp: 0, - TreeSize: 0, - RootHash: testNodeHash, - Extension: make([]byte, min), - }, - }, - { - description: "test_cases_thv1: valid: max", - item: TreeHeadV1{ - Timestamp: 0, - TreeSize: 0, - RootHash: testNodeHash, - Extension: make([]byte, max), - }, - }, - { - description: "test_cases_thv1: valid: testTreeHeadV1", - item: testTreeHeadV1, - wantBytes: testTreeHeadV1Bytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_nh returns test cases for the NodeHash structure -func test_cases_nh(t *testing.T) []testCaseSerialize { - t.Helper() - min, max := 32, 1<<8-1 // NodeHash min and max - return []testCaseSerialize{ - { - description: "test_cases_nh: invalid: min", - item: NodeHash{make([]byte, min-1)}, - wantErr: true, - }, - { - description: "test_cases_nh: invalid: max", - item: NodeHash{make([]byte, max+1)}, - wantErr: true, - }, - { - description: "test_cases_nh: valid: min", - item: NodeHash{make([]byte, min)}, - }, - { - description: "test_cases_nh: valid: max", - item: NodeHash{make([]byte, max)}, - }, - { - description: "test_cases_nh: valid: testNodeHash", - item: testNodeHash, - wantBytes: testNodeHashBytes, - }, // other invalid bounds are already tested in subtypes - } -} - -// test_cases_sigv1 returns test cases for the SignatureV1 structure -func test_cases_sigv1(t *testing.T) []testCaseSerialize { - t.Helper() - min, max := 1, 1<<16-1 // signature min and max - return []testCaseSerialize{ - { - description: "test_cases_sigv1: invalid: min", - item: SignatureV1{ - Namespace: testNamespace, - Signature: make([]byte, min-1), - }, - wantErr: true, - }, - { - description: "test_cases_sigv1: invalid: max", - item: SignatureV1{ - Namespace: testNamespace, - Signature: make([]byte, max+1), - }, - wantErr: true, - }, - { - description: "test_cases_sigv1: valid: min", - item: SignatureV1{ - Namespace: testNamespace, - Signature: make([]byte, min), - }, - }, - { - description: "test_cases_sigv1: valid: max", - item: SignatureV1{ - Namespace: testNamespace, - Signature: make([]byte, max), - }, - }, - { - description: "test_cases_sigV1: valid: testSignatureV1", - item: testSignatureV1, - wantBytes: testSignatureV1Bytes, - }, - } -} - -// test_cases_namespace returns test cases for the different Namespace types. -func test_cases_namespace(t *testing.T) []testCaseSerialize { - return []testCaseSerialize{ - { - description: "invalid: Namespace: reserved", - item: testNamespaceReserved, - wantErr: true, - }, - { - description: "valid: Namespace: ed25519_v1", - item: testNamespaceEd25519V1, - wantBytes: testNamespaceEd25519V1Bytes, - }, - } -} - -// test_cases_ed25519v1 returns test cases for the Ed25519V1 structure -func test_cases_ed25519v1(t *testing.T) []testCaseSerialize { - return []testCaseSerialize{ - { - description: "valid: testNamespaceEd25519V1", - item: testEd25519V1, - wantBytes: testEd25519V1Bytes, - }, - } -} - -// test_cases_requests returns test cases for proof request types -func test_cases_requests(t *testing.T) []testCaseSerialize { - return []testCaseSerialize{ - { - description: "valid: GetProofByHashV1", - item: GetProofByHashV1{ - Hash: [HashSizeV1]byte{}, - TreeSize: 16909060, - }, - wantBytes: bytes.Join([][]byte{ - make([]byte, 32), // hash - []byte{0x00, 0x00, 0x00, 0x00, 0x1, 0x2, 0x3, 0x4}, // tree size - }, nil), - }, - { - description: "valid: GetConsistencyProofV1", - item: GetConsistencyProofV1{ - First: 0, - Second: 16909060, - }, - wantBytes: bytes.Join([][]byte{ - make([]byte, 8), // first - []byte{0x00, 0x00, 0x00, 0x00, 0x1, 0x2, 0x3, 0x4}, // second - }, nil), - }, - { - description: "valid: GetEntriesV1", - item: GetEntriesV1{ - Start: 0, - End: 16909060, - }, - wantBytes: bytes.Join([][]byte{ - make([]byte, 8), // start - []byte{0x00, 0x00, 0x00, 0x00, 0x1, 0x2, 0x3, 0x4}, // end - }, nil), - }, - } -} - -var ( - // StItemList - testStItemList = StItemList{ - Items: []StItem{ - testStItemSignedChecksumV1, - testStItemInclusionProofV1, - testStItemCosignedTreeHeadV1, - }, - } - testStItemListBytes = bytes.Join([][]byte{ - func() []byte { - sum := uint32(len(testStItemSignedChecksumV1Bytes)) - sum += uint32(len(testStItemInclusionProofV1Bytes)) - sum += uint32(len(testStItemCosignedTreeHeadV1Bytes)) - buf := make([]byte, 4) - binary.BigEndian.PutUint32(buf, sum) - return buf - }(), // length specifier list - testStItemSignedChecksumV1Bytes, // first StItem - testStItemInclusionProofV1Bytes, // second StItem - testStItemCosignedTreeHeadV1Bytes, // third StItem - }, nil) - - // StItem - testStItemReserved = StItem{ - Format: StFormatReserved, - } - - testStItemSignedTreeHeadV1 = StItem{ - Format: StFormatSignedTreeHeadV1, - SignedTreeHeadV1: &testSignedTreeHeadV1, - } - testStItemSignedTreeHeadV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x01}, // format signed_tree_head_v1 - testSignedTreeHeadV1Bytes, // SignedTreeHeadV1 - }, nil) - - testStItemCosignedTreeHeadV1 = StItem{ - Format: StFormatCosignedTreeHeadV1, - CosignedTreeHeadV1: &testCosignedTreeHeadV1, - } - testStItemCosignedTreeHeadV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x02}, // format cosigned_tree_head_v1 - testCosignedTreeHeadV1Bytes, // CosignedTreeHeadV1, - }, nil) - - testStItemConsistencyProofV1 = StItem{ - Format: StFormatConsistencyProofV1, - ConsistencyProofV1: &testConsistencyProofV1, - } - testStItemConsistencyProofV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x03}, // format consistency_proof_v1 - testConsistencyProofV1Bytes, // ConsistencyProofV1 - }, nil) - - testStItemInclusionProofV1 = StItem{ - Format: StFormatInclusionProofV1, - InclusionProofV1: &testInclusionProofV1, - } - testStItemInclusionProofV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x04}, // format inclusion_proof_v1 - testInclusionProofV1Bytes, // InclusionProofV1 - }, nil) - - testStItemSignedChecksumV1 = StItem{ - Format: StFormatSignedChecksumV1, - SignedChecksumV1: &testSignedChecksumV1, - } - testStItemSignedChecksumV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x05}, // format signed_checksum_v1 - testSignedChecksumV1Bytes, // SignedChecksumV1 - }, nil) - - // Subtypes used by StItem - testSignedTreeHeadV1 = SignedTreeHeadV1{ - TreeHead: testTreeHeadV1, - Signature: testSignatureV1, - } - testSignedTreeHeadV1Bytes = bytes.Join([][]byte{ - testTreeHeadV1Bytes, // tree head - testSignatureV1Bytes, // signature - }, nil) - - testCosignedTreeHeadV1 = CosignedTreeHeadV1{ - SignedTreeHead: testSignedTreeHeadV1, - Cosignatures: []SignatureV1{ - testSignatureV1, - }, - } - testCosignedTreeHeadV1Bytes = bytes.Join([][]byte{ - testSignedTreeHeadV1Bytes, // signed tree head - []byte{0x00, 0x00, 0x00, byte(len(testSignatureV1Bytes))}, // cosignature length specifier - testSignatureV1Bytes, // the only cosignature in this list - }, nil) - - testConsistencyProofV1 = ConsistencyProofV1{ - LogId: testNamespace, - TreeSize1: 16909060, - TreeSize2: 16909060, - ConsistencyPath: []NodeHash{ - testNodeHash, - }, - } - testConsistencyProofV1Bytes = bytes.Join([][]byte{ - testNamespaceBytes, // log id - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // tree size 1 - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // tree size 2 - []byte{0x00, byte(len(testNodeHashBytes))}, // consistency path length specifier - testNodeHashBytes, // the only node hash in this proof - }, nil) - - testInclusionProofV1 = InclusionProofV1{ - LogId: testNamespace, - TreeSize: 16909060, - LeafIndex: 16909060, - InclusionPath: []NodeHash{ - testNodeHash, - }, - } - testInclusionProofV1Bytes = bytes.Join([][]byte{ - testNamespaceBytes, // log id - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // tree size - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // leaf index - []byte{0x00, byte(len(testNodeHashBytes))}, // inclusion path length specifier - testNodeHashBytes, // the only node hash in this proof - }, nil) - - testSignedChecksumV1 = SignedChecksumV1{ - Data: testChecksumV1, - Signature: testSignatureV1, - } - testSignedChecksumV1Bytes = bytes.Join([][]byte{ - testChecksumV1Bytes, // data - testSignatureV1Bytes, // signature - }, nil) - - // Additional subtypes - testChecksumV1 = ChecksumV1{ - Identifier: []byte("foobar-1-2-3"), - Checksum: make([]byte, 32), - } - testChecksumV1Bytes = bytes.Join([][]byte{ - []byte{12}, // identifier length specifier - []byte("foobar-1-2-3"), // identifier - []byte{32}, // checksum length specifier - make([]byte, 32), // checksum - }, nil) - - testTreeHeadV1 = TreeHeadV1{ - Timestamp: 16909060, - TreeSize: 16909060, - RootHash: testNodeHash, - Extension: make([]byte, 0), - } - testTreeHeadV1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // timestamp - []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, // tree size - testNodeHashBytes, // root hash - []byte{0x00, 0x00}, // extension length specifier - // no extension - }, nil) - - testNodeHash = NodeHash{ - Data: make([]byte, 32), - } - testNodeHashBytes = bytes.Join([][]byte{ - []byte{32}, // node hash length specifier - make([]byte, 32), - }, nil) - - testSignatureV1 = SignatureV1{ - Namespace: testNamespace, - Signature: make([]byte, 64), - } - testSignatureV1Bytes = bytes.Join([][]byte{ - testNamespaceBytes, // namespace field - []byte{0, 64}, // signature length specifier - make([]byte, 64), // signature - }, nil) - - // Namespace - testNamespaceReserved = Namespace{ - Format: NamespaceFormatReserved, - } - - testNamespace = testNamespaceEd25519V1 - testNamespaceBytes = testNamespaceEd25519V1Bytes - testNamespaceEd25519V1 = Namespace{ - Format: NamespaceFormatEd25519V1, - Ed25519V1: &testEd25519V1, - } - testNamespaceEd25519V1Bytes = bytes.Join([][]byte{ - []byte{0x00, 0x01}, // format ed25519_v1 - testEd25519V1Bytes, // Ed25519V1 - }, nil) - - // Subtypes used by Namespace - testEd25519V1 = Ed25519V1{ - Namespace: [32]byte{}, - } - testEd25519V1Bytes = bytes.Join([][]byte{ - make([]byte, 32), // namespace, no length specifier because fixed size - }, nil) -) diff --git a/types/stitem.go b/types/stitem.go deleted file mode 100644 index 447cad0..0000000 --- a/types/stitem.go +++ /dev/null @@ -1,192 +0,0 @@ -package types - -import ( - "fmt" - - "github.com/google/certificate-transparency-go/tls" -) - -// StFormat defines a particular StItem type that is versioned -type StFormat tls.Enum - -const ( - StFormatReserved StFormat = 0 - StFormatSignedTreeHeadV1 StFormat = 1 - StFormatCosignedTreeHeadV1 StFormat = 2 - StFormatConsistencyProofV1 StFormat = 3 - StFormatInclusionProofV1 StFormat = 4 - StFormatSignedChecksumV1 StFormat = 5 -) - -// StItem references a versioned item based on a given format specifier -type StItem struct { - Format StFormat `tls:"maxval:65535"` - SignedTreeHeadV1 *SignedTreeHeadV1 `tls:"selector:Format,val:1"` - CosignedTreeHeadV1 *CosignedTreeHeadV1 `tls:"selector:Format,val:2"` - ConsistencyProofV1 *ConsistencyProofV1 `tls:"selector:Format,val:3"` - InclusionProofV1 *InclusionProofV1 `tls:"selector:Format,val:4"` - SignedChecksumV1 *SignedChecksumV1 `tls:"selector:Format,val:5"` -} - -type StItemList struct { - Items []StItem `tls:"minlen:0,maxlen:4294967295"` -} - -type SignedTreeHeadV1 struct { - TreeHead TreeHeadV1 - Signature SignatureV1 -} - -type CosignedTreeHeadV1 struct { - SignedTreeHead SignedTreeHeadV1 - Cosignatures []SignatureV1 `tls:"minlen:0,maxlen:4294967295"` -} - -type ConsistencyProofV1 struct { - LogId Namespace - TreeSize1 uint64 - TreeSize2 uint64 - ConsistencyPath []NodeHash `tls:"minlen:0,maxlen:65535"` -} - -type InclusionProofV1 struct { - LogId Namespace - TreeSize uint64 - LeafIndex uint64 - InclusionPath []NodeHash `tls:"minlen:0,maxlen:65535"` -} - -type SignedChecksumV1 struct { - Data ChecksumV1 - Signature SignatureV1 -} - -type ChecksumV1 struct { - Identifier []byte `tls:"minlen:1,maxlen:128"` - Checksum []byte `tls:"minlen:1,maxlen:64"` -} - -type TreeHeadV1 struct { - Timestamp uint64 - TreeSize uint64 - RootHash NodeHash - Extension []byte `tls:"minlen:0,maxlen:65535"` -} - -type NodeHash struct { - Data []byte `tls:"minlen:32,maxlen:255"` -} - -type SignatureV1 struct { - Namespace Namespace - Signature []byte `tls:"minlen:1,maxlen:65535"` -} - -func (f StFormat) String() string { - switch f { - case StFormatReserved: - return "reserved" - case StFormatSignedTreeHeadV1: - return "signed_tree_head_v1" - case StFormatCosignedTreeHeadV1: - return "cosigned_tree_head_v1" - case StFormatConsistencyProofV1: - return "consistency_proof_v1" - case StFormatInclusionProofV1: - return "inclusion_proof_v1" - case StFormatSignedChecksumV1: - return "signed_checksum_v1" - default: - return fmt.Sprintf("unknown StFormat: %d", f) - } -} - -func (i StItem) String() string { - switch i.Format { - case StFormatReserved: - return fmt.Sprintf("Format(%s)", i.Format) - case StFormatSignedTreeHeadV1: - return fmt.Sprintf("Format(%s): %+v", i.Format, i.SignedTreeHeadV1) - case StFormatCosignedTreeHeadV1: - return fmt.Sprintf("Format(%s): %+v", i.Format, i.CosignedTreeHeadV1) - case StFormatConsistencyProofV1: - return fmt.Sprintf("Format(%s): %+v", i.Format, i.ConsistencyProofV1) - case StFormatInclusionProofV1: - return fmt.Sprintf("Format(%s): %+v", i.Format, i.InclusionProofV1) - case StFormatSignedChecksumV1: - return fmt.Sprintf("Format(%s): %+v", i.Format, i.SignedChecksumV1) - default: - return fmt.Sprintf("unknown StItem: %v", i.Format) - } -} - -func NewSignedTreeHeadV1(th *TreeHeadV1, sig *SignatureV1) *StItem { - return &StItem{ - Format: StFormatSignedTreeHeadV1, - SignedTreeHeadV1: &SignedTreeHeadV1{ - TreeHead: *th, - Signature: *sig, - }, - } -} - -func NewCosignedTreeHeadV1(sth *SignedTreeHeadV1, cosig []SignatureV1) *StItem { - if cosig == nil { - cosig = make([]SignatureV1, 0) - } - return &StItem{ - Format: StFormatCosignedTreeHeadV1, - CosignedTreeHeadV1: &CosignedTreeHeadV1{ - SignedTreeHead: *sth, - Cosignatures: cosig, - }, - } -} - -func NewConsistencyProofV1(id *Namespace, size1, size2 uint64, path []NodeHash) *StItem { - return &StItem{ - Format: StFormatConsistencyProofV1, - ConsistencyProofV1: &ConsistencyProofV1{ - LogId: *id, - TreeSize1: size1, - TreeSize2: size2, - ConsistencyPath: path, - }, - } -} - -func NewInclusionProofV1(id *Namespace, size, index uint64, path []NodeHash) *StItem { - return &StItem{ - Format: StFormatInclusionProofV1, - InclusionProofV1: &InclusionProofV1{ - LogId: *id, - TreeSize: size, - LeafIndex: index, - InclusionPath: path, - }, - } -} - -func NewSignedChecksumV1(data *ChecksumV1, sig *SignatureV1) *StItem { - return &StItem{ - Format: StFormatSignedChecksumV1, - SignedChecksumV1: &SignedChecksumV1{ - Data: *data, - Signature: *sig, - }, - } -} - -func NewTreeHeadV1(timestamp, size uint64, hash, extension []byte) *TreeHeadV1 { - if extension == nil { - extension = make([]byte, 0) - } - return &TreeHeadV1{ - Timestamp: timestamp, - TreeSize: size, - RootHash: NodeHash{ - Data: hash, - }, - Extension: extension, - } -} diff --git a/types/stitem_test.go b/types/stitem_test.go deleted file mode 100644 index 90d6808..0000000 --- a/types/stitem_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package types - -import ( - "strings" - "testing" -) - -// TestStItemString checks that the String() function prints the right format, -// and that the body is printed without a nil-pointer panic. -func TestStItemString(t *testing.T) { - wantPrefix := map[StFormat]string{ - StFormatReserved: "Format(reserved)", - StFormatSignedTreeHeadV1: "Format(signed_tree_head_v1): &{TreeHead", - StFormatCosignedTreeHeadV1: "Format(cosigned_tree_head_v1): &{SignedTreeHead", - StFormatConsistencyProofV1: "Format(consistency_proof_v1): &{LogId", - StFormatInclusionProofV1: "Format(inclusion_proof_v1): &{LogId", - StFormatSignedChecksumV1: "Format(signed_checksum_v1): &{Data", - StFormat(1<<16 - 1): "unknown StItem: unknown StFormat: 65535", - } - tests := append(test_cases_stitem(t), testCaseSerialize{ - description: "valid: unknown StItem", - item: StItem{ - Format: StFormat(1<<16 - 1), - }, - }) - for _, table := range tests { - item, ok := table.item.(StItem) - if !ok { - t.Fatalf("must cast to StItem in test %q", table.description) - } - - prefix, ok := wantPrefix[item.Format] - if !ok { - t.Fatalf("must have prefix for StFormat %v in test %q", item.Format, table.description) - } - if got, want := item.String(), prefix; !strings.HasPrefix(got, want) { - t.Errorf("got %q but wanted prefix %q in test %q", got, want, table.description) - } - } -} - -// TODO: TestNewSignedTreeHeadV1 -func TestNewSignedTreeHeadV1(t *testing.T) { -} - -// TODO: TestNewCosignedTreeHeadV1 -func TestNewCosignedTreeHeadV1(t *testing.T) { -} - -// TODO: TestNewConsistencyProofV1 -func TestNewConsistencyProofV1(t *testing.T) { -} - -// TODO: TestNewInclusionProofV1 -func TestNewInclusionProofV1(t *testing.T) { -} - -// TODO: TestNewSignedChecksumV1 -func TestNewSignedChecksumV1(t *testing.T) { -} - -// TODO: TestNewTreeHeadV1 -func TestNewTreeHeadV1(t *testing.T) { -} |