diff options
| author | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-06-06 15:59:35 +0200 | 
|---|---|---|
| committer | Rasmus Dahlberg <rasmus.dahlberg@kau.se> | 2021-06-06 15:59:35 +0200 | 
| commit | 47bacfd5c5d22470340e0823c4ad37b45914b68e (patch) | |
| tree | 0984b55ced1e537e8d1d681c77157f1a47e47cdc /types | |
| parent | 0285454c34b0b3003bc8ede3e304b843ad949be8 (diff) | |
started using the refactored packages in siglog server
Diffstat (limited to 'types')
| -rw-r--r-- | types/ascii.go | 421 | ||||
| -rw-r--r-- | types/ascii_test.go | 465 | ||||
| -rw-r--r-- | types/trunnel.go | 60 | ||||
| -rw-r--r-- | types/trunnel_test.go | 114 | ||||
| -rw-r--r-- | types/types.go | 155 | ||||
| -rw-r--r-- | types/types_test.go | 58 | ||||
| -rw-r--r-- | types/util.go | 21 | 
7 files changed, 0 insertions, 1294 deletions
| diff --git a/types/ascii.go b/types/ascii.go deleted file mode 100644 index d27d79b..0000000 --- a/types/ascii.go +++ /dev/null @@ -1,421 +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          = 5 -	NumFieldConsistencyProof        = 3 -	NumFieldInclusionProof          = 3 -	NumFieldLeavesRequest           = 2 -	NumFieldInclusionProofRequest   = 2 -	NumFieldConsistencyProofRequest = 2 -	NumFieldLeafRequest             = 5 -	NumFieldCosignatureRequest      = 2 - -	// New leaf keys -	ShardHint            = "shard_hint" -	Checksum             = "checksum" -	SignatureOverMessage = "signature_over_message" -	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" - -	// Signature and signer-identity keys -	Signature = "signature" -	KeyHash   = "key_hash" -) - -// 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, SignatureOverMessage, 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) -	} -	for _, sigident := range sth.SigIdent { -		if err := sigident.MarshalASCII(w); err != nil { -			return fmt.Errorf("MarshalASCII: %v", err) -		} -	} -	return nil -} - -func (si *SigIdent) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, Signature, hex.EncodeToString(si.Signature[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, KeyHash, hex.EncodeToString(si.KeyHash[:])); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	return nil -} - -func (p *ConsistencyProof) MarshalASCII(w io.Writer) error { -	if err := writeASCII(w, NewSize, strconv.FormatUint(p.NewSize, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	if err := writeASCII(w, OldSize, strconv.FormatUint(p.OldSize, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	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, TreeSize, strconv.FormatUint(p.TreeSize, 10)); err != nil { -		return fmt.Errorf("writeASCII: %v", err) -	} -	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) -	} - -	// TreeHead -	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) -	} - -	// SigIdent -	signatures := msg.GetStrings(Signature) -	if len(signatures) == 0 { -		return fmt.Errorf("no signer") -	} -	keyHashes := msg.GetStrings(KeyHash) -	if len(signatures) != len(keyHashes) { -		return fmt.Errorf("mismatched signature-signer count") -	} -	sth.SigIdent = make([]*SigIdent, 0, len(signatures)) -	for i, n := 0, len(signatures); i < n; i++ { -		var signature [SignatureSize]byte -		if err := decodeHex(signatures[i], signature[:]); err != nil { -			return fmt.Errorf("decodeHex: %v", err) -		} -		var hash [HashSize]byte -		if err := decodeHex(keyHashes[i], hash[:]); err != nil { -			return fmt.Errorf("decodeHex: %v", err) -		} -		sth.SigIdent = append(sth.SigIdent, &SigIdent{ -			Signature: &signature, -			KeyHash:   &hash, -		}) -	} -	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(SignatureOverMessage); 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(Signature); 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/types/ascii_test.go b/types/ascii_test.go deleted file mode 100644 index 92732f9..0000000 --- a/types/ascii_test.go +++ /dev/null @@ -1,465 +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, -		SignatureOverMessage, Delim, testBuffer64[:], EOL, -		KeyHash, Delim, testBuffer32[:], EOL, -		// Leaf 2 -		ShardHint, Delim, 456, EOL, -		Checksum, Delim, testBuffer32[:], EOL, -		SignatureOverMessage, 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, -		}, -		SigIdent: []*SigIdent{ -			&SigIdent{ -				Signature: testBuffer64, -				KeyHash:   testBuffer32, -			}, -			&SigIdent{ -				Signature: testBuffer64, -				KeyHash:   testBuffer32, -			}, -		}, -	} -	wantBuf := bytes.NewBufferString(fmt.Sprintf( -		"%s%s%d%s"+"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s"+"%s%s%x%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, -		KeyHash, Delim, testBuffer32[:], EOL, -		Signature, Delim, testBuffer64[:], EOL, -		KeyHash, Delim, testBuffer32[:], 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%d%s"+"%s%s%x%s"+"%s%s%x%s", -		TreeSize, Delim, 321, EOL, -		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%d%s"+"%s%s%d%s"+"%s%s%x%s"+"%s%s%x%s", -		NewSize, Delim, 321, EOL, -		OldSize, Delim, 123, EOL, -		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"+"%s%s%x%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, -				KeyHash, Delim, testBuffer32[:], EOL, -				Signature, Delim, testBuffer64[:], EOL, -				KeyHash, Delim, testBuffer32[:], EOL, -			)), -			wantSth: &SignedTreeHead{ -				TreeHead: TreeHead{ -					Timestamp: 123, -					TreeSize:  456, -					RootHash:  testBuffer32, -				}, -				SigIdent: []*SigIdent{ -					&SigIdent{ -						Signature: testBuffer64, -						KeyHash:   testBuffer32, -					}, -					&SigIdent{ -						Signature: testBuffer64, -						KeyHash:   testBuffer32, -					}, -				}, -			}, -		}, -	} { -		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, -				SignatureOverMessage, 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", -				Signature, 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/types/trunnel.go b/types/trunnel.go deleted file mode 100644 index 268f6f7..0000000 --- a/types/trunnel.go +++ /dev/null @@ -1,60 +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 -) - -// 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, 8+8+HashSize) -	binary.BigEndian.PutUint64(buf[0:8], th.Timestamp) -	binary.BigEndian.PutUint64(buf[8:16], th.TreeSize) -	copy(buf[16:], th.RootHash[:]) -	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/types/trunnel_test.go b/types/trunnel_test.go deleted file mode 100644 index 297578c..0000000 --- a/types/trunnel_test.go +++ /dev/null @@ -1,114 +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 0x00,0x01,..." -	th := &TreeHead{ -		Timestamp: 16909060, -		TreeSize:  72623859790382856, -		RootHash:  testBuffer32, -	} -	want := bytes.Join([][]byte{ -		[]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}, -		[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, -		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/types/types.go b/types/types.go deleted file mode 100644 index 9ca7db8..0000000 --- a/types/types.go +++ /dev/null @@ -1,155 +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") -	EndpointGetProofByHash      = Endpoint("get-proof-by-hash") -	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)), "/") -} - -// Leaf is the log's Merkle tree leaf. -type Leaf struct { -	Message -	SigIdent -} - -// Message is composed of a shard hint and a checksum.  The submitter selects -// these values to fit the log's shard interval and the opaque data in question. -type Message struct { -	ShardHint uint64 -	Checksum  *[HashSize]byte -} - -// SigIdent is composed of a signature-signer pair.  The signature is computed -// over the Trunnel-serialized leaf message.  KeyHash identifies the signer. -type SigIdent struct { -	Signature *[SignatureSize]byte -	KeyHash   *[HashSize]byte -} - -// SignedTreeHead is composed of a tree head and a list of signature-signer -// pairs.  Each signature is computed over the Trunnel-serialized tree head. -type SignedTreeHead struct { -	TreeHead -	SigIdent []*SigIdent -} - -// TreeHead is the log's tree head. -type TreeHead struct { -	Timestamp uint64 -	TreeSize  uint64 -	RootHash  *[HashSize]byte -} - -// ConsistencyProof is a consistency proof that proves the log's append-only -// property. -type ConsistencyProof struct { -	NewSize uint64 -	OldSize uint64 -	Path    []*[HashSize]byte -} - -// InclusionProof is an inclusion proof that proves a leaf is included in the -// log. -type InclusionProof struct { -	TreeSize  uint64 -	LeafIndex uint64 -	Path      []*[HashSize]byte -} - -// LeafList is a list of leaves -type LeafList []*Leaf - -// ConsistencyProofRequest is a get-consistency-proof request -type ConsistencyProofRequest struct { -	NewSize uint64 -	OldSize uint64 -} - -// InclusionProofRequest is a get-proof-by-hash request -type InclusionProofRequest struct { -	LeafHash *[HashSize]byte -	TreeSize uint64 -} - -// LeavesRequest is a get-leaves request -type LeavesRequest struct { -	StartSize uint64 -	EndSize   uint64 -} - -// LeafRequest is an add-leaf request -type LeafRequest struct { -	Message -	Signature       *[SignatureSize]byte -	VerificationKey *[VerificationKeySize]byte -	DomainHint      string -} - -// CosignatureRequest is an add-cosignature request -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) -	} - -	sigident := SigIdent{ -		KeyHash:   Hash(signer.Public().(ed25519.PublicKey)[:]), -		Signature: &[SignatureSize]byte{}, -	} -	copy(sigident.Signature[:], sig) -	return &SignedTreeHead{ -		TreeHead: *th, -		SigIdent: []*SigIdent{ -			&sigident, -		}, -	}, 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/types/types_test.go b/types/types_test.go deleted file mode 100644 index da89c59..0000000 --- a/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", "st/v0" -	for _, table := range []struct { -		endpoint Endpoint -		want     string -	}{ -		{ -			endpoint: EndpointAddLeaf, -			want:     "example.com/log/st/v0/add-leaf", -		}, -		{ -			endpoint: EndpointAddCosignature, -			want:     "example.com/log/st/v0/add-cosignature", -		}, -		{ -			endpoint: EndpointGetTreeHeadLatest, -			want:     "example.com/log/st/v0/get-tree-head-latest", -		}, -		{ -			endpoint: EndpointGetTreeHeadToSign, -			want:     "example.com/log/st/v0/get-tree-head-to-sign", -		}, -		{ -			endpoint: EndpointGetTreeHeadCosigned, -			want:     "example.com/log/st/v0/get-tree-head-cosigned", -		}, -		{ -			endpoint: EndpointGetConsistencyProof, -			want:     "example.com/log/st/v0/get-consistency-proof", -		}, -		{ -			endpoint: EndpointGetProofByHash, -			want:     "example.com/log/st/v0/get-proof-by-hash", -		}, -		{ -			endpoint: EndpointGetLeaves, -			want:     "example.com/log/st/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/types/util.go b/types/util.go deleted file mode 100644 index 3cd7dfa..0000000 --- a/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...)) -} | 
