package tuf

import (
	"bytes"
	"crypto"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"
	"time"

	"github.com/secure-systems-lab/go-securesystemslib/cjson"
	"github.com/theupdateframework/go-tuf/data"
	"github.com/theupdateframework/go-tuf/encrypted"
	"github.com/theupdateframework/go-tuf/internal/sets"
	"github.com/theupdateframework/go-tuf/pkg/keys"
	"github.com/theupdateframework/go-tuf/pkg/targets"
	"github.com/theupdateframework/go-tuf/util"
	"github.com/theupdateframework/go-tuf/verify"
	"golang.org/x/crypto/ed25519"
	. "gopkg.in/check.v1"
)

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type RepoSuite struct{}

var _ = Suite(&RepoSuite{})

func (RepoSuite) TestNewRepo(c *C) {
	testNewRepo(c, NewRepo)
}

func (RepoSuite) TestNewRepoIndent(c *C) {
	testNewRepo(c, func(local LocalStore, hashAlgorithms ...string) (*Repo, error) {
		return NewRepoIndent(local, "", "\t")
	})
}

// UniqueKeys returns the unique keys for each associated role.
// We might have multiple key IDs that correspond to the same key.
func UniqueKeys(r *data.Root) map[string][]*data.PublicKey {
	keysByRole := make(map[string][]*data.PublicKey)
	for name, role := range r.Roles {
		seen := make(map[string]struct{})
		roleKeys := []*data.PublicKey{}
		for _, id := range role.KeyIDs {
			// Double-check that there is actually a key with that ID.
			if key, ok := r.Keys[id]; ok {
				verifier, err := keys.GetVerifier(key)
				if err != nil {
					continue
				}
				val := verifier.Public()
				if _, ok := seen[val]; ok {
					continue
				}
				seen[val] = struct{}{}
				roleKeys = append(roleKeys, key)
			}
		}
		keysByRole[name] = roleKeys
	}
	return keysByRole
}

// AssertNumUniqueKeys verifies that the number of unique root keys for a given role is as expected.
func (*RepoSuite) assertNumUniqueKeys(c *C, root *data.Root, role string, num int) {
	c.Assert(UniqueKeys(root)[role], HasLen, num)
}

func testNewRepo(c *C, newRepo func(local LocalStore, hashAlgorithms ...string) (*Repo, error)) {
	meta := map[string]json.RawMessage{
		"root.json": []byte(`{
		  "signed": {
		    "_type": "root",
		    "version": 1,
		    "expires": "2015-12-26T03:26:55.821520874Z",
		    "keys": {},
		    "roles": {}
		  },
		  "signatures": []
		}`),
		"targets.json": []byte(`{
		  "signed": {
		    "_type": "targets",
		    "version": 1,
		    "expires": "2015-03-26T03:26:55.82155686Z",
		    "targets": {}
		  },
		  "signatures": []
		}`),
		"snapshot.json": []byte(`{
		  "signed": {
		    "_type": "snapshot",
		    "version": 1,
		    "expires": "2015-01-02T03:26:55.821585981Z",
		    "meta": {}
		  },
		  "signatures": []
		}`),
		"timestamp.json": []byte(`{
		  "signed": {
		    "_type": "timestamp",
		    "version": 1,
		    "expires": "2014-12-27T03:26:55.821599702Z",
		    "meta": {}
		  },
		  "signatures": []
		}`),
	}
	local := MemoryStore(meta, nil)
	r, err := newRepo(local)
	c.Assert(err, IsNil)

	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Type, Equals, "root")
	c.Assert(root.Version, Equals, int64(1))
	c.Assert(root.Keys, NotNil)
	c.Assert(root.Keys, HasLen, 0)

	targets, err := r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(targets.Type, Equals, "targets")
	c.Assert(targets.Version, Equals, int64(1))
	c.Assert(targets.Targets, NotNil)
	c.Assert(targets.Targets, HasLen, 0)

	snapshot, err := r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Type, Equals, "snapshot")
	c.Assert(snapshot.Version, Equals, int64(1))
	c.Assert(snapshot.Meta, NotNil)
	c.Assert(snapshot.Meta, HasLen, 0)

	timestamp, err := r.timestamp()
	c.Assert(err, IsNil)
	c.Assert(timestamp.Type, Equals, "timestamp")
	c.Assert(timestamp.Version, Equals, int64(1))
	c.Assert(timestamp.Meta, NotNil)
	c.Assert(timestamp.Meta, HasLen, 0)
}

func (rs *RepoSuite) TestInit(c *C) {
	local := MemoryStore(
		make(map[string]json.RawMessage),
		map[string][]byte{"foo.txt": []byte("foo")},
	)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Init() sets root.ConsistentSnapshot
	for _, v := range []bool{true, false} {
		c.Assert(r.Init(v), IsNil)
		root, err := r.root()
		c.Assert(err, IsNil)
		c.Assert(root.ConsistentSnapshot, Equals, v)
	}

	// Add a target.
	generateAndAddPrivateKey(c, r, "targets")
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)

	// Init() fails if targets have been added
	c.Assert(r.Init(true), Equals, ErrInitNotAllowed)
}

func genKey(c *C, r *Repo, role string) []string {
	keyids, err := r.GenKey(role)
	c.Assert(err, IsNil)
	c.Assert(len(keyids) > 0, Equals, true)
	return keyids
}

func (rs *RepoSuite) TestGenKey(c *C) {
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// generate a key for an unknown role
	_, err = r.GenKey("foo")
	c.Assert(err, Equals, ErrInvalidRole{"foo", "only support adding keys for top-level roles"})

	// generate a root key
	ids := genKey(c, r, "root")

	// check root metadata is correct
	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 1)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rootRole, ok := root.Roles["root"]
	if !ok {
		c.Fatal("missing root role")
	}
	c.Assert(rootRole.KeyIDs, HasLen, 1)
	c.Assert(rootRole.KeyIDs, DeepEquals, ids)
	for _, keyID := range ids {
		k, ok := root.Keys[keyID]
		if !ok {
			c.Fatal("missing key")
		}
		c.Assert(k.IDs(), DeepEquals, ids)
		pk, err := keys.GetVerifier(k)
		c.Assert(err, IsNil)
		c.Assert(pk.Public(), HasLen, ed25519.PublicKeySize)
	}

	// check root key + role are in db
	db, err := r.topLevelKeysDB()
	c.Assert(err, IsNil)
	for _, keyID := range ids {
		rootKey, err := db.GetVerifier(keyID)
		c.Assert(err, IsNil)
		c.Assert(rootKey.MarshalPublicKey().IDs(), DeepEquals, ids)
		role := db.GetRole("root")
		c.Assert(role.KeyIDs, DeepEquals, sets.StringSliceToSet(ids))

		// check the key was saved correctly
		localKeys, err := local.GetSigners("root")
		c.Assert(err, IsNil)
		c.Assert(localKeys, HasLen, 1)
		c.Assert(localKeys[0].PublicData().IDs(), DeepEquals, ids)

		// check RootKeys() is correct
		rootKeys, err := r.RootKeys()
		c.Assert(err, IsNil)
		c.Assert(rootKeys, HasLen, 1)
		c.Assert(rootKeys[0].IDs(), DeepEquals, rootKey.MarshalPublicKey().IDs())
		pk, err := keys.GetVerifier(rootKeys[0])
		c.Assert(err, IsNil)
		c.Assert(pk.Public(), DeepEquals, rootKey.Public())
	}

	rootKey, err := db.GetVerifier(ids[0])
	c.Assert(err, IsNil)

	// generate two targets keys
	genKey(c, r, "targets")
	genKey(c, r, "targets")

	// check root metadata is correct
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, HasLen, 2)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rs.assertNumUniqueKeys(c, root, "targets", 2)
	targetsRole, ok := root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, 2)
	targetKeyIDs := make(map[string]struct{}, 2)
	db, err = r.topLevelKeysDB()
	c.Assert(err, IsNil)
	for _, id := range targetsRole.KeyIDs {
		targetKeyIDs[id] = struct{}{}
		_, ok = root.Keys[id]
		if !ok {
			c.Fatal("missing key")
		}
		verifier, err := db.GetVerifier(id)
		c.Assert(err, IsNil)
		c.Assert(verifier.MarshalPublicKey().ContainsID(id), Equals, true)
	}
	role := db.GetRole("targets")
	c.Assert(role.KeyIDs, DeepEquals, targetKeyIDs)

	// check RootKeys() is unchanged
	rootKeys, err := r.RootKeys()
	c.Assert(err, IsNil)
	c.Assert(rootKeys, HasLen, 1)
	c.Assert(rootKeys[0].IDs(), DeepEquals, rootKey.MarshalPublicKey().IDs())

	// check the keys were saved correctly
	localKeys, err := local.GetSigners("targets")
	c.Assert(err, IsNil)
	c.Assert(localKeys, HasLen, 2)
	for _, key := range localKeys {
		found := false
		for _, id := range targetsRole.KeyIDs {
			if key.PublicData().ContainsID(id) {
				found = true
				break
			}
		}
		if !found {
			c.Fatal("missing key")
		}
	}

	// check root.json got staged
	meta, err := local.GetMeta()
	c.Assert(err, IsNil)
	rootJSON, ok := meta["root.json"]
	if !ok {
		c.Fatal("missing root metadata")
	}
	s := &data.Signed{}
	c.Assert(json.Unmarshal(rootJSON, s), IsNil)
	stagedRoot := &data.Root{}
	c.Assert(json.Unmarshal(s.Signed, stagedRoot), IsNil)
	c.Assert(stagedRoot.Type, Equals, root.Type)
	c.Assert(stagedRoot.Version, Equals, root.Version)
	c.Assert(stagedRoot.Expires.UnixNano(), Equals, root.Expires.UnixNano())

	// make sure both root and stagedRoot have evaluated IDs(), otherwise
	// DeepEquals will fail because those values might not have been
	// computed yet.
	for _, key := range root.Keys {
		key.IDs()
	}
	for _, key := range stagedRoot.Keys {
		key.IDs()
	}
	c.Assert(stagedRoot.Keys, DeepEquals, root.Keys)
	c.Assert(stagedRoot.Roles, DeepEquals, root.Roles)
}

func addPrivateKey(c *C, r *Repo, role string, key keys.Signer) []string {
	err := r.AddPrivateKey(role, key)
	c.Assert(err, IsNil)
	keyids := key.PublicData().IDs()
	c.Assert(len(keyids) > 0, Equals, true)
	return keyids
}

func generateAndAddPrivateKey(c *C, r *Repo, role string) []string {
	signer, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	return addPrivateKey(c, r, role, signer)
}

