Skip to content

Commit

Permalink
Add tests to make sure the top level targets 'delegation' edge has as…
Browse files Browse the repository at this point in the history
…sociated keys. Make NewDelegationsIterator return an error if the passed DB is missing the top level targets role
  • Loading branch information
ethan-lowman-dd committed Feb 28, 2022
1 parent 3716bf3 commit d2ae1bc
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 19 deletions.
6 changes: 5 additions & 1 deletion client/delegations.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) {
// - filter delegations with paths or path_hash_prefixes matching searched target
// - 5.6.7.1 cycles protection
// - 5.6.7.2 terminations
delegations := targets.NewDelegationsIterator(target, c.db)
delegations, err := targets.NewDelegationsIterator(target, c.db)
if err != nil {
return data.TargetFileMeta{}, err
}

for i := 0; i < c.MaxDelegations; i++ {
d, ok := delegations.Next()
if !ok {
Expand Down
24 changes: 14 additions & 10 deletions pkg/targets/delegation.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package targets

import (
"errors"

"github.com/theupdateframework/go-tuf/data"
"github.com/theupdateframework/go-tuf/internal/sets"
"github.com/theupdateframework/go-tuf/verify"
)

Expand All @@ -17,30 +20,31 @@ type delegationsIterator struct {
visitedRoles map[string]struct{}
}

var ErrTopLevelTargetsRoleMissing = errors.New("tuf: top level targets role missing from top level keys DB")

// NewDelegationsIterator initialises an iterator with a first step
// on top level targets.
func NewDelegationsIterator(target string, topLevelKeysDB *verify.DB) *delegationsIterator {
// role := topLevelKeysDB.GetRole("targets")
keyIDs := []string{}

// if role != nil {
// keyIDs = sets.StringSetToSlice(role.KeyIDs)
// }
func NewDelegationsIterator(target string, topLevelKeysDB *verify.DB) (*delegationsIterator, error) {
targetsRole := topLevelKeysDB.GetRole("targets")
if targetsRole == nil {
return nil, ErrTopLevelTargetsRoleMissing
}

i := &delegationsIterator{
target: target,
stack: []Delegation{
{
Delegatee: data.DelegatedRole{
Name: "targets",
KeyIDs: keyIDs,
Name: "targets",
KeyIDs: sets.StringSetToSlice(targetsRole.KeyIDs),
Threshold: targetsRole.Threshold,
},
DB: topLevelKeysDB,
},
},
visitedRoles: make(map[string]struct{}),
}
return i
return i, nil
}

func (d *delegationsIterator) Next() (value Delegation, ok bool) {
Expand Down
51 changes: 43 additions & 8 deletions pkg/targets/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,35 @@ var (
)

func TestDelegationsIterator(t *testing.T) {
defaultKeyIDs := []string{"26b878ad73362774b8b69dd4fdeb2cc6a2688e4133ed5ace9e18a06e9d998a6d"}
topTargetsPubKey := &data.PublicKey{
Type: data.KeyTypeEd25519,
Scheme: data.KeySchemeEd25519,
Algorithms: data.HashAlgorithms,
Value: []byte(`{"public":"aaaaec567e5901ba3976c34f7cd5169704292439bf71e6aa19c64b96706f95ef"}`),
}
delTargetsPubKey := &data.PublicKey{
Type: data.KeyTypeEd25519,
Scheme: data.KeySchemeEd25519,
Algorithms: data.HashAlgorithms,
Value: []byte(`{"public":"bbbbec567e5901ba3976c34f7cd5169704292439bf71e6aa19c64b96706f95ef"}`),
}

defaultKeyIDs := delTargetsPubKey.IDs()
var iteratorTests = []struct {
testName string
roles map[string][]data.DelegatedRole
file string
resultOrder []string
err error
}{
{
testName: "no delegation",
roles: map[string][]data.DelegatedRole{
"targets": {},
},
file: "test.txt",
resultOrder: []string{"targets"},
},
{
testName: "no termination",
roles: map[string][]data.DelegatedRole{
Expand Down Expand Up @@ -180,23 +201,28 @@ func TestDelegationsIterator(t *testing.T) {

for _, tt := range iteratorTests {
t.Run(tt.testName, func(t *testing.T) {
flattened := []data.DelegatedRole{}
for _, roles := range tt.roles {
flattened = append(flattened, roles...)
}
db, err := verify.NewDBFromDelegations(&data.Delegations{
Roles: flattened,
topLevelDB := verify.NewDB()
topLevelDB.AddKey(topTargetsPubKey.IDs()[0], topTargetsPubKey)
topLevelDB.AddRole("targets", &data.Role{
KeyIDs: topTargetsPubKey.IDs(),
Threshold: 1,
})

d, err := NewDelegationsIterator(tt.file, topLevelDB)
assert.NoError(t, err)
d := NewDelegationsIterator(tt.file, db)

var iterationOrder []string
for {
r, ok := d.Next()
if !ok {
break
}

// A delegation should have associated keys. Testing the exact keys
// isn't useful in this module since the keys are supplied by the
// caller in the arguments to Add().
assert.Greater(t, len(r.Delegatee.KeyIDs), 0)

iterationOrder = append(iterationOrder, r.Delegatee.Name)
delegations, ok := tt.roles[r.Delegatee.Name]
if !ok {
Expand All @@ -215,3 +241,12 @@ func TestDelegationsIterator(t *testing.T) {
})
}
}

func TestNewDelegationsIteratorError(t *testing.T) {
// Empty DB. It is supposed to have at least the top-level targets role and
// keys.
tldb := verify.NewDB()

_, err := NewDelegationsIterator("targets", tldb)
assert.ErrorIs(t, err, ErrTopLevelTargetsRoleMissing)
}

0 comments on commit d2ae1bc

Please sign in to comment.