package client import ( "path/filepath" "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 func (r *NotaryRepository) Witness(roles ...string) ([]string, error) { cl, err := changelist.NewFileChangelist(filepath.Join(r.tufRepoPath, "changelist")) if err != nil { return nil, err } defer cl.Close() successful := make([]string, 0, len(roles)) for _, role := range roles { // scope is role c := changelist.NewTUFChange( changelist.ActionUpdate, role, changelist.TypeWitness, "", nil, ) err = cl.Add(c) if err != nil { break } successful = append(successful, role) } return successful, err } func witnessTargets(repo *tuf.Repo, invalid *tuf.Repo, role string) error { 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", } }