From 9a411b6182aa49f6c13fc40cecfa4afaac9725e1 Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Mon, 25 Mar 2024 15:17:53 -0400 Subject: [PATCH 1/6] Update TAP 20 and move to accepted * update rotate file definitions to match those in TAP 8 * add reference implementation * minor wording changes Signed-off-by: Marina Moore --- tap20.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tap20.md b/tap20.md index d6c6e8b..8a663f4 100644 --- a/tap20.md +++ b/tap20.md @@ -3,7 +3,7 @@ * Version: 1 * Last-Modified: 29-Jan-2024 * Author: Marina Moore -* Status: Draft +* Status: Accepted * Content-Type: text/markdown * Created: 19-Jan-2024 @@ -39,7 +39,7 @@ still the source of trust, but allows the role to act independently. # Motivation -Several use cases can benefit from an independent revocation mechanism: +The following use case can benefit from an independent revocation mechanism: ## Community repositories @@ -81,21 +81,21 @@ signatures wrapper as in tuf spec, not shown here): ```python { - "_type" : "rotate" , - "previous" : PREV_FILENAME + "_type" : "rotate", + "version" : VERSION, "role" : ROLE, "keys" : { KEYID : KEY , ... } , - "threshold" : THRESHOLD } + "threshold" : THRESHOLD } ``` Where ROLE, KEYID, KEY, and THRESHOLD are as defined in the original tuf spec. The value of ROLE has to be the same as the role for the -delegation. The value of THRESHOLD is its new value. PREV_FILENAME is -the name of the previous rotate file in the chain, or the empty string if this is -the first rotate file for this role. The keys specify the new valid keys +delegation. The value of THRESHOLD is its new value. VERSION is the index of +this rotate file, incrementing by 1 on each rotation. The keys specify the new +valid keys and associated key ids (which may be a subset or superset of the old ones). A rotate file does _not_ contain an expiration date, it is meant to be signed once and never modified. The rotate @@ -125,23 +125,23 @@ where NULL is the null key. ### Prioritizing Self Revocation -Rotation files are immutable unless replaced with a revocation (rotate -to null). This is the only case in which they can be replaced or +Rotation files are immutable unless replaced with a revocation. +This is the only case in which they can be replaced or modified. If a client wants to rotate to a different key, without having access to their currently delegated private key, this requires a key revocation by the delegating metadata. - # Security Analysis There should be no negative security impact. The major benefits are that many security-sensitive revocations that require key use by multiple parties, will now be much easier to do. -Clients need to take care to check for rotation to a null key (rotate +Clients need to take care to check for revocation (rotate files that contain a null key). This shall be handled in the same manner as an invalid metadata signature on by the role possessing -the key. The role will be invalid until it is re-delegated to with a new key. +the key. The role will be invalid until it is re-delegated to with a new +rolename and key. Clients MUST use snapshot metadata to ensure that they receive all rotate files in the chain. @@ -162,7 +162,7 @@ verify the revocations. # Augmented Reference Implementation -TODO +https://github.com/theupdateframework/python-tuf/pull/2257/files # Copyright From 3a3278e9d729f314153220363ca7bcab0b2c7106 Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Mon, 25 Mar 2024 15:19:10 -0400 Subject: [PATCH 2/6] update index to move TAP 20 to accepted Signed-off-by: Marina Moore --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f19604..f1fa36b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ * [TAP 11: Using POUFs for Interoperability](tap11.md) * [TAP 12: Improving keyid flexibility](tap12.md) * [TAP 15: Succinct hashed bin delegations](tap15.md) +* [TAP 20: Self-revocation](tap20.md) ## Draft @@ -21,7 +22,6 @@ * [TAP 17: Remove Signature Wrapper from the TUF Specification](tap17.md) * [TAP 18: Ephemeral identity verification using sigstore's Fulcio for TUF developer key management](tap18.md) * [TAP 19: Content Addressable Systems and TUF](tap19.md) -* [TAP 20: Self-revocation](tap20.md) ## Deferred From 60e950f4d617eb74c92959b8b0beb744238c3d6f Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Tue, 9 Apr 2024 08:56:08 -0400 Subject: [PATCH 3/6] [TAP 8] Describe DoS attack and prevention (#183) * Describe DoS attack and prevention Signed-off-by: Marina Moore * Add rotate file limit Signed-off-by: Marina Moore * Address multiple-delegation Signed-off-by: Marina Moore --------- Signed-off-by: Marina Moore --- tap8.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tap8.md b/tap8.md index 8470b9e..b2ccc47 100644 --- a/tap8.md +++ b/tap8.md @@ -210,6 +210,8 @@ old rotate files for the old role should be deleted and removed from snapshot on the next snapshot key rotation. The client will determine the correct rotate file for the new role by starting from VERSION 1. +The repository SHOULD set a limit to the number of rotate files per role. This limit should be clear to all key holders (for example, it could be in repository documentation or added to root metadata). Once this number of rotate files is reached, the repository will reject rotations for this role and the delegator should create a new delegation to a new role. + ## Client workflow A client who wants to install foo now fetches Alice's targets file and will @@ -370,6 +372,14 @@ As a general note, this TAP only extends the possibilities of a target, but the delegation mechanism is still in place - i.e. a key higher up in the delegation can always revoke / modify the delegation itself. +A key holder or attacker could upload a large number of rotate files to DoS the +role or repository. This is similar to an existing attack where an attacker +with access to a private key can upload several different versions of the same +metadata file. To mitigate this attack on rotations, the repository should +set a limit on the number of rotate files per role. If a role needs to change +more than this limit, the delegator must re-delegate to a new role, re-setting +any rotations. + Baton - Baton: Certificate Agility for Android’s Decentralized Signing Infrastructure - http://people.scs.carleton.ca/~paulv/papers/wisec2014-baton.pdf - is a similar proposal to extend Android's signing infrastructure. From 4ce8f1fdadcabf7eac8b13237ab2d0b75d7d10b9 Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Tue, 9 Apr 2024 08:08:18 -0500 Subject: [PATCH 4/6] Clarify the client process Signed-off-by: Marina Moore --- tap20.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tap20.md b/tap20.md index 8a663f4..9eb8ea2 100644 --- a/tap20.md +++ b/tap20.md @@ -77,7 +77,7 @@ from that proposal to support key revocation. ## Rotate file (from TAP 8) The signed portion of a `rotate` file is as follows (there's also a -signatures wrapper as in tuf spec, not shown here): +signatures wrapper as in the TUF specification, not shown here): ```python { @@ -92,7 +92,7 @@ signatures wrapper as in tuf spec, not shown here): ``` Where ROLE, KEYID, KEY, and THRESHOLD are as defined in the original -tuf spec. The value of ROLE has to be the same as the role for the +TUF specification. The value of ROLE has to be the same as the role for the delegation. The value of THRESHOLD is its new value. VERSION is the index of this rotate file, incrementing by 1 on each rotation. The keys specify the new valid keys @@ -101,6 +101,10 @@ the old ones). A rotate file does _not_ contain an expiration date, it is meant to be signed once and never modified. The rotate file has to be signed with an old threshold of old keys. +This rotate file will be named `ROLE.rotate.VERSION` where ROLE and VERSION are +defined as above and go into a 'rotate' folder on the repository that +contains all rotate files for the repository. + ## Rotation to Null @@ -131,6 +135,13 @@ modified. If a client wants to rotate to a different key, without having access to their currently delegated private key, this requires a key revocation by the delegating metadata. +## Client workflow + +Rotate files will be downloaded by clients as described in TAP 8. Once a +rotate file is downloaded and verified, the client will check for a rotation +to null. If such a rotation to null is found, the client will treat the given +role as revoked. + # Security Analysis There should be no negative security impact. The major benefits are From e3e4a8da82a59f3a41ca0f6dbd422693651629f9 Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Tue, 9 Apr 2024 08:29:05 -0500 Subject: [PATCH 5/6] fix typo client -> key holder Signed-off-by: Marina Moore --- tap20.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tap20.md b/tap20.md index 9eb8ea2..d08dda7 100644 --- a/tap20.md +++ b/tap20.md @@ -131,7 +131,7 @@ where NULL is the null key. Rotation files are immutable unless replaced with a revocation. This is the only case in which they can be replaced or -modified. If a client wants to rotate to a different +modified. If a key holder wants to rotate to a different key, without having access to their currently delegated private key, this requires a key revocation by the delegating metadata. From 683cc5d8d10c791ec1972d15f317defda5704ad0 Mon Sep 17 00:00:00 2001 From: Marina Moore Date: Mon, 15 Apr 2024 09:47:02 -0400 Subject: [PATCH 6/6] Move TAP 8 to accepted (#187) * Remove remaining references to revocation and add implementation revocation has been moved ot TAP 20. Signed-off-by: Marina Moore * Move TAP 8 to accepted Signed-off-by: Marina Moore * Apply suggestions from code review Co-authored-by: John Kjell Signed-off-by: Marina Moore --------- Signed-off-by: Marina Moore Signed-off-by: Marina Moore Co-authored-by: John Kjell --- README.md | 2 +- tap8.md | 76 +++++++++++++------------------------------------------ 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 8f19604..f6d1a2c 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ * [TAP 3: Multi-role delegations](tap3.md) * [TAP 4: Multiple repository consensus on entrusted targets](tap4.md) * [TAP 6: Include specification version in metadata](tap6.md) +* [TAP 8: Key rotation and explicit self-revocation](tap8.md) * [TAP 9: Mandatory metadata signing schemes](tap9.md) * [TAP 10: Remove native support for compressed metadata](tap10.md) * [TAP 11: Using POUFs for Interoperability](tap11.md) @@ -15,7 +16,6 @@ ## Draft -* [TAP 8: Key rotation and explicit self-revocation](tap8.md) * [TAP 13: User Selection of the Top-Level Target Files Through Mapping Metadata](tap13.md) * [TAP 16: Snapshot Merkle Trees](tap16.md) * [TAP 17: Remove Signature Wrapper from the TUF Specification](tap17.md) diff --git a/tap8.md b/tap8.md index b2ccc47..4e6ba8a 100644 --- a/tap8.md +++ b/tap8.md @@ -1,9 +1,9 @@ * TAP: 8 * Title: Key rotation and explicit self-revocation * Version: 2 -* Last-Modified: 16-Nov-2022 +* Last-Modified: 26-Mar-2024 * Author: Hannes Mehnert, Justin Cappos, Marina Moore -* Status: Draft +* Status: Accepted * Content-Type: text/markdown * Created: 10-May-2017 @@ -30,26 +30,12 @@ Snapshot and timestamp cannot use this rotation mechanism. Conceptually, the rotation process says if you trusted threshold of keys X = X_0, ... X_n, now instead trust threshold of keys Y = Y_0, ... Y_n. Rotation -of a key may be performed any number of times, transferring trust from X to Y, then +of a role may be performed any number of times, transferring trust from X to Y, then from Y to Z, etc. Trust can even be transferred back from Z to X, allowing a key to be added to a role, then later removed. If a single key needs to be replaced, it can be safely rotated using the mechanism in this TAP. -The mechanism in this TAP has an additional use case: if a rotation -to a null key is detected, it causes the role to no longer be trusted. -A role could use a rotation to a null key if they suspect a threshold of keys -have been compromised -(a lost hard drive, system breach, etc). The role is able to create a -rotation to null without the help of the delegator, so they are able to -explicitly revoke trust in the role immediately, improving response time -to a key compromise. A rotation to a null key revokes trust in the role, -not specific keys, so all keys associated with the role will be invalid -after a rotation to null. The client will detect a rotation -to a null key and treat it as if the metadata was unsigned. - -A delegator to a role A is able to help A recover from a rotation to null of A by -delegating to a new set of keys for A with a new role name. -Additionally, a delegator can overrule a rotate file by delegating to a new role +A delegator can overrule a rotate file by delegating to a new role with a new set of keys. This ensures that the delegator is still the source of trust, but allows the role to act independently. @@ -71,7 +57,7 @@ delegations to be redone whenever this quorum changed.) Adding and removing delegations of a project often uses the project role's key which is delegated to. This project role gives persons with access to it elevated privileges, and needs intervention from a higher level of delegations if -it needs to be rotated or revoked. +it needs to be rotated. With TAP 8, the delegation can be assigned to a role (that contains a set of keys and a threshold value). Developers could then collectively sign @@ -130,15 +116,15 @@ role T to delegate to the new keyset e. If one of role D's keys is compromised, they have to wait for role T to replace the key with a new, trusted key. -With this proposal, the owner of role D can replace their own key, and also -revoke their key without relying on the delegator. This will improve +With this proposal, the owner of role D can replace their own key +without relying on the delegator. This will improve response time to key compromises and prevent key sharing by allowing keys to be rotated more regularly. Combined with multi-role delegations this allows project teams to shrink and grow without delegation to a project key. TUF already contains a key rotation mechanism, which is only specified and used for the root file. This proposal allows the rotation -mechanism to be used by other delegations, and extends it with self-revocation. +mechanism to be used by other delegations. # Specification @@ -152,7 +138,7 @@ delegations stay intact, the targets can rotate keys, remove keys, or add keys. ## Rotate file The signed portion of a `rotate` file is as follows (there's also a -signatures wrapper as in tuf spec, not shown here): +signatures wrapper as in the TUF specification, not shown here): ```python { @@ -162,12 +148,12 @@ signatures wrapper as in tuf spec, not shown here): "keys" : { KEYID : KEY , ... } , - "threshold" : THRESHOLD } + "threshold" : THRESHOLD } ``` Where ROLE, KEYID, KEY, and THRESHOLD are as defined in the original -tuf spec. The value of ROLE has to be the same as the role for the +tuf specification. The value of ROLE has to be the same as the role for the delegation. The value of THRESHOLD is its new value. VERSION is the integer version number of rotate files for this role. Version numbers MUST increase by exactly 1 from the previous rotate file for @@ -221,16 +207,13 @@ The client will then look for all files that begin with `rotate/foo.rotate` in the snapshot metadata. The client will process these in version order (ie starting with `rotate/foo.rotate.1`, then `rotate/foo.rotate.2` by first checking for this version file in a local cache. The client will then fetch the rotate file from -remote. If the remote file is a rotation to null, and is signed with the currently -trusted keys, the client will halt the verification of this metadata and act as if -it is unverified when continuing the update process (and look for metadata from -the next role in the pre-order depth-first search). Otherwise, the client should +remote. The client should then ensure that the cached file is identical to the remote version. The client will then verify the rotate file using the currently trusted public key(s) for this role. If a rotate file is successfully verified, the client will update the set of trusted keys for -this role to be the set listed in the rotate files. If key data is missing -or there is a rotation to null, the targets file is invalid and the client will +this role to be the set listed in the rotate files. If key data is missing, +the targets file is invalid and the client will proceed with the update process as if verification for this role failed (by moving on to another trusted role for this target, or reporting an error to the user). @@ -294,20 +277,6 @@ foo.rotate.2 is created, which contains the existing keyids as well as Evelyn's public key, and a threshold value of 3. This is signed with at least 2 keys from the current set of keyids. -## Rotation to Null - -Clients need to check for rotations to a null key, and any delegation pointing -to a rotation to a null key is invalid. The null key is a hard coded value used across -tuf implementations. This enables a role to explicitly revoke their -own key(s) by introducing a rotation to null. - -**Prioritizing Self Revocation** -Rotation files are immutable unless replaced with a revocation (rotate -to null). This is the only case in which they can be replaced or -modified. If a client wants to rotate to a different -key, without having access to their currently delegated private key, -this requires a key revocation by the delegating metadata. - Rotations which do not have any entry point anymore (the delegation they stem from has can been replaced with new keys) can be safely removed from the repository. If the delegation of foo is @@ -327,7 +296,7 @@ The interaction between the Fulcio TAP and this TAP may impact the security considerations in this TAP. If the Fulcio server or OIDC issuer is compromised, an attacker could gain control over all TUF roles controlled by that entity. If this happens, the attacker could use TAP 8 to create large-scale rotations -to null to perform a denial of service. However, this attack can be safely +to perform a denial of service. However, this attack can be safely recovered from using the delegator to replace all effected keys. This is especially effective if the top-level targets is controlled by offline keys. For this reason, we recommend that both root and top-level targets are @@ -347,25 +316,16 @@ provide a simple mechanism for extending and shrinking project membership without an individual with elevated privileges, but based on a threshold of signatures. -Clients need to take care to check for rotation to a null key (rotate -files that contain a null key). This shall be handled in the -same manner as an invalid metadata signature on by the role possessing -the key. The role will be invalid until it is re-delegated to with a new key. -Clients MUST use snapshot metadata to ensure that they recieve all rotate files +Clients MUST use snapshot metadata to ensure that they receive all rotate files in the chain. -Intentionally rotating to null enables a repository, a -project, and individuals to explicitly revoke their key material -themselves. An individual whose key is compromised can introduce -a rotation to null, and all delegations to them will be invalid. - For mitigation of private key compromises, rotation can be used if and only if it can be assured that the legitimate holder is faster (at the snapshot service, and/or at the client) than the attacker who got control over the private key. Because this is hard to achieve, it is recommended for proper mitigation that the delegation itself is changed from the compromised key to a new key as soon as possible. Key revocation using -rotation defined in this TAP can be used as a stop-gap for delegations made +rotation defined in TAP 20 can be used as a stop-gap for delegations made by offline keys that may take some time to update. As a general note, this TAP only extends the possibilities of a target, @@ -396,7 +356,7 @@ verify the rotation chain. # Augmented Reference Implementation -TODO +https://github.com/theupdateframework/python-tuf/pull/2257/files # Copyright