Skip to content
Open
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
4 changes: 2 additions & 2 deletions cmd/cosign/cli/attach/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func attachAttestation(ctx context.Context, remoteOpts []ociremote.Option, signe
// each access.
ref = digest // nolint

opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)}
att, err := static.NewAttestation(payload, opts...)
staticOpts := []static.StaticOption{static.WithLayerMediaType(types.DssePayloadType)}
att, err := static.NewAttestation(payload, staticOpts...)
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions cmd/cosign/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
return nil
}

opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)}
staticOpts := []static.StaticOption{static.WithLayerMediaType(types.DssePayloadType)}
if sv.Cert != nil {
opts = append(opts, static.WithCertChain(sv.Cert, sv.Chain))
staticOpts = append(staticOpts, static.WithCertChain(sv.Cert, sv.Chain))
}
var timestampBytes []byte
var tsaPayload []byte
Expand Down Expand Up @@ -206,7 +206,7 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
}
bundle := cbundle.TimestampToRFC3161Timestamp(timestampBytes)

opts = append(opts, static.WithRFC3161Timestamp(bundle))
staticOpts = append(staticOpts, static.WithRFC3161Timestamp(bundle))
}

predicateType, err := options.ParsePredicateType(c.PredicateType)
Expand All @@ -218,7 +218,7 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
"predicateType": predicateType,
}
// Add predicateType as manifest annotation
opts = append(opts, static.WithAnnotations(predicateTypeAnnotation))
staticOpts = append(staticOpts, static.WithAnnotations(predicateTypeAnnotation))

// Check whether we should be uploading to the transparency log
shouldUpload, err := sign.ShouldUploadToTlog(ctx, c.KeyOpts, digest, c.TlogUpload)
Expand All @@ -238,10 +238,10 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
if err != nil {
return err
}
opts = append(opts, static.WithBundle(cbundle.EntryToBundle(rekorEntry)))
staticOpts = append(staticOpts, static.WithBundle(cbundle.EntryToBundle(rekorEntry)))
}

sig, err := static.NewAttestation(signedPayload, opts...)
sig, err := static.NewAttestation(signedPayload, staticOpts...)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/cosign/cli/options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type SignOptions struct {
OutputPayload string
OutputCertificate string
PayloadPath string
PayloadMediaType string
Recursive bool
Attachment string
SkipConfirmation bool
Expand Down Expand Up @@ -96,6 +97,8 @@ func (o *SignOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.PayloadPath, "payload", "",
"path to a payload file to use rather than generating one")
// _ = cmd.MarkFlagFilename("payload") // no typical extensions
cmd.Flags().StringVar(&o.PayloadMediaType, "payload-media-type", "",
"media type of the payload. Ignored if --payload is not specified.")

cmd.Flags().BoolVarP(&o.Recursive, "recursive", "r", false,
"if a multi-arch image is specified, additionally sign each discrete image")
Expand Down
8 changes: 7 additions & 1 deletion cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio/fulcioverifier"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
Expand All @@ -51,6 +52,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/oci"
"github.com/sigstore/cosign/v2/pkg/oci/mutate"
ociremote "github.com/sigstore/cosign/v2/pkg/oci/remote"
"github.com/sigstore/cosign/v2/pkg/oci/static"
"github.com/sigstore/cosign/v2/pkg/oci/walk"
sigs "github.com/sigstore/cosign/v2/pkg/signature"
"github.com/sigstore/sigstore/pkg/cryptoutils"
Expand Down Expand Up @@ -233,7 +235,11 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
}