func (rs *RepoSuite) TestAddPrivateKey(c *C) {
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// generate a key for an unknown role
	signer, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	err = r.AddPrivateKey("foo", signer)
	c.Assert(err, Equals, ErrInvalidRole{"foo", "only support adding keys for top-level roles"})

	// add a root key
	ids := addPrivateKey(c, r, "root", signer)

	// check root metadata is correct
	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Version, Equals, int64(1))
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 1)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rootRole, ok := root.Roles["root"]
	if !ok {
		c.Fatal("missing root role")
	}
	c.Assert(rootRole.KeyIDs, HasLen, 1)
	c.Assert(rootRole.KeyIDs, DeepEquals, ids)
	for _, keyID := range ids {
		k, ok := root.Keys[keyID]
		if !ok {
			c.Fatalf("missing key %s", keyID)
		}
		c.Assert(k.IDs(), DeepEquals, ids)
		pk, err := keys.GetVerifier(k)
		c.Assert(err, IsNil)
		c.Assert(pk.Public(), HasLen, ed25519.PublicKeySize)
	}

	// check root key + role are in db
	db, err := r.topLevelKeysDB()
	c.Assert(err, IsNil)
	for _, keyID := range ids {
		rootKey, err := db.GetVerifier(keyID)
		c.Assert(err, IsNil)
		c.Assert(rootKey.MarshalPublicKey().IDs(), DeepEquals, ids)
		role := db.GetRole("root")
		c.Assert(role.KeyIDs, DeepEquals, sets.StringSliceToSet(ids))

		// check the key was saved correctly
		localKeys, err := local.GetSigners("root")
		c.Assert(err, IsNil)
		c.Assert(localKeys, HasLen, 1)
		c.Assert(localKeys[0].PublicData().IDs(), DeepEquals, ids)

		// check RootKeys() is correct
		rootKeys, err := r.RootKeys()
		c.Assert(err, IsNil)
		c.Assert(rootKeys, HasLen, 1)
		c.Assert(rootKeys[0].IDs(), DeepEquals, rootKey.MarshalPublicKey().IDs())
		pk, err := keys.GetVerifier(rootKeys[0])
		c.Assert(err, IsNil)
		c.Assert(pk.Public(), DeepEquals, rootKey.Public())
	}

	rootKey, err := db.GetVerifier(ids[0])
	c.Assert(err, IsNil)

	// generate two targets keys
	generateAndAddPrivateKey(c, r, "targets")
	generateAndAddPrivateKey(c, r, "targets")

	// check root metadata is correct
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, HasLen, 2)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rs.assertNumUniqueKeys(c, root, "targets", 2)
	targetsRole, ok := root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, 2)
	targetKeyIDs := make(map[string]struct{}, 2)
	db, err = r.topLevelKeysDB()
	c.Assert(err, IsNil)
	for _, id := range targetsRole.KeyIDs {
		targetKeyIDs[id] = struct{}{}
		_, ok = root.Keys[id]
		if !ok {
			c.Fatal("missing key")
		}
		verifier, err := db.GetVerifier(id)
		c.Assert(err, IsNil)
		c.Assert(verifier.MarshalPublicKey().ContainsID(id), Equals, true)
	}
	role := db.GetRole("targets")
	c.Assert(role.KeyIDs, DeepEquals, targetKeyIDs)

	// check RootKeys() is unchanged
	rootKeys, err := r.RootKeys()
	c.Assert(err, IsNil)
	c.Assert(rootKeys, HasLen, 1)
	c.Assert(rootKeys[0].IDs(), DeepEquals, rootKey.MarshalPublicKey().IDs())

	// check the keys were saved correctly
	localKeys, err := local.GetSigners("targets")
	c.Assert(err, IsNil)
	c.Assert(localKeys, HasLen, 2)
	for _, key := range localKeys {
		found := false
		for _, id := range targetsRole.KeyIDs {
			if key.PublicData().ContainsID(id) {
				found = true
				break
			}
		}
		if !found {
			c.Fatal("missing key")
		}
	}

	// check root.json got staged
	meta, err := local.GetMeta()
	c.Assert(err, IsNil)
	rootJSON, ok := meta["root.json"]
	if !ok {
		c.Fatal("missing root metadata")
	}
	s := &data.Signed{}
	c.Assert(json.Unmarshal(rootJSON, s), IsNil)
	stagedRoot := &data.Root{}
	c.Assert(json.Unmarshal(s.Signed, stagedRoot), IsNil)
	c.Assert(stagedRoot.Type, Equals, root.Type)
	c.Assert(stagedRoot.Version, Equals, root.Version)
	c.Assert(stagedRoot.Expires.UnixNano(), Equals, root.Expires.UnixNano())

	// make sure both root and stagedRoot have evaluated IDs(), otherwise
	// DeepEquals will fail because those values might not have been
	// computed yet.
	for _, key := range root.Keys {
		key.IDs()
	}
	for _, key := range stagedRoot.Keys {
		key.IDs()
	}
	c.Assert(stagedRoot.Keys, DeepEquals, root.Keys)
	c.Assert(stagedRoot.Roles, DeepEquals, root.Roles)

	// commit to make sure we don't modify metadata after committing metadata.
	generateAndAddPrivateKey(c, r, "snapshot")
	generateAndAddPrivateKey(c, r, "timestamp")
	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// add the same root key to make sure the metadata is unmodified.
	oldRoot, err := r.root()
	c.Assert(err, IsNil)
	addPrivateKey(c, r, "root", signer)
	newRoot, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(oldRoot, DeepEquals, newRoot)
	if r.local.FileIsStaged("root.json") {
		c.Fatal("root should not be marked dirty")
	}
}

func (rs *RepoSuite) TestRevokeKey(c *C) {
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// revoking a key for an unknown role returns ErrInvalidRole
	c.Assert(r.RevokeKey("foo", ""), DeepEquals, ErrInvalidRole{"foo", "only revocations for top-level roles supported"})

	// revoking a key which doesn't exist returns ErrKeyNotFound
	c.Assert(r.RevokeKey("root", "nonexistent"), DeepEquals, ErrKeyNotFound{"root", "nonexistent"})

	// generate keys
	genKey(c, r, "root")
	target1IDs := genKey(c, r, "targets")
	target2IDs := genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 4)
	c.Assert(root.Keys, NotNil)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rs.assertNumUniqueKeys(c, root, "targets", 2)
	rs.assertNumUniqueKeys(c, root, "snapshot", 1)
	rs.assertNumUniqueKeys(c, root, "timestamp", 1)

	// revoke a key
	targetsRole, ok := root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, len(target1IDs)+len(target2IDs))
	id := targetsRole.KeyIDs[0]
	c.Assert(r.RevokeKey("targets", id), IsNil)

	// make sure all the other key ids were also revoked
	for _, id := range target1IDs {
		c.Assert(r.RevokeKey("targets", id), DeepEquals, ErrKeyNotFound{"targets", id})
	}

	// check root was updated
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 4)
	c.Assert(root.Keys, NotNil)
	rs.assertNumUniqueKeys(c, root, "root", 1)
	rs.assertNumUniqueKeys(c, root, "targets", 1)
	rs.assertNumUniqueKeys(c, root, "snapshot", 1)
	rs.assertNumUniqueKeys(c, root, "timestamp", 1)
	targetsRole, ok = root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, 1)
	c.Assert(targetsRole.KeyIDs, DeepEquals, target2IDs)
}

func (rs *RepoSuite) TestRevokeKeyInMultipleRoles(c *C) {
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// generate keys. add a root key that is shared with the targets role
	rootSigner, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("root", rootSigner.PublicData()), IsNil)
	sharedSigner, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	sharedIDs := sharedSigner.PublicData().IDs()
	c.Assert(r.AddVerificationKey("root", sharedSigner.PublicData()), IsNil)
	c.Assert(r.AddVerificationKey("targets", sharedSigner.PublicData()), IsNil)
	targetIDs := genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 4)
	c.Assert(root.Keys, NotNil)
	rs.assertNumUniqueKeys(c, root, "root", 2)
	rs.assertNumUniqueKeys(c, root, "targets", 2)
	rs.assertNumUniqueKeys(c, root, "snapshot", 1)
	rs.assertNumUniqueKeys(c, root, "timestamp", 1)

	// revoke a key
	targetsRole, ok := root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, len(targetIDs)+len(sharedIDs))
	id := targetsRole.KeyIDs[0]
	c.Assert(r.RevokeKey("targets", id), IsNil)

	// make sure all the other key ids were also revoked
	for _, id := range sharedIDs {
		c.Assert(r.RevokeKey("targets", id), DeepEquals, ErrKeyNotFound{"targets", id})
	}

	// check root was updated
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Roles, NotNil)
	c.Assert(root.Roles, HasLen, 4)
	c.Assert(root.Keys, NotNil)
	// the shared root/targets signer should still be present in root keys
	c.Assert(UniqueKeys(root)["root"], DeepEquals,
		[]*data.PublicKey{rootSigner.PublicData(), sharedSigner.PublicData()})
	rs.assertNumUniqueKeys(c, root, "root", 2)
	rs.assertNumUniqueKeys(c, root, "targets", 1)
	rs.assertNumUniqueKeys(c, root, "snapshot", 1)
	rs.assertNumUniqueKeys(c, root, "timestamp", 1)
	targetsRole, ok = root.Roles["targets"]
	if !ok {
		c.Fatal("missing targets role")
	}
	c.Assert(targetsRole.KeyIDs, HasLen, 1)
	c.Assert(targetsRole.KeyIDs, DeepEquals, targetIDs)
}

