Exemple #1
0
func TestGetDelegationRolesInvalidPaths(t *testing.T) {
	ed25519 := signed.NewEd25519()
	repo := initRepo(t, ed25519)

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

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

	testKey2, err := ed25519.Create("targets/test/b", data.ED25519Key)
	assert.NoError(t, err)
	// Now we add a delegation with a path that is not prefixed by its parent delegation
	role, err = data.NewRole("targets/test/b", 1, []string{testKey2.ID()}, []string{"invalidpath"})
	assert.NoError(t, err)

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

	// Getting this delegation does not actually restrict paths, unless we use the RestrictChild method
	delgRole, err := repo.GetDelegationRole("targets/test/b")
	assert.NoError(t, err)
	assert.Contains(t, delgRole.Paths, "invalidpath")

	delgRole, err = repo.GetDelegationRole("targets/test")
	assert.NoError(t, err)
	assert.Contains(t, delgRole.Paths, "path")
	assert.Contains(t, delgRole.Paths, "anotherpath")
}
Exemple #2
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)
}
Exemple #3
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)
}
Exemple #4
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)
}
Exemple #5
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.")

}
Exemple #6
0
func TestRotation(t *testing.T) {
	signer := signed.NewEd25519()
	repo := tuf.NewRepo(signer)
	remote := store.NewMemoryStore(nil)
	cache := store.NewMemoryStore(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)
	assert.NoError(t, err, "Error creating root role")

	originalRoot, err := data.NewRoot(
		map[string]data.PublicKey{rootKey.ID(): rootKey},
		map[string]*data.RootRole{"root": &rootRole.RootRole},
		false,
	)

	repo.Root = originalRoot

	// Generate new key and role.
	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)
	assert.NoError(t, err, "Error creating replacement root role")

	// 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{
			data.CanonicalRootRole:      &replacementRole.RootRole,
			data.CanonicalSnapshotRole:  &replacementRole.RootRole,
			data.CanonicalTargetsRole:   &replacementRole.RootRole,
			data.CanonicalTimestampRole: &replacementRole.RootRole,
		},
		false,
	)
	assert.NoError(t, err, "Failed to create new root")

	// Sign testRoot with both old and new keys
	signedRoot, err := testRoot.ToSigned()
	err = signed.Sign(signer, signedRoot, rootKey, replacementKey)
	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.True(t, replKeySig, "Replacement root key signature not present")

	client := NewClient(repo, remote, cache)

	err = client.verifyRoot("root", signedRoot, 0)
	assert.NoError(t, err, "Failed to verify key rotated root")
}
Exemple #7
0
func initRoles(kdb *keys.KeyDB, rootKey, targetsKey, snapshotKey, timestampKey data.PublicKey) error {
	rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
	if err != nil {
		return err
	}
	targetsRole, err := data.NewRole("targets", 1, []string{targetsKey.ID()}, nil, nil)
	if err != nil {
		return err
	}
	snapshotRole, err := data.NewRole("snapshot", 1, []string{snapshotKey.ID()}, nil, nil)
	if err != nil {
		return err
	}
	timestampRole, err := data.NewRole("timestamp", 1, []string{timestampKey.ID()}, nil, nil)
	if err != nil {
		return err
	}

	if err := kdb.AddRole(rootRole); err != nil {
		return err
	}
	if err := kdb.AddRole(targetsRole); err != nil {
		return err
	}
	if err := kdb.AddRole(snapshotRole); err != nil {
		return err
	}
	if err := kdb.AddRole(timestampRole); err != nil {
		return err
	}
	return nil
}
Exemple #8
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")
}
Exemple #9
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")
}
Exemple #10
0
// AddBaseKeys is used to add keys to the role in root.json
func (tr *Repo) AddBaseKeys(role string, keys ...data.PublicKey) error {
	if tr.Root == nil {
		return ErrNotLoaded{role: "root"}
	}
	ids := []string{}
	for _, k := range keys {
		// Store only the public portion
		tr.Root.Signed.Keys[k.ID()] = k
		tr.keysDB.AddKey(k)
		tr.Root.Signed.Roles[role].KeyIDs = append(tr.Root.Signed.Roles[role].KeyIDs, k.ID())
		ids = append(ids, k.ID())
	}
	r, err := data.NewRole(
		role,
		tr.Root.Signed.Roles[role].Threshold,
		ids,
		nil,
		nil,
	)
	if err != nil {
		return err
	}
	tr.keysDB.AddRole(r)
	tr.Root.Dirty = true
	return nil

}
Exemple #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)
}
Exemple #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)
}
Exemple #13
0
// Adding targets to a role that exists and has not metadata first creates the
// metadata and then correctly adds the target
func TestAddTargetsRoleExistsAndMetadataDoesntExist(t *testing.T) {
	hash := sha256.Sum256([]byte{})
	f := data.FileMeta{
		Length: 1,
		Hashes: map[string][]byte{
			"sha256": hash[:],
		},
	}

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

	testKey, err := ed25519.Create("targets/test", data.ED25519Key)
	assert.NoError(t, err)
	role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []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")

	// adding the targets to the role should create the metadata though
	_, err = repo.AddTargets("targets/test", data.Files{"f": f})
	assert.NoError(t, err)

	r, ok := repo.Targets["targets/test"]
	assert.True(t, ok)
	targetsF, ok := r.Signed.Targets["f"]
	assert.True(t, ok)
	assert.Equal(t, f, targetsF)
}
Exemple #14
0
// ToNewRole creates a fresh role object from the TUFDelegation data
func (td TUFDelegation) ToNewRole(scope string) (*data.Role, error) {
	name := scope
	if td.NewName != "" {
		name = td.NewName
	}
	return data.NewRole(name, td.NewThreshold, td.AddKeys.IDs(), td.AddPaths)
}
Exemple #15
0
// If applying a change fails due to a prefix error, it does not fall back
// on the parent.
func TestChangeTargetMetaDoesntFallbackIfPrefixError(t *testing.T) {
	repo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)

	newKey, err := cs.Create("targets/level1", data.ED25519Key)
	assert.NoError(t, err)

	r, err := data.NewRole("targets/level1", 1, []string{newKey.ID()},
		[]string{"pathprefix"})
	assert.NoError(t, err)
	repo.UpdateDelegations(r, []data.PublicKey{newKey})

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

	err = changeTargetMeta(repo, &changelist.TufChange{
		Actn:       changelist.ActionCreate,
		Role:       "targets/level1",
		ChangeType: "target",
		ChangePath: "notPathPrefix",
		Data:       fjson,
	})
	assert.Error(t, err)

	// no target in targets or targets/latest
	assert.Empty(t, repo.Targets[data.CanonicalTargetsRole].Signed.Targets)
	assert.Empty(t, repo.Targets["targets/level1"].Signed.Targets)
}
Exemple #16
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)
}
Exemple #17
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)
}
Exemple #18
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")
}
Exemple #19
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")
}
Exemple #20
0
// SetRoot parses the Signed object into a SignedRoot object, sets
// the keys and roles in the KeyDB, and sets the Repo.Root field
// to the SignedRoot object.
func (tr *Repo) SetRoot(s *data.SignedRoot) error {
	for _, key := range s.Signed.Keys {
		logrus.Debug("Adding key ", key.ID())
		tr.keysDB.AddKey(key)
	}
	for roleName, role := range s.Signed.Roles {
		logrus.Debugf("Adding role %s with keys %s", roleName, strings.Join(role.KeyIDs, ","))
		baseRole, err := data.NewRole(
			roleName,
			role.Threshold,
			role.KeyIDs,
			nil,
			nil,
		)
		if err != nil {
			return err
		}
		err = tr.keysDB.AddRole(baseRole)
		if err != nil {
			return err
		}
	}
	tr.Root = s
	return nil
}
Exemple #21
0
// Each change applies only to the role specified
func TestApplyChangelistTargetsToMultipleRoles(t *testing.T) {
	repo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)

	newKey, err := cs.Create("targets/level1", data.ED25519Key)
	assert.NoError(t, err)

	r, err := data.NewRole("targets/level1", 1, []string{newKey.ID()}, []string{""})
	assert.NoError(t, err)
	repo.UpdateDelegations(r, []data.PublicKey{newKey})

	r, err = data.NewRole("targets/level2", 1, []string{newKey.ID()}, []string{""})
	assert.NoError(t, err)
	repo.UpdateDelegations(r, []data.PublicKey{newKey})

	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()
	assert.NoError(t, cl.Add(&changelist.TufChange{
		Actn:       changelist.ActionCreate,
		Role:       "targets/level1",
		ChangeType: "target",
		ChangePath: "latest",
		Data:       fjson,
	}))
	assert.NoError(t, cl.Add(&changelist.TufChange{
		Actn:       changelist.ActionDelete,
		Role:       "targets/level2",
		ChangeType: "target",
		ChangePath: "latest",
		Data:       nil,
	}))

	assert.NoError(t, applyChangelist(repo, cl))
	_, ok := repo.Targets["targets/level1"].Signed.Targets["latest"]
	assert.True(t, ok)
	_, ok = repo.Targets["targets/level2"]
	assert.False(t, ok, "no change to targets/level2, so metadata not created")
}
func TestValidateTargetsRoleNotInParent(t *testing.T) {
	baseRepo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)
	store := storage.NewMemStorage()

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

	baseRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles = []*data.Role{r}
	baseRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Keys = data.Keys{
		level1Key.ID(): level1Key,
	}

	baseRepo.InitTargets("targets/level1")

	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,
	}

	// set back to empty so stored targets doesn't have reference to level1
	baseRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles = nil
	baseRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Keys = nil
	targets, err := baseRepo.SignTargets(data.CanonicalTargetsRole, 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)

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

	valRepo := tuf.NewRepo(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, store)
	assert.NoError(t, err)
	assert.Len(t, updates, 1)
	assert.Equal(t, data.CanonicalTargetsRole, updates[0].Role)
	assert.Equal(t, tgtsJSON, updates[0].Data)
}
Exemple #23
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)
}
Exemple #24
0
func TestFindRoleIndexNotFound(t *testing.T) {
	role, err := data.NewRole("targets/test", 1, []string{}, []string{""})
	require.NoError(t, err)

	require.Equal(
		t,
		-1,
		FindRoleIndex(nil, role.Name),
	)
}
Exemple #25
0
func TestFindRoleIndexFound(t *testing.T) {
	role, err := data.NewRole("targets/test", 1, []string{}, []string{""})
	assert.NoError(t, err)

	assert.Equal(
		t,
		0,
		FindRoleIndex([]*data.Role{role}, role.Name),
	)
}
Exemple #26
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)
}
Exemple #27
0
// add a key to a KeyDB, and create a role for the key and add it.
func addKeyForRole(kdb *keys.KeyDB, role string, key data.PublicKey) error {
	theRole, err := data.NewRole(role, 1, []string{key.ID()}, nil, nil)
	if err != nil {
		return err
	}
	kdb.AddKey(key)
	if err := kdb.AddRole(theRole); err != nil {
		return err
	}
	return nil
}
Exemple #28
0
func testValidateSuccessfulRootRotation(t *testing.T, keyAlg, rootKeyType string) {
	// The gun to test
	gun := "docker.com/notary"

	tempBaseDir, keyStoreManager, certs := filestoreWithTwoCerts(t, gun, keyAlg)
	defer os.RemoveAll(tempBaseDir)
	origRootCert := certs[0]
	replRootCert := certs[1]

	// Add the old root cert part of trustedCertificates
	keyStoreManager.AddTrustedCert(origRootCert)

	// We need the PEM representation of the replacement key to put it into the TUF data
	origRootPEMCert := trustmanager.CertToPEM(origRootCert)
	replRootPEMCert := trustmanager.CertToPEM(replRootCert)

	// Tuf key with PEM-encoded x509 certificate
	origRootKey := data.NewPublicKey(rootKeyType, origRootPEMCert)
	replRootKey := data.NewPublicKey(rootKeyType, replRootPEMCert)

	rootRole, err := data.NewRole("root", 1, []string{replRootKey.ID()}, nil, nil)
	assert.NoError(t, err)

	testRoot, err := data.NewRoot(
		map[string]data.PublicKey{replRootKey.ID(): replRootKey},
		map[string]*data.RootRole{"root": &rootRole.RootRole},
		false,
	)
	assert.NoError(t, err, "Failed to create new root")

	signedTestRoot, err := testRoot.ToSigned()
	assert.NoError(t, err)

	cs := cryptoservice.NewCryptoService(gun, keyStoreManager.KeyStore)

	err = signed.Sign(cs, signedTestRoot, replRootKey)
	assert.NoError(t, err)

	err = signed.Sign(cs, signedTestRoot, origRootKey)
	assert.NoError(t, err)

	//
	// This call to ValidateRoot will succeed since we are using a valid PEM
	// encoded certificate, and have no other certificates for this CN
	//
	err = keyStoreManager.ValidateRoot(signedTestRoot, gun)
	assert.NoError(t, err)

	// Finally, validate the only trusted certificate that exists is the new one
	certs = keyStoreManager.trustedCertificateStore.GetCertificates()
	assert.Len(t, certs, 1)
	assert.Equal(t, certs[0], replRootCert)
}
Exemple #29
0
// If the parent exists, the metadata exists, and the delegation is in it,
// returns the role that was found
func TestGetDelegationRoleAndMetadataExistDelegationExists(t *testing.T) {
	ed25519 := signed.NewEd25519()
	repo := initRepo(t, ed25519)

	testKey, err := ed25519.Create("meh", data.ED25519Key)
	assert.NoError(t, err)

	role, err := data.NewRole("targets/level1", 1, []string{testKey.ID()}, []string{""})
	assert.NoError(t, err)
	assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))

	role, err = data.NewRole("targets/level1/level2", 1, []string{testKey.ID()}, []string{""})
	assert.NoError(t, err)
	assert.NoError(t, repo.UpdateDelegations(role, data.KeyList{testKey}))

	gottenRole, gottenKeys, err := repo.GetDelegation("targets/level1/level2")
	assert.NoError(t, err)
	assert.Equal(t, role, gottenRole)
	_, ok := gottenKeys[testKey.ID()]
	assert.True(t, ok)
}
Exemple #30
0
// TargetMeta returns the file metadata for a file path in the role subtree,
// if it exists. It also returns the role in that subtree in which the target
// was found. If the path doesn't exist in that role subtree, returns
// nil and an empty string.
func TestTargetMeta(t *testing.T) {
	kdb, repo, cs, err := testutils.EmptyRepo("docker.com/notary")
	assert.NoError(t, err)
	localStorage := store.NewMemoryStore(nil)
	client := NewClient(repo, nil, kdb, localStorage)

	delegations := []string{
		"targets/level1",
		"targets/level1/a",
		"targets/level1/a/i",
	}

	k, err := cs.Create("", data.ED25519Key)
	assert.NoError(t, err)

	hash := sha256.Sum256([]byte{})
	f := data.FileMeta{
		Length: 1,
		Hashes: map[string][]byte{
			"sha256": hash[:],
		},
	}

	for i, r := range delegations {
		// create role
		role, err := data.NewRole(r, 1, []string{k.ID()}, []string{""}, nil)
		assert.NoError(t, err)

		// add role to repo
		repo.UpdateDelegations(role, []data.PublicKey{k})
		repo.InitTargets(r)

		// add a target to the role
		_, err = repo.AddTargets(r, data.Files{strconv.Itoa(i): f})
		assert.NoError(t, err)
	}

	// returns the right level
	fileMeta, role := client.TargetMeta("targets", "1")
	assert.Equal(t, &f, fileMeta)
	assert.Equal(t, "targets/level1/a", role)

	// looks only in subtree
	fileMeta, role = client.TargetMeta("targets/level1/a", "0")
	assert.Nil(t, fileMeta)
	assert.Equal(t, "", role)

	fileMeta, role = client.TargetMeta("targets/level1/a", "2")
	assert.Equal(t, &f, fileMeta)
	assert.Equal(t, "targets/level1/a/i", role)
}