Skip to content

Commit

Permalink
Merge pull request #704 from sigstore/bundles-pt2
Browse files Browse the repository at this point in the history
Change all APIs to use bundle instead of keylessSignature
  • Loading branch information
loosebazooka authored May 19, 2024
2 parents ae185ca + a6f2df6 commit 0e81bff
Show file tree
Hide file tree
Showing 16 changed files with 348 additions and 255 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package fuzzing;

import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import dev.sigstore.KeylessVerificationRequest.CertificateIdentity;
import dev.sigstore.VerificationOptions.CertificateIdentity;
import dev.sigstore.fulcio.client.FulcioCertificateVerifier;
import dev.sigstore.fulcio.client.FulcioVerificationException;
import java.io.ByteArrayInputStream;
Expand Down
12 changes: 4 additions & 8 deletions sigstore-cli/src/main/java/dev/sigstore/cli/Sign.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package dev.sigstore.cli;

import dev.sigstore.KeylessSigner;
import dev.sigstore.bundle.Bundle;
import dev.sigstore.encryption.certificates.Certificates;
import dev.sigstore.oidc.client.OidcClients;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -66,18 +65,15 @@ public Integer call() throws Exception {
signerBuilder.oidcClients(OidcClients.of(new TokenStringOidcClient(identityToken)));
}
var signer = signerBuilder.build();
var signingResult = signer.signFile(artifact);
var bundle = signer.signFile2(artifact);
if (signatureFiles.sigAndCert != null) {
Files.write(
signatureFiles.sigAndCert.signatureFile,
Base64.getEncoder().encode(signingResult.getSignature()));
Base64.getEncoder().encode(bundle.getMessageSignature().get().getSignature()));
Files.write(
signatureFiles.sigAndCert.certificateFile,
Certificates.toPemBytes(signingResult.getCertPath()));
signatureFiles.sigAndCert.certificateFile, Certificates.toPemBytes(bundle.getCertPath()));
} else {
Files.write(
signatureFiles.bundleFile,
Bundle.from(signingResult).toJson().getBytes(StandardCharsets.UTF_8));
Files.write(signatureFiles.bundleFile, bundle.toJson().getBytes(StandardCharsets.UTF_8));
}
return 0;
}
Expand Down
40 changes: 23 additions & 17 deletions sigstore-cli/src/main/java/dev/sigstore/cli/Verify.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
import static com.google.common.io.Files.newReader;

import com.google.common.hash.Hashing;
import dev.sigstore.KeylessSignature;
import dev.sigstore.KeylessVerificationRequest;
import dev.sigstore.KeylessVerificationRequest.CertificateIdentity;
import dev.sigstore.KeylessVerificationRequest.VerificationOptions;
import dev.sigstore.KeylessVerifier;
import dev.sigstore.VerificationOptions;
import dev.sigstore.VerificationOptions.CertificateIdentity;
import dev.sigstore.bundle.Bundle;
import dev.sigstore.bundle.Bundle.HashAlgorithm;
import dev.sigstore.bundle.Bundle.MessageSignature;
import dev.sigstore.bundle.ImmutableBundle;
import dev.sigstore.encryption.certificates.Certificates;
import dev.sigstore.rekor.client.RekorEntryFetcher;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -90,20 +92,29 @@ static class Policy {
@Override
public Integer call() throws Exception {
byte[] digest = asByteSource(artifact.toFile()).hash(Hashing.sha256()).asBytes();
KeylessSignature keylessSignature;

Bundle bundle;
if (signatureFiles.sigAndCert != null) {
byte[] signature =
Base64.getMimeDecoder()
.decode(Files.readAllBytes(signatureFiles.sigAndCert.signatureFile));
CertPath certPath =
Certificates.fromPemChain(Files.readAllBytes(signatureFiles.sigAndCert.certificateFile));
keylessSignature =
KeylessSignature.builder().signature(signature).certPath(certPath).digest(digest).build();
RekorEntryFetcher fetcher =
target == null
? RekorEntryFetcher.sigstorePublicGood()
: target.staging
? RekorEntryFetcher.sigstoreStaging()
: RekorEntryFetcher.fromTrustedRoot(target.trustedRoot);
bundle =
ImmutableBundle.builder()
.messageSignature(MessageSignature.of(HashAlgorithm.SHA2_256, digest, signature))
.certPath(certPath)
.addEntries(
fetcher.getEntryFromRekor(digest, Certificates.getLeaf(certPath), signature))
.build();
} else {
Bundle bundle =
Bundle.from(newReader(signatureFiles.bundleFile.toFile(), StandardCharsets.UTF_8));
keylessSignature = bundle.toKeylessSignature();
bundle = Bundle.from(newReader(signatureFiles.bundleFile.toFile(), StandardCharsets.UTF_8));
}

var verificationOptionsBuilder = VerificationOptions.builder();
Expand All @@ -114,20 +125,15 @@ public Integer call() throws Exception {
.subjectAlternativeName(policy.certificateSan)
.build());
}
var verificationOptions = verificationOptionsBuilder.alwaysUseRemoteRekorEntry(false).build();
var verificationOptions = verificationOptionsBuilder.build();

var verifier =
target == null
? new KeylessVerifier.Builder().sigstorePublicDefaults().build()
: target.staging
? new KeylessVerifier.Builder().sigstoreStagingDefaults().build()
: new KeylessVerifier.Builder().fromTrustedRoot(target.trustedRoot).build();
verifier.verify(
artifact,
KeylessVerificationRequest.builder()
.keylessSignature(keylessSignature)
.verificationOptions(verificationOptions)
.build());
verifier.verify(artifact, bundle, verificationOptions);
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ abstract class SignWorkAction : WorkAction<SignWorkParameters> {
}.build()
}

