Example #1
0
func TestGetAllRoles(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	// After we init, we get the base roles
	roles := repo.GetAllLoadedRoles()
	assert.Len(t, roles, len(data.BaseRoles))

	// Clear the keysDB, check that we get an empty list
	repo.keysDB = keys.NewDB()
	roles = repo.GetAllLoadedRoles()
	assert.Len(t, roles, 0)
}
Example #2
0
func TestDeleteDelegationsRoleNotExistBecauseNoParentMeta(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	// no empty delegation metadata created for new delegation
	_, ok := repo.Targets["targets/test"]
	assert.False(t, ok, "no targets file should be created for empty delegation")

	delRole, err := data.NewRole(
		"targets/test/a", 1, []string{testKey.ID()}, []string{"test"}, []string{})

	err = repo.DeleteDelegation(*delRole)
	assert.NoError(t, err)
	// still no metadata
	_, ok = repo.Targets["targets/test"]
	assert.False(t, ok)
}
Example #3
0
func TestRotationNewSigMissing(t *testing.T) {
	logrus.SetLevel(logrus.DebugLevel)
	kdb := keys.NewDB()
	signer := signed.NewEd25519()
	repo := tuf.NewRepo(kdb, signer)
	remote := store.NewMemoryStore(nil, nil)
	cache := store.NewMemoryStore(nil, nil)

	// Generate initial root key and role and add to key DB
	rootKey, err := signer.Create("root", data.ED25519Key)
	assert.NoError(t, err, "Error creating root key")
	rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
	assert.NoError(t, err, "Error creating root role")

	kdb.AddKey(rootKey)
	err = kdb.AddRole(rootRole)
	assert.NoError(t, err, "Error adding root role to db")

	// Generate new key and role. These will appear in the root.json
	// but will not be added to the keyDB.
	replacementKey, err := signer.Create("root", data.ED25519Key)
	assert.NoError(t, err, "Error creating replacement root key")
	replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
	assert.NoError(t, err, "Error creating replacement root role")

	assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same")

	// Generate a new root with the replacement key and role
	testRoot, err := data.NewRoot(
		map[string]data.PublicKey{replacementKey.ID(): replacementKey},
		map[string]*data.RootRole{"root": &replacementRole.RootRole},
		false,
	)
	assert.NoError(t, err, "Failed to create new root")

	_, ok := testRoot.Signed.Keys[rootKey.ID()]
	assert.False(t, ok, "Old root key appeared in test root")

	// Sign testRoot with both old and new keys
	signedRoot, err := testRoot.ToSigned()
	err = signed.Sign(signer, signedRoot, rootKey)
	assert.NoError(t, err, "Failed to sign root")
	var origKeySig bool
	var replKeySig bool
	for _, sig := range signedRoot.Signatures {
		if sig.KeyID == rootKey.ID() {
			origKeySig = true
		} else if sig.KeyID == replacementKey.ID() {
			replKeySig = true
		}
	}
	assert.True(t, origKeySig, "Original root key signature not present")
	assert.False(t, replKeySig, "Replacement root key signature was present and shouldn't be")

	client := NewClient(repo, remote, kdb, cache)

	err = client.verifyRoot("root", signedRoot, 0)
	assert.Error(t, err, "Should have errored on verify as replacement signature was missing.")

}
Example #4
0
// A delegation can be created with a role that is missing a signing key, so
// long as UpdateDelegations is called with the key
func TestUpdateDelegationsRoleThatIsMissingDelegationKey(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	roleKey, err := ed25519.Create("Invalid Role", data.ED25519Key)
	assert.NoError(t, err)

	role, err := data.NewRole("targets/role", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	// key should get added to role as part of updating the delegation
	err = repo.UpdateDelegations(role, data.KeyList{roleKey})
	assert.NoError(t, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, roleKey.ID(), keyIDs[0])
	assert.True(t, r.Dirty)

	// no empty delegation metadata created for new delegation
	_, ok = repo.Targets["targets/role"]
	assert.False(t, ok, "no targets file should be created for empty delegation")
}
Example #5
0
func TestDeleteDelegationsMidSliceRole(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	role2, err := data.NewRole("targets/test2", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role2, data.KeyList{testKey})
	assert.NoError(t, err)

	role3, err := data.NewRole("targets/test3", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role3, data.KeyList{testKey})
	assert.NoError(t, err)

	err = repo.DeleteDelegation(*role2)
	assert.NoError(t, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 2)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	assert.True(t, r.Dirty)
}
Example #6
0
func TestUpdateDelegationsInvalidRole(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	roleKey, err := ed25519.Create("Invalid Role", data.ED25519Key)
	assert.NoError(t, err)

	// data.NewRole errors if the role isn't a valid TUF role so use one of the non-delegation
	// valid roles
	invalidRole, err := data.NewRole("root", 1, []string{roleKey.ID()}, []string{}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(invalidRole, data.KeyList{roleKey})
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 0)

	// no delegation metadata created for invalid delgation
	_, ok = repo.Targets["root"]
	assert.False(t, ok, "no targets file should be created since delegation failed")
}
Example #7
0
// Adding targets to a role that we don't have signing keys for fails
func TestAddTargetsNoSigningKeys(t *testing.T) {
	hash := sha256.Sum256([]byte{})
	f := data.FileMeta{
		Length: 1,
		Hashes: map[string][]byte{
			"sha256": hash[:],
		},
	}

	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole(
		"targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	// now delete the signing key (all keys)
	repo.cryptoService = signed.NewEd25519()

	// adding the targets to the role should create the metadata though
	_, err = repo.AddTargets("targets/test", data.Files{"f": f})
	assert.Error(t, err)
	assert.IsType(t, signed.ErrNoKeys{}, err)
}
Example #8
0
// we require that at least the base targets role is available when creating
// initializing a snapshot
func TestInitSnapshotNoTargets(t *testing.T) {
	cryptoService := signed.NewEd25519()
	keyDB := keys.NewDB()
	rootKey, err := cryptoService.Create("root", data.ED25519Key)
	assert.NoError(t, err)
	snapshotKey, err := cryptoService.Create("snapshot", data.ED25519Key)
	assert.NoError(t, err)

	keyDB.AddKey(rootKey)
	keyDB.AddKey(snapshotKey)

	rootRole := &data.Role{
		Name: "root",
		RootRole: data.RootRole{
			KeyIDs:    []string{rootKey.ID()},
			Threshold: 1,
		},
	}
	snapshotRole := &data.Role{
		Name: "snapshot",
		RootRole: data.RootRole{
			KeyIDs:    []string{snapshotKey.ID()},
			Threshold: 1,
		},
	}

	keyDB.AddRole(rootRole)
	keyDB.AddRole(snapshotRole)

	repo := NewRepo(keyDB, cryptoService)
	err = repo.InitSnapshot()
	assert.Error(t, err)
	assert.IsType(t, ErrNotLoaded{}, err)
}
Example #9
0
// Removing targets from a role that exists, has targets, and is signable
// should succeed, even if we also want to remove targets that don't exist.
func TestRemoveExistingAndNonexistingTargets(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole(
		"targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	// no empty metadata is created for this role
	_, ok := repo.Targets["targets/test"]
	assert.False(t, ok, "no empty targets file should be created")

	// now remove a target
	assert.NoError(t, repo.RemoveTargets("targets/test", "f"))

	// still no metadata
	_, ok = repo.Targets["targets/test"]
	assert.False(t, ok)
}
Example #10
0
// adding a key to a role marks root as dirty as well as the role
func TestAddBaseKeysToRoot(t *testing.T) {
	for _, role := range data.BaseRoles {
		ed25519 := signed.NewEd25519()
		keyDB := keys.NewDB()
		repo := initRepo(t, ed25519, keyDB)

		key, err := ed25519.Create(role, data.ED25519Key)
		assert.NoError(t, err)

		assert.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 1)

		assert.NoError(t, repo.AddBaseKeys(role, key))

		_, ok := repo.Root.Signed.Keys[key.ID()]
		assert.True(t, ok)
		assert.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 2)
		assert.True(t, repo.Root.Dirty)

		switch role {
		case data.CanonicalSnapshotRole:
			assert.True(t, repo.Snapshot.Dirty)
		case data.CanonicalTargetsRole:
			assert.True(t, repo.Targets[data.CanonicalTargetsRole].Dirty)
		case data.CanonicalTimestampRole:
			assert.True(t, repo.Timestamp.Dirty)
		}
	}
}
Example #11
0
func TestDuplicateSigs(t *testing.T) {
	cs := NewEd25519()
	k, err := cs.Create("root", data.ED25519Key)
	assert.NoError(t, err)
	r, err := data.NewRole(
		"root",
		2,
		[]string{k.ID()},
		nil,
		nil,
	)
	assert.NoError(t, err)
	db := keys.NewDB()
	assert.NoError(t, err)
	db.AddKey(k)
	err = db.AddRole(r)
	assert.NoError(t, err)
	meta := &data.SignedCommon{Type: "Root", Version: 1, Expires: data.DefaultExpires("root")}

	b, err := json.MarshalCanonical(meta)
	assert.NoError(t, err)
	s := &data.Signed{Signed: b}
	Sign(cs, s, k)
	s.Signatures = append(s.Signatures, s.Signatures[0])
	err = Verify(s, "root", 1, db)
	assert.IsType(t, ErrRoleThreshold{}, err)
}
Example #12
0
func TestMoreThanEnoughSigs(t *testing.T) {
	cs := NewEd25519()
	k1, err := cs.Create("root", data.ED25519Key)
	assert.NoError(t, err)
	k2, err := cs.Create("root", data.ED25519Key)
	assert.NoError(t, err)
	r, err := data.NewRole(
		"root",
		1,
		[]string{k1.ID(), k2.ID()},
		nil,
		nil,
	)
	assert.NoError(t, err)
	db := keys.NewDB()
	assert.NoError(t, err)
	db.AddKey(k1)
	db.AddKey(k2)
	err = db.AddRole(r)
	assert.NoError(t, err)
	meta := &data.SignedCommon{Type: "Root", Version: 1, Expires: data.DefaultExpires("root")}

	b, err := json.MarshalCanonical(meta)
	assert.NoError(t, err)
	s := &data.Signed{Signed: b}
	Sign(cs, s, k1, k2)
	assert.Equal(t, 2, len(s.Signatures))
	err = Verify(s, "root", 1, db)
	assert.NoError(t, err)
}
Example #13
0
func TestUpdateDelegations(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	if err != nil {
		t.Fatal(err)
	}
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	if err != nil {
		t.Fatal(err)
	}

	err = repo.UpdateDelegations(role, data.KeyList{testKey}, "")
	if err != nil {
		t.Fatal(err)
	}

	testDeepKey, err := ed25519.Create("targets/test/deep", data.ED25519Key)
	if err != nil {
		t.Fatal(err)
	}
	roleDeep, err := data.NewRole("targets/test/deep", 1, []string{testDeepKey.ID()}, []string{"test/deep"}, []string{})
	if err != nil {
		t.Fatal(err)
	}

	err = repo.UpdateDelegations(roleDeep, data.KeyList{testDeepKey}, "")
	if err != nil {
		t.Fatal(err)
	}

	writeRepo(t, "/tmp/tufdelegation", repo)
}
Example #14
0
func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
	var rootJSON []byte
	remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
	if err == nil {
		// if remote store successfully set up, try and get root from remote
		rootJSON, err = remote.GetMeta("root", maxSize)
	}

	// if remote store couldn't be setup, or we failed to get a root from it
	// load the root from cache (offline operation)
	if err != nil {
		if err, ok := err.(store.ErrMetaNotFound); ok {
			// if the error was MetaNotFound then we successfully contacted
			// the store and it doesn't know about the repo.
			return nil, err
		}
		result, cacheErr := r.fileStore.GetMeta("root", maxSize)
		if cacheErr != nil {
			// if cache didn't return a root, we cannot proceed - just return
			// the original error.
			return nil, err
		}
		rootJSON = result
		logrus.Debugf(
			"Using local cache instead of remote due to failure: %s", err.Error())
	}
	// can't just unmarshal into SignedRoot because validate root
	// needs the root.Signed field to still be []byte for signature
	// validation
	root := &data.Signed{}
	err = json.Unmarshal(rootJSON, root)
	if err != nil {
		return nil, err
	}

	err = r.CertManager.ValidateRoot(root, r.gun)
	if err != nil {
		return nil, err
	}

	kdb := keys.NewDB()
	r.tufRepo = tuf.NewRepo(kdb, r.CryptoService)

	signedRoot, err := data.RootFromSigned(root)
	if err != nil {
		return nil, err
	}
	err = r.tufRepo.SetRoot(signedRoot)
	if err != nil {
		return nil, err
	}

	return tufclient.NewClient(
		r.tufRepo,
		remote,
		kdb,
		r.fileStore,
	), nil
}
Example #15
0
func TestValidateTargetsParentInUpdate(t *testing.T) {
	_, baseRepo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)
	store := storage.NewMemStorage()

	k, err := cs.Create("targets/level1", data.ED25519Key)
	assert.NoError(t, err)
	r, err := data.NewRole("targets/level1", 1, []string{k.ID()}, []string{""}, nil)
	assert.NoError(t, err)

	baseRepo.UpdateDelegations(r, []data.PublicKey{k})

	// no targets file is created for the new delegations, so force one
	baseRepo.InitTargets("targets/level1")

	targets, err := baseRepo.SignTargets("targets", data.DefaultExpires(data.CanonicalTargetsRole))

	tgtsJSON, err := json.Marshal(targets)
	assert.NoError(t, err)
	update := storage.MetaUpdate{
		Role:    data.CanonicalTargetsRole,
		Version: 1,
		Data:    tgtsJSON,
	}
	store.UpdateCurrent("gun", update)

	del, err := baseRepo.SignTargets("targets/level1", data.DefaultExpires(data.CanonicalTargetsRole))
	assert.NoError(t, err)
	delJSON, err := json.Marshal(del)
	assert.NoError(t, err)

	delUpdate := storage.MetaUpdate{
		Role:    "targets/level1",
		Version: 1,
		Data:    delJSON,
	}

	roles := map[string]storage.MetaUpdate{
		"targets/level1": delUpdate,
		"targets":        update,
	}

	kdb := keys.NewDB()
	valRepo := tuf.NewRepo(kdb, nil)
	valRepo.SetRoot(baseRepo.Root)

	// because we sort the roles, the list of returned updates
	// will contain shallower roles first, in this case "targets",
	// and then "targets/level1"
	updates, err := loadAndValidateTargets("gun", valRepo, roles, kdb, store)
	assert.NoError(t, err)
	assert.Len(t, updates, 2)
	assert.Equal(t, "targets", updates[0].Role)
	assert.Equal(t, tgtsJSON, updates[0].Data)
	assert.Equal(t, "targets/level1", updates[1].Role)
	assert.Equal(t, delJSON, updates[1].Data)
}
Example #16
0
// Removing targets from a role that doesn't exist fails
func TestRemoveTargetsRoleDoesntExist(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	err := repo.RemoveTargets("targets/test", "f")
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)
}
Example #17
0
// If the parent role doesn't exist, GetDelegation fails with an ErrInvalidRole
func TestGetDelegationParentMissing(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	_, _, err := repo.GetDelegation("targets/level1/level2")
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)
}
Example #18
0
func TestValidateTargetsRoleNotInParent(t *testing.T) {
	kdb, baseRepo, cs := testutils.EmptyRepo()
	store := storage.NewMemStorage()

	k, err := cs.Create("targets/level1", data.ED25519Key)
	assert.NoError(t, err)
	r, err := data.NewRole("targets/level1", 1, []string{k.ID()}, []string{""}, nil)
	assert.NoError(t, err)

	kdb.AddKey(k)
	err = kdb.AddRole(r)
	assert.NoError(t, err)

	baseRepo.InitTargets("targets/level1")

	targets, err := baseRepo.SignTargets("targets", data.DefaultExpires(data.CanonicalTargetsRole))

	tgtsJSON, err := json.MarshalCanonical(targets)
	assert.NoError(t, err)
	update := storage.MetaUpdate{
		Role:    data.CanonicalTargetsRole,
		Version: 1,
		Data:    tgtsJSON,
	}
	store.UpdateCurrent("gun", update)

	del, err := baseRepo.SignTargets("targets/level1", data.DefaultExpires(data.CanonicalTargetsRole))
	assert.NoError(t, err)
	delJSON, err := json.MarshalCanonical(del)
	assert.NoError(t, err)

	delUpdate := storage.MetaUpdate{
		Role:    "targets/level1",
		Version: 1,
		Data:    delJSON,
	}

	roles := map[string]storage.MetaUpdate{
		"targets/level1": delUpdate,
		"targets":        update,
	}

	kdb = keys.NewDB()
	valRepo := tuf.NewRepo(kdb, nil)
	valRepo.SetRoot(baseRepo.Root)

	// because we sort the roles, the list of returned updates
	// will contain shallower roles first, in this case "targets",
	// and then "targets/level1"
	updates, err := loadAndValidateTargets("gun", valRepo, roles, kdb, store)
	assert.NoError(t, err)
	assert.Len(t, updates, 1)
	assert.Equal(t, "targets", updates[0].Role)
	assert.Equal(t, tgtsJSON, updates[0].Data)
}
Example #19
0
func TestUpdateDelegationsReplaceRole(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, testKey.ID(), keyIDs[0])

	// no empty delegation metadata created for new delegation
	_, ok = repo.Targets["targets/test"]
	assert.False(t, ok, "no targets file should be created for empty delegation")

	// create one now to assert that replacing the delegation doesn't delete the
	// metadata
	repo.InitTargets("targets/test")

	// create another role with the same name and ensure it replaces the
	// previous role
	testKey2, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role2, err := data.NewRole("targets/test", 1, []string{testKey2.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role2, data.KeyList{testKey2})
	assert.NoError(t, err)

	r, ok = repo.Targets["targets"]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs = r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, testKey2.ID(), keyIDs[0])
	assert.True(t, r.Dirty)

	// delegation was not deleted
	_, ok = repo.Targets["targets/test"]
	assert.True(t, ok, "targets file should still be here")
}
Example #20
0
func TestValidateTargetsLoadParent(t *testing.T) {
	_, baseRepo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)
	store := storage.NewMemStorage()

	k, err := cs.Create("targets/level1", data.ED25519Key)
	assert.NoError(t, err)
	r, err := data.NewRole("targets/level1", 1, []string{k.ID()}, []string{""}, nil)
	assert.NoError(t, err)

	err = baseRepo.UpdateDelegations(r, []data.PublicKey{k})
	assert.NoError(t, err)

	// no targets file is created for the new delegations, so force one
	baseRepo.InitTargets("targets/level1")

	// we're not going to validate things loaded from storage, so no need
	// to sign the base targets, just Marshal it and set it into storage
	tgtsJSON, err := json.Marshal(baseRepo.Targets["targets"])
	assert.NoError(t, err)
	update := storage.MetaUpdate{
		Role:    data.CanonicalTargetsRole,
		Version: 1,
		Data:    tgtsJSON,
	}
	store.UpdateCurrent("gun", update)

	// generate the update object we're doing to use to call loadAndValidateTargets
	del, err := baseRepo.SignTargets("targets/level1", data.DefaultExpires(data.CanonicalTargetsRole))
	assert.NoError(t, err)
	delJSON, err := json.Marshal(del)
	assert.NoError(t, err)

	delUpdate := storage.MetaUpdate{
		Role:    "targets/level1",
		Version: 1,
		Data:    delJSON,
	}

	roles := map[string]storage.MetaUpdate{"targets/level1": delUpdate}

	kdb := keys.NewDB()
	valRepo := tuf.NewRepo(kdb, nil)
	valRepo.SetRoot(baseRepo.Root)

	updates, err := loadAndValidateTargets("gun", valRepo, roles, kdb, store)
	assert.NoError(t, err)
	assert.Len(t, updates, 1)
	assert.Equal(t, "targets/level1", updates[0].Role)
	assert.Equal(t, delJSON, updates[0].Data)
}
Example #21
0
// EmptyRepo creates an in memory key database, crypto service
// and initializes a repo with no targets or delegations.
func EmptyRepo() (*keys.KeyDB, *tuf.Repo, signed.CryptoService) {
	c := signed.NewEd25519()
	kdb := keys.NewDB()
	r := tuf.NewRepo(kdb, c)

	for _, role := range []string{"root", "targets", "snapshot", "timestamp"} {
		key, _ := c.Create(role, data.ED25519Key)
		role, _ := data.NewRole(role, 1, []string{key.ID()}, nil, nil)
		kdb.AddKey(key)
		kdb.AddRole(role)
	}

	r.InitRepo(false)
	return kdb, r, c
}
Example #22
0
func TestUpdateDelegations(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	// no empty metadata is created for this role
	_, ok := repo.Targets["targets/test"]
	assert.False(t, ok, "no empty targets file should be created for deepest delegation")

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, testKey.ID(), keyIDs[0])

	testDeepKey, err := ed25519.Create("targets/test/deep", data.ED25519Key)
	assert.NoError(t, err)
	roleDeep, err := data.NewRole("targets/test/deep", 1, []string{testDeepKey.ID()}, []string{"test/deep"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(roleDeep, data.KeyList{testDeepKey})
	assert.NoError(t, err)

	// this metadata didn't exist before, but creating targets/test/deep created
	// the targets/test metadata
	r, ok = repo.Targets["targets/test"]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs = r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, testDeepKey.ID(), keyIDs[0])
	assert.True(t, r.Dirty)

	// no empty delegation metadata is created for targets/test/deep
	_, ok = repo.Targets["targets/test/deep"]
	assert.False(t, ok, "no empty targets file should be created for deepest delegation")
}
Example #23
0
func TestDeleteDelegationsParentMissing(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testRole, err := data.NewRole("targets/test/deep", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.DeleteDelegation(*testRole)
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 0)
}
Example #24
0
// This changes the root key
func TestSwizzlerChangeRootKey(t *testing.T) {
	f, origMeta := createNewSwizzler(t)

	f.ChangeRootKey()

	kdb := keys.NewDB()
	tufRepo := tuf.NewRepo(kdb, f.CryptoService)

	// we want to test these in a specific order
	roles := []string{data.CanonicalRootRole, data.CanonicalTargetsRole, data.CanonicalSnapshotRole,
		data.CanonicalTimestampRole, "targets/a", "targets/a/b"}

	for _, role := range roles {
		origMeta := origMeta[role]
		newMeta, err := f.MetadataCache.GetMeta(role, -1)
		require.NoError(t, err)

		// the threshold for base roles is set in root
		switch role {
		case data.CanonicalRootRole:
			require.False(t, bytes.Equal(origMeta, newMeta))
			origRoot, newRoot := &data.SignedRoot{}, &data.SignedRoot{}
			require.NoError(t, json.Unmarshal(origMeta, origRoot))
			require.NoError(t, json.Unmarshal(newMeta, newRoot))

			require.NotEqual(t, len(origRoot.Signed.Keys), len(newRoot.Signed.Keys))

			for r, origRole := range origRoot.Signed.Roles {
				newRole := newRoot.Signed.Roles[r]
				require.Len(t, origRole.KeyIDs, 1)
				require.Len(t, newRole.KeyIDs, 1)
				if r == data.CanonicalRootRole {
					require.NotEqual(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
				} else {
					require.Equal(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
				}
			}

			require.NoError(t, tufRepo.SetRoot(newRoot))
			signedThing, err := newRoot.ToSigned()
			require.NoError(t, err)
			require.NoError(t, signed.Verify(signedThing, data.CanonicalRootRole, 1, kdb))
		default:
			require.True(t, bytes.Equal(origMeta, newMeta), "bytes have changed for role %s", role)
		}
	}
}
Example #25
0
func TestApplyChangelist(t *testing.T) {
	kdb := keys.NewDB()
	role, err := data.NewRole("targets", 1, nil, nil, nil)
	assert.NoError(t, err)
	kdb.AddRole(role)

	repo := tuf.NewRepo(kdb, nil)
	err = repo.InitTargets()
	assert.NoError(t, err)
	hash := sha256.Sum256([]byte{})
	f := &data.FileMeta{
		Length: 1,
		Hashes: map[string][]byte{
			"sha256": hash[:],
		},
	}
	fjson, err := json.Marshal(f)
	assert.NoError(t, err)

	cl := changelist.NewMemChangelist()
	addChange := &changelist.TufChange{
		Actn:       changelist.ActionCreate,
		Role:       changelist.ScopeTargets,
		ChangeType: "target",
		ChangePath: "latest",
		Data:       fjson,
	}
	cl.Add(addChange)
	err = applyChangelist(repo, cl)
	assert.NoError(t, err)
	assert.NotNil(t, repo.Targets["targets"].Signed.Targets["latest"])

	cl.Clear("")

	removeChange := &changelist.TufChange{
		Actn:       changelist.ActionDelete,
		Role:       changelist.ScopeTargets,
		ChangeType: "target",
		ChangePath: "latest",
		Data:       nil,
	}
	cl.Add(removeChange)
	err = applyChangelist(repo, cl)
	assert.NoError(t, err)
	_, ok := repo.Targets["targets"].Signed.Targets["latest"]
	assert.False(t, ok)
}
Example #26
0
// Adding targets to a role that doesn't exist fails
func TestAddTargetsRoleDoesntExist(t *testing.T) {
	hash := sha256.Sum256([]byte{})
	f := data.FileMeta{
		Length: 1,
		Hashes: map[string][]byte{
			"sha256": hash[:],
		},
	}

	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	_, err := repo.AddTargets("targets/test", data.Files{"f": f})
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)
}
Example #27
0
// Can't delete a delegation if we don't have the parent's signing key
func TestDeleteDelegationsMissingParentSigningKey(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{testKey})
	assert.NoError(t, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	keyIDs := r.Signed.Delegations.Roles[0].KeyIDs
	assert.Len(t, keyIDs, 1)
	assert.Equal(t, testKey.ID(), keyIDs[0])

	// ensure that the metadata is there and snapshot is there
	targets, err := repo.InitTargets("targets/test")
	assert.NoError(t, err)
	targetsSigned, err := targets.ToSigned()
	assert.NoError(t, err)
	assert.NoError(t, repo.UpdateSnapshot("targets/test", targetsSigned))
	_, ok = repo.Snapshot.Signed.Meta["targets/test"]
	assert.True(t, ok)

	// delete all signing keys
	repo.cryptoService = signed.NewEd25519()
	err = repo.DeleteDelegation(*role)
	assert.Error(t, err)
	assert.IsType(t, signed.ErrNoKeys{}, err)

	assert.Len(t, r.Signed.Delegations.Roles, 1)
	assert.Len(t, r.Signed.Delegations.Keys, 1)
	assert.True(t, r.Dirty)

	// metadata should be here still
	_, ok = repo.Targets["targets/test"]
	assert.True(t, ok)
	_, ok = repo.Snapshot.Signed.Meta["targets/test"]
	assert.True(t, ok)
}
Example #28
0
// bootstrapRepo loads the repository from the local file system.  This attempts
// to load metadata for all roles.  Since server snapshots are supported,
// if the snapshot metadata fails to load, that's ok.
// This can also be unified with some cache reading tools from tuf/client.
// This assumes that bootstrapRepo is only used by Publish()
func (r *NotaryRepository) bootstrapRepo() error {
	kdb := keys.NewDB()
	tufRepo := tuf.NewRepo(kdb, r.CryptoService)

	logrus.Debugf("Loading trusted collection.")
	rootJSON, err := r.fileStore.GetMeta("root", 0)
	if err != nil {
		return err
	}
	root := &data.SignedRoot{}
	err = json.Unmarshal(rootJSON, root)
	if err != nil {
		return err
	}
	err = tufRepo.SetRoot(root)
	if err != nil {
		return err
	}
	targetsJSON, err := r.fileStore.GetMeta("targets", 0)
	if err != nil {
		return err
	}
	targets := &data.SignedTargets{}
	err = json.Unmarshal(targetsJSON, targets)
	if err != nil {
		return err
	}
	tufRepo.SetTargets("targets", targets)

	snapshotJSON, err := r.fileStore.GetMeta("snapshot", 0)
	if err == nil {
		snapshot := &data.SignedSnapshot{}
		err = json.Unmarshal(snapshotJSON, snapshot)
		if err != nil {
			return err
		}
		tufRepo.SetSnapshot(snapshot)
	} else if _, ok := err.(store.ErrMetaNotFound); !ok {
		return err
	}

	r.tufRepo = tufRepo

	return nil
}
Example #29
0
func TestDeleteDelegationsInvalidRole(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	// data.NewRole errors if the role isn't a valid TUF role so use one of the non-delegation
	// valid roles
	invalidRole, err := data.NewRole("root", 1, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.DeleteDelegation(*invalidRole)
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)

	r, ok := repo.Targets[data.CanonicalTargetsRole]
	assert.True(t, ok)
	assert.Len(t, r.Signed.Delegations.Roles, 0)
}
Example #30
0
func TestUpdateDelegationsNotEnoughKeys(t *testing.T) {
	ed25519 := signed.NewEd25519()
	keyDB := keys.NewDB()
	repo := initRepo(t, ed25519, keyDB)

	roleKey, err := ed25519.Create("Invalid Role", data.ED25519Key)
	assert.NoError(t, err)

	role, err := data.NewRole("targets/role", 2, []string{}, []string{""}, []string{})
	assert.NoError(t, err)

	err = repo.UpdateDelegations(role, data.KeyList{roleKey})
	assert.Error(t, err)
	assert.IsType(t, data.ErrInvalidRole{}, err)

	// no delegation metadata created for failed delegation
	_, ok := repo.Targets["targets/role"]
	assert.False(t, ok, "no targets file should be created since delegation failed")
}