Skip to content

Commit

Permalink
Merge pull request #599 from sigstore/conformance009
Browse files Browse the repository at this point in the history
Rework trusted root injection for conformance v0.0.9
  • Loading branch information
loosebazooka authored Dec 28, 2023
2 parents 76aca3e + 9a98407 commit 5f17fc9
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ jobs:
- name: Unpack sigstore-java distribution
run: tar -xvf ${{ github.workspace }}/sigstore-cli/build/distributions/sigstore-cli-*.tar --strip-components 1

- uses: sigstore/sigstore-conformance@00922385de455be5ec46288a947044aa44fb0981 # v0.0.8
- uses: sigstore/sigstore-conformance@c8d17eb7ee884cf86b93a3a3f471648fb0a83819 # v0.0.9
with:
entrypoint: ${{ github.workspace }}/bin/sigstore-cli
5 changes: 4 additions & 1 deletion sigstore-cli/src/main/java/dev/sigstore/cli/Sign.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.concurrent.Callable;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
Expand Down Expand Up @@ -57,7 +58,9 @@ public Integer call() throws Exception {
var signer = signerBuilder.build();
var signingResult = signer.signFile(artifact);
if (signatureFiles.sigAndCert != null) {
Files.write(signatureFiles.sigAndCert.signatureFile, signingResult.getSignature());
Files.write(
signatureFiles.sigAndCert.signatureFile,
Base64.getEncoder().encode(signingResult.getSignature()));
Files.write(
signatureFiles.sigAndCert.certificateFile,
Certificates.toPemBytes(signingResult.getCertPath()));
Expand Down
16 changes: 14 additions & 2 deletions sigstore-cli/src/main/java/dev/sigstore/cli/Verify.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.cert.CertPath;
import java.util.Base64;
import java.util.concurrent.Callable;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
Expand All @@ -50,6 +51,12 @@ public class Verify implements Callable<Integer> {
@ArgGroup(multiplicity = "0..1", exclusive = false)
Policy policy;

@Option(
names = {"--trusted-root"},
description = "an alternative to the TUF managed sigstore public good trusted root",
required = false)
Path trustedRoot;

static class Policy {
@Option(
names = {"--certificate-identity"},
Expand All @@ -70,7 +77,9 @@ public Integer call() throws Exception {
KeylessSignature keylessSignature;

if (signatureFiles.sigAndCert != null) {
byte[] signature = Files.readAllBytes(signatureFiles.sigAndCert.signatureFile);
byte[] signature =
Base64.getMimeDecoder()
.decode(Files.readAllBytes(signatureFiles.sigAndCert.signatureFile));
CertPath certPath =
Certificates.fromPemChain(Files.readAllBytes(signatureFiles.sigAndCert.certificateFile));
keylessSignature =
Expand All @@ -91,7 +100,10 @@ public Integer call() throws Exception {
}
var verificationOptions = verificationOptionsBuilder.alwaysUseRemoteRekorEntry(false).build();

var verifier = new KeylessVerifier.Builder().sigstorePublicDefaults().build();
var verifier =
(trustedRoot == null)
? new KeylessVerifier.Builder().sigstorePublicDefaults().build()
: new KeylessVerifier.Builder().fromTrustedRoot(trustedRoot).build();
verifier.verify(
artifact,
KeylessVerificationRequest.builder()
Expand Down
18 changes: 12 additions & 6 deletions sigstore-java/src/main/java/dev/sigstore/KeylessVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,33 @@ public static KeylessVerifier.Builder builder() {
}

public static class Builder {
private SigstoreTufClient sigstoreTufClient;
private TrustedRootProvider trustedRootProvider;

public KeylessVerifier build()
throws InvalidAlgorithmParameterException, CertificateException, InvalidKeySpecException,
NoSuchAlgorithmException, IOException, InvalidKeyException {
Preconditions.checkNotNull(sigstoreTufClient);
sigstoreTufClient.update();
var trustedRoot = sigstoreTufClient.getSigstoreTrustedRoot();
Preconditions.checkNotNull(trustedRootProvider);
var trustedRoot = trustedRootProvider.get();
var fulcioVerifier = FulcioVerifier.newFulcioVerifier(trustedRoot);
var rekorClient = RekorClient.builder().setTransparencyLog(trustedRoot).build();
var rekorVerifier = RekorVerifier.newRekorVerifier(trustedRoot);
return new KeylessVerifier(fulcioVerifier, rekorClient, rekorVerifier);
}

public Builder sigstorePublicDefaults() throws IOException {
sigstoreTufClient = SigstoreTufClient.builder().usePublicGoodInstance().build();
var sigstoreTufClient = SigstoreTufClient.builder().usePublicGoodInstance().build();
trustedRootProvider = TrustedRootProvider.from(sigstoreTufClient);
return this;
}

public Builder sigstoreStagingDefaults() throws IOException {
sigstoreTufClient = SigstoreTufClient.builder().useStagingInstance().build();
var sigstoreTufClient = SigstoreTufClient.builder().useStagingInstance().build();
trustedRootProvider = TrustedRootProvider.from(sigstoreTufClient);
return this;
}

public Builder fromTrustedRoot(Path trustedRoot) {
trustedRootProvider = TrustedRootProvider.from(trustedRoot);
return this;
}
}
Expand Down
57 changes: 57 additions & 0 deletions sigstore-java/src/main/java/dev/sigstore/TrustedRootProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2023 The Sigstore Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.sigstore;

import com.google.common.base.Preconditions;
import com.google.protobuf.util.JsonFormat;
import dev.sigstore.proto.trustroot.v1.TrustedRoot;
import dev.sigstore.trustroot.SigstoreTrustedRoot;
import dev.sigstore.tuf.SigstoreTufClient;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.spec.InvalidKeySpecException;

@FunctionalInterface
public interface TrustedRootProvider {

SigstoreTrustedRoot get()
throws InvalidAlgorithmParameterException, CertificateException, InvalidKeySpecException,
NoSuchAlgorithmException, IOException, InvalidKeyException;

static TrustedRootProvider from(SigstoreTufClient tufClient) {
Preconditions.checkNotNull(tufClient);
return () -> {
tufClient.update();
return tufClient.getSigstoreTrustedRoot();
};
}

static TrustedRootProvider from(Path trustedRoot) {
Preconditions.checkNotNull(trustedRoot);
return () -> {
var trustedRootBuilder = TrustedRoot.newBuilder();
JsonFormat.parser()
.merge(Files.readString(trustedRoot, StandardCharsets.UTF_8), trustedRootBuilder);
return SigstoreTrustedRoot.from(trustedRootBuilder.build());
};
}
}

0 comments on commit 5f17fc9

Please sign in to comment.