Skip to content

Commit

Permalink
fix: timestamp.json meta can has optional fields
Browse files Browse the repository at this point in the history
According to the TUF specification, the `meta` attribute of
`timestamp.json` must follow the same specification of `METAFILES`.
That means it has optional `LENGTH` and `HASHES`.

See [this](https://theupdateframework.github.io/specification/latest/#file-formats-timestamp) section of
the TUF specification.

Fixes issue awslabs#771

Signed-off-by: Flavio Castelli <[email protected]>
  • Loading branch information
flavio committed Jul 1, 2024
1 parent eb5e25e commit 0b85d55
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
5 changes: 3 additions & 2 deletions tough/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ impl Repository {
{
self.cache_file_from_transport(
self.snapshot_filename().as_str(),
self.max_snapshot_size()?,
self.max_snapshot_size()?
.unwrap_or(self.limits.max_timestamp_size),
"timestamp.json",
&metadata_outdir,
)
Expand Down Expand Up @@ -237,7 +238,7 @@ impl Repository {
}

/// Gets the max size of the snapshot.json file as specified by the timestamp file.
fn max_snapshot_size(&self) -> Result<u64> {
fn max_snapshot_size(&self) -> Result<Option<u64>> {
let snapshot_meta =
self.timestamp()
.signed
Expand Down
6 changes: 3 additions & 3 deletions tough/src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,11 +745,11 @@ impl RepositoryEditor {
R: Role,
{
TimestampMeta {
hashes: Hashes {
hashes: Some(Hashes {
sha256: role.sha256.to_vec().into(),
_extra: HashMap::new(),
},
length: role.length,
}),
length: Some(role.length),
version: role.signed.signed.version(),
_extra: HashMap::new(),
}
Expand Down
29 changes: 21 additions & 8 deletions tough/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ impl Repository {
transport.as_ref(),
&root,
&timestamp,
limits.max_timestamp_size,
&datastore,
&metadata_base_url,
expiration_enforcement,
Expand Down Expand Up @@ -910,6 +911,7 @@ async fn load_snapshot(
transport: &dyn Transport,
root: &Signed<Root>,
timestamp: &Signed<Timestamp>,
max_timestamp_size: u64,
datastore: &Datastore,
metadata_base_url: &Url,
expiration_enforcement: ExpirationEnforcement,
Expand Down Expand Up @@ -941,14 +943,25 @@ async fn load_snapshot(
path: path.clone(),
url: metadata_base_url.clone(),
})?;
let stream = fetch_sha256(
transport,
url.clone(),
snapshot_meta.length,
"timestamp.json",
&snapshot_meta.hashes.sha256,
)
.await?;
let stream = if let Some(hashes) = &snapshot_meta.hashes {
fetch_sha256(
transport,
url.clone(),
snapshot_meta.length.unwrap_or(max_timestamp_size),
"timestamp.json",
&hashes.sha256,
)
.await?
} else {
fetch_max_size(
transport,
url.clone(),
snapshot_meta.length.unwrap_or(max_timestamp_size),
"timestamp.json",
)
.await?
};

let data = stream
.into_vec()
.await
Expand Down
15 changes: 11 additions & 4 deletions tough/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,11 +1128,18 @@ pub struct Timestamp {
/// file, this MUST only include a description of the snapshot.json file.
#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
pub struct TimestampMeta {
/// The integer length in bytes of the snapshot.json file.
pub length: u64,
/// The integer length in bytes of the snapshot.json file. It is OPTIONAL and
/// can be omitted to reduce the snapshot metadata file size. In that case the client MUST use a
/// custom download limit for the listed metadata.
#[serde(skip_serializing_if = "Option::is_none")]
pub length: Option<u64>,

/// The hashes of the snapshot.json file.
pub hashes: Hashes,
/// The hashes of the snapshot.json file. HASHES
/// is OPTIONAL and can be omitted to reduce the snapshot metadata file size. In that case the
/// repository MUST guarantee that VERSION alone unambiguously identifies the metadata at
/// METAPATH.
#[serde(skip_serializing_if = "Option::is_none")]
pub hashes: Option<Hashes>,

/// An integer that is greater than 0. Clients MUST NOT replace a metadata file with a version
/// number less than the one currently trusted.
Expand Down

0 comments on commit 0b85d55

Please sign in to comment.