Skip to content

Commit 0cfa089

Browse files
committed
Add --signing-algorithm flag
1 parent 0928190 commit 0cfa089

File tree

14 files changed

+158
-40
lines changed

14 files changed

+158
-40
lines changed

cmd/cosign/cli/generate/generate_key_pair.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/sigstore/cosign/v2/pkg/cosign"
3535
"github.com/sigstore/cosign/v2/pkg/cosign/kubernetes"
3636
"github.com/sigstore/sigstore/pkg/cryptoutils"
37+
"github.com/sigstore/sigstore/pkg/signature"
3738
"github.com/sigstore/sigstore/pkg/signature/kms"
3839
)
3940

@@ -43,7 +44,7 @@ var (
4344
)
4445

4546
// nolint
46-
func GenerateKeyPairCmd(ctx context.Context, kmsVal string, outputKeyPrefixVal string, args []string) error {
47+
func GenerateKeyPairCmd(ctx context.Context, kmsVal string, outputKeyPrefixVal string, signatureAlgorithmName string, args []string) error {
4748
privateKeyFileName := outputKeyPrefixVal + ".key"
4849
publicKeyFileName := outputKeyPrefixVal + ".pub"
4950

@@ -86,7 +87,16 @@ func GenerateKeyPairCmd(ctx context.Context, kmsVal string, outputKeyPrefixVal s
8687
return fmt.Errorf("undefined provider: %s", provider)
8788
}
8889

89-
keys, err := cosign.GenerateKeyPair(GetPass)
90+
signatureAlgorithm, err := signature.ParseSignatureAlgorithmFlag(signatureAlgorithmName)
91+
if err != nil {
92+
return err
93+
}
94+
algorithmDetails, err := signature.GetAlgorithmDetails(signatureAlgorithm)
95+
if err != nil {
96+
return err
97+
}
98+
99+
keys, err := cosign.GenerateKeyPairWithAlgo(GetPass, algorithmDetails)
90100
if err != nil {
91101
return err
92102
}

cmd/cosign/cli/generate/generate_key_pair_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func TestGenerationOfKeys(t *testing.T) {
5757
// be default it's set to `cosign`, but this is done by the CLI flag
5858
// framework if there is no value set by the user when running the
5959
// command.
60-
GenerateKeyPairCmd(context.Background(), "", "my-test", nil)
60+
GenerateKeyPairCmd(context.Background(), "", "my-test", "ecdsa-sha2-256-nistp256", nil)
6161

6262
checkIfFileExistsThenDelete(privateKeyName, t)
6363
checkIfFileExistsThenDelete(publicKeyName, t)

cmd/cosign/cli/generate_key_pair.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ func GenerateKeyPair() *cobra.Command {
3434
# generate key-pair and write to cosign.key and cosign.pub files
3535
cosign generate-key-pair
3636
37+
# generate ED25519 key-pair and write to cosign.key and cosign.pub files
38+
cosign generate-key-pair --signing-algorithm=ed25519-ph
39+
3740
# generate key-pair and write to custom named my-name.key and my-name.pub files
3841
cosign generate-key-pair --output-key-prefix my-name
3942
@@ -67,7 +70,7 @@ CAVEATS:
6770

6871
PersistentPreRun: options.BindViper,
6972
RunE: func(cmd *cobra.Command, args []string) error {
70-
return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, o.OutputKeyPrefix, args)
73+
return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, o.OutputKeyPrefix, o.SigningAlgorithm, args)
7174
},
7275
}
7376

cmd/cosign/cli/options/generate_key_pair.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@
1616
package options
1717

1818
import (
19+
"fmt"
20+
"strings"
21+
22+
"github.com/sigstore/cosign/v2/pkg/cosign"
23+
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
24+
"github.com/sigstore/sigstore/pkg/signature"
1925
"github.com/spf13/cobra"
2026
)
2127

2228
// GenerateKeyPairOptions is the top level wrapper for the generate-key-pair command.
2329
type GenerateKeyPairOptions struct {
2430
// KMS Key Management Service
25-
KMS string
26-
OutputKeyPrefix string
31+
KMS string
32+
OutputKeyPrefix string
33+
SigningAlgorithm string
2734
}
2835

2936
var _ Interface = (*GenerateKeyPairOptions)(nil)
@@ -34,4 +41,9 @@ func (o *GenerateKeyPairOptions) AddFlags(cmd *cobra.Command) {
3441
"create key pair in KMS service to use for signing")
3542
cmd.Flags().StringVar(&o.OutputKeyPrefix, "output-key-prefix", "cosign",
3643
"name used for generated .pub and .key files (defaults to `cosign`)")
44+
45+
keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
46+
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
47+
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
48+
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)
3749
}

