diff --git a/cmd/cosign/cli/verify/verify_blob.go b/cmd/cosign/cli/verify/verify_blob.go index 37e2d0282bf..faee2a15543 100644 --- a/cmd/cosign/cli/verify/verify_blob.go +++ b/cmd/cosign/cli/verify/verify_blob.go @@ -27,7 +27,9 @@ import ( "io/fs" "os" "path/filepath" + "strings" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/sigstore/cosign/v2/cmd/cosign/cli/options" "github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor" "github.com/sigstore/cosign/v2/internal/ui" @@ -122,11 +124,6 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { return err } - blobBytes, err := payloadBytes(blobRef) - if err != nil { - return err - } - co := &cosign.CheckOpts{ CertGithubWorkflowTrigger: c.CertGithubWorkflowTrigger, CertGithubWorkflowSha: c.CertGithubWorkflowSHA, @@ -300,12 +297,36 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { } } + var hash *v1.Hash + var blobBytes []byte + if _, err := os.Stat(blobRef); err != nil { + if hexAlg, hexDigest, ok := strings.Cut(blobRef, ":"); !ok { + return err + } else { + hash = &v1.Hash{ + Algorithm: hexAlg, + Hex: hexDigest, + } + } + } else { + blobBytes, err = payloadBytes(blobRef) + if err != nil { + return err + } + } + signature, err := static.NewSignature(blobBytes, sig, opts...) if err != nil { return err } - if _, err = cosign.VerifyBlobSignature(ctx, signature, co); err != nil { - return err + if hash == nil { + if _, err = cosign.VerifyBlobSignature(ctx, signature, co); err != nil { + return err + } + } else { + if _, err = cosign.VerifyImageSignature(ctx, signature, *hash, co); err != nil { + return err + } } ui.Infof(ctx, "Verified OK") diff --git a/cmd/cosign/cli/verify/verify_bundle.go b/cmd/cosign/cli/verify/verify_bundle.go index 74f19a5f116..df768b75bd4 100644 --- a/cmd/cosign/cli/verify/verify_bundle.go +++ b/cmd/cosign/cli/verify/verify_bundle.go @@ -21,8 +21,11 @@ import ( "crypto/sha256" "crypto/x509" "encoding/base64" + "encoding/hex" "encoding/json" "fmt" + "os" + "strings" "time" "github.com/secure-systems-lab/go-securesystemslib/dsse" @@ -167,19 +170,33 @@ func verifyNewBundle(ctx context.Context, bundlePath, trustedRootPath, keyRef, s verifierConfig = append(verifierConfig, verify.WithoutAnyObserverTimestampsUnsafe()) } - // Perform verification - payload, err := payloadBytes(artifactRef) - if err != nil { - return nil, err + // Check if artifactRef is a digest or a file path + var artifactOpt verify.ArtifactPolicyOption + if _, err := os.Stat(artifactRef); err != nil { + if hexAlg, hexDigest, ok := strings.Cut(artifactRef, ":"); !ok { + return nil, err + } else { + digestBytes, err := hex.DecodeString(hexDigest) + if err != nil { + return nil, err + } + artifactOpt = verify.WithArtifactDigest(hexAlg, digestBytes) + } + } else { + // Perform verification + payload, err := payloadBytes(artifactRef) + if err != nil { + return nil, err + } + artifactOpt = verify.WithArtifact(bytes.NewBuffer(payload)) } - buf := bytes.NewBuffer(payload) sev, err := verify.NewSignedEntityVerifier(trustedmaterial, verifierConfig...) if err != nil { return nil, err } - return sev.Verify(bundle, verify.NewPolicy(verify.WithArtifact(buf), identityPolicies...)) + return sev.Verify(bundle, verify.NewPolicy(artifactOpt, 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) { diff --git a/cmd/cosign/cli/verify/verify_bundle_test.go b/cmd/cosign/cli/verify/verify_bundle_test.go index 0bfad165f13..667781c83c7 100644 --- a/cmd/cosign/cli/verify/verify_bundle_test.go +++ b/cmd/cosign/cli/verify/verify_bundle_test.go @@ -23,7 +23,9 @@ import ( "crypto/rand" "crypto/sha256" "crypto/x509" + "encoding/hex" "encoding/pem" + "fmt" "os" "path/filepath" "testing" @@ -36,6 +38,7 @@ func TestVerifyBundleWithKey(t *testing.T) { ctx := context.Background() artifact := "hello world" digest := sha256.Sum256([]byte(artifact)) + hexDigest := hex.EncodeToString(digest[:]) privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) checkErr(t, err) @@ -88,6 +91,13 @@ func TestVerifyBundleWithKey(t *testing.T) { if result == nil { t.Fatal("invalid verification result") } + + result2, err := verifyNewBundle(ctx, bundlePath, trustedRootPath, publicKeyPath, "", "", "", "", "", "", "", "", "", "", fmt.Sprintf("sha256:%s", hexDigest), false, true, false, true) + checkErr(t, err) + + if result2 == nil { + t.Fatal("invalid verification result") + } } func checkErr(t *testing.T, err error) {