From c105077d0518d54ea1234523d442f703f3e2c4bb Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Feb 2017 14:48:37 -0500 Subject: [PATCH 01/34] Add compression_algorithms and consistent_snapshot attributes to root.json --- docs/tuf-spec.txt | 181 ++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 85 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index bba03f3e..6d74edb4 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -74,7 +74,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 +134,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 +170,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 +207,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 +277,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 +415,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 +425,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 +443,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 +460,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 +480,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 +491,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 @@ -518,6 +518,8 @@ Version 1.0 (Draft) The "signed" portion of root.json is as follows: { "_type" : "Root", + "compression_algorithms": [ COMPRESSION_ALGORITHM, ... ], + "consistent_snapshot": CONSISTENT_SNAPSHOT, "version" : VERSION, "expires" : EXPIRES, "keys" : { @@ -530,6 +532,14 @@ Version 1.0 (Draft) , ... } } + COMPRESSION_ALGORITHM specifies one of the compression algorithms supported + by the repository. Metadata files available on the repository may + optionally be compressed with this algorithm. Compressed versions of + metadata are not listed in snapshot.json. + + CONSISTENT_SNAPSHOT is a boolean indicating whether the repository supports + consistent snapshots (section 7). + VERSION is an integer that is greater than 0. Clients MUST NOT replace a metadata file with a version number less than the one currently trusted. @@ -556,68 +566,69 @@ 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", + "compression_algorithms": ["gz"], + "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 +659,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 +671,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 +745,7 @@ Version 1.0 (Draft) "paths" : [ PATHPATTERN, ... ]) }, ... ] } - + ROLENAME is the full name of the delegated role. For example, "targets/projects" @@ -788,51 +799,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 +875,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 } } @@ -995,7 +1006,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 @@ -1004,8 +1015,8 @@ Version 1.0 (Draft) required, the root.json file is versioned and accessible by version number, e.g. 3.root.json. Clients update the set of trusted root keys by requesting the current root.json and all previous root.json versions, until one is - found that has been signed by keys the client already trusts. This is to - ensure that outdated clients remain able to update, without requiring all + found that has been signed by keys the client already trusts. This is to + ensure that outdated clients remain able to update, without requiring all previous root keys to be kept to sign new root.json metadata. @@ -1038,7 +1049,7 @@ 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 From 1a00c4cd8f565350a610a3024b494418158c02a2 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Feb 2017 15:11:37 -0500 Subject: [PATCH 02/34] Update text describing format of PATHPATTERN --- docs/tuf-spec.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 6d74edb4..6e515740 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -765,14 +765,13 @@ Version 1.0 (Draft) The "paths" list describes paths that the role is trusted to provide. Clients MUST check that a target is in one of the trusted paths of all roles in a delegation chain, not just in a trusted path of the role that describes - the target file. The format of a PATHPATTERN may be either a path to a - single file, or a path to a directory to indicate all files and/or - subdirectories under that directory. - - A path to a directory is used to indicate all possible targets sharing that - directory as a prefix; e.g. if the directory is "targets/A", then targets - which match that directory include "targets/A/B.json" and - "targets/A/B/C.json". + the target file. PATHPATTERN can include shell-style wildcards and supports + the Unix filename pattern matching convention. Its format may either + indicate a path to a single file, or to multiple paths with the use of + shell-style wildcards. For example, the path pattern "targets/*.tgz" would + match file paths "targets/foo.tgz" and "targets/bar.tgz", but not + "targets/foo.txt". Likewise, path pattern "foo-version-?.tgz" matches + foo-version-2.tgz", but not "foo-version-alpha.tgz". We are currently investigating a few "priority tag" schemes to resolve conflicts between delegated roles that share responsibility for overlapping From bbd3288245dd2ac25335c2153149ef4339a73cd4 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Feb 2017 15:29:51 -0500 Subject: [PATCH 03/34] Update text for handling overlapping targets between delegations. Remove note about priority tag schemes and our investigation of several of these schemes --- docs/tuf-spec.txt | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 6e515740..d7c0e352 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -773,21 +773,20 @@ Version 1.0 (Draft) "targets/foo.txt". Likewise, path pattern "foo-version-?.tgz" matches foo-version-2.tgz", but not "foo-version-alpha.tgz". - We are currently investigating a few "priority tag" schemes to resolve - conflicts between delegated roles that share responsibility for overlapping - target paths. One of the simplest of such schemes is for the client to - consider metadata in order of appearance of delegations; we treat the order - of delegations such that the first delegation is trusted more than the - second one, the second delegation is trusted more than the third one, and so - on. The metadata of the first delegation will override that of the second - delegation, the metadata of the second delegation will override that of the - third delegation, and so on. In order to accommodate this scheme, the - "roles" key in the DELEGATIONS object above points to an array, instead of a - hash table, of delegated roles. + Several schemes exist to resolve conflicts between delegated roles that + share responsibility for overlapping target paths. One of the simplest of + such schemes is for the client to consider metadata in order of appearance + of delegations; we treat the order of delegations such that the first + delegation is trusted more than the second one, the second delegation is + trusted more than the third one, and so on. The metadata of the first + delegation will override that of the second delegation, the metadata of the + second delegation will override that of the third delegation, and so on. In + order to accommodate this scheme, the "roles" key in the DELEGATIONS object + above points to an array, instead of a hash table, of delegated roles. - Another priority tag scheme would have the clients prefer the delegated role - with the latest metadata for a conflicting target path. Similar ideas were - explored in the Stork package manager (University of Arizona Tech Report + Another scheme would have the clients prefer the delegated role with the + latest metadata for a conflicting target path. Similar ideas were explored + in the Stork package manager (University of Arizona Tech Report 08-04)[https://isis.poly.edu/~jcappos/papers/cappos_stork_dissertation_08.pdf]. The metadata files for delegated target roles has the same format as the From 6cca34b6f1545c0d59cf7c030bb58b4e052f8751 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Feb 2017 16:19:25 -0500 Subject: [PATCH 04/34] Add 'terminating' attribute and text explaining its use --- docs/tuf-spec.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index d7c0e352..ce8a41ef 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -742,12 +742,27 @@ Version 1.0 (Draft) "keyids" : [ KEYID, ... ] , "threshold" : THRESHOLD, ("path_hash_prefixes" : [ HEX_DIGEST, ... ] | - "paths" : [ PATHPATTERN, ... ]) + "paths" : [ PATHPATTERN, ... ]), + "terminating": TERMINATING, }, ... ] } ROLENAME is the full name of the delegated role. For example, - "targets/projects" + "targets/projects". + + TERMINATING is a boolean indicating whether subsequent delegations should be + considered. + + As explained in the Diplomat paper + (https://github.com/theupdateframework/tuf/blob/develop/docs/papers/protect-community-repositories-nsdi2016.pdf), + terminating delegations instruct the client not to consider future trust + statements that match the delegation's pattern. This stops the delegation + processing once this delegation (and its descendants) have been processed. + (Handling this case is conceptually similar to the use of the cut operator + in Prolog to stop computation, except that TUF uses this technique for + security instead of efficiency.) A terminating delegation for a package + causes any further statements about a package that are not made by the + delegated party or its descendants to be ignored. In order to discuss target paths, a role MUST specify only one of the "path_hash_prefixes" or "paths" attributes, each of which we discuss next. From 6665d25b9e3cc0ecb6ccb0586213c2cece69d725 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Feb 2017 16:22:10 -0500 Subject: [PATCH 05/34] Remove notion of a full rolename We previously used a full rolename when delegations resembled a tree --- docs/tuf-spec.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index ce8a41ef..33cca3e5 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -747,8 +747,8 @@ Version 1.0 (Draft) }, ... ] } - ROLENAME is the full name of the delegated role. For example, - "targets/projects". + ROLENAME is the name of the delegated role. For example, + "projects". TERMINATING is a boolean indicating whether subsequent delegations should be considered. @@ -834,7 +834,7 @@ Version 1.0 (Draft) "keyids": [ "ce3e02e72980b09ca6f5efa68197130b381921e5d0675e2e0c8f3c47e0626bba" ], - "name": "targets/project", + "name": "project", "paths": [ "/project/file3.txt" ], From adf48f90ce5192c0527b0f4724a84730c4ac555a Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 24 Apr 2017 12:25:12 -0400 Subject: [PATCH 06/34] Remove parenthetical note in text for terminating delegations. --- docs/tuf-spec.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 33cca3e5..cc7c10ab 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -756,13 +756,11 @@ Version 1.0 (Draft) As explained in the Diplomat paper (https://github.com/theupdateframework/tuf/blob/develop/docs/papers/protect-community-repositories-nsdi2016.pdf), terminating delegations instruct the client not to consider future trust - statements that match the delegation's pattern. This stops the delegation + statements that match the delegation's pattern, which stops the delegation processing once this delegation (and its descendants) have been processed. - (Handling this case is conceptually similar to the use of the cut operator - in Prolog to stop computation, except that TUF uses this technique for - security instead of efficiency.) A terminating delegation for a package - causes any further statements about a package that are not made by the - delegated party or its descendants to be ignored. + A terminating delegation for a package causes any further statements about + a package that are not made by the delegated party or its descendants to + be ignored. In order to discuss target paths, a role MUST specify only one of the "path_hash_prefixes" or "paths" attributes, each of which we discuss next. From 116cb39039c6df5dedb1c752a0152c4df512cc69 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 24 Apr 2017 12:55:51 -0400 Subject: [PATCH 07/34] Add matching example of shell-style wildcard One more matching example here would help. Right now, it looks as if "?" matches only "numbers". --- docs/tuf-spec.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index cc7c10ab..fbc0e0b1 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -784,7 +784,7 @@ Version 1.0 (Draft) shell-style wildcards. For example, the path pattern "targets/*.tgz" would match file paths "targets/foo.tgz" and "targets/bar.tgz", but not "targets/foo.txt". Likewise, path pattern "foo-version-?.tgz" matches - foo-version-2.tgz", but not "foo-version-alpha.tgz". + foo-version-2.tgz" and "foo-version-a.tgz", but not "foo-version-alpha.tgz". Several schemes exist to resolve conflicts between delegated roles that share responsibility for overlapping target paths. One of the simplest of From 3532fb800533f64484092fffa97a376ecc130c73 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 24 Apr 2017 14:59:18 -0400 Subject: [PATCH 08/34] Remove alternative schemes for overlapping targets --- docs/tuf-spec.txt | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index fbc0e0b1..ad9763fc 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -786,21 +786,16 @@ Version 1.0 (Draft) "targets/foo.txt". Likewise, path pattern "foo-version-?.tgz" matches foo-version-2.tgz" and "foo-version-a.tgz", but not "foo-version-alpha.tgz". - Several schemes exist to resolve conflicts between delegated roles that - share responsibility for overlapping target paths. One of the simplest of - such schemes is for the client to consider metadata in order of appearance - of delegations; we treat the order of delegations such that the first - delegation is trusted more than the second one, the second delegation is - trusted more than the third one, and so on. The metadata of the first - delegation will override that of the second delegation, the metadata of the - second delegation will override that of the third delegation, and so on. In - order to accommodate this scheme, the "roles" key in the DELEGATIONS object - above points to an array, instead of a hash table, of delegated roles. - - Another scheme would have the clients prefer the delegated role with the - latest metadata for a conflicting target path. Similar ideas were explored - in the Stork package manager (University of Arizona Tech Report - 08-04)[https://isis.poly.edu/~jcappos/papers/cappos_stork_dissertation_08.pdf]. + Prioritized delegations allow clients to resolve conflicts between delegated + roles that share responsibility for overlapping target paths. To resolve + conflicts, clients must consider metadata in order of appearance of delegations; + we treat the order of delegations such that the first delegation is trusted + over the second one, the second delegation is trusted more than the third + one, and so on. Likewise, the metadata of the first delegation will override that + of the second delegation, the metadata of the second delegation will override + that of the third one, etc. In order to accommodate prioritized + delegations, the "roles" key in the DELEGATIONS object above points to an array + of delegated roles, rather than to a hash table. The metadata files for delegated target roles has the same format as the top-level targets.json metadata file. From 7eae7e38b02931f1e390b6a3de3748cdeff38f16 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 24 Apr 2017 16:10:16 -0400 Subject: [PATCH 09/34] Explain that section 7 covers consistent snapshots --- docs/tuf-spec.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index ad9763fc..7c4c07ca 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -538,7 +538,8 @@ Version 1.0 (Draft) metadata are not listed in snapshot.json. CONSISTENT_SNAPSHOT is a boolean indicating whether the repository supports - consistent snapshots (section 7). + consistent snapshots. Section 7 goes into more detail on the consequences + of enabling this setting on a repository. VERSION is an integer that is greater than 0. Clients MUST NOT replace a metadata file with a version number less than the one currently trusted. From f092d2a87b8220a6f9219743c6e076173c0ae038 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Wed, 26 Apr 2017 14:02:01 -0400 Subject: [PATCH 10/34] Expand on the TUF client update workflow, per popular demand. --- docs/tuf-spec.txt | 113 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 12 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index bba03f3e..a3b0e3a7 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -928,24 +928,113 @@ Version 1.0 (Draft) 5.1. The client application - 1. The client application first instructs TUF to check for updates. + 1. **Download the root metadata file**, up to some predetermined number of + bytes (because the size is unknown). - 2. TUF downloads and verifies timestamp.json. + 1.1. **Check signatures.** It 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. + 1.2. **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. - 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.3. **Check for a freeze attack.** The latest known time should be lower + than the expiration timestamp in this metadata file. - 5. TUF provides the software update system with a list of available files - according to targets.json. + 1.4. **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 Mercury + paper for more details (to be published soon). - 6. The software update system instructs TUF to download a specific target file. + 2. **Download the timestamp metadata file**, up to some predetermined + number of bytes (because the size is unknown.) - 7. TUF downloads and verifies the file and then makes the file available to the - software update system. + 2.1. **Check signatures.** It 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. + + 3.1. **Check against timestamp metadata.** The hashes, and version number + of this metadata file must match the timestamp metadata. + + 3.2. **Check signatures.** It 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. 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.2. 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 + predetermined number. + + 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.** + + 4.5.1. If this file 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 it 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 it). + + 4.5.2.2. If it is a terminating delegation, then jump to step 5. + + 4.5.2.3. Otherwise, if it 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. 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), From 6236878eb1f280e2d5bce79678c7b92cf7ac2b9e Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Wed, 26 Apr 2017 15:07:56 -0400 Subject: [PATCH 11/34] Address comments by @JustinCappos. --- docs/tuf-spec.txt | 69 ++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index a3b0e3a7..fb32b691 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -928,11 +928,12 @@ Version 1.0 (Draft) 5.1. The client application - 1. **Download the root metadata file**, up to some predetermined number of - bytes (because the size is unknown). + 1. **Download 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. - 1.1. **Check signatures.** It must have been signed by a threshold of keys - specified in the previous root metadata file. + 1.1. **Check signatures.** The root metadata file must have been signed by + a threshold of keys specified in the previous root metadata file. 1.2. **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 @@ -947,14 +948,17 @@ Version 1.0 (Draft) 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 Mercury - paper for more details (to be published soon). + 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. - 2. **Download the timestamp metadata file**, up to some predetermined - number of bytes (because the size is unknown.) + 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. - 2.1. **Check signatures.** It must have been signed by a threshold of keys - specified in the root metadata file. + 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 @@ -969,8 +973,8 @@ Version 1.0 (Draft) 3.1. **Check against timestamp metadata.** The hashes, and version number of this metadata file must match the timestamp metadata. - 3.2. **Check signatures.** It must have been signed by a threshold of keys - specified in the previous root metadata file. + 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.** @@ -990,7 +994,8 @@ Version 1.0 (Draft) 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 - predetermined number. + 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. 4.1. **Check against snapshot metadata.** The hashes (if any), and version number of this metadata file must match the snapshot metadata. This is @@ -1017,23 +1022,25 @@ Version 1.0 (Draft) 4.5.2. Otherwise, recursively search the list of delegations in order of appearance. - 4.5.2.1. If it 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 it). + 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 it is a terminating delegation, then jump to step 5. + 4.5.2.2. If the current delegation is a terminating delegation, then jump + to step 5. - 4.5.2.3. Otherwise, if it 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. + 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 + 5.2. Otherwise, download the target (exactly the number of bytes specified + in the targets metadata), and verify that its hashes match the targets metadata. Note: If at any point in the above procedure there is a problem (i.e., if @@ -1052,14 +1059,14 @@ Version 1.0 (Draft) updates are available and the update checking process stops. 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 + verifies that the file 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. By comparing the trusted targets from the old trusted metadata with the new @@ -1069,7 +1076,7 @@ Version 1.0 (Draft) 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 + checks the downloaded file to ensure that the file matches the information described in the targets files, and then makes the file available to the client code. From 5e215ee223e6117c97b3407ee309daed66ddaac8 Mon Sep 17 00:00:00 2001 From: Artyom Baloyan Date: Wed, 3 May 2017 22:48:31 -0400 Subject: [PATCH 12/34] - Modified LICENCE.txt file. Added The MIT License as a main license of the TuF project. --- LICENSE.txt | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 544f53dc..f100e063 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,33 +1,25 @@ - This file contains the license for TUF: The Update Framework. +The MIT License (MIT) - It also lists license information for components and source - code used by TUF: The Update Framework. +Copyright (c) 2010 New York University - If you got this file as a part of a larger bundle, - there may be other license terms that you should be aware of. - -=============================================================================== -TUF: The Update Framework is distributed under this license: - -Copyright (c) 2010, Justin Samuel and Justin Cappos. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and/or hardware specification (the “Work”) to deal in the Work -without restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies of the Work, -and to permit persons to whom the Work is furnished to do so, subject to the -following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Work. +copies or substantial portions of the Software. -THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER -DEALINGS IN THE WORK. +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + =============================================================================== Many files are modified from Thandy and are licensed under the following license: From c06da3f1d9ff13bf3ff44fcda69582b86aa43944 Mon Sep 17 00:00:00 2001 From: Wilson Ding Date: Tue, 16 May 2017 13:24:07 -0500 Subject: [PATCH 13/34] Fixed markdown errors in Client README.md --- tuf/client/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tuf/client/README.md b/tuf/client/README.md index d0087294..2e69a823 100644 --- a/tuf/client/README.md +++ b/tuf/client/README.md @@ -1,4 +1,4 @@ -#updater.py +# updater.py **updater.py** is intended as the only TUF module that software update systems need to utilize for a low-level integration. It provides a single class representing an updater that includes methods to download, install, and @@ -152,7 +152,7 @@ for target in updated_target: target_custom_data = target['fileinfo']['custom'] ``` -###A Simple Integration Example with basic_client.py +### A Simple Integration Example with basic_client.py ``` Bash # Assume a simple TUF repository has been setup with 'tuf.repository_tool.py'. $ basic_client.py --repo http://localhost:8001 From 739224a2a677e81dd5423620207bb212280e3f92 Mon Sep 17 00:00:00 2001 From: Wilson Ding Date: Tue, 16 May 2017 13:27:54 -0500 Subject: [PATCH 14/34] Fixed markdown issues in Security.md --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 1aa59d24..6de729a0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,4 +1,4 @@ -#Security +# Security Generally, a software update system is secure if it can be sure that it knows about the latest available updates in a timely manner, any files it downloads are the correct files, and no harm results from checking or downloading files. The details of making this happen are complicated by various attacks that can be carried out against software update systems. From ec83e5603fd01a6ae8174753163676f9fe47f4c3 Mon Sep 17 00:00:00 2001 From: Wilson Ding Date: Tue, 16 May 2017 13:35:09 -0500 Subject: [PATCH 15/34] More fixes to markdown in Security.md --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 6de729a0..52fba62f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -32,7 +32,7 @@ snapshot metadata, and thus new updates could never be downloaded. * **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 by SSL) or a single offline key (such as most software update systems use to sign files). -##Design Concepts +## Design Concepts The design and implementation of TUF aims to be secure against all of the above attacks. A few general ideas drive much of the security of TUF. From afa804f093a05a3a691d85fe5dcb1d88aa69c037 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Thu, 18 May 2017 12:36:01 -0400 Subject: [PATCH 16/34] Clarify that the previous snapshot metadata file may be safely expired. --- docs/tuf-spec.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index fb32b691..03a8fefc 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -978,11 +978,15 @@ Version 1.0 (Draft) 3.3. **Check for a rollback attack.** - 3.3.1. The version number of the previous snapshot metadata file, if any, + 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.2. The version number of the targets metadata file, and all delegated + 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 From be7a7ffd6f36138dddb6fdc6bce3c311b81b86b2 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Thu, 18 May 2017 11:54:33 -0400 Subject: [PATCH 17/34] Clarify procedure for updating to new root.json Client's should validate new root.json according to the threshold and keys set by its previous version. See @heartsucker comment [here](https://github.com/heartsucker/rust-tuf/issues/42#issuecomment-302436972) --- docs/tuf-spec.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index bba03f3e..e3b6f1ba 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1002,12 +1002,14 @@ Version 1.0 (Draft) role. When replacing root keys, an application will sign the new root.json file with both the new and old root keys. Any time such a change is required, the root.json file is versioned and accessible by version number, - e.g. 3.root.json. Clients update the set of trusted root keys by requesting + e.g., 3.root.json. Clients update the set of trusted root keys by requesting the current root.json and all previous root.json versions, until one is - found that has been signed by keys the client already trusts. This is to - ensure that outdated clients remain able to update, without requiring all - previous root keys to be kept to sign new root.json metadata. - + found that has been signed by a threshold of keys that the client already + trusts. This is to ensure that outdated clients remain able to update, + without requiring all previous root keys to be kept to sign new root.json + metadata. Before a new version of root (e.g., 2.root.json) can be trusted, + the client must validate it against the trusted keys and threshold set by + its previous version (i.e., 1.root.json). 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 From 4a1791d125fbcbc4a3b29f7115fe7f328218629f Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Thu, 18 May 2017 15:14:56 -0400 Subject: [PATCH 18/34] Incorporate @awwad and @heartsucker suggestions --- docs/tuf-spec.txt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index e3b6f1ba..1f562b4b 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1007,10 +1007,17 @@ Version 1.0 (Draft) found that has been signed by a threshold of keys that the client already trusts. This is to ensure that outdated clients remain able to update, without requiring all previous root keys to be kept to sign new root.json - metadata. Before a new version of root (e.g., 2.root.json) can be trusted, - the client must validate it against the trusted keys and threshold set by - its previous version (i.e., 1.root.json). - + metadata. + + In the event that the keys being updated are root keys, it is important to + note that the new root.json must at least be signed by the keys listed as + root keys in the previous version of root.json, up to the threshold listed + for root in the previous version of root.json. If this is not the case, + clients will (correctly) not validate the new root.json file. For example, + if there is 1.root.json that has threshold 2 and 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 3.root.json. + 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. From 1269ed96784dd7c0b9417c8d09f0f16c0c905c2a Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Thu, 18 May 2017 15:15:51 -0400 Subject: [PATCH 19/34] Fix whitespace issue in previous commit --- docs/tuf-spec.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 1f562b4b..2fcb5004 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1010,8 +1010,8 @@ Version 1.0 (Draft) metadata. In the event that the keys being updated are root keys, it is important to - note that the new root.json must at least be signed by the keys listed as - root keys in the previous version of root.json, up to the threshold listed + note that the new root.json must at least be signed by the keys listed as + root keys in the previous version of root.json, up to the threshold listed for root in the previous version of root.json. If this is not the case, clients will (correctly) not validate the new root.json file. For example, if there is 1.root.json that has threshold 2 and 2.root.json that has From 70cf57ad85330d6af8a99bda1f3db2660084ef90 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Thu, 18 May 2017 15:28:54 -0400 Subject: [PATCH 20/34] Slight edit to fix incorrect version of root file --- docs/tuf-spec.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 2fcb5004..c10e9563 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1014,9 +1014,9 @@ Version 1.0 (Draft) root keys in the previous version of root.json, up to the threshold listed for root in the previous version of root.json. If this is not the case, clients will (correctly) not validate the new root.json file. For example, - if there is 1.root.json that has threshold 2 and 2.root.json that has + 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 3.root.json. + 1.root.json and at least 3 keys defined in 2.root.json. 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 From 947e36655773b9162fdd147ceca4a3546a7c5f52 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Thu, 18 May 2017 20:44:46 -0400 Subject: [PATCH 21/34] Use "MUST" with regard to RFC 2119. --- docs/tuf-spec.txt | 195 +++++++++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 96 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 03a8fefc..04c2b886 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1,6 +1,6 @@ The Update Framework Specification -7 October 2016 +18 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 } } @@ -932,7 +936,7 @@ Version 1.0 (Draft) (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. - 1.1. **Check signatures.** The root metadata file must have been signed by + 1.1. **Check signatures.** The root metadata file MUST have been signed by a threshold of keys specified in the previous root metadata file. 1.2. **Check for a rollback attack.** The version number of the previous @@ -971,9 +975,9 @@ Version 1.0 (Draft) bytes specified in the timestamp metadata file. 3.1. **Check against timestamp metadata.** The hashes, and version number - of this metadata file must match the timestamp metadata. + of this metadata file MUST match the timestamp metadata. - 3.2. **Check signatures.** The snapshot metadata file must have been signed + 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.** @@ -983,14 +987,14 @@ Version 1.0 (Draft) 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 + 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 + 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 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 @@ -1002,16 +1006,16 @@ Version 1.0 (Draft) using TUF. For example, Z may be tens of kilobytes. 4.1. **Check against snapshot metadata.** The hashes (if any), and version - number of this metadata file must match the snapshot metadata. This is + 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 + 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 + 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 @@ -1095,7 +1099,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 @@ -1104,8 +1108,8 @@ Version 1.0 (Draft) required, the root.json file is versioned and accessible by version number, e.g. 3.root.json. Clients update the set of trusted root keys by requesting the current root.json and all previous root.json versions, until one is - found that has been signed by keys the client already trusts. This is to - ensure that outdated clients remain able to update, without requiring all + found that has been signed by keys the client already trusts. This is to + ensure that outdated clients remain able to update, without requiring all previous root keys to be kept to sign new root.json metadata. @@ -1138,7 +1142,7 @@ 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 @@ -1213,4 +1217,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. - From 8b1f85363a85990a9ecf1fa394768efc7302f3e1 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Thu, 18 May 2017 20:58:37 -0400 Subject: [PATCH 22/34] Explain how to obtain and load the previous root metadata file. --- docs/tuf-spec.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 04c2b886..c371db4f 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -932,6 +932,16 @@ Version 1.0 (Draft) 5.1. The client application + 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. + + 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. + + 0.2. **Check for a freeze attack.** The latest known time should be lower + than the expiration timestamp in this metadata file. + 1. **Download 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. From c5deaa340ff33f47fc94e1480240a67639cdbab8 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Thu, 18 May 2017 20:59:00 -0400 Subject: [PATCH 23/34] Explain why download targets up to the # of bytes in the targets metadata. --- docs/tuf-spec.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index c371db4f..57495b96 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1057,9 +1057,12 @@ Version 1.0 (Draft) 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 (exactly the number of bytes specified - in the targets metadata), and verify that its hashes match the targets - metadata. + 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.) 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), From 30536cfb1a1ca7998af702305679bb59932c1715 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Thu, 18 May 2017 21:09:35 -0400 Subject: [PATCH 24/34] Edit Section 7.2 to reflect Section 5.1. Ideally, the former should be merged with the latter. --- docs/tuf-spec.txt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 57495b96..812e8133 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1071,7 +1071,6 @@ Version 1.0 (Draft) using the framework can decide how to proceed rather than automatically downloading a new Root 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 @@ -1204,24 +1203,25 @@ Version 1.0 (Draft) 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. + 1. It MUST first retrieve the root metadata from the repository without + modifying its filename (e.g., root.json), because its hashes are unknown + ahead of time. + 2. Then it MUST first retrieve the timestamp metadata from the + repository without modifying its filename (e.g., timestamp.json), because + its hashes are unknown ahead of time. + 3. Then it 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. + file retrieved with the name DIGEST.FILENAME.EXT to the name + FILENAME.EXT. F. Future directions and open questions From 487d27a6545b9d718304f742f7fa38bea1a9a93a Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Fri, 19 May 2017 00:06:47 -0400 Subject: [PATCH 25/34] Add subtleties to preorder DFS for targets. --- docs/tuf-spec.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 812e8133..7209cdf4 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1032,10 +1032,15 @@ Version 1.0 (Draft) lower than the expiration timestamp in this metadata file. 4.5. **Perform a preorder depth-first search for metadata about the desired - target.** + target, beginning with the top-level targets role.** - 4.5.1. If this file contains metadata about the desired target, then go to - step 5. + 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. From 5666cbcfc06fa7471125cbb25aee09e1792e8a8f Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Fri, 19 May 2017 00:10:50 -0400 Subject: [PATCH 26/34] Remove what seems like unnecessary, obsolete text. --- docs/tuf-spec.txt | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 7209cdf4..8e1864dc 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1076,35 +1076,6 @@ Version 1.0 (Draft) using the framework can decide how to proceed rather than automatically downloading a new Root 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. - - If the snapshot.json file has changed, the framework downloads the file and - verifies that the file 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. - - 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. - - 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 the file matches the information - described in the targets files, and then makes the file available to the - client code. - 6. Usage See https://www.theupdateframework.com/ for discussion of recommended usage From a2a59318836a293021cce8b386a1c226eb2deb0e Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Fri, 19 May 2017 00:45:28 -0400 Subject: [PATCH 27/34] Merge reading consistent snapshots with the client update workflow. --- docs/tuf-spec.txt | 51 ++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 8e1864dc..f0f79107 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -944,7 +944,9 @@ Version 1.0 (Draft) 1. **Download 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. + 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 + FILENAME.EXT (e.g., root.json). 1.1. **Check signatures.** The root metadata file MUST have been signed by a threshold of keys specified in the previous root metadata file. @@ -969,7 +971,9 @@ Version 1.0 (Draft) 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. + 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. @@ -983,6 +987,14 @@ Version 1.0 (Draft) 3. **Download and check the snapshot metadata file**, up to the number of bytes specified in the timestamp metadata file. + If consistent snapshots are 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 FILENAME.HASH.EXT (e.g., + snapshot.c14aeb4ac9f4a8fc0d83d12482b9197452f6adf3eb710e3b1e2b79e8d14cb681.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 disk as FILENAME.EXT. 3.1. **Check against timestamp metadata.** The hashes, and version number of this metadata file MUST match the timestamp metadata. @@ -1014,6 +1026,13 @@ Version 1.0 (Draft) 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 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 FILENAME.VERSION.EXT (e.g., + targets.42.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 disk 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 @@ -1171,33 +1190,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 root metadata from the repository without - modifying its filename (e.g., root.json), because its hashes are unknown - ahead of time. - 2. Then it MUST first retrieve the timestamp metadata from the - repository without modifying its filename (e.g., timestamp.json), because - its hashes are unknown ahead of time. - 3. Then it 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 From 3935141b858c610efb18f805d1a65c982ef4a9bf Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Fri, 19 May 2017 16:31:18 -0400 Subject: [PATCH 28/34] Remove what seems like an unnecessary note. --- docs/tuf-spec.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index f0f79107..d1c26e97 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1088,13 +1088,6 @@ Version 1.0 (Draft) 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.) - 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. - 6. Usage See https://www.theupdateframework.com/ for discussion of recommended usage From d80ea0b1451d4f4a01868860b8a0ce13390c53a9 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Fri, 19 May 2017 16:32:48 -0400 Subject: [PATCH 29/34] Add a note about the expiration of the previous root metadata file. --- docs/tuf-spec.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index d1c26e97..976e0b0c 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -939,8 +939,8 @@ Version 1.0 (Draft) 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. - 0.2. **Check for a freeze attack.** The latest known time should be lower - than the expiration timestamp in this metadata file. + 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. 1. **Download 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 From 98de3c490f46e0f21b8d812acf059ef16e4d1d46 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Tue, 23 May 2017 17:09:57 -0400 Subject: [PATCH 30/34] Worked with @vladimir-v-diaz to add root migration workflow. Also corrected how files are fetched. --- docs/tuf-spec.txt | 95 ++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 976e0b0c..d0f07222 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -942,23 +942,39 @@ Version 1.0 (Draft) 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. - 1. **Download 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 - FILENAME.EXT (e.g., 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. - 1.1. **Check signatures.** The root metadata file MUST have been signed by - a threshold of keys specified in the previous root metadata file. + 1.1. Let N denote the version number of the previous root metadata file. - 1.2. **Check for a rollback attack.** The version number of the previous + 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. + + 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). + + 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. + root metadata file. Effectively, this means checking that the version + number signed in the current root metadata file is indeed N+1. - 1.3. **Check for a freeze attack.** The latest known time should be lower - than the expiration timestamp in this metadata file. + 1.5. **Check for a freeze attack.** The latest known time should be lower + than the expiration timestamp in the current root metadata file. - 1.4. **If the the timestamp and / or snapshot keys have been rotated, then + 1.6. Set the previous to the current root metadata file. + + 1.7. Repeat steps 1.1 to 1.6. + + 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 @@ -990,11 +1006,11 @@ Version 1.0 (Draft) If consistent snapshots are 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 FILENAME.HASH.EXT (e.g., - snapshot.c14aeb4ac9f4a8fc0d83d12482b9197452f6adf3eb710e3b1e2b79e8d14cb681.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 disk as FILENAME.EXT. + 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. @@ -1029,10 +1045,11 @@ Version 1.0 (Draft) If consistent snapshots are 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 FILENAME.VERSION.EXT (e.g., - targets.42.json), where VERSION is the version number of the targets + 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 disk as FILENAME.EXT. + 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 @@ -1087,6 +1104,15 @@ Version 1.0 (Draft) 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 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 @@ -1110,8 +1136,8 @@ Version 1.0 (Draft) the current root.json and all previous root.json versions, until one is found that has been signed by keys the client already trusts. This is to ensure that outdated clients remain able to update, without requiring all - previous root keys to be kept to sign new root.json metadata. - + previous root keys to be kept to sign new root.json metadata. 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 @@ -1141,21 +1167,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. + 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 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. + 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 From c5e8c079bbc4c84a7f0c03f2f8ffbdf2aab171e9 Mon Sep 17 00:00:00 2001 From: Trishank Karthik Kuppusamy Date: Tue, 23 May 2017 21:41:31 -0400 Subject: [PATCH 31/34] Fix bloopers. --- docs/tuf-spec.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 902da32b..37653350 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1003,9 +1003,9 @@ Version 1.0 (Draft) 3. **Download and check the snapshot metadata file**, up to the number of bytes specified in the timestamp metadata file. - If consistent snapshots are 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). + 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. @@ -1042,9 +1042,9 @@ Version 1.0 (Draft) 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 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). + 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. @@ -1104,9 +1104,9 @@ Version 1.0 (Draft) 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 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). + 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 From 836ebe59cb74fc9c156c8d9ecb006e55ffa40ec9 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Wed, 24 May 2017 10:31:26 -0400 Subject: [PATCH 32/34] Fix section 3, where the hash is specified rather than the version number --- docs/tuf-spec.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 37653350..65582002 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1007,9 +1007,9 @@ Version 1.0 (Draft) 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 + 42.snapshot.json), where VERSION is the version number 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 From b7f893dd624ee2d9f855c59596e2ab66e3c91e39 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Wed, 24 May 2017 11:06:54 -0400 Subject: [PATCH 33/34] Edit instances of "downloaded time" to just "time" --- docs/tuf-spec.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 65582002..2c40e215 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1035,8 +1035,8 @@ Version 1.0 (Draft) 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. + 3.4. **Check for a freeze attack.** The latest 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 @@ -1064,8 +1064,8 @@ Version 1.0 (Draft) 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.4. **Check for a freeze attack.** The latest 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.** From c1e72e0fdd092c5d71d52ffa345893b4a8013a25 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Wed, 24 May 2017 12:16:18 -0400 Subject: [PATCH 34/34] "latest time" --> "latest known time" --- docs/tuf-spec.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index 2c40e215..d2b2a006 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -1035,8 +1035,8 @@ Version 1.0 (Draft) 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 time should be lower than the - expiration timestamp in this metadata file. + 3.4. **Check for a freeze attack.** The latest known 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 @@ -1064,8 +1064,8 @@ Version 1.0 (Draft) 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 time should be lower than - the expiration timestamp in this metadata file. + 4.4. **Check for a freeze attack.** The latest known 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.**