func (rs *RepoSuite) TestSign(c *C) {
	meta := map[string]json.RawMessage{"root.json": []byte(`{"signed":{},"signatures":[]}`)}
	local := MemoryStore(meta, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	c.Assert(r.Sign("foo.json"), Equals, ErrMissingMetadata{"foo.json"})

	// signing with no keys returns ErrNoKeys
	c.Assert(r.Sign("root.json"), Equals, ErrNoKeys{"root.json"})

	checkSigIDs := func(keyIDs ...string) {
		meta, err := local.GetMeta()
		c.Assert(err, IsNil)
		rootJSON, ok := meta["root.json"]
		if !ok {
			c.Fatal("missing root.json")
		}
		s := &data.Signed{}
		c.Assert(json.Unmarshal(rootJSON, s), IsNil)
		c.Assert(s.Signatures, HasLen, len(keyIDs))

		// Signatures may be in any order, so must sort key IDs before comparison.
		wantKeyIDs := append([]string{}, keyIDs...)
		sort.Strings(wantKeyIDs)

		gotKeyIDs := []string{}
		for _, sig := range s.Signatures {
			gotKeyIDs = append(gotKeyIDs, sig.KeyID)
		}
		sort.Strings(gotKeyIDs)

		c.Assert(wantKeyIDs, DeepEquals, gotKeyIDs)
	}

	// signing with an available key generates a signature
	signer, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(local.SaveSigner("root", signer), IsNil)
	c.Assert(r.Sign("root.json"), IsNil)
	checkSigIDs(signer.PublicData().IDs()...)

	// signing again does not generate a duplicate signature
	c.Assert(r.Sign("root.json"), IsNil)
	checkSigIDs(signer.PublicData().IDs()...)

	// signing with a new available key generates another signature
	newKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(local.SaveSigner("root", newKey), IsNil)
	c.Assert(r.Sign("root.json"), IsNil)
	checkSigIDs(append(signer.PublicData().IDs(), newKey.PublicData().IDs()...)...)

	// attempt to sign missing metadata
	c.Assert(r.Sign("targets.json"), Equals, ErrMissingMetadata{"targets.json"})
}

func (rs *RepoSuite) TestStatus(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	c.Assert(r.SnapshotWithExpires(time.Now().Add(24*time.Hour)), IsNil)
	c.Assert(r.TimestampWithExpires(time.Now().Add(1*time.Hour)), IsNil)
	c.Assert(r.Commit(), IsNil)

	expires := time.Now().Add(2 * time.Hour)
	c.Assert(r.CheckRoleUnexpired("timestamp", expires), ErrorMatches, "role expired on.*")
	c.Assert(r.CheckRoleUnexpired("snapshot", expires), IsNil)
	c.Assert(r.CheckRoleUnexpired("targets", expires), IsNil)
	c.Assert(r.CheckRoleUnexpired("root", expires), IsNil)
}

func (rs *RepoSuite) TestCommit(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo"), "bar.txt": []byte("bar")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// commit without root.json
	c.Assert(r.Commit(), DeepEquals, ErrMissingMetadata{"root.json"})

	// Init should create targets.json, but not signed yet
	r.Init(false)
	c.Assert(r.Commit(), DeepEquals, ErrMissingMetadata{"snapshot.json"})

	genKey(c, r, "root")

	// commit without snapshot.json
	genKey(c, r, "targets")
	c.Assert(r.Sign("targets.json"), IsNil)
	c.Assert(r.Commit(), DeepEquals, ErrMissingMetadata{"snapshot.json"})

	// commit without timestamp.json
	genKey(c, r, "snapshot")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Commit(), DeepEquals, ErrMissingMetadata{"timestamp.json"})

	// commit with timestamp.json but no timestamp key
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), DeepEquals, ErrInsufficientSignatures{"timestamp.json", verify.ErrNoSignatures})

	// commit success
	genKey(c, r, "timestamp")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// commit with an invalid root hash in snapshot.json due to new key creation
	genKey(c, r, "targets")
	c.Assert(r.Sign("targets.json"), IsNil)
	c.Assert(r.Commit(), DeepEquals, errors.New("tuf: invalid targets.json in snapshot.json: wrong length, expected 338 got 552"))

	// commit with an invalid targets hash in snapshot.json
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.AddTarget("bar.txt", nil), IsNil)
	c.Assert(r.Commit(), DeepEquals, errors.New("tuf: invalid targets.json in snapshot.json: wrong length, expected 552 got 725"))

	// commit with an invalid timestamp
	c.Assert(r.Snapshot(), IsNil)
	err = r.Commit()
	c.Assert(err, NotNil)
	c.Assert(err.Error()[0:44], Equals, "tuf: invalid snapshot.json in timestamp.json")

	// commit with a role's threshold greater than number of keys
	root, err := r.root()
	c.Assert(err, IsNil)
	role, ok := root.Roles["timestamp"]
	if !ok {
		c.Fatal("missing timestamp role")
	}
	c.Assert(role.KeyIDs, HasLen, 1)
	c.Assert(role.Threshold, Equals, 1)
	c.Assert(r.RevokeKey("timestamp", role.KeyIDs[0]), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), DeepEquals, ErrNotEnoughKeys{"timestamp", 0, 1})
}

func (rs *RepoSuite) TestCommitVersions(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// on initial commit everything should be at version 1.
	rootVersion, err := r.RootVersion()
	c.Assert(err, IsNil)
	c.Assert(rootVersion, Equals, int64(1))

	targetsVersion, err := r.TargetsVersion()
	c.Assert(err, IsNil)
	c.Assert(targetsVersion, Equals, int64(1))

	snapshotVersion, err := r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(snapshotVersion, Equals, int64(1))

	timestampVersion, err := r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(timestampVersion, Equals, int64(1))

	// taking a snapshot should only increment snapshot and timestamp.
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	rootVersion, err = r.RootVersion()
	c.Assert(err, IsNil)
	c.Assert(rootVersion, Equals, int64(1))

	targetsVersion, err = r.TargetsVersion()
	c.Assert(err, IsNil)
	c.Assert(targetsVersion, Equals, int64(1))

	snapshotVersion, err = r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(snapshotVersion, Equals, int64(2))

	timestampVersion, err = r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(timestampVersion, Equals, int64(2))

	// rotating multiple keys should increment the root once.
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	rootVersion, err = r.RootVersion()
	c.Assert(err, IsNil)
	c.Assert(rootVersion, Equals, int64(2))

	targetsVersion, err = r.TargetsVersion()
	c.Assert(err, IsNil)
	c.Assert(targetsVersion, Equals, int64(1))

	snapshotVersion, err = r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(snapshotVersion, Equals, int64(3))

	timestampVersion, err = r.TimestampVersion()
	c.Assert(err, IsNil)
	c.Assert(timestampVersion, Equals, int64(3))
}

type tmpDir struct {
	path string
	c    *C
}

func newTmpDir(c *C) *tmpDir {
	return &tmpDir{path: c.MkDir(), c: c}
}

func (t *tmpDir) assertExists(path string) {
	if _, err := os.Stat(filepath.Join(t.path, path)); os.IsNotExist(err) {
		t.c.Fatalf("expected path to exist but it doesn't: %s", path)
	}
}

func (t *tmpDir) assertNotExist(path string) {
	if _, err := os.Stat(filepath.Join(t.path, path)); !os.IsNotExist(err) {
		t.c.Fatalf("expected path to not exist but it does: %s", path)
	}
}

func (t *tmpDir) assertHashedFilesExist(path string, hashes data.Hashes) {
	t.c.Assert(len(hashes) > 0, Equals, true)
	for _, path := range util.HashedPaths(path, hashes) {
		t.assertExists(path)
	}
}

func (t *tmpDir) assertHashedFilesNotExist(path string, hashes data.Hashes) {
	for _, path := range util.HashedPaths(path, hashes) {
		t.assertNotExist(path)
	}
}

func (t *tmpDir) assertVersionedFileExist(path string, version int64) {
	t.assertExists(util.VersionedPath(path, version))
}

func (t *tmpDir) assertVersionedFileNotExist(path string, version int64) {
	t.assertNotExist(util.VersionedPath(path, version))
}

func (t *tmpDir) assertEmpty(dir string) {
	path := filepath.Join(t.path, dir)
	f, err := os.Stat(path)
	if os.IsNotExist(err) {
		t.c.Fatalf("expected dir to exist but it doesn't: %s", dir)
	}
	t.c.Assert(err, IsNil)
	t.c.Assert(f.IsDir(), Equals, true)

	entries, err := os.ReadDir(path)
	t.c.Assert(err, IsNil)
	// check that all (if any) entries are also empty
	for _, e := range entries {
		t.assertEmpty(filepath.Join(dir, e.Name()))
	}
}

func (t *tmpDir) assertFileContent(path, content string) {
	actual := t.readFile(path)
	t.c.Assert(string(actual), Equals, content)
}

func (t *tmpDir) stagedTargetPath(path string) string {
	return filepath.Join(t.path, "staged", "targets", path)
}

func (t *tmpDir) writeStagedTarget(path, data string) {
	path = t.stagedTargetPath(path)
	t.c.Assert(os.MkdirAll(filepath.Dir(path), 0755), IsNil)
	t.c.Assert(os.WriteFile(path, []byte(data), 0644), IsNil)
}

func (t *tmpDir) readFile(path string) []byte {
	t.assertExists(path)
	data, err := os.ReadFile(filepath.Join(t.path, path))
	t.c.Assert(err, IsNil)
	return data
}

func (rs *RepoSuite) TestCommitFileSystem(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// don't use consistent snapshots to make the checks simpler
	c.Assert(r.Init(false), IsNil)

	// cleaning with nothing staged or committed should fail
	c.Assert(r.Clean(), Equals, ErrNewRepository)

	// generating keys should stage root.json and create repo dirs
	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	tmp.assertExists("staged/root.json")
	tmp.assertEmpty("repository")
	tmp.assertEmpty("staged/targets")

	// cleaning with nothing committed should fail
	c.Assert(r.Clean(), Equals, ErrNewRepository)

	// adding a non-existent file fails
	c.Assert(r.AddTarget("foo.txt", nil), Equals, ErrFileNotFound{tmp.stagedTargetPath("foo.txt")})
	tmp.assertEmpty("repository")

	// adding a file stages targets.json
	tmp.writeStagedTarget("foo.txt", "foo")
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	tmp.assertExists("staged/targets.json")
	tmp.assertEmpty("repository")
	t, err := r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(t.Targets, HasLen, 1)
	if _, ok := t.Targets["foo.txt"]; !ok {
		c.Fatal("missing target file: foo.txt")
	}

	// Snapshot() stages snapshot.json
	c.Assert(r.Snapshot(), IsNil)
	tmp.assertExists("staged/snapshot.json")
	tmp.assertEmpty("repository")

	// Timestamp() stages timestamp.json
	c.Assert(r.Timestamp(), IsNil)
	tmp.assertExists("staged/timestamp.json")
	tmp.assertEmpty("repository")

	// committing moves files from staged -> repository
	c.Assert(r.Commit(), IsNil)
	tmp.assertExists("repository/root.json")
	tmp.assertExists("repository/targets.json")
	tmp.assertExists("repository/snapshot.json")
	tmp.assertExists("repository/timestamp.json")
	tmp.assertFileContent("repository/targets/foo.txt", "foo")
	tmp.assertEmpty("staged/targets")
	tmp.assertEmpty("staged")

	// adding and committing another file moves it into repository/targets
	tmp.writeStagedTarget("path/to/bar.txt", "bar")
	c.Assert(r.AddTarget("path/to/bar.txt", nil), IsNil)
	tmp.assertExists("staged/targets.json")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	tmp.assertFileContent("repository/targets/foo.txt", "foo")
	tmp.assertFileContent("repository/targets/path/to/bar.txt", "bar")
	tmp.assertEmpty("staged/targets")
	tmp.assertEmpty("staged")

	// removing and committing a file removes it from repository/targets
	c.Assert(r.RemoveTarget("foo.txt"), IsNil)
	tmp.assertExists("staged/targets.json")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	tmp.assertNotExist("repository/targets/foo.txt")
	tmp.assertFileContent("repository/targets/path/to/bar.txt", "bar")
	tmp.assertEmpty("staged/targets")
	tmp.assertEmpty("staged")
}

