Skip to content

Commit ca53935

Browse files
committed
cmd/cosign: add --signing-algorithm flag
Signed-off-by: Riccardo Schirone <riccardo.schirone@trailofbits.com>
1 parent 2961ce1 commit ca53935

File tree

5 files changed

+60
-5
lines changed

5 files changed

+60
-5
lines changed

cmd/cosign/cli/options/key.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,8 @@ type KeyOpts struct {
6565
// By default, Ed25519ph is used for ed25519 keys and RSA-PKCS1v15 is used
6666
// for RSA keys.
6767
DefaultLoadOptions *[]signature.LoadOption
68+
69+
// SigningAlgorithm is the AlgorithmDetails string representation used to
70+
// sign/hash the payload.
71+
SigningAlgorithm string
6872
}

cmd/cosign/cli/options/signblob.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
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

@@ -43,6 +49,7 @@ type SignBlobOptions struct {
4349
TSAServerURL string
4450
RFC3161TimestampPath string
4551
IssueCertificate bool
52+
SigningAlgorithm string
4653
}
4754

4855
var _ Interface = (*SignBlobOptions)(nil)
@@ -113,4 +120,9 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
113120

114121
cmd.Flags().BoolVar(&o.IssueCertificate, "issue-certificate", false,
115122
"issue a code signing certificate from Fulcio, even if a key is provided")
123+
124+
keyAlgorithmTypes := cosign.GetSupportedAlgorithms()
125+
keyAlgorithmHelp := fmt.Sprintf("signing algorithm to use for signing/hashing (allowed %s)", strings.Join(keyAlgorithmTypes, ", "))
126+
defaultKeyFlag, _ := signature.FormatSignatureAlgorithmFlag(v1.PublicKeyDetails_PKIX_ECDSA_P256_SHA_256)
127+
cmd.Flags().StringVar(&o.SigningAlgorithm, "signing-algorithm", defaultKeyFlag, keyAlgorithmHelp)
116128
}

cmd/cosign/cli/sign/sign.go

Lines changed: 18 additions & 5 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"
@@ -521,12 +520,26 @@ func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef strin
521520
return certSigner, nil
522521
}
523522

524-
func signerFromNewKey() (*SignerVerifier, error) {
525-
privKey, err := cosign.GeneratePrivateKey()
523+
func signerFromNewKey(signingAlgorithm string, defaultLoadOptions *[]signature.LoadOption) (*SignerVerifier, error) {
524+
keyDetails, err := signature.ParseSignatureAlgorithmFlag(signingAlgorithm)
525+
if err != nil {
526+
return nil, fmt.Errorf("parsing signature algorithm: %w", err)
527+
}
528+
algo, err := signature.GetAlgorithmDetails(keyDetails)
529+
if err != nil {
530+
return nil, fmt.Errorf("getting algorithm details: %w", err)
531+
}
532+
533+
privKey, err := cosign.GeneratePrivateKeyWithAlgorithm(&algo)
526534
if err != nil {
527535
return nil, fmt.Errorf("generating cert: %w", err)
528536
}
529-
sv, err := signature.LoadECDSASignerVerifier(privKey, crypto.SHA256)
537+
538+
if defaultLoadOptions == nil {
539+
// Cosign uses ED25519ph by default for ED25519 keys
540+
defaultLoadOptions = &[]signature.LoadOption{signatureoptions.WithED25519ph()}
541+
}
542+
sv, err := signature.LoadSignerVerifierFromAlgorithmDetails(privKey, algo, *defaultLoadOptions...)
530543
if err != nil {
531544
return nil, err
532545
}
@@ -598,7 +611,7 @@ func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath strin
598611
default:
599612
genKey = true
600613
ui.Infof(ctx, "Generating ephemeral keys...")
601-
sv, err = signerFromNewKey()
614+
sv, err = signerFromNewKey(ko.SigningAlgorithm, ko.DefaultLoadOptions)
602615
}
603616
if err != nil {
604617
return nil, err

cmd/cosign/cli/signblob.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func SignBlob() *cobra.Command {
9393
TSAServerURL: o.TSAServerURL,
9494
RFC3161TimestampPath: o.RFC3161TimestampPath,
9595
IssueCertificateForExistingKey: o.IssueCertificate,
96+
SigningAlgorithm: o.SigningAlgorithm,
9697
}
9798

9899
for _, blob := range args {

pkg/cosign/keys.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"fmt"
2929
"os"
3030
"path/filepath"
31+
"sort"
3132

3233
"github.com/secure-systems-lab/go-securesystemslib/encrypted"
3334
"github.com/sigstore/cosign/v2/pkg/oci/static"
@@ -50,6 +51,16 @@ const (
5051
RFC3161TimestampKey = static.RFC3161TimestampAnnotationKey
5152
)
5253

54+
var SupportedKeyDetails = []v1.PublicKeyDetails{
55+
v1.PublicKeyDetails_PKIX_ECDSA_P256_SHA_256,
56+
v1.PublicKeyDetails_PKIX_ECDSA_P384_SHA_384,
57+
v1.PublicKeyDetails_PKIX_ECDSA_P521_SHA_512,
58+
v1.PublicKeyDetails_PKIX_RSA_PKCS1V15_2048_SHA256,
59+
v1.PublicKeyDetails_PKIX_RSA_PKCS1V15_3072_SHA256,
60+
v1.PublicKeyDetails_PKIX_RSA_PKCS1V15_4096_SHA256,
61+
v1.PublicKeyDetails_PKIX_ED25519_PH,
62+
}
63+
5364
// PassFunc is the function to be called to retrieve the signer password. If
5465
// nil, then it assumes that no password is provided.
5566
type PassFunc func(bool) ([]byte, error)
@@ -292,3 +303,17 @@ func LoadPrivateKey(key []byte, pass []byte, defaultLoadOptions *[]signature.Loa
292303
}
293304
return signature.LoadDefaultSignerVerifier(pk, *defaultLoadOptions...)
294305
}
306+
307+
// GetSupportedAlgorithms returns a list of supported algorithms sorted alphabetically.
308+
func GetSupportedAlgorithms() []string {
309+
algorithms := make([]string, 0, len(SupportedKeyDetails))
310+
for _, algorithm := range SupportedKeyDetails {
311+
signatureFlag, err := signature.FormatSignatureAlgorithmFlag(algorithm)
312+
if err != nil {
313+
continue
314+
}
315+
algorithms = append(algorithms, signatureFlag)
316+
}
317+
sort.Strings(algorithms)
318+
return algorithms
319+
}

0 commit comments

Comments
 (0)