Merge pull request #440 from trishankkarthik/add-detailed-workflow

Expand on the TUF client update workflow, per popular demand.
This commit is contained in:
Justin Cappos 2017-05-23 23:15:19 -04:00 committed by GitHub
commit 85eb8995fe

View file

@ -1,6 +1,6 @@
The Update Framework Specification
7 October 2016
23 May 2017
Version 1.0 (Draft)
1. Introduction
@ -9,6 +9,10 @@ Version 1.0 (Draft)
This document describes a framework for securing software update systems.
The keywords "MUST," "MUST NOT," "REQUIRED," "SHALL," "SHALL NOT," "SHOULD,"
"SHOULD NOT," "RECOMMENDED," "MAY," and "OPTIONAL" in this document are to be
interpreted as described in RFC 2119.
1.2. Motivation
Software is commonly updated through software update systems. These systems
@ -74,7 +78,7 @@ Version 1.0 (Draft)
The framework will not have the responsibility of deciding on the correct
course of action in all error situations, such as those that can occur when
certain attacks are being performed. Instead, the framework will provide
certain attacks are being performed. Instead, the framework will provide
the software update system the relevant information about any errors that
require security decisions which are situation-specific. How those errors
are handled is up to the software update system.
@ -134,31 +138,31 @@ Version 1.0 (Draft)
the client system. That is, an attacker can provide arbitrary files in
response to download requests and the files will not be detected as
illegitimate.
Endless data attacks. Attackers should not be able to respond to client
requests with huge amounts of data (extremely large files) that interfere
with the client's system.
Extraneous dependencies attacks. Attackers should not be able to cause
clients to download or install software dependencies that are not the
intended dependencies.
Fast-forward attacks. An attacker arbitrarily increases the version numbers
of project metadata files in the snapshot metadata well beyond the current
of project metadata files in the snapshot metadata well beyond the current
value, thus tricking a software update system into thinking any subsequent
updates are trying to rollback the package to a previous, out-of-date version.
In some situations, such as those where there is a maximum possible version
number, the perpetrator could use a number so high that the system would
never be able to match it with the one in the snapshot metadata, and thus
new updates could never be downloaded.
Indefinite freeze attacks. Attackers should not be able to respond to
client requests with the same, outdated metadata without the client being
aware of the problem.
Malicious mirrors preventing updates. Repository mirrors should be unable
to prevent updates from good mirrors.
Mix-and-match attacks. Attackers should not be able to trick clients into
using a combination of metadata that never existed together on the
repository at the same time.
@ -170,7 +174,7 @@ Version 1.0 (Draft)
Slow retrieval attacks. Attackers should not be able to prevent clients
from being aware of interference with receiving updates by responding to
client requests so slowly that automated updates never complete.
Vulnerability to key compromises. An attacker who is able to compromise a
single key or less than a given threshold of keys can compromise clients.
This includes relying on a single online key (such as only being protected
@ -207,7 +211,7 @@ Version 1.0 (Draft)
the file. As providing additional information about
target files may be important to some software update systems using the
framework, additional arbitrary information can be provided with any target
file. This information will be included in signed metadata that describes
file. This information will be included in signed metadata that describes
the target files.
The following are the high-level steps of using the framework from the
@ -277,7 +281,7 @@ Version 1.0 (Draft)
(that is, another set of keys and the threshold required for trust) is
trusted to sign target file metadata. Partial trust delegation is when the
delegated role is only trusted for some of the target files that the
delegating role is trusted for.
delegating role is trusted for.
Delegated developer roles can further delegate trust to other delegated
roles. This provides for multiple levels of trust delegation where each
@ -415,7 +419,7 @@ Version 1.0 (Draft)
provides one signed metadata file. As is the case with the directory
structure of top-level metadata, the delegated files are relative to the
base URL of metadata available from a given repository mirror.
A delegated role file is located at:
/DELEGATED_ROLE.json
@ -425,7 +429,7 @@ Version 1.0 (Draft)
named ANOTHER_ROLE, that role's signed metadata file is made available at:
/ANOTHER_ROLE.json
4. Document formats
All of the formats described below include the ability to add more
@ -443,7 +447,7 @@ Version 1.0 (Draft)
4.2. File formats: general principles
All signed metadata objects have the format:
{ "signed" : ROLE,
"signatures" : [
{ "keyid" : KEYID,
@ -460,18 +464,18 @@ Version 1.0 (Draft)
The current reference implementation of TUF defines two signing methods,
although TUF is not restricted to any particular key signing method,
key type, or cryptographic library:
"RSASSA-PSS" : RSA Probabilistic signature scheme with appendix.
The underlying hash function is SHA256.
"ed25519" : Elliptic curve digital signature algorithm based on Twisted
Edwards curves.
RSASSA-PSS: https://tools.ietf.org/html/rfc3447#page-29
RSASSA-PSS: https://tools.ietf.org/html/rfc3447#page-29
ed25519: https://ed25519.cr.yp.to/
All keys have the format:
{ "keytype" : KEYTYPE,
"keyval" : KEYVAL }
@ -480,9 +484,9 @@ Version 1.0 (Draft)
KEYVAL.
We define two keytypes at present: 'rsa' and 'ed25519'.
The 'rsa' format is:
{ "keytype" : "rsa",
"keyval" : { "public" : PUBLIC}
}
@ -491,16 +495,16 @@ Version 1.0 (Draft)
must be at least 2048 bits.
The 'ed25519' format is:
{ "keytype" : "ed25519",
"keyval" : { "public" : PUBLIC}
}
where PUBLIC is a 32-byte string.
The KEYID of a key is the hexdigest of the SHA-256 hash of the
canonical JSON form of the key.
Metadata date-time data follows the ISO 8601 standard. The expected format
of the combined date and time string is "YYYY-MM-DDTHH:MM:SSZ". Time is
always in UTC, and the "Z" time zone designator is attached to indicate a
@ -556,68 +560,68 @@ Version 1.0 (Draft)
{
"signatures": [
{
"keyid": "f2d5020d08aea06a0a9192eb6a4f549e17032ebefa1aa9ac167c1e3e727930d6",
"method": "ed25519",
"keyid": "f2d5020d08aea06a0a9192eb6a4f549e17032ebefa1aa9ac167c1e3e727930d6",
"method": "ed25519",
"sig": "a312b9c3cb4a1b693e8ebac5ee1ca9cc01f2661c14391917dcb111517f72370809
f32c890c6b801e30158ac4efe0d4d87317223077784c7a378834249d048306"
}
],
],
"signed": {
"_type": "Root",
"consistent_snapshot": false,
"expires": "2030-01-01T00:00:00Z",
"_type": "Root",
"consistent_snapshot": false,
"expires": "2030-01-01T00:00:00Z",
"keys": {
"1a2b4110927d4cba257262f614896179ff85ca1f1353a41b5224ac474ca71cb4": {
"keytype": "ed25519",
"keytype": "ed25519",
"keyval": {
"public": "72378e5bc588793e58f81c8533da64a2e8f1565c1fcc7f253496394ffc52542c"
}
},
},
"93ec2c3dec7cc08922179320ccd8c346234bf7f21705268b93e990d5273a2a3b": {
"keytype": "ed25519",
"keytype": "ed25519",
"keyval": {
"public": "68ead6e54a43f8f36f9717b10669d1ef0ebb38cee6b05317669341309f1069cb"
}
},
},
"f2d5020d08aea06a0a9192eb6a4f549e17032ebefa1aa9ac167c1e3e727930d6": {
"keytype": "ed25519",
"keytype": "ed25519",
"keyval": {
"public": "66dd78c5c2a78abc6fc6b267ff1a8017ba0e8bfc853dd97af351949bba021275"
}
},
},
"fce9cf1cc86b0945d6a042f334026f31ed8e4ee1510218f198e8d3f191d15309": {
"keytype": "ed25519",
"keytype": "ed25519",
"keyval": {
"public": "01c61f8dc7d77fcef973f4267927541e355e8ceda757e2c402818dad850f856e"
}
}
},
},
"roles": {
"root": {
"keyids": [
"f2d5020d08aea06a0a9192eb6a4f549e17032ebefa1aa9ac167c1e3e727930d6"
],
],
"threshold": 1
},
},
"snapshot": {
"keyids": [
"fce9cf1cc86b0945d6a042f334026f31ed8e4ee1510218f198e8d3f191d15309"
],
],
"threshold": 1
},
},
"targets": {
"keyids": [
"93ec2c3dec7cc08922179320ccd8c346234bf7f21705268b93e990d5273a2a3b"
],
],
"threshold": 1
},
},
"timestamp": {
"keyids": [
"1a2b4110927d4cba257262f614896179ff85ca1f1353a41b5224ac474ca71cb4"
],
],
"threshold": 1
}
},
},
"version": 1
}
}
@ -648,7 +652,7 @@ Version 1.0 (Draft)
METAPATH is the the metadata file's path on the repository relative to the
metadata base URL.
The HASHES and LENGTH are the hashes and length of the file, both of which
are only specified for the root file. VERSION is listed for the root file
and all other roles available on the repository. LENGTH is an integer.
@ -660,31 +664,31 @@ Version 1.0 (Draft)
{
"signatures": [
{
"keyid": "fce9cf1cc86b0945d6a042f334026f31ed8e4ee1510218f198e8d3f191d15309",
"method": "ed25519",
"keyid": "fce9cf1cc86b0945d6a042f334026f31ed8e4ee1510218f198e8d3f191d15309",
"method": "ed25519",
"sig": "f7f03b13e3f4a78a23561419fc0dd741a637e49ee671251be9f8f3fceedfc112e4
4ee3aaff2278fad9164ab039118d4dc53f22f94900dae9a147aa4d35dcfc0f"
}
],
],
"signed": {
"_type": "Snapshot",
"expires": "2030-01-01T00:00:00Z",
"_type": "Snapshot",
"expires": "2030-01-01T00:00:00Z",
"meta": {
"root.json": {
"hashes": {
"sha256": "52bbb30f683d166fae5c366e4582cfe8212aacbe1b21ae2026dae58ec55d3701"
},
},
"length": 1831,
"version": 1
},
},
"targets.json": {
"version": 1
},
},
"project.json": {
"version": 1
},
},
}
},
},
"version": 1
}
@ -734,7 +738,7 @@ Version 1.0 (Draft)
"paths" : [ PATHPATTERN, ... ])
}, ... ]
}
ROLENAME is the full name of the delegated role. For example,
"targets/projects"
@ -788,51 +792,51 @@ Version 1.0 (Draft)
{
"signatures": [
{
"keyid": "93ec2c3dec7cc08922179320ccd8c346234bf7f21705268b93e990d5273a2a3b",
"method": "ed25519",
"keyid": "93ec2c3dec7cc08922179320ccd8c346234bf7f21705268b93e990d5273a2a3b",
"method": "ed25519",
"sig": "e9fd40008fba263758a3ff1dc59f93e42a4910a282749af915fbbea1401178e5a0
12090c228f06db1deb75ad8ddd7e40635ac51d4b04301fce0fd720074e0209"
}
],
],
"signed": {
"_type": "Targets",
"_type": "Targets",
"delegations": {
"keys": {
"ce3e02e72980b09ca6f5efa68197130b381921e5d0675e2e0c8f3c47e0626bba": {
"keytype": "ed25519",
"keytype": "ed25519",
"keyval": {
"public": "b6e40fb71a6041212a3d84331336ecaa1f48a0c523f80ccc762a034c727606fa"
}
}
},
},
"roles": [
{
"keyids": [
"ce3e02e72980b09ca6f5efa68197130b381921e5d0675e2e0c8f3c47e0626bba"
],
"name": "targets/project",
],
"name": "targets/project",
"paths": [
"/project/file3.txt"
],
],
"threshold": 1
}
]
},
"expires": "2030-01-01T00:00:00Z",
},
"expires": "2030-01-01T00:00:00Z",
"targets": {
"/file1.txt": {
"hashes": {
"sha256": "65b8c67f51c993d898250f40aa57a317d854900b3a04895464313e48785440da"
},
},
"length": 31
},
},
"/file2.txt": {
"hashes": {
"sha256": "452ce8308500d83ef44248d8e6062359211992fd837ea9e370e561efb1a4ca99"
},
},
"length": 39
}
},
},
"version": 1
}
}
@ -864,24 +868,24 @@ Version 1.0 (Draft)
{
"signatures": [
{
"keyid": "1a2b4110927d4cba257262f614896179ff85ca1f1353a41b5224ac474ca71cb4",
"method": "ed25519",
"keyid": "1a2b4110927d4cba257262f614896179ff85ca1f1353a41b5224ac474ca71cb4",
"method": "ed25519",
"sig": "90d2a06c7a6c2a6a93a9f5771eb2e5ce0c93dd580bebc2080d10894623cfd6eaed
f4df84891d5aa37ace3ae3736a698e082e12c300dfe5aee92ea33a8f461f02"
}
],
],
"signed": {
"_type": "Timestamp",
"expires": "2030-01-01T00:00:00Z",
"_type": "Timestamp",
"expires": "2030-01-01T00:00:00Z",
"meta": {
"snapshot.json": {
"hashes": {
"sha256": "c14aeb4ac9f4a8fc0d83d12482b9197452f6adf3eb710e3b1e2b79e8d14cb681"
},
},
"length": 1007,
"version": 1
}
},
},
"version": 1
}
}
@ -928,61 +932,187 @@ Version 1.0 (Draft)
5.1. The client application
1. The client application first instructs TUF to check for updates.
0. **Load the previous root metadata file.** We assume that a good, trusted
copy of this file was shipped with the package manager / software updater
using an out-of-band process.
2. TUF downloads and verifies timestamp.json.
0.1. **Check signatures.** The previous root metadata file MUST have been
signed by a threshold of keys specified in the previous root metadata file.
3. If timestamp.json indicates that snapshot.json has changed, TUF downloads
and verifies snapshot.json.
0.2. Note that the expiration of the previous root metadata file does not
matter, because we will attempt to update it in the next step.
4. TUF determines which metadata files listed in snapshot.json differ from
those described in the last snapshot.json that TUF has seen. If root.json
has changed, the update process starts over using the new root.json.
1. **Update the root metadata file.** Since it may now be signed using
entirely different keys, the client must somehow be able to establish a
trusted line of continuity to the latest set of keys (see Section 6.1). To
do so, the client MUST download intermediate root metadata files, until the
latest available one is reached.
5. TUF provides the software update system with a list of available files
according to targets.json.
1.1. Let N denote the version number of the previous root metadata file.
6. The software update system instructs TUF to download a specific target file.
1.2. **Try downloading version N+1 of the root metadata file**, up to some
X number of bytes (because the size is unknown). The value for X is set by
the authors of the application using TUF. For example, X may be tens of
kilobytes. The filename used to download the root metadata file is of the
fixed form VERSION.FILENAME.EXT (e.g., 42.root.json). If this file is not
available, then go to step 1.8.
7. TUF downloads and verifies the file and then makes the file available to the
software update system.
1.3. **Check signatures.** Version N+1 of the root metadata file MUST have
been signed by: (1) a threshold of keys specified in the previous root
metadata file (version N), and (2) a threshold of keys specified in the
current root metadata file (version N+1).
Note: If at any point in the above procedure there is a problem (i.e., if
unexpired, signed, valid metadata cannot be retrieved from the repository),
the Root file is downloaded and the process is retried once more (and only
once to avoid an infinite loop). Optionally, the software update system
using the framework can decide how to proceed rather than automatically
downloading a new Root file.
1.4. **Check for a rollback attack.** The version number of the previous
root metadata file must be less than or equal to the version number of this
root metadata file. Effectively, this means checking that the version
number signed in the current root metadata file is indeed N+1.
1.5. **Check for a freeze attack.** The latest known time should be lower
than the expiration timestamp in the current root metadata file.
The client code instructs the framework to check for updates. The framework
downloads the timestamp.json file from a mirror and checks that the file is
properly signed by the timestamp role, is not expired, and is not older than
the last timestamp.json file retrieved. If the timestamp file lists the same
snapshot.json file as was previously seen, the client code is informed that no
updates are available and the update checking process stops.
1.6. Set the previous to the current root metadata file.
If the snapshot.json file has changed, the framework downloads the file and
verifies that it is properly signed by the snapshot role, is not expired, has
a newer timestamp than the last snapshot.json file seen, and matches the
description (hashes and size) in the timestamp.json file. The framework then
checks which metadata files listed in snapshot.json differ from those
described in the last snapshot.json file the framework had seen. If the
root.json file has changed, the framework updates this (following the same
security measures as with the other files) and starts the process over. If
any other metadata files have changed, the framework downloads and checks
those.
1.7. Repeat steps 1.1 to 1.6.
By comparing the trusted targets from the old trusted metadata with the new
metadata, the framework is able to determine which target files have
changed. The framework ensures that any targets described in delegated
targets files are allowed to be provided by the delegated role.
1.8. **If the the timestamp and / or snapshot keys have been rotated, then
delete the previous timestamp and snapshot metadata files.** This is done
in order to recover from fast-forward attacks after the repository has been
compromised and recovered. A _fast-forward attack_ happens when attackers
arbitrarily increase the version numbers of: (1) the timestamp metadata,
(2) the snapshot metadata, and / or (3) the targets, or a delegated
targets, metadata file in the snapshot metadata. Please see [the submitted
Mercury
draft](https://ssl.engineering.nyu.edu/papers/kuppusamy_usenix_17.pdf) for
more details.
When the client code asks the framework to download a target file, the
framework downloads the file from (potentially trying multiple mirrors),
checks the downloaded file to ensure that it matches the information
described in the targets files, and then makes the file available to the
client code.
2. **Download the timestamp metadata file**, up to Y number of bytes
(because the size is unknown.) The value for Y is set by the authors of the
application using TUF. For example, Y may be tens of kilobytes. The
filename used to download the timestamp metadata file is of the fixed form
FILENAME.EXT (e.g., timestamp.json).
2.1. **Check signatures.** The timestamp metadata file must have been
signed by a threshold of keys specified in the root metadata file.
2.2. **Check for a rollback attack.** The version number of the previous
timestamp metadata file, if any, must be less than or equal to the version
number of this timestamp metadata file.
2.3. **Check for a freeze attack.** The latest known time should be lower
than the expiration timestamp in this metadata file.
3. **Download and check the snapshot metadata file**, up to the number of
bytes specified in the timestamp metadata file.
If consistent snapshots are not used (see Section 7), then the filename
used to download the snapshot metadata file is of the fixed form
FILENAME.EXT (e.g., snapshot.json).
Otherwise, the filename is of the form VERSION.FILENAME.EXT (e.g.,
42.snapshot.json), where HASH is one of the hashes of the snapshot metadata
file listed in the timestamp metadata file.
In either case, the client MUST write the file to non-volatile storage as
FILENAME.EXT.
3.1. **Check against timestamp metadata.** The hashes, and version number
of this metadata file MUST match the timestamp metadata.
3.2. **Check signatures.** The snapshot metadata file MUST have been signed
by a threshold of keys specified in the previous root metadata file.
3.3. **Check for a rollback attack.**
3.3.1. Note that the previous snapshot metadata file may be checked for
authenticity, but its expiration does not matter for the following
purposes.
3.3.2. The version number of the previous snapshot metadata file, if any,
MUST be less than or equal to the version number of this snapshot metadata
file.
3.3.3. The version number of the targets metadata file, and all delegated
targets metadata files (if any), in the previous snapshot metadata file, if
any, MUST be less than or equal to its version number in this snapshot
metadata file. Furthermore, any targets metadata filename that was listed
in the previous snapshot metadata file, if any, MUST continue to be listed
in this snapshot metadata file.
3.4. **Check for a freeze attack.** The latest downloaded time should be
lower than the expiration timestamp in this metadata file.
4. **Download and check the top-level targets metadata file**, up to either
the number of bytes specified in the snapshot metadata file, or some
Z number of bytes. The value for Z is set by the authors of the application
using TUF. For example, Z may be tens of kilobytes.
If consistent snapshots are not used (see Section 7), then the filename
used to download the targets metadata file is of the fixed form
FILENAME.EXT (e.g., targets.json).
Otherwise, the filename is of the form VERSION.FILENAME.EXT (e.g.,
42.targets.json), where VERSION is the version number of the targets
metadata file listed in the snapshot metadata file.
In either case, the client MUST write the file to non-volatile storage as
FILENAME.EXT.
4.1. **Check against snapshot metadata.** The hashes (if any), and version
number of this metadata file MUST match the snapshot metadata. This is
done, in part, to prevent a mix-and-match attack by man-in-the-middle
attackers.
4.2. **Check for an arbitrary software attack.** This metadata file MUST
have been signed by a threshold of keys specified in the latest root
metadata file.
4.3. **Check for a rollback attack.** The version number of the previous
targets metadata file, if any, MUST be less than or equal to the version
number of this targets metadata file.
4.4. **Check for a freeze attack.** The latest downloaded time should be
lower than the expiration timestamp in this metadata file.
4.5. **Perform a preorder depth-first search for metadata about the desired
target, beginning with the top-level targets role.**
4.5.1. If this role has been visited before, then skip this role (so that
cycles in the delegation graph are avoided).
Otherwise, if an application-specific maximum number of roles have been
visited, then go to step 5 (so that attackers cannot cause the client to
waste excessive bandwidth or time).
Otherwise, if this role contains metadata about the desired target, then go
to step 5.
4.5.2. Otherwise, recursively search the list of delegations in order of
appearance.
4.5.2.1. If the current delegation is a multi-role delegation, recursively
visit each role, and check that each has signed exactly the same non-custom
metadata (i.e., length and hashes) about the target (or the lack of any
such metadata).
4.5.2.2. If the current delegation is a terminating delegation, then jump
to step 5.
4.5.2.3. Otherwise, if the current delegation is a non-terminating
delegation, continue processing the next delegation, if any. Stop the
search, and jump to step 5 as soon as a delegation returns a result.
5. **Verify the desired target against its targets metadata.**
5.1. If there is no targets metadata about this target, then report that
there is no such target.
5.2. Otherwise, download the target (up to the number of bytes specified in
the targets metadata), and verify that its hashes match the targets
metadata. (We download up to this number of bytes, because in some cases,
the exact number is unknown. This may happen, for example, if an external
program is used to compute the root hash of a tree of targets files, and
this program does not provide the total size of all of these files.)
If consistent snapshots are not used (see Section 7), then the filename
used to download the target file is of the fixed form FILENAME.EXT (e.g.,
foobar.tar.gz).
Otherwise, the filename is of the form HASH.FILENAME.EXT (e.g.,
c14aeb4ac9f4a8fc0d83d12482b9197452f6adf3eb710e3b1e2b79e8d14cb681.foobar.tar.gz),
where HASH is one of the hashes of the targets file listed in the targets
metadata file found earlier in step 4.
In either case, the client MUST write the file to non-volatile storage as
FILENAME.EXT.
6. Usage
@ -995,7 +1125,7 @@ Version 1.0 (Draft)
stored securely offline (e.g. encrypted and on a separate machine, in
special-purpose hardware, etc.). This document does not prescribe how keys
should be encrypted and stored, and so it is left to implementers of
this document to decide how best to secure them.
this document to decide how best to secure them.
To replace a compromised root key or any other top-level role key, the root
role signs a new root.json file that lists the updated trusted keys for the
@ -1016,8 +1146,9 @@ Version 1.0 (Draft)
clients will (correctly) not validate the new root.json file. For example,
if there is a 1.root.json that has threshold 2 and a 2.root.json that has
threshold 3, 2.root.json MUST be signed by at least 2 keys defined in
1.root.json and at least 3 keys defined in 2.root.json.
1.root.json and at least 3 keys defined in 2.root.json. See step 1 in
Section 5.1 for more details.
To replace a delegated developer key, the role that delegated to that key
just replaces that key with another in the signed metadata where the
delegation is done.
@ -1046,21 +1177,22 @@ Version 1.0 (Draft)
Simply put, TUF should write every metadata file as such: if the
file had the original name of filename.ext, then it should be written to
disk as version_number.filename.ext, where version_number is an integer.
On the other hand, consistent target files should be written to disk as
digest.filename.ext. This means that if the referrer metadata lists N
cryptographic hashes of the referred file, then there must be N identical
copies of the referred file, where each file will be distinguished only by
the value of the digest in its filename. The modified filename need not
include the name of the cryptographic hash function used to produce the
digest because, on a read, the choice of function follows from the
selection of a digest (which includes the name of the cryptographic
function) from all digests in the referred file.
non-volatile storage as version_number.filename.ext, where version_number
is an integer.
On the other hand, consistent target files should be written to
non-volatile storage as digest.filename.ext. This means that if the
referrer metadata lists N cryptographic hashes of the referred file, then
there must be N identical copies of the referred file, where each file will
be distinguished only by the value of the digest in its filename. The
modified filename need not include the name of the cryptographic hash
function used to produce the digest because, on a read, the choice of
function follows from the selection of a digest (which includes the name of
the cryptographic function) from all digests in the referred file.
Additionally, the timestamp metadata (timestamp.json) should also be
written to disk whenever it is updated. It is optional for an
implementation to write identical copies at digest.timestamp.json for
written to non-volatile storage whenever it is updated. It is optional for
an implementation to write identical copies at digest.timestamp.json for
record-keeping purposes, because a cryptographic hash of the timestamp
metadata is usually not known in advance. The same step applies to the root
metadata (root.json), although an implementation must write both root.json
@ -1088,32 +1220,7 @@ Version 1.0 (Draft)
7.2. Reading consistent snapshots
We now explain how a client should read a self-contained consistent
snapshot.
If the root metadata (root.json) is either missing the Boolean
"consistent_snapshot" attribute or the attribute is set to False, then the
client should do nothing different from the workflow in Section 5.1.
Otherwise, the client must perform as follows:
1. It must first retrieve the timestamp metadata (timestamp.json) from the
repository.
2. If a threshold number of signatures of the timestamp or snapshot
metadata are not valid, then the client must download the root metadata
(root.json) from the repository and return to step 1.
3. Otherwise, the client must download every subsequent metadata or
target file as follows: if the metadata or target file has the name
filename.ext, then the client must actually retrieve the file with the
name digest.filename.ext, where digest is the hex digest of a
cryptographic hash of the referred file as listed by its referrer file.
Even though the modified filename does not include the name of the
cryptographic hash function used to produce the chosen digest value, the
choice of function follows from the selection of the digest (which
includes the name of the cryptographic function) from all digests in the
referred file.
4. Finally, the client must be careful to rename every metadata or target
file retrieved with the name digest.filename.ext to the name
filename.ext.
See Section 5.1 for more details.
F. Future directions and open questions
@ -1122,4 +1229,3 @@ F.1. Support for bogus clocks.
The framework may need to offer an application-enablable "no, my clock is
_supposed_ to be wrong" mode, since others have noticed that many users seem
to have incorrect clocks.