-
Notifications
You must be signed in to change notification settings - Fork 510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support deprecating old root keys after rotation #942
Conversation
Can one of the admins verify this patch? |
86ce5c3
to
bea7cac
Compare
@@ -13,11 +13,12 @@ import ( | |||
"github.com/docker/notary/trustmanager" | |||
"github.com/docker/notary/utils" | |||
|
|||
"os" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would you mind if moving this package up to those canonical packages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do - could've sworn gofmt does this for you.
bea7cac
to
24273a3
Compare
@@ -906,7 +909,7 @@ func (r *NotaryRepository) bootstrapClient(checkInitialized bool) (*TUFClient, e | |||
// RotateKey removes all existing keys associated with the role, and either | |||
// creates and adds one new key or delegates managing the key to the server. | |||
// These changes are staged in a changelist until publish is called. | |||
func (r *NotaryRepository) RotateKey(role string, serverManagesKey bool) error { | |||
func (r *NotaryRepository) RotateKey(role string, serverManagesKey bool, keyList []string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we document what keyList
is in the function description?
thanks @ecordell for your work on this! I have a couple of things:
|
24273a3
to
377176c
Compare
@riyazdf thanks for taking a look!
|
4bc591c
to
5ec5862
Compare
@@ -88,6 +92,13 @@ func (mts *MockCryptoService) GetKey(keyID string) data.PublicKey { | |||
return nil | |||
} | |||
|
|||
func (mts *MockCryptoService) GetKeyInfo(keyID string) (trustmanager.KeyInfo, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can probably be removed too.
@@ -203,6 +204,11 @@ func (trust *NotarySigner) GetKey(keyid string) data.PublicKey { | |||
return pubKey | |||
} | |||
|
|||
// GetKeyInfo returns the gun and role given a keyID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can probably be removed too.
@@ -215,6 +215,16 @@ func (rdb *RethinkDBKeyStore) GetKey(keyID string) data.PublicKey { | |||
return data.NewPublicKey(dbPrivateKey.Algorithm, dbPrivateKey.Public) | |||
} | |||
|
|||
// GetKeyInfo returns the gun and role given a KeyID, and does not activate the key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can probably be removed too.
@@ -228,6 +228,15 @@ func (s *SQLKeyDBStore) GetKey(keyID string) data.PublicKey { | |||
return data.NewPublicKey(privKey.Algorithm, []byte(privKey.Public)) | |||
} | |||
|
|||
// GetKeyInfo returns role and GUN info of a key by ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can probably be removed too.
@ecordell We were thinking for (3) something like having the local cache at v1 (either expired or not), and downloading an expired v2 and a valid v3? It should successfully update to v3. Similarly for (2), except v2 is not properly rotated. The only reason being because some checks are skipped for intermediate roots (like checksum and expiry), and this would validate that the root signing is validated for the intermediate roots. |
7a15b51
to
1dc0dc9
Compare
@cyli I gotcha - I added those extra tests to be safe, thanks for clarifying. I also removed those other |
@ecordell Thanks for adding them!
Not at all, easy to lose track :) |
jenkins, test this please |
LGTM! Thank you so much for all your work and patience on this @ecordell! |
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
Signed-off-by: Evan Cordell <[email protected]>
61a274c
to
bebce70
Compare
Thanks! I've rebased on master, so hopefully everything will be good shortly. |
Jenkins, test this please |
|
||
return oldKeys | ||
} | ||
|
||
func oldRootVersionName(version int) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Followup PR: I think we can remove this function. I don't think it's used anywhere with the new root rotation logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@ecordell thank you for all the hard work and perseverance on this. Conceptually and concretely I think this root rotation methodology is an outstanding improvement to both the TUF spec and Notary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple of nits between myself and @endophage's comment that can be followed up in a subsequent PR.
Overall LGTM, thank you for continuously working through this PR! 🎉
@@ -700,11 +714,84 @@ func signRootIfNecessary(updates map[string][]byte, repo *tuf.Repo, initialPubli | |||
return nil | |||
} | |||
|
|||
// Fetch back a `legacyVersions` number of roots files, collect the root public keys | |||
// This includes old `root` roles as well as legacy versioned root roles, e.g. `1.root` | |||
func (r *NotaryRepository) oldKeysForLegacyClientSupport(legacyVersions int, initialPublish bool) (data.KeyList, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
followup PR: I'm pretty happy with this function but would like to add some unit tests around overly large or negative legacyVersions and the skipping logic
Thanks for your patience and great work on this @ecordell ! |
Thanks for all of the reviews! I can't merge myself if someone with write access would like to :) Glad to finally have this wrapped up. |
This adds support for root key rotation as described in #835.
Previously, old root keys needed to sign for all subsequent
root.json
files in perpetuity. This changes root rotation so that new keys are trusted if signed by the previous root key/threshold. To support this behavior, root files can now be requested by version number from the server.This also adds an additional command line flag for
rotate
,--key
, which allows specifying keys to rotate the root to. This supports specifying multiple keys, but all must be available to sign locally (i.e. this doesn't support threshold/witness behavior at the moment).Example:
Closes #1014
Closes #835