Skip to content

Commit

Permalink
TUF allows optional hashes and length on snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
loosebazooka committed Mar 11, 2024
1 parent 677fc17 commit a6cb067
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
33 changes: 21 additions & 12 deletions sigstore-java/src/main/java/dev/sigstore/tuf/Updater.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,17 +308,20 @@ Snapshot updateSnapshot(Root root, Timestamp timestamp)
Role.Name.SNAPSHOT,
timestampSnapshotVersion,
Snapshot.class,
timestamp.getSignedMeta().getSnapshotMeta().getLength());
timestamp.getSignedMeta().getSnapshotMeta().getLengthOrDefault());
if (snapshotResult.isEmpty()) {
throw new FileNotFoundException(
timestampSnapshotVersion + ".snapshot.json", fetcher.getSource());
}
// 2) check against timestamp.snapshot.hash
// 2) check against timestamp.snapshot.hash, this is optional, the fallback is
// that the version must match, which is handled in (4).
var snapshot = snapshotResult.get();
verifyHashes(
"snapshot",
snapshot.getRawBytes(),
timestamp.getSignedMeta().getSnapshotMeta().getHashes());
if (timestamp.getSignedMeta().getSnapshotMeta().getHashes().isPresent()) {
verifyHashes(
"snapshot",
snapshot.getRawBytes(),
timestamp.getSignedMeta().getSnapshotMeta().getHashes().get());
}
// 3) Check against threshold of root signing keys, else fail
verifyDelegate(root, snapshot.getMetaResource());
// 4) Check snapshot.version matches timestamp.snapshot.version, else fail.
Expand Down Expand Up @@ -392,17 +395,23 @@ Targets updateTargets(Root root, Snapshot snapshot)
SnapshotMeta.SnapshotTarget targetMeta = snapshot.getSignedMeta().getTargetMeta("targets.json");
var targetsResultMaybe =
fetcher.getMeta(
Role.Name.TARGETS, targetMeta.getVersion(), Targets.class, targetMeta.getLength());
Role.Name.TARGETS,
targetMeta.getVersion(),
Targets.class,
targetMeta.getLengthOrDefault());
if (targetsResultMaybe.isEmpty()) {
throw new FileNotFoundException(
targetMeta.getVersion() + ".targets.json", fetcher.getSource());
}
var targetsResult = targetsResultMaybe.get();
// 2) check hash against snapshot.targets.hash, else fail.
verifyHashes(
targetMeta.getVersion() + ".targets.json",
targetsResult.getRawBytes(),
targetMeta.getHashes());
// 2) check hash against snapshot.targets.hash, else just make sure versions match, handled
// by (4)
if (targetMeta.getHashes().isPresent()) {
verifyHashes(
targetMeta.getVersion() + ".targets.json",
targetsResult.getRawBytes(),
targetMeta.getHashes().get());
}
// 3) check against threshold of keys as specified by trusted root.json
verifyDelegate(root, targetsResult.getMetaResource());
// 4) check targets.version == snapshot.targets.version, else fail.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
package dev.sigstore.tuf.model;

import java.util.Map;
import java.util.Optional;
import org.immutables.gson.Gson;
import org.immutables.value.Value;
import org.immutables.value.Value.Derived;

/**
* The snapshot.json metadata file lists version numbers of all metadata files other than
Expand All @@ -29,6 +31,8 @@
@Value.Immutable
public interface SnapshotMeta extends TufMeta {

Integer DEFAULT_MAX_LENGTH = 2000000;

/** Maps role and delegation role names (e.g. "targets.json") to snapshot metadata. */
Map<String, SnapshotTarget> getMeta();

Expand All @@ -40,11 +44,20 @@ default SnapshotTarget getTargetMeta(String targetName) {
@Value.Immutable
interface SnapshotTarget {

/** The valid hashes for the given target's metadata. */
Hashes getHashes();
/** The valid hashes for the given target's metadata. This is optional and may not be present */
Optional<Hashes> getHashes();

/**
* The length in bytes of the given target's metadata. This is optional and may not be present,
* use {@link #getLengthOrDefault} to delegate to the client default config.
*/
Optional<Integer> getLength();

/** The length in bytes of the given target's metadata. */
int getLength();
/** The length in bytes of the given target's metadata, or a default if not present */
@Derived
default Integer getLengthOrDefault() {
return getLength().orElse(DEFAULT_MAX_LENGTH);
}

/** The expected version of the given target's metadata. */
int getVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ public void loadSnapshotJson() throws IOException {
assertNotNull(rekorSnapshot.getHashes());
assertEquals(
"9d2e1a5842937d8e0d3e3759170b0ad15c56c5df36afc5cf73583ddd283a463b",
rekorSnapshot.getHashes().getSha256());
rekorSnapshot.getHashes().get().getSha256());
assertEquals(
"176e9e710ddddd1b357a7d7970831bae59763395a0c18976110cbd35b25e5412dc50f356ec421a7a30265670cf7aec9ed84ee944ba700ec2394b9c876645b960",
rekorSnapshot.getHashes().getSha512());
assertEquals(797, rekorSnapshot.getLength());
rekorSnapshot.getHashes().get().getSha512());
assertEquals(797, rekorSnapshot.getLength().get());
assertEquals(3, rekorSnapshot.getVersion());
}

Expand Down

0 comments on commit a6cb067

Please sign in to comment.