var s icos.Signer
s = ipayload.NewSigner(sv)
var staticOpts []static.StaticOption
if signOpts.PayloadPath != "" && signOpts.PayloadMediaType != "" {
staticOpts = append(staticOpts, static.WithLayerMediaType(types.MediaType(signOpts.PayloadMediaType)))
}
s = ipayload.NewSigner(sv, staticOpts)
if sv.Cert != nil {
s = ifulcio.NewSigner(s, sv.Cert, sv.Chain)
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/cosign/cli/verify/verify_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {

// Keys are optional!
var cert *x509.Certificate
opts := make([]static.Option, 0)
staticOpts := make([]static.StaticOption, 0)
switch {
case c.KeyRef != "":
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
Expand Down Expand Up @@ -270,7 +270,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
}
cert = bundleCert
}
opts = append(opts, static.WithBundle(b.Bundle))
staticOpts = append(staticOpts, static.WithBundle(b.Bundle))
}
if c.RFC3161TimestampPath != "" {
var rfc3161Timestamp bundle.RFC3161Timestamp
Expand All @@ -281,7 +281,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
if err := json.Unmarshal(ts, &rfc3161Timestamp); err != nil {
return err
}
opts = append(opts, static.WithRFC3161Timestamp(&rfc3161Timestamp))
staticOpts = append(staticOpts, static.WithRFC3161Timestamp(&rfc3161Timestamp))
}
// Set an SCT if provided via the CLI.
if c.SCTRef != "" {
Expand Down Expand Up @@ -327,7 +327,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
if err != nil {
return err
}
opts = append(opts, static.WithCertChain(certPEM, chainPEM))
staticOpts = append(staticOpts, static.WithCertChain(certPEM, chainPEM))
}

// Ignore Signed Certificate Timestamp if the flag is set or a key is provided
Expand All @@ -342,7 +342,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
if err != nil {
return err
}
signature, err := static.NewSignature(blobBytes, sig, opts...)
signature, err := static.NewSignature(blobBytes, sig, staticOpts...)
if err != nil {
return err
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/cosign/cli/verify/verify_blob_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st

// Keys are optional!
var cert *x509.Certificate
opts := make([]static.Option, 0)
staticOpts := make([]static.StaticOption, 0)
switch {
case c.KeyRef != "":
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
Expand Down Expand Up @@ -316,7 +316,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
if err != nil {
return fmt.Errorf("decoding signature: %w", err)
}
opts = append(opts, static.WithBundle(b.Bundle))
staticOpts = append(staticOpts, static.WithBundle(b.Bundle))
}
if c.RFC3161TimestampPath != "" {
var rfc3161Timestamp bundle.RFC3161Timestamp
Expand All @@ -327,7 +327,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
if err := json.Unmarshal(ts, &rfc3161Timestamp); err != nil {
return err
}
opts = append(opts, static.WithRFC3161Timestamp(&rfc3161Timestamp))
staticOpts = append(staticOpts, static.WithRFC3161Timestamp(&rfc3161Timestamp))
}
// Set an SCT if provided via the CLI.
if c.SCTRef != "" {
Expand Down Expand Up @@ -369,10 +369,10 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
if err != nil {
return err
}
opts = append(opts, static.WithCertChain(certPEM, chainPEM))
staticOpts = append(staticOpts, static.WithCertChain(certPEM, chainPEM))
}

signature, err := static.NewAttestation(encodedSig, opts...)
signature, err := static.NewAttestation(encodedSig, staticOpts...)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/pkg/cosign/payload/attestor.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o
return nil, nil, err
}

opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)}
staticOpts := []static.StaticOption{static.WithLayerMediaType(types.DssePayloadType)}

att, err := static.NewAttestation(envelopeJSON, opts...)
att, err := static.NewAttestation(envelopeJSON, staticOpts...)
if err != nil {
return nil, nil, err
}
Expand All @@ -81,9 +81,9 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o
// Option types other than `signature.SignOption` and `signature.PublicKeyOption` cause a runtime panic.
func NewDSSEAttestor(payloadType string,
s signature.Signer,
signAndPublicKeyOptions ...interface{}) cosign.DSSEAttestor {
opts ...interface{}) cosign.DSSEAttestor {
return &payloadAttestor{
signer: newSigner(s, signAndPublicKeyOptions...),
signer: newSigner(s, opts...),
payloadType: payloadType,
}
}
19 changes: 11 additions & 8 deletions internal/pkg/cosign/payload/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type payloadSigner struct {
payloadSigner signature.Signer
payloadSignerOpts []signature.SignOption
publicKeyProviderOpts []signature.PublicKeyOption
staticOpts []static.StaticOption
}

