From 2699ced85e59f1793b9b175d9060dc8be495d708 Mon Sep 17 00:00:00 2001 From: Ying Li Date: Mon, 9 May 2016 13:32:03 -0700 Subject: [PATCH] Simplify even further and only save the previous role during a root rotation so that in the saved roles named "root.version", the version is the latest version for which that root role was valid. Signed-off-by: Ying Li --- tuf/tuf.go | 40 ++++++++++++++++++---------------------- tuf/tuf_test.go | 22 +++++++++++----------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/tuf/tuf.go b/tuf/tuf.go index b6f312f410..eb838957ad 100644 --- a/tuf/tuf.go +++ b/tuf/tuf.go @@ -845,30 +845,26 @@ func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) { } } - tempRoot.Signed.Expires = expires - tempRoot.Signed.Version++ + // If the root role (root keys or root threshold) has changed, save the + // previous role under the role name "root.", such that the "n" is the + // latest root.json version for which previous root role was valid. + // Also, guard against re-saving the previous role if the latest + // saved role is the same (which should not happen). + // n = root.json version of the originalRootRole (previous role) + // n+1 = root.json version of the currRoot (current role) + // n-m = root.json version of latestSavedRole (not necessarily n-1, because the + // last root rotation could have happened several root.json versions ago + if !tr.originalRootRole.Equals(currRoot) && !tr.originalRootRole.Equals(latestSavedRole) { + rolesToSignWith = append(rolesToSignWith, tr.originalRootRole) + latestSavedRole = tr.originalRootRole - // if the root role (root keys or root threshold) has changed, save the - // current role if it hasn't already been saved, as well as saving the - // new root role - if !tr.originalRootRole.Equals(currRoot) { - // if the current role has not been saved before, save it now as - // role name "root." - if !tr.originalRootRole.Equals(latestSavedRole) { - rolesToSignWith = append(rolesToSignWith, tr.originalRootRole) - latestSavedRole = tr.originalRootRole - - versionName := oldRootVersionName(tempRoot.Signed.Version - 1) - tempRoot.Signed.Roles[versionName] = &data.RootRole{ - KeyIDs: latestSavedRole.ListKeyIDs(), Threshold: latestSavedRole.Threshold} - } - - // always save the new root as role name "root.", since - // it would not have been saved yet versionName := oldRootVersionName(tempRoot.Signed.Version) tempRoot.Signed.Roles[versionName] = &data.RootRole{ - KeyIDs: currRoot.ListKeyIDs(), Threshold: currRoot.Threshold} + KeyIDs: latestSavedRole.ListKeyIDs(), Threshold: latestSavedRole.Threshold} } + + tempRoot.Signed.Expires = expires + tempRoot.Signed.Version++ rolesToSignWith = append(rolesToSignWith, currRoot) signed, err := tempRoot.ToSigned() @@ -886,7 +882,7 @@ func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) { 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 { oldRootRoles := make(versionedRootRoles, 0, len(tr.Root.Signed.Roles)) @@ -902,7 +898,7 @@ func (tr *Repo) getOldRootRoles() versionedRootRoles { continue } version, err := strconv.Atoi(nameTokens[1]) - if err != nil || version > tr.Root.Signed.Version { + if err != nil || version >= tr.Root.Signed.Version { continue } diff --git a/tuf/tuf_test.go b/tuf/tuf_test.go index 99b0750adf..6753895d44 100644 --- a/tuf/tuf_test.go +++ b/tuf/tuf_test.go @@ -881,8 +881,8 @@ func TestReplaceBaseKeysInRoot(t *testing.T) { switch role { case data.CanonicalRootRole: - // root role changed, so the old role and the new role should have been saved - require.Len(t, repo.Root.Signed.Roles, origNumRoles+2) + // root role changed, so the old role should have been saved + require.Len(t, repo.Root.Signed.Roles, origNumRoles+1) default: // number of roles should not have changed require.Len(t, repo.Root.Signed.Roles, origNumRoles) @@ -1325,8 +1325,8 @@ func TestSignRootOldRootRolesAndOldSigs(t *testing.T) { repo.Root.Signed.Roles["root.4a"] = &data.RootRole{KeyIDs: []string{rootCertKeys[4].ID()}, Threshold: 1} // valid old root role and version repo.Root.Signed.Roles["root.5"] = &data.RootRole{KeyIDs: []string{rootCertKeys[5].ID()}, Threshold: 1} - // higher than current root version, so invalid name, but valid root role - repo.Root.Signed.Roles["root.7"] = &data.RootRole{KeyIDs: []string{rootCertKeys[7].ID()}, Threshold: 1} + // greater or equal to the current root version, so invalid name, but valid root role + repo.Root.Signed.Roles["root.6"] = &data.RootRole{KeyIDs: []string{rootCertKeys[7].ID()}, Threshold: 1} lenRootRoles := len(repo.Root.Signed.Roles) @@ -1372,18 +1372,18 @@ func TestSignRootOldRootRolesAndOldSigs(t *testing.T) { rootCertKeys[8], // newly rotated key } verifySignatureList(t, signedObj, expectedSigningKeys...) - // verify that we saved the previous root, since it wasn't in the list of old roots, - // and the new root (which overwrote an invalid root) + // verify that we saved the previous root (which overwrote an invalid saved root), + // since it wasn't in the list of old valid roots, and we didn't save the newest + // role require.NotNil(t, repo.Root.Signed.Roles["root.6"]) require.Equal(t, data.RootRole{KeyIDs: []string{rootCertKeys[6].ID()}, Threshold: 1}, *repo.Root.Signed.Roles["root.6"]) - require.NotNil(t, repo.Root.Signed.Roles["root.7"]) - require.Equal(t, data.RootRole{KeyIDs: []string{rootCertKeys[8].ID()}, Threshold: 1}, - *repo.Root.Signed.Roles["root.7"]) + require.Nil(t, repo.Root.Signed.Roles["root.7"]) - // bumped version, 2 new roles, but one overwrote the previous root.7, so one additional role + // bumped version, 1 new roles, but one overwrote the previous root.6, so actually no + // additional roles require.Equal(t, 7, repo.Root.Signed.Version) - require.Len(t, repo.Root.Signed.Roles, lenRootRoles+1) + require.Len(t, repo.Root.Signed.Roles, lenRootRoles) require.True(t, oldExpiry.Before(repo.Root.Signed.Expires)) lenRootRoles = len(repo.Root.Signed.Roles)