mirror of https://github.com/docker/docs.git
When signing the root, modify and sign a temporary root that gets assigned back into
the repo if signing was successful. This way, we don't mutate the existing root in a failed attempt to sign it. Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
parent
cea46f7c3e
commit
f8cd53cf2f
52
tuf/tuf.go
52
tuf/tuf.go
|
@ -842,12 +842,23 @@ func (v versionedRootRoles) Less(i, j int) bool { return v[i].version < v[j].ver
|
||||||
// back to the way it was (so version won't be incremented, for instance).
|
// back to the way it was (so version won't be incremented, for instance).
|
||||||
func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
|
func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
|
||||||
logrus.Debug("signing root...")
|
logrus.Debug("signing root...")
|
||||||
|
|
||||||
|
// duplicate root and attempt to modify it rather than the existing root
|
||||||
|
rootBytes, err := tr.Root.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tempRoot := data.SignedRoot{}
|
||||||
|
if err := json.Unmarshal(rootBytes, &tempRoot); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
currRoot, err := tr.GetBaseRole(data.CanonicalRootRole)
|
currRoot, err := tr.GetBaseRole(data.CanonicalRootRole)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
oldRootRoles, origRoles := tr.getOldRootRoles()
|
oldRootRoles := tr.getOldRootRoles()
|
||||||
|
|
||||||
var latestSavedRole data.BaseRole
|
var latestSavedRole data.BaseRole
|
||||||
rolesToSignWith := make([]data.BaseRole, 0, len(oldRootRoles))
|
rolesToSignWith := make([]data.BaseRole, 0, len(oldRootRoles))
|
||||||
|
@ -867,49 +878,48 @@ func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
|
||||||
|
|
||||||
// if the root role has changed and original role had not been saved as a previous role, save it now
|
// if the root role has changed and original role had not been saved as a previous role, save it now
|
||||||
if !tr.originalRootRole.Equals(currRoot) && !tr.originalRootRole.Equals(latestSavedRole) {
|
if !tr.originalRootRole.Equals(currRoot) && !tr.originalRootRole.Equals(latestSavedRole) {
|
||||||
tr.saveOldRootRole(tr.originalRootRole, tr.Root.Signed.Version)
|
|
||||||
rolesToSignWith = append(rolesToSignWith, tr.originalRootRole)
|
rolesToSignWith = append(rolesToSignWith, tr.originalRootRole)
|
||||||
latestSavedRole = tr.originalRootRole
|
latestSavedRole = tr.originalRootRole
|
||||||
|
|
||||||
|
versionName := oldRootVersionName(tempRoot.Signed.Version)
|
||||||
|
tempRoot.Signed.Roles[versionName] = &data.RootRole{
|
||||||
|
KeyIDs: latestSavedRole.ListKeyIDs(), Threshold: latestSavedRole.Threshold}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
origVersion := tr.Root.Signed.Expires
|
tempRoot.Signed.Expires = expires
|
||||||
tr.Root.Signed.Expires = expires
|
tempRoot.Signed.Version++
|
||||||
tr.Root.Signed.Version++
|
|
||||||
|
|
||||||
// if the current role doesn't match with the latest saved role, save it
|
// if the current role doesn't match with the latest saved role, save it
|
||||||
if !currRoot.Equals(latestSavedRole) {
|
if !currRoot.Equals(latestSavedRole) {
|
||||||
tr.saveOldRootRole(currRoot, tr.Root.Signed.Version)
|
|
||||||
rolesToSignWith = append(rolesToSignWith, currRoot)
|
rolesToSignWith = append(rolesToSignWith, currRoot)
|
||||||
|
|
||||||
|
versionName := oldRootVersionName(tempRoot.Signed.Version)
|
||||||
|
tempRoot.Signed.Roles[versionName] = &data.RootRole{
|
||||||
|
KeyIDs: currRoot.ListKeyIDs(), Threshold: currRoot.Threshold}
|
||||||
}
|
}
|
||||||
|
|
||||||
signed, err := tr.Root.ToSigned()
|
signed, err := tempRoot.ToSigned()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tr.Root.Signed.Expires = origVersion
|
|
||||||
tr.Root.Signed.Version--
|
|
||||||
tr.Root.Signed.Roles = origRoles
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
signed, err = tr.sign(signed, rolesToSignWith, tr.getOptionalRootKeys(rolesToSignWith))
|
signed, err = tr.sign(signed, rolesToSignWith, tr.getOptionalRootKeys(rolesToSignWith))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tr.Root.Signed.Expires = origVersion
|
|
||||||
tr.Root.Signed.Version--
|
|
||||||
tr.Root.Signed.Roles = origRoles
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.Root = &tempRoot
|
||||||
tr.Root.Signatures = signed.Signatures
|
tr.Root.Signatures = signed.Signatures
|
||||||
tr.originalRootRole = currRoot
|
tr.originalRootRole = currRoot
|
||||||
return signed, nil
|
return signed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all the saved previous roles <= the current root version
|
// get all the saved previous roles <= the current root version
|
||||||
func (tr *Repo) getOldRootRoles() (versionedRootRoles, map[string]*data.RootRole) {
|
func (tr *Repo) getOldRootRoles() versionedRootRoles {
|
||||||
oldRootRoles := make(versionedRootRoles, 0, len(tr.Root.Signed.Roles))
|
oldRootRoles := make(versionedRootRoles, 0, len(tr.Root.Signed.Roles))
|
||||||
oldRoles := make(map[string]*data.RootRole)
|
|
||||||
|
|
||||||
// now go through the old roles
|
// now go through the old roles
|
||||||
for roleName, r := range tr.Root.Signed.Roles {
|
for roleName := range tr.Root.Signed.Roles {
|
||||||
oldRoles[roleName] = r
|
|
||||||
// ensure that the rolename matches our format and that the version is
|
// ensure that the rolename matches our format and that the version is
|
||||||
// not too high
|
// not too high
|
||||||
if data.ValidRole(roleName) {
|
if data.ValidRole(roleName) {
|
||||||
|
@ -933,7 +943,7 @@ func (tr *Repo) getOldRootRoles() (versionedRootRoles, map[string]*data.RootRole
|
||||||
oldRootRoles = append(oldRootRoles, versionedRootRole{BaseRole: oldRole, version: version})
|
oldRootRoles = append(oldRootRoles, versionedRootRole{BaseRole: oldRole, version: version})
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldRootRoles, oldRoles
|
return oldRootRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets any extra optional root keys from the existing root.json signatures
|
// gets any extra optional root keys from the existing root.json signatures
|
||||||
|
@ -960,10 +970,8 @@ func (tr *Repo) getOptionalRootKeys(signingRoles []data.BaseRole) []data.PublicK
|
||||||
return oldKeys
|
return oldKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *Repo) saveOldRootRole(role data.BaseRole, version int) {
|
func oldRootVersionName(version int) string {
|
||||||
versionName := fmt.Sprintf("%s.%v", data.CanonicalRootRole, version)
|
return fmt.Sprintf("%s.%v", data.CanonicalRootRole, version)
|
||||||
tr.Root.Signed.Roles[versionName] = &data.RootRole{
|
|
||||||
KeyIDs: role.ListKeyIDs(), Threshold: role.Threshold}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignTargets signs the targets file for the given top level or delegated targets role
|
// SignTargets signs the targets file for the given top level or delegated targets role
|
||||||
|
|
Loading…
Reference in New Issue