Skip to content

Commit d405b79

Browse files
mnm678joshuagl
andauthored
[TAP 8] Simplify rotate file names (#167)
* [TAP 8] Simplify rotate file names Signed-off-by: Marina Moore <mnm678@gmail.com> * Recommend use of hash in snapshot for rotate files For extra protection in the event of a key compromise, this recommends the use of hashes in snapshot, and the secure storage of previous keys. Signed-off-by: Marina Moore <mnm678@gmail.com> * Add section about interaction with TAP 4 Signed-off-by: Marina Moore <mnm678@gmail.com> * [TAP 8] Start at version 1 for consistency Signed-off-by: Marina Moore <mnm678@gmail.com> * [TAP 8] Update client workflow to include snapshot check Signed-off-by: Marina Moore <mnm678@gmail.com> * fix line wrap Signed-off-by: Marina Moore <mnm678@gmail.com> * Add additional clarificatio to client workflow Signed-off-by: Marina Moore <mnm678@gmail.com> * clarify "unverified" Signed-off-by: Marina Moore <mnm678@gmail.com> * minor edits Signed-off-by: Marina Moore <mnm678@gmail.com> * re-delegation should use a new rolename This change ensures that if two parties delegate to the same role, there won't be a state where the two delegations have different keys, and the rotations only apply to one of these. It also simplifies finding rotate files after a delegation change Signed-off-by: Marina Moore <mnm678@gmail.com> * Update tap8.md Co-authored-by: Joshua Lock <joshuagloe@gmail.com> Signed-off-by: Marina Moore <mnm678@users.noreply.github.com> --------- Signed-off-by: Marina Moore <mnm678@gmail.com> Signed-off-by: Marina Moore <mnm678@users.noreply.github.com> Co-authored-by: Joshua Lock <joshuagloe@gmail.com>
1 parent 7318556 commit d405b79

1 file changed

Lines changed: 86 additions & 63 deletions

File tree

tap8.md

Lines changed: 86 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ after a rotation to null. The client will detect a rotation
4848
to a null key and treat it as if the metadata was unsigned.
4949

5050
A delegator to a role A is able to help A recover from a rotation to null of A by
51-
delegating to a new set of keys for A.
52-
Additionally, a delegator can overrule a rotate file by delegating to the role
51+
delegating to a new set of keys for A with a new role name.
52+
Additionally, a delegator can overrule a rotate file by delegating to a new role
5353
with a new set of keys. This ensures that the delegator is still the source of
5454
trust, but allows the role to act independently.
5555

@@ -144,10 +144,10 @@ mechanism to be used by other delegations, and extends it with self-revocation.
144144
# Specification
145145

146146
To support key rotation, the new metadata type `rotate` is
147-
introduced, which contains the new public key(s), the threshold, a hash
148-
of the previous rotate file in the chain, and is
149-
signed by a threshold of old public keys. The intuition is while
150-
delegations keep intact, the targets can rotate keys, shrink or grow.
147+
introduced, which contains the new public key(s), the threshold, a version
148+
number, and is
149+
signed by a threshold of old public keys. The intuition is that while
150+
delegations stay intact, the targets can rotate keys, remove keys, or add keys.
151151

152152
## Rotate file
153153

@@ -156,8 +156,8 @@ signatures wrapper as in tuf spec, not shown here):
156156

