mirror of https://github.com/docker/docs.git
Merge pull request #555 from docker/remove-kdb-from-verify
Remove keyDB from signed.Verify
This commit is contained in:
commit
b673a15a49
|
@ -79,7 +79,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
|
|||
}
|
||||
}
|
||||
|
||||
targetsToUpdate, err := loadAndValidateTargets(gun, repo, roles, kdb, store)
|
||||
targetsToUpdate, err := loadAndValidateTargets(gun, repo, roles, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
|
|||
}
|
||||
}
|
||||
|
||||
if err := validateSnapshot(snapshotRole, oldSnap, roles[snapshotRole], roles, kdb); err != nil {
|
||||
if err := validateSnapshot(snapshotRole, oldSnap, roles[snapshotRole], roles, repo); err != nil {
|
||||
logrus.Error("ErrBadSnapshot: ", err.Error())
|
||||
return nil, validation.ErrBadSnapshot{Msg: err.Error()}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
|
|||
// Then:
|
||||
// - generate a new snapshot
|
||||
// - add it to the updates
|
||||
update, err := generateSnapshot(gun, kdb, repo, store)
|
||||
update, err := generateSnapshot(gun, repo, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
|
|||
return updatesToApply, nil
|
||||
}
|
||||
|
||||
func loadAndValidateTargets(gun string, repo *tuf.Repo, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB, store storage.MetaStore) ([]storage.MetaUpdate, error) {
|
||||
func loadAndValidateTargets(gun string, repo *tuf.Repo, roles map[string]storage.MetaUpdate, store storage.MetaStore) ([]storage.MetaUpdate, error) {
|
||||
targetsRoles := make(utils.RoleList, 0)
|
||||
for role := range roles {
|
||||
if role == data.CanonicalTargetsRole || data.IsDelegation(role) {
|
||||
|
@ -160,8 +160,8 @@ func loadAndValidateTargets(gun string, repo *tuf.Repo, roles map[string]storage
|
|||
t *data.SignedTargets
|
||||
err error
|
||||
)
|
||||
if t, err = validateTargets(role, roles, kdb); err != nil {
|
||||
if err == signed.ErrUnknownRole {
|
||||
if t, err = validateTargets(role, roles, repo); err != nil {
|
||||
if _, ok := err.(tuf.ErrNotLoaded); ok {
|
||||
// role wasn't found in its parent. It has been removed
|
||||
// or never existed. Drop this role from the update
|
||||
// (by not adding it to updatesToApply)
|
||||
|
@ -193,9 +193,9 @@ func loadTargetsFromStore(gun, role string, repo *tuf.Repo, store storage.MetaSt
|
|||
return repo.SetTargets(role, t)
|
||||
}
|
||||
|
||||
func generateSnapshot(gun string, kdb *keys.KeyDB, repo *tuf.Repo, store storage.MetaStore) (*storage.MetaUpdate, error) {
|
||||
role := kdb.GetRole(data.CanonicalSnapshotRole)
|
||||
if role == nil {
|
||||
func generateSnapshot(gun string, repo *tuf.Repo, store storage.MetaStore) (*storage.MetaUpdate, error) {
|
||||
role, err := repo.GetRoleWithKeys(data.CanonicalSnapshotRole)
|
||||
if err != nil {
|
||||
return nil, validation.ErrBadRoot{Msg: "root did not include snapshot role"}
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ func generateSnapshot(gun string, kdb *keys.KeyDB, repo *tuf.Repo, store storage
|
|||
}, nil
|
||||
}
|
||||
|
||||
func validateSnapshot(role string, oldSnap *data.SignedSnapshot, snapUpdate storage.MetaUpdate, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) error {
|
||||
func validateSnapshot(role string, oldSnap *data.SignedSnapshot, snapUpdate storage.MetaUpdate, roles map[string]storage.MetaUpdate, repo *tuf.Repo) error {
|
||||
s := &data.Signed{}
|
||||
err := json.Unmarshal(snapUpdate.Data, s)
|
||||
if err != nil {
|
||||
|
@ -265,7 +265,11 @@ func validateSnapshot(role string, oldSnap *data.SignedSnapshot, snapUpdate stor
|
|||
}
|
||||
// version specifically gets validated when writing to store to
|
||||
// better handle race conditions there.
|
||||
if err := signed.Verify(s, role, 0, kdb); err != nil {
|
||||
snapshotRole, err := repo.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := signed.Verify(s, snapshotRole, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -315,7 +319,7 @@ func checkHashes(meta data.FileMeta, update []byte) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func validateTargets(role string, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) (*data.SignedTargets, error) {
|
||||
func validateTargets(role string, roles map[string]storage.MetaUpdate, repo *tuf.Repo) (*data.SignedTargets, error) {
|
||||
// TODO: when delegations are being validated, validate parent
|
||||
// role exists for any delegation
|
||||
s := &data.Signed{}
|
||||
|
@ -325,7 +329,11 @@ func validateTargets(role string, roles map[string]storage.MetaUpdate, kdb *keys
|
|||
}
|
||||
// version specifically gets validated when writing to store to
|
||||
// better handle race conditions there.
|
||||
if err := signed.Verify(s, role, 0, kdb); err != nil {
|
||||
targetsRole, err := repo.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := signed.Verify(s, targetsRole, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := data.TargetsFromSigned(s)
|
||||
|
|
|
@ -270,11 +270,10 @@ func TestValidateSnapshotGenerateWithPrev(t *testing.T) {
|
|||
kdb, repo, cs, err := testutils.EmptyRepo("docker.com/notary")
|
||||
assert.NoError(t, err)
|
||||
store := storage.NewMemStorage()
|
||||
snapRole := kdb.GetRole(data.CanonicalSnapshotRole)
|
||||
snapRole, err := repo.GetRoleWithKeys(data.CanonicalSnapshotRole)
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, id := range snapRole.KeyIDs {
|
||||
k := kdb.GetKey(id)
|
||||
assert.NotNil(t, k)
|
||||
for _, k := range snapRole.Keys {
|
||||
err := store.SetKey("testGUN", data.CanonicalSnapshotRole, k.Algorithm(), k.Public())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -311,11 +310,10 @@ func TestValidateSnapshotGeneratePrevCorrupt(t *testing.T) {
|
|||
kdb, repo, cs, err := testutils.EmptyRepo("docker.com/notary")
|
||||
assert.NoError(t, err)
|
||||
store := storage.NewMemStorage()
|
||||
snapRole := kdb.GetRole(data.CanonicalSnapshotRole)
|
||||
snapRole, err := repo.GetRoleWithKeys(data.CanonicalSnapshotRole)
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, id := range snapRole.KeyIDs {
|
||||
k := kdb.GetKey(id)
|
||||
assert.NotNil(t, k)
|
||||
for _, k := range snapRole.Keys {
|
||||
err := store.SetKey("testGUN", data.CanonicalSnapshotRole, k.Algorithm(), k.Public())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -342,11 +340,10 @@ func TestValidateSnapshotGenerateNoTargets(t *testing.T) {
|
|||
kdb, repo, cs, err := testutils.EmptyRepo("docker.com/notary")
|
||||
assert.NoError(t, err)
|
||||
store := storage.NewMemStorage()
|
||||
snapRole := kdb.GetRole(data.CanonicalSnapshotRole)
|
||||
snapRole, err := repo.GetRoleWithKeys(data.CanonicalSnapshotRole)
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, id := range snapRole.KeyIDs {
|
||||
k := kdb.GetKey(id)
|
||||
assert.NotNil(t, k)
|
||||
for _, k := range snapRole.Keys {
|
||||
err := store.SetKey("testGUN", data.CanonicalSnapshotRole, k.Algorithm(), k.Public())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -367,11 +364,10 @@ func TestValidateSnapshotGenerate(t *testing.T) {
|
|||
kdb, repo, cs, err := testutils.EmptyRepo("docker.com/notary")
|
||||
assert.NoError(t, err)
|
||||
store := storage.NewMemStorage()
|
||||
snapRole := kdb.GetRole(data.CanonicalSnapshotRole)
|
||||
snapRole, err := repo.GetRoleWithKeys(data.CanonicalSnapshotRole)
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, id := range snapRole.KeyIDs {
|
||||
k := kdb.GetKey(id)
|
||||
assert.NotNil(t, k)
|
||||
for _, k := range snapRole.Keys {
|
||||
err := store.SetKey("testGUN", data.CanonicalSnapshotRole, k.Algorithm(), k.Public())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -799,18 +795,18 @@ func TestValidateTargetsModifiedHash(t *testing.T) {
|
|||
|
||||
// ### generateSnapshot tests ###
|
||||
func TestGenerateSnapshotNoRole(t *testing.T) {
|
||||
kdb := keys.NewDB()
|
||||
_, err := generateSnapshot("gun", kdb, nil, nil)
|
||||
repo := tuf.NewRepo(keys.NewDB(), nil)
|
||||
_, err := generateSnapshot("gun", repo, nil)
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, validation.ErrBadRoot{}, err)
|
||||
}
|
||||
|
||||
func TestGenerateSnapshotNoKey(t *testing.T) {
|
||||
kdb, _, _, err := testutils.EmptyRepo("docker.com/notary")
|
||||
_, repo, _, err := testutils.EmptyRepo("docker.com/notary")
|
||||
assert.NoError(t, err)
|
||||
store := storage.NewMemStorage()
|
||||
|
||||
_, err = generateSnapshot("gun", kdb, nil, store)
|
||||
_, err = generateSnapshot("gun", repo, store)
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, validation.ErrBadHierarchy{}, err)
|
||||
}
|
||||
|
@ -904,7 +900,7 @@ func TestValidateTargetsLoadParent(t *testing.T) {
|
|||
valRepo := tuf.NewRepo(kdb, nil)
|
||||
valRepo.SetRoot(baseRepo.Root)
|
||||
|
||||
updates, err := loadAndValidateTargets("gun", valRepo, roles, kdb, store)
|
||||
updates, err := loadAndValidateTargets("gun", valRepo, roles, store)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, updates, 1)
|
||||
assert.Equal(t, "targets/level1", updates[0].Role)
|
||||
|
@ -960,7 +956,7 @@ func TestValidateTargetsParentInUpdate(t *testing.T) {
|
|||
// 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)
|
||||
updates, err := loadAndValidateTargets("gun", valRepo, roles, store)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, updates, 2)
|
||||
assert.Equal(t, "targets", updates[0].Role)
|
||||
|
@ -1002,7 +998,7 @@ func TestValidateTargetsParentNotFound(t *testing.T) {
|
|||
valRepo := tuf.NewRepo(kdb, nil)
|
||||
valRepo.SetRoot(baseRepo.Root)
|
||||
|
||||
_, err = loadAndValidateTargets("gun", valRepo, roles, kdb, store)
|
||||
_, err = loadAndValidateTargets("gun", valRepo, roles, store)
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, storage.ErrNotFound{}, err)
|
||||
}
|
||||
|
@ -1057,7 +1053,7 @@ func TestValidateTargetsRoleNotInParent(t *testing.T) {
|
|||
// 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)
|
||||
updates, err := loadAndValidateTargets("gun", valRepo, roles, store)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, updates, 1)
|
||||
assert.Equal(t, "targets", updates[0].Role)
|
||||
|
|
|
@ -200,12 +200,16 @@ func (c *Client) downloadRoot() error {
|
|||
|
||||
func (c Client) verifyRoot(role string, s *data.Signed, minVersion int) error {
|
||||
// this will confirm that the root has been signed by the old root role
|
||||
// as c.keysDB contains the root keys we bootstrapped with.
|
||||
// with the root keys we bootstrapped with.
|
||||
// Still need to determine if there has been a root key update and
|
||||
// confirm signature with new root key
|
||||
logrus.Debug("verifying root with existing keys")
|
||||
err := signed.Verify(s, role, minVersion, c.keysDB)
|
||||
rootRole, err := c.local.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
logrus.Debug("no previous root role loaded")
|
||||
return err
|
||||
}
|
||||
if err = signed.Verify(s, rootRole, minVersion); err != nil {
|
||||
logrus.Debug("root did not verify with existing keys")
|
||||
return err
|
||||
}
|
||||
|
@ -227,7 +231,12 @@ func (c Client) verifyRoot(role string, s *data.Signed, minVersion int) error {
|
|||
// TODO(endophage): be more intelligent and only re-verify if we detect
|
||||
// there has been a change in root keys
|
||||
logrus.Debug("verifying root with updated keys")
|
||||
err = signed.Verify(s, role, minVersion, c.keysDB)
|
||||
rootRole, err = c.local.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
logrus.Debug("root role with new keys not loaded")
|
||||
return err
|
||||
}
|
||||
err = signed.Verify(s, rootRole, minVersion)
|
||||
if err != nil {
|
||||
logrus.Debug("root did not verify with new keys")
|
||||
return err
|
||||
|
@ -267,7 +276,7 @@ func (c *Client) downloadTimestamp() error {
|
|||
// from remote, only using the cache one if we couldn't reach remote.
|
||||
raw, s, err := c.downloadSigned(role, notary.MaxTimestampSize, nil)
|
||||
if err == nil {
|
||||
ts, err = c.verifyTimestamp(s, version, c.keysDB)
|
||||
ts, err = c.verifyTimestamp(s, version)
|
||||
if err == nil {
|
||||
logrus.Debug("successfully verified downloaded timestamp")
|
||||
c.cache.SetMeta(role, raw)
|
||||
|
@ -282,7 +291,7 @@ func (c *Client) downloadTimestamp() error {
|
|||
}
|
||||
logrus.Debug(err.Error())
|
||||
logrus.Warn("Error while downloading remote metadata, using cached timestamp - this might not be the latest version available remotely")
|
||||
ts, err = c.verifyTimestamp(old, version, c.keysDB)
|
||||
ts, err = c.verifyTimestamp(old, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -292,8 +301,13 @@ func (c *Client) downloadTimestamp() error {
|
|||
}
|
||||
|
||||
// verifies that a timestamp is valid, and returned the SignedTimestamp object to add to the tuf repo
|
||||
func (c *Client) verifyTimestamp(s *data.Signed, minVersion int, kdb *keys.KeyDB) (*data.SignedTimestamp, error) {
|
||||
if err := signed.Verify(s, data.CanonicalTimestampRole, minVersion, kdb); err != nil {
|
||||
func (c *Client) verifyTimestamp(s *data.Signed, minVersion int) (*data.SignedTimestamp, error) {
|
||||
timestampRole, err := c.local.GetRoleWithKeys(data.CanonicalTimestampRole)
|
||||
if err != nil {
|
||||
logrus.Debug("no timestamp role loaded")
|
||||
return nil, err
|
||||
}
|
||||
if err := signed.Verify(s, timestampRole, minVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data.TimestampFromSigned(s)
|
||||
|
@ -351,7 +365,12 @@ func (c *Client) downloadSnapshot() error {
|
|||
s = old
|
||||
}
|
||||
|
||||
err = signed.Verify(s, role, version, c.keysDB)
|
||||
snapshotRole, err := c.local.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
logrus.Debug("no snapshot role loaded")
|
||||
return err
|
||||
}
|
||||
err = signed.Verify(s, snapshotRole, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -489,8 +508,12 @@ func (c Client) getTargetsFile(role string, keyIDs []string, snapshotMeta data.F
|
|||
s = old
|
||||
}
|
||||
|
||||
err = signed.Verify(s, role, version, c.keysDB)
|
||||
targetsRole, err := c.local.GetRoleWithKeys(role)
|
||||
if err != nil {
|
||||
logrus.Debugf("no %s role loaded", role)
|
||||
return nil, err
|
||||
}
|
||||
if err = signed.Verify(s, targetsRole, version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Debugf("successfully verified %s", role)
|
||||
|
|
|
@ -2,10 +2,11 @@ package data
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Canonical base role names
|
||||
|
@ -244,3 +245,9 @@ func subtractStrSlices(orig, remove []string) []string {
|
|||
}
|
||||
return keep
|
||||
}
|
||||
|
||||
// RoleWithKeys is a role that has the signing keys for the role embedded
|
||||
type RoleWithKeys struct {
|
||||
Role
|
||||
Keys Keys
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/go/canonical/json"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/keys"
|
||||
)
|
||||
|
||||
// Various basic signing errors
|
||||
|
@ -57,18 +56,18 @@ func VerifyRoot(s *data.Signed, minVersion int, keys map[string]data.PublicKey)
|
|||
continue
|
||||
}
|
||||
// threshold of 1 so return on first success
|
||||
return verifyMeta(s, "root", minVersion)
|
||||
return verifyMeta(s, data.CanonicalRootRole, minVersion)
|
||||
}
|
||||
return ErrRoleThreshold{}
|
||||
}
|
||||
|
||||
// Verify checks the signatures and metadata (expiry, version) for the signed role
|
||||
// data
|
||||
func Verify(s *data.Signed, role string, minVersion int, db *keys.KeyDB) error {
|
||||
if err := verifyMeta(s, role, minVersion); err != nil {
|
||||
func Verify(s *data.Signed, role *data.RoleWithKeys, minVersion int) error {
|
||||
if err := verifyMeta(s, role.Name, minVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
return VerifySignatures(s, role, db)
|
||||
return VerifySignatures(s, role)
|
||||
}
|
||||
|
||||
func verifyMeta(s *data.Signed, role string, minVersion int) error {
|
||||
|
@ -96,21 +95,18 @@ func IsExpired(t time.Time) bool {
|
|||
}
|
||||
|
||||
// VerifySignatures checks the we have sufficient valid signatures for the given role
|
||||
func VerifySignatures(s *data.Signed, role string, db *keys.KeyDB) error {
|
||||
func VerifySignatures(s *data.Signed, roleData *data.RoleWithKeys) error {
|
||||
if len(s.Signatures) == 0 {
|
||||
return ErrNoSignatures
|
||||
}
|
||||
|
||||
roleData := db.GetRole(role)
|
||||
if roleData == nil {
|
||||
return ErrUnknownRole
|
||||
}
|
||||
|
||||
if roleData.Threshold < 1 {
|
||||
return ErrRoleThreshold{}
|
||||
}
|
||||
logrus.Debugf("%s role has key IDs: %s", role, strings.Join(roleData.KeyIDs, ","))
|
||||
logrus.Debugf("%s role has key IDs: %s", roleData.Name, strings.Join(roleData.KeyIDs, ","))
|
||||
|
||||
// remarshal the signed part so we can verify the signature, since the signature has
|
||||
// to be of a canonically marshalled signed object
|
||||
var decoded map[string]interface{}
|
||||
if err := json.Unmarshal(s.Signed, &decoded); err != nil {
|
||||
return err
|
||||
|
@ -127,8 +123,8 @@ func VerifySignatures(s *data.Signed, role string, db *keys.KeyDB) error {
|
|||
logrus.Debugf("continuing b/c keyid was invalid: %s for roledata %s\n", sig.KeyID, roleData)
|
||||
continue
|
||||
}
|
||||
key := db.GetKey(sig.KeyID)
|
||||
if key == nil {
|
||||
key, ok := roleData.Keys[sig.KeyID]
|
||||
if !ok {
|
||||
logrus.Debugf("continuing b/c keyid lookup was nil: %s\n", sig.KeyID)
|
||||
continue
|
||||
}
|
||||
|
@ -153,28 +149,3 @@ func VerifySignatures(s *data.Signed, role string, db *keys.KeyDB) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals and verifys the raw bytes for a given role's metadata
|
||||
func Unmarshal(b []byte, v interface{}, role string, minVersion int, db *keys.KeyDB) error {
|
||||
s := &data.Signed{}
|
||||
if err := json.Unmarshal(b, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Verify(s, role, minVersion, db); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(s.Signed, v)
|
||||
}
|
||||
|
||||
// UnmarshalTrusted unmarshals and verifies signatures only, not metadata, for a
|
||||
// given role's metadata
|
||||
func UnmarshalTrusted(b []byte, v interface{}, role string, db *keys.KeyDB) error {
|
||||
s := &data.Signed{}
|
||||
if err := json.Unmarshal(b, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := VerifySignatures(s, role, db); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(s.Signed, v)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/keys"
|
||||
)
|
||||
|
||||
func TestRoleNoKeys(t *testing.T) {
|
||||
|
@ -24,17 +23,15 @@ func TestRoleNoKeys(t *testing.T) {
|
|||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
db := keys.NewDB()
|
||||
assert.NoError(t, err)
|
||||
err = db.AddRole(r)
|
||||
assert.NoError(t, err)
|
||||
roleWithKeys := &data.RoleWithKeys{Role: *r, Keys: data.Keys{k.ID(): k}}
|
||||
|
||||
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)
|
||||
err = Verify(s, "root", 1, db)
|
||||
err = Verify(s, roleWithKeys, 1)
|
||||
assert.IsType(t, ErrRoleThreshold{}, err)
|
||||
}
|
||||
|
||||
|
@ -50,18 +47,15 @@ func TestNotEnoughSigs(t *testing.T) {
|
|||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
db := keys.NewDB()
|
||||
assert.NoError(t, err)
|
||||
db.AddKey(k)
|
||||
err = db.AddRole(r)
|
||||
assert.NoError(t, err)
|
||||
roleWithKeys := &data.RoleWithKeys{Role: *r, Keys: data.Keys{k.ID(): k}}
|
||||
|
||||
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)
|
||||
err = Verify(s, "root", 1, db)
|
||||
err = Verify(s, roleWithKeys, 1)
|
||||
assert.IsType(t, ErrRoleThreshold{}, err)
|
||||
}
|
||||
|
||||
|
@ -79,12 +73,8 @@ func TestMoreThanEnoughSigs(t *testing.T) {
|
|||
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)
|
||||
roleWithKeys := &data.RoleWithKeys{Role: *r, Keys: data.Keys{k1.ID(): k1, k2.ID(): k2}}
|
||||
|
||||
meta := &data.SignedCommon{Type: "Root", Version: 1, Expires: data.DefaultExpires("root")}
|
||||
|
||||
b, err := json.MarshalCanonical(meta)
|
||||
|
@ -92,7 +82,7 @@ func TestMoreThanEnoughSigs(t *testing.T) {
|
|||
s := &data.Signed{Signed: b}
|
||||
Sign(cs, s, k1, k2)
|
||||
assert.Equal(t, 2, len(s.Signatures))
|
||||
err = Verify(s, "root", 1, db)
|
||||
err = Verify(s, roleWithKeys, 1)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -108,11 +98,8 @@ func TestDuplicateSigs(t *testing.T) {
|
|||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
db := keys.NewDB()
|
||||
assert.NoError(t, err)
|
||||
db.AddKey(k)
|
||||
err = db.AddRole(r)
|
||||
assert.NoError(t, err)
|
||||
roleWithKeys := &data.RoleWithKeys{Role: *r, Keys: data.Keys{k.ID(): k}}
|
||||
|
||||
meta := &data.SignedCommon{Type: "Root", Version: 1, Expires: data.DefaultExpires("root")}
|
||||
|
||||
b, err := json.MarshalCanonical(meta)
|
||||
|
@ -120,7 +107,7 @@ func TestDuplicateSigs(t *testing.T) {
|
|||
s := &data.Signed{Signed: b}
|
||||
Sign(cs, s, k)
|
||||
s.Signatures = append(s.Signatures, s.Signatures[0])
|
||||
err = Verify(s, "root", 1, db)
|
||||
err = Verify(s, roleWithKeys, 1)
|
||||
assert.IsType(t, ErrRoleThreshold{}, err)
|
||||
}
|
||||
|
||||
|
@ -138,12 +125,8 @@ func TestUnknownKeyBelowThreshold(t *testing.T) {
|
|||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
db := keys.NewDB()
|
||||
assert.NoError(t, err)
|
||||
db.AddKey(k)
|
||||
db.AddKey(unknown)
|
||||
err = db.AddRole(r)
|
||||
assert.NoError(t, err)
|
||||
roleWithKeys := &data.RoleWithKeys{Role: *r, Keys: data.Keys{k.ID(): k, unknown.ID(): unknown}}
|
||||
|
||||
meta := &data.SignedCommon{Type: "Root", Version: 1, Expires: data.DefaultExpires("root")}
|
||||
|
||||
b, err := json.MarshalCanonical(meta)
|
||||
|
@ -151,23 +134,22 @@ func TestUnknownKeyBelowThreshold(t *testing.T) {
|
|||
s := &data.Signed{Signed: b}
|
||||
Sign(cs, s, k, unknown)
|
||||
s.Signatures = append(s.Signatures)
|
||||
err = Verify(s, "root", 1, db)
|
||||
err = Verify(s, roleWithKeys, 1)
|
||||
assert.IsType(t, ErrRoleThreshold{}, err)
|
||||
}
|
||||
|
||||
func Test(t *testing.T) {
|
||||
cryptoService := NewEd25519()
|
||||
type test struct {
|
||||
name string
|
||||
keys []data.PublicKey
|
||||
roles map[string]*data.Role
|
||||
s *data.Signed
|
||||
ver int
|
||||
exp *time.Time
|
||||
typ string
|
||||
role string
|
||||
err error
|
||||
mut func(*test)
|
||||
name string
|
||||
roleData *data.RoleWithKeys
|
||||
s *data.Signed
|
||||
ver int
|
||||
exp *time.Time
|
||||
typ string
|
||||
role string
|
||||
err error
|
||||
mut func(*test)
|
||||
}
|
||||
|
||||
expiredTime := time.Now().Add(-time.Hour)
|
||||
|
@ -204,7 +186,6 @@ func Test(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, run := range tests {
|
||||
db := keys.NewDB()
|
||||
if run.role == "" {
|
||||
run.role = "root"
|
||||
}
|
||||
|
@ -218,9 +199,8 @@ func Test(t *testing.T) {
|
|||
if run.typ == "" {
|
||||
run.typ = data.TUFTypes[run.role]
|
||||
}
|
||||
if run.keys == nil && run.s == nil {
|
||||
if run.s == nil {
|
||||
k, _ := cryptoService.Create("root", data.ED25519Key)
|
||||
db.AddKey(k)
|
||||
r, err := data.NewRole(
|
||||
"root",
|
||||
1,
|
||||
|
@ -229,7 +209,7 @@ func Test(t *testing.T) {
|
|||
nil,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
db.AddRole(r)
|
||||
run.roleData = &data.RoleWithKeys{Role: *r, Keys: data.Keys{k.ID(): k}}
|
||||
meta := &data.SignedCommon{Type: run.typ, Version: run.ver, Expires: *run.exp}
|
||||
|
||||
b, err := json.MarshalCanonical(meta)
|
||||
|
@ -242,7 +222,7 @@ func Test(t *testing.T) {
|
|||
run.mut(&run)
|
||||
}
|
||||
|
||||
err := Verify(run.s, run.role, minVer, db)
|
||||
err := Verify(run.s, run.roleData, minVer)
|
||||
if e, ok := run.err.(ErrExpired); ok {
|
||||
assertErrExpired(t, err, e)
|
||||
} else {
|
||||
|
|
|
@ -406,12 +406,14 @@ func TestSwizzlerChangeRootKey(t *testing.T) {
|
|||
|
||||
require.NotEqual(t, len(origRoot.Signed.Keys), len(newRoot.Signed.Keys))
|
||||
|
||||
var rootRole data.Role
|
||||
for r, origRole := range origRoot.Signed.Roles {
|
||||
newRole := newRoot.Signed.Roles[r]
|
||||
require.Len(t, origRole.KeyIDs, 1)
|
||||
require.Len(t, newRole.KeyIDs, 1)
|
||||
if r == data.CanonicalRootRole {
|
||||
require.NotEqual(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
|
||||
rootRole = data.Role{RootRole: *newRole, Name: data.CanonicalRootRole}
|
||||
} else {
|
||||
require.Equal(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
|
||||
}
|
||||
|
@ -420,7 +422,9 @@ func TestSwizzlerChangeRootKey(t *testing.T) {
|
|||
require.NoError(t, tufRepo.SetRoot(newRoot))
|
||||
signedThing, err := newRoot.ToSigned()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, signed.Verify(signedThing, data.CanonicalRootRole, 1, kdb))
|
||||
newKey := newRoot.Signed.Keys[rootRole.KeyIDs[0]]
|
||||
require.NoError(t, signed.Verify(signedThing,
|
||||
&data.RoleWithKeys{Role: rootRole, Keys: map[string]data.PublicKey{newKey.ID(): newKey}}, 1))
|
||||
default:
|
||||
require.True(t, bytes.Equal(origMeta, newMeta), "bytes have changed for role %s", role)
|
||||
}
|
||||
|
|
16
tuf/tuf.go
16
tuf/tuf.go
|
@ -771,3 +771,19 @@ func (tr Repo) sign(signedData *data.Signed, role data.Role) (*data.Signed, erro
|
|||
}
|
||||
return signedData, nil
|
||||
}
|
||||
|
||||
// GetRoleWithKeys returns a RoleWithKeys object, given a role name.
|
||||
func (tr Repo) GetRoleWithKeys(role string) (*data.RoleWithKeys, error) {
|
||||
roleData := tr.keysDB.GetRole(role)
|
||||
if roleData == nil {
|
||||
return nil, ErrNotLoaded{role: role}
|
||||
}
|
||||
keysInRole := make(data.Keys)
|
||||
for _, keyID := range roleData.KeyIDs {
|
||||
k := tr.keysDB.GetKey(keyID)
|
||||
if k != nil {
|
||||
keysInRole[keyID] = k
|
||||
}
|
||||
}
|
||||
return &data.RoleWithKeys{Role: *roleData, Keys: keysInRole}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue