Skip to content

Commit

Permalink
Remove current tlog/ca refs from trusted_root
Browse files Browse the repository at this point in the history
- Removes determination of signing configuraiton urls from the trusted_root.json.
- Simplifies representation of SigstoreTrustedRoot
- Initializes signers using known defaults

Signed-off-by: Appu Goundan <[email protected]>
  • Loading branch information
loosebazooka committed Apr 2, 2024
1 parent 1ba6f8b commit fc6beb1
Show file tree
Hide file tree
Showing 20 changed files with 164 additions and 424 deletions.
14 changes: 5 additions & 9 deletions fuzzing/src/main/java/util/Tuf.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@

import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.google.common.hash.Hashing;
import dev.sigstore.trustroot.CertificateAuthorities;
import dev.sigstore.trustroot.CertificateAuthority;
import dev.sigstore.trustroot.ImmutableCertificateAuthorities;
import dev.sigstore.trustroot.ImmutableCertificateAuthority;
import dev.sigstore.trustroot.ImmutableLogId;
import dev.sigstore.trustroot.ImmutablePublicKey;
import dev.sigstore.trustroot.ImmutableSubject;
import dev.sigstore.trustroot.ImmutableTransparencyLog;
import dev.sigstore.trustroot.ImmutableTransparencyLogs;
import dev.sigstore.trustroot.ImmutableValidFor;
import dev.sigstore.trustroot.TransparencyLog;
import dev.sigstore.trustroot.TransparencyLogs;
import java.io.ByteArrayInputStream;
import java.net.URI;
import java.security.cert.CertPath;
Expand All @@ -47,17 +43,17 @@ public final class Tuf {
// ecdsa key size in bytes
private static final int ECDSA_KEY_BYTES = 91;

public static TransparencyLogs transparencyLogsFrom(FuzzedDataProvider data) {
return ImmutableTransparencyLogs.builder().addTransparencyLog(genTlog(data)).build();
public static List<TransparencyLog> transparencyLogsFrom(FuzzedDataProvider data) {
return List.of(genTlog(data));
}

public static CertificateAuthorities certificateAuthoritiesFrom(FuzzedDataProvider data)
public static List<CertificateAuthority> certificateAuthoritiesFrom(FuzzedDataProvider data)
throws CertificateException {
return ImmutableCertificateAuthorities.builder().addCertificateAuthority(genCA(data)).build();
return List.of(genCA(data));
}

private static CertPath genCertPath(FuzzedDataProvider data) throws CertificateException {
List<Certificate> certList = new ArrayList<Certificate>();
List<Certificate> certList = new ArrayList<>();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
certList.add(
cf.generateCertificate(new ByteArrayInputStream(data.consumeBytes(MAX_CERT_SIZE))));
Expand Down
60 changes: 44 additions & 16 deletions sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
import dev.sigstore.rekor.client.RekorResponse;
import dev.sigstore.rekor.client.RekorVerificationException;
import dev.sigstore.rekor.client.RekorVerifier;
import dev.sigstore.trustroot.SigstoreTrustedRoot;
import dev.sigstore.tuf.SigstoreTufClient;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.security.InvalidAlgorithmParameterException;
Expand Down Expand Up @@ -132,15 +134,29 @@ public static Builder builder() {
}

public static class Builder {
private SigstoreTufClient sigstoreTufClient;
private OidcClients oidcClients;
private List<OidcIdentity> oidcIdentities = Collections.emptyList();
private Signer signer;
private Duration minSigningCertificateLifetime = DEFAULT_MIN_SIGNING_CERTIFICATE_LIFETIME;
private URI fulcioUri;
private URI rekorUri;
private SigstoreTrustedRoot trustedRoot;

@CanIgnoreReturnValue
public Builder sigstoreTufClient(SigstoreTufClient sigstoreTufClient) {
this.sigstoreTufClient = sigstoreTufClient;
public Builder fulcioUrl(URI uri) {
this.fulcioUri = uri;
return this;
}

@CanIgnoreReturnValue
public Builder rekorUrl(URI uri) {
this.rekorUri = uri;
return this;
}

@CanIgnoreReturnValue
public Builder trustedRoot(SigstoreTrustedRoot trustedRoot) {
this.trustedRoot = trustedRoot;
return this;
}

Expand All @@ -152,7 +168,8 @@ public Builder oidcClients(OidcClients oidcClients) {

/**
* An allow list OIDC identities to be used during signing. If the OidcClients are misconfigured
* or pick up unexpected credentials, this should prevent signing from proceeding
* or pick up unexpected credentials, this should prevent signing from proceeding. Cannot be
* null but can be an empty list and will allow all identities.
*/
@CanIgnoreReturnValue
public Builder allowedOidcIdentities(List<OidcIdentity> oidcIdentities) {
Expand Down Expand Up @@ -188,14 +205,16 @@ public Builder minSigningCertificateLifetime(Duration minSigningCertificateLifet
public KeylessSigner build()
throws CertificateException, IOException, NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException, InvalidAlgorithmParameterException {
Preconditions.checkNotNull(sigstoreTufClient, "sigstoreTufClient");
sigstoreTufClient.update();
var trustedRoot = sigstoreTufClient.getSigstoreTrustedRoot();
var fulcioClient =
FulcioClient.builder().setUri(trustedRoot.getCAs().current().getUri()).build();
Preconditions.checkNotNull(fulcioUri);
Preconditions.checkNotNull(rekorUri);
Preconditions.checkNotNull(trustedRoot);
Preconditions.checkNotNull(oidcClients);
Preconditions.checkNotNull(oidcIdentities);
Preconditions.checkNotNull(signer);
Preconditions.checkNotNull(minSigningCertificateLifetime);
var fulcioClient = FulcioClient.builder().setUri(fulcioUri).build();
var fulcioVerifier = FulcioVerifier.newFulcioVerifier(trustedRoot);
var rekorClient =
RekorClient.builder().setUri(trustedRoot.getTLogs().current().getBaseUrl()).build();
var rekorClient = RekorClient.builder().setUri(rekorUri).build();
var rekorVerifier = RekorVerifier.newRekorVerifier(trustedRoot);
return new KeylessSigner(
fulcioClient,
Expand All @@ -213,9 +232,15 @@ public KeylessSigner build()
* ecdsa signing.
*/
@CanIgnoreReturnValue
public Builder sigstorePublicDefaults() throws IOException, NoSuchAlgorithmException {
sigstoreTufClient = SigstoreTufClient.builder().usePublicGoodInstance().build();
oidcClients(OidcClients.DEFAULTS);
public Builder sigstorePublicDefaults()
throws IOException, NoSuchAlgorithmException, CertificateException, InvalidKeySpecException,
InvalidKeyException {
var sigstoreTufClient = SigstoreTufClient.builder().usePublicGoodInstance().build();
sigstoreTufClient.update();
trustedRoot = sigstoreTufClient.getSigstoreTrustedRoot();
fulcioUri = FulcioClient.PUBLIC_GOOD_URI;
rekorUri = RekorClient.PUBLIC_GOOD_URI;
oidcClients(OidcClients.PUBLIC_GOOD);
signer(Signers.newEcdsaSigner());
minSigningCertificateLifetime(DEFAULT_MIN_SIGNING_CERTIFICATE_LIFETIME);
return this;
Expand All @@ -227,8 +252,11 @@ public Builder sigstorePublicDefaults() throws IOException, NoSuchAlgorithmExcep
*/
@CanIgnoreReturnValue
public Builder sigstoreStagingDefaults() throws IOException, NoSuchAlgorithmException {
sigstoreTufClient = SigstoreTufClient.builder().useStagingInstance().build();
oidcClients(OidcClients.STAGING_DEFAULTS);
var sigstoreTufClient = SigstoreTufClient.builder().useStagingInstance().build();
trustedRoot = sigstoreTufClient.getSigstoreTrustedRoot();
fulcioUri = FulcioClient.STAGING_URI;
rekorUri = RekorClient.STAGING_URI;
oidcClients(OidcClients.STAGING);
signer(Signers.newEcdsaSigner());
minSigningCertificateLifetime(DEFAULT_MIN_SIGNING_CERTIFICATE_LIFETIME);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public KeylessVerifier build()
var fulcioVerifier = FulcioVerifier.newFulcioVerifier(trustedRoot);
var rekorVerifier = RekorVerifier.newRekorVerifier(trustedRoot);
var rekorClients =
trustedRoot.getTLogs().getTransparencyLogs().stream()
trustedRoot.getTLogs().stream()
.map(TransparencyLog::getBaseUrl)
.distinct()
.map(uri -> RekorClient.builder().setUri(uri).build())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
/** A client to communicate with a fulcio service instance over gRPC. */
public class FulcioClient {

public static final URI PUBLIC_GOOD_URI = URI.create("https://fulcio.sigstore.dev");
public static final URI STAGING_URI = URI.create("https://fulcio.sigstage.dev");

private final HttpParams httpParams;
private final URI uri;

Expand All @@ -55,7 +58,7 @@ private FulcioClient(HttpParams httpParams, URI uri) {
}

public static class Builder {
private URI uri = URI.create("https://fulcio.sigstore.dev");
private URI uri = PUBLIC_GOOD_URI;
private HttpParams httpParams = ImmutableHttpParams.builder().build();

private Builder() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import dev.sigstore.encryption.certificates.transparency.CTLogInfo;
import dev.sigstore.encryption.certificates.transparency.CTVerificationResult;
import dev.sigstore.encryption.certificates.transparency.CTVerifier;
import dev.sigstore.trustroot.CertificateAuthorities;
import dev.sigstore.trustroot.CertificateAuthority;
import dev.sigstore.trustroot.SigstoreTrustedRoot;
import dev.sigstore.trustroot.TransparencyLogs;
import dev.sigstore.trustroot.TransparencyLog;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
Expand All @@ -46,8 +46,8 @@

/** Verifier for fulcio generated signing cerificates */
public class FulcioVerifier {
private final CertificateAuthorities cas;
private final TransparencyLogs ctLogs;
private final List<CertificateAuthority> cas;
private final List<TransparencyLog> ctLogs;
private final CTVerifier ctVerifier;

public static FulcioVerifier newFulcioVerifier(SigstoreTrustedRoot trustRoot)
Expand All @@ -57,11 +57,11 @@ public static FulcioVerifier newFulcioVerifier(SigstoreTrustedRoot trustRoot)
}

public static FulcioVerifier newFulcioVerifier(
CertificateAuthorities cas, TransparencyLogs ctLogs)
List<CertificateAuthority> cas, List<TransparencyLog> ctLogs)
throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
CertificateException {
List<CTLogInfo> logs = new ArrayList<>();
for (var ctLog : ctLogs.all()) {
for (var ctLog : ctLogs) {
logs.add(
new CTLogInfo(
ctLog.getPublicKey().toJavaPublicKey(), "CT Log", ctLog.getBaseUrl().toString()));
Expand All @@ -75,15 +75,15 @@ public static FulcioVerifier newFulcioVerifier(
.orElse(null));

// check to see if we can use all fulcio roots (this is a bit eager)
for (var ca : cas.all()) {
for (var ca : cas) {
ca.asTrustAnchor();
}

return new FulcioVerifier(cas, ctLogs, verifier);
}

private FulcioVerifier(
CertificateAuthorities cas, TransparencyLogs ctLogs, CTVerifier ctVerifier) {
List<CertificateAuthority> cas, List<TransparencyLog> ctLogs, CTVerifier ctVerifier) {
this.cas = cas;
this.ctLogs = ctLogs;
this.ctVerifier = ctVerifier;
Expand Down Expand Up @@ -122,7 +122,7 @@ private void verifyEmbeddedScts(CertPath certPath) throws FulcioVerificationExce
var logId = sct.getLogID();
var entryTime = Instant.ofEpochMilli(sct.getTimestamp());

var ctLog = ctLogs.find(logId, entryTime);
var ctLog = TransparencyLog.find(ctLogs, logId, entryTime);
if (ctLog.isPresent()) {
// TODO: currently we only require one valid SCT, but maybe this should be configurable?
// found at least one valid sct with a matching valid log
Expand Down Expand Up @@ -178,7 +178,7 @@ CertPath validateCertPath(CertPath signingCertificate) throws FulcioVerification
}

var leaf = Certificates.getLeaf(signingCertificate);
var validCAs = cas.find(leaf.getNotBefore().toInstant());
var validCAs = CertificateAuthority.find(cas, leaf.getNotBefore().toInstant());

if (validCAs.size() == 0) {
throw new FulcioVerificationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
/** An ordered list of oidc clients to use when looking for credentials. */
public class OidcClients {

public static final OidcClients DEFAULTS =
public static final OidcClients PUBLIC_GOOD =
of(GithubActionsOidcClient.builder().build(), WebOidcClient.builder().build());

public static final OidcClients STAGING_DEFAULTS =
public static final OidcClients STAGING =
of(
GithubActionsOidcClient.builder().build(),
WebOidcClient.builder().setIssuer(WebOidcClient.STAGING_DEX_ISSUER).build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

/** A client to communicate with a rekor service instance. */
public class RekorClient {
public static final URI PUBLIC_GOOD_URI = URI.create("https://rekor.sigstore.dev");
public static final URI STAGING_URI = URI.create("https://rekor.sigstage.dev");

public static final String REKOR_ENTRIES_PATH = "/api/v1/log/entries";
public static final String REKOR_INDEX_SEARCH_PATH = "/api/v1/index/retrieve";

Expand All @@ -52,7 +55,7 @@ private RekorClient(HttpParams httpParams, URI uri) {

public static class Builder {
private HttpParams httpParams = ImmutableHttpParams.builder().build();
private URI uri = URI.create("https://rekor.sigstore.dev");
private URI uri = PUBLIC_GOOD_URI;

private Builder() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@
import dev.sigstore.rekor.client.RekorEntry.Checkpoint;
import dev.sigstore.trustroot.SigstoreTrustedRoot;
import dev.sigstore.trustroot.TransparencyLog;
import dev.sigstore.trustroot.TransparencyLogs;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import org.bouncycastle.util.encoders.Hex;

/** Verifier for rekor entries. */
public class RekorVerifier {
private final TransparencyLogs tlogs;
private final List<TransparencyLog> tlogs;

public static RekorVerifier newRekorVerifier(SigstoreTrustedRoot trustRoot) {
return newRekorVerifier(trustRoot.getTLogs());
}

public static RekorVerifier newRekorVerifier(TransparencyLogs tlogs) {
public static RekorVerifier newRekorVerifier(List<TransparencyLog> tlogs) {
return new RekorVerifier(tlogs);
}

private RekorVerifier(TransparencyLogs tlogs) {
private RekorVerifier(List<TransparencyLog> tlogs) {
this.tlogs = tlogs;
}

Expand All @@ -61,8 +61,7 @@ public void verifyEntry(RekorEntry entry) throws RekorVerificationException {
}

var tlog =
tlogs
.find(Hex.decode(entry.getLogID()), entry.getIntegratedTimeInstant())
TransparencyLog.find(tlogs, Hex.decode(entry.getLogID()), entry.getIntegratedTimeInstant())
.orElseThrow(
() ->
new RekorVerificationException(
Expand Down
Loading

0 comments on commit fc6beb1

Please sign in to comment.