Skip to content

Commit 0b85d55

Browse files
committed
fix: timestamp.json meta can has optional fields
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]>
1 parent eb5e25e commit 0b85d55

File tree

4 files changed

+38
-17
lines changed

4 files changed

+38
-17
lines changed

tough/src/cache.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ impl Repository {
9696
{
9797
self.cache_file_from_transport(
9898
self.snapshot_filename().as_str(),
99-
self.max_snapshot_size()?,
99+
self.max_snapshot_size()?
100+
.unwrap_or(self.limits.max_timestamp_size),
100101
"timestamp.json",
101102
&metadata_outdir,
102103
)
@@ -237,7 +238,7 @@ impl Repository {
237238
}
238239

239240
/// Gets the max size of the snapshot.json file as specified by the timestamp file.
240-
fn max_snapshot_size(&self) -> Result<u64> {
241+
fn max_snapshot_size(&self) -> Result<Option<u64>> {
241242
let snapshot_meta =
242243
self.timestamp()
243244
.signed

tough/src/editor/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,11 +745,11 @@ impl RepositoryEditor {
745745
R: Role,
746746
{
747747
TimestampMeta {
748-
hashes: Hashes {
748+
hashes: Some(Hashes {
749749
sha256: role.sha256.to_vec().into(),
750750
_extra: HashMap::new(),
751-
},
752-
length: role.length,
751+
}),
752+
length: Some(role.length),
753753
version: role.signed.signed.version(),
754754
_extra: HashMap::new(),
755755
}

tough/src/lib.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ impl Repository {
360360
transport.as_ref(),
361361
&root,
362362
&timestamp,
363+
limits.max_timestamp_size,
363364
&datastore,
364365
&metadata_base_url,
365366
expiration_enforcement,
@@ -910,6 +911,7 @@ async fn load_snapshot(
910911
transport: &dyn Transport,
911912
root: &Signed<Root>,
912913
timestamp: &Signed<Timestamp>,
914+
max_timestamp_size: u64,
913915
datastore: &Datastore,
914916
metadata_base_url: &Url,
915917
expiration_enforcement: ExpirationEnforcement,
@@ -941,14 +943,25 @@ async fn load_snapshot(
941943
path: path.clone(),
942944
url: metadata_base_url.clone(),
943945
})?;
944-
let stream = fetch_sha256(
945-
transport,
946-
url.clone(),
947-
snapshot_meta.length,
948-
"timestamp.json",
949-
&snapshot_meta.hashes.sha256,
950-
)
951-
.await?;
946+
let stream = if let Some(hashes) = &snapshot_meta.hashes {
947+
fetch_sha256(
948+
transport,
949+
url.clone(),
950+
snapshot_meta.length.unwrap_or(max_timestamp_size),
951+
"timestamp.json",
952+
&hashes.sha256,
953+
)
954+
.await?
955+
} else {
956+
fetch_max_size(
957+
transport,
958+
url.clone(),
959+
snapshot_meta.length.unwrap_or(max_timestamp_size),
960+
"timestamp.json",
961+
)
962+
.await?
963+
};
964+
952965
let data = stream
953966
.into_vec()
954967
.await

tough/src/schema/mod.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,11 +1128,18 @@ pub struct Timestamp {
11281128
/// file, this MUST only include a description of the snapshot.json file.
11291129
#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
11301130
pub struct TimestampMeta {
1131-
/// The integer length in bytes of the snapshot.json file.
1132-
pub length: u64,
1131+
/// The integer length in bytes of the snapshot.json file. It is OPTIONAL and
1132+
/// can be omitted to reduce the snapshot metadata file size. In that case the client MUST use a
1133+
/// custom download limit for the listed metadata.
1134+
#[serde(skip_serializing_if = "Option::is_none")]
1135+
pub length: Option<u64>,
11331136

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

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

0 commit comments

Comments
 (0)