Skip to content

Commit

Permalink
[Delegations prereq] Add roles helpers
Browse files Browse the repository at this point in the history
Splitting up #175
  • Loading branch information
ethan-lowman-dd committed Dec 10, 2021
1 parent 9e07992 commit a8a6feb
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 26 deletions.
41 changes: 41 additions & 0 deletions internal/roles/roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package roles

import (
"strconv"
"strings"
)

var TopLevelRoles = map[string]struct{}{
"root": {},
"targets": {},
"snapshot": {},
"timestamp": {},
}

func IsTopLevelRole(name string) bool {
_, ok := TopLevelRoles[name]
return ok
}

func IsDelegatedTargetsRole(name string) bool {
return !IsTopLevelRole(name)
}

func IsTopLevelManifest(name string) bool {
return IsTopLevelRole(strings.TrimSuffix(name, ".json"))
}

func IsDelegatedTargetsManifest(name string) bool {
return !IsTopLevelManifest(name)
}

func IsVersionedManifest(name string) bool {
parts := strings.Split(name, ".")
// Versioned manifests have the form "x.role.json"
if len(parts) < 3 {
return false
}

_, err := strconv.Atoi(parts[0])
return err == nil
}
48 changes: 48 additions & 0 deletions internal/roles/roles_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package roles

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestIsTopLevelRole(t *testing.T) {
assert.True(t, IsTopLevelRole("root"))
assert.True(t, IsTopLevelRole("targets"))
assert.True(t, IsTopLevelRole("timestamp"))
assert.True(t, IsTopLevelRole("snapshot"))
assert.False(t, IsTopLevelRole("bins"))
}

func TestIsDelegatedTargetsRole(t *testing.T) {
assert.False(t, IsDelegatedTargetsRole("root"))
assert.False(t, IsDelegatedTargetsRole("targets"))
assert.False(t, IsDelegatedTargetsRole("timestamp"))
assert.False(t, IsDelegatedTargetsRole("snapshot"))
assert.True(t, IsDelegatedTargetsRole("deleg"))
}

func TestIsTopLevelManifest(t *testing.T) {
assert.True(t, IsTopLevelManifest("root.json"))
assert.True(t, IsTopLevelManifest("targets.json"))
assert.True(t, IsTopLevelManifest("timestamp.json"))
assert.True(t, IsTopLevelManifest("snapshot.json"))
assert.False(t, IsTopLevelManifest("bins.json"))
}

func TestIsDelegatedTargetsManifest(t *testing.T) {
assert.False(t, IsDelegatedTargetsManifest("root.json"))
assert.False(t, IsDelegatedTargetsManifest("targets.json"))
assert.False(t, IsDelegatedTargetsManifest("timestamp.json"))
assert.False(t, IsDelegatedTargetsManifest("snapshot.json"))
assert.True(t, IsDelegatedTargetsManifest("bins.json"))
}

func TestIsVersionedManifest(t *testing.T) {
assert.False(t, IsVersionedManifest("a.b"))
assert.False(t, IsVersionedManifest("a.b.c"))
assert.False(t, IsVersionedManifest("a.b.json"))
assert.False(t, IsVersionedManifest("1.a"))
assert.True(t, IsVersionedManifest("1.a.json"))
assert.True(t, IsVersionedManifest("2.a.json"))
}
13 changes: 7 additions & 6 deletions repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/secure-systems-lab/go-securesystemslib/cjson"
"github.com/theupdateframework/go-tuf/data"
"github.com/theupdateframework/go-tuf/internal/roles"
"github.com/theupdateframework/go-tuf/internal/signer"
"github.com/theupdateframework/go-tuf/pkg/keys"
"github.com/theupdateframework/go-tuf/sign"
Expand Down Expand Up @@ -199,7 +200,7 @@ func (r *Repo) GetThreshold(keyRole string) (int, error) {
}

