From 0d55987bd62f5615a81e7d46a2598fd802b4acb0 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Fri, 1 Nov 2024 13:59:03 -0400 Subject: [PATCH] Fix bug with detached signature Also add test for Fulcio certificate and old bundle format Signed-off-by: Zach Steindler --- cmd/cosign/cli/bundle/bundle.go | 7 +++- cmd/cosign/cli/bundle/bundle_test.go | 51 ++++++++++++++++++++++++++ cmd/cosign/cli/verify/verify_bundle.go | 14 ++----- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/cmd/cosign/cli/bundle/bundle.go b/cmd/cosign/cli/bundle/bundle.go index ee4eb7c7a80..54778e45e99 100644 --- a/cmd/cosign/cli/bundle/bundle.go +++ b/cmd/cosign/cli/bundle/bundle.go @@ -108,7 +108,12 @@ func (c *CreateCmd) Exec(ctx context.Context) (err error) { } if c.SignaturePath != "" { - sigBytes, err = os.ReadFile(c.SignaturePath) + signatureB64, err := os.ReadFile(c.SignaturePath) + if err != nil { + return err + } + + sigBytes, err = base64.StdEncoding.DecodeString(string(signatureB64)) if err != nil { return err } diff --git a/cmd/cosign/cli/bundle/bundle_test.go b/cmd/cosign/cli/bundle/bundle_test.go index 051e4f4374e..4b64a7aea9c 100644 --- a/cmd/cosign/cli/bundle/bundle_test.go +++ b/cmd/cosign/cli/bundle/bundle_test.go @@ -24,12 +24,16 @@ import ( "crypto/sha256" "crypto/x509" "encoding/base64" + "encoding/json" "encoding/pem" "os" "path/filepath" "testing" + "github.com/sigstore/cosign/v2/pkg/cosign" + "github.com/sigstore/cosign/v2/test" sgBundle "github.com/sigstore/sigstore-go/pkg/bundle" + "github.com/sigstore/sigstore/pkg/cryptoutils" ) func TestCreateCmd(t *testing.T) { @@ -43,6 +47,7 @@ func TestCreateCmd(t *testing.T) { err := os.WriteFile(artifactPath, []byte(artifact), 0600) checkErr(t, err) + // Test signing with a key privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) checkErr(t, err) sigBytes, err := privateKey.Sign(rand.Reader, digest[:], crypto.SHA256) @@ -90,6 +95,52 @@ func TestCreateCmd(t *testing.T) { if b.Bundle.GetMessageSignature() == nil { t.Fatal("bundle does not have message signature") } + + // Test using an identity certificate in an old bundle format + rootCert, rootKey, _ := test.GenerateRootCa() + leafCert, privKey, _ := test.GenerateLeafCert("subject", "oidc-issuer", rootCert, rootKey) + + sigBytes, err = privKey.Sign(rand.Reader, digest[:], crypto.SHA256) + checkErr(t, err) + + signedPayload := cosign.LocalSignedPayload{} + signedPayload.Base64Signature = base64.StdEncoding.EncodeToString(sigBytes) + + certBytes, err := cryptoutils.MarshalCertificateToPEM(leafCert) + checkErr(t, err) + + signedPayload.Cert = base64.StdEncoding.EncodeToString(certBytes) + bundleContents, err := json.Marshal(signedPayload) + checkErr(t, err) + + bundlePath := filepath.Join(td, "old-bundle.json") + err = os.WriteFile(bundlePath, bundleContents, 0600) + checkErr(t, err) + + bundleCreate = CreateCmd{ + Artifact: artifactPath, + BundlePath: bundlePath, + IgnoreTlog: true, + Out: outPath, + } + + err = bundleCreate.Exec(ctx) + checkErr(t, err) + + b, err = sgBundle.LoadJSONFromPath(outPath) + checkErr(t, err) + + if b.Bundle.VerificationMaterial == nil { + t.Fatal("bundle does not have verification material") + } + + if b.Bundle.VerificationMaterial.GetCertificate() == nil { + t.Fatal("bundle verification material does not have certificate") + } + + if b.Bundle.GetMessageSignature() == nil { + t.Fatal("bundle does not have message signature") + } } func checkErr(t *testing.T, err error) { diff --git a/cmd/cosign/cli/verify/verify_bundle.go b/cmd/cosign/cli/verify/verify_bundle.go index 8bbf14714cb..05a50ebd801 100644 --- a/cmd/cosign/cli/verify/verify_bundle.go +++ b/cmd/cosign/cli/verify/verify_bundle.go @@ -31,7 +31,6 @@ import ( protodsse "github.com/sigstore/protobuf-specs/gen/pb-go/dsse" protorekor "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1" "github.com/sigstore/rekor/pkg/generated/client" - "github.com/sigstore/rekor/pkg/generated/models" "github.com/sigstore/rekor/pkg/tle" sgbundle "github.com/sigstore/sigstore-go/pkg/bundle" "github.com/sigstore/sigstore-go/pkg/fulcio/certificate" @@ -294,18 +293,11 @@ func AssembleNewBundle(ctx context.Context, sigBytes, signedTimestamp []byte, en if len(tlogEntries) == 0 { return nil, fmt.Errorf("unable to find tlog entry") } - // Attempt to verify with the earliest integrated entry - var earliestLogEntry models.LogEntryAnon - var earliestLogEntryTime *time.Time - for _, e := range tlogEntries { - entryTime := time.Unix(*e.IntegratedTime, 0) - if earliestLogEntryTime == nil || entryTime.Before(*earliestLogEntryTime) { - earliestLogEntryTime = &entryTime - earliestLogEntry = e - } + if len(tlogEntries) > 1 { + return nil, fmt.Errorf("too many tlog entries; should only have 1") } - tlogEntry, err := tle.GenerateTransparencyLogEntry(earliestLogEntry) + tlogEntry, err := tle.GenerateTransparencyLogEntry(tlogEntries[0]) if err != nil { return nil, err }