Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Delegations prereq 6] Use a verify.DB for delegation in client #196

Merged
merged 4 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
ethan-lowman-dd marked this conversation as resolved.
Show resolved Hide resolved
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 {
ethan-lowman-dd marked this conversation as resolved.
Show resolved Hide resolved
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