2017-04-17 18:08:24 -04:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/docker/notary/client/changelist"
|
|
|
|
"github.com/docker/notary/tuf"
|
|
|
|
"github.com/docker/notary/tuf/data"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Witness creates change objects to witness (i.e. re-sign) the given
|
|
|
|
// roles on the next publish. One change is created per role
|
2017-09-11 17:07:00 -04:00
|
|
|
func (r *repository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
|
2017-08-24 18:40:24 -04:00
|
|
|
var err error
|
|
|
|
successful := make([]data.RoleName, 0, len(roles))
|
2017-04-17 18:08:24 -04:00
|
|
|
for _, role := range roles {
|
|
|
|
// scope is role
|
|
|
|
c := changelist.NewTUFChange(
|
|
|
|
changelist.ActionUpdate,
|
|
|
|
role,
|
|
|
|
changelist.TypeWitness,
|
|
|
|
"",
|
|
|
|
nil,
|
|
|
|
)
|
2017-08-24 18:40:24 -04:00
|
|
|
err = r.changelist.Add(c)
|
2017-04-17 18:08:24 -04:00
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
successful = append(successful, role)
|
|
|
|
}
|
|
|
|
return successful, err
|
|
|
|
}
|
|
|
|
|
2017-08-24 18:40:24 -04:00
|
|
|
func witnessTargets(repo *tuf.Repo, invalid *tuf.Repo, role data.RoleName) error {
|
2017-04-17 18:08:24 -04:00
|
|
|
if r, ok := repo.Targets[role]; ok {
|
|
|
|
// role is already valid, mark for re-signing/updating
|
|
|
|
r.Dirty = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if roleObj, err := repo.GetDelegationRole(role); err == nil && invalid != nil {
|
|
|
|
// A role with a threshold > len(keys) is technically invalid, but we let it build in the builder because
|
|
|
|
// we want to be able to download the role (which may still have targets on it), add more keys, and then
|
|
|
|
// witness the role, thus bringing it back to valid. However, if no keys have been added before witnessing,
|
|
|
|
// then it is still an invalid role, and can't be witnessed because nothing can bring it back to valid.
|
|
|
|
if roleObj.Threshold > len(roleObj.Keys) {
|
|
|
|
return data.ErrInvalidRole{
|
|
|
|
Role: role,
|
|
|
|
Reason: "role does not specify enough valid signing keys to meet its required threshold",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r, ok := invalid.Targets[role]; ok {
|
|
|
|
// role is recognized but invalid, move to valid data and mark for re-signing
|
|
|
|
repo.Targets[role] = r
|
|
|
|
r.Dirty = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// role isn't recognized, even as invalid
|
|
|
|
return data.ErrInvalidRole{
|
|
|
|
Role: role,
|
|
|
|
Reason: "this role is not known",
|
|
|
|
}
|
|
|
|
}
|