func (rs *RepoSuite) TestCommitFileSystemWithNewRepositories(c *C) {
	tmp := newTmpDir(c)

	newRepo := func() *Repo {
		local := FileSystemStore(tmp.path, nil)
		r, err := NewRepo(local)
		c.Assert(err, IsNil)
		return r
	}

	genKey(c, newRepo(), "root")
	genKey(c, newRepo(), "targets")
	genKey(c, newRepo(), "snapshot")
	genKey(c, newRepo(), "timestamp")

	tmp.writeStagedTarget("foo.txt", "foo")
	c.Assert(newRepo().AddTarget("foo.txt", nil), IsNil)
	c.Assert(newRepo().Snapshot(), IsNil)
	c.Assert(newRepo().Timestamp(), IsNil)
	c.Assert(newRepo().Commit(), IsNil)
}

func (rs *RepoSuite) TestConsistentSnapshot(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local, "sha512", "sha256")
	c.Assert(err, IsNil)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	tmp.writeStagedTarget("foo.txt", "foo")
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	tmp.writeStagedTarget("dir/bar.txt", "bar")
	c.Assert(r.AddTarget("dir/bar.txt", nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	versions, err := r.fileVersions()
	c.Assert(err, IsNil)
	c.Assert(versions["root.json"], Equals, int64(1))
	c.Assert(versions["targets.json"], Equals, int64(1))
	c.Assert(versions["snapshot.json"], Equals, int64(1))

	hashes, err := r.fileHashes()
	c.Assert(err, IsNil)

	// root.json, targets.json and snapshot.json should exist at both versioned and unversioned paths
	for _, meta := range []string{"root.json", "targets.json", "snapshot.json"} {
		repoPath := path.Join("repository", meta)
		if meta != "root.json" {
			c.Assert(len(hashes[meta]) > 0, Equals, true)
		}
		tmp.assertHashedFilesNotExist(repoPath, hashes[meta])
		tmp.assertVersionedFileExist(repoPath, versions[meta])
		tmp.assertExists(repoPath)
	}

	// target files should exist at hashed but not unhashed paths
	for _, target := range []string{"targets/foo.txt", "targets/dir/bar.txt"} {
		repoPath := path.Join("repository", target)
		tmp.assertHashedFilesExist(repoPath, hashes[target])
		tmp.assertNotExist(repoPath)
	}

	// timestamp.json should exist at an unversioned and unhashed path (it doesn't have a hash)
	c.Assert(hashes["repository/timestamp.json"], IsNil)
	tmp.assertVersionedFileNotExist("repository/timestamp.json", versions["repository/timestamp.json"])
	tmp.assertExists("repository/timestamp.json")

	// removing a file should remove the hashed files
	c.Assert(r.RemoveTarget("foo.txt"), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	versions, err = r.fileVersions()
	c.Assert(err, IsNil)
	c.Assert(versions["root.json"], Equals, int64(1))
	c.Assert(versions["targets.json"], Equals, int64(2))
	c.Assert(versions["snapshot.json"], Equals, int64(2))

	// Save the old hashes for foo.txt to make sure we can assert it doesn't exist later.
	fooHashes := hashes["targets/foo.txt"]
	hashes, err = r.fileHashes()
	c.Assert(err, IsNil)

	// root.json, targets.json and snapshot.json should exist at both versioned and unversioned paths
	for _, meta := range []string{"root.json", "targets.json", "snapshot.json"} {
		repoPath := path.Join("repository", meta)
		if meta != "root.json" {
			c.Assert(len(hashes[meta]) > 0, Equals, true)
		}
		tmp.assertHashedFilesNotExist(repoPath, hashes[meta])
		tmp.assertVersionedFileExist(repoPath, versions[meta])
		tmp.assertExists(repoPath)
	}

	tmp.assertHashedFilesNotExist("repository/targets/foo.txt", fooHashes)
	tmp.assertNotExist("repository/targets/foo.txt")

	// targets should be returned by new repo
	newRepo, err := NewRepo(local, "sha512", "sha256")
	c.Assert(err, IsNil)
	t, err := newRepo.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(t.Targets, HasLen, 1)
	if _, ok := t.Targets["dir/bar.txt"]; !ok {
		c.Fatal("missing targets file: dir/bar.txt")
	}
}

func (rs *RepoSuite) TestExpiresAndVersion(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	past := time.Now().Add(-1 * time.Second)
	_, genKeyErr := r.GenKeyWithExpires("root", past)
	for _, err := range []error{
		genKeyErr,
		r.AddTargetWithExpires("foo.txt", nil, past),
		r.RemoveTargetWithExpires("foo.txt", past),
		r.SnapshotWithExpires(past),
		r.TimestampWithExpires(past),
	} {
		c.Assert(err, Equals, ErrInvalidExpires{past})
	}

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Version, Equals, int64(1))

	expires := time.Now().Add(24 * time.Hour)
	_, err = r.GenKeyWithExpires("root", expires)
	c.Assert(err, IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Expires.Unix(), DeepEquals, expires.Round(time.Second).Unix())
	c.Assert(root.Version, Equals, int64(2))

	expires = time.Now().Add(12 * time.Hour)
	role, ok := root.Roles["root"]
	if !ok {
		c.Fatal("missing root role")
	}
	c.Assert(role.KeyIDs, HasLen, 2)
	c.Assert(r.RevokeKeyWithExpires("root", role.KeyIDs[0], expires), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	root, err = r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Expires.Unix(), DeepEquals, expires.Round(time.Second).Unix())
	c.Assert(root.Version, Equals, int64(3))

	expires = time.Now().Add(6 * time.Hour)
	c.Assert(r.AddTargetWithExpires("foo.txt", nil, expires), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	targets, err := r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(targets.Expires.Unix(), Equals, expires.Round(time.Second).Unix())
	c.Assert(targets.Version, Equals, int64(2))

	expires = time.Now().Add(2 * time.Hour)
	c.Assert(r.RemoveTargetWithExpires("foo.txt", expires), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	targets, err = r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(targets.Expires.Unix(), Equals, expires.Round(time.Second).Unix())
	c.Assert(targets.Version, Equals, int64(3))

	expires = time.Now().Add(time.Hour)
	c.Assert(r.SnapshotWithExpires(expires), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	snapshot, err := r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Expires.Unix(), Equals, expires.Round(time.Second).Unix())
	c.Assert(snapshot.Version, Equals, int64(6))

	_, snapshotHasRoot := snapshot.Meta["root.json"]
	c.Assert(snapshotHasRoot, Equals, false)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, targets.Version)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Version, Equals, int64(7))

	expires = time.Now().Add(10 * time.Minute)
	c.Assert(r.TimestampWithExpires(expires), IsNil)
	c.Assert(r.Commit(), IsNil)
	timestamp, err := r.timestamp()
	c.Assert(err, IsNil)
	c.Assert(timestamp.Expires.Unix(), Equals, expires.Round(time.Second).Unix())
	c.Assert(timestamp.Version, Equals, int64(8))

	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	timestamp, err = r.timestamp()
	c.Assert(err, IsNil)
	c.Assert(timestamp.Version, Equals, int64(9))
	c.Assert(timestamp.Meta["snapshot.json"].Version, Equals, snapshot.Version)
}

func (rs *RepoSuite) TestHashAlgorithm(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	type hashTest struct {
		args     []string
		expected []string
	}
	for _, test := range []hashTest{
		{args: []string{}, expected: []string{"sha512"}},
		{args: []string{"sha256"}},
		{args: []string{"sha512", "sha256"}},
	} {
		// generate metadata with specific hash functions
		r, err := NewRepo(local, test.args...)
		c.Assert(err, IsNil)
		genKey(c, r, "root")
		genKey(c, r, "targets")
		genKey(c, r, "snapshot")
		c.Assert(r.AddTarget("foo.txt", nil), IsNil)
		c.Assert(r.Snapshot(), IsNil)
		c.Assert(r.Timestamp(), IsNil)

		// check metadata has correct hash functions
		if test.expected == nil {
			test.expected = test.args
		}
		targets, err := r.topLevelTargets()
		c.Assert(err, IsNil)
		snapshot, err := r.snapshot()
		c.Assert(err, IsNil)
		timestamp, err := r.timestamp()
		c.Assert(err, IsNil)
		for name, file := range map[string]data.FileMeta{
			"foo.txt":       targets.Targets["foo.txt"].FileMeta,
			"targets.json":  {Length: snapshot.Meta["targets.json"].Length, Hashes: snapshot.Meta["targets.json"].Hashes},
			"snapshot.json": {Length: timestamp.Meta["snapshot.json"].Length, Hashes: timestamp.Meta["snapshot.json"].Hashes},
		} {
			for _, hashAlgorithm := range test.expected {
				if _, ok := file.Hashes[hashAlgorithm]; !ok {
					c.Fatalf("expected %s hash to contain hash func %s, got %s", name, hashAlgorithm, file.Hashes.HashAlgorithms())
				}
			}
		}
	}
}

func (rs *RepoSuite) TestKeyPersistence(c *C) {
	tmp := newTmpDir(c)
	oldPassphrase := []byte("old_s3cr3t")
	newPassphrase := []byte("new_s3cr3t")
	// returnNewPassphrase is used to force the passphrase function to return the new passphrase when called by the SaveSigner() method
	returnNewPassphrase := false
	// passphrase mock function
	testPassphraseFunc := func(a string, b, change bool) ([]byte, error) {
		if change || returnNewPassphrase {
			return newPassphrase, nil
		}
		return oldPassphrase, nil
	}
	store := FileSystemStore(tmp.path, testPassphraseFunc)

	assertKeys := func(role string, enc bool, expected []*data.PrivateKey) {
		keysJSON := tmp.readFile("keys/" + role + ".json")
		pk := &persistedKeys{}
		c.Assert(json.Unmarshal(keysJSON, pk), IsNil)

		// check the persisted keys are correct
		var actual []*data.PrivateKey
		pass := oldPassphrase
		if enc {
			c.Assert(pk.Encrypted, Equals, true)
			if returnNewPassphrase {
				pass = newPassphrase
			}
			decrypted, err := encrypted.Decrypt(pk.Data, pass)
			c.Assert(err, IsNil)
			c.Assert(json.Unmarshal(decrypted, &actual), IsNil)
		} else {
			c.Assert(pk.Encrypted, Equals, false)
			c.Assert(json.Unmarshal(pk.Data, &actual), IsNil)
		}

		// Compare slices of unique elements disregarding order.
		c.Assert(actual, HasLen, len(expected))
		for _, gotKey := range actual {
			expectedNumMatches := 0
			for _, x := range actual {
				if reflect.DeepEqual(gotKey, x) {
					expectedNumMatches++
				}
			}

			numMatches := 0
			for _, wantKey := range expected {
				wantCanon, err := cjson.EncodeCanonical(wantKey)
				c.Assert(err, IsNil)

				gotCanon, err := cjson.EncodeCanonical(gotKey)
				c.Assert(err, IsNil)

				if string(wantCanon) == string(gotCanon) {
					numMatches++
				}
			}

			c.Assert(numMatches, Equals, expectedNumMatches, Commentf("actual: %+v, expected: %+v", actual, expected))
		}

		// check GetKeys is correct
		signers, err := store.GetSigners(role)
		c.Assert(err, IsNil)

		// Compare slices of unique elements disregarding order.
		c.Assert(signers, HasLen, len(expected))
		for _, s := range signers {
			expectedNumMatches := 0
			for _, x := range signers {
				if reflect.DeepEqual(s, x) {
					expectedNumMatches++
				}
			}

			numMatches := 0
			for _, e := range expected {
				v, err := keys.GetSigner(e)
				c.Assert(err, IsNil)

				if reflect.DeepEqual(s.PublicData().IDs(), v.PublicData().IDs()) {
					numMatches++
				}
			}

			c.Assert(numMatches, Equals, expectedNumMatches, Commentf("signers: %+v, expected: %+v", signers, expected))
		}
	}

	// save a key and check it gets encrypted
	signer, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	privateKey, err := signer.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(store.SaveSigner("root", signer), IsNil)
	assertKeys("root", true, []*data.PrivateKey{privateKey})

	// save another key and check it gets added to the existing keys
	newKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	newPrivateKey, err := newKey.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(store.SaveSigner("root", newKey), IsNil)
	assertKeys("root", true, []*data.PrivateKey{privateKey, newPrivateKey})

	// check saving a key to an encrypted file without a passphrase fails
	insecureStore := FileSystemStore(tmp.path, nil)
	signer, err = keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(insecureStore.SaveSigner("root", signer), Equals, ErrPassphraseRequired{"root"})

	// save a key to an insecure store and check it is not encrypted
	signer, err = keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	privateKey, err = signer.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(insecureStore.SaveSigner("targets", signer), IsNil)
	assertKeys("targets", false, []*data.PrivateKey{privateKey})

	c.Assert(insecureStore.SaveSigner("foo", signer), IsNil)
	assertKeys("foo", false, []*data.PrivateKey{privateKey})

	// Test changing the passphrase
	// 1. Create a secure store with a passphrase (create new object and temp folder so we discard any previous state)
	tmp = newTmpDir(c)
	store = FileSystemStore(tmp.path, testPassphraseFunc)

	// 1.5. Changing passphrase works for top-level and delegated roles.
	r, err := NewRepo(store)
	c.Assert(err, IsNil)

	c.Assert(r.ChangePassphrase("targets"), NotNil)
	c.Assert(r.ChangePassphrase("foo"), NotNil)

	// 2. Test changing the passphrase when the keys file does not exist - should FAIL
	c.Assert(store.(PassphraseChanger).ChangePassphrase("root"), NotNil)

	// 3. Generate a new key
	signer, err = keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	privateKey, err = signer.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(store.SaveSigner("root", signer), IsNil)

	// 4. Verify the key file can be decrypted using the original passphrase - should SUCCEED
	assertKeys("root", true, []*data.PrivateKey{privateKey})

	// 5. Change the passphrase (our mock passphrase function is called with change=true thus returning the newPassphrase value)
	c.Assert(store.(PassphraseChanger).ChangePassphrase("root"), IsNil)

	// 6. Try to add a key and implicitly decrypt the keys file using the OLD passphrase - should FAIL
	newKey, err = keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	_, err = newKey.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(store.SaveSigner("root", newKey), NotNil)

	// 7. Try to add a key and implicitly decrypt the keys using the NEW passphrase - should SUCCEED
	returnNewPassphrase = true
	newKey, err = keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	newPrivateKey, err = newKey.MarshalPrivateKey()
	c.Assert(err, IsNil)
	c.Assert(store.SaveSigner("root", newKey), IsNil)

	// 8. Verify again that the key entries are what we expect after decrypting them using the NEW passphrase
	assertKeys("root", true, []*data.PrivateKey{privateKey, newPrivateKey})
}

func (rs *RepoSuite) TestManageMultipleTargets(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)
	// don't use consistent snapshots to make the checks simpler
	c.Assert(r.Init(false), IsNil)
	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	assertRepoTargets := func(paths ...string) {
		t, err := r.topLevelTargets()
		c.Assert(err, IsNil)
		for _, path := range paths {
			if _, ok := t.Targets[path]; !ok {
				c.Fatalf("missing target file: %s", path)
			}
		}
	}

	// adding and committing multiple files moves correct targets from staged -> repository
	tmp.writeStagedTarget("foo.txt", "foo")
	tmp.writeStagedTarget("bar.txt", "bar")
	c.Assert(r.AddTargets([]string{"foo.txt", "bar.txt"}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	assertRepoTargets("foo.txt", "bar.txt")
	tmp.assertExists("repository/targets/foo.txt")
	tmp.assertExists("repository/targets/bar.txt")

	// adding all targets moves them all from staged -> repository
	count := 10
	files := make([]string, count)
	for i := 0; i < count; i++ {
		files[i] = fmt.Sprintf("file%d.txt", i)
		tmp.writeStagedTarget(files[i], "data")
	}
	c.Assert(r.AddTargets(nil, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	tmp.assertExists("repository/targets/foo.txt")
	tmp.assertExists("repository/targets/bar.txt")
	assertRepoTargets(files...)
	for _, file := range files {
		tmp.assertExists("repository/targets/" + file)
	}
	tmp.assertEmpty("staged/targets")
	tmp.assertEmpty("staged")

	// removing all targets removes them from the repository and targets.json
	c.Assert(r.RemoveTargets(nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
	tmp.assertNotExist("repository/targets")
	t, err := r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(t.Targets, HasLen, 0)
}

func (rs *RepoSuite) TestCustomTargetMetadata(c *C) {
	files := map[string][]byte{
		"foo.txt": []byte("foo"),
		"bar.txt": []byte("bar"),
		"baz.txt": []byte("baz"),
	}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	generateAndAddPrivateKey(c, r, "targets")

	custom := json.RawMessage(`{"foo":"bar"}`)
	assertCustomMeta := func(file string, custom *json.RawMessage) {
		t, err := r.topLevelTargets()
		c.Assert(err, IsNil)
		target, ok := t.Targets[file]
		if !ok {
			c.Fatalf("missing target file: %s", file)
		}
		c.Assert(target.Custom, DeepEquals, custom)
	}

	// check custom metadata gets added to the target
	c.Assert(r.AddTarget("foo.txt", custom), IsNil)
	assertCustomMeta("foo.txt", &custom)

	// check adding bar.txt with no metadata doesn't affect foo.txt
	c.Assert(r.AddTarget("bar.txt", nil), IsNil)
	assertCustomMeta("bar.txt", nil)
	assertCustomMeta("foo.txt", &custom)

	// check adding all files with no metadata doesn't reset existing metadata
	c.Assert(r.AddTargets(nil, nil), IsNil)
	assertCustomMeta("baz.txt", nil)
	assertCustomMeta("bar.txt", nil)
	assertCustomMeta("foo.txt", &custom)
}

func (rs *RepoSuite) TestUnknownKeyIDs(c *C) {
	// generate a repo
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	// add a new key to the root metadata with an unknown key id.
	signer, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)

	root, err := r.root()
	c.Assert(err, IsNil)
	c.Assert(root.Version, Equals, int64(1))

	root.Keys["unknown-key-id"] = signer.PublicData()
	r.setMeta("root.json", root)

	// commit the metadata to the store.
	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// validate that the unknown key id wasn't stripped when written to the
	// store.
	meta, err := local.GetMeta()
	c.Assert(err, IsNil)

	rootJSON, ok := meta["root.json"]
	c.Assert(ok, Equals, true)

	var signedRoot struct {
		Signed     data.Root        `json:"signed"`
		Signatures []data.Signature `json:"signatures"`
	}
	c.Assert(json.Unmarshal(rootJSON, &signedRoot), IsNil)
	c.Assert(signedRoot.Signed.Version, Equals, int64(1))

	unknownKey, ok := signedRoot.Signed.Keys["unknown-key-id"]
	c.Assert(ok, Equals, true)
	c.Assert(unknownKey, DeepEquals, signer.PublicData())

	// a new root should preserve the unknown key id.
	root, err = r.root()
	c.Assert(root, NotNil)
	c.Assert(err, IsNil)

	genKey(c, r, "timestamp")
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	meta, err = local.GetMeta()
	c.Assert(err, IsNil)

	rootJSON, ok = meta["root.json"]
	c.Assert(ok, Equals, true)

	c.Assert(json.Unmarshal(rootJSON, &signedRoot), IsNil)
	c.Assert(signedRoot.Signed.Version, Equals, int64(2))

	unknownKey, ok = signedRoot.Signed.Keys["unknown-key-id"]
	c.Assert(ok, Equals, true)
	c.Assert(unknownKey, DeepEquals, signer.PublicData())
}

func (rs *RepoSuite) TestThreshold(c *C) {
	local := MemoryStore(make(map[string]json.RawMessage), nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	_, err = r.GetThreshold("root")
	c.Assert(err, DeepEquals, ErrInvalidRole{"root", "role missing from root metadata"})
	err = r.SetThreshold("root", 2)
	c.Assert(err, DeepEquals, ErrInvalidRole{"root", "role missing from root metadata"})

	// Add one key to each role
	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	t, err := r.GetThreshold("root")
	c.Assert(err, IsNil)
	c.Assert(t, Equals, 1)

	_, err = r.GetThreshold("foo")
	c.Assert(err, DeepEquals, ErrInvalidRole{"foo", "only thresholds for top-level roles supported"})
	err = r.SetThreshold("foo", 2)
	c.Assert(err, DeepEquals, ErrInvalidRole{"foo", "only thresholds for top-level roles supported"})

	// commit the metadata to the store.
	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// Set a new threshold. Commit without threshold keys
	c.Assert(r.SetThreshold("root", 2), IsNil)
	t, err = r.GetThreshold("root")
	c.Assert(err, IsNil)
	c.Assert(t, Equals, 2)
	c.Assert(r.Commit(), DeepEquals, ErrNotEnoughKeys{"root", 1, 2})

	// Add a second root key and try again
	genKey(c, r, "root")
	c.Assert(r.Sign("root.json"), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// Check versions updated
	rootVersion, err := r.RootVersion()
	c.Assert(err, IsNil)
	c.Assert(rootVersion, Equals, int64(2))

	targetsVersion, err := r.TargetsVersion()
	c.Assert(err, IsNil)
	c.Assert(targetsVersion, Equals, int64(1))

	snapshotVersion, err := r.SnapshotVersion()
	c.Assert(err, IsNil)
	c.Assert(snapshotVersion, Equals, int64(2))

	timestampVersion, err := r.TimestampVersion()
	c.Assert(err, IsNil)
	c.Assert(timestampVersion, Equals, int64(2))
}

func (rs *RepoSuite) TestAddOrUpdateSignatures(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// don't use consistent snapshots to make the checks simpler
	c.Assert(r.Init(false), IsNil)

	// generate root key offline and add as a verification key
	rootKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("root", rootKey.PublicData()), IsNil)
	targetsKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("targets", targetsKey.PublicData()), IsNil)
	snapshotKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("snapshot", snapshotKey.PublicData()), IsNil)
	timestampKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("timestamp", timestampKey.PublicData()), IsNil)

	// generate signatures externally and append
	rootMeta, err := r.SignedMeta("root.json")
	c.Assert(err, IsNil)
	rootCanonical, err := cjson.EncodeCanonical(rootMeta.Signed)
	c.Assert(err, IsNil)
	rootSig, err := rootKey.SignMessage(rootCanonical)
	c.Assert(err, IsNil)
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root.json", data.Signature{
			KeyID:     id,
			Signature: rootSig}), IsNil)
	}

	// add targets and sign
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	targetsMeta, err := r.SignedMeta("targets.json")
	c.Assert(err, IsNil)
	targetsCanonical, err := cjson.EncodeCanonical(targetsMeta.Signed)
	c.Assert(err, IsNil)
	targetsSig, err := targetsKey.SignMessage(targetsCanonical)
	c.Assert(err, IsNil)
	for _, id := range targetsKey.PublicData().IDs() {
		r.AddOrUpdateSignature("targets.json", data.Signature{
			KeyID:     id,
			Signature: targetsSig})
	}

	// snapshot and timestamp
	c.Assert(r.Snapshot(), IsNil)
	snapshotMeta, err := r.SignedMeta("snapshot.json")
	c.Assert(err, IsNil)
	snapshotCanonical, err := cjson.EncodeCanonical(snapshotMeta.Signed)
	c.Assert(err, IsNil)
	snapshotSig, err := snapshotKey.SignMessage(snapshotCanonical)
	c.Assert(err, IsNil)
	for _, id := range snapshotKey.PublicData().IDs() {
		r.AddOrUpdateSignature("snapshot.json", data.Signature{
			KeyID:     id,
			Signature: snapshotSig})
	}

	c.Assert(r.Timestamp(), IsNil)
	timestampMeta, err := r.SignedMeta("timestamp.json")
	c.Assert(err, IsNil)
	timestampCanonical, err := cjson.EncodeCanonical(timestampMeta.Signed)
	c.Assert(err, IsNil)
	timestampSig, err := timestampKey.SignMessage(timestampCanonical)
	c.Assert(err, IsNil)
	for _, id := range timestampKey.PublicData().IDs() {
		r.AddOrUpdateSignature("timestamp.json", data.Signature{
			KeyID:     id,
			Signature: timestampSig})
	}

	// commit successfully!
	c.Assert(r.Commit(), IsNil)
}