func (r *Repo) SetThreshold(keyRole string, t int) error {
if !validMetadata(keyRole + ".json") {
if !roles.IsTopLevelRole(keyRole) {
// Delegations are not currently supported, so return an error if this is not a
// top-level metadata file.
return ErrInvalidRole{keyRole}
Expand Down Expand Up @@ -319,7 +320,7 @@ func (r *Repo) timestamp() (*data.Timestamp, error) {
}

func (r *Repo) ChangePassphrase(keyRole string) error {
if !verify.ValidRole(keyRole) {
if !roles.IsTopLevelRole(keyRole) {
return ErrInvalidRole{keyRole}
}

Expand Down Expand Up @@ -352,7 +353,7 @@ func (r *Repo) AddPrivateKey(role string, signer keys.Signer) error {
}

func (r *Repo) AddPrivateKeyWithExpires(keyRole string, signer keys.Signer, expires time.Time) error {
if !verify.ValidRole(keyRole) {
if !roles.IsTopLevelRole(keyRole) {
return ErrInvalidRole{keyRole}
}

Expand Down Expand Up @@ -451,7 +452,7 @@ func (r *Repo) RevokeKey(role, id string) error {
}

func (r *Repo) RevokeKeyWithExpires(keyRole, id string, expires time.Time) error {
if !verify.ValidRole(keyRole) {
if !roles.IsTopLevelRole(keyRole) {
return ErrInvalidRole{keyRole}
}

Expand Down Expand Up @@ -555,7 +556,7 @@ func (r *Repo) setMeta(roleFilename string, meta interface{}) error {

func (r *Repo) Sign(roleFilename string) error {
role := strings.TrimSuffix(roleFilename, ".json")
if !verify.ValidRole(role) {
if !roles.IsTopLevelRole(role) {
return ErrInvalidRole{role}
}

Expand Down Expand Up @@ -591,7 +592,7 @@ func (r *Repo) Sign(roleFilename string) error {
// The name must be a valid metadata file name, like root.json.
func (r *Repo) AddOrUpdateSignature(roleFilename string, signature data.Signature) error {
role := strings.TrimSuffix(roleFilename, ".json")
if !verify.ValidRole(role) {
if !roles.IsTopLevelRole(role) {
return ErrInvalidRole{role}
}

Expand Down
22 changes: 3 additions & 19 deletions verify/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package verify

import (
"github.com/theupdateframework/go-tuf/data"
"github.com/theupdateframework/go-tuf/internal/roles"
"github.com/theupdateframework/go-tuf/pkg/keys"
)

Expand Down Expand Up @@ -44,7 +45,7 @@ func NewDelegationsVerifier(d *data.Delegations) (DelegationsVerifier, error) {
verifiers: make(map[string]keys.Verifier, len(d.Keys)),
}
for _, r := range d.Roles {
if _, ok := topLevelRoles[r.Name]; ok {
if _, ok := roles.TopLevelRoles[r.Name]; ok {
return DelegationsVerifier{}, ErrInvalidDelegatedRole
}
role := &data.Role{Threshold: r.Threshold, KeyIDs: r.KeyIDs}
Expand Down Expand Up @@ -72,25 +73,8 @@ func (db *DB) AddKey(id string, k *data.PublicKey) error {
return nil
}

var topLevelRoles = map[string]struct{}{
"root": {},
"targets": {},
"snapshot": {},
"timestamp": {},
}

// ValidRole checks if a role is a top level role.
func ValidRole(name string) bool {
return isTopLevelRole(name)
}

func isTopLevelRole(name string) bool {
_, ok := topLevelRoles[name]
return ok
}

func (db *DB) AddRole(name string, r *data.Role) error {
if !isTopLevelRole(name) {
if !roles.IsTopLevelRole(name) {
return ErrInvalidRole
}
return db.addRole(name, r)
Expand Down
3 changes: 2 additions & 1 deletion verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/secure-systems-lab/go-securesystemslib/cjson"
"github.com/theupdateframework/go-tuf/data"
"github.com/theupdateframework/go-tuf/internal/roles"
)

type signedMeta struct {
Expand All @@ -25,7 +26,7 @@ func (db *DB) VerifyIgnoreExpiredCheck(s *data.Signed, role string, minVersion i
return err
}

if isTopLevelRole(role) {
if roles.IsTopLevelRole(role) {
// Top-level roles can only sign metadata of the same type (e.g. snapshot
// metadata must be signed by the snapshot role).
if !strings.EqualFold(sm.Type, role) {
Expand Down

0 comments on commit a8a6feb

Please sign in to comment.