Skip to content

Commit

Permalink
Add --signing-algorithm flag
Browse files Browse the repository at this point in the history
  • Loading branch information
ret2libc committed Jan 29, 2024
1 parent 0928190 commit 0cfa089
Show file tree
Hide file tree
Showing 14 changed files with 158 additions and 40 deletions.
14 changes: 12 additions & 2 deletions cmd/cosign/cli/generate/generate_key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/cosign/v2/pkg/cosign/kubernetes"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/sigstore/sigstore/pkg/signature/kms"
)

Expand All @@ -43,7 +44,7 @@ var (
)

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

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

keys, err := cosign.GenerateKeyPair(GetPass)
signatureAlgorithm, err := signature.ParseSignatureAlgorithmFlag(signatureAlgorithmName)
if err != nil {
return err
}
algorithmDetails, err := signature.GetAlgorithmDetails(signatureAlgorithm)
if err != nil {
return err
}

keys, err := cosign.GenerateKeyPairWithAlgo(GetPass, algorithmDetails)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/generate/generate_key_pair_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestGenerationOfKeys(t *testing.T) {
// be default it's set to `cosign`, but this is done by the CLI flag
// framework if there is no value set by the user when running the
// command.
GenerateKeyPairCmd(context.Background(), "", "my-test", nil)
GenerateKeyPairCmd(context.Background(), "", "my-test", "ecdsa-sha2-256-nistp256", nil)

checkIfFileExistsThenDelete(privateKeyName, t)
checkIfFileExistsThenDelete(publicKeyName, t)
Expand Down
5 changes: 4 additions & 1 deletion cmd/cosign/cli/generate_key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ func GenerateKeyPair() *cobra.Command {
# generate key-pair and write to cosign.key and cosign.pub files
cosign generate-key-pair
# generate ED25519 key-pair and write to cosign.key and cosign.pub files
cosign generate-key-pair --signing-algorithm=ed25519-ph
# generate key-pair and write to custom named my-name.key and my-name.pub files
cosign generate-key-pair --output-key-prefix my-name
Expand Down Expand Up @@ -67,7 +70,7 @@ CAVEATS:

PersistentPreRun: options.BindViper,
RunE: func(cmd *cobra.Command, args []string) error {
return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, o.OutputKeyPrefix, args)
return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, o.OutputKeyPrefix, o.SigningAlgorithm, args)
},
}

Expand Down
16 changes: 14 additions & 2 deletions cmd/cosign/cli/options/generate_key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@
package options

import (
"fmt"
"strings"

"github.com/sigstore/cosign/v2/pkg/cosign"
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/spf13/cobra"
)

// GenerateKeyPairOptions is the top level wrapper for the generate-key-pair command.
type GenerateKeyPairOptions struct {
// KMS Key Management Service
KMS string
OutputKeyPrefix string
KMS string
OutputKeyPrefix string
SigningAlgorithm string
}

var _ Interface = (*GenerateKeyPairOptions)(nil)
Expand All @@ -34,4 +41,9 @@ func (o *GenerateKeyPairOptions) AddFlags(cmd *cobra.Command) {
"create key pair in KMS service to use for signing")
cmd.Flags().StringVar(&o.OutputKeyPrefix, "output-key-prefix", "cosign",
"name used for generated .pub and .key files (defaults to `cosign`)")

keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)
}
5 changes: 4 additions & 1 deletion cmd/cosign/cli/options/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@

package options

import "github.com/sigstore/cosign/v2/pkg/cosign"
import (
"github.com/sigstore/cosign/v2/pkg/cosign"
)

type KeyOpts struct {
Sk bool
Slot string
KeyRef string
SigningAlgorithm string
FulcioURL string
RekorURL string
IDToken string
Expand Down
12 changes: 12 additions & 0 deletions cmd/cosign/cli/options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
package options

import (
"fmt"
"strings"

"github.com/sigstore/cosign/v2/pkg/cosign"
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/spf13/cobra"
)

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

keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)

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"})
Expand Down
12 changes: 12 additions & 0 deletions cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@
package options

import (
"fmt"
"strings"

"github.com/sigstore/cosign/v2/pkg/cosign"
v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/spf13/cobra"
)

// 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
type SignBlobOptions struct {
Key string
SigningAlgorithm 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 @@ -57,6 +64,11 @@ 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{})

keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256)
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)

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