cmd/cosign/cli/options/key.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515

1616
package options
1717

18-
import "github.com/sigstore/cosign/v2/pkg/cosign"
18+
import (
19+
"github.com/sigstore/cosign/v2/pkg/cosign"
20+
)
1921

2022
type KeyOpts struct {
2123
Sk bool
2224
Slot string
2325
KeyRef string
26+
SigningAlgorithm string
2427
FulcioURL string
2528
RekorURL string
2629
IDToken string

cmd/cosign/cli/options/sign.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616
package options
1717

1818
import (
19+
"fmt"
20+
"strings"
21+
22+
"github.com/sigstore/cosign/v2/pkg/cosign"
23+
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
24+
"github.com/sigstore/sigstore/pkg/signature"
1925
"github.com/spf13/cobra"
2026
)
2127

2228
// SignOptions is the top level wrapper for the sign command.
2329
type SignOptions struct {
2430
Key string
31+
SigningAlgorithm string
2532
Cert string
2633
CertChain string
2734
Upload bool
@@ -67,6 +74,11 @@ func (o *SignOptions) AddFlags(cmd *cobra.Command) {
6774
"path to the private key file, KMS URI or Kubernetes Secret")
6875
_ = cmd.Flags().SetAnnotation("key", cobra.BashCompFilenameExt, []string{})
6976

77+
keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
78+
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
79+
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
80+
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)
81+
7082
cmd.Flags().StringVar(&o.Cert, "certificate", "",
7183
"path to the X.509 certificate in PEM format to include in the OCI Signature")
7284
_ = cmd.Flags().SetAnnotation("certificate", cobra.BashCompFilenameExt, []string{"cert"})

cmd/cosign/cli/options/signblob.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@
1616
package options
1717

1818
import (
19+
"fmt"
20+
"strings"
21+
22+
"github.com/sigstore/cosign/v2/pkg/cosign"
23+
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
24+
"github.com/sigstore/sigstore/pkg/signature"
1925
"github.com/spf13/cobra"
2026
)
2127

2228
// SignBlobOptions is the top level wrapper for the sign-blob command.
2329
// The new output-certificate flag is only in use when COSIGN_EXPERIMENTAL is enabled
2430
type SignBlobOptions struct {
2531
Key string
32+
SigningAlgorithm string
2633
Base64Output bool
2734
Output string // deprecated: TODO remove when the output flag is fully deprecated
2835
OutputSignature string // TODO: this should be the root output file arg.
@@ -57,6 +64,11 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
5764
"path to the private key file, KMS URI or Kubernetes Secret")
5865
_ = cmd.Flags().SetAnnotation("key", cobra.BashCompFilenameExt, []string{})
5966

67+
keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
68+
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
69+
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
70+
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)
71+
6072
cmd.Flags().BoolVar(&o.Base64Output, "b64", true,
6173
"whether to base64 encode the output")
6274