func (rs *RepoSuite) TestBadAddOrUpdateSignatures(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// don't use consistent snapshots to make the checks simpler
	c.Assert(r.Init(false), IsNil)

	c.Assert(r.AddOrUpdateSignature("targets.json", data.Signature{
		KeyID:     "foo",
		Signature: nil}), Equals, ErrInvalidRole{"targets", "role is not in verifier DB"})

	// generate root key offline and add as a verification key
	rootKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("root", rootKey.PublicData()), IsNil)
	targetsKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("targets", targetsKey.PublicData()), IsNil)
	snapshotKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("snapshot", snapshotKey.PublicData()), IsNil)
	timestampKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	c.Assert(r.AddVerificationKey("timestamp", timestampKey.PublicData()), IsNil)

	// attempt to sign `root`, rather than `root.json`
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root", data.Signature{
			KeyID:     id,
			Signature: nil}), Equals, ErrMissingMetadata{"root"})
	}

	// add a signature with a bad role
	rootMeta, err := r.SignedMeta("root.json")
	c.Assert(err, IsNil)
	rootCanonical, err := cjson.EncodeCanonical(rootMeta.Signed)
	c.Assert(err, IsNil)
	rootSig, err := rootKey.Sign(rand.Reader, rootCanonical, crypto.Hash(0))
	c.Assert(err, IsNil)
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("invalid_root.json", data.Signature{
			KeyID:     id,
			Signature: rootSig}), Equals, ErrInvalidRole{"invalid_root", "no trusted keys for role"})
	}

	// add a root signature with an key ID that is for the targets role
	for _, id := range targetsKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root.json", data.Signature{
			KeyID:     id,
			Signature: rootSig}), Equals, verify.ErrInvalidKey)
	}

	// attempt to add a bad signature to root
	badSig, err := rootKey.Sign(rand.Reader, []byte(""), crypto.Hash(0))
	c.Assert(err, IsNil)
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root.json", data.Signature{
			KeyID:     id,
			Signature: badSig}), Equals, verify.ErrInvalid)
	}

	// add the correct root signature
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root.json", data.Signature{
			KeyID:     id,
			Signature: rootSig}), IsNil)
	}
	checkSigIDs := func(role string) {
		s, err := r.SignedMeta(role)
		c.Assert(err, IsNil)
		db, err := r.topLevelKeysDB()
		c.Assert(err, IsNil)
		// keys is a map of key IDs.
		keys := db.GetRole(strings.TrimSuffix(role, ".json")).KeyIDs
		c.Assert(s.Signatures, HasLen, len(keys))
		// If the lengths are equal, and each signature key ID appears
		// in the role keys, they Sig IDs are equal to keyIDs.
		for _, sig := range s.Signatures {
			if _, ok := keys[sig.KeyID]; !ok {
				c.Fatal("missing key ID in signatures")
			}
		}
	}
	checkSigIDs("root.json")

	// re-adding should not duplicate. this is checked by verifying
	// signature key IDs match with the map of role key IDs.
	for _, id := range rootKey.PublicData().IDs() {
		c.Assert(r.AddOrUpdateSignature("root.json", data.Signature{
			KeyID:     id,
			Signature: rootSig}), IsNil)
	}
	checkSigIDs("root.json")
}

