Skip to content

Commit

Permalink
[Delegations prereq 6] Use a verify.DB for delegation in client (#196)
Browse files Browse the repository at this point in the history
* [Delegations prereq] Use a verify.DB for delegation in client

Splitting up #175

* stash

* Add tests to make sure the top level targets 'delegation' edge has associated keys. Make NewDelegationsIterator return an error if the passed DB is missing the top level targets role

* Pass delegation directly to loadDelegatedTargets
  • Loading branch information
ethan-lowman-dd authored Mar 7, 2022
1 parent b98aea5 commit 314eed4
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 82 deletions.
22 changes: 12 additions & 10 deletions client/delegations.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ 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)
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 {
return data.TargetFileMeta{}, ErrUnknownTarget{target, snapshot.Version}
}

// covers 5.6.{1,2,3,4,5,6}
targets, err := c.loadDelegatedTargets(snapshot, d.Delegatee.Name, d.Verifier)
targets, err := c.loadDelegatedTargets(snapshot, d)
if err != nil {
return data.TargetFileMeta{}, err
}
Expand All @@ -39,11 +43,11 @@ func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) {
}

if targets.Delegations != nil {
delegationsVerifier, err := verify.NewDelegationsVerifier(targets.Delegations)
delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations)
if err != nil {
return data.TargetFileMeta{}, err
}
err = delegations.Add(targets.Delegations.Roles, d.Delegatee.Name, delegationsVerifier)
err = delegations.Add(targets.Delegations.Roles, d.Delegatee.Name, delegationsDB)
if err != nil {
return data.TargetFileMeta{}, err
}
Expand Down Expand Up @@ -75,7 +79,9 @@ func (c *Client) loadLocalSnapshot() (*data.Snapshot, error) {
}

// loadDelegatedTargets downloads, decodes, verifies and stores targets
func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, role string, verifier verify.DelegationsVerifier) (*data.Targets, error) {
func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, delegation targets.Delegation) (*data.Targets, error) {
role := delegation.Delegatee.Name

var err error
fileName := role + ".json"
fileMeta, ok := snapshot.Meta[fileName]
Expand All @@ -98,11 +104,7 @@ func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, role string, veri
// 5.6.3 verify signature with parent public keys
// 5.6.5 verify that the targets is not expired
// role "targets" is a top role verified by root keys loaded in the client db
if role == "targets" {
err = c.db.Unmarshal(raw, targets, role, fileMeta.Version)
} else {
err = verifier.Unmarshal(raw, targets, role, fileMeta.Version)
}
err = delegation.DB.Unmarshal(raw, targets, role, fileMeta.Version)
if err != nil {
return nil, ErrDecodeFailed{fileName, err}
}
Expand Down
9 changes: 8 additions & 1 deletion client/delegations_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
Expand All @@ -26,7 +27,13 @@ func TestGetTargetMeta(t *testing.T) {

f, err := c.getTargetFileMeta("f.txt")
assert.Nil(t, err)
assert.Equal(t, int64(15), f.Length)
hash := sha256.Sum256([]byte("Contents: f.txt"))
assert.Equal(t, data.HexBytes(hash[:]), f.Hashes["sha256"])

f, err = c.getTargetFileMeta("targets.txt")
assert.Nil(t, err)
hash = sha256.Sum256([]byte("Contents: targets.txt"))
assert.Equal(t, data.HexBytes(hash[:]), f.Hashes["sha256"])
}

func TestMaxDelegations(t *testing.T) {
Expand Down
29 changes: 22 additions & 7 deletions pkg/targets/delegation.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package targets

import (
"errors"

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

type Delegation struct {
Delegator string
Verifier verify.DelegationsVerifier
Delegatee data.DelegatedRole
DB *verify.DB
}

type delegationsIterator struct {
Expand All @@ -17,19 +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) *delegationsIterator {
// on top level targets.
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"},
Delegatee: data.DelegatedRole{
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 Expand Up @@ -57,7 +72,7 @@ func (d *delegationsIterator) Next() (value Delegation, ok bool) {
return delegation, true
}

func (d *delegationsIterator) Add(roles []data.DelegatedRole, delegator string, verifier verify.DelegationsVerifier) error {
func (d *delegationsIterator) Add(roles []data.DelegatedRole, delegator string, db *verify.DB) error {
for i := len(roles) - 1; i >= 0; i-- {
// Push the roles onto the stack in reverse so we get an preorder traversal
// of the delegations graph.
Expand All @@ -70,7 +85,7 @@ func (d *delegationsIterator) Add(roles []data.DelegatedRole, delegator string,
delegation := Delegation{
Delegator: delegator,
Delegatee: r,
Verifier: verifier,
DB: db,
}
d.stack = append(d.stack, delegation)
}
Expand Down
Loading

0 comments on commit 314eed4

Please sign in to comment.