Skip to content

Commit

Permalink
feature: support sign-blob with certificate
Browse files Browse the repository at this point in the history
Adds support for `--certificate` and `--certificate-chain` to the
sign-blob command. Fixes #2635

Signed-off-by: Nathan Smith <nathan@nfsmith.ca>
  • Loading branch information
nsmith5 committed Jan 18, 2023
1 parent 29360f6 commit 2769376
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 18 deletions.
4 changes: 2 additions & 2 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func Attest() *cobra.Command {
}
ko := options.KeyOpts{
KeyRef: o.Key,
Cert: o.Cert,
CertChain: o.CertChain,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand All @@ -84,8 +86,6 @@ func Attest() *cobra.Command {
attestCommand := attest.AttestCommand{
KeyOpts: ko,
RegistryOptions: o.Registry,
CertPath: o.Cert,
CertChainPath: o.CertChain,
NoUpload: o.NoUpload,
PredicatePath: o.Predicate.Path,
PredicateType: o.Predicate.Type,
Expand Down
4 changes: 1 addition & 3 deletions cmd/cosign/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ func uploadToTlog(ctx context.Context, sv *sign.SignerVerifier, rekorURL string,
type AttestCommand struct {
options.KeyOpts
options.RegistryOptions
CertPath string
CertChainPath string
NoUpload bool
PredicatePath string
PredicateType string
Expand Down Expand Up @@ -118,7 +116,7 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
// each access.
ref = digest // nolint

sv, err := sign.SignerFromKeyOpts(ctx, c.CertPath, c.CertChainPath, c.KeyOpts)
sv, err := sign.SignerFromKeyOpts(ctx, c.KeyOpts)
if err != nil {
return fmt.Errorf("getting signer: %w", err)
}
Expand Down
4 changes: 1 addition & 3 deletions cmd/cosign/cli/attest/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ import (
// nolint
type AttestBlobCommand struct {
options.KeyOpts
CertPath string
CertChainPath string

ArtifactHash string

Expand Down Expand Up @@ -114,7 +112,7 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error
}
defer predicate.Close()

sv, err := sign.SignerFromKeyOpts(ctx, c.CertPath, c.CertChainPath, c.KeyOpts)
sv, err := sign.SignerFromKeyOpts(ctx, c.KeyOpts)
if err != nil {
return fmt.Errorf("getting signer: %w", err)
}
Expand Down
8 changes: 5 additions & 3 deletions cmd/cosign/cli/attest/attest_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,11 @@ func TestAttestBlobCmdLocalKeyAndCert(t *testing.T) {
} {
t.Run(tc.name, func(t *testing.T) {
at := AttestBlobCommand{
KeyOpts: options.KeyOpts{KeyRef: tc.keyref},
CertPath: tc.certref,
CertChainPath: tc.certchainref,
KeyOpts: options.KeyOpts{
KeyRef: tc.keyref,
Cert: tc.certref,
CertChain: tc.certchainref,
},
PredicatePath: predicatePath,
PredicateType: predicateType,
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/cosign/cli/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func AttestBlob() *cobra.Command {
}
ko := options.KeyOpts{
KeyRef: o.Key,
Cert: o.Cert,
CertChain: o.CertChain,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand All @@ -72,8 +74,6 @@ func AttestBlob() *cobra.Command {
}
v := attest.AttestBlobCommand{
KeyOpts: ko,
CertPath: o.Cert,
CertChainPath: o.CertChain,
ArtifactHash: o.Hash,
TlogUpload: o.TlogUpload,
PredicateType: o.Predicate.Type,
Expand Down
2 changes: 2 additions & 0 deletions cmd/cosign/cli/options/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type KeyOpts struct {
Sk bool
Slot string
KeyRef string
Cert string
CertChain string
FulcioURL string
RekorURL string
IDToken string
Expand Down
13 changes: 13 additions & 0 deletions cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
// The new output-certificate flag is only in use when COSIGN_EXPERIMENTAL is enabled
type SignBlobOptions struct {
Key string
Cert string
CertChain 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.
Expand Down Expand Up @@ -52,6 +54,17 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
"path to the private key file, KMS URI or Kubernetes Secret")
_ = cmd.Flags().SetAnnotation("key", cobra.BashCompFilenameExt, []string{})

cmd.Flags().StringVar(&o.Cert, "certificate", "",
"path to the X.509 certificate in PEM format to include in the OCI Signature")
_ = cmd.Flags().SetAnnotation("certificate", cobra.BashCompFilenameExt, []string{"cert"})

cmd.Flags().StringVar(&o.CertChain, "certificate-chain", "",
"path to a list of CA X.509 certificates in PEM format which will be needed "+
"when building the certificate chain for the signing certificate. "+
"Must start with the parent intermediate CA certificate of the "+
"signing certificate and end with the root certificate. Included in the OCI Signature")
_ = cmd.Flags().SetAnnotation("certificate-chain", cobra.BashCompFilenameExt, []string{"cert"})

cmd.Flags().BoolVar(&o.Base64Output, "b64", true,
"whether to base64 encode the output")

Expand Down
6 changes: 5 additions & 1 deletion cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ func signPolicy() *cobra.Command {
return err
}
ko := options.KeyOpts{
// TODO(nsmith5): support signing keyless policy w/ BYO PKI
Cert: "",
CertChain: "",

FulcioURL: o.Fulcio.URL,
IDToken: o.Fulcio.IdentityToken,
InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify,
Expand All @@ -200,7 +204,7 @@ func signPolicy() *cobra.Command {
SkipConfirmation: o.SkipConfirmation,
TSAServerURL: o.TSAServerURL,
}
sv, err := sign.SignerFromKeyOpts(ctx, "", "", ko)
sv, err := sign.SignerFromKeyOpts(ctx, ko)

if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ race conditions or (worse) malicious tampering.
}
ko := options.KeyOpts{
KeyRef: o.Key,
Cert: o.Cert,
CertChain: o.CertChain,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand Down
6 changes: 3 additions & 3 deletions cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func SignCmd(ro *options.RootOptions, ko options.KeyOpts, signOpts options.SignO
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
defer cancel()

sv, err := SignerFromKeyOpts(ctx, signOpts.Cert, signOpts.CertChain, ko)
sv, err := SignerFromKeyOpts(ctx, ko)
if err != nil {
return fmt.Errorf("getting signer: %w", err)
}
Expand Down Expand Up @@ -517,13 +517,13 @@ func keylessSigner(ctx context.Context, ko options.KeyOpts) (*SignerVerifier, er
}, nil
}

func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) {
func SignerFromKeyOpts(ctx context.Context, ko options.KeyOpts) (*SignerVerifier, error) {
if ko.Sk {
return signerFromSecurityKey(ctx, ko.Slot)
}

if ko.KeyRef != "" {
return signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc)
return signerFromKeyRef(ctx, ko.Cert, ko.CertChain, ko.KeyRef, ko.PassFunc)
}

// Default Keyless!
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
defer cancel()

sv, err := SignerFromKeyOpts(ctx, "", "", ko)
sv, err := SignerFromKeyOpts(ctx, ko)
if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ func SignBlob() *cobra.Command {
# sign a blob with a local key pair file
cosign sign-blob --key cosign.key <FILE>
# sign a blob with local certificate and CA bundle
cosign sign-blob --key cosign.key --certificate <FILE> --certificate-chain <FILE> --bundle <FILE> <FILE>
# sign a blob with a key pair stored in Azure Key Vault
cosign sign-blob --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] <FILE>
Expand All @@ -67,6 +70,8 @@ func SignBlob() *cobra.Command {
}
ko := options.KeyOpts{
KeyRef: o.Key,
Cert: o.Cert,
CertChain: o.CertChain,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand Down
5 changes: 5 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.

0 comments on commit 2769376

Please sign in to comment.