func (rs *RepoSuite) TestSignDigest(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	digest := "sha256:bc11b176a293bb341a0f2d0d226f52e7fcebd186a7c4dfca5fc64f305f06b94c"
	hash := "bc11b176a293bb341a0f2d0d226f52e7fcebd186a7c4dfca5fc64f305f06b94c"
	size := int64(42)

	c.Assert(r.AddTargetsWithDigest(hash, "sha256", size, digest, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	digest_bytes, err := hex.DecodeString("bc11b176a293bb341a0f2d0d226f52e7fcebd186a7c4dfca5fc64f305f06b94c")
	hex_digest_bytes := data.HexBytes(digest_bytes)
	c.Assert(err, IsNil)

	targets, err := r.topLevelTargets()
	c.Assert(err, IsNil)
	c.Assert(targets.Targets["sha256:bc11b176a293bb341a0f2d0d226f52e7fcebd186a7c4dfca5fc64f305f06b94c"].FileMeta.Length, Equals, size)
	c.Assert(targets.Targets["sha256:bc11b176a293bb341a0f2d0d226f52e7fcebd186a7c4dfca5fc64f305f06b94c"].FileMeta.Hashes["sha256"], DeepEquals, hex_digest_bytes)
}

func concat(ss ...[]string) []string {
	ret := []string{}
	for _, s := range ss {
		ret = append(ret, s...)
	}
	return ret
}

func checkSigKeyIDs(c *C, local LocalStore, fileToKeyIDs map[string][]string) {
	metas, err := local.GetMeta()
	c.Assert(err, IsNil)

	for f, keyIDs := range fileToKeyIDs {
		meta, ok := metas[f]
		c.Assert(ok, Equals, true, Commentf("meta file: %v", f))

		s := &data.Signed{}
		err = json.Unmarshal(meta, s)
		c.Assert(err, IsNil)

		gotKeyIDs := []string{}
		for _, sig := range s.Signatures {
			gotKeyIDs = append(gotKeyIDs, sig.KeyID)
		}
		gotKeyIDs = sets.DeduplicateStrings(gotKeyIDs)
		sort.Strings(gotKeyIDs)

		sort.Strings(keyIDs)
		c.Assert(gotKeyIDs, DeepEquals, keyIDs)
	}
}

func (rs *RepoSuite) TestDelegations(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Add one key to each role
	genKey(c, r, "root")
	targetsKeyIDs := genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	// commit the metadata to the store.
	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err := r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 1)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(1))

	checkSigKeyIDs(c, local, map[string][]string{
		"1.targets.json": targetsKeyIDs,
	})

	saveNewKey := func(role string) keys.Signer {
		key, err := keys.GenerateEd25519Key()
		c.Assert(err, IsNil)

		err = local.SaveSigner(role, key)
		c.Assert(err, IsNil)

		return key
	}

	// Delegate from targets -> role1 for A/*, B/* with one key, threshold 1.
	role1ABKey := saveNewKey("role1")
	role1AB := data.DelegatedRole{
		Name:      "role1",
		KeyIDs:    role1ABKey.PublicData().IDs(),
		Paths:     []string{"A/*", "B/*"},
		Threshold: 1,
	}
	err = r.AddDelegatedRole("targets", role1AB, []*data.PublicKey{
		role1ABKey.PublicData(),
	})
	c.Assert(err, IsNil)

	// Adding duplicate delegation should return an error.
	err = r.AddDelegatedRole("targets", role1AB, []*data.PublicKey{
		role1ABKey.PublicData(),
	})
	c.Assert(err, NotNil)

	// Delegate from targets -> role2 for C/*, D/* with three key, threshold 2.
	role2CDKey1 := saveNewKey("role2")
	role2CDKey2 := saveNewKey("role2")
	role2CDKey3 := saveNewKey("role2")
	role2CD := data.DelegatedRole{
		Name: "role2",
		KeyIDs: concat(
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
		),
		Paths:     []string{"C/*", "D/*"},
		Threshold: 2,
	}
	err = r.AddDelegatedRole("targets", role2CD, []*data.PublicKey{
		role2CDKey1.PublicData(),
		role2CDKey2.PublicData(),
		role2CDKey3.PublicData(),
	})
	c.Assert(err, IsNil)

	// Delegate from role1 -> role2 for A/allium.txt with one key, threshold 1.
	role1To2Key := saveNewKey("role2")
	role1To2 := data.DelegatedRole{
		Name:        "role2",
		KeyIDs:      role1To2Key.PublicData().IDs(),
		Paths:       []string{"A/allium.txt"},
		Threshold:   1,
		Terminating: true,
	}
	err = r.AddDelegatedRole("role1", role1To2, []*data.PublicKey{
		role1To2Key.PublicData(),
	})
	c.Assert(err, IsNil)

	checkDelegations := func(delegator string, delegatedRoles ...data.DelegatedRole) {
		t, err := r.targets(delegator)
		c.Assert(err, IsNil)

		// Check that delegated roles are copied verbatim.
		c.Assert(t.Delegations.Roles, DeepEquals, delegatedRoles)

		// Check that public keys match key IDs in roles.
		expectedKeyIDs := []string{}
		for _, dr := range delegatedRoles {
			expectedKeyIDs = append(expectedKeyIDs, dr.KeyIDs...)
		}
		expectedKeyIDs = sets.DeduplicateStrings(expectedKeyIDs)
		sort.Strings(expectedKeyIDs)

		gotKeyIDs := []string{}
		for _, k := range t.Delegations.Keys {
			gotKeyIDs = append(gotKeyIDs, k.IDs()...)
		}
		gotKeyIDs = sets.DeduplicateStrings(gotKeyIDs)
		sort.Strings(gotKeyIDs)

		c.Assert(gotKeyIDs, DeepEquals, expectedKeyIDs)
	}

	checkDelegations("targets", role1AB, role2CD)
	checkDelegations("role1", role1To2)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(2))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(1))

	checkSigKeyIDs(c, local, map[string][]string{
		"2.targets.json": targetsKeyIDs,
		"1.role1.json":   role1ABKey.PublicData().IDs(),
		"1.role2.json": concat(
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
			role1To2Key.PublicData().IDs(),
		),
	})

	// Add a variety of targets.
	files := map[string]string{
		// targets.json
		"potato.txt": "potatoes can be starchy or waxy",
		// role1.json
		"A/apple.txt":  "apples are sometimes red",
		"B/banana.txt": "bananas are yellow and sometimes brown",
		// role2.json
		"C/clementine.txt": "clementines are a citrus fruit",
		"D/durian.txt":     "durians are spiky",
		"A/allium.txt":     "alliums include garlic and leeks",
	}
	for name, content := range files {
		tmp.writeStagedTarget(name, content)
		c.Assert(r.AddTarget(name, nil), IsNil)
	}

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	// All roles should have new targets.
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(2))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(2))

	checkSigKeyIDs(c, local, map[string][]string{
		"3.targets.json": targetsKeyIDs,
		"2.role1.json":   role1ABKey.PublicData().IDs(),
		"2.role2.json": concat(
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
			role1To2Key.PublicData().IDs(),
		),
	})

	// Check that the given targets role has signed for the given filenames, with
	// the correct file metadata.
	checkTargets := func(role string, filenames ...string) {
		t, err := r.targets(role)
		c.Assert(err, IsNil)
		c.Assert(t.Targets, HasLen, len(filenames))

		for _, fn := range filenames {
			content := files[fn]

			fm, err := util.GenerateTargetFileMeta(strings.NewReader(content))
			c.Assert(err, IsNil)

			c.Assert(util.TargetFileMetaEqual(t.Targets[fn], fm), IsNil)
		}
	}

	checkTargets("targets", "potato.txt")
	checkTargets("role1", "A/apple.txt", "B/banana.txt")
	checkTargets("role2", "C/clementine.txt", "D/durian.txt", "A/allium.txt")

	// Test AddTargetToPreferredRole.
	// role2 is the default signer for A/allium.txt, but role1 is also eligible
	// for A/*.txt according to the delegation from the top-level targets role.
	c.Assert(r.RemoveTarget("A/allium.txt"), IsNil)
	tmp.writeStagedTarget("A/allium.txt", files["A/allium.txt"])
	c.Assert(r.AddTargetToPreferredRole("A/allium.txt", nil, "role1"), IsNil)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	// Only role1 and role2 should have bumped versions.
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(3))

	checkSigKeyIDs(c, local, map[string][]string{
		"3.targets.json": targetsKeyIDs,
		"3.role1.json":   role1ABKey.PublicData().IDs(),
		"3.role2.json": concat(
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
			role1To2Key.PublicData().IDs(),
		),
	})

	// role1 now signs A/allium.txt.
	checkTargets("targets", "potato.txt")
	checkTargets("role1", "A/apple.txt", "B/banana.txt", "A/allium.txt")
	checkTargets("role2", "C/clementine.txt", "D/durian.txt")

	// Remove the delegation from role1 to role2.
	c.Assert(r.ResetTargetsDelegations("role1"), IsNil)
	checkDelegations("targets", role1AB, role2CD)
	checkDelegations("role1")

	// Try to sign A/allium.txt with role2.
	// It should fail since we removed the role1 -> role2 delegation.
	c.Assert(r.RemoveTarget("A/allium.txt"), IsNil)
	tmp.writeStagedTarget("A/allium.txt", files["A/allium.txt"])
	c.Assert(r.AddTargetToPreferredRole("A/allium.txt", nil, "role2"), Equals, ErrNoDelegatedTarget{Path: "A/allium.txt"})

	// Try to sign A/allium.txt with the default role (role1).
	c.Assert(r.AddTarget("A/allium.txt", nil), IsNil)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	// Only role1 should have a bumped version.
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(4))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(3))

	checkSigKeyIDs(c, local, map[string][]string{
		"3.targets.json": targetsKeyIDs,
		"4.role1.json":   role1ABKey.PublicData().IDs(),
		"3.role2.json": concat(
			// Metadata (and therefore signers) for role2.json shouldn't have
			// changed, even though we revoked role1To2Key. Clients verify the
			// signature using keys specified by 4.role1.json, so role1To2Key
			// shouldn't contribute to the threshold.
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
			role1To2Key.PublicData().IDs(),
		),
	})

	// Re-sign target signed by role2 to test that role1To2Key is not used going
	// forward.
	c.Assert(r.RemoveTarget("C/clementine.txt"), IsNil)
	tmp.writeStagedTarget("C/clementine.txt", files["C/clementine.txt"])
	c.Assert(r.AddTarget("C/clementine.txt", nil), IsNil)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	// Only role2 should have a bumped version.
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(4))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(4))

	checkSigKeyIDs(c, local, map[string][]string{
		"3.targets.json": targetsKeyIDs,
		"4.role1.json":   role1ABKey.PublicData().IDs(),
		"4.role2.json": concat(
			role2CDKey1.PublicData().IDs(),
			role2CDKey2.PublicData().IDs(),
			role2CDKey3.PublicData().IDs(),
			// Note that role1To2Key no longer signs since the role1 -> role2
			// delegation was removed.
		),
	})

	// Targets should still be signed by the same roles.
	checkTargets("targets", "potato.txt")
	checkTargets("role1", "A/apple.txt", "B/banana.txt", "A/allium.txt")
	checkTargets("role2", "C/clementine.txt", "D/durian.txt")

	// Add back the role1 -> role2 delegation, and verify that it doesn't change
	// existing targets in role2.json.
	err = r.AddDelegatedRole("role1", role1To2, []*data.PublicKey{
		role1To2Key.PublicData(),
	})
	c.Assert(err, IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 3)
	// Both role1 and role2 should have a bumped version.
	// role1 is bumped because the delegations changed.
	// role2 is only bumped because its expiration is bumped.
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(5))
	c.Assert(snapshot.Meta["role2.json"].Version, Equals, int64(5))

	checkTargets("targets", "potato.txt")
	checkTargets("role1", "A/apple.txt", "B/banana.txt", "A/allium.txt")
	checkTargets("role2", "C/clementine.txt", "D/durian.txt")
}