var _ cosign.Signer = (*payloadSigner)(nil)
Expand All @@ -53,7 +54,7 @@ func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signa
}

b64sig := base64.StdEncoding.EncodeToString(sig)
ociSig, err := static.NewSignature(payloadBytes, b64sig)
ociSig, err := static.NewSignature(payloadBytes, b64sig, ps.staticOpts...)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -82,33 +83,35 @@ func (ps *payloadSigner) signPayload(ctx context.Context, payloadBytes []byte) (
return sig, nil
}

func newSigner(s signature.Signer,
signAndPublicKeyOptions ...interface{}) payloadSigner {
func newSigner(s signature.Signer, opts ...interface{}) payloadSigner {
var sOpts []signature.SignOption
var pkOpts []signature.PublicKeyOption
var staticOpts []static.StaticOption

for _, opt := range signAndPublicKeyOptions {
for _, opt := range opts {
switch o := opt.(type) {
case signature.SignOption:
sOpts = append(sOpts, o)
case signature.PublicKeyOption:
pkOpts = append(pkOpts, o)
case static.StaticOption:
staticOpts = append(staticOpts, o)
default:
panic(fmt.Sprintf("options must be of type `signature.SignOption` or `signature.PublicKeyOption`. Got a %T: %v", o, o))
panic(fmt.Sprintf("options must be of type `signature.SignOption`, `signature.PublicKeyOption` or `static.Option`. Got a %T: %v", o, o))
}
}

return payloadSigner{
payloadSigner: s,
staticOpts: staticOpts,
payloadSignerOpts: sOpts,
publicKeyProviderOpts: pkOpts,
}
}

// NewSigner returns a `cosign.Signer` which uses the given `signature.Signer` to sign requested payloads.
// Option types other than `signature.SignOption` and `signature.PublicKeyOption` cause a runtime panic.
func NewSigner(s signature.Signer,
signAndPublicKeyOptions ...interface{}) cosign.Signer {
signer := newSigner(s, signAndPublicKeyOptions...)
func NewSigner(s signature.Signer, opts ...interface{}) cosign.Signer {
signer := newSigner(s, opts...)
return &signer
}
8 changes: 4 additions & 4 deletions pkg/cosign/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ func TestVerifyImageSignatureWithNoChain(t *testing.T) {
rekorPubKeys := NewTrustedTransparencyLogPubKeys()
rekorPubKeys.AddTransparencyLogPubKey(pemBytes, tuf.Active)

opts := []static.Option{static.WithCertChain(pemLeaf, []byte{}), static.WithBundle(rekorBundle)}
ociSig, _ := static.NewSignature(payload, base64.StdEncoding.EncodeToString(signature), opts...)
staticOpts := []static.StaticOption{static.WithCertChain(pemLeaf, []byte{}), static.WithBundle(rekorBundle)}
ociSig, _ := static.NewSignature(payload, base64.StdEncoding.EncodeToString(signature), staticOpts...)

verified, err := VerifyImageSignature(context.TODO(), ociSig, v1.Hash{},
&CheckOpts{
Expand Down Expand Up @@ -354,8 +354,8 @@ func TestVerifyImageSignatureWithInvalidPublicKeyType(t *testing.T) {
// Add one valid key here.
rekorPubKeys.AddTransparencyLogPubKey(pemBytes, tuf.Active)

opts := []static.Option{static.WithCertChain(pemLeaf, []byte{}), static.WithBundle(rekorBundle)}
ociSig, _ := static.NewSignature(payload, base64.StdEncoding.EncodeToString(signature), opts...)
staticOpts := []static.StaticOption{static.WithCertChain(pemLeaf, []byte{}), static.WithBundle(rekorBundle)}
ociSig, _ := static.NewSignature(payload, base64.StdEncoding.EncodeToString(signature), staticOpts...)

// Then try to validate with keys that are not ecdsa.PublicKey and should
// fail.
Expand Down
4 changes: 2 additions & 2 deletions pkg/oci/mutate/signature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==
`)
)

func mustCreateSignature(t *testing.T, payload []byte, b64sig string, opts ...static.Option) oci.Signature {
func mustCreateSignature(t *testing.T, payload []byte, b64sig string, staticOpts ...static.StaticOption) oci.Signature {
t.Helper()
sig, err := static.NewSignature(payload, b64sig, opts...)
sig, err := static.NewSignature(payload, b64sig, staticOpts...)
if err != nil {
t.Fatalf("failed to create static signature: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/oci/static/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (
)

// NewFile constructs a new v1.Image with the provided payload.
func NewFile(payload []byte, opts ...Option) (oci.File, error) {
o, err := makeOptions(opts...)
func NewFile(payload []byte, staticOpts ...StaticOption) (oci.File, error) {
o, err := makeOptions(staticOpts...)
if err != nil {
return nil, err
}
Expand Down
22 changes: 11 additions & 11 deletions pkg/oci/static/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
ctypes "github.com/sigstore/cosign/v2/pkg/types"
)

// Option is a functional option for customizing static signatures.
type Option func(*options)
// StaticOption is a functional option for customizing static signatures.
type StaticOption func(*options)

type options struct {
LayerMediaType types.MediaType
Expand All @@ -37,14 +37,14 @@ type options struct {
RecordCreationTimestamp bool
}

func makeOptions(opts ...Option) (*options, error) {
func makeOptions(staticOpts ...StaticOption) (*options, error) {
o := &options{
LayerMediaType: ctypes.SimpleSigningMediaType,
ConfigMediaType: types.OCIConfigJSON,
Annotations: make(map[string]string),
}

for _, opt := range opts {
for _, opt := range staticOpts {
opt(o)
}

Expand Down Expand Up @@ -72,50 +72,50 @@ func makeOptions(opts ...Option) (*options, error) {
}

// WithLayerMediaType sets the media type of the signature.
func WithLayerMediaType(mt types.MediaType) Option {
func WithLayerMediaType(mt types.MediaType) StaticOption {
return func(o *options) {
o.LayerMediaType = mt
}
}

// WithConfigMediaType sets the media type of the signature.
func WithConfigMediaType(mt types.MediaType) Option {
func WithConfigMediaType(mt types.MediaType) StaticOption {
return func(o *options) {
o.ConfigMediaType = mt
}
}

// WithAnnotations sets the annotations that will be associated.
func WithAnnotations(ann map[string]string) Option {
func WithAnnotations(ann map[string]string) StaticOption {
return func(o *options) {
o.Annotations = ann
}
}

// WithBundle sets the bundle to attach to the signature
func WithBundle(b *bundle.RekorBundle) Option {
func WithBundle(b *bundle.RekorBundle) StaticOption {
return func(o *options) {
o.Bundle = b
}
}

// WithRFC3161Timestamp sets the time-stamping bundle to attach to the signature
func WithRFC3161Timestamp(b *bundle.RFC3161Timestamp) Option {
func WithRFC3161Timestamp(b *bundle.RFC3161Timestamp) StaticOption {
return func(o *options) {
o.RFC3161Timestamp = b
}
}

// WithCertChain sets the certificate chain for this signature.
func WithCertChain(cert, chain []byte) Option {
func WithCertChain(cert, chain []byte) StaticOption {
return func(o *options) {
o.Cert = cert
o.Chain = chain
}
}

// WithRecordCreationTimestamp sets the feature flag to honor the creation timestamp to time of running
func WithRecordCreationTimestamp(rct bool) Option {
func WithRecordCreationTimestamp(rct bool) StaticOption {
return func(o *options) {
o.RecordCreationTimestamp = rct
}
Expand Down
Loading