val result = signer.signFile(inputFile.toPath())
val bundleJson = Bundle.from(result).toJson()
val result = signer.signFile2(inputFile.toPath())
val bundleJson = result.toJson()
parameters.outputSignature.get().asFile.writeText(bundleJson)
}
}
36 changes: 25 additions & 11 deletions sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import dev.sigstore.KeylessVerifier.Builder;
import dev.sigstore.bundle.Bundle;
import dev.sigstore.bundle.Bundle.HashAlgorithm;
import dev.sigstore.bundle.Bundle.MessageSignature;
import dev.sigstore.bundle.ImmutableBundle;
import dev.sigstore.encryption.certificates.Certificates;
import dev.sigstore.encryption.signers.Signer;
import dev.sigstore.encryption.signers.Signers;
Expand Down Expand Up @@ -270,13 +273,13 @@ public Builder sigstoreStagingDefaults() {
* @return a list of keyless singing results.
*/
@CheckReturnValue
public List<KeylessSignature> sign(List<byte[]> artifactDigests) throws KeylessSignerException {
public List<Bundle> sign(List<byte[]> artifactDigests) throws KeylessSignerException {

if (artifactDigests.size() == 0) {
throw new IllegalArgumentException("Require one or more digests");
}

var result = ImmutableList.<KeylessSignature>builder();
var result = ImmutableList.<Bundle>builder();

for (var artifactDigest : artifactDigests) {
byte[] signature;
Expand Down Expand Up @@ -334,11 +337,11 @@ public List<KeylessSignature> sign(List<byte[]> artifactDigests) throws KeylessS
}

result.add(
KeylessSignature.builder()
.digest(artifactDigest)
ImmutableBundle.builder()
.certPath(signingCert)
.signature(signature)
.entry(rekorResponse.getEntry())
.addEntries(rekorResponse.getEntry())
.messageSignature(
MessageSignature.of(HashAlgorithm.SHA2_256, artifactDigest, signature))
.build());
}
return result.build();
Expand Down Expand Up @@ -409,7 +412,7 @@ private void renewSigningCertificate()
* @return a keyless singing results.
*/
@CheckReturnValue
public KeylessSignature sign(byte[] artifactDigest) throws KeylessSignerException {
public Bundle sign(byte[] artifactDigest) throws KeylessSignerException {
return sign(List.of(artifactDigest)).get(0);
}

Expand All @@ -420,7 +423,7 @@ public KeylessSignature sign(byte[] artifactDigest) throws KeylessSignerExceptio
* @return a map of artifacts and their keyless singing results.
*/
@CheckReturnValue
public Map<Path, KeylessSignature> signFiles(List<Path> artifacts) throws KeylessSignerException {
public Map<Path, Bundle> signFiles(List<Path> artifacts) throws KeylessSignerException {
if (artifacts.size() == 0) {
throw new IllegalArgumentException("Require one or more paths");
}
Expand All @@ -434,21 +437,32 @@ public Map<Path, KeylessSignature> signFiles(List<Path> artifacts) throws Keyles
}
}
var signingResult = sign(digests);
var result = ImmutableMap.<Path, KeylessSignature>builder();
var result = ImmutableMap.<Path, Bundle>builder();
for (int i = 0; i < artifacts.size(); i++) {
result.put(artifacts.get(i), signingResult.get(i));
}
return result.build();
}

/**
* Convenience wrapper around {@link #sign(List)} to accept a file instead of digests
* Convenience wrapper around {@link #sign(List)} to accept a single file This is a compat method
* and will be switched out with signFile2
*
* @param artifact the artifacts to sign.
* @return a keyless singing results.
*/
@CheckReturnValue
public KeylessSignature signFile(Path artifact) throws KeylessSignerException {
return signFiles(List.of(artifact)).get(artifact).toKeylessSignature();
}

/**
* Convenience wrapper around {@link #sign(List)} to accept a signe file
*
* @param artifact the artifacts to sign
* @return a sigstore bundle
*/
public Bundle signFile2(Path artifact) throws KeylessSignerException {
return signFiles(List.of(artifact)).get(artifact);
}
}

This file was deleted.

Loading

0 comments on commit 0e81bff

Please sign in to comment.