func (rs *RepoSuite) TestHashBinDelegations(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Add one key to each role
	genKey(c, r, "root")
	targetsKeyIDs := genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	hb, err := targets.NewHashBins("bins_", 3)
	if err != nil {
		c.Assert(err, IsNil)
	}

	// Generate key for the intermediate bins role.
	binsKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	err = local.SaveSigner("bins", binsKey)
	c.Assert(err, IsNil)

	// Generate key for the leaf bins role.
	leafKey, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)
	for i := uint64(0); i < hb.NumBins(); i++ {
		b := hb.GetBin(i)
		err = local.SaveSigner(b.RoleName(), leafKey)
		if err != nil {
			c.Assert(err, IsNil)
		}
	}

	err = r.AddDelegatedRole("targets", data.DelegatedRole{
		Name:      "bins",
		KeyIDs:    binsKey.PublicData().IDs(),
		Paths:     []string{"*.txt"},
		Threshold: 1,
	}, []*data.PublicKey{
		binsKey.PublicData(),
	})
	c.Assert(err, IsNil)

	err = r.AddDelegatedRolesForPathHashBins("bins", hb, []*data.PublicKey{leafKey.PublicData()}, 1)
	c.Assert(err, IsNil)
	targets, err := r.targets("bins")
	c.Assert(err, IsNil)
	c.Assert(targets.Delegations.Roles, HasLen, 8)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	tmp.writeStagedTarget("foo.txt", "foo")
	err = r.AddTarget("foo.txt", nil)
	c.Assert(err, IsNil)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err := r.snapshot()
	c.Assert(err, IsNil)
	// 1 targets.json, 1 bins.json, 8 bins_*.json.
	c.Assert(snapshot.Meta, HasLen, 10)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_0-1.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_2-3.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_4-5.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_6-7.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_8-9.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_a-b.json"].Version, Equals, int64(1))
	c.Assert(snapshot.Meta["bins_c-d.json"].Version, Equals, int64(2))
	c.Assert(snapshot.Meta["bins_e-f.json"].Version, Equals, int64(1))

	targets, err = r.targets("bins_c-d")
	c.Assert(err, IsNil)
	c.Assert(targets.Targets, HasLen, 1)

	checkSigKeyIDs(c, local, map[string][]string{
		"targets.json":    targetsKeyIDs,
		"1.bins.json":     binsKey.PublicData().IDs(),
		"1.bins_0-1.json": leafKey.PublicData().IDs(),
		"1.bins_2-3.json": leafKey.PublicData().IDs(),
		"1.bins_4-5.json": leafKey.PublicData().IDs(),
		"1.bins_6-7.json": leafKey.PublicData().IDs(),
		"1.bins_8-9.json": leafKey.PublicData().IDs(),
		"1.bins_a-b.json": leafKey.PublicData().IDs(),
		"1.bins_c-d.json": leafKey.PublicData().IDs(),
		"2.bins_c-d.json": leafKey.PublicData().IDs(),
		"1.bins_e-f.json": leafKey.PublicData().IDs(),
	})
}

