Skip to content

Commit e41df29

Browse files
committed
Allow cli to run with alt tuf remote repository
Signed-off-by: Appu Goundan <[email protected]>
1 parent 8fdbdac commit e41df29

File tree

5 files changed

+118
-22
lines changed

5 files changed

+118
-22
lines changed

sigstore-cli/src/main/java/dev/sigstore/cli/Sign.java

+57-10
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
package dev.sigstore.cli;
1717

1818
import dev.sigstore.KeylessSigner;
19+
import dev.sigstore.TrustedRootProvider;
1920
import dev.sigstore.encryption.certificates.Certificates;
2021
import dev.sigstore.oidc.client.OidcClients;
22+
import dev.sigstore.tuf.RootProvider;
23+
import dev.sigstore.tuf.SigstoreTufClient;
24+
import java.net.URL;
2125
import java.nio.charset.StandardCharsets;
2226
import java.nio.file.Files;
2327
import java.nio.file.Path;
@@ -40,12 +44,29 @@ public class Sign implements Callable<Integer> {
4044
@ArgGroup(multiplicity = "1", exclusive = true)
4145
SignatureFiles signatureFiles;
4246

43-
@Option(
44-
names = {"--staging"},
45-
description = "test against staging",
46-
required = false,
47-
defaultValue = "false")
48-
Boolean staging;
47+
@ArgGroup(multiplicity = "0..1", exclusive = true)
48+
Verify.Target target;
49+
50+
static class Target {
51+
@Option(
52+
names = {"--staging"},
53+
description = "test against staging",
54+
required = false,
55+
defaultValue = "false")
56+
Boolean staging;
57+
58+
@Option(
59+
names = {"--public-good-with-tuf-url-override"},
60+
description = "use public good with a tuf remote repository override",
61+
required = false)
62+
String publicGoodWithTufUrlOverride;
63+
64+
@Option(
65+
names = {"--staging-with-tuf-url-override"},
66+
description = "use staging with a tuf remote repository override",
67+
required = false)
68+
String stagingWithTufUrlOverride;
69+
}
4970

5071
@Option(
5172
names = {"--identity-token"},
@@ -55,10 +76,36 @@ public class Sign implements Callable<Integer> {
5576

5677
@Override
5778
public Integer call() throws Exception {
58-
var signerBuilder =
59-
staging
60-
? KeylessSigner.builder().sigstoreStagingDefaults()
61-
: KeylessSigner.builder().sigstorePublicDefaults();
79+
KeylessSigner.Builder signerBuilder;
80+
if (target == null) {
81+
signerBuilder = new KeylessSigner.Builder().sigstorePublicDefaults();
82+
} else if (target.staging) {
83+
signerBuilder = new KeylessSigner.Builder().sigstoreStagingDefaults();
84+
} else if (target.publicGoodWithTufUrlOverride != null) {
85+
var tufClientBuilder =
86+
SigstoreTufClient.builder()
87+
.usePublicGoodInstance()
88+
.tufMirror(
89+
new URL(target.publicGoodWithTufUrlOverride),
90+
RootProvider.fromResource(SigstoreTufClient.PUBLIC_GOOD_ROOT_RESOURCE));
91+
signerBuilder =
92+
KeylessSigner.builder()
93+
.sigstorePublicDefaults()
94+
.trustedRootProvider(TrustedRootProvider.from(tufClientBuilder));
95+
} else if (target.stagingWithTufUrlOverride != null) {
96+
var tufClientBuilder =
97+
SigstoreTufClient.builder()
98+
.useStagingInstance()
99+
.tufMirror(
100+
new URL(target.stagingWithTufUrlOverride),
101+
RootProvider.fromResource(SigstoreTufClient.STAGING_ROOT_RESOURCE));
102+
signerBuilder =
103+
KeylessSigner.builder()
104+
.sigstoreStagingDefaults()
105+
.trustedRootProvider(TrustedRootProvider.from(tufClientBuilder));
106+
} else {
107+
throw new IllegalStateException("Unable to initialize signer");
108+
}
62109
if (identityToken != null) {
63110
// If we've explicitly provided an identity token, customize the signer to only use the token
64111
// string OIDC client.

sigstore-cli/src/main/java/dev/sigstore/cli/Verify.java

+51-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import com.google.common.hash.Hashing;
2121
import dev.sigstore.KeylessVerifier;
22+
import dev.sigstore.TrustedRootProvider;
2223
import dev.sigstore.VerificationOptions;
2324
import dev.sigstore.VerificationOptions.CertificateIdentity;
2425
import dev.sigstore.bundle.Bundle;
@@ -27,6 +28,9 @@
2728
import dev.sigstore.bundle.ImmutableBundle;
2829
import dev.sigstore.encryption.certificates.Certificates;
2930
import dev.sigstore.rekor.client.RekorEntryFetcher;
31+
import dev.sigstore.tuf.RootProvider;
32+
import dev.sigstore.tuf.SigstoreTufClient;
33+
import java.net.URL;
3034
import java.nio.charset.StandardCharsets;
3135
import java.nio.file.Files;
3236
import java.nio.file.Path;
@@ -72,6 +76,18 @@ static class Target {
7276
description = "an alternative to the TUF managed sigstore public good trusted root",
7377
required = false)
7478
Path trustedRoot;
79+
80+
@Option(
81+
names = {"--public-good-with-tuf-url-override"},
82+
description = "use public good with a tuf remote repository override",
83+
required = false)
84+
String publicGoodWithTufUrlOverride;
85+
86+
@Option(
87+
names = {"--staging-with-tuf-url-override"},
88+
description = "use staging with a tuf remote repository override",
89+
required = false)
90+
String stagingWithTufUrlOverride;
7591
}
7692

7793
static class Policy {
@@ -127,12 +143,41 @@ public Integer call() throws Exception {
127143
}
128144
var verificationOptions = verificationOptionsBuilder.build();
129145

130-
var verifier =
131-
target == null
132-
? new KeylessVerifier.Builder().sigstorePublicDefaults().build()
133-
: target.staging
134-
? new KeylessVerifier.Builder().sigstoreStagingDefaults().build()
135-
: new KeylessVerifier.Builder().fromTrustedRoot(target.trustedRoot).build();
146+
KeylessVerifier verifier;
147+
if (target == null) {
148+
verifier = new KeylessVerifier.Builder().sigstorePublicDefaults().build();
149+
} else if (target.staging) {
150+
verifier = new KeylessVerifier.Builder().sigstoreStagingDefaults().build();
151+
} else if (target.trustedRoot != null) {
152+
verifier =
153+
new KeylessVerifier.Builder()
154+
.trustedRootProvider(TrustedRootProvider.from(target.trustedRoot))
155+
.build();
156+
} else if (target.publicGoodWithTufUrlOverride != null) {
157+
var tufClientBuilder =
158+
SigstoreTufClient.builder()
159+
.usePublicGoodInstance()
160+
.tufMirror(
161+
new URL(target.publicGoodWithTufUrlOverride),
162+
RootProvider.fromResource(SigstoreTufClient.PUBLIC_GOOD_ROOT_RESOURCE));
163+
verifier =
164+
KeylessVerifier.builder()
165+
.trustedRootProvider(TrustedRootProvider.from(tufClientBuilder))
166+
.build();
167+
} else if (target.stagingWithTufUrlOverride != null) {
168+
var tufClientBuilder =
169+
SigstoreTufClient.builder()
170+
.useStagingInstance()
171+
.tufMirror(
172+
new URL(target.stagingWithTufUrlOverride),
173+
RootProvider.fromResource(SigstoreTufClient.STAGING_ROOT_RESOURCE));
174+
verifier =
175+
KeylessVerifier.builder()
176+
.trustedRootProvider(TrustedRootProvider.from(tufClientBuilder))
177+
.build();
178+
} else {
179+
throw new IllegalStateException("Unable to initialize verifier");
180+
}
136181
verifier.verify(artifact, bundle, verificationOptions);
137182
return 0;
138183
}

sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ public Builder rekorUrl(URI uri) {
158158
}
159159

160160
@CanIgnoreReturnValue
161-
public Builder trustedRoot(Path trustedRoot) {
162-
trustedRootProvider = TrustedRootProvider.from(trustedRoot);
161+
public Builder trustedRootProvider(TrustedRootProvider trustedRootProvider) {
162+
this.trustedRootProvider = trustedRootProvider;
163163
return this;
164164
}
165165

sigstore-java/src/main/java/dev/sigstore/KeylessVerifier.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public Builder sigstoreStagingDefaults() {
8181
return this;
8282
}
8383

84-
public Builder fromTrustedRoot(Path trustedRoot) {
85-
trustedRootProvider = TrustedRootProvider.from(trustedRoot);
84+
public Builder trustedRootProvider(TrustedRootProvider trustedRootProvider) {
85+
this.trustedRootProvider = trustedRootProvider;
8686
return this;
8787
}
8888
}

sigstore-java/src/main/java/dev/sigstore/tuf/SigstoreTufClient.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ public class SigstoreTufClient {
4141

4242
@VisibleForTesting static final String TRUST_ROOT_FILENAME = "trusted_root.json";
4343

44+
public static final String PUBLIC_GOOD_ROOT_RESOURCE =
45+
"dev/sigstore/tuf/tuf-root-staging/root.json";
46+
public static final String STAGING_ROOT_RESOURCE = "dev/sigstore/tuf/tuf-root-staging/root.json";
47+
4448
private final Updater updater;
4549
private Instant lastUpdate;
4650
private SigstoreTrustedRoot sigstoreTrustedRoot;
@@ -72,7 +76,7 @@ public Builder usePublicGoodInstance() {
7276
try {
7377
tufMirror(
7478
new URL("https://tuf-repo-cdn.sigstore.dev"),
75-
RootProvider.fromResource("dev/sigstore/tuf/sigstore-tuf-root/root.json"));
79+
RootProvider.fromResource(PUBLIC_GOOD_ROOT_RESOURCE));
7680
} catch (MalformedURLException e) {
7781
throw new AssertionError(e);
7882
}
@@ -87,7 +91,7 @@ public Builder useStagingInstance() {
8791
try {
8892
tufMirror(
8993
new URL("https://tuf-repo-cdn.sigstage.dev"),
90-
RootProvider.fromResource("dev/sigstore/tuf/tuf-root-staging/root.json"));
94+
RootProvider.fromResource(STAGING_ROOT_RESOURCE));
9195
} catch (MalformedURLException e) {
9296
throw new AssertionError(e);
9397
}

0 commit comments

Comments
 (0)