Expand Down
1 change: 1 addition & 0 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ race conditions or (worse) malicious tampering.
}
ko := options.KeyOpts{
KeyRef: o.Key,
SigningAlgorithm: o.SigningAlgorithm,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand Down
41 changes: 25 additions & 16 deletions cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package sign
import (
"bytes"
"context"
"crypto"
"crypto/x509"
"encoding/base64"
"encoding/json"
Expand All @@ -32,6 +31,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"
pb_go_v1 "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"

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

svOptions := []signature.LoadOption{
signatureoptions.WithHash(crypto.SHA256),
signatureoptions.WithED25519ph(),
}

sv, err := signerFromKeyOptsWithSVOpts(ctx, signOpts.Cert, signOpts.CertChain, ko, svOptions...)
sv, err := SignerFromKeyOpts(ctx, signOpts.Cert, signOpts.CertChain, ko)
if err != nil {
return fmt.Errorf("getting signer: %w", err)
}
Expand Down Expand Up @@ -531,8 +526,8 @@ func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef strin
return certSigner, nil
}

func signerFromNewKey(svOpts ...signature.LoadOption) (*SignerVerifier, error) {
privKey, err := cosign.GeneratePrivateKey()
func signerFromNewKey(algorithmDetails signature.AlgorithmDetails, svOpts ...signature.LoadOption) (*SignerVerifier, error) {
privKey, err := cosign.GeneratePrivateKeyWithAlgo(algorithmDetails)
if err != nil {
return nil, fmt.Errorf("generating cert: %w", err)
}
Expand Down Expand Up @@ -569,9 +564,27 @@ func keylessSigner(ctx context.Context, ko options.KeyOpts, sv *SignerVerifier)
}, nil
}

func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts, svOpts ...signature.LoadOption) (*SignerVerifier, error) {
func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) {
var svOpts []signature.LoadOption
signingAlgorithm, err := signature.ParseSignatureAlgorithmFlag(ko.SigningAlgorithm)
if err != nil {
// Default to ECDSA_SHA2_256_NISTP256 if no algorithm is specified
signingAlgorithm = pb_go_v1.KnownSignatureAlgorithm_ECDSA_SHA2_256_NISTP256
}

algorithmDetails, err := signature.GetAlgorithmDetails(signingAlgorithm)
if err != nil {
return nil, err
}
hashAlgorithm := algorithmDetails.GetHashType()
svOpts = []signature.LoadOption{
signatureoptions.WithHash(hashAlgorithm),
}
if algorithmDetails.GetSignatureAlgorithm() == pb_go_v1.KnownSignatureAlgorithm_ED25519_PH {
svOpts = append(svOpts, signatureoptions.WithED25519ph())
}

var sv *SignerVerifier
var err error
genKey := false
switch {
case ko.Sk:
Expand All @@ -581,7 +594,7 @@ func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChain
default:
genKey = true
ui.Infof(ctx, "Generating ephemeral keys...")
sv, err = signerFromNewKey(svOpts...)
sv, err = signerFromNewKey(algorithmDetails, svOpts...)
}
if err != nil {
return nil, err
Expand All @@ -594,10 +607,6 @@ func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChain
return sv, nil
}

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

type SignerVerifier struct {
Cert []byte
Chain []byte
Expand Down
8 changes: 1 addition & 7 deletions cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import (
"github.com/sigstore/cosign/v2/pkg/cosign"
cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
)

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

svOptions := []signature.LoadOption{
signatureoptions.WithHash(crypto.SHA256),
signatureoptions.WithED25519ph(),
}

sv, err := signerFromKeyOptsWithSVOpts(ctx, "", "", ko, svOptions...)
sv, err := SignerFromKeyOpts(ctx, "", "", ko)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func SignBlob() *cobra.Command {
}
ko := options.KeyOpts{
KeyRef: o.Key,
SigningAlgorithm: o.SigningAlgorithm,
PassFunc: generate.GetPass,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/secure-systems-lab/go-securesystemslib v0.8.0
github.com/sigstore/fulcio v1.4.3
github.com/sigstore/protobuf-specs v0.3.0-beta.2
github.com/sigstore/rekor v1.3.4
github.com/sigstore/sigstore v1.8.1
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1
Expand Down Expand Up @@ -278,6 +279,6 @@ require (
)

// TODO: REMOVE ME
replace github.com/sigstore/sigstore => github.com/trail-of-forks/sigstore v0.0.0-20240129151206-cff4abcde12e
replace github.com/sigstore/sigstore => /Users/ret2libc/projects/sigstore/sigstore

replace github.com/sigstore/rekor => github.com/trail-of-forks/rekor v0.0.0-20240129163653-3ac4c89bd056
replace github.com/sigstore/rekor => /Users/ret2libc/projects/sigstore/rekor
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ=
github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og=
github.com/sigstore/protobuf-specs v0.3.0-beta.2 h1:neHS0O1z7qz4q21vyXqSaKuKYxA0upzJERT88NrgYlM=
github.com/sigstore/protobuf-specs v0.3.0-beta.2/go.mod h1:ynKzXpqr3dUj2Xk9O/5ZUhjnpi0F53DNi5AdH6pS3jc=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1 h1:rEDdUefulkIQaMJyzLwtgPDLNXBIltBABiFYfb0YmgQ=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.1/go.mod h1:RCdYCc1IxCYWzh2IdzdA6Yf7JIY0cMRqH08fpQYechw=
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.1 h1:DvRWG99QGWZC5mp42SEde2Xke/Q384Idnj2da7yB+Mk=
Expand Down Expand Up @@ -672,10 +674,6 @@ github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHT
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/trail-of-forks/rekor v0.0.0-20240129163653-3ac4c89bd056 h1:jTVzEjC2Mm5x9mnZwKyspP7ygDyP1BiZHleUvh81V4Y=
github.com/trail-of-forks/rekor v0.0.0-20240129163653-3ac4c89bd056/go.mod h1:KMOYGlQZ96wQ0MfdHvVHjp8mM0fA8Lh6sqtwYkXP5YE=
github.com/trail-of-forks/sigstore v0.0.0-20240129151206-cff4abcde12e h1:EXVlV8GAQ7nct3uYZwga7JVjQ/GfwWAtMKbmYll3sZ8=
github.com/trail-of-forks/sigstore v0.0.0-20240129151206-cff4abcde12e/go.mod h1:rbZxJoss0Qf/OQeIuyqkQxo9jLKZlyLqOGX0BUaK7/I=
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
Expand Down
Loading

0 comments on commit 0cfa089

Please sign in to comment.