Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pkg/plugin/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ var trustedRootFetcher = func() (root.TrustedMaterial, error) {
// inclusion and a trusted timestamp. Any failure — bad signature, wrong identity,
// missing log entry, digest mismatch against manifestData — is an error.
func verifyManifestSignature(sigBundleJSON, manifestData []byte) error {
// cosign's LEGACY bundle ({base64Signature,cert,rekorBundle}) is not the
// Sigstore protobuf bundle sigstore-go parses; detect it and give a clear
// error rather than a cryptic protobuf "unknown field" message. Releases must
// sign with `cosign sign-blob --new-bundle-format`.
if bytes.Contains(sigBundleJSON, []byte(`"base64Signature"`)) {
return fmt.Errorf("signature is in cosign's legacy bundle format; the release must be signed with --new-bundle-format")
}
var b bundle.Bundle
if err := b.UnmarshalJSON(sigBundleJSON); err != nil {
return fmt.Errorf("parse signature bundle: %w", err)
Expand Down
15 changes: 15 additions & 0 deletions pkg/plugin/signature_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package plugin

import (
"strings"
"testing"

"github.com/sigstore/sigstore-go/pkg/root"
Expand Down Expand Up @@ -68,6 +69,20 @@ func TestVerifySignedEntity(t *testing.T) {
})
}

// TestVerifyManifestSignature_RejectsLegacyBundle ensures a cosign legacy bundle
// (the default `cosign sign-blob --bundle` output) is rejected with a clear,
// actionable error rather than a cryptic protobuf parse failure.
func TestVerifyManifestSignature_RejectsLegacyBundle(t *testing.T) {
legacy := []byte(`{"base64Signature":"MEUCIQ...","cert":"LS0tLS1CRUdJTi...","rekorBundle":{}}`)
err := verifyManifestSignature(legacy, []byte(`{"any":"manifest"}`))
if err == nil {
t.Fatal("expected an error for a legacy cosign bundle, got nil")
}
if !strings.Contains(err.Error(), "legacy bundle format") {
t.Errorf("error %q does not explain the legacy-format problem", err)
}
}

// TestTrustedRootFetcherOverride confirms the fetcher hook is overridable, so
// verifyManifestSignature never touches the network in tests. (The JSON-bundle
// unmarshal is sigstore-go's own tested code; the verification policy it feeds
Expand Down
Loading