diff --git a/cmd/cosign/cli/options/signblob.go b/cmd/cosign/cli/options/signblob.go index 600993d4a797..a220dc2d276e 100644 --- a/cmd/cosign/cli/options/signblob.go +++ b/cmd/cosign/cli/options/signblob.go @@ -24,6 +24,7 @@ type SignBlobOptions struct { Key string Base64Output bool Output string // TODO: this should be the root output file arg. + PubKeyOutput string SecurityKey SecurityKeyOptions Fulcio FulcioOptions Rekor RekorOptions @@ -49,4 +50,7 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&o.Output, "output", "", "write the signature to FILE") + + cmd.Flags().StringVar(&o.PubKeyOutput, "pubkey-output", "", + "write the public key/certificate to FILE") } diff --git a/cmd/cosign/cli/sign/sign_blob.go b/cmd/cosign/cli/sign/sign_blob.go index 2c441bba6ef3..7adb391a7d0e 100644 --- a/cmd/cosign/cli/sign/sign_blob.go +++ b/cmd/cosign/cli/sign/sign_blob.go @@ -51,7 +51,7 @@ type KeyOpts struct { } // nolint -func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, output string) ([]byte, error) { +func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, output string, pubKeyOutput string) ([]byte, error) { var payload []byte var err error @@ -76,9 +76,9 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption return nil, errors.Wrap(err, "signing blob") } + var rekorBytes []byte 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 @@ -100,6 +100,26 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) } + if pubKeyOutput != "" { + f, err := os.Create(pubKeyOutput) + 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 + } + } + } + if output != "" { f, err := os.Create(output) if err != nil { diff --git a/cmd/cosign/cli/signblob.go b/cmd/cosign/cli/signblob.go index 628aa115a235..6e4246275c6d 100644 --- a/cmd/cosign/cli/signblob.go +++ b/cmd/cosign/cli/signblob.go @@ -74,7 +74,7 @@ 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); err != nil { + if _, err := sign.SignBlobCmd(cmd.Context(), ko, o.Registry, blob, o.Base64Output, o.Output, o.PubKeyOutput); err != nil { return errors.Wrapf(err, "signing %s", blob) } }