Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement a new flag for sign-blob subcommand to save certificate to disk or stdout #1016

Merged
merged 1 commit into from
Nov 19, 2021
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
29 changes: 19 additions & 10 deletions cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ import (
)

// SignBlobOptions is the top level wrapper for the sign-blob command.
// The new output-certificate flag is only in use when COSIGN_EXPERIMENTAL is enabled
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asraa is this docstring on the right position? I thought about adding it to the SignBlob function, but the SignBlob function has a // nolint on top.. I am not sure if I can have docstrings and nolint at the same time.

type SignBlobOptions struct {
Key string
Base64Output bool
Output string // TODO: this should be the root output file arg.
SecurityKey SecurityKeyOptions
Fulcio FulcioOptions
Rekor RekorOptions
OIDC OIDCOptions
Registry RegistryOptions
Timeout time.Duration
Key string
Base64Output bool
Output string // deprecated: TODO remove when the output flag is fully deprecated
OutputSignature string // TODO: this should be the root output file arg.
OutputCertificate string // TODO: this should be the root output file arg.
SecurityKey SecurityKeyOptions
Fulcio FulcioOptions
Rekor RekorOptions
OIDC OIDCOptions
Registry RegistryOptions
Timeout time.Duration
}

var _ Interface = (*SignBlobOptions)(nil)
Expand All @@ -50,9 +53,15 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.Base64Output, "b64", true,
"whether to base64 encode the output")

cmd.Flags().StringVar(&o.Output, "output", "",
cmd.Flags().StringVar(&o.OutputSignature, "output-signature", "",
"write the signature to FILE")

// TODO: remove when output flag is fully deprecated
cmd.Flags().StringVar(&o.Output, "output", "", "write the signature to FILE")

cmd.Flags().StringVar(&o.OutputCertificate, "output-certificate", "",
"write the certificate to FILE")

cmd.Flags().DurationVar(&o.Timeout, "timeout", time.Second*30,
"HTTP Timeout defaults to 30 seconds")
}
3 changes: 2 additions & 1 deletion cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/sigstore/cosign/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
Expand All @@ -28,6 +29,7 @@ import (

func Sign() *cobra.Command {
o := &options.SignOptions{}
viper.RegisterAlias("output", "output-signature")

cmd := &cobra.Command{
Use: "sign",
Expand Down Expand Up @@ -98,7 +100,6 @@ func Sign() *cobra.Command {
return nil
},
}

o.AddFlags(cmd)
return cmd
}
28 changes: 24 additions & 4 deletions cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ type KeyOpts struct {
}

// nolint
func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, output string, timeout time.Duration) ([]byte, error) {
func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, outputSignature string, outputCertificate string, timeout time.Duration) ([]byte, error) {
var payload []byte
var err error
var rekorBytes []byte

if payloadPath == "-" {
payload, err = io.ReadAll(os.Stdin)
Expand All @@ -79,7 +80,6 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption

if options.EnableExperimental() {
// TODO: Refactor with sign.go
var rekorBytes []byte
if sv.Cert != nil {
fmt.Fprintf(os.Stderr, "signing with ephemeral certificate:\n%s\n", string(sv.Cert))
rekorBytes = sv.Cert
Expand All @@ -101,8 +101,8 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption
fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex)
}

if output != "" {
f, err := os.Create(output)
if outputSignature != "" {
f, err := os.Create(outputSignature)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -131,5 +131,25 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption
}
}

if outputCertificate != "" {
f, err := os.Create(outputCertificate)
if err != nil {
return nil, err
}
defer f.Close()

if b64 {
_, err = f.Write([]byte(base64.StdEncoding.EncodeToString(rekorBytes)))
if err != nil {
return nil, err
}
} else {
_, err = f.Write(rekorBytes)
if err != nil {
return nil, err
}
}
}

return sig, nil
}
13 changes: 10 additions & 3 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
package cli

import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"fmt"
"os"

"github.com/pkg/errors"
"github.com/sigstore/cosign/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/sign"
"github.com/spf13/cobra"
)

func SignBlob() *cobra.Command {
Expand Down Expand Up @@ -74,7 +76,12 @@ func SignBlob() *cobra.Command {
OIDCClientSecret: o.OIDC.ClientSecret,
}
for _, blob := range args {
if _, err := sign.SignBlobCmd(cmd.Context(), ko, o.Registry, blob, o.Base64Output, o.Output, o.Timeout); err != nil {
// TODO: remove when the output flag has been deprecated
if o.Output != "" {
fmt.Fprintln(os.Stderr, "WARNING: the '--output' flag is deprecated and will be removed in the future. Use '--output-signature'")
o.OutputSignature = o.Output
}
if _, err := sign.SignBlobCmd(cmd.Context(), ko, o.Registry, blob, o.Base64Output, o.OutputSignature, o.OutputCertificate, o.Timeout); err != nil {
return errors.Wrapf(err, "signing %s", blob)
}
}
Expand Down
2 changes: 2 additions & 0 deletions doc/cosign_sign-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ require (
github.com/miekg/pkcs11 v1.0.3
github.com/onsi/gomega v1.16.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/spf13/viper v1.8.1
github.com/urfave/cli v1.22.5 // indirect
go.opentelemetry.io/contrib v1.1.0 // indirect
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ func TestSignBlob(t *testing.T) {
KeyRef: privKeyPath1,
PassFunc: passFunc,
}
sig, err := sign.SignBlobCmd(ctx, ko, options.RegistryOptions{}, bp, true, "", time.Duration(30*time.Second))
sig, err := sign.SignBlobCmd(ctx, ko, options.RegistryOptions{}, bp, true, "", "", time.Duration(30*time.Second))
if err != nil {
t.Fatal(err)
}
Expand Down
5 changes: 2 additions & 3 deletions test/piv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// +build resetyubikey
// +build e2e
// +build !pivkeydisabled
//go:build resetyubikey && e2e && !pivkeydisabled
// +build resetyubikey,e2e,!pivkeydisabled

// DANGER
// This test requires a yubikey to be present. It WILL reset the yubikey to exercise functionality.
Expand Down