157157
```python
158158
{
159-
"_type" : "rotate" ,
160-
"previous" : PREV_FILENAME
159+
"_type" : "rotate",
160+
"version" : VERSION,
161161
"role" : ROLE,
162162
"keys" : {
163163
KEYID : KEY
@@ -168,60 +168,81 @@ signatures wrapper as in tuf spec, not shown here):
168168

169169
Where ROLE, KEYID, KEY, and THRESHOLD are as defined in the original
170170
tuf spec. The value of ROLE has to be the same as the role for the
171-
delegation. The value of THRESHOLD is its new value. PREV_FILENAME is
172-
the name of the previous rotate file in the chain, or the empty string if this is
173-
the first rotate file for this role. The keys specify the new valid keys
171+
delegation. The value of THRESHOLD is its new value. VERSION is
172+
the integer version number of rotate files for this role. Version
173+
numbers MUST increase by exactly 1 from the previous rotate file for
174+
this role. The keys specify the new valid keys
174175
and associated key ids (which may be a subset or superset of
175-
the old ones). A rotate file does _not_ contain an expiration date,
176+
the old ones). A rotate file does _not_ contain an expiration date, as
176177
it is meant to be signed once and never modified. The rotate
177-
file has to be signed with an old threshold of old keys.
178+
file has to be signed with an old threshold of old keys. All keys in a
179+
rotation chain, other than a chain that has a rotation to null, should
180+
be securely stored.
178181

179-
The rotate file will go into a repository in a 'rotate' folder that contains
182+
The rotate file will go into a 'rotate' folder on the repository that contains
180183
all rotate files for the repository. These files will be listed in snapshot
181-
metadata for the repository so that the client can verify that they recieve
182-
all current rotate files.
184+
metadata for the repository so that the client can verify that they receive
185+
all current rotate files. The files listed in snapshot SHOULD contain a
186+
hash in order to ensure that an attacker that later compromises previously
187+
trusted keys cannot replace a rotate file. If a rotate file listed in
188+
snapshot for a role is not found, the user MUST act as if the role's metadata
189+
is not signed with a valid threshold of keys.
183190

184191
Let's consider a motivating example, project foo is delegated to Alice.
185192
Alice's computer with the key material got stolen, but the disk was
186193
encrypted. To be safe, she decides to get her key from her backup and
187-
roll over her key to a fresh one. To do that, she creates a file
188-
`foo.rotate.ID.PREV`. This file contains her new key, a threshold of 1, and
194+
rotate her key to a fresh one. To do that, she creates a file
195+
`foo.rotate.VERSION`. This file contains her new key, a threshold of 1, and
189196
is signed with her old key. She signs her targets file with the new key,
190197
and uploads both the rotate file and the freshly signed targets file to
191198
the repository.
192199

193-
The first filename suffix, referred as `ID` above and below, is the hex
194-
representation of the SHA256 hash of the concatenation (using "." as
195-
separator) of the KEYIDs (in ascending lexical order), and the old
196-
threshold value, encoded decimal as ASCII (0x31 for 1, 0x32 for 2,
197-
0x31 0x30 for 10).
198-
199-
The second suffix, referred to as 'PREV' is a SHA256 hash of the previous
200-
rotate file, or the empty string if there is no previous rotate file.
201-
This prevents rotation cycles.
200+
The filename suffix, referred as `VERSION` above and below, is the
201+
same as the VERSION listed in the metadata.
202202

203203
The existing delegation to Alice's old key is still valid. The client will
204-
start with this delegation and look for rotation files to determine the current
205-
set of trusted keys.
204+
start with this delegation and look for rotate files to determine the current
205+
set of trusted keys. They will see `foo.rotate.1` and discover Alice's new key.
206206

207-
If the delegation is changed to include her new key, it will also be valid. Any
208-
old rotate files for this role should be deleted and removed from snapshot on
209-
the next snapshot key rotation. The client will determine the correct rotate file
210-
to begin the chain using the set of keys in the delegation for the role as the `ID`.
207+
If the delegation is changed to Alice's new key, it should use a new role name to
208+
over-rule any existing rotate files. Any
209+
old rotate files for the old role should be deleted and removed from snapshot on
210+
the next snapshot key rotation. The client will determine the correct rotate file for the new role
211+
by starting from VERSION 1.
211212

212213
## Client workflow
213214

214-
A client who wants to install foo now fetches Alice's targets file, and
215-
during verification looks for a file named `foo.rotate.ID.PREV` in the
216-
rotate folder, ID and PREV are explained above using Alice's old keyid.
217-
The client sees the file, fetches
218-
it and verifies this rotate file using the public key from the delegation.
219-
The client then looks for a rotate file with the new keyid, repeating until
220-
there is no matching rotate file to ensure up to date key information. This
221-
establishes trust in Alice's new key, and the client can now verify the
222-
signature of Alice's targets file using the new key. If key data is missing
223-
or there is a rotation to null the targets file is invalid and the client will
224-
proceed with the update process as if verification for this file failed.
215+
A client who wants to install foo now fetches Alice's targets file and will
216+
determine the set of trusted keys for this role as follows. The client will start
217+
with the keys listed in the delegation as trusted keys for this role.
218+
The client will then look for all files that begin with `rotate/foo.rotate` in
219+
the snapshot metadata. The client will process these in version order (ie starting
220+
with `rotate/foo.rotate.1`, then `rotate/foo.rotate.2` by first checking for this
221+
version file in a local cache. The client will then fetch the rotate file from
222+
remote. If the remote file is a rotation to null, and is signed with the currently
223+
trusted keys, the client will halt the verification of this metadata and act as if
224+
it is unverified when continuing the update process (and look for metadata from
225+
the next role in the pre-order depth-first search). Otherwise, the client should
226+
ensure that the cached file is identical to the remote version. The client will
227+
then verify the rotate file using the currently trusted public key(s) for this role.
228+
If a rotate
229+
file is successfully verified, the client will update the set of trusted keys for
230+
this role to be the set listed in the rotate files. If key data is missing
231+
or there is a rotation to null, the targets file is invalid and the client will
232+
proceed with the update process as if verification for this role failed (by moving
233+
on to another trusted role for this target, or reporting an error to the user).
234+
235+
This process establishes trust in Alice's new key, and the client can now verify the
236+
signature of Alice's targets file using the new key. In the case that there are
237+
multiple keys for a role, this rotate process can be used to rotate any number of
238+
individual keys, or to add or remove keys. A role `foo` can be delegated to with keys
239+
A, B, and C with a threshold of 2. A rotate file can then change the keys for both B
240+
and C by creating a rotation to A, D, and E. Another rotate file can then add an
241+
additional collaborator by rotating to A, D, E, and F.
242+
243+
The delegating role should ensure that all previous rotate files are removed when
244+
it delegates to a new chain of trust. This saves space and simplifies the client
245+
search for rotate files.
225246

226247
## Timestamp and snapshot rotation
227248

@@ -234,32 +255,41 @@ files can only be verified after snapshot metadata has been verified. In the TUF
234255
workflow, the timestamp and snapshot keys are used before the snapshot metadata
235256
is verified, and thus cannot be rotated using the mechanism in this TAP.
236257

258+
## Interoperability with TAP 4 (Multiple repository consensus)
259+
260+
If multiple repositories use the same role definition, rotate files may need to be
261+
coordinated to ensure consistency. There are two cases when roles are used across
262+
multiple repositories, the first is a mirror of a repository, and the second is
263+
two repositories that have different contents, but share a particular targets
264+
role. In the case of a mirror, all rotate files should be copied, and the
265+
repository can perform as usual, including any rotations. In the second case, the
266+
repository manager must ensure that they have the same set of trusted keys for a
267+
role after all rotations. This can be achieved by copying all rotate files for a
268+
role or by creating a delegation to the final set of trusted keys indicated by
269+
rotate files on another repository. If the latter method is used, note that future
270+
rotate files may not by copied as the version numbers will not start from one.
271+
237272
## Interoperability with TAP 3 (multi-role delegations)
238273

239274
Multi-role delegations are handled using the same methodology.
240275

241276
Let's consider the project baz, initially delegated to a multi-role
242277
threshold (of 2) to roles foo, and bar, each of which have a threshold of 2
243278
keys. When they want to add a keyid from Dan to the foo role, the current foo
244-
keyholders create a foo.rotate.ID.PREV file, where ID is as described above (the
245-
SHA256 of the concatenated key ids of foo, and the character 0x32). This contains
246-
all previous foo keys, as well as Dan's key and a new threshold. PREV is the
247-
SHA256 of "" as this is the first rotation for foo. The file
248-
foo.rotate.ID.PREV is signed by at least 2 current keyids of foo.
279+
keyholders create a foo.rotate.1 file. This contains
280+
all previous foo keys, as well as Dan's key and a new threshold. The file
281+
foo.rotate.1 is signed by at least 2 current keyids of foo.
249282
The new targets file foo is then signed by a new threshold (again 2) of
250283
the new keyids (including Dan) to complete the rotation.
251284

252285
Let's assume Bob and Dan signed foo. A client which encounters a
253-
delegation to foo first looks for a foo.rotate.ID.PREV file with the
254-
keyids and threshold specified in the delegation file and an initial
255-
value of "" for the previous rotate file. If this file exists and is
256-
properly signed by Alice and Bob, the client uses it to fetch new keys.
286+
delegation to foo first looks for a foo.rotate.1 file. If this file exists
287+
and is properly signed by Alice and Bob, the client uses it to fetch new keys.
257288
The client can then verify foo using Bob's and Dan's signature.
258289

259290
When Evelyn joins, and the threshold is increased to 3,
260-
foo.rotate.ID'.PREV' is created (ID' is the SHA256 of the concatenated old keyids,
261-
and 0x32, PREV' is the SHA256 of the previous rotate file), which contains the
262-
existing keyids as well as Evelyn's public key, and a threshold value of 3. This
291+
foo.rotate.2 is created, which contains the existing keyids as well as
292+
Evelyn's public key, and a threshold value of 3. This
263293
is signed with at least 2 keys from the current set of keyids.
264294

265295
## Rotation to Null
@@ -349,13 +379,6 @@ keyids are already listed in the delegation. Our proposal also takes advantage
349379
of the existing delegation model in TUF to allow for thresholds of signatures
350380
and revocation by a more trusted role.
351381

352-
Clashes of rotate file names are unlikely - the role is the first
353-
element, followed by "rotate", all key ids in alphabetical order,
354-
and the threshold value. Certainly this requires that key ids and
355-
roles do not contain any "." - which is used as separator. In addition
356-
the inclusion of the SHA256 of the previous rotate file makes collisions
357-
even more unlikely.
358-
359382
# Backwards compatibility
360383

361384
TAP 8 is not backwards compatible since clients have to download and

0 commit comments

Comments
 (0)