func (rs *RepoSuite) TestResetTargetsDelegationsWithExpires(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Add one key to each role
	genKey(c, r, "root")
	targetsKeyIDs := genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	// commit the metadata to the store.
	c.Assert(r.AddTargets([]string{}, nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err := r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 1)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(1))

	checkSigKeyIDs(c, local, map[string][]string{
		"1.targets.json": targetsKeyIDs,
	})

	role1Key, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)

	err = local.SaveSigner("role1", role1Key)
	c.Assert(err, IsNil)

	// Delegate from targets -> role1 for A/*, B/* with one key, threshold 1.
	role1 := data.DelegatedRole{
		Name:      "role1",
		KeyIDs:    role1Key.PublicData().IDs(),
		Paths:     []string{"A/*", "B/*"},
		Threshold: 1,
	}
	err = r.AddDelegatedRole("targets", role1, []*data.PublicKey{
		role1Key.PublicData(),
	})
	c.Assert(err, IsNil)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 2)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(2))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(1))

	checkSigKeyIDs(c, local, map[string][]string{
		"1.targets.json": targetsKeyIDs,
		"targets.json":   targetsKeyIDs,
		"1.role1.json":   role1Key.PublicData().IDs(),
		"role1.json":     role1Key.PublicData().IDs(),
	})

	c.Assert(r.ResetTargetsDelegations("targets"), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	snapshot, err = r.snapshot()
	c.Assert(err, IsNil)
	c.Assert(snapshot.Meta, HasLen, 2)
	c.Assert(snapshot.Meta["targets.json"].Version, Equals, int64(3))
	c.Assert(snapshot.Meta["role1.json"].Version, Equals, int64(1))

	checkSigKeyIDs(c, local, map[string][]string{
		"2.targets.json": targetsKeyIDs,
		"targets.json":   targetsKeyIDs,
		"1.role1.json":   role1Key.PublicData().IDs(),
		"role1.json":     role1Key.PublicData().IDs(),
	})
}

func (rs *RepoSuite) TestSignWithDelegations(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Add one key to each role
	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	role1Key, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)

	role1 := data.DelegatedRole{
		Name:      "role1",
		KeyIDs:    role1Key.PublicData().IDs(),
		Paths:     []string{"A/*", "B/*"},
		Threshold: 1,
	}
	err = r.AddDelegatedRole("targets", role1, []*data.PublicKey{
		role1Key.PublicData(),
	})
	c.Assert(err, IsNil)

	// targets.json should be signed, but role1.json is not signed because there
	// is no key in the local store.
	m, err := local.GetMeta()
	c.Assert(err, IsNil)
	targetsMeta := &data.Signed{}
	c.Assert(json.Unmarshal(m["targets.json"], targetsMeta), IsNil)
	c.Assert(len(targetsMeta.Signatures), Equals, 1)
	role1Meta := &data.Signed{}
	c.Assert(json.Unmarshal(m["role1.json"], role1Meta), IsNil)
	c.Assert(len(role1Meta.Signatures), Equals, 0)

	c.Assert(r.Snapshot(), DeepEquals, ErrInsufficientSignatures{"role1.json", verify.ErrNoSignatures})

	// Sign role1.json.
	c.Assert(local.SaveSigner("role1", role1Key), IsNil)
	c.Assert(r.Sign("role1.json"), IsNil)

	m, err = local.GetMeta()
	c.Assert(err, IsNil)
	targetsMeta = &data.Signed{}
	c.Assert(json.Unmarshal(m["targets.json"], targetsMeta), IsNil)
	c.Assert(len(targetsMeta.Signatures), Equals, 1)
	role1Meta = &data.Signed{}
	c.Assert(json.Unmarshal(m["role1.json"], role1Meta), IsNil)
	c.Assert(len(role1Meta.Signatures), Equals, 1)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
}

func (rs *RepoSuite) TestAddOrUpdateSignatureWithDelegations(c *C) {
	tmp := newTmpDir(c)
	local := FileSystemStore(tmp.path, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Add one key to each role
	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")

	role1Key, err := keys.GenerateEd25519Key()
	c.Assert(err, IsNil)

	role1 := data.DelegatedRole{
		Name:      "role1",
		KeyIDs:    role1Key.PublicData().IDs(),
		Paths:     []string{"A/*", "B/*"},
		Threshold: 1,
	}
	err = r.AddDelegatedRole("targets", role1, []*data.PublicKey{
		role1Key.PublicData(),
	})
	c.Assert(err, IsNil)

	// targets.json should be signed, but role1.json is not signed because there
	// is no key in the local store.
	m, err := local.GetMeta()
	c.Assert(err, IsNil)
	targetsMeta := &data.Signed{}
	c.Assert(json.Unmarshal(m["targets.json"], targetsMeta), IsNil)
	c.Assert(len(targetsMeta.Signatures), Equals, 1)
	role1Meta := &data.Signed{}
	c.Assert(json.Unmarshal(m["role1.json"], role1Meta), IsNil)
	c.Assert(len(role1Meta.Signatures), Equals, 0)

	c.Assert(r.Snapshot(), DeepEquals, ErrInsufficientSignatures{"role1.json", verify.ErrNoSignatures})

	// Sign role1.json.
	canonical, err := cjson.EncodeCanonical(role1Meta.Signed)
	c.Assert(err, IsNil)
	sig, err := role1Key.SignMessage(canonical)
	c.Assert(err, IsNil)
	err = r.AddOrUpdateSignature("role1.json", data.Signature{
		KeyID:     role1Key.PublicData().IDs()[0],
		Signature: sig,
	})
	c.Assert(err, IsNil)

	m, err = local.GetMeta()
	c.Assert(err, IsNil)
	targetsMeta = &data.Signed{}
	c.Assert(json.Unmarshal(m["targets.json"], targetsMeta), IsNil)
	c.Assert(len(targetsMeta.Signatures), Equals, 1)
	role1Meta = &data.Signed{}
	c.Assert(json.Unmarshal(m["role1.json"], role1Meta), IsNil)
	c.Assert(len(role1Meta.Signatures), Equals, 1)

	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
}

// Test the offline signature flow: Payload -> SignPayload -> AddSignature
func (rs *RepoSuite) TestOfflineFlow(c *C) {
	// Set up repo.
	meta := make(map[string]json.RawMessage)
	local := MemoryStore(meta, nil)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)
	c.Assert(r.Init(false), IsNil)
	_, err = r.GenKey("root")
	c.Assert(err, IsNil)

	// Get the payload to sign
	_, err = r.Payload("badrole.json")
	c.Assert(err, Equals, ErrMissingMetadata{"badrole.json"})
	_, err = r.Payload("root")
	c.Assert(err, Equals, ErrMissingMetadata{"root"})
	payload, err := r.Payload("root.json")
	c.Assert(err, IsNil)

	root, err := r.SignedMeta("root.json")
	c.Assert(err, IsNil)
	rootCanonical, err := cjson.EncodeCanonical(root.Signed)
	c.Assert(err, IsNil)
	if !bytes.Equal(payload, rootCanonical) {
		c.Fatalf("Payload(): not canonical.\n%s\n%s", string(payload), string(rootCanonical))
	}

	// Sign the payload
	signed := data.Signed{Signed: payload}
	_, err = r.SignPayload("targets", &signed)
	c.Assert(err, Equals, ErrNoKeys{"targets"})
	numKeys, err := r.SignPayload("root", &signed)
	c.Assert(err, IsNil)
	c.Assert(numKeys, Equals, 1)

	// Add the payload signatures back
	for _, sig := range signed.Signatures {
		// This method checks that the signature verifies!
		err = r.AddOrUpdateSignature("root.json", sig)
		c.Assert(err, IsNil)
	}
}

// Regression test: Snapshotting an invalid root should fail.
func (rs *RepoSuite) TestSnapshotWithInvalidRoot(c *C) {
	files := map[string][]byte{"foo.txt": []byte("foo")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Init should create targets.json, but not signed yet
	r.Init(false)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)

	// Clear the root signature so that signature verification fails.
	s, err := r.SignedMeta("root.json")
	c.Assert(err, IsNil)
	c.Assert(s.Signatures, HasLen, 1)
	s.Signatures[0].Signature = data.HexBytes{}
	b, err := r.jsonMarshal(s)
	c.Assert(err, IsNil)
	r.meta["root.json"] = b
	local.SetMeta("root.json", b)

	// Snapshotting should fail.
	c.Assert(r.Snapshot(), Equals, ErrInsufficientSignatures{"root.json", verify.ErrInvalid})

	// Correctly sign root
	c.Assert(r.Sign("root.json"), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)
}

// Regression test: Do not omit length in target metadata files.
func (rs *RepoSuite) TestTargetMetadataLength(c *C) {
	files := map[string][]byte{"foo.txt": []byte("")}
	local := MemoryStore(make(map[string]json.RawMessage), files)
	r, err := NewRepo(local)
	c.Assert(err, IsNil)

	// Init should create targets.json, but not signed yet
	r.Init(false)

	genKey(c, r, "root")
	genKey(c, r, "targets")
	genKey(c, r, "snapshot")
	genKey(c, r, "timestamp")
	c.Assert(r.AddTarget("foo.txt", nil), IsNil)
	c.Assert(r.Snapshot(), IsNil)
	c.Assert(r.Timestamp(), IsNil)
	c.Assert(r.Commit(), IsNil)

	// Check length field of foo.txt exists.
	meta, err := local.GetMeta()
	c.Assert(err, IsNil)
	targetsJSON, ok := meta["targets.json"]
	if !ok {
		c.Fatal("missing targets metadata")
	}
	s := &data.Signed{}
	c.Assert(json.Unmarshal(targetsJSON, s), IsNil)
	fmt.Fprint(os.Stderr, s.Signed)
	var objMap map[string]json.RawMessage
	c.Assert(json.Unmarshal(s.Signed, &objMap), IsNil)
	targetsMap, ok := objMap["targets"]
	if !ok {
		c.Fatal("missing targets field in targets metadata")
	}
	c.Assert(json.Unmarshal(targetsMap, &objMap), IsNil)
	targetsMap, ok = objMap["foo.txt"]
	if !ok {
		c.Fatal("missing foo.txt in targets")
	}
	c.Assert(json.Unmarshal(targetsMap, &objMap), IsNil)
	lengthMsg, ok := objMap["length"]
	if !ok {
		c.Fatal("missing length field in foo.txt file meta")
	}
	var length int64
	c.Assert(json.Unmarshal(lengthMsg, &length), IsNil)
	c.Assert(length, Equals, int64(0))
}
