in tough/src/lib.rs [801:869]
fn load_timestamp(
transport: &dyn Transport,
root: &Signed<Root>,
datastore: &Datastore,
max_timestamp_size: u64,
metadata_base_url: &Url,
expiration_enforcement: ExpirationEnforcement,
) -> Result<Signed<Timestamp>> {
// 2. Download the timestamp metadata file, up to Y number of bytes (because the size is
// unknown.) The value for Y is set by the authors of the application using TUF. For
// example, Y may be tens of kilobytes. The filename used to download the timestamp metadata
// file is of the fixed form FILENAME.EXT (e.g., timestamp.json).
let path = "timestamp.json";
let reader = fetch_max_size(
transport,
metadata_base_url.join(path).context(error::JoinUrlSnafu {
path,
url: metadata_base_url.clone(),
})?,
max_timestamp_size,
"max_timestamp_size argument",
)?;
let timestamp: Signed<Timestamp> =
serde_json::from_reader(reader).context(error::ParseMetadataSnafu {
role: RoleType::Timestamp,
})?;
// 2.1. Check signatures. The new timestamp metadata file must have been signed by a threshold
// of keys specified in the trusted root metadata file. If the new timestamp metadata file is
// not properly signed, discard it, abort the update cycle, and report the signature failure.
root.signed
.verify_role(×tamp)
.context(error::VerifyMetadataSnafu {
role: RoleType::Timestamp,
})?;
// 2.2. Check for a rollback attack. The version number of the trusted timestamp metadata file,
// if any, must be less than or equal to the version number of the new timestamp metadata
// file. If the new timestamp metadata file is older than the trusted timestamp metadata
// file, discard it, abort the update cycle, and report the potential rollback attack.
if let Some(Ok(old_timestamp)) = datastore
.reader("timestamp.json")?
.map(serde_json::from_reader::<_, Signed<Timestamp>>)
{
if root.signed.verify_role(&old_timestamp).is_ok() {
ensure!(
old_timestamp.signed.version <= timestamp.signed.version,
error::OlderMetadataSnafu {
role: RoleType::Timestamp,
current_version: old_timestamp.signed.version,
new_version: timestamp.signed.version
}
);
}
}
// TUF v1.0.16, 5.3.3. Check for a freeze attack. The expiration timestamp in the new timestamp
// metadata file MUST be higher than the fixed update start time. If so, the new timestamp
// metadata file becomes the trusted timestamp metadata file. If the new timestamp metadata file
// has expired, discard it, abort the update cycle, and report the potential freeze attack.
if expiration_enforcement == ExpirationEnforcement::Safe {
check_expired(datastore, ×tamp.signed)?;
}
// Now that everything seems okay, write the timestamp file to the datastore.
datastore.create("timestamp.json", ×tamp)?;
Ok(timestamp)
}