mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Merge pull request #440 from trishankkarthik/add-detailed-workflow
Expand on the TUF client update workflow, per popular demand.
This commit is contained in:
commit
85eb8995fe
1 changed files with 274 additions and 168 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue