diff --git a/cmd/cosign/cli/verify/verify_blob.go b/cmd/cosign/cli/verify/verify_blob.go index be72e5e73be..08eb4c8aeae 100644 --- a/cmd/cosign/cli/verify/verify_blob.go +++ b/cmd/cosign/cli/verify/verify_blob.go @@ -40,6 +40,7 @@ import ( sigs "github.com/sigstore/cosign/v2/pkg/signature" sgbundle "github.com/sigstore/sigstore-go/pkg/bundle" + "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore/pkg/cryptoutils" ) @@ -82,7 +83,7 @@ func (c *VerifyBlobCmd) loadTSACertificates(ctx context.Context) (*cosign.TSACer } // nolint -func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { +func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) (err error) { // Require a certificate/key OR a local bundle file that has the cert. if options.NOf(c.KeyRef, c.CertRef, c.Sk, c.BundlePath) == 0 { return fmt.Errorf("provide a key with --key or --sk, a certificate to verify against with --certificate, or a bundle with --bundle") @@ -93,33 +94,6 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { return &options.PubKeyParseError{} } - if c.KeyOpts.NewBundleFormat { - if options.NOf(c.RFC3161TimestampPath, c.TSACertChainPath, c.RekorURL, c.CertChain, c.CARoots, c.CAIntermediates, c.CertRef, c.SigRef, c.SCTRef) > 1 { - return fmt.Errorf("when using --new-bundle-format, please supply signed content with --bundle and verification content with --trusted-root") - } - b, err := sgbundle.LoadJSONFromPath(c.BundlePath) - if err != nil { - return err - } - _, err = verifyNewBundle(ctx, b, c.TrustedRootPath, c.KeyRef, c.Slot, c.CertVerifyOptions.CertOidcIssuer, c.CertVerifyOptions.CertOidcIssuerRegexp, c.CertVerifyOptions.CertIdentity, c.CertVerifyOptions.CertIdentityRegexp, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef, blobRef, c.Sk, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) - if err == nil { - ui.Infof(ctx, "Verified OK") - } - return err - } - - var cert *x509.Certificate - opts := make([]static.Option, 0) - - sig, err := base64signature(c.SigRef, c.BundlePath) - if err != nil { - return err - } - sigBytes, err := base64.StdEncoding.DecodeString(sig) - if err != nil { - return err - } - co := &cosign.CheckOpts{ CertGithubWorkflowTrigger: c.CertGithubWorkflowTrigger, CertGithubWorkflowSha: c.CertGithubWorkflowSHA, @@ -152,7 +126,50 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { if err != nil { return fmt.Errorf("loading public key from token: %w", err) } - case c.CertRef != "": + } + + var trustedroot *root.TrustedRoot + co.TrustedMaterial, trustedroot, err = makeTrustedMaterial(c.TrustedRootPath, &co.SigVerifier) + if err != nil { + return err + } + + co.VerifierOptions = makeVerifierOptions(trustedroot, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) + + if c.KeyOpts.NewBundleFormat { + if options.NOf(c.RFC3161TimestampPath, c.TSACertChainPath, c.RekorURL, c.CertChain, c.CARoots, c.CAIntermediates, c.CertRef, c.SigRef, c.SCTRef) > 1 { + return fmt.Errorf("when using --new-bundle-format, please supply signed content with --bundle and verification content with --trusted-root") + } + b, err := sgbundle.LoadJSONFromPath(c.BundlePath) + if err != nil { + return err + } + + co.IdentityPolicies, err = makeIdentityPolicy(b, c.CertVerifyOptions, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef) + if err != nil { + return err + } + + _, err = verifyNewBundle(b, co, blobRef) + if err == nil { + ui.Infof(ctx, "Verified OK") + } + return err + } + + var cert *x509.Certificate + opts := make([]static.Option, 0) + + sig, err := base64signature(c.SigRef, c.BundlePath) + if err != nil { + return err + } + sigBytes, err := base64.StdEncoding.DecodeString(sig) + if err != nil { + return err + } + + if c.CertRef != "" { cert, err = loadCertFromFileOrURL(c.CertRef) if err != nil { return err @@ -228,7 +245,12 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { return err } - _, err = verifyNewBundle(ctx, b, c.TrustedRootPath, c.KeyRef, c.Slot, c.CertVerifyOptions.CertOidcIssuer, c.CertVerifyOptions.CertOidcIssuerRegexp, c.CertVerifyOptions.CertIdentity, c.CertVerifyOptions.CertIdentityRegexp, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef, blobRef, c.Sk, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) + co.IdentityPolicies, err = makeIdentityPolicy(b, c.CertVerifyOptions, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef) + + if err != nil { + return err + } + _, err = verifyNewBundle(b, co, blobRef) if err == nil { ui.Infof(ctx, "Verified OK") } diff --git a/cmd/cosign/cli/verify/verify_blob_attestation.go b/cmd/cosign/cli/verify/verify_blob_attestation.go index c33be7c6498..6554526849d 100644 --- a/cmd/cosign/cli/verify/verify_blob_attestation.go +++ b/cmd/cosign/cli/verify/verify_blob_attestation.go @@ -44,6 +44,7 @@ import ( "github.com/sigstore/cosign/v2/pkg/policy" sigs "github.com/sigstore/cosign/v2/pkg/signature" sgbundle "github.com/sigstore/sigstore-go/pkg/bundle" + "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore/pkg/cryptoutils" ) @@ -94,36 +95,6 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st return &options.KeyParseError{} } - if c.KeyOpts.NewBundleFormat { - if options.NOf(c.RFC3161TimestampPath, c.TSACertChainPath, c.RekorURL, c.CertChain, c.CARoots, c.CAIntermediates, c.CertRef, c.SCTRef) > 1 { - return fmt.Errorf("when using --new-bundle-format, please supply signed content with --bundle and verification content with --trusted-root") - } - b, err := sgbundle.LoadJSONFromPath(c.BundlePath) - if err != nil { - return err - } - result, err := verifyNewBundle(ctx, b, c.TrustedRootPath, c.KeyRef, c.Slot, c.CertVerifyOptions.CertOidcIssuer, c.CertVerifyOptions.CertOidcIssuerRegexp, c.CertVerifyOptions.CertIdentity, c.CertVerifyOptions.CertIdentityRegexp, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef, artifactPath, c.Sk, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) - if err != nil { - return err - } - if c.PredicateType != "" && result.Statement.GetPredicateType() != c.PredicateType { - return fmt.Errorf("invalid predicate type, expected %s got %s", c.PredicateType, result.Statement.GetPredicateType()) - } - fmt.Fprintln(os.Stderr, "Verified OK") - return nil - } - - var cert *x509.Certificate - opts := make([]static.Option, 0) - - var encodedSig []byte - if c.SignaturePath != "" { - encodedSig, err = os.ReadFile(filepath.Clean(c.SignaturePath)) - if err != nil { - return fmt.Errorf("reading %s: %w", c.SignaturePath, err) - } - } - co := &cosign.CheckOpts{ CertGithubWorkflowTrigger: c.CertGithubWorkflowTrigger, CertGithubWorkflowSha: c.CertGithubWorkflowSHA, @@ -156,6 +127,53 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st if err != nil { return fmt.Errorf("loading public key from token: %w", err) } + } + + var trustedroot *root.TrustedRoot + co.TrustedMaterial, trustedroot, err = makeTrustedMaterial(c.TrustedRootPath, &co.SigVerifier) + if err != nil { + return err + } + + co.VerifierOptions = makeVerifierOptions(trustedroot, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) + + if c.KeyOpts.NewBundleFormat { + if options.NOf(c.RFC3161TimestampPath, c.TSACertChainPath, c.RekorURL, c.CertChain, c.CARoots, c.CAIntermediates, c.CertRef, c.SCTRef) > 1 { + return fmt.Errorf("when using --new-bundle-format, please supply signed content with --bundle and verification content with --trusted-root") + } + b, err := sgbundle.LoadJSONFromPath(c.BundlePath) + if err != nil { + return err + } + + co.IdentityPolicies, err = makeIdentityPolicy(b, c.CertVerifyOptions, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef) + if err != nil { + return err + } + + result, err := verifyNewBundle(b, co, artifactPath) + if err != nil { + return err + } + if c.PredicateType != "" && result.Statement.GetPredicateType() != c.PredicateType { + return fmt.Errorf("invalid predicate type, expected %s got %s", c.PredicateType, result.Statement.GetPredicateType()) + } + fmt.Fprintln(os.Stderr, "Verified OK") + return nil + } + + var cert *x509.Certificate + opts := make([]static.Option, 0) + + var encodedSig []byte + if c.SignaturePath != "" { + encodedSig, err = os.ReadFile(filepath.Clean(c.SignaturePath)) + if err != nil { + return fmt.Errorf("reading %s: %w", c.SignaturePath, err) + } + } + + switch { case c.CertRef != "": cert, err = loadCertFromFileOrURL(c.CertRef) if err != nil { @@ -246,7 +264,12 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st return err } - result, err := verifyNewBundle(ctx, b, c.TrustedRootPath, c.KeyRef, c.Slot, c.CertVerifyOptions.CertOidcIssuer, c.CertVerifyOptions.CertOidcIssuerRegexp, c.CertVerifyOptions.CertIdentity, c.CertVerifyOptions.CertIdentityRegexp, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef, artifactPath, c.Sk, c.IgnoreTlog, c.UseSignedTimestamps, c.IgnoreSCT) + co.IdentityPolicies, err = makeIdentityPolicy(b, c.CertVerifyOptions, c.CertGithubWorkflowTrigger, c.CertGithubWorkflowSHA, c.CertGithubWorkflowName, c.CertGithubWorkflowRepository, c.CertGithubWorkflowRef) + if err != nil { + return err + } + + result, err := verifyNewBundle(b, co, artifactPath) if err != nil { return err } diff --git a/cmd/cosign/cli/verify/verify_bundle.go b/cmd/cosign/cli/verify/verify_bundle.go index 71f6ff691ef..1439a74b465 100644 --- a/cmd/cosign/cli/verify/verify_bundle.go +++ b/cmd/cosign/cli/verify/verify_bundle.go @@ -39,9 +39,8 @@ import ( "github.com/sigstore/sigstore/pkg/cryptoutils" "github.com/sigstore/sigstore/pkg/signature" + "github.com/sigstore/cosign/v2/cmd/cosign/cli/options" "github.com/sigstore/cosign/v2/pkg/cosign" - "github.com/sigstore/cosign/v2/pkg/cosign/pivkey" - sigs "github.com/sigstore/cosign/v2/pkg/signature" ) type verifyTrustedMaterial struct { @@ -56,122 +55,31 @@ func (v *verifyTrustedMaterial) PublicKeyVerifier(hint string) (root.TimeConstra return v.keyTrustedMaterial.PublicKeyVerifier(hint) } -func verifyNewBundle(ctx context.Context, bundle *sgbundle.Bundle, trustedRootPath, keyRef, slot, certOIDCIssuer, certOIDCIssuerRegex, certIdentity, certIdentityRegexp, githubWorkflowTrigger, githubWorkflowSHA, githubWorkflowName, githubWorkflowRepository, githubWorkflowRef, artifactRef string, sk, ignoreTlog, useSignedTimestamps, ignoreSCT bool) (*verify.VerificationResult, error) { - var trustedroot *root.TrustedRoot - var err error - - if trustedRootPath == "" { - // Assume we're using public good instance; fetch via TUF - trustedroot, err = root.FetchTrustedRoot() - if err != nil { - return nil, err - } - } else { - trustedroot, err = root.NewTrustedRootFromPath(trustedRootPath) - if err != nil { - return nil, err - } - } - - trustedmaterial := &verifyTrustedMaterial{TrustedMaterial: trustedroot} - - // See if we need to wrap trusted root with provided key - if keyRef != "" { - signatureVerifier, err := sigs.PublicKeyFromKeyRef(ctx, keyRef) - if err != nil { - return nil, err - } - - newExpiringKey := root.NewExpiringKey(signatureVerifier, time.Time{}, time.Time{}) - trustedmaterial.keyTrustedMaterial = root.NewTrustedPublicKeyMaterial(func(_ string) (root.TimeConstrainedVerifier, error) { - return newExpiringKey, nil - }) - } else if sk { - s, err := pivkey.GetKeyWithSlot(slot) - if err != nil { - return nil, fmt.Errorf("opening piv token: %w", err) - } - defer s.Close() - signatureVerifier, err := s.Verifier() - if err != nil { - return nil, fmt.Errorf("loading public key from token: %w", err) - } - - newExpiringKey := root.NewExpiringKey(signatureVerifier, time.Time{}, time.Time{}) - trustedmaterial.keyTrustedMaterial = root.NewTrustedPublicKeyMaterial(func(_ string) (root.TimeConstrainedVerifier, error) { - return newExpiringKey, nil - }) - } - - identityPolicies := []verify.PolicyOption{} - - verificationMaterial := bundle.GetVerificationMaterial() - - if verificationMaterial == nil { - return nil, fmt.Errorf("no verification material in bundle") +func verifyNewBundle(bundle *sgbundle.Bundle, checkOpts *cosign.CheckOpts, artifactRef string) (*verify.VerificationResult, error) { + if checkOpts.TrustedMaterial == nil { + return nil, fmt.Errorf("checkOpts must have TrustedMaterial set") } - if verificationMaterial.GetPublicKey() != nil { - identityPolicies = append(identityPolicies, verify.WithKey()) - } else { - sanMatcher, err := verify.NewSANMatcher(certIdentity, certIdentityRegexp) - if err != nil { - return nil, err - } - - issuerMatcher, err := verify.NewIssuerMatcher(certOIDCIssuer, certOIDCIssuerRegex) - if err != nil { - return nil, err - } - - extensions := certificate.Extensions{ - GithubWorkflowTrigger: githubWorkflowTrigger, - GithubWorkflowSHA: githubWorkflowSHA, - GithubWorkflowName: githubWorkflowName, - GithubWorkflowRepository: githubWorkflowRepository, - GithubWorkflowRef: githubWorkflowRef, - } - - certIdentity, err := verify.NewCertificateIdentity(sanMatcher, issuerMatcher, extensions) - if err != nil { - return nil, err - } - - identityPolicies = append(identityPolicies, verify.WithCertificateIdentity(certIdentity)) - } - - // Make some educated guesses about verification policy - verifierConfig := []verify.VerifierOption{} - - if len(trustedroot.RekorLogs()) > 0 && !ignoreTlog { - verifierConfig = append(verifierConfig, verify.WithTransparencyLog(1), verify.WithIntegratedTimestamps(1)) - } - - if len(trustedroot.TimestampingAuthorities()) > 0 && useSignedTimestamps { - verifierConfig = append(verifierConfig, verify.WithSignedTimestamps(1)) + if len(checkOpts.IdentityPolicies) == 0 { + return nil, fmt.Errorf("checkOpts IdentityPolicies must have at least 1 item") } - if !ignoreSCT { - verifierConfig = append(verifierConfig, verify.WithSignedCertificateTimestamps(1)) - } - - if ignoreTlog && !useSignedTimestamps { - verifierConfig = append(verifierConfig, verify.WithoutAnyObserverTimestampsUnsafe()) + if len(checkOpts.VerifierOptions) == 0 { + return nil, fmt.Errorf("checkOpts VerfierOption must have at least 1 item") } - // Perform verification payload, err := payloadBytes(artifactRef) if err != nil { return nil, err } buf := bytes.NewBuffer(payload) - sev, err := verify.NewSignedEntityVerifier(trustedmaterial, verifierConfig...) + sev, err := verify.NewSignedEntityVerifier(checkOpts.TrustedMaterial, checkOpts.VerifierOptions...) if err != nil { return nil, err } - return sev.Verify(bundle, verify.NewPolicy(verify.WithArtifact(buf), identityPolicies...)) + return sev.Verify(bundle, verify.NewPolicy(verify.WithArtifact(buf), checkOpts.IdentityPolicies...)) } func assembleNewBundle(ctx context.Context, sigBytes, signedTimestamp []byte, envelope *dsse.Envelope, artifactRef string, cert *x509.Certificate, ignoreTlog bool, sigVerifier signature.Verifier, pkOpts []signature.PublicKeyOption, rekorClient *client.Rekor) (*sgbundle.Bundle, error) { @@ -315,3 +223,96 @@ func assembleNewBundle(ctx context.Context, sigBytes, signedTimestamp []byte, en return b, nil } + +func makeTrustedMaterial(trustedRootPath string, sigVerifier *signature.Verifier) (root.TrustedMaterial, *root.TrustedRoot, error) { + var trustedroot *root.TrustedRoot + var err error + + if trustedRootPath == "" { + // Assume we're using public good instance; fetch via TUF + trustedroot, err = root.FetchTrustedRoot() + if err != nil { + return nil, nil, err + } + } else { + trustedroot, err = root.NewTrustedRootFromPath(trustedRootPath) + if err != nil { + return nil, nil, err + } + } + + trustedmaterial := &verifyTrustedMaterial{TrustedMaterial: trustedroot} + + if sigVerifier != nil { + newExpiringKey := root.NewExpiringKey(*sigVerifier, time.Time{}, time.Time{}) + trustedmaterial.keyTrustedMaterial = root.NewTrustedPublicKeyMaterial(func(_ string) (root.TimeConstrainedVerifier, error) { + return newExpiringKey, nil + }) + } + + return trustedmaterial, trustedroot, nil +} + +func makeIdentityPolicy(bundle *sgbundle.Bundle, certVerifyOpts options.CertVerifyOptions, githubWorkflowTrigger, githubWorkflowSHA, githubWorkflowName, githubWorkflowRepository, githubWorkflowRef string) ([]verify.PolicyOption, error) { + identityPolicies := []verify.PolicyOption{} + + verificationMaterial := bundle.GetVerificationMaterial() + + if verificationMaterial == nil { + return nil, fmt.Errorf("no verification material in bundle") + } + + if verificationMaterial.GetPublicKey() != nil { + identityPolicies = append(identityPolicies, verify.WithKey()) + } else { + sanMatcher, err := verify.NewSANMatcher(certVerifyOpts.CertIdentity, certVerifyOpts.CertIdentityRegexp) + if err != nil { + return nil, err + } + + issuerMatcher, err := verify.NewIssuerMatcher(certVerifyOpts.CertOidcIssuer, certVerifyOpts.CertOidcIssuerRegexp) + if err != nil { + return nil, err + } + + extensions := certificate.Extensions{ + GithubWorkflowTrigger: githubWorkflowTrigger, + GithubWorkflowSHA: githubWorkflowSHA, + GithubWorkflowName: githubWorkflowName, + GithubWorkflowRepository: githubWorkflowRepository, + GithubWorkflowRef: githubWorkflowRef, + } + + certIdentity, err := verify.NewCertificateIdentity(sanMatcher, issuerMatcher, extensions) + if err != nil { + return nil, err + } + + identityPolicies = append(identityPolicies, verify.WithCertificateIdentity(certIdentity)) + } + + return identityPolicies, nil +} + +func makeVerifierOptions(trustedroot *root.TrustedRoot, ignoreTlog, useSignedTimestamps, ignoreSCT bool) []verify.VerifierOption { + // Make some educated guesses about verification policy + verifierConfig := []verify.VerifierOption{} + + if len(trustedroot.RekorLogs()) > 0 && !ignoreTlog { + verifierConfig = append(verifierConfig, verify.WithTransparencyLog(1), verify.WithIntegratedTimestamps(1)) + } + + if len(trustedroot.TimestampingAuthorities()) > 0 && useSignedTimestamps { + verifierConfig = append(verifierConfig, verify.WithSignedTimestamps(1)) + } + + if !ignoreSCT { + verifierConfig = append(verifierConfig, verify.WithSignedCertificateTimestamps(1)) + } + + if ignoreTlog && !useSignedTimestamps { + verifierConfig = append(verifierConfig, verify.WithoutAnyObserverTimestampsUnsafe()) + } + + return verifierConfig +} diff --git a/cmd/cosign/cli/verify/verify_bundle_test.go b/cmd/cosign/cli/verify/verify_bundle_test.go index 04dfc82334b..ffd2c21bd83 100644 --- a/cmd/cosign/cli/verify/verify_bundle_test.go +++ b/cmd/cosign/cli/verify/verify_bundle_test.go @@ -28,6 +28,10 @@ import ( "path/filepath" "testing" + "github.com/sigstore/sigstore-go/pkg/root" + + "github.com/sigstore/cosign/v2/cmd/cosign/cli/options" + "github.com/sigstore/cosign/v2/pkg/cosign" "github.com/sigstore/cosign/v2/pkg/signature" ) @@ -76,7 +80,20 @@ func TestVerifyBundleWithKey(t *testing.T) { err = os.WriteFile(publicKeyPath, pem.EncodeToMemory(pemBlock), 0600) checkErr(t, err) - result, err := verifyNewBundle(ctx, bundle, trustedRootPath, publicKeyPath, "", "", "", "", "", "", "", "", "", "", artifactPath, false, true, false, true) + co := &cosign.CheckOpts{} + co.SigVerifier, err = signature.PublicKeyFromKeyRef(ctx, publicKeyPath) + checkErr(t, err) + + var trustedroot *root.TrustedRoot + co.TrustedMaterial, trustedroot, err = makeTrustedMaterial(trustedRootPath, &co.SigVerifier) + checkErr(t, err) + + co.IdentityPolicies, err = makeIdentityPolicy(bundle, options.CertVerifyOptions{}, "", "", "", "", "") + checkErr(t, err) + + co.VerifierOptions = makeVerifierOptions(trustedroot, true, false, true) + + result, err := verifyNewBundle(bundle, co, artifactPath) checkErr(t, err) if result == nil { diff --git a/pkg/cosign/verify.go b/pkg/cosign/verify.go index 3ab5d76026a..d7d1559b0a6 100644 --- a/pkg/cosign/verify.go +++ b/pkg/cosign/verify.go @@ -45,6 +45,8 @@ import ( cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle" "github.com/sigstore/cosign/v2/pkg/oci/static" "github.com/sigstore/cosign/v2/pkg/types" + "github.com/sigstore/sigstore-go/pkg/root" + "github.com/sigstore/sigstore-go/pkg/verify" "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" "github.com/google/go-containerregistry/pkg/name" @@ -163,6 +165,19 @@ type CheckOpts struct { // Should the experimental OCI 1.1 behaviour be enabled or not. // Defaults to false. ExperimentalOCI11 bool + + // These items are for verifying new bundles or verifying with a trusted root + + // The verification material to use, including public key material + TrustedMaterial root.TrustedMaterial + + // Options around the identity of the verification material, + // particularly for verifying certificates + IdentityPolicies []verify.PolicyOption + + // Options around what sort of verification material you're expecting: + // transparency logs, signed timestamps, certificate transparency logs, etc + VerifierOptions []verify.VerifierOption } // This is a substitutable signature verification function that can be used for verifying