[rust-3p] Update tuf to 0.3.0-beta7
Change-Id: I7b3ad95824b51e11925010fc33590f4eb9a5fa97
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/693938
Commit-Queue: Erick Tryzelaar <etryzelaar@google.com>
Fuchsia-Auto-Submit: Erick Tryzelaar <etryzelaar@google.com>
Reviewed-by: Ben Keller <galbanum@google.com>
diff --git a/src/developer/ffx/lib/pkg/src/repository.rs b/src/developer/ffx/lib/pkg/src/repository.rs
index 6f5dc07..1a2ef84 100644
--- a/src/developer/ffx/lib/pkg/src/repository.rs
+++ b/src/developer/ffx/lib/pkg/src/repository.rs
@@ -34,8 +34,8 @@
crypto::KeyType,
interchange::Json,
metadata::{
- Metadata as _, MetadataPath, MetadataVersion, RawSignedMetadata, Role,
- TargetDescription, TargetPath, TargetsMetadata,
+ Metadata as _, MetadataPath, MetadataVersion, RawSignedMetadata, TargetDescription,
+ TargetPath, TargetsMetadata,
},
repository::{EphemeralRepository, RepositoryProvider},
verify::Verified,
@@ -335,8 +335,8 @@
// https://github.com/heartsucker/rust-tuf/pull/318 lands.
match client.update().await {
Ok(_) => {}
- Err(err @ tuf::Error::ExpiredMetadata(Role::Root)) => {
- return Err(err.into());
+ Err(tuf::Error::ExpiredMetadata(path)) if path == MetadataPath::root() => {
+ return Err(tuf::Error::ExpiredMetadata(path).into());
}
Err(tuf::Error::ExpiredMetadata(_)) => {}
Err(err) => {
@@ -595,16 +595,12 @@
let raw_signed_meta = {
// FIXME(http://fxbug.dev/92126) we really should be initializing trust, rather than just
// trusting 1.root.json.
- let root = tuf_repo
- .fetch_metadata(&MetadataPath::from_role(&Role::Root), MetadataVersion::Number(1))
- .await;
+ let root = tuf_repo.fetch_metadata(&MetadataPath::root(), MetadataVersion::Number(1)).await;
// If we couldn't find 1.root.json, see if root.json exists and try to initialize trust with it.
let mut root = match root {
Err(tuf::Error::NotFound) => {
- tuf_repo
- .fetch_metadata(&MetadataPath::from_role(&Role::Root), MetadataVersion::None)
- .await?
+ tuf_repo.fetch_metadata(&MetadataPath::root(), MetadataVersion::None).await?
}
Err(err) => return Err(err.into()),
Ok(root) => root,
diff --git a/src/sys/pkg/bin/pkg-resolver/src/repository.rs b/src/sys/pkg/bin/pkg-resolver/src/repository.rs
index d6035a0..11b63ea 100644
--- a/src/sys/pkg/bin/pkg-resolver/src/repository.rs
+++ b/src/sys/pkg/bin/pkg-resolver/src/repository.rs
@@ -343,6 +343,7 @@
path::{Path, PathBuf},
sync::Arc,
},
+ tuf::metadata::MetadataPath,
updating_tuf_client::METADATA_CACHE_STALE_TIMEOUT,
};
@@ -554,8 +555,10 @@
assert_matches!(
repo.get_merkle_at_path(&target_path).await,
Err(MerkleForError::FetchTargetDescription(
- extracted_path, TufError::MissingMetadata(tuf::metadata::Role::Snapshot)))
- if extracted_path == "just-meta-far/0"
+ extracted_path, TufError::MissingMetadata(metadata_path)))
+ if
+ metadata_path == MetadataPath::snapshot() &&
+ extracted_path == "just-meta-far/0"
);
}
diff --git a/src/sys/pkg/bin/pkg-resolver/src/repository/local_provider.rs b/src/sys/pkg/bin/pkg-resolver/src/repository/local_provider.rs
index a483abc..05167c4 100644
--- a/src/sys/pkg/bin/pkg-resolver/src/repository/local_provider.rs
+++ b/src/sys/pkg/bin/pkg-resolver/src/repository/local_provider.rs
@@ -103,7 +103,6 @@
fidl_fuchsia_pkg::LocalMirrorMarker,
fuchsia_async as fasync,
fuchsia_pkg_testing::{FakePkgLocalMirror, PackageBuilder, Repository, RepositoryBuilder},
- tuf::metadata::Role,
};
struct TestEnv {
@@ -146,7 +145,7 @@
let env = TestEnv::new().await;
let mut result = env
.provider
- .fetch_metadata(&MetadataPath::from_role(&Role::Root), MetadataVersion::None)
+ .fetch_metadata(&MetadataPath::root(), MetadataVersion::None)
.await
.expect("fetch_metadata succeeds");
@@ -160,7 +159,7 @@
let env = TestEnv::new().await;
let mut result = env
.provider
- .fetch_metadata(&MetadataPath::from_role(&Role::Root), MetadataVersion::Number(1))
+ .fetch_metadata(&MetadataPath::root(), MetadataVersion::Number(1))
.await
.expect("fetch_metadata succeeds");
@@ -172,10 +171,8 @@
#[fasync::run_singlethreaded(test)]
async fn test_fetch_metadata_v4_fails() {
let env = TestEnv::new().await;
- let result = env
- .provider
- .fetch_metadata(&MetadataPath::from_role(&Role::Root), MetadataVersion::Number(4))
- .await;
+ let result =
+ env.provider.fetch_metadata(&MetadataPath::root(), MetadataVersion::Number(4)).await;
assert!(result.is_err());
}
diff --git a/third_party/rust_crates/BUILD.gn b/third_party/rust_crates/BUILD.gn
index 568056f..17ab911 100644
--- a/third_party/rust_crates/BUILD.gn
+++ b/third_party/rust_crates/BUILD.gn
@@ -974,7 +974,7 @@
}
group("tuf") {
- public_deps = [ ":tuf-v0_3_0-beta6" ]
+ public_deps = [ ":tuf-v0_3_0-beta7" ]
}
group("tui") {
@@ -11023,10 +11023,10 @@
visibility = [ ":*" ]
}
-rust_library("tuf-v0_3_0-beta6") {
+rust_library("tuf-v0_3_0-beta7") {
crate_name = "tuf"
crate_root = "//third_party/rust_crates/vendor/tuf/./src/lib.rs"
- output_name = "tuf-952564b68aeb1a54"
+ output_name = "tuf-96c9a4f85a521c39"
configs -= [ "//build/config/rust:2018_idioms" ]
deps = []
@@ -11054,8 +11054,8 @@
rustflags = [
"--cap-lints=allow",
"--edition=2018",
- "-Cmetadata=952564b68aeb1a54",
- "-Cextra-filename=-952564b68aeb1a54",
+ "-Cmetadata=96c9a4f85a521c39",
+ "-Cextra-filename=-96c9a4f85a521c39",
"--cfg=feature=\"hyper_014\"",
]
diff --git a/third_party/rust_crates/Cargo.lock b/third_party/rust_crates/Cargo.lock
index c1d7a9e..1512db5 100644
--- a/third_party/rust_crates/Cargo.lock
+++ b/third_party/rust_crates/Cargo.lock
@@ -4301,9 +4301,9 @@
[[package]]
name = "tuf"
-version = "0.3.0-beta6"
+version = "0.3.0-beta7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10732acf3faedf67088c0e74d0e272d3081f6c0baafdb32a22d1703013a5f03e"
+checksum = "162303bc477f3f6e2919b4a0e2f4d5e421b13c430321251b3d68941b784ab354"
dependencies = [
"chrono",
"data-encoding",
diff --git a/third_party/rust_crates/Cargo.toml b/third_party/rust_crates/Cargo.toml
index 02d6c21..adbecef 100644
--- a/third_party/rust_crates/Cargo.toml
+++ b/third_party/rust_crates/Cargo.toml
@@ -190,7 +190,7 @@
strsim = "0.10.0"
structopt = "0.2.14"
tempfile = "3.2"
-tuf = { version = "0.3.0-beta6", default-features = false, features = ["hyper_014"] }
+tuf = { version = "0.3.0-beta7", default-features = false, features = ["hyper_014"] }
tui = "0.16.0"
termion = "1.5.3"
test-case = "1.1.0"
diff --git a/third_party/rust_crates/vendor/tuf/.cargo-checksum.json b/third_party/rust_crates/vendor/tuf/.cargo-checksum.json
index f5e365d..902b25d 100644
--- a/third_party/rust_crates/vendor/tuf/.cargo-checksum.json
+++ b/third_party/rust_crates/vendor/tuf/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"1bfad60e2967b9119fd37046ab884729b5cc6ff9a26e75c185c65365802aa3af","LICENSE-APACHE":"2bdfac761d8c617b32c5e24c429518d71be44aac4aba1a6ac7aa196f929bb601","LICENSE-MIT":"61ed40687d2656636a04680013dffe41d5c724201edaa84045e0677b8e2064d6","README.md":"a18679a3942a9c8c279dc411e29030dab720745af669291b9398723b2c56956f","src/client.rs":"6e5c44c9c1de685f3932c2c6636a1c9c8f698b7da6eb988a0365e70de83d80ca","src/crypto.rs":"46c297f21c70a0861765cd30fe1fb7dc0e646ae8ca1cf8228143d613b565f4c8","src/database.rs":"7595fddcc45c08b47680ceae07ead14c1a3ec98c4dcfa6b601f2d3a09a5cebfb","src/error.rs":"9a0a051b3be5a7e56990ed02c83b2c41072e19e28f12ac4cf8c870dad0c0776a","src/format_hex.rs":"38b2ac4e7bd69a6edf2f35027600211452f084e6294415536cd305c3e849485a","src/interchange/cjson/mod.rs":"14ac2fe8adc1d2be53a29bfffedeba99b9cb435fbfb8c3d72b0fbcf51de8fffa","src/interchange/cjson/pretty.rs":"7948954ebbb88de1ddc1969600814ea23add7604ade51cb7927950002bee5f7f","src/interchange/cjson/shims.rs":"6f17283c0e331b0e5fe3b97340c913aef3869348828c4730164e126bd05f4a9a","src/interchange/mod.rs":"4ec7047ab6a6f9a256d056a4026e412dd4cb207451b24506629f614b08d897a8","src/lib.rs":"12f03d45f6772614c64d81c5f2962bd9d9042ca10c79443a67f13de24983209b","src/metadata.rs":"834c58bfd2e10a4806ae82fe7b21934955f9b323890f5e130c73cc4a8fa0a327","src/repo_builder.rs":"22fc6d0352bd0020c85da270d6a2ab78fe83988c7f32cc3634e68c1c60531d28","src/repository.rs":"a1052d6e34edbf1d71acb3475c2d6936ce59dde8ac870d20f4f1604e8f86fa32","src/repository/ephemeral.rs":"acbe838d2f3f040630eef1d2976fc486315cb315d7eea789f3e06dea8fb7adfd","src/repository/error_repo.rs":"ece7afa0010b56b6b4b8354488ae788a6c68747507b88534110f288910141afa","src/repository/file_system.rs":"022f2a47d0e154c410fc450d40f39345978ef443558cc5ef7c1c0e213464f6e7","src/repository/http.rs":"6a1630a73856a574fd3305e7955c9d36cedd7907ab6e9c3231ee044c79337c08","src/repository/track_repo.rs":"601b130aad6c669d90b3bd12c04fa768179d62c0dad42c2b284164980a699bf9","src/util.rs":"78d2ef67aae28ae421aafa70d5cc367b0d65ebd683cab444f00b51b26542fa40","src/verify.rs":"7e86461716e3c7d314f67da6f9de4142580cd48970fc10f4cd58b5e08da1ef56","tests/ed25519/ed25519-1":"39b04e2225d769fa8a3af913c40559b09cd5f4fb889827c3f6ce3fb99b727654","tests/ed25519/ed25519-1.pk8.der":"8db9bbc5ac4480f3cc645e610f7ed1d7ab69f5718cd12e275eaaeb107d704799","tests/ed25519/ed25519-1.pub":"afbe17fbfbc28b1e1220c162883da3f616f21d08a484c013cee9aae332989108","tests/ed25519/ed25519-1.spki.der":"a9fadf06b901e2504148310195981a4c64bf4ab13a51f98e37d90fe22ddd2456","tests/ed25519/ed25519-2.pk8.der":"dead09835a4a725c6278b22e1eeb1429b0827554503f3c101c93ffd567096d45","tests/ed25519/ed25519-3.pk8.der":"a95f7d893b13b5eea411bbc76b355219a86dd469e47efcc1cebfd327ea739a32","tests/ed25519/ed25519-4.pk8.der":"f0385d82f284eaaea6bf71a71d7a0961535562451c98b59da33660eed740606e","tests/ed25519/ed25519-5.pk8.der":"2a7566c8a1a56644fd0df47f2eaeba6a24432fe2b6461d33821f35b93bae70a3","tests/ed25519/ed25519-6.pk8.der":"6595ddaee0a08b59c14bc83a9dba4a7993ddd24cac7d46aed947269370ae7a1b","tests/integration.rs":"cc4d3d724a6513440af65804661292e4bb399206e68055da19b1dfebd435218b","tests/rsa/gen.sh":"1422883e49a63544b951bb1b76e98bf5a96e6e2353349d98ca2cac9ff7d0b4ac","tests/rsa/rsa-2048":"1ec467d90c163814dbf2e2de913f8b3714ee0f1cbd3eeb863112db818e3b92df","tests/rsa/rsa-2048.der":"3df4f04a2badbb2cd3e8204a9648cc8d4ee0094a740de1694be5e8348e7a5ccb","tests/rsa/rsa-2048.pk8.der":"8998d4d952040173a0d652207132d3bd62c668338190f150b184b2a8be3ae2f5","tests/rsa/rsa-2048.pkcs1.der":"6f541b7eb4af92d33bea3cb93d7b91af27042c1cd4dc9d70e2c78d9b883d9bba","tests/rsa/rsa-2048.spki.der":"960e2da59100772ecadff393e7d703fe5a7aed2600c63e7eef70daa61f671535","tests/rsa/rsa-4096.der":"9065496b699e242fb1b5e17a147322b0a3ede74752205ccfb05a07ef70c4e748","tests/rsa/rsa-4096.pk8.der":"af4c5b20cb762c238659764c7cfd4fe43b19ac3d971421cc82bdf3092416b3ac","tests/rsa/rsa-4096.pkcs1.der":"e5d5ceb6ecfe59e45b9766cc999ef2fad4897f245e191fad6ebdaba4ce79f97d","tests/rsa/rsa-4096.spki.der":"e0ad84cd41a33d6c6a671346565de376b3cd806011a965e9e427432748021de9","tests/simple_example.rs":"8444d37fc5a2105d2fc44ef8639da8b6591ff671e04c80804af8bffd47a10037"},"package":"10732acf3faedf67088c0e74d0e272d3081f6c0baafdb32a22d1703013a5f03e"}
\ No newline at end of file
+{"files":{"Cargo.toml":"135fe2bde1d4df41d20d6e2cc70a48e800982451e622e2260d44fa1a8aa9507d","LICENSE-APACHE":"2bdfac761d8c617b32c5e24c429518d71be44aac4aba1a6ac7aa196f929bb601","LICENSE-MIT":"61ed40687d2656636a04680013dffe41d5c724201edaa84045e0677b8e2064d6","README.md":"a18679a3942a9c8c279dc411e29030dab720745af669291b9398723b2c56956f","src/client.rs":"3d43f2c3694669c019c21c971b77ab364b05518757874c14111db104e7bd43a4","src/crypto.rs":"46c297f21c70a0861765cd30fe1fb7dc0e646ae8ca1cf8228143d613b565f4c8","src/database.rs":"6f3b5b0fdf4636db9e293b957371cc311c0fda937a8dfc6caecbd2bdeac91750","src/error.rs":"980bbbb1136e72eaa6068d363634cb5788f4d959b24e49ec471b452d3ffe924f","src/format_hex.rs":"38b2ac4e7bd69a6edf2f35027600211452f084e6294415536cd305c3e849485a","src/interchange/cjson/mod.rs":"14ac2fe8adc1d2be53a29bfffedeba99b9cb435fbfb8c3d72b0fbcf51de8fffa","src/interchange/cjson/pretty.rs":"7948954ebbb88de1ddc1969600814ea23add7604ade51cb7927950002bee5f7f","src/interchange/cjson/shims.rs":"ca1ac7ac79b8085f802fd0c092f84eda5afb683131d8b6c0446d9df3ce563a53","src/interchange/mod.rs":"4ec7047ab6a6f9a256d056a4026e412dd4cb207451b24506629f614b08d897a8","src/lib.rs":"12f03d45f6772614c64d81c5f2962bd9d9042ca10c79443a67f13de24983209b","src/metadata.rs":"9cbcdd04e3b52ab14f52ab0189a07925cdefb341edac00cab032712ec8749cc4","src/repo_builder.rs":"c235454f33905075087f05d7d1f3ef9809b79a5de1a54ce4d47a1da2c92dfe2f","src/repository.rs":"85685c434ff8e55292682125f6ef38643542e1b010d886f2af9812aeb1202411","src/repository/ephemeral.rs":"acbe838d2f3f040630eef1d2976fc486315cb315d7eea789f3e06dea8fb7adfd","src/repository/error_repo.rs":"ece7afa0010b56b6b4b8354488ae788a6c68747507b88534110f288910141afa","src/repository/file_system.rs":"029e7d09c11c290e4862729dd983d9d28018cb7dbe27760c2e2a34b0b5711874","src/repository/http.rs":"6a1630a73856a574fd3305e7955c9d36cedd7907ab6e9c3231ee044c79337c08","src/repository/track_repo.rs":"7c14ed2c041fc57eb63aa2137b11293403dc85ac4f6267b9f6b413d549bce3bc","src/util.rs":"78d2ef67aae28ae421aafa70d5cc367b0d65ebd683cab444f00b51b26542fa40","src/verify.rs":"7e86461716e3c7d314f67da6f9de4142580cd48970fc10f4cd58b5e08da1ef56","tests/ed25519/ed25519-1":"39b04e2225d769fa8a3af913c40559b09cd5f4fb889827c3f6ce3fb99b727654","tests/ed25519/ed25519-1.pk8.der":"8db9bbc5ac4480f3cc645e610f7ed1d7ab69f5718cd12e275eaaeb107d704799","tests/ed25519/ed25519-1.pub":"afbe17fbfbc28b1e1220c162883da3f616f21d08a484c013cee9aae332989108","tests/ed25519/ed25519-1.spki.der":"a9fadf06b901e2504148310195981a4c64bf4ab13a51f98e37d90fe22ddd2456","tests/ed25519/ed25519-2.pk8.der":"dead09835a4a725c6278b22e1eeb1429b0827554503f3c101c93ffd567096d45","tests/ed25519/ed25519-3.pk8.der":"a95f7d893b13b5eea411bbc76b355219a86dd469e47efcc1cebfd327ea739a32","tests/ed25519/ed25519-4.pk8.der":"f0385d82f284eaaea6bf71a71d7a0961535562451c98b59da33660eed740606e","tests/ed25519/ed25519-5.pk8.der":"2a7566c8a1a56644fd0df47f2eaeba6a24432fe2b6461d33821f35b93bae70a3","tests/ed25519/ed25519-6.pk8.der":"6595ddaee0a08b59c14bc83a9dba4a7993ddd24cac7d46aed947269370ae7a1b","tests/integration.rs":"4dc68fa351f4f80ca73dbde6a5e3edc6e53a76ff85f768d310ae237118d936fe","tests/rsa/gen.sh":"1422883e49a63544b951bb1b76e98bf5a96e6e2353349d98ca2cac9ff7d0b4ac","tests/rsa/rsa-2048":"1ec467d90c163814dbf2e2de913f8b3714ee0f1cbd3eeb863112db818e3b92df","tests/rsa/rsa-2048.der":"3df4f04a2badbb2cd3e8204a9648cc8d4ee0094a740de1694be5e8348e7a5ccb","tests/rsa/rsa-2048.pk8.der":"8998d4d952040173a0d652207132d3bd62c668338190f150b184b2a8be3ae2f5","tests/rsa/rsa-2048.pkcs1.der":"6f541b7eb4af92d33bea3cb93d7b91af27042c1cd4dc9d70e2c78d9b883d9bba","tests/rsa/rsa-2048.spki.der":"960e2da59100772ecadff393e7d703fe5a7aed2600c63e7eef70daa61f671535","tests/rsa/rsa-4096.der":"9065496b699e242fb1b5e17a147322b0a3ede74752205ccfb05a07ef70c4e748","tests/rsa/rsa-4096.pk8.der":"af4c5b20cb762c238659764c7cfd4fe43b19ac3d971421cc82bdf3092416b3ac","tests/rsa/rsa-4096.pkcs1.der":"e5d5ceb6ecfe59e45b9766cc999ef2fad4897f245e191fad6ebdaba4ce79f97d","tests/rsa/rsa-4096.spki.der":"e0ad84cd41a33d6c6a671346565de376b3cd806011a965e9e427432748021de9","tests/simple_example.rs":"8444d37fc5a2105d2fc44ef8639da8b6591ff671e04c80804af8bffd47a10037"},"package":"162303bc477f3f6e2919b4a0e2f4d5e421b13c430321251b3d68941b784ab354"}
\ No newline at end of file
diff --git a/third_party/rust_crates/vendor/tuf/Cargo.toml b/third_party/rust_crates/vendor/tuf/Cargo.toml
index c59faf8..a4a8496 100644
--- a/third_party/rust_crates/vendor/tuf/Cargo.toml
+++ b/third_party/rust_crates/vendor/tuf/Cargo.toml
@@ -12,13 +12,20 @@
[package]
edition = "2018"
name = "tuf"
-version = "0.3.0-beta6"
-authors = ["heartsucker <heartsucker@autistici.org>", "Erick Tryzelaar <etryzelaar@google.com>"]
+version = "0.3.0-beta7"
+authors = [
+ "heartsucker <heartsucker@autistici.org>",
+ "Erick Tryzelaar <etryzelaar@google.com>",
+]
description = "Library for The Update Framework (TUF)"
homepage = "https://github.com/theupdateframework/rust-tuf"
documentation = "https://docs.rs/tuf"
readme = "README.md"
-keywords = ["security", "update", "repository"]
+keywords = [
+ "security",
+ "update",
+ "repository",
+]
categories = ["cryptography"]
license = "MIT/Apache-2.0"
repository = "https://github.com/theupdateframework/rust-tuf"
@@ -26,6 +33,7 @@
[lib]
name = "tuf"
path = "./src/lib.rs"
+
[dependencies.chrono]
version = "0.4"
features = ["serde"]
@@ -55,7 +63,11 @@
[dependencies.hyper_014]
version = "0.14.15"
-features = ["stream", "client", "http1"]
+features = [
+ "stream",
+ "client",
+ "http1",
+]
optional = true
default-features = false
package = "hyper"
@@ -92,6 +104,7 @@
[dependencies.url]
version = "2"
+
[dev-dependencies.assert_matches]
version = "1.5.0"
diff --git a/third_party/rust_crates/vendor/tuf/src/client.rs b/third_party/rust_crates/vendor/tuf/src/client.rs
index 3738672..81b28ea 100644
--- a/third_party/rust_crates/vendor/tuf/src/client.rs
+++ b/third_party/rust_crates/vendor/tuf/src/client.rs
@@ -51,7 +51,7 @@
//! # }
//! ```
-use chrono::offset::Utc;
+use chrono::{offset::Utc, DateTime};
use futures_io::AsyncRead;
use log::{error, warn};
use std::future::Future;
@@ -62,8 +62,8 @@
use crate::error::Error;
use crate::interchange::DataInterchange;
use crate::metadata::{
- Metadata, MetadataPath, MetadataVersion, RawSignedMetadata, Role, RootMetadata,
- SnapshotMetadata, TargetDescription, TargetPath, TargetsMetadata,
+ Metadata, MetadataPath, MetadataVersion, RawSignedMetadata, RootMetadata, SnapshotMetadata,
+ TargetDescription, TargetPath, TargetsMetadata,
};
use crate::repository::{Repository, RepositoryProvider, RepositoryStorage};
use crate::verify::Verified;
@@ -128,7 +128,7 @@
/// .timestamp_key(public_key.clone())
/// .signed::<Json>(&private_key)?;
///
- /// let root_path = MetadataPath::from_role(&Role::Root);
+ /// let root_path = MetadataPath::root();
/// let root_version = MetadataVersion::Number(root_version);
///
/// local.store_metadata(
@@ -148,7 +148,7 @@
/// ```
pub async fn with_trusted_local(config: Config, local: L, remote: R) -> Result<Self> {
let (local, remote) = (Repository::new(local), Repository::new(remote));
- let root_path = MetadataPath::from_role(&Role::Root);
+ let root_path = MetadataPath::root();
// FIXME should this be MetadataVersion::None so we bootstrap with the latest version?
let root_version = MetadataVersion::Number(1);
@@ -261,7 +261,7 @@
/// .timestamp_key(public_key.clone())
/// .signed::<Json>(&private_key)?;
///
- /// let root_path = MetadataPath::from_role(&Role::Root);
+ /// let root_path = MetadataPath::root();
/// let root_version = MetadataVersion::Number(root_version);
///
/// remote.store_metadata(
@@ -295,7 +295,7 @@
{
let (mut local, remote) = (Repository::new(local), Repository::new(remote));
- let root_path = MetadataPath::from_role(&Role::Root);
+ let root_path = MetadataPath::root();
let (fetched, raw_root) = fetch_metadata_from_local_or_else_remote(
&root_path,
root_version,
@@ -374,13 +374,32 @@
local: Repository<L, D>,
remote: Repository<R, D>,
) -> Result<Self> {
+ let start_time = Utc::now();
+
let res = async {
- let _r = Self::update_root_with_repos(&config, &mut tuf, None, &local).await?;
- let _ts = Self::update_timestamp_with_repos(&config, &mut tuf, None, &local).await?;
- let _sn =
- Self::update_snapshot_with_repos(&config, &mut tuf, None, &local, false).await?;
- let _ta =
- Self::update_targets_with_repos(&config, &mut tuf, None, &local, false).await?;
+ let _r =
+ Self::update_root_with_repos(&start_time, &config, &mut tuf, None, &local).await?;
+ let _ts =
+ Self::update_timestamp_with_repos(&start_time, &config, &mut tuf, None, &local)
+ .await?;
+ let _sn = Self::update_snapshot_with_repos(
+ &start_time,
+ &config,
+ &mut tuf,
+ None,
+ &local,
+ false,
+ )
+ .await?;
+ let _ta = Self::update_targets_with_repos(
+ &start_time,
+ &config,
+ &mut tuf,
+ None,
+ &local,
+ false,
+ )
+ .await?;
Ok(())
}
@@ -405,10 +424,20 @@
///
/// Returns `true` if an update occurred and `false` otherwise.
pub async fn update(&mut self) -> Result<bool> {
- let r = self.update_root().await?;
- let ts = self.update_timestamp().await?;
- let sn = self.update_snapshot().await?;
- let ta = self.update_targets().await?;
+ self.update_with_start_time(&Utc::now()).await
+ }
+
+ /// Update TUF metadata from the remote repository, using the specified time to determine if
+ /// the metadata is expired.
+ ///
+ /// Returns `true` if an update occurred and `false` otherwise.
+ ///
+ /// **WARNING**: Using an older time opens up users to a freeze attack.
+ pub async fn update_with_start_time(&mut self, start_time: &DateTime<Utc>) -> Result<bool> {
+ let r = self.update_root(start_time).await?;
+ let ts = self.update_timestamp(start_time).await?;
+ let sn = self.update_snapshot(start_time).await?;
+ let ta = self.update_targets(start_time).await?;
Ok(r || ts || sn || ta)
}
@@ -462,8 +491,9 @@
/// Update TUF root metadata from the remote repository.
///
/// Returns `true` if an update occurred and `false` otherwise.
- pub async fn update_root(&mut self) -> Result<bool> {
+ pub async fn update_root(&mut self, start_time: &DateTime<Utc>) -> Result<bool> {
Self::update_root_with_repos(
+ start_time,
&self.config,
&mut self.tuf,
Some(&mut self.local),
@@ -473,6 +503,7 @@
}
async fn update_root_with_repos<Remote>(
+ start_time: &DateTime<Utc>,
config: &Config,
tuf: &mut Database<D>,
mut local: Option<&mut Repository<L, D>>,
@@ -481,7 +512,7 @@
where
Remote: RepositoryProvider<D>,
{
- let root_path = MetadataPath::from_role(&Role::Root);
+ let root_path = MetadataPath::root();
let mut updated = false;
@@ -556,9 +587,9 @@
// TODO: Consider moving the root metadata expiration check into `tuf::Database`, since that's
// where we check timestamp/snapshot/targets/delegations for expiration.
- if tuf.trusted_root().expires() <= &Utc::now() {
+ if tuf.trusted_root().expires() <= start_time {
error!("Root metadata expired, potential freeze attack");
- return Err(Error::ExpiredMetadata(Role::Root));
+ return Err(Error::ExpiredMetadata(MetadataPath::root()));
}
/////////////////////////////////////////
@@ -571,8 +602,9 @@
}
/// Returns `true` if an update occurred and `false` otherwise.
- async fn update_timestamp(&mut self) -> Result<bool> {
+ async fn update_timestamp(&mut self, start_time: &DateTime<Utc>) -> Result<bool> {
Self::update_timestamp_with_repos(
+ start_time,
&self.config,
&mut self.tuf,
Some(&mut self.local),
@@ -582,6 +614,7 @@
}
async fn update_timestamp_with_repos<Remote>(
+ start_time: &DateTime<Utc>,
config: &Config,
tuf: &mut Database<D>,
local: Option<&mut Repository<L, D>>,
@@ -590,7 +623,7 @@
where
Remote: RepositoryProvider<D>,
{
- let timestamp_path = MetadataPath::from_role(&Role::Timestamp);
+ let timestamp_path = MetadataPath::timestamp();
/////////////////////////////////////////
// TUF-1.0.9 §5.2:
@@ -609,7 +642,10 @@
)
.await?;
- if tuf.update_timestamp(&raw_signed_timestamp)?.is_some() {
+ if tuf
+ .update_timestamp(start_time, &raw_signed_timestamp)?
+ .is_some()
+ {
/////////////////////////////////////////
// TUF-1.0.9 §5.2.4:
//
@@ -633,9 +669,10 @@
}
/// Returns `true` if an update occurred and `false` otherwise.
- async fn update_snapshot(&mut self) -> Result<bool> {
+ async fn update_snapshot(&mut self, start_time: &DateTime<Utc>) -> Result<bool> {
let consistent_snapshot = self.tuf.trusted_root().consistent_snapshot();
Self::update_snapshot_with_repos(
+ start_time,
&self.config,
&mut self.tuf,
Some(&mut self.local),
@@ -646,6 +683,7 @@
}
async fn update_snapshot_with_repos<Remote>(
+ start_time: &DateTime<Utc>,
config: &Config,
tuf: &mut Database<D>,
local: Option<&mut Repository<L, D>>,
@@ -657,7 +695,7 @@
{
let snapshot_description = match tuf.trusted_timestamp() {
Some(ts) => Ok(ts.snapshot()),
- None => Err(Error::MissingMetadata(Role::Timestamp)),
+ None => Err(Error::MissingMetadata(MetadataPath::timestamp())),
}?
.clone();
@@ -673,7 +711,7 @@
MetadataVersion::None
};
- let snapshot_path = MetadataPath::from_role(&Role::Snapshot);
+ let snapshot_path = MetadataPath::snapshot();
// https://theupdateframework.github.io/specification/v1.0.26/#update-snapshot 5.5.1:
@@ -693,7 +731,7 @@
// https://theupdateframework.github.io/specification/v1.0.26/#update-snapshot 5.5.3 through
// 5.5.6 are checked in [Database].
- if tuf.update_snapshot(&raw_signed_snapshot)? {
+ if tuf.update_snapshot(start_time, &raw_signed_snapshot)? {
// https://theupdateframework.github.io/specification/v1.0.26/#update-snapshot 5.5.7:
//
// Persist snapshot metadata. The client MUST write the file to non-volatile storage as
@@ -711,9 +749,10 @@
}
/// Returns `true` if an update occurred and `false` otherwise.
- async fn update_targets(&mut self) -> Result<bool> {
+ async fn update_targets(&mut self, start_time: &DateTime<Utc>) -> Result<bool> {
let consistent_snapshot = self.tuf.trusted_root().consistent_snapshot();
Self::update_targets_with_repos(
+ start_time,
&self.config,
&mut self.tuf,
Some(&mut self.local),
@@ -724,6 +763,7 @@
}
async fn update_targets_with_repos<Remote>(
+ start_time: &DateTime<Utc>,
config: &Config,
tuf: &mut Database<D>,
local: Option<&mut Repository<L, D>>,
@@ -734,7 +774,7 @@
Remote: RepositoryProvider<D>,
{
let targets_description = match tuf.trusted_snapshot() {
- Some(sn) => match sn.meta().get(&MetadataPath::from_role(&Role::Targets)) {
+ Some(sn) => match sn.meta().get(&MetadataPath::targets()) {
Some(d) => Ok(d),
None => Err(Error::VerificationFailure(
"Snapshot metadata did not contain a description of the \
@@ -742,7 +782,7 @@
.into(),
)),
},
- None => Err(Error::MissingMetadata(Role::Snapshot)),
+ None => Err(Error::MissingMetadata(MetadataPath::snapshot())),
}?
.clone();
@@ -757,7 +797,7 @@
MetadataVersion::None
};
- let targets_path = MetadataPath::from_role(&Role::Targets);
+ let targets_path = MetadataPath::targets();
// https://theupdateframework.github.io/specification/v1.0.26/#update-targets 5.6.1:
//
@@ -775,7 +815,7 @@
.fetch_metadata(&targets_path, version, targets_length, target_hashes)
.await?;
- if tuf.update_targets(&raw_signed_targets)? {
+ if tuf.update_targets(start_time, &raw_signed_targets)? {
/////////////////////////////////////////
// TUF-1.0.9 §5.4.4:
//
@@ -803,7 +843,23 @@
&mut self,
target: &TargetPath,
) -> Result<impl AsyncRead + Send + Unpin + '_> {
- let target_description = self.fetch_target_description(target).await?;
+ self.fetch_target_with_start_time(target, &Utc::now()).await
+ }
+
+ /// Fetch a target from the remote repo.
+ ///
+ /// It is **critical** that none of the bytes written to the `write` are used until this future
+ /// returns `Ok`, as the hash of the target is not verified until all bytes are read from the
+ /// repository.
+ pub async fn fetch_target_with_start_time(
+ &mut self,
+ target: &TargetPath,
+ start_time: &DateTime<Utc>,
+ ) -> Result<impl AsyncRead + Send + Unpin + '_> {
+ let target_description = self
+ .fetch_target_description_with_start_time(target, start_time)
+ .await?;
+
// TODO: Check the local repository to see if it already has the target.
self.remote
.fetch_target(
@@ -820,7 +876,23 @@
/// returns `Ok`, as the hash of the target is not verified until all bytes are read from the
/// repository.
pub async fn fetch_target_to_local(&mut self, target: &TargetPath) -> Result<()> {
- let target_description = self.fetch_target_description(target).await?;
+ self.fetch_target_to_local_with_start_time(target, &Utc::now())
+ .await
+ }
+
+ /// Fetch a target from the remote repo and write it to the local repo.
+ ///
+ /// It is **critical** that none of the bytes written to the `write` are used until this future
+ /// returns `Ok`, as the hash of the target is not verified until all bytes are read from the
+ /// repository.
+ pub async fn fetch_target_to_local_with_start_time(
+ &mut self,
+ target: &TargetPath,
+ start_time: &DateTime<Utc>,
+ ) -> Result<()> {
+ let target_description = self
+ .fetch_target_description_with_start_time(target, start_time)
+ .await?;
// Since the async read we fetch from the remote repository has internal
// lifetimes, we need to break up client into sub-objects so that rust
@@ -847,19 +919,40 @@
&mut self,
target: &TargetPath,
) -> Result<TargetDescription> {
+ self.fetch_target_description_with_start_time(target, &Utc::now())
+ .await
+ }
+
+ /// Fetch a target description from the remote repo and return it.
+ pub async fn fetch_target_description_with_start_time(
+ &mut self,
+ target: &TargetPath,
+ start_time: &DateTime<Utc>,
+ ) -> Result<TargetDescription> {
let snapshot = self
.tuf
.trusted_snapshot()
- .ok_or(Error::MissingMetadata(Role::Snapshot))?
+ .ok_or_else(|| Error::MissingMetadata(MetadataPath::snapshot()))?
.clone();
+
+ /////////////////////////////////////////
+ // https://theupdateframework.github.io/specification/v1.0.30/#update-targets:
+ //
+ // 7. **Perform a pre-order depth-first search for metadata about the
+ // desired target, beginning with the top-level targets role.** Note: If
+ // any metadata requested in steps 5.6.7.1 - 5.6.7.2 cannot be downloaded nor
+ // validated, end the search and report that the target cannot be found.
+
let (_, target_description) = self
- .lookup_target_description(false, 0, target, &snapshot, None)
+ .lookup_target_description(start_time, false, 0, target, &snapshot, None)
.await;
+
target_description
}
async fn lookup_target_description(
&mut self,
+ start_time: &DateTime<Utc>,
default_terminate: bool,
current_depth: u32,
target: &TargetPath,
@@ -879,11 +972,11 @@
let (targets, targets_role) = match targets {
Some((t, role)) => (t.clone(), role),
None => match self.tuf.trusted_targets() {
- Some(t) => (t.clone(), MetadataPath::from_role(&Role::Targets)),
+ Some(t) => (t.clone(), MetadataPath::targets()),
None => {
return (
default_terminate,
- Err(Error::MissingMetadata(Role::Targets)),
+ Err(Error::MissingMetadata(MetadataPath::targets())),
);
}
},
@@ -960,10 +1053,12 @@
}
};
- match self
- .tuf
- .update_delegation(&targets_role, delegation.role(), &raw_signed_meta)
- {
+ match self.tuf.update_delegated_targets(
+ start_time,
+ &targets_role,
+ delegation.role(),
+ &raw_signed_meta,
+ ) {
Ok(_) => {
/////////////////////////////////////////
// TUF-1.0.9 §5.4.4:
@@ -994,6 +1089,7 @@
.clone();
let f: Pin<Box<dyn Future<Output = _>>> =
Box::pin(self.lookup_target_description(
+ start_time,
delegation.terminating(),
current_depth + 1,
target,
@@ -1416,10 +1512,7 @@
MetadataVersion::Number(1),
metadata1.root().unwrap()
),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(2)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(2)),
],
);
}
@@ -1427,7 +1520,7 @@
assert_eq!(
client.local_repo().take_tracks(),
vec![Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
+ MetadataPath::root(),
MetadataVersion::Number(2)
)],
);
@@ -1440,10 +1533,7 @@
MetadataVersion::Number(1),
metadata1.root().unwrap()
),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(2)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(2)),
],
);
}
@@ -1451,7 +1541,7 @@
assert_eq!(
client.local_repo().take_tracks(),
vec![Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
+ MetadataPath::root(),
MetadataVersion::Number(2)
)],
);
@@ -1467,10 +1557,7 @@
client.remote_repo().take_tracks(),
vec![
Track::fetch_meta_found(MetadataVersion::Number(2), metadata2.root().unwrap()),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(3)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(3)),
Track::fetch_meta_found(MetadataVersion::None, metadata2.timestamp().unwrap()),
Track::fetch_meta_found(MetadataVersion::Number(2), metadata2.snapshot().unwrap()),
Track::fetch_meta_found(MetadataVersion::Number(2), metadata2.targets().unwrap()),
@@ -1495,10 +1582,7 @@
assert_eq!(
client.remote_repo().take_tracks(),
vec![
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(3)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(3)),
Track::fetch_meta_found(MetadataVersion::None, metadata2.timestamp().unwrap()),
]
);
@@ -1549,14 +1633,8 @@
assert_eq!(
client.local_repo().take_tracks(),
vec![
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(2)
- ),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None
- )
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(2)),
+ Track::FetchErr(MetadataPath::timestamp(), MetadataVersion::None)
],
);
@@ -1588,10 +1666,7 @@
client.remote_repo().take_tracks(),
vec![
Track::fetch_meta_found(MetadataVersion::Number(2), metadata2.root().unwrap()),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(3)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(3)),
Track::fetch_meta_found(MetadataVersion::None, metadata2.timestamp().unwrap()),
Track::fetch_meta_found(
MetadataVersion::Number(2),
@@ -1683,10 +1758,7 @@
client.local_repo().take_tracks(),
vec![
Track::fetch_meta_found(MetadataVersion::Number(2), metadata2.root().unwrap()),
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(3)
- )
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(3))
],
);
@@ -1728,7 +1800,7 @@
local
.store_metadata(
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
&mut junk_timestamp.as_bytes(),
)
@@ -1769,12 +1841,9 @@
assert_eq!(
client.local_repo().take_tracks(),
vec![
- Track::FetchErr(
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(2)
- ),
+ Track::FetchErr(MetadataPath::root(), MetadataVersion::Number(2)),
Track::FetchFound {
- path: MetadataPath::from_role(&Role::Timestamp),
+ path: MetadataPath::timestamp(),
version: MetadataVersion::None,
metadata: junk_timestamp.into(),
},
@@ -1815,8 +1884,8 @@
.await
.unwrap();
- let root_path = MetadataPath::from_role(&Role::Root);
- let timestamp_path = MetadataPath::from_role(&Role::Timestamp);
+ let root_path = MetadataPath::root();
+ let timestamp_path = MetadataPath::timestamp();
let targets_version;
let snapshot_version;
@@ -2216,7 +2285,7 @@
client
.local_repo_mut()
.store_metadata(
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
&mut metadata2.timestamp().unwrap().as_bytes(),
)
@@ -2226,7 +2295,7 @@
client
.remote_repo_mut()
.store_metadata(
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
&mut metadata2.timestamp().unwrap().as_bytes(),
)
@@ -2241,7 +2310,7 @@
×tamp2,
&fetch_metadata_to_string(
client.local_repo(),
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
)
.await
@@ -2252,7 +2321,7 @@
×tamp2,
&fetch_metadata_to_string(
client.remote_repo(),
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
)
.await
@@ -2282,7 +2351,7 @@
.unwrap();
repo.store_metadata(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::Number(1),
&mut root.as_bytes(),
)
@@ -2296,7 +2365,7 @@
.unwrap();
repo.store_metadata(
- &MetadataPath::from_role(&Role::Targets),
+ &MetadataPath::targets(),
MetadataVersion::Number(1),
&mut targets.as_bytes(),
)
@@ -2308,17 +2377,14 @@
let targets_description = MetadataDescription::new(1, None, HashMap::new()).unwrap();
let snapshot = SnapshotMetadataBuilder::new()
- .insert_metadata_description(
- MetadataPath::from_role(&Role::Targets),
- targets_description,
- )
+ .insert_metadata_description(MetadataPath::targets(), targets_description)
.signed::<Json>(&KEYS[2])
.unwrap()
.to_raw()
.unwrap();
repo.store_metadata(
- &MetadataPath::from_role(&Role::Snapshot),
+ &MetadataPath::snapshot(),
MetadataVersion::Number(1),
&mut snapshot.as_bytes(),
)
@@ -2337,7 +2403,7 @@
.unwrap();
repo.store_metadata(
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
&mut timestamp.as_bytes(),
)
diff --git a/third_party/rust_crates/vendor/tuf/src/database.rs b/third_party/rust_crates/vendor/tuf/src/database.rs
index c90095d..e493664 100644
--- a/third_party/rust_crates/vendor/tuf/src/database.rs
+++ b/third_party/rust_crates/vendor/tuf/src/database.rs
@@ -1,6 +1,6 @@
//! Components needed to verify TUF metadata and targets.
-use chrono::offset::Utc;
+use chrono::{offset::Utc, DateTime};
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::marker::PhantomData;
@@ -9,9 +9,8 @@
use crate::error::Error;
use crate::interchange::DataInterchange;
use crate::metadata::{
- Delegations, Metadata, MetadataPath, RawSignedMetadata, RawSignedMetadataSet, Role,
- RootMetadata, SnapshotMetadata, TargetDescription, TargetPath, TargetsMetadata,
- TimestampMetadata,
+ Delegations, Metadata, MetadataPath, RawSignedMetadata, RawSignedMetadataSet, RootMetadata,
+ SnapshotMetadata, TargetDescription, TargetPath, TargetsMetadata, TimestampMetadata,
};
use crate::verify::{self, Verified};
use crate::Result;
@@ -114,13 +113,33 @@
where
I: IntoIterator<Item = &'a PublicKey>,
{
+ Self::from_metadata_with_trusted_keys_and_start_time(
+ &Utc::now(),
+ metadata_set,
+ root_threshold,
+ root_keys,
+ )
+ }
+
+ /// Create a new [`Database`] struct from a set of metadata that is assumed to be trusted. The
+ /// signed root metadata in the `metadata_set` must be signed with at least a `root_threshold`
+ /// of the provided root_keys. It is not necessary for the root metadata to contain these keys.
+ pub fn from_metadata_with_trusted_keys_and_start_time<'a, I>(
+ start_time: &DateTime<Utc>,
+ metadata_set: &RawSignedMetadataSet<D>,
+ root_threshold: u32,
+ root_keys: I,
+ ) -> Result<Self>
+ where
+ I: IntoIterator<Item = &'a PublicKey>,
+ {
let mut db = if let Some(root) = metadata_set.root() {
Database::from_root_with_trusted_keys(root, root_threshold, root_keys)?
} else {
- return Err(Error::MissingMetadata(Role::Root));
+ return Err(Error::MissingMetadata(MetadataPath::root()));
};
- db.update_metadata_after_root(metadata_set)?;
+ db.update_metadata_after_root(start_time, metadata_set)?;
Ok(db)
}
@@ -133,13 +152,27 @@
/// signed properly. This exposes us to potential parser exploits. This method should only be
/// used if the metadata is loaded from a trusted source.
pub fn from_trusted_metadata(metadata_set: &RawSignedMetadataSet<D>) -> Result<Self> {
+ Self::from_trusted_metadata_with_start_time(metadata_set, &Utc::now())
+ }
+
+ /// Create a new [`Database`] struct from a set of metadata that is assumed to be trusted.
+ ///
+ /// **WARNING**: This is trust-on-first-use (TOFU) and offers weaker security guarantees than
+ /// the related method [`Database::from_metadata_with_trusted_keys`] because this method needs
+ /// to deserialize the root metadata from `metadata_set` before we have verified it has been
+ /// signed properly. This exposes us to potential parser exploits. This method should only be
+ /// used if the metadata is loaded from a trusted source.
+ pub fn from_trusted_metadata_with_start_time(
+ metadata_set: &RawSignedMetadataSet<D>,
+ start_time: &DateTime<Utc>,
+ ) -> Result<Self> {
let mut db = if let Some(root) = metadata_set.root() {
Database::from_trusted_root(root)?
} else {
- return Err(Error::MissingMetadata(Role::Root));
+ return Err(Error::MissingMetadata(MetadataPath::root()));
};
- db.update_metadata_after_root(metadata_set)?;
+ db.update_metadata_after_root(start_time, metadata_set)?;
Ok(db)
}
@@ -169,36 +202,17 @@
&self.trusted_delegations
}
- fn trusted_timestamp_version(&self) -> u32 {
- self.trusted_timestamp
- .as_ref()
- .map(|t| t.version())
- .unwrap_or(0)
- }
-
- fn trusted_snapshot_version(&self) -> u32 {
- self.trusted_snapshot
- .as_ref()
- .map(|t| t.version())
- .unwrap_or(0)
- }
-
- fn trusted_targets_version(&self) -> u32 {
- self.trusted_targets
- .as_ref()
- .map(|t| t.version())
- .unwrap_or(0)
- }
-
- fn trusted_delegation_version(&self, role: &MetadataPath) -> u32 {
- self.trusted_delegations
- .get(role)
- .map(|t| t.version())
- .unwrap_or(0)
+ /// Verify and update metadata. Returns true if any of the metadata was updated.
+ pub fn update_metadata(&mut self, metadata: &RawSignedMetadataSet<D>) -> Result<bool> {
+ self.update_metadata_with_start_time(metadata, &Utc::now())
}
/// Verify and update metadata. Returns true if any of the metadata was updated.
- pub fn update_metadata(&mut self, metadata: &RawSignedMetadataSet<D>) -> Result<bool> {
+ pub fn update_metadata_with_start_time(
+ &mut self,
+ metadata: &RawSignedMetadataSet<D>,
+ start_time: &DateTime<Utc>,
+ ) -> Result<bool> {
let updated = if let Some(root) = metadata.root() {
self.update_root(root)?;
true
@@ -206,7 +220,7 @@
false
};
- if self.update_metadata_after_root(metadata)? {
+ if self.update_metadata_after_root(start_time, metadata)? {
Ok(true)
} else {
Ok(updated)
@@ -215,23 +229,24 @@
fn update_metadata_after_root(
&mut self,
+ start_time: &DateTime<Utc>,
metadata_set: &RawSignedMetadataSet<D>,
) -> Result<bool> {
let mut updated = false;
if let Some(timestamp) = metadata_set.timestamp() {
- if self.update_timestamp(timestamp)?.is_some() {
+ if self.update_timestamp(start_time, timestamp)?.is_some() {
updated = true;
}
}
if let Some(snapshot) = metadata_set.snapshot() {
- if self.update_snapshot(snapshot)? {
+ if self.update_snapshot(start_time, snapshot)? {
updated = true;
}
}
if let Some(targets) = metadata_set.targets() {
- if self.update_targets(targets)? {
+ if self.update_targets(start_time, targets)? {
updated = true;
}
}
@@ -338,6 +353,7 @@
/// Returns a reference to the parsed metadata if the metadata was newer.
pub fn update_timestamp(
&mut self,
+ start_time: &DateTime<Utc>,
raw_timestamp: &RawSignedMetadata<D, TimestampMetadata>,
) -> Result<Option<&Verified<TimestampMetadata>>> {
let verified = {
@@ -371,20 +387,20 @@
// new timestamp metadata file is older than the trusted timestamp metadata file,
// discard it, abort the update cycle, and report the potential rollback attack.
- let trusted_timestamp_version = self.trusted_timestamp_version();
-
- match new_timestamp.version().cmp(&trusted_timestamp_version) {
- Ordering::Less => {
- return Err(Error::VerificationFailure(format!(
- "Attempted to roll back timestamp metadata at version {} to {}.",
- trusted_timestamp_version,
- new_timestamp.version()
- )));
+ if let Some(trusted_timestamp) = &self.trusted_timestamp {
+ match new_timestamp.version().cmp(&trusted_timestamp.version()) {
+ Ordering::Less => {
+ return Err(Error::VerificationFailure(format!(
+ "Attempted to roll back timestamp metadata at version {} to {}.",
+ trusted_timestamp.version(),
+ new_timestamp.version()
+ )));
+ }
+ Ordering::Equal => {
+ return Ok(None);
+ }
+ Ordering::Greater => {}
}
- Ordering::Equal => {
- return Ok(None);
- }
- Ordering::Greater => {}
}
/////////////////////////////////////////
@@ -401,8 +417,10 @@
// FIXME(#297): forgetting the trusted snapshot here is not part of the spec. Do we need to
// do it?
- if self.trusted_snapshot_version() != new_timestamp.snapshot().version() {
- self.trusted_snapshot = None;
+ if let Some(trusted_snapshot) = &self.trusted_snapshot {
+ if trusted_snapshot.version() != new_timestamp.snapshot().version() {
+ self.trusted_snapshot = None;
+ }
}
/////////////////////////////////////////
@@ -414,8 +432,8 @@
// timestamp metadata file has expired, discard it, abort the update cycle, and
// report the potential freeze attack.
- if new_timestamp.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Timestamp));
+ if new_timestamp.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(MetadataPath::timestamp()));
}
new_timestamp
@@ -428,32 +446,34 @@
/// Verify and update the snapshot metadata.
pub fn update_snapshot(
&mut self,
+ start_time: &DateTime<Utc>,
raw_snapshot: &RawSignedMetadata<D, SnapshotMetadata>,
) -> Result<bool> {
let verified = {
/////////////////////////////////////////
// FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
// this metadata expired isn't part of the spec. Do we actually want to do this?
- let trusted_root = self.trusted_root_unexpired()?;
- let trusted_timestamp = self.trusted_timestamp_unexpired()?;
- let trusted_snapshot_version = self.trusted_snapshot_version();
+ let trusted_root = self.trusted_root_unexpired(start_time)?;
+ let trusted_timestamp = self.trusted_timestamp_unexpired(start_time)?;
- match trusted_timestamp
- .snapshot()
- .version()
- .cmp(&trusted_snapshot_version)
- {
- Ordering::Less => {
- return Err(Error::VerificationFailure(format!(
- "Attempted to roll back snapshot metadata at version {} to {}.",
- trusted_snapshot_version,
- trusted_timestamp.snapshot().version()
- )));
+ if let Some(trusted_snapshot) = &self.trusted_snapshot {
+ match trusted_timestamp
+ .snapshot()
+ .version()
+ .cmp(&trusted_snapshot.version())
+ {
+ Ordering::Less => {
+ return Err(Error::VerificationFailure(format!(
+ "Attempted to roll back snapshot metadata at version {} to {}.",
+ trusted_snapshot.version(),
+ trusted_timestamp.snapshot().version()
+ )));
+ }
+ Ordering::Equal => {
+ return Ok(false);
+ }
+ Ordering::Greater => {}
}
- Ordering::Equal => {
- return Ok(false);
- }
- Ordering::Greater => {}
}
/////////////////////////////////////////
@@ -511,12 +531,14 @@
// new snapshot metadata file is older than the trusted metadata file, discard it,
// abort the update cycle, and report the potential rollback attack.
- if new_snapshot.version() < trusted_snapshot_version {
- return Err(Error::VerificationFailure(format!(
- "Attempted to roll back snapshot metadata at version {} to {}",
- trusted_snapshot_version,
- new_snapshot.version(),
- )));
+ if let Some(trusted_snapshot) = &self.trusted_snapshot {
+ if new_snapshot.version() < trusted_snapshot.version() {
+ return Err(Error::VerificationFailure(format!(
+ "Attempted to roll back snapshot metadata at version {} to {}",
+ trusted_snapshot.version(),
+ new_snapshot.version(),
+ )));
+ }
}
/////////////////////////////////////////
@@ -557,7 +579,7 @@
.unwrap_or(0)
!= verified
.meta()
- .get(&MetadataPath::from_role(&Role::Targets))
+ .get(&MetadataPath::targets())
.map(|m| m.version())
.unwrap_or(0)
{
@@ -602,106 +624,183 @@
/// Verify and update the targets metadata.
pub fn update_targets(
&mut self,
+ start_time: &DateTime<Utc>,
raw_targets: &RawSignedMetadata<D, TargetsMetadata>,
) -> Result<bool> {
let verified = {
// FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
// this metadata expired isn't part of the spec. Do we actually want to do this?
- let trusted_root = self.trusted_root_unexpired()?;
- let trusted_snapshot = self.trusted_snapshot_unexpired()?;
+ let trusted_root = self.trusted_root_unexpired(start_time)?;
+ let trusted_targets_version = self.trusted_targets.as_ref().map(|t| t.version());
- // FIXME(#295): TUF-1.0.5 §5.3.3.2 says this check should be done when updating the
- // snapshot, not here.
- let trusted_targets_description = trusted_snapshot
- .meta()
- .get(&MetadataPath::from_role(&Role::Targets))
+ self.verify_target_or_delegated_target(
+ start_time,
+ &MetadataPath::targets(),
+ raw_targets,
+ trusted_root.targets().threshold(),
+ trusted_root.targets_keys(),
+ trusted_targets_version,
+ )?
+ };
+
+ if let Some(verified) = verified {
+ self.trusted_targets = Some(verified);
+ Ok(true)
+ } else {
+ Ok(false)
+ }
+ }
+
+ /// Verify and update a delegation metadata.
+ pub fn update_delegated_targets(
+ &mut self,
+ start_time: &DateTime<Utc>,
+ parent_role: &MetadataPath,
+ role: &MetadataPath,
+ raw_delegated_targets: &RawSignedMetadata<D, TargetsMetadata>,
+ ) -> Result<bool> {
+ let verified = {
+ // FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
+ // this metadata expired isn't part of the spec. Do we actually want to do this?
+ let _ = self.trusted_root_unexpired(start_time)?;
+ let _ = self.trusted_snapshot_unexpired(start_time)?;
+ let trusted_targets = self.trusted_targets_unexpired(start_time)?;
+
+ if trusted_targets.delegations().is_none() {
+ return Err(Error::VerificationFailure(
+ "Delegations not authorized".into(),
+ ));
+ };
+
+ let (threshold, keys) = self
+ .find_delegation_threshold_and_keys(parent_role, role)?
.ok_or_else(|| {
- Error::VerificationFailure(
- "Snapshot metadata had no description of the targets metadata".into(),
- )
+ Error::VerificationFailure(format!(
+ "The delegated targets role {:?} is not known to the delegating targets role {}",
+ role, parent_role,
+ ))
})?;
- let trusted_targets_version = self.trusted_targets_version();
+ let trusted_delegated_targets_version =
+ self.trusted_delegations.get(role).map(|t| t.version());
- match trusted_targets_description
- .version()
- .cmp(&trusted_targets_version)
- {
+ self.verify_target_or_delegated_target(
+ start_time,
+ role,
+ raw_delegated_targets,
+ threshold,
+ keys.into_iter(),
+ trusted_delegated_targets_version,
+ )?
+ };
+
+ if let Some(verified) = verified {
+ let _ = self.trusted_delegations.insert(role.clone(), verified);
+ Ok(true)
+ } else {
+ Ok(false)
+ }
+ }
+
+ fn verify_target_or_delegated_target<'a>(
+ &self,
+ start_time: &DateTime<Utc>,
+ role: &MetadataPath,
+ raw_targets: &RawSignedMetadata<D, TargetsMetadata>,
+ trusted_targets_threshold: u32,
+ trusted_targets_keys: impl Iterator<Item = &'a PublicKey>,
+ trusted_targets_version: Option<u32>,
+ ) -> Result<Option<Verified<TargetsMetadata>>> {
+ // FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
+ // this metadata expired isn't part of the spec. Do we actually want to do this?
+ let trusted_snapshot = self.trusted_snapshot_unexpired(start_time)?;
+
+ let trusted_targets_description = trusted_snapshot.meta().get(role).ok_or_else(|| {
+ Error::VerificationFailure(format!(
+ "Snapshot metadata had no description of the {} metadata",
+ role
+ ))
+ })?;
+
+ /////////////////////////////////////////
+ // TUF-1.0.5 §5.4.1:
+ //
+ // Check against snapshot metadata. The hashes and version number of the new
+ // targets metadata file MUST match the hashes (if any) and version number listed
+ // in the trusted snapshot metadata. This is done, in part, to prevent a
+ // mix-and-match attack by man-in-the-middle attackers. If the new targets metadata
+ // file does not match, discard it, abort the update cycle, and report the failure.
+
+ // FIXME: rust-tuf checks the hash during download, but it would be better if we
+ // checked the hash here to make it easier to validate we've correctly implemented the
+ // spec.
+
+ // NOTE(https://github.com/theupdateframework/specification/pull/112): Technically
+ // we're supposed to check the version before checking the signature, but we do it
+ // afterwards. That PR proposes formally moving the version check to after signature
+ // verification.
+
+ /////////////////////////////////////////
+ // TUF-1.0.5 §5.4.2:
+ //
+ // Check for an arbitrary software attack. The new targets metadata file MUST have
+ // been signed by a threshold of keys specified in the trusted root metadata file.
+ // If the new targets metadata file is not signed as required, discard it, abort
+ // the update cycle, and report the failure.
+
+ let new_targets = verify::verify_signatures(
+ raw_targets,
+ trusted_targets_threshold,
+ trusted_targets_keys,
+ )?;
+
+ /////////////////////////////////////////
+ // FIXME(https://github.com/theupdateframework/specification/pull/112): Actually check
+ // the version.
+
+ // FIXME(#295): TUF-1.0.5 §5.3.3.2 says this check should be done when updating the
+ // snapshot, not here.
+ if new_targets.version() != trusted_targets_description.version() {
+ return Err(Error::VerificationFailure(format!(
+ "The snapshot metadata reported that the {} metadata should be at \
+ version {} but version {} was found instead.",
+ role,
+ trusted_targets_description.version(),
+ new_targets.version()
+ )));
+ }
+
+ if let Some(trusted_targets_version) = trusted_targets_version {
+ match new_targets.version().cmp(&trusted_targets_version) {
Ordering::Less => {
return Err(Error::VerificationFailure(format!(
- "Attempted to roll back targets metadata at version {} to {}.",
+ "Attempted to roll back {} metadata at version {} to {}.",
+ role,
trusted_targets_version,
trusted_targets_description.version()
)));
}
Ordering::Equal => {
- return Ok(false);
+ return Ok(None);
}
Ordering::Greater => {}
}
+ }
- /////////////////////////////////////////
- // TUF-1.0.5 §5.4.1:
- //
- // Check against snapshot metadata. The hashes and version number of the new
- // targets metadata file MUST match the hashes (if any) and version number listed
- // in the trusted snapshot metadata. This is done, in part, to prevent a
- // mix-and-match attack by man-in-the-middle attackers. If the new targets metadata
- // file does not match, discard it, abort the update cycle, and report the failure.
+ /////////////////////////////////////////
+ // TUF-1.0.5 §5.4.3:
+ //
+ // Check for a freeze attack. The latest known time should be lower than the
+ // expiration timestamp in the new targets metadata file. If so, the new targets
+ // metadata file becomes the trusted targets metadata file. If the new targets
+ // metadata file is expired, discard it, abort the update cycle, and report the
+ // potential freeze attack.
- // FIXME: rust-tuf checks the hash during download, but it would be better if we
- // checked the hash here to make it easier to validate we've correctly implemented the
- // spec.
+ if new_targets.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(role.clone()));
+ }
- // NOTE(https://github.com/theupdateframework/specification/pull/112): Technically
- // we're supposed to check the version before checking the signature, but we do it
- // afterwards. That PR proposes formally moving the version check to after signature
- // verification.
-
- /////////////////////////////////////////
- // TUF-1.0.5 §5.4.2:
- //
- // Check for an arbitrary software attack. The new targets metadata file MUST have
- // been signed by a threshold of keys specified in the trusted root metadata file.
- // If the new targets metadata file is not signed as required, discard it, abort
- // the update cycle, and report the failure.
-
- let new_targets = verify::verify_signatures(
- raw_targets,
- trusted_root.targets().threshold(),
- trusted_root.targets_keys(),
- )?;
-
- /////////////////////////////////////////
- // FIXME(https://github.com/theupdateframework/specification/pull/112): Actually check
- // the version.
-
- if new_targets.version() != trusted_targets_description.version() {
- return Err(Error::VerificationFailure(format!(
- "The timestamp metadata reported that the targets metadata should be at \
- version {} but version {} was found instead.",
- trusted_targets_description.version(),
- new_targets.version()
- )));
- }
-
- /////////////////////////////////////////
- // TUF-1.0.5 §5.4.3:
- //
- // Check for a freeze attack. The latest known time should be lower than the
- // expiration timestamp in the new targets metadata file. If so, the new targets
- // metadata file becomes the trusted targets metadata file. If the new targets
- // metadata file is expired, discard it, abort the update cycle, and report the
- // potential freeze attack.
- if new_targets.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Snapshot));
- }
-
- new_targets
- };
-
- self.trusted_targets = Some(verified);
- Ok(true)
+ Ok(Some(new_targets))
}
/// Find the signing keys and metadata for the delegation given by `role`, as seen from the
@@ -710,20 +809,24 @@
&self,
parent_role: &MetadataPath,
role: &MetadataPath,
- ) -> Option<(u32, Vec<&PublicKey>)> {
+ ) -> Result<Option<(u32, Vec<&PublicKey>)>> {
// Find the parent TargetsMetadata that is expected to refer to `role`.
- let trusted_parent = {
- if parent_role == &MetadataPath::from_role(&Role::Targets) {
- self.trusted_targets()?
+ let trusted_parent = if parent_role == &MetadataPath::targets() {
+ if let Some(trusted_targets) = self.trusted_targets() {
+ trusted_targets
} else {
- self.trusted_delegations.get(parent_role)?
+ return Err(Error::MissingMetadata(parent_role.clone()));
}
+ } else if let Some(trusted_parent) = self.trusted_delegations.get(parent_role) {
+ trusted_parent
+ } else {
+ return Err(Error::MissingMetadata(parent_role.clone()));
};
// Only consider targets metadata that define delegations.
let trusted_delegations = match trusted_parent.delegations() {
Some(d) => d,
- None => return None,
+ None => return Ok(None),
};
for trusted_delegation in trusted_delegations.roles() {
@@ -744,103 +847,10 @@
})
.collect();
- return Some((trusted_delegation.threshold(), authorized_keys));
+ return Ok(Some((trusted_delegation.threshold(), authorized_keys)));
}
- None
- }
-
- /// Verify and update a delegation metadata.
- pub fn update_delegation(
- &mut self,
- parent_role: &MetadataPath,
- role: &MetadataPath,
- raw_delegation: &RawSignedMetadata<D, TargetsMetadata>,
- ) -> Result<bool> {
- let verified = {
- // FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
- // this metadata expired isn't part of the spec. Do we actually want to do this?
- let _ = self.trusted_root_unexpired()?;
- let trusted_snapshot = self.trusted_snapshot_unexpired()?;
- let trusted_targets = self.trusted_targets_unexpired()?;
-
- if trusted_targets.delegations().is_none() {
- return Err(Error::VerificationFailure(
- "Delegations not authorized".into(),
- ));
- };
-
- let trusted_delegation_description = match trusted_snapshot.meta().get(role) {
- Some(d) => d,
- None => {
- return Err(Error::VerificationFailure(format!(
- "The degated role {:?} was not present in the snapshot metadata.",
- role
- )));
- }
- };
-
- let trusted_delegation_version = self.trusted_delegation_version(role);
-
- if trusted_delegation_description.version() < trusted_delegation_version {
- return Err(Error::VerificationFailure(format!(
- "Snapshot metadata did listed delegation {:?} version as {} but current\
- version is {}",
- role,
- trusted_delegation_description.version(),
- trusted_delegation_version
- )));
- }
-
- // FIXME(#279) update_delegation trusts tuf::Client to provide too much information,
- // making this difficult to verify as correct.
-
- /////////////////////////////////////////
- // TUF-1.0.5 §5.4.1:
- //
- // Check against snapshot metadata. The hashes and version number of the new
- // targets metadata file MUST match the hashes (if any) and version number listed
- // in the trusted snapshot metadata. This is done, in part, to prevent a
- // mix-and-match attack by man-in-the-middle attackers. If the new targets metadata
- // file does not match, discard it, abort the update cycle, and report the failure.
-
- let (threshold, keys) = self
- .find_delegation_threshold_and_keys(parent_role, role)
- .ok_or_else(|| {
- Error::VerificationFailure(format!(
- "The delegated role {:?} is not known to the base \
- targets metadata or any known delegated targets metadata",
- role
- ))
- })?;
-
- let new_delegation = verify::verify_signatures(raw_delegation, threshold, keys)?;
-
- if trusted_delegation_version == trusted_delegation_description.version() {
- return Ok(false);
- }
-
- if new_delegation.version() != trusted_delegation_description.version() {
- return Err(Error::VerificationFailure(format!(
- "The snapshot metadata reported that the delegation {:?} should be at \
- version {} but version {} was found instead.",
- role,
- trusted_delegation_description.version(),
- new_delegation.version(),
- )));
- }
-
- if new_delegation.expires() <= &Utc::now() {
- // TODO this needs to be chagned to accept a MetadataPath and not Role
- return Err(Error::ExpiredMetadata(Role::Targets));
- }
-
- new_delegation
- };
-
- let _ = self.trusted_delegations.insert(role.clone(), verified);
-
- Ok(true)
+ Ok(None)
}
/// Get a reference to the description needed to verify the target defined by the given
@@ -848,15 +858,28 @@
/// metadata. This may mean the target exists somewhere in the metadata, but the chain of trust
/// to that target may be invalid or incomplete.
pub fn target_description(&self, target_path: &TargetPath) -> Result<TargetDescription> {
- let _ = self.trusted_root_unexpired()?;
- let _ = self.trusted_snapshot_unexpired()?;
- let targets = self.trusted_targets_unexpired()?;
+ self.target_description_with_start_time(&Utc::now(), target_path)
+ }
+
+ /// Get a reference to the description needed to verify the target defined by the given
+ /// `TargetPath`. Returns an `Error` if the target is not defined in the trusted
+ /// metadata. This may mean the target exists somewhere in the metadata, but the chain of trust
+ /// to that target may be invalid or incomplete.
+ pub fn target_description_with_start_time(
+ &self,
+ start_time: &DateTime<Utc>,
+ target_path: &TargetPath,
+ ) -> Result<TargetDescription> {
+ let _ = self.trusted_root_unexpired(start_time)?;
+ let _ = self.trusted_snapshot_unexpired(start_time)?;
+ let targets = self.trusted_targets_unexpired(start_time)?;
if let Some(d) = targets.targets().get(target_path) {
return Ok(d.clone());
}
fn lookup<D: DataInterchange>(
+ start_time: &DateTime<Utc>,
tuf: &Database<D>,
default_terminate: bool,
current_depth: u32,
@@ -883,7 +906,7 @@
None => return (delegation.terminating(), None),
};
- if trusted_delegation.expires() <= &Utc::now() {
+ if trusted_delegation.expires() <= start_time {
return (delegation.terminating(), None);
}
@@ -895,6 +918,7 @@
let mut new_parents = parents.to_vec();
new_parents.push(delegation.paths().clone());
let (term, res) = lookup(
+ start_time,
tuf,
delegation.terminating(),
current_depth + 1,
@@ -916,9 +940,18 @@
match targets.delegations() {
Some(d) => {
let mut visited = HashSet::new();
- lookup(self, false, 0, target_path, d, &[], &mut visited)
- .1
- .ok_or(Error::TargetUnavailable)
+ lookup(
+ start_time,
+ self,
+ false,
+ 0,
+ target_path,
+ d,
+ &[],
+ &mut visited,
+ )
+ .1
+ .ok_or(Error::TargetUnavailable)
}
None => Err(Error::TargetUnavailable),
}
@@ -931,46 +964,50 @@
self.trusted_delegations.clear();
}
- fn trusted_root_unexpired(&self) -> Result<&RootMetadata> {
+ fn trusted_root_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&RootMetadata> {
let trusted_root = &self.trusted_root;
- if trusted_root.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Root));
+ if trusted_root.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(MetadataPath::root()));
}
Ok(trusted_root)
}
- fn trusted_snapshot_unexpired(&self) -> Result<&SnapshotMetadata> {
- match self.trusted_snapshot {
- Some(ref trusted_snapshot) => {
- if trusted_snapshot.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Snapshot));
- }
- Ok(trusted_snapshot)
- }
- None => Err(Error::MissingMetadata(Role::Snapshot)),
- }
- }
-
- fn trusted_targets_unexpired(&self) -> Result<&TargetsMetadata> {
- match self.trusted_targets {
- Some(ref trusted_targets) => {
- if trusted_targets.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Targets));
- }
- Ok(trusted_targets)
- }
- None => Err(Error::MissingMetadata(Role::Targets)),
- }
- }
- fn trusted_timestamp_unexpired(&self) -> Result<&TimestampMetadata> {
+ fn trusted_timestamp_unexpired(
+ &self,
+ start_time: &DateTime<Utc>,
+ ) -> Result<&TimestampMetadata> {
match self.trusted_timestamp {
Some(ref trusted_timestamp) => {
- if trusted_timestamp.expires() <= &Utc::now() {
- return Err(Error::ExpiredMetadata(Role::Timestamp));
+ if trusted_timestamp.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(MetadataPath::timestamp()));
}
Ok(trusted_timestamp)
}
- None => Err(Error::MissingMetadata(Role::Timestamp)),
+ None => Err(Error::MissingMetadata(MetadataPath::timestamp())),
+ }
+ }
+
+ fn trusted_snapshot_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&SnapshotMetadata> {
+ match self.trusted_snapshot {
+ Some(ref trusted_snapshot) => {
+ if trusted_snapshot.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(MetadataPath::snapshot()));
+ }
+ Ok(trusted_snapshot)
+ }
+ None => Err(Error::MissingMetadata(MetadataPath::snapshot())),
+ }
+ }
+
+ fn trusted_targets_unexpired(&self, start_time: &DateTime<Utc>) -> Result<&TargetsMetadata> {
+ match self.trusted_targets {
+ Some(ref trusted_targets) => {
+ if trusted_targets.expires() <= start_time {
+ return Err(Error::ExpiredMetadata(MetadataPath::targets()));
+ }
+ Ok(trusted_targets)
+ }
+ None => Err(Error::MissingMetadata(MetadataPath::targets())),
}
}
}
@@ -1180,6 +1217,8 @@
#[test]
fn good_timestamp_update() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1204,16 +1243,18 @@
let raw_timestamp = timestamp.to_raw().unwrap();
assert_matches!(
- tuf.update_timestamp(&raw_timestamp),
+ tuf.update_timestamp(&now, &raw_timestamp),
Ok(Some(_parsed_timestamp))
);
// second update should do nothing
- assert_matches!(tuf.update_timestamp(&raw_timestamp), Ok(None))
+ assert_matches!(tuf.update_timestamp(&now, &raw_timestamp), Ok(None))
}
#[test]
fn bad_timestamp_update_wrong_key() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1239,11 +1280,13 @@
.to_raw()
.unwrap();
- assert!(tuf.update_timestamp(&raw_timestamp).is_err())
+ assert!(tuf.update_timestamp(&now, &raw_timestamp).is_err())
}
#[test]
fn good_snapshot_update() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1267,16 +1310,18 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
- assert_matches!(tuf.update_snapshot(&raw_snapshot), Ok(true));
+ assert_matches!(tuf.update_snapshot(&now, &raw_snapshot), Ok(true));
// second update should do nothing
- assert_matches!(tuf.update_snapshot(&raw_snapshot), Ok(false));
+ assert_matches!(tuf.update_snapshot(&now, &raw_snapshot), Ok(false));
}
#[test]
fn bad_snapshot_update_wrong_key() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1303,13 +1348,15 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
- assert!(tuf.update_snapshot(&raw_snapshot).is_err());
+ assert!(tuf.update_snapshot(&now, &raw_snapshot).is_err());
}
#[test]
fn bad_snapshot_update_wrong_version() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1335,7 +1382,7 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
let raw_snapshot = SnapshotMetadataBuilder::new()
.version(1)
@@ -1344,11 +1391,13 @@
.to_raw()
.unwrap();
- assert!(tuf.update_snapshot(&raw_snapshot).is_err());
+ assert!(tuf.update_snapshot(&now, &raw_snapshot).is_err());
}
#[test]
fn good_targets_update() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1381,17 +1430,19 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
- tuf.update_snapshot(&raw_snapshot).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
+ tuf.update_snapshot(&now, &raw_snapshot).unwrap();
- assert_matches!(tuf.update_targets(&raw_targets), Ok(true));
+ assert_matches!(tuf.update_targets(&now, &raw_targets), Ok(true));
// second update should do nothing
- assert_matches!(tuf.update_targets(&raw_targets), Ok(false));
+ assert_matches!(tuf.update_targets(&now, &raw_targets), Ok(false));
}
#[test]
fn bad_targets_update_wrong_key() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1425,14 +1476,16 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
- tuf.update_snapshot(&raw_snapshot).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
+ tuf.update_snapshot(&now, &raw_snapshot).unwrap();
- assert!(tuf.update_targets(&raw_targets).is_err());
+ assert!(tuf.update_targets(&now, &raw_targets).is_err());
}
#[test]
fn bad_targets_update_wrong_version() {
+ let now = Utc::now();
+
let raw_root = RootMetadataBuilder::new()
.root_key(KEYS[0].public().clone())
.snapshot_key(KEYS[1].public().clone())
@@ -1465,8 +1518,8 @@
.to_raw()
.unwrap();
- tuf.update_timestamp(&raw_timestamp).unwrap();
- tuf.update_snapshot(&raw_snapshot).unwrap();
+ tuf.update_timestamp(&now, &raw_timestamp).unwrap();
+ tuf.update_snapshot(&now, &raw_snapshot).unwrap();
let raw_targets = TargetsMetadataBuilder::new()
.version(1)
@@ -1475,7 +1528,7 @@
.to_raw()
.unwrap();
- assert!(tuf.update_targets(&raw_targets).is_err());
+ assert!(tuf.update_targets(&now, &raw_targets).is_err());
}
#[test]
diff --git a/third_party/rust_crates/vendor/tuf/src/error.rs b/third_party/rust_crates/vendor/tuf/src/error.rs
index d808b7c..1e6b977 100644
--- a/third_party/rust_crates/vendor/tuf/src/error.rs
+++ b/third_party/rust_crates/vendor/tuf/src/error.rs
@@ -9,7 +9,7 @@
use std::path::Path;
use thiserror::Error;
-use crate::metadata::Role;
+use crate::metadata::MetadataPath;
/// Error type for all TUF related errors.
#[non_exhaustive]
@@ -25,7 +25,7 @@
/// Metadata was expired.
#[error("expired {0} metadata")]
- ExpiredMetadata(Role),
+ ExpiredMetadata(MetadataPath),
/// An illegal argument was passed into a function.
#[error("illegal argument: {0}")]
@@ -52,7 +52,7 @@
/// The metadata was missing, so an operation could not be completed.
#[error("missing {0} metadata")]
- MissingMetadata(Role),
+ MissingMetadata(MetadataPath),
/// There were no available hash algorithms.
#[error("no supported hash algorithm")]
diff --git a/third_party/rust_crates/vendor/tuf/src/interchange/cjson/shims.rs b/third_party/rust_crates/vendor/tuf/src/interchange/cjson/shims.rs
index d69e00e..a3f10a2 100644
--- a/third_party/rust_crates/vendor/tuf/src/interchange/cjson/shims.rs
+++ b/third_party/rust_crates/vendor/tuf/src/interchange/cjson/shims.rs
@@ -258,7 +258,7 @@
)));
}
- let s = p.split_at(p.len() - ".json".len()).0;
+ let s = p.split_at(p.len() - ".json".len()).0.to_owned();
let p = metadata::MetadataPath::new(s)?;
Ok((p, d))
diff --git a/third_party/rust_crates/vendor/tuf/src/metadata.rs b/third_party/rust_crates/vendor/tuf/src/metadata.rs
index 14ffae0..d9ae3034 100644
--- a/third_party/rust_crates/vendor/tuf/src/metadata.rs
+++ b/third_party/rust_crates/vendor/tuf/src/metadata.rs
@@ -6,7 +6,7 @@
use serde::de::{Deserialize, DeserializeOwned, Deserializer, Error as DeserializeError};
use serde::ser::{Error as SerializeError, Serialize, Serializer};
use serde_derive::{Deserialize, Serialize};
-use std::borrow::Borrow;
+use std::borrow::{Borrow, Cow};
use std::collections::{HashMap, HashSet};
use std::fmt::{self, Debug, Display};
use std::marker::PhantomData;
@@ -151,12 +151,15 @@
/// The root role.
#[serde(rename = "root")]
Root,
+
/// The snapshot role.
#[serde(rename = "snapshot")]
Snapshot,
+
/// The targets role.
#[serde(rename = "targets")]
Targets,
+
/// The timestamp role.
#[serde(rename = "timestamp")]
Timestamp,
@@ -168,12 +171,12 @@
/// ```
/// use tuf::metadata::{MetadataPath, Role};
///
- /// assert!(Role::Root.fuzzy_matches_path(&MetadataPath::from_role(&Role::Root)));
- /// assert!(Role::Snapshot.fuzzy_matches_path(&MetadataPath::from_role(&Role::Snapshot)));
- /// assert!(Role::Targets.fuzzy_matches_path(&MetadataPath::from_role(&Role::Targets)));
- /// assert!(Role::Timestamp.fuzzy_matches_path(&MetadataPath::from_role(&Role::Timestamp)));
+ /// assert!(Role::Root.fuzzy_matches_path(&MetadataPath::root()));
+ /// assert!(Role::Snapshot.fuzzy_matches_path(&MetadataPath::snapshot()));
+ /// assert!(Role::Targets.fuzzy_matches_path(&MetadataPath::targets()));
+ /// assert!(Role::Timestamp.fuzzy_matches_path(&MetadataPath::timestamp()));
///
- /// assert!(!Role::Root.fuzzy_matches_path(&MetadataPath::from_role(&Role::Snapshot)));
+ /// assert!(!Role::Root.fuzzy_matches_path(&MetadataPath::snapshot()));
/// assert!(!Role::Root.fuzzy_matches_path(&MetadataPath::new("wat").unwrap()));
/// ```
pub fn fuzzy_matches_path(&self, path: &MetadataPath) -> bool {
@@ -182,7 +185,7 @@
Role::Snapshot if &path.0 == "snapshot" => true,
Role::Timestamp if &path.0 == "timestamp" => true,
Role::Targets if &path.0 == "targets" => true,
- Role::Targets if !&["root", "snapshot", "targets"].contains(&path.0.as_str()) => true,
+ Role::Targets if !&["root", "snapshot", "targets"].contains(&path.0.as_ref()) => true,
_ => false,
}
}
@@ -973,9 +976,29 @@
/// let _ = MetadataPath::new("root.json");
/// ```
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
-pub struct MetadataPath(String);
+pub struct MetadataPath(Cow<'static, str>);
impl MetadataPath {
+ /// Create a new `MetadataPath` for the Root role.
+ pub fn root() -> Self {
+ MetadataPath(Role::Root.name().into())
+ }
+
+ /// Create a new `MetadataPath` for the Timestamp role.
+ pub fn timestamp() -> Self {
+ MetadataPath(Role::Timestamp.name().into())
+ }
+
+ /// Create a new `MetadataPath` for the Snapshot role.
+ pub fn snapshot() -> Self {
+ MetadataPath(Role::Snapshot.name().into())
+ }
+
+ /// Create a new `MetadataPath` for the targets role.
+ pub fn targets() -> Self {
+ MetadataPath(Role::Targets.name().into())
+ }
+
/// Create a new `MetadataPath` from a `String`.
///
/// ```
@@ -989,27 +1012,18 @@
/// assert!(MetadataPath::new("foo/..bar").is_ok());
/// assert!(MetadataPath::new("foo/bar..").is_ok());
/// ```
- pub fn new<P: Into<String>>(path: P) -> Result<Self> {
+ pub fn new<P: Into<Cow<'static, str>>>(path: P) -> Result<Self> {
let path = path.into();
- safe_path(&path)?;
- Ok(MetadataPath(path))
- }
-
- /// Create a metadata path from the given role.
- ///
- /// ```
- /// # use tuf::metadata::{Role, MetadataPath};
- /// assert_eq!(MetadataPath::from_role(&Role::Root),
- /// MetadataPath::new("root").unwrap());
- /// assert_eq!(MetadataPath::from_role(&Role::Snapshot),
- /// MetadataPath::new("snapshot").unwrap());
- /// assert_eq!(MetadataPath::from_role(&Role::Targets),
- /// MetadataPath::new("targets").unwrap());
- /// assert_eq!(MetadataPath::from_role(&Role::Timestamp),
- /// MetadataPath::new("timestamp").unwrap());
- /// ```
- pub fn from_role(role: &Role) -> Self {
- Self::new(format!("{}", role)).unwrap()
+ match path.as_ref() {
+ "root" => Ok(MetadataPath::root()),
+ "timestamp" => Ok(MetadataPath::timestamp()),
+ "snapshot" => Ok(MetadataPath::snapshot()),
+ "targets" => Ok(MetadataPath::targets()),
+ _ => {
+ safe_path(&path)?;
+ Ok(MetadataPath(path))
+ }
+ }
}
/// Split `MetadataPath` into components that can be joined to create URL paths, Unix paths, or
@@ -1037,6 +1051,17 @@
}
}
+impl From<Role> for MetadataPath {
+ fn from(role: Role) -> MetadataPath {
+ match role {
+ Role::Root => MetadataPath::root(),
+ Role::Timestamp => MetadataPath::timestamp(),
+ Role::Snapshot => MetadataPath::snapshot(),
+ Role::Targets => MetadataPath::targets(),
+ }
+ }
+}
+
impl Display for MetadataPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&self.0)
@@ -1332,7 +1357,7 @@
hash_algs: &[HashAlgorithm],
) -> Result<Self>
where
- P: Into<String>,
+ P: Into<Cow<'static, str>>,
M: Metadata,
D: DataInterchange,
{
diff --git a/third_party/rust_crates/vendor/tuf/src/repo_builder.rs b/third_party/rust_crates/vendor/tuf/src/repo_builder.rs
index 46ce6d0..0079145 100644
--- a/third_party/rust_crates/vendor/tuf/src/repo_builder.rs
+++ b/third_party/rust_crates/vendor/tuf/src/repo_builder.rs
@@ -7,10 +7,10 @@
interchange::DataInterchange,
metadata::{
Metadata, MetadataDescription, MetadataPath, MetadataVersion, RawSignedMetadata,
- RawSignedMetadataSet, RawSignedMetadataSetBuilder, Role, RootMetadata,
- RootMetadataBuilder, SignedMetadataBuilder, SnapshotMetadata, SnapshotMetadataBuilder,
- TargetDescription, TargetPath, TargetsMetadata, TargetsMetadataBuilder,
- TimestampMetadata, TimestampMetadataBuilder,
+ RawSignedMetadataSet, RawSignedMetadataSetBuilder, RootMetadata, RootMetadataBuilder,
+ SignedMetadataBuilder, SnapshotMetadata, SnapshotMetadataBuilder, TargetDescription,
+ TargetPath, TargetsMetadata, TargetsMetadataBuilder, TimestampMetadata,
+ TimestampMetadataBuilder,
},
repository::RepositoryStorage,
Error, Result,
@@ -707,7 +707,7 @@
} else if let Some(db) = self.ctx.db {
db.trusted_root().consistent_snapshot()
} else {
- return Err(Error::MissingMetadata(Role::Root));
+ return Err(Error::MissingMetadata(MetadataPath::root()));
};
let target_description = TargetDescription::from_reader_with_custom(
@@ -929,10 +929,8 @@
// Overwrite the targets entry if specified.
if let Some(targets_description) = self.state.targets_description()? {
- snapshot_builder = snapshot_builder.insert_metadata_description(
- MetadataPath::from_role(&Role::Targets),
- targets_description,
- );
+ snapshot_builder = snapshot_builder
+ .insert_metadata_description(MetadataPath::targets(), targets_description);
};
let snapshot = f(snapshot_builder).build()?;
@@ -1082,7 +1080,7 @@
.db
.and_then(|db| db.trusted_timestamp())
.map(|timestamp| timestamp.snapshot().clone())
- .ok_or(Error::MissingMetadata(Role::Timestamp))?
+ .ok_or_else(|| Error::MissingMetadata(MetadataPath::timestamp()))?
};
let timestamp_builder = TimestampMetadataBuilder::from_metadata_description(description)
@@ -1213,19 +1211,21 @@
} else if let Some(ref root) = self.state.staged_root {
Database::from_trusted_root(&root.raw)?
} else {
- return Err(Error::MissingMetadata(Role::Root));
+ return Err(Error::MissingMetadata(MetadataPath::root()));
};
+ let now = Utc::now();
+
if let Some(ref timestamp) = self.state.staged_timestamp {
- db.update_timestamp(×tamp.raw)?;
+ db.update_timestamp(&now, ×tamp.raw)?;
}
if let Some(ref snapshot) = self.state.staged_snapshot {
- db.update_snapshot(&snapshot.raw)?;
+ db.update_snapshot(&now, &snapshot.raw)?;
}
if let Some(ref targets) = self.state.staged_targets {
- db.update_targets(&targets.raw)?;
+ db.update_targets(&now, &targets.raw)?;
}
Ok(())
@@ -1236,7 +1236,7 @@
self.ctx
.repo
.store_metadata(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::Number(root.metadata.version()),
&mut root.raw.as_bytes(),
)
@@ -1245,7 +1245,7 @@
self.ctx
.repo
.store_metadata(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::None,
&mut root.raw.as_bytes(),
)
@@ -1255,11 +1255,11 @@
} else if let Some(db) = self.ctx.db {
db.trusted_root().consistent_snapshot()
} else {
- return Err(Error::MissingMetadata(Role::Root));
+ return Err(Error::MissingMetadata(MetadataPath::root()));
};
if let Some(ref targets) = self.state.staged_targets {
- let path = MetadataPath::from_role(&Role::Targets);
+ let path = MetadataPath::targets();
self.ctx
.repo
.store_metadata(&path, MetadataVersion::None, &mut targets.raw.as_bytes())
@@ -1278,7 +1278,7 @@
}
if let Some(ref snapshot) = self.state.staged_snapshot {
- let path = MetadataPath::from_role(&Role::Snapshot);
+ let path = MetadataPath::snapshot();
self.ctx
.repo
.store_metadata(&path, MetadataVersion::None, &mut snapshot.raw.as_bytes())
@@ -1300,7 +1300,7 @@
self.ctx
.repo
.store_metadata(
- &MetadataPath::from_role(&Role::Timestamp),
+ &MetadataPath::timestamp(),
MetadataVersion::None,
&mut timestamp.raw.as_bytes(),
)
@@ -1432,7 +1432,7 @@
};
let snapshot = SnapshotMetadataBuilder::new()
- .insert_metadata_description(MetadataPath::from_role(&Role::Targets), description)
+ .insert_metadata_description(MetadataPath::targets(), description)
.version(version)
.expires(expires)
.build()
@@ -1598,35 +1598,23 @@
// Make sure we stored the metadata correctly.
let mut expected_metadata: BTreeMap<_, _> = vec![
(
- (
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::root(), MetadataVersion::Number(1)),
raw_root1.as_bytes(),
),
(
- (MetadataPath::from_role(&Role::Root), MetadataVersion::None),
+ (MetadataPath::root(), MetadataVersion::None),
raw_root1.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::None,
- ),
+ (MetadataPath::targets(), MetadataVersion::None),
raw_targets1.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::None,
- ),
+ (MetadataPath::snapshot(), MetadataVersion::None),
raw_snapshot1.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
raw_timestamp1.as_bytes(),
),
]
@@ -1636,17 +1624,11 @@
if consistent_snapshot {
expected_metadata.extend(vec![
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::targets(), MetadataVersion::Number(1)),
raw_targets1.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::snapshot(), MetadataVersion::Number(1)),
raw_snapshot1.as_bytes(),
),
]);
@@ -1726,35 +1708,23 @@
// Check that the new metadata was written.
expected_metadata.extend(vec![
(
- (
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(2),
- ),
+ (MetadataPath::root(), MetadataVersion::Number(2)),
raw_root2.as_bytes(),
),
(
- (MetadataPath::from_role(&Role::Root), MetadataVersion::None),
+ (MetadataPath::root(), MetadataVersion::None),
raw_root2.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::None,
- ),
+ (MetadataPath::targets(), MetadataVersion::None),
raw_targets2.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::None,
- ),
+ (MetadataPath::snapshot(), MetadataVersion::None),
raw_snapshot2.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
raw_timestamp2.as_bytes(),
),
]);
@@ -1762,17 +1732,11 @@
if consistent_snapshot {
expected_metadata.extend(vec![
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::Number(2),
- ),
+ (MetadataPath::targets(), MetadataVersion::Number(2)),
raw_targets2.as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::Number(2),
- ),
+ (MetadataPath::snapshot(), MetadataVersion::Number(2)),
raw_snapshot2.as_bytes(),
),
]);
@@ -2222,49 +2186,31 @@
let mut expected_metadata: BTreeMap<_, _> = vec![
(
- (
- MetadataPath::from_role(&Role::Root),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::root(), MetadataVersion::Number(1)),
metadata1.root().unwrap().as_bytes(),
),
(
- (MetadataPath::from_role(&Role::Root), MetadataVersion::None),
+ (MetadataPath::root(), MetadataVersion::None),
metadata1.root().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::targets(), MetadataVersion::Number(1)),
metadata1.targets().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::None,
- ),
+ (MetadataPath::targets(), MetadataVersion::None),
metadata1.targets().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::Number(1),
- ),
+ (MetadataPath::snapshot(), MetadataVersion::Number(1)),
metadata1.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::None,
- ),
+ (MetadataPath::snapshot(), MetadataVersion::None),
metadata1.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
metadata1.timestamp().unwrap().as_bytes(),
),
]
@@ -2302,38 +2248,23 @@
expected_metadata.extend(
vec![
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::Number(2),
- ),
+ (MetadataPath::targets(), MetadataVersion::Number(2)),
metadata2.targets().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Targets),
- MetadataVersion::None,
- ),
+ (MetadataPath::targets(), MetadataVersion::None),
metadata2.targets().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::Number(2),
- ),
+ (MetadataPath::snapshot(), MetadataVersion::Number(2)),
metadata2.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::None,
- ),
+ (MetadataPath::snapshot(), MetadataVersion::None),
metadata2.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
metadata2.timestamp().unwrap().as_bytes(),
),
]
@@ -2368,24 +2299,15 @@
expected_metadata.extend(
vec![
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::Number(3),
- ),
+ (MetadataPath::snapshot(), MetadataVersion::Number(3)),
metadata3.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Snapshot),
- MetadataVersion::None,
- ),
+ (MetadataPath::snapshot(), MetadataVersion::None),
metadata3.snapshot().unwrap().as_bytes(),
),
(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
metadata3.timestamp().unwrap().as_bytes(),
),
]
@@ -2417,10 +2339,7 @@
expected_metadata.extend(
vec![(
- (
- MetadataPath::from_role(&Role::Timestamp),
- MetadataVersion::None,
- ),
+ (MetadataPath::timestamp(), MetadataVersion::None),
metadata4.timestamp().unwrap().as_bytes(),
)]
.into_iter(),
diff --git a/third_party/rust_crates/vendor/tuf/src/repository.rs b/third_party/rust_crates/vendor/tuf/src/repository.rs
index 6f80c06..861416b 100644
--- a/third_party/rust_crates/vendor/tuf/src/repository.rs
+++ b/third_party/rust_crates/vendor/tuf/src/repository.rs
@@ -514,7 +514,7 @@
mod test {
use super::*;
use crate::interchange::Json;
- use crate::metadata::{MetadataPath, MetadataVersion, Role, RootMetadata, SnapshotMetadata};
+ use crate::metadata::{MetadataPath, MetadataVersion, RootMetadata, SnapshotMetadata};
use crate::repository::EphemeralRepository;
use assert_matches::assert_matches;
use futures_executor::block_on;
@@ -526,7 +526,7 @@
assert_matches!(
repo.fetch_metadata::<RootMetadata>(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::None,
None,
vec![],
@@ -543,17 +543,13 @@
let mut repo = Repository::<_, Json>::new(EphemeralRepository::new());
let fake_metadata = RawSignedMetadata::<Json, RootMetadata>::new(vec![]);
- repo.store_metadata(
- &MetadataPath::from_role(&Role::Root),
- MetadataVersion::None,
- &fake_metadata,
- )
- .await
- .unwrap();
+ repo.store_metadata(&MetadataPath::root(), MetadataVersion::None, &fake_metadata)
+ .await
+ .unwrap();
assert_matches!(
repo.store_metadata(
- &MetadataPath::from_role(&Role::Snapshot),
+ &MetadataPath::snapshot(),
MetadataVersion::None,
&fake_metadata,
)
@@ -563,7 +559,7 @@
assert_matches!(
repo.fetch_metadata::<SnapshotMetadata>(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::None,
None,
vec![],
@@ -577,7 +573,7 @@
#[test]
fn repository_verifies_metadata_hash() {
block_on(async {
- let path = MetadataPath::from_role(&Role::Root);
+ let path = MetadataPath::root();
let version = MetadataVersion::None;
let data: &[u8] = b"valid metadata";
let _metadata = RawSignedMetadata::<Json, RootMetadata>::new(data.to_vec());
@@ -607,7 +603,7 @@
#[test]
fn repository_rejects_corrupt_metadata() {
block_on(async {
- let path = MetadataPath::from_role(&Role::Root);
+ let path = MetadataPath::root();
let version = MetadataVersion::None;
let data: &[u8] = b"corrupt metadata";
@@ -635,7 +631,7 @@
#[test]
fn repository_verifies_metadata_size() {
block_on(async {
- let path = MetadataPath::from_role(&Role::Root);
+ let path = MetadataPath::root();
let version = MetadataVersion::None;
let data: &[u8] = b"reasonably sized metadata";
let _metadata = RawSignedMetadata::<Json, RootMetadata>::new(data.to_vec());
@@ -659,7 +655,7 @@
#[test]
fn repository_rejects_oversized_metadata() {
block_on(async {
- let path = MetadataPath::from_role(&Role::Root);
+ let path = MetadataPath::root();
let version = MetadataVersion::None;
let data: &[u8] = b"very big metadata";
diff --git a/third_party/rust_crates/vendor/tuf/src/repository/file_system.rs b/third_party/rust_crates/vendor/tuf/src/repository/file_system.rs
index bea4ed3..80c7651 100644
--- a/third_party/rust_crates/vendor/tuf/src/repository/file_system.rs
+++ b/third_party/rust_crates/vendor/tuf/src/repository/file_system.rs
@@ -347,7 +347,7 @@
use super::*;
use crate::error::Error;
use crate::interchange::Json;
- use crate::metadata::{Role, RootMetadata};
+ use crate::metadata::RootMetadata;
use crate::repository::{fetch_metadata_to_string, fetch_target_to_string, Repository};
use assert_matches::assert_matches;
use futures_executor::block_on;
@@ -368,7 +368,7 @@
assert_matches!(
Repository::<_, Json>::new(repo)
.fetch_metadata::<RootMetadata>(
- &MetadataPath::from_role(&Role::Root),
+ &MetadataPath::root(),
MetadataVersion::None,
None,
vec![],
diff --git a/third_party/rust_crates/vendor/tuf/src/repository/track_repo.rs b/third_party/rust_crates/vendor/tuf/src/repository/track_repo.rs
index 6149e48..c7d0762 100644
--- a/third_party/rust_crates/vendor/tuf/src/repository/track_repo.rs
+++ b/third_party/rust_crates/vendor/tuf/src/repository/track_repo.rs
@@ -48,11 +48,7 @@
M: Metadata,
D: DataInterchange,
{
- Self::store(
- &MetadataPath::from_role(&M::ROLE),
- version,
- metadata.as_bytes(),
- )
+ Self::store(&M::ROLE.into(), version, metadata.as_bytes())
}
pub(crate) fn fetch_found<T>(
@@ -78,11 +74,7 @@
M: Metadata,
D: DataInterchange,
{
- Track::fetch_found(
- &MetadataPath::from_role(&M::ROLE),
- version,
- metadata.as_bytes(),
- )
+ Track::fetch_found(&M::ROLE.into(), version, metadata.as_bytes())
}
}
diff --git a/third_party/rust_crates/vendor/tuf/tests/integration.rs b/third_party/rust_crates/vendor/tuf/tests/integration.rs
index 0edf478..c633c7d 100644
--- a/third_party/rust_crates/vendor/tuf/tests/integration.rs
+++ b/third_party/rust_crates/vendor/tuf/tests/integration.rs
@@ -1,11 +1,11 @@
use assert_matches::assert_matches;
+use chrono::offset::Utc;
use futures_executor::block_on;
use maplit::hashmap;
use tuf::crypto::{Ed25519PrivateKey, HashAlgorithm, PrivateKey};
use tuf::interchange::Json;
use tuf::metadata::{
- Delegation, Delegations, MetadataDescription, MetadataPath, Role, TargetPath,
- TargetsMetadataBuilder,
+ Delegation, Delegations, MetadataDescription, MetadataPath, TargetPath, TargetsMetadataBuilder,
};
use tuf::repo_builder::RepoBuilder;
use tuf::repository::EphemeralRepository;
@@ -22,6 +22,8 @@
#[test]
fn simple_delegation() {
block_on(async {
+ let now = Utc::now();
+
let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
let snapshot_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
@@ -84,8 +86,9 @@
.unwrap();
let raw_delegation = delegation.to_raw().unwrap();
- tuf.update_delegation(
- &MetadataPath::from_role(&Role::Targets),
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::targets(),
&MetadataPath::new("delegation").unwrap(),
&raw_delegation,
)
@@ -100,6 +103,8 @@
#[test]
fn nested_delegation() {
block_on(async {
+ let now = Utc::now();
+
let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
let snapshot_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
@@ -179,8 +184,9 @@
.unwrap();
let raw_delegation = delegation.to_raw().unwrap();
- tuf.update_delegation(
- &MetadataPath::from_role(&Role::Targets),
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::targets(),
&MetadataPath::new("delegation-a").unwrap(),
&raw_delegation,
)
@@ -201,7 +207,8 @@
.unwrap();
let raw_delegation = delegation.to_raw().unwrap();
- tuf.update_delegation(
+ tuf.update_delegated_targets(
+ &now,
&MetadataPath::new("delegation-a").unwrap(),
&MetadataPath::new("delegation-b").unwrap(),
&raw_delegation,
@@ -217,6 +224,8 @@
#[test]
fn rejects_bad_delegation_signatures() {
block_on(async {
+ let now = Utc::now();
+
let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
let snapshot_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
@@ -280,8 +289,9 @@
let raw_delegation = delegation.to_raw().unwrap();
assert_matches!(
- tuf.update_delegation(
- &MetadataPath::from_role(&Role::Targets),
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::targets(),
&MetadataPath::new("delegation").unwrap(),
&raw_delegation
),
@@ -298,6 +308,8 @@
#[test]
fn diamond_delegation() {
block_on(async {
+ let now = Utc::now();
+
let etc_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
let delegation_a_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
@@ -320,6 +332,73 @@
//
// Verify tuf::Database handles this situation correctly.
+ //// build delegation A ////
+
+ let delegation_a_delegations = Delegations::new(
+ hashmap! { delegation_c_key.public().key_id().clone() => delegation_c_key.public().clone() },
+ vec![Delegation::new(
+ MetadataPath::new("delegation-c").unwrap(),
+ false,
+ 1,
+ vec![delegation_c_key.public().key_id().clone()].iter().cloned().collect(),
+ vec![TargetPath::new("foo").unwrap()].iter().cloned().collect(),
+ )
+ .unwrap()],
+ )
+ .unwrap();
+
+ let delegation_a = TargetsMetadataBuilder::new()
+ .delegations(delegation_a_delegations)
+ .signed::<Json>(&delegation_a_key)
+ .unwrap();
+ let raw_delegation_a = delegation_a.to_raw().unwrap();
+
+ //// build delegation B ////
+
+ let delegations_b = Delegations::new(
+ hashmap! { delegation_c_key.public().key_id().clone() => delegation_c_key.public().clone() },
+ vec![Delegation::new(
+ MetadataPath::new("delegation-c").unwrap(),
+ false,
+ 1,
+ // oops, wrong key.
+ vec![delegation_b_key.public().key_id().clone()].iter().cloned().collect(),
+ vec![TargetPath::new("bar").unwrap()].iter().cloned().collect(),
+ )
+ .unwrap()],
+ )
+ .unwrap();
+
+ let delegation_b = TargetsMetadataBuilder::new()
+ .delegations(delegations_b)
+ .signed::<Json>(&delegation_b_key)
+ .unwrap();
+ let raw_delegation_b = delegation_b.to_raw().unwrap();
+
+ //// build delegation C ////
+
+ let foo_target_file: &[u8] = b"foo contents";
+ let bar_target_file: &[u8] = b"bar contents";
+
+ let delegation_c = TargetsMetadataBuilder::new()
+ .insert_target_from_slice(
+ TargetPath::new("foo").unwrap(),
+ foo_target_file,
+ &[HashAlgorithm::Sha256],
+ )
+ .unwrap()
+ .insert_target_from_slice(
+ TargetPath::new("bar").unwrap(),
+ bar_target_file,
+ &[HashAlgorithm::Sha256],
+ )
+ .unwrap()
+ .signed::<Json>(&delegation_c_key)
+ .unwrap();
+ let raw_delegation_c = delegation_c.to_raw().unwrap();
+
+ //// construct the database ////
+
let delegations = Delegations::new(
hashmap! {
delegation_a_key.public().key_id().clone() => delegation_a_key.public().clone(),
@@ -372,18 +451,30 @@
builder
.insert_metadata_description(
MetadataPath::new("delegation-a").unwrap(),
- MetadataDescription::from_slice(&[0u8], 1, &[HashAlgorithm::Sha256])
- .unwrap(),
+ MetadataDescription::from_slice(
+ raw_delegation_a.as_bytes(),
+ 1,
+ &[HashAlgorithm::Sha256],
+ )
+ .unwrap(),
)
.insert_metadata_description(
MetadataPath::new("delegation-b").unwrap(),
- MetadataDescription::from_slice(&[0u8], 1, &[HashAlgorithm::Sha256])
- .unwrap(),
+ MetadataDescription::from_slice(
+ raw_delegation_b.as_bytes(),
+ 1,
+ &[HashAlgorithm::Sha256],
+ )
+ .unwrap(),
)
.insert_metadata_description(
MetadataPath::new("delegation-c").unwrap(),
- MetadataDescription::from_slice(&[0u8], 1, &[HashAlgorithm::Sha256])
- .unwrap(),
+ MetadataDescription::from_slice(
+ raw_delegation_c.as_bytes(),
+ 1,
+ &[HashAlgorithm::Sha256],
+ )
+ .unwrap(),
)
})
.unwrap()
@@ -393,103 +484,44 @@
let mut tuf = Database::<Json>::from_trusted_metadata(&metadata).unwrap();
- //// build delegation A ////
+ //// Verify we can trust delegation-a and delegation-b..
- let delegations = Delegations::new(
- hashmap! { delegation_c_key.public().key_id().clone() => delegation_c_key.public().clone() },
- vec![Delegation::new(
- MetadataPath::new("delegation-c").unwrap(),
- false,
- 1,
- vec![delegation_c_key.public().key_id().clone()].iter().cloned().collect(),
- vec![TargetPath::new("foo").unwrap()].iter().cloned().collect(),
- )
- .unwrap()],
- )
- .unwrap();
-
- let delegation = TargetsMetadataBuilder::new()
- .delegations(delegations)
- .signed::<Json>(&delegation_a_key)
- .unwrap();
- let raw_delegation = delegation.to_raw().unwrap();
-
- tuf.update_delegation(
- &MetadataPath::from_role(&Role::Targets),
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::targets(),
&MetadataPath::new("delegation-a").unwrap(),
- &raw_delegation,
+ &raw_delegation_a,
)
.unwrap();
- //// build delegation B ////
-
- let delegations = Delegations::new(
- hashmap! { delegation_c_key.public().key_id().clone() => delegation_c_key.public().clone() },
- vec![Delegation::new(
- MetadataPath::new("delegation-c").unwrap(),
- false,
- 1,
- // oops, wrong key.
- vec![delegation_b_key.public().key_id().clone()].iter().cloned().collect(),
- vec![TargetPath::new("bar").unwrap()].iter().cloned().collect(),
- )
- .unwrap()],
- )
- .unwrap();
-
- let delegation = TargetsMetadataBuilder::new()
- .delegations(delegations)
- .signed::<Json>(&delegation_b_key)
- .unwrap();
- let raw_delegation = delegation.to_raw().unwrap();
-
- tuf.update_delegation(
- &MetadataPath::from_role(&Role::Targets),
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::targets(),
&MetadataPath::new("delegation-b").unwrap(),
- &raw_delegation,
+ &raw_delegation_b,
)
.unwrap();
- //// build delegation C ////
-
- let foo_target_file: &[u8] = b"foo contents";
- let bar_target_file: &[u8] = b"bar contents";
-
- let delegation = TargetsMetadataBuilder::new()
- .insert_target_from_slice(
- TargetPath::new("foo").unwrap(),
- foo_target_file,
- &[HashAlgorithm::Sha256],
- )
- .unwrap()
- .insert_target_from_slice(
- TargetPath::new("bar").unwrap(),
- bar_target_file,
- &[HashAlgorithm::Sha256],
- )
- .unwrap()
- .signed::<Json>(&delegation_c_key)
- .unwrap();
- let raw_delegation = delegation.to_raw().unwrap();
-
//// Verify delegation-c is valid, but only when updated through delegation-a.
- tuf.update_delegation(
- &MetadataPath::new("delegation-a").unwrap(),
- &MetadataPath::new("delegation-c").unwrap(),
- &raw_delegation,
- )
- .unwrap();
-
assert_matches!(
- tuf.update_delegation(
+ tuf.update_delegated_targets(
+ &now,
&MetadataPath::new("delegation-b").unwrap(),
&MetadataPath::new("delegation-c").unwrap(),
- &raw_delegation
+ &raw_delegation_c
),
Err(Error::VerificationFailure(_))
);
+ tuf.update_delegated_targets(
+ &now,
+ &MetadataPath::new("delegation-a").unwrap(),
+ &MetadataPath::new("delegation-c").unwrap(),
+ &raw_delegation_c,
+ )
+ .unwrap();
+
assert!(tuf
.target_description(&TargetPath::new("foo").unwrap())
.is_ok());