Skip to content

Commit

Permalink
Merge pull request #839 from sigstore/minor-tuf-updates
Browse files Browse the repository at this point in the history
Update tuf updater api surface
  • Loading branch information
loosebazooka authored Nov 1, 2024
2 parents 8e91247 + 775e0a0 commit 90d958b
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 17 deletions.
50 changes: 33 additions & 17 deletions sigstore-java/src/main/java/dev/sigstore/tuf/Updater.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import dev.sigstore.encryption.Keys;
import dev.sigstore.encryption.signers.Verifiers;
import dev.sigstore.tuf.model.*;
import dev.sigstore.tuf.model.TargetMeta.TargetData;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
Expand Down Expand Up @@ -91,13 +92,15 @@ public static Builder builder() {
return new Builder();
}

/** Update metadata and download all targets. */
public void update()
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
updateMeta();
downloadTargets(trustedMetaStore.getTargets());
}

void updateMeta() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
/** Update just metadata but do not download targets. */
public void updateMeta() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
updateRoot();
var oldTimestamp = trustedMetaStore.findTimestamp();
updateTimestamp();
Expand All @@ -112,6 +115,16 @@ void updateMeta() throws IOException, NoSuchAlgorithmException, InvalidKeySpecEx
updateTargets();
}

/** Download a single target defined in targets. Does not handle delegated targets. */
public void downloadTarget(String targetName)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
var targetData = trustedMetaStore.getTargets().getSignedMeta().getTargets().get(targetName);
if (targetData == null) {
throw new TargetMetadataMissingException(targetName);
}
downloadTarget(targetName, targetData);
}

// https://theupdateframework.github.io/specification/latest/#detailed-client-workflow
void updateRoot()
throws IOException, RoleExpiredException, NoSuchAlgorithmException, InvalidKeySpecException,
Expand Down Expand Up @@ -304,7 +317,6 @@ void updateTimestamp()
localTimestamp.getSignedMeta().getVersion(), timestamp.getSignedMeta().getVersion());
}
if (localTimestamp.getSignedMeta().getVersion() == timestamp.getSignedMeta().getVersion()) {
trustedMetaStore.setTimestamp(localTimestamp);
return;
}
}
Expand Down Expand Up @@ -459,24 +471,28 @@ void downloadTargets(Targets targets)
throw new TargetMetadataMissingException(targetName);
}
TargetMeta.TargetData targetData = entry.getValue();
// 9) Download target up to length specified in bytes. verify against hash.
String versionedTargetName;
if (targetData.getHashes().getSha512() != null) {
versionedTargetName = targetData.getHashes().getSha512() + "." + targetName;
} else {
versionedTargetName = targetData.getHashes().getSha256() + "." + targetName;
}
downloadTarget(targetName, targetData);
}
}

var targetBytes = targetFetcher.fetchResource(versionedTargetName, targetData.getLength());
if (targetBytes == null) {
throw new FileNotFoundException(targetName, targetFetcher.getSource());
}
verifyHashes(entry.getKey(), targetBytes, targetData.getHashes());
void downloadTarget(String targetName, TargetData targetData) throws IOException {
// 9) Download target up to length specified in bytes. verify against hash.
String versionedTargetName;
if (targetData.getHashes().getSha512() != null) {
versionedTargetName = targetData.getHashes().getSha512() + "." + targetName;
} else {
versionedTargetName = targetData.getHashes().getSha256() + "." + targetName;
}

// when persisting targets use the targetname without sha512 prefix
// https://theupdateframework.github.io/specification/latest/index.html#fetch-target
targetStore.writeTarget(targetName, targetBytes);
var targetBytes = targetFetcher.fetchResource(versionedTargetName, targetData.getLength());
if (targetBytes == null) {
throw new FileNotFoundException(targetName, targetFetcher.getSource());
}
verifyHashes(targetName, targetBytes, targetData.getHashes());

// when persisting targets use the targetname without sha512 prefix
// https://theupdateframework.github.io/specification/latest/index.html#fetch-target
targetStore.writeTarget(targetName, targetBytes);
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
@Value.Immutable
public interface Root extends SignedTufMeta<RootMeta> {
@Override
@Gson.Ignore
@Derived
default RootMeta getSignedMeta() {
return getSignedMeta(RootMeta.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public interface SignedTufMeta<T extends TufMeta> {

/** An internal helper to translate raw signed json to a useable type. */
@Derived
@Gson.Ignore
default T getSignedMeta(Class<T> type) {
return GsonSupplier.GSON.get().fromJson(getRawSignedMeta(), type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
public interface Snapshot extends SignedTufMeta<SnapshotMeta> {
@Override
@Derived
@Gson.Ignore
default SnapshotMeta getSignedMeta() {
return getSignedMeta(SnapshotMeta.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ interface SnapshotTarget {

/** The length in bytes of the given target's metadata, or a default if not present */
@Derived
@Gson.Ignore
default Integer getLengthOrDefault() {
return getLength().orElse(DEFAULT_MAX_LENGTH);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
public interface Targets extends SignedTufMeta<TargetMeta> {
@Override
@Derived
@Gson.Ignore
default TargetMeta getSignedMeta() {
return getSignedMeta(TargetMeta.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public interface Timestamp extends SignedTufMeta<TimestampMeta> {

@Override
@Derived
@Gson.Ignore
default TimestampMeta getSignedMeta() {
return getSignedMeta(TimestampMeta.class);
}
Expand Down

0 comments on commit 90d958b

Please sign in to comment.