cmd/cosign/cli/sign.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ race conditions or (worse) malicious tampering.
102102
}
103103
ko := options.KeyOpts{
104104
KeyRef: o.Key,
105+
SigningAlgorithm: o.SigningAlgorithm,
105106
PassFunc: generate.GetPass,
106107
Sk: o.SecurityKey.Use,
107108
Slot: o.SecurityKey.Slot,

cmd/cosign/cli/sign/sign.go

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package sign
1818
import (
1919
"bytes"
2020
"context"
21-
"crypto"
2221
"crypto/x509"
2322
"encoding/base64"
2423
"encoding/json"
@@ -32,6 +31,7 @@ import (
3231
"github.com/google/go-containerregistry/pkg/name"
3332
v1 "github.com/google/go-containerregistry/pkg/v1"
3433
"github.com/google/go-containerregistry/pkg/v1/remote"
34+
pb_go_v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
3535

3636
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"
3737
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio/fulcioverifier"
@@ -138,12 +138,7 @@ func SignCmd(ro *options.RootOptions, ko options.KeyOpts, signOpts options.SignO
138138
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
139139
defer cancel()
140140

141-
svOptions := []signature.LoadOption{
142-
signatureoptions.WithHash(crypto.SHA256),
143-
signatureoptions.WithED25519ph(),
144-
}
145-
146-
sv, err := signerFromKeyOptsWithSVOpts(ctx, signOpts.Cert, signOpts.CertChain, ko, svOptions...)
141+
sv, err := SignerFromKeyOpts(ctx, signOpts.Cert, signOpts.CertChain, ko)
147142
if err != nil {
148143
return fmt.Errorf("getting signer: %w", err)
149144
}
@@ -531,8 +526,8 @@ func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef strin
531526
return certSigner, nil
532527
}
533528

534-
func signerFromNewKey(svOpts ...signature.LoadOption) (*SignerVerifier, error) {
535-
privKey, err := cosign.GeneratePrivateKey()
529+
func signerFromNewKey(algorithmDetails signature.AlgorithmDetails, svOpts ...signature.LoadOption) (*SignerVerifier, error) {
530+
privKey, err := cosign.GeneratePrivateKeyWithAlgo(algorithmDetails)
536531
if err != nil {
537532
return nil, fmt.Errorf("generating cert: %w", err)
538533
}
@@ -569,9 +564,27 @@ func keylessSigner(ctx context.Context, ko options.KeyOpts, sv *SignerVerifier)
569564
}, nil
570565
}
571566

572-
func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts, svOpts ...signature.LoadOption) (*SignerVerifier, error) {
567+
func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) {
568+
var svOpts []signature.LoadOption
569+
signingAlgorithm, err := signature.ParseSignatureAlgorithmFlag(ko.SigningAlgorithm)
570+
if err != nil {
571+
// Default to ECDSA_SHA2_256_NISTP256 if no algorithm is specified
572+
signingAlgorithm = pb_go_v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256
573+
}
574+
575+
algorithmDetails, err := signature.GetAlgorithmDetails(signingAlgorithm)
576+
if err != nil {
577+
return nil, err
578+
}
579+
hashAlgorithm := algorithmDetails.GetHashType()
580+
svOpts = []signature.LoadOption{
581+
signatureoptions.WithHash(hashAlgorithm),
582+
}
583+
if algorithmDetails.GetSignatureAlgorithm() == pb_go_v1.KnownSignatureAlgorithm_ED25519_PH {
584+
svOpts = append(svOpts, signatureoptions.WithED25519ph())
585+
}
586+
573587
var sv *SignerVerifier
574-
var err error
575588
genKey := false
576589
switch {
577590
case ko.Sk:
@@ -581,7 +594,7 @@ func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChain
581594
default:
582595
genKey = true
583596
ui.Infof(ctx, "Generating ephemeral keys...")
584-
sv, err = signerFromNewKey(svOpts...)
597+
sv, err = signerFromNewKey(algorithmDetails, svOpts...)
585598
}
586599
if err != nil {
587600
return nil, err
@@ -594,10 +607,6 @@ func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChain
594607
return sv, nil
595608
}
596609

597-
func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) {
598-
return signerFromKeyOptsWithSVOpts(ctx, certPath, certChainPath, ko)
599-
}
600-
601610
type SignerVerifier struct {
602611
Cert []byte
603612
Chain []byte

cmd/cosign/cli/sign/sign_blob.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import (
3636
"github.com/sigstore/cosign/v2/pkg/cosign"
3737
cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
3838
"github.com/sigstore/sigstore/pkg/cryptoutils"
39-
"github.com/sigstore/sigstore/pkg/signature"
4039
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
4140
)
4241

@@ -66,12 +65,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
6665
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
6766
defer cancel()
6867

69-
svOptions := []signature.LoadOption{
70-
signatureoptions.WithHash(crypto.SHA256),
71-
signatureoptions.WithED25519ph(),
72-
}
73-
74-
sv, err := signerFromKeyOptsWithSVOpts(ctx, "", "", ko, svOptions...)
68+
sv, err := SignerFromKeyOpts(ctx, "", "", ko)
7569
if err != nil {
7670
return nil, err
7771
}

0 commit comments

Comments
 (0)