diff options
Diffstat (limited to 'pkg/types')
| -rw-r--r-- | pkg/types/ascii.go | 399 | ||||
| -rw-r--r-- | pkg/types/ascii_test.go | 438 | ||||
| -rw-r--r-- | pkg/types/trunnel.go | 63 | ||||
| -rw-r--r-- | pkg/types/trunnel_test.go | 116 | ||||
| -rw-r--r-- | pkg/types/types.go | 138 | ||||
| -rw-r--r-- | pkg/types/types_test.go | 58 | ||||
| -rw-r--r-- | pkg/types/util.go | 21 | 
7 files changed, 0 insertions, 1233 deletions
| diff --git a/pkg/types/ascii.go b/pkg/types/ascii.go deleted file mode 100644 index 72abfcb..0000000 --- a/pkg/types/ascii.go +++ /dev/null @@ -1,399 +0,0 @@ -package types - -import ( -	"bytes" -	"encoding/hex" -	"fmt" -	"io" -	"io/ioutil" -	"strconv" -) - -const ( -	// Delim is a key-value separator -	Delim = "=" - -	// EOL is a line sepator -	EOL = "\n" - -	// NumField* is the number of unique keys in an incoming ASCII message -	NumFieldLeaf                    = 4 -	NumFieldSignedTreeHead          = 4 -	NumFieldConsistencyProof        = 3 -	NumFieldInclusionProof          = 3 -	NumFieldLeavesRequest           = 2 -	NumFieldInclusionProofRequest   = 2 -	NumFieldConsistencyProofRequest = 2 -	NumFieldLeafRequest             = 5 -	NumFieldCosignatureRequest      = 2 - -	// New leaf keys -	ShardHint       = "shard_hint" -	Checksum        = "checksum" -	Signature       = "signature" -	VerificationKey = "verification_key" -	DomainHint      = "domain_hint" - -	// Inclusion proof keys -	LeafHash      = "leaf_hash" -	LeafIndex     = "leaf_index" -	InclusionPath = "inclusion_path" - -	// Consistency proof keys -	NewSize         = "new_size" -	OldSize         = "old_size" -	ConsistencyPath = "consistency_path" - -	// Range of leaves keys -	StartSize = "start_size" -	EndSize   = "end_size" - -	// Tree head keys -	Timestamp = "timestamp" -	TreeSize  = "tree_size" -	RootHash  = "root_hash" - -	// Witness signature-identity keys -	KeyHash     = "key_hash" -	Cosignature = "cosignature" -) - -// MessageASCI is a wrapper that manages ASCII key-value pairs -type MessageASCII struct { -	m map[string][]string -} - -// NewMessageASCII unpacks an incoming ASCII message -func NewMessageASCII(r io.Reader, numFieldExpected int) (*MessageASCII, error) { -	buf, err := ioutil.ReadAll(r) -	if err != nil { -		return nil, fmt.Errorf("ReadAll: %v", err) -	} -	lines := bytes.Split(buf, []byte(EOL)) -	if len(lines) <= 1 { -		return nil, fmt.Errorf("Not enough lines: empty") -	} -	lines = lines[:len(lines)-1] // valid message => split gives empty last line - -	msg := MessageASCII{make(map[string][]string)} -	for _, line := range lines { -		split := bytes.Index(line, []byte(Delim)) -		if split == -1 { -			return nil, fmt.Errorf("invalid line: %v", string(line)) -		} - -		key := string(line[:split]) -		value := string(line[split+len(Delim):]) -		values, ok := msg.m[key] -		if !ok { -			values = nil -			msg.m[key] = values -		} -		msg.m[key] = append(values, value) -	} - -	if msg.NumField() != numFieldExpected { -		return nil, fmt.Errorf("Unexpected number of keys: %v", msg.NumField()) -	} -	return &msg, nil -} - -// NumField returns the number of unique keys -func (msg *MessageASCII) NumField() int { -	return len(msg.m) -} - -// GetStrings returns a list of strings -func (msg *MessageASCII) GetStrings(key string) []string { -	strs, ok := msg.m[key] -	if !ok { -		return nil -	} -	return strs -} - -// GetString unpacks a string -func (msg *MessageASCII) GetString(key string) (string, error) { -	strs := msg.GetStrings(key) -	if len(strs) != 1 { -		return "", fmt.Errorf("expected one string: %v", strs) -	} -	return strs[0], nil -} - -// GetUint64 unpacks an uint64 -func (msg *MessageASCII) GetUint64(key string) (uint64, error) { -	str, err := msg.GetString(key) -	if err != nil { -		return 0, fmt.Errorf("GetString: %v", err) -	} -	num, err := strconv.ParseUint(str, 10, 64) -	if err != nil { -		return 0, fmt.Errorf("ParseUint: %v", err) -	} -	return num, nil -} - -// GetHash unpacks a hash -func (msg *MessageASCII) GetHash(key string) (*[HashSize]byte, error) { -	str, err := msg.GetString(key) -	if err != nil { -		return nil, fmt.Errorf("GetString: %v", err) -	} - -	var hash [HashSize]byte -	if err := decodeHex(str, hash[:]); err != nil { -		return nil, fmt.Errorf("decodeHex: %v", err) -	} -	return &hash, nil -} - -// GetSignature unpacks a signature -func (msg *MessageASCII) GetSignature(key string) (*[SignatureSize]byte, error) { -	str, err := msg.GetString(key) -	if err != nil { -		return nil, fmt.Errorf("GetString: %v", err) -	} - -	var signature [SignatureSize]byte -	if err := decodeHex(str, signature[:]); err != nil { -		return nil, fmt.Errorf("decodeHex: %v", err) -	} -	return &signature, nil -} - -// GetVerificationKey unpacks a verification key -func (msg *MessageASCII) GetVerificationKey(key string) (*[VerificationKeySize]byte, error) { -	str, err := msg.GetString(key) -	if err != nil { -		return nil, fmt.Errorf("GetString: %v", err) -	} - -	var vk [VerificationKeySize]byte -	if err := decodeHex(str, vk[:]); err != nil { -		return nil, fmt.Errorf("decodeHex: %v", err) -	} -	return &vk, nil -} - -// decodeHex decodes a hex-encoded string into an already-sized byte slice -func decodeHex(str string, out []byte) error { -	buf, err := hex.DecodeString(str) -	if err != nil { -		return fmt.Errorf("DecodeString: %v", err) -	} -	if len(buf) != len(out) { -		return fmt.Errorf("invalid length: %v", len(buf)) -	} -	copy(out, buf) -	return nil -} - -/* - * - * MarshalASCII wrappers for types that the log server outputs - * - */ -func (l *Leaf) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, ShardHint, strconv.FormatUint(l.ShardHint, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, Checksum, hex.EncodeToString(l.Checksum[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, Signature, hex.EncodeToString(l.Signature[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, KeyHash, hex.EncodeToString(l.KeyHash[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	return nil -} - -func (sth *SignedTreeHead) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, Timestamp, strconv.FormatUint(sth.Timestamp, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, TreeSize, strconv.FormatUint(sth.TreeSize, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, RootHash, hex.EncodeToString(sth.RootHash[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, Signature, hex.EncodeToString(sth.Signature[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	return nil -} - -func (cth *CosignedTreeHead) MarshalASCII(w io.Writer) error { -	if err := cth.SignedTreeHead.MarshalASCII(w); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	for _, si := range cth.SigIdent { -		if err := si.MarshalASCII(w); err != nil { -			return fmt.Errorf("writeASCII: %v", err) -		} -	} -	return nil -} - -func (si *SigIdent) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, KeyHash, hex.EncodeToString(si.KeyHash[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, Cosignature, hex.EncodeToString(si.Signature[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	return nil -} - -func (p *ConsistencyProof) MarshalASCII(w io.Writer) error { -	for _, hash := range p.Path { -		if err := writeASCII(w, ConsistencyPath, hex.EncodeToString(hash[:])); err != nil { -			return fmt.Errorf("writeASCII: %v", err) -		} -	} -	return nil -} - -func (p *InclusionProof) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, LeafIndex, strconv.FormatUint(p.LeafIndex, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	for _, hash := range p.Path { -		if err := writeASCII(w, InclusionPath, hex.EncodeToString(hash[:])); err != nil { -			return fmt.Errorf("writeASCII: %v", err) -		} -	} -	return nil -} - -func writeASCII(w io.Writer, key, value string) error { -	if _, err := fmt.Fprintf(w, "%s%s%s%s", key, Delim, value, EOL); err != nil { -		return fmt.Errorf("Fprintf: %v", err) -	} -	return nil -} - -/* - * - * Unmarshal ASCII wrappers that the log server and/or log clients receive. - * - */ -func (ll *LeafList) UnmarshalASCII(r io.Reader) error { -	return nil -} - -func (sth *SignedTreeHead) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldSignedTreeHead) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if sth.Timestamp, err = msg.GetUint64(Timestamp); err != nil { -		return fmt.Errorf("GetUint64(Timestamp): %v", err) -	} -	if sth.TreeSize, err = msg.GetUint64(TreeSize); err != nil { -		return fmt.Errorf("GetUint64(TreeSize): %v", err) -	} -	if sth.RootHash, err = msg.GetHash(RootHash); err != nil { -		return fmt.Errorf("GetHash(RootHash): %v", err) -	} -	if sth.Signature, err = msg.GetSignature(Signature); err != nil { -		return fmt.Errorf("GetHash(RootHash): %v", err) -	} -	return nil -} - -func (p *InclusionProof) UnmarshalASCII(r io.Reader) error { -	return nil -} - -func (p *ConsistencyProof) UnmarshalASCII(r io.Reader) error { -	return nil -} - -func (req *InclusionProofRequest) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldInclusionProofRequest) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if req.LeafHash, err = msg.GetHash(LeafHash); err != nil { -		return fmt.Errorf("GetHash(LeafHash): %v", err) -	} -	if req.TreeSize, err = msg.GetUint64(TreeSize); err != nil { -		return fmt.Errorf("GetUint64(TreeSize): %v", err) -	} -	return nil -} - -func (req *ConsistencyProofRequest) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldConsistencyProofRequest) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if req.NewSize, err = msg.GetUint64(NewSize); err != nil { -		return fmt.Errorf("GetUint64(NewSize): %v", err) -	} -	if req.OldSize, err = msg.GetUint64(OldSize); err != nil { -		return fmt.Errorf("GetUint64(OldSize): %v", err) -	} -	return nil -} - -func (req *LeavesRequest) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldLeavesRequest) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if req.StartSize, err = msg.GetUint64(StartSize); err != nil { -		return fmt.Errorf("GetUint64(StartSize): %v", err) -	} -	if req.EndSize, err = msg.GetUint64(EndSize); err != nil { -		return fmt.Errorf("GetUint64(EndSize): %v", err) -	} -	return nil -} - -func (req *LeafRequest) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldLeafRequest) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if req.ShardHint, err = msg.GetUint64(ShardHint); err != nil { -		return fmt.Errorf("GetUint64(ShardHint): %v", err) -	} -	if req.Checksum, err = msg.GetHash(Checksum); err != nil { -		return fmt.Errorf("GetHash(Checksum): %v", err) -	} -	if req.Signature, err = msg.GetSignature(Signature); err != nil { -		return fmt.Errorf("GetSignature: %v", err) -	} -	if req.VerificationKey, err = msg.GetVerificationKey(VerificationKey); err != nil { -		return fmt.Errorf("GetVerificationKey: %v", err) -	} -	if req.DomainHint, err = msg.GetString(DomainHint); err != nil { -		return fmt.Errorf("GetString(DomainHint): %v", err) -	} -	return nil -} - -func (req *CosignatureRequest) UnmarshalASCII(r io.Reader) error { -	msg, err := NewMessageASCII(r, NumFieldCosignatureRequest) -	if err != nil { -		return fmt.Errorf("NewMessageASCII: %v", err) -	} - -	if req.Signature, err = msg.GetSignature(Cosignature); err != nil { -		return fmt.Errorf("GetSignature: %v", err) -	} -	if req.KeyHash, err = msg.GetHash(KeyHash); err != nil { -		return fmt.Errorf("GetHash(KeyHash): %v", err) -	} -	return nil -} diff --git a/pkg/types/ascii_test.go b/pkg/types/ascii_test.go deleted file mode 100644 index fc3f486..0000000 --- a/pkg/types/ascii_test.go +++ /dev/null @@ -1,438 +0,0 @@ -package types - -import ( -	"bytes" -	"fmt" -	"io" -	"reflect" -	"testing" -) - -/* - * - * MessageASCII methods and helpers - * - */ -func TestNewMessageASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		input       io.Reader -		wantErr     bool -		wantMap     map[string][]string -	}{ -		{ -			description: "invalid: not enough lines", -			input:       bytes.NewBufferString(""), -			wantErr:     true, -		}, -		{ -			description: "invalid: lines must end with new line", -			input:       bytes.NewBufferString("k1=v1\nk2=v2"), -			wantErr:     true, -		}, -		{ -			description: "invalid: lines must not be empty", -			input:       bytes.NewBufferString("k1=v1\n\nk2=v2\n"), -			wantErr:     true, -		}, -		{ -			description: "invalid: wrong number of fields", -			input:       bytes.NewBufferString("k1=v1\n"), -			wantErr:     true, -		}, -		{ -			description: "valid", -			input:       bytes.NewBufferString("k1=v1\nk2=v2\nk2=v3=4\n"), -			wantMap: map[string][]string{ -				"k1": []string{"v1"}, -				"k2": []string{"v2", "v3=4"}, -			}, -		}, -	} { -		msg, err := NewMessageASCII(table.input, len(table.wantMap)) -		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 := msg.m, table.wantMap; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestNumField(t *testing.T)           {} -func TestGetStrings(t *testing.T)         {} -func TestGetString(t *testing.T)          {} -func TestGetUint64(t *testing.T)          {} -func TestGetHash(t *testing.T)            {} -func TestGetSignature(t *testing.T)       {} -func TestGetVerificationKey(t *testing.T) {} -func TestDecodeHex(t *testing.T)          {} - -/* - * - * MarshalASCII methods and helpers - * - */ -func TestLeafMarshalASCII(t *testing.T) { -	description := "valid: two leaves" -	leafList := []*Leaf{ -		&Leaf{ -			Message: Message{ -				ShardHint: 123, -				Checksum:  testBuffer32, -			}, -			SigIdent: SigIdent{ -				Signature: testBuffer64, -				KeyHash:   testBuffer32, -			}, -		}, -		&Leaf{ -			Message: Message{ -				ShardHint: 456, -				Checksum:  testBuffer32, -			}, -			SigIdent: SigIdent{ -				Signature: testBuffer64, -				KeyHash:   testBuffer32, -			}, -		}, -	} -	wantBuf := bytes.NewBufferString(fmt.Sprintf( -		"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s"+"%s%s%x%s"+ -			"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s"+"%s%s%x%s", -		// Leaf 1 -		ShardHint, Delim, 123, EOL, -		Checksum, Delim, testBuffer32[:], EOL, -		Signature, Delim, testBuffer64[:], EOL, -		KeyHash, Delim, testBuffer32[:], EOL, -		// Leaf 2 -		ShardHint, Delim, 456, EOL, -		Checksum, Delim, testBuffer32[:], EOL, -		Signature, Delim, testBuffer64[:], EOL, -		KeyHash, Delim, testBuffer32[:], EOL, -	)) -	buf := bytes.NewBuffer(nil) -	for _, leaf := range leafList { -		if err := leaf.MarshalASCII(buf); err != nil { -			t.Errorf("expected error %v but got %v in test %q: %v", false, true, description, err) -			return -		} -	} -	if got, want := buf.Bytes(), wantBuf.Bytes(); !bytes.Equal(got, want) { -		t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", string(got), string(want), description) -	} -} - -func TestSignedTreeHeadMarshalASCII(t *testing.T) { -	description := "valid" -	sth := &SignedTreeHead{ -		TreeHead: TreeHead{ -			Timestamp: 123, -			TreeSize:  456, -			RootHash:  testBuffer32, -		}, -		Signature: testBuffer64, -	} -	wantBuf := bytes.NewBufferString(fmt.Sprintf( -		"%s%s%d%s"+"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s", -		Timestamp, Delim, 123, EOL, -		TreeSize, Delim, 456, EOL, -		RootHash, Delim, testBuffer32[:], EOL, -		Signature, Delim, testBuffer64[:], EOL, -	)) -	buf := bytes.NewBuffer(nil) -	if err := sth.MarshalASCII(buf); err != nil { -		t.Errorf("expected error %v but got %v in test %q", false, true, description) -		return -	} -	if got, want := buf.Bytes(), wantBuf.Bytes(); !bytes.Equal(got, want) { -		t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", string(got), string(want), description) -	} -} - -func TestInclusionProofMarshalASCII(t *testing.T) { -	description := "valid" -	proof := InclusionProof{ -		TreeSize:  321, -		LeafIndex: 123, -		Path: []*[HashSize]byte{ -			testBuffer32, -			testBuffer32, -		}, -	} -	wantBuf := bytes.NewBufferString(fmt.Sprintf( -		"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s", -		LeafIndex, Delim, 123, EOL, -		InclusionPath, Delim, testBuffer32[:], EOL, -		InclusionPath, Delim, testBuffer32[:], EOL, -	)) -	buf := bytes.NewBuffer(nil) -	if err := proof.MarshalASCII(buf); err != nil { -		t.Errorf("expected error %v but got %v in test %q", false, true, description) -		return -	} -	if got, want := buf.Bytes(), wantBuf.Bytes(); !bytes.Equal(got, want) { -		t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", string(got), string(want), description) -	} -} - -func TestConsistencyProofMarshalASCII(t *testing.T) { -	description := "valid" -	proof := ConsistencyProof{ -		NewSize: 321, -		OldSize: 123, -		Path: []*[HashSize]byte{ -			testBuffer32, -			testBuffer32, -		}, -	} -	wantBuf := bytes.NewBufferString(fmt.Sprintf( -		"%s%s%x%s"+"%s%s%x%s", -		ConsistencyPath, Delim, testBuffer32[:], EOL, -		ConsistencyPath, Delim, testBuffer32[:], EOL, -	)) -	buf := bytes.NewBuffer(nil) -	if err := proof.MarshalASCII(buf); err != nil { -		t.Errorf("expected error %v but got %v in test %q", false, true, description) -		return -	} -	if got, want := buf.Bytes(), wantBuf.Bytes(); !bytes.Equal(got, want) { -		t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", string(got), string(want), description) -	} -} - -func TestWriteASCII(t *testing.T) { -} - -/* - * - * UnmarshalASCII methods and helpers - * - */ -func TestLeafListUnmarshalASCII(t *testing.T) {} - -func TestSignedTreeHeadUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantSth     *SignedTreeHead -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%d%s"+"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s", -				Timestamp, Delim, 123, EOL, -				TreeSize, Delim, 456, EOL, -				RootHash, Delim, testBuffer32[:], EOL, -				Signature, Delim, testBuffer64[:], EOL, -			)), -			wantSth: &SignedTreeHead{ -				TreeHead: TreeHead{ -					Timestamp: 123, -					TreeSize:  456, -					RootHash:  testBuffer32, -				}, -				Signature: testBuffer64, -			}, -		}, -	} { -		var sth SignedTreeHead -		err := sth.UnmarshalASCII(table.buf) -		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 := &sth, table.wantSth; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestInclusionProofUnmarshalASCII(t *testing.T)   {} -func TestConsistencyProofUnmarshalASCII(t *testing.T) {} - -func TestInclusionProofRequestUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantReq     *InclusionProofRequest -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%x%s"+"%s%s%d%s", -				LeafHash, Delim, testBuffer32[:], EOL, -				TreeSize, Delim, 123, EOL, -			)), -			wantReq: &InclusionProofRequest{ -				LeafHash: testBuffer32, -				TreeSize: 123, -			}, -		}, -	} { -		var req InclusionProofRequest -		err := req.UnmarshalASCII(table.buf) -		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 := &req, table.wantReq; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestConsistencyProofRequestUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantReq     *ConsistencyProofRequest -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%d%s"+"%s%s%d%s", -				NewSize, Delim, 321, EOL, -				OldSize, Delim, 123, EOL, -			)), -			wantReq: &ConsistencyProofRequest{ -				NewSize: 321, -				OldSize: 123, -			}, -		}, -	} { -		var req ConsistencyProofRequest -		err := req.UnmarshalASCII(table.buf) -		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 := &req, table.wantReq; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestLeavesRequestUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantReq     *LeavesRequest -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%d%s"+"%s%s%d%s", -				StartSize, Delim, 123, EOL, -				EndSize, Delim, 456, EOL, -			)), -			wantReq: &LeavesRequest{ -				StartSize: 123, -				EndSize:   456, -			}, -		}, -	} { -		var req LeavesRequest -		err := req.UnmarshalASCII(table.buf) -		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 := &req, table.wantReq; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestLeafRequestUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantReq     *LeafRequest -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s"+"%s%s%x%s"+"%s%s%s%s", -				ShardHint, Delim, 123, EOL, -				Checksum, Delim, testBuffer32[:], EOL, -				Signature, Delim, testBuffer64[:], EOL, -				VerificationKey, Delim, testBuffer32[:], EOL, -				DomainHint, Delim, "example.com", EOL, -			)), -			wantReq: &LeafRequest{ -				Message: Message{ -					ShardHint: 123, -					Checksum:  testBuffer32, -				}, -				Signature:       testBuffer64, -				VerificationKey: testBuffer32, -				DomainHint:      "example.com", -			}, -		}, -	} { -		var req LeafRequest -		err := req.UnmarshalASCII(table.buf) -		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 := &req, table.wantReq; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} - -func TestCosignatureRequestUnmarshalASCII(t *testing.T) { -	for _, table := range []struct { -		description string -		buf         io.Reader -		wantErr     bool -		wantReq     *CosignatureRequest -	}{ -		{ -			description: "valid", -			buf: bytes.NewBufferString(fmt.Sprintf( -				"%s%s%x%s"+"%s%s%x%s", -				Cosignature, Delim, testBuffer64[:], EOL, -				KeyHash, Delim, testBuffer32[:], EOL, -			)), -			wantReq: &CosignatureRequest{ -				SigIdent: SigIdent{ -					Signature: testBuffer64, -					KeyHash:   testBuffer32, -				}, -			}, -		}, -	} { -		var req CosignatureRequest -		err := req.UnmarshalASCII(table.buf) -		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 := &req, table.wantReq; !reflect.DeepEqual(got, want) { -			t.Errorf("got\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description) -		} -	} -} diff --git a/pkg/types/trunnel.go b/pkg/types/trunnel.go deleted file mode 100644 index 5350c5b..0000000 --- a/pkg/types/trunnel.go +++ /dev/null @@ -1,63 +0,0 @@ -package types - -import ( -	"encoding/binary" -	"fmt" -) - -const ( -	// MessageSize is the number of bytes in a Trunnel-encoded leaf message -	MessageSize = 8 + HashSize -	// LeafSize is the number of bytes in a Trunnel-encoded leaf -	LeafSize = MessageSize + SignatureSize + HashSize -	// TreeHeadSize is the number of bytes in a Trunnel-encoded tree head -	TreeHeadSize = 8 + 8 + HashSize + HashSize -) - -// Marshal returns a Trunnel-encoded message -func (m *Message) Marshal() []byte { -	buf := make([]byte, MessageSize) -	binary.BigEndian.PutUint64(buf, m.ShardHint) -	copy(buf[8:], m.Checksum[:]) -	return buf -} - -// Marshal returns a Trunnel-encoded leaf -func (l *Leaf) Marshal() []byte { -	buf := l.Message.Marshal() -	buf = append(buf, l.SigIdent.Signature[:]...) -	buf = append(buf, l.SigIdent.KeyHash[:]...) -	return buf -} - -// Marshal returns a Trunnel-encoded tree head -func (th *TreeHead) Marshal() []byte { -	buf := make([]byte, TreeHeadSize) -	binary.BigEndian.PutUint64(buf[0:8], th.Timestamp) -	binary.BigEndian.PutUint64(buf[8:16], th.TreeSize) -	copy(buf[16:16+HashSize], th.RootHash[:]) -	copy(buf[16+HashSize:], th.KeyHash[:]) -	return buf -} - -// Unmarshal parses the Trunnel-encoded buffer as a leaf -func (l *Leaf) Unmarshal(buf []byte) error { -	if len(buf) != LeafSize { -		return fmt.Errorf("invalid leaf size: %v", len(buf)) -	} -	// Shard hint -	l.ShardHint = binary.BigEndian.Uint64(buf) -	offset := 8 -	// Checksum -	l.Checksum = &[HashSize]byte{} -	copy(l.Checksum[:], buf[offset:offset+HashSize]) -	offset += HashSize -	// Signature -	l.Signature = &[SignatureSize]byte{} -	copy(l.Signature[:], buf[offset:offset+SignatureSize]) -	offset += SignatureSize -	// KeyHash -	l.KeyHash = &[HashSize]byte{} -	copy(l.KeyHash[:], buf[offset:]) -	return nil -} diff --git a/pkg/types/trunnel_test.go b/pkg/types/trunnel_test.go deleted file mode 100644 index a3ae1ba..0000000 --- a/pkg/types/trunnel_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package types - -import ( -	"bytes" -	"reflect" -	"testing" -) - -var ( -	testBuffer32 = &[32]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} -	testBuffer64 = &[64]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63} -) - -func TestMarshalMessage(t *testing.T) { -	description := "valid: shard hint 72623859790382856, checksum 0x00,0x01,..." -	message := &Message{ -		ShardHint: 72623859790382856, -		Checksum:  testBuffer32, -	} -	want := bytes.Join([][]byte{ -		[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, -		testBuffer32[:], -	}, nil) -	if got := message.Marshal(); !bytes.Equal(got, want) { -		t.Errorf("got message\n\t%v\nbut wanted\n\t%v\nin test %q\n", got, want, description) -	} -} - -func TestMarshalLeaf(t *testing.T) { -	description := "valid: shard hint 72623859790382856, buffers 0x00,0x01,..." -	leaf := &Leaf{ -		Message: Message{ -			ShardHint: 72623859790382856, -			Checksum:  testBuffer32, -		}, -		SigIdent: SigIdent{ -			Signature: testBuffer64, -			KeyHash:   testBuffer32, -		}, -	} -	want := bytes.Join([][]byte{ -		[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, -		testBuffer32[:], testBuffer64[:], testBuffer32[:], -	}, nil) -	if got := leaf.Marshal(); !bytes.Equal(got, want) { -		t.Errorf("got leaf\n\t%v\nbut wanted\n\t%v\nin test %q\n", got, want, description) -	} -} - -func TestMarshalTreeHead(t *testing.T) { -	description := "valid: timestamp 16909060, tree size 72623859790382856, root hash & key hash 0x00,0x01,..." -	th := &TreeHead{ -		Timestamp: 16909060, -		TreeSize:  72623859790382856, -		RootHash:  testBuffer32, -		KeyHash:   testBuffer32, -	} -	want := bytes.Join([][]byte{ -		[]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, -		[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, -		testBuffer32[:], -		testBuffer32[:], -	}, nil) -	if got := th.Marshal(); !bytes.Equal(got, want) { -		t.Errorf("got tree head\n\t%v\nbut wanted\n\t%v\nin test %q\n", got, want, description) -	} -} - -func TestUnmarshalLeaf(t *testing.T) { -	for _, table := range []struct { -		description string -		serialized  []byte -		wantErr     bool -		want        *Leaf -	}{ -		{ -			description: "invalid: not enough bytes", -			serialized:  make([]byte, LeafSize-1), -			wantErr:     true, -		}, -		{ -			description: "invalid: too many bytes", -			serialized:  make([]byte, LeafSize+1), -			wantErr:     true, -		}, -		{ -			description: "valid: shard hint 72623859790382856, buffers 0x00,0x01,...", -			serialized: bytes.Join([][]byte{ -				[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, -				testBuffer32[:], testBuffer64[:], testBuffer32[:], -			}, nil), -			want: &Leaf{ -				Message: Message{ -					ShardHint: 72623859790382856, -					Checksum:  testBuffer32, -				}, -				SigIdent: SigIdent{ -					Signature: testBuffer64, -					KeyHash:   testBuffer32, -				}, -			}, -		}, -	} { -		var leaf Leaf -		err := leaf.Unmarshal(table.serialized) -		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 := &leaf, table.want; !reflect.DeepEqual(got, want) { -			t.Errorf("got leaf\n\t%v\nbut wanted\n\t%v\nin test %q\n", got, want, table.description) -		} -	} -} diff --git a/pkg/types/types.go b/pkg/types/types.go deleted file mode 100644 index bc58c98..0000000 --- a/pkg/types/types.go +++ /dev/null @@ -1,138 +0,0 @@ -package types - -import ( -	"crypto" -	"crypto/ed25519" -	"crypto/sha256" -	"fmt" -	"strings" -) - -const ( -	HashSize            = sha256.Size -	SignatureSize       = ed25519.SignatureSize -	VerificationKeySize = ed25519.PublicKeySize - -	EndpointAddLeaf             = Endpoint("add-leaf") -	EndpointAddCosignature      = Endpoint("add-cosignature") -	EndpointGetTreeHeadLatest   = Endpoint("get-tree-head-latest") -	EndpointGetTreeHeadToSign   = Endpoint("get-tree-head-to-sign") -	EndpointGetTreeHeadCosigned = Endpoint("get-tree-head-cosigned") -	EndpointGetInclusionProof   = Endpoint("get-inclusion-proof") -	EndpointGetConsistencyProof = Endpoint("get-consistency-proof") -	EndpointGetLeaves           = Endpoint("get-leaves") -) - -// Endpoint is a named HTTP API endpoint -type Endpoint string - -// Path joins a number of components to form a full endpoint path.  For example, -// EndpointAddLeaf.Path("example.com", "st/v0") -> example.com/st/v0/add-leaf. -func (e Endpoint) Path(components ...string) string { -	return strings.Join(append(components, string(e)), "/") -} - -type Leaf struct { -	Message -	SigIdent -} - -type Message struct { -	ShardHint uint64 -	Checksum  *[HashSize]byte -} - -type SigIdent struct { -	Signature *[SignatureSize]byte -	KeyHash   *[HashSize]byte -} - -type SignedTreeHead struct { -	TreeHead -	Signature *[SignatureSize]byte -} - -type CosignedTreeHead struct { -	SignedTreeHead -	SigIdent []*SigIdent -} - -type TreeHead struct { -	Timestamp uint64 -	TreeSize  uint64 -	RootHash  *[HashSize]byte -	KeyHash   *[HashSize]byte -} - -type ConsistencyProof struct { -	NewSize uint64 -	OldSize uint64 -	Path    []*[HashSize]byte -} - -type InclusionProof struct { -	TreeSize  uint64 -	LeafIndex uint64 -	Path      []*[HashSize]byte -} - -type LeafList []*Leaf - -type ConsistencyProofRequest struct { -	NewSize uint64 -	OldSize uint64 -} - -type InclusionProofRequest struct { -	LeafHash *[HashSize]byte -	TreeSize uint64 -} - -type LeavesRequest struct { -	StartSize uint64 -	EndSize   uint64 -} - -type LeafRequest struct { -	Message -	Signature       *[SignatureSize]byte -	VerificationKey *[VerificationKeySize]byte -	DomainHint      string -} - -type CosignatureRequest struct { -	SigIdent -} - -// Sign signs the tree head using the log's signature scheme -func (th *TreeHead) Sign(signer crypto.Signer) (*SignedTreeHead, error) { -	sig, err := signer.Sign(nil, th.Marshal(), crypto.Hash(0)) -	if err != nil { -		return nil, fmt.Errorf("Sign: %v", err) -	} - -	sth := &SignedTreeHead{ -		TreeHead:  *th, -		Signature: &[SignatureSize]byte{}, -	} -	copy(sth.Signature[:], sig) -	return sth, nil -} - -// Verify verifies the tree head signature using the log's signature scheme -func (th *TreeHead) Verify(vk *[VerificationKeySize]byte, sig *[SignatureSize]byte) error { -	if !ed25519.Verify(ed25519.PublicKey(vk[:]), th.Marshal(), sig[:]) { -		return fmt.Errorf("invalid tree head signature") -	} -	return nil -} - -// Verify checks if a leaf is included in the log -func (p *InclusionProof) Verify(leaf *Leaf, th *TreeHead) error { // TODO -	return nil -} - -// Verify checks if two tree heads are consistent -func (p *ConsistencyProof) Verify(oldTH, newTH *TreeHead) error { // TODO -	return nil -} diff --git a/pkg/types/types_test.go b/pkg/types/types_test.go deleted file mode 100644 index d823ea2..0000000 --- a/pkg/types/types_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package types - -import ( -	"testing" -) - -func TestEndpointPath(t *testing.T) { -	base, prefix, proto := "example.com", "log", "sigsum/v0" -	for _, table := range []struct { -		endpoint Endpoint -		want     string -	}{ -		{ -			endpoint: EndpointAddLeaf, -			want:     "example.com/log/sigsum/v0/add-leaf", -		}, -		{ -			endpoint: EndpointAddCosignature, -			want:     "example.com/log/sigsum/v0/add-cosignature", -		}, -		{ -			endpoint: EndpointGetTreeHeadLatest, -			want:     "example.com/log/sigsum/v0/get-tree-head-latest", -		}, -		{ -			endpoint: EndpointGetTreeHeadToSign, -			want:     "example.com/log/sigsum/v0/get-tree-head-to-sign", -		}, -		{ -			endpoint: EndpointGetTreeHeadCosigned, -			want:     "example.com/log/sigsum/v0/get-tree-head-cosigned", -		}, -		{ -			endpoint: EndpointGetConsistencyProof, -			want:     "example.com/log/sigsum/v0/get-consistency-proof", -		}, -		{ -			endpoint: EndpointGetInclusionProof, -			want:     "example.com/log/sigsum/v0/get-inclusion-proof", -		}, -		{ -			endpoint: EndpointGetLeaves, -			want:     "example.com/log/sigsum/v0/get-leaves", -		}, -	} { -		if got, want := table.endpoint.Path(base+"/"+prefix+"/"+proto), table.want; got != want { -			t.Errorf("got endpoint\n%s\n\tbut wanted\n%s\n\twith one component", got, want) -		} -		if got, want := table.endpoint.Path(base, prefix, proto), table.want; got != want { -			t.Errorf("got endpoint\n%s\n\tbut wanted\n%s\n\tmultiple components", got, want) -		} -	} -} - -func TestTreeHeadSign(t *testing.T)           {} -func TestTreeHeadVerify(t *testing.T)         {} -func TestInclusionProofVerify(t *testing.T)   {} -func TestConsistencyProofVerify(t *testing.T) {} diff --git a/pkg/types/util.go b/pkg/types/util.go deleted file mode 100644 index 3cd7dfa..0000000 --- a/pkg/types/util.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -import ( -	"crypto/sha256" -) - -const ( -	LeafHashPrefix = 0x00 -) - -func Hash(buf []byte) *[HashSize]byte { -	var ret [HashSize]byte -	hash := sha256.New() -	hash.Write(buf) -	copy(ret[:], hash.Sum(nil)) -	return &ret -} - -func HashLeaf(buf []byte) *[HashSize]byte { -	return Hash(append([]byte{LeafHashPrefix}, buf...)) -} | 
