Skip to content

Commit 7f0717d

Browse files
committed
Used LoadOptions for more flexibility
* Use ED25519ph algorithm with sign/verify-blob commands Signed-off-by: Riccardo Schirone <riccardo.schirone@trailofbits.com> Signed-off-by: William Woodruff <william@trailofbits.com>
1 parent a4da0c2 commit 7f0717d

File tree

15 files changed

+382
-150
lines changed

15 files changed

+382
-150
lines changed

cmd/cosign/cli/sign/sign.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ 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-
sv, err := SignerFromKeyOpts(ctx, signOpts.Cert, signOpts.CertChain, ko)
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...)
142147
if err != nil {
143148
return fmt.Errorf("getting signer: %w", err)
144149
}
@@ -261,7 +266,12 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
261266
if err != nil {
262267
return err
263268
}
264-
s = irekor.NewSigner(s, rClient)
269+
270+
hashAlgorithm, err := getHashAlgorithmFromSignerVerifier(sv)
271+
if err != nil {
272+
return err
273+
}
274+
s = irekor.NewSigner(s, rClient, hashAlgorithm)
265275
}
266276

267277
ociSig, _, err := s.Sign(ctx, bytes.NewReader(payload))
@@ -391,8 +401,8 @@ func signerFromSecurityKey(ctx context.Context, keySlot string) (*SignerVerifier
391401
}, nil
392402
}
393403

394-
func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef string, passFunc cosign.PassFunc) (*SignerVerifier, error) {
395-
k, err := sigs.SignerVerifierFromKeyRef(ctx, keyRef, passFunc)
404+
func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef string, passFunc cosign.PassFunc, opts ...signature.LoadOption) (*SignerVerifier, error) {
405+
k, err := sigs.SignerVerifierFromKeyRefWithOpts(ctx, keyRef, passFunc, opts...)
396406
if err != nil {
397407
return nil, fmt.Errorf("reading key: %w", err)
398408
}
@@ -521,12 +531,12 @@ func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef strin
521531
return certSigner, nil
522532
}
523533

524-
func signerFromNewKey() (*SignerVerifier, error) {
534+
func signerFromNewKey(svOpts ...signature.LoadOption) (*SignerVerifier, error) {
525535
privKey, err := cosign.GeneratePrivateKey()
526536
if err != nil {
527537
return nil, fmt.Errorf("generating cert: %w", err)
528538
}
529-
sv, err := signature.LoadECDSASignerVerifier(privKey, crypto.SHA256)
539+
sv, err := signature.LoadSignerVerifierWithOpts(privKey, svOpts...)
530540
if err != nil {
531541
return nil, err
532542
}
@@ -559,19 +569,19 @@ func keylessSigner(ctx context.Context, ko options.KeyOpts, sv *SignerVerifier)
559569
}, nil
560570
}
561571

562-
func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) {
572+
func signerFromKeyOptsWithSVOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts, svOpts ...signature.LoadOption) (*SignerVerifier, error) {
563573
var sv *SignerVerifier
564574
var err error
565575
genKey := false
566576
switch {
567577
case ko.Sk:
568578
sv, err = signerFromSecurityKey(ctx, ko.Slot)
569579
case ko.KeyRef != "":
570-
sv, err = signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc)
580+
sv, err = signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc, svOpts...)
571581
default:
572582
genKey = true
573583
ui.Infof(ctx, "Generating ephemeral keys...")
574-
sv, err = signerFromNewKey()
584+
sv, err = signerFromNewKey(svOpts...)
575585
}
576586
if err != nil {
577587
return nil, err
@@ -584,6 +594,10 @@ func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath strin
584594
return sv, nil
585595
}
586596

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

cmd/cosign/cli/sign/sign_blob.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ package sign
1717

1818
import (
1919
"context"
20-
"crypto/sha256"
20+
"crypto"
21+
"crypto/ecdsa"
22+
"crypto/ed25519"
23+
"crypto/rsa"
2124
"encoding/base64"
2225
"encoding/json"
2326
"fmt"
@@ -33,9 +36,28 @@ import (
3336
"github.com/sigstore/cosign/v2/pkg/cosign"
3437
cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
3538
"github.com/sigstore/sigstore/pkg/cryptoutils"
39+
"github.com/sigstore/sigstore/pkg/signature"
3640
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
3741
)
3842

43+
func getHashAlgorithmFromSignerVerifier(sv *SignerVerifier) (crypto.Hash, error) {
44+
publicKey, err := sv.SignerVerifier.PublicKey()
45+
if err != nil {
46+
return crypto.Hash(0), err
47+
}
48+
49+
switch publicKey.(type) {
50+
case *ecdsa.PublicKey:
51+
return crypto.SHA256, nil
52+
case *rsa.PublicKey:
53+
return crypto.SHA256, nil
54+
case ed25519.PublicKey:
55+
return crypto.SHA512, nil
56+
default:
57+
return crypto.Hash(0), fmt.Errorf("unsupported public key type")
58+
}
59+
}
60+
3961
// nolint
4062
func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string, b64 bool, outputSignature string, outputCertificate string, tlogUpload bool) ([]byte, error) {
4163
var payload internal.HashReader
@@ -44,26 +66,36 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
4466
ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout)
4567
defer cancel()
4668

69+
svOptions := []signature.LoadOption{
70+
signatureoptions.WithHash(crypto.SHA256),
71+
signatureoptions.WithED25519ph(),
72+
}
73+
74+
sv, err := signerFromKeyOptsWithSVOpts(ctx, "", "", ko, svOptions...)
75+
if err != nil {
76+
return nil, err
77+
}
78+
defer sv.Close()
79+
80+
hashAlgorithm, err := getHashAlgorithmFromSignerVerifier(sv)
81+
if err != nil {
82+
return nil, err
83+
}
84+
4785
if payloadPath == "-" {
48-
payload = internal.NewHashReader(os.Stdin, sha256.New())
86+
payload = internal.NewHashReader(os.Stdin, hashAlgorithm)
4987
} else {
5088
ui.Infof(ctx, "Using payload from: %s", payloadPath)
5189
f, err := os.Open(filepath.Clean(payloadPath))
5290
if err != nil {
5391
return nil, err
5492
}
55-
payload = internal.NewHashReader(f, sha256.New())
93+
payload = internal.NewHashReader(f, hashAlgorithm)
5694
}
5795
if err != nil {
5896
return nil, err
5997
}
6098

61-
sv, err := SignerFromKeyOpts(ctx, "", "", ko)
62-
if err != nil {
63-
return nil, err
64-
}
65-
defer sv.Close()
66-
6799
sig, err := sv.SignMessage(&payload, signatureoptions.WithContext(ctx))
68100
if err != nil {
69101
return nil, fmt.Errorf("signing blob: %w", err)
@@ -123,7 +155,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
123155
if err != nil {
124156
return nil, err
125157
}
126-
entry, err := cosign.TLogUpload(ctx, rekorClient, sig, &payload, rekorBytes)
158+
entry, err := cosign.TLogUploadWithCustomHash(ctx, rekorClient, sig, &payload, rekorBytes)
127159
if err != nil {
128160
return nil, err
129161
}

cmd/cosign/cli/verify/verify.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
sigs "github.com/sigstore/cosign/v2/pkg/signature"
4545
"github.com/sigstore/sigstore/pkg/cryptoutils"
4646
"github.com/sigstore/sigstore/pkg/signature"
47+
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
4748
"github.com/sigstore/sigstore/pkg/signature/payload"
4849
)
4950

@@ -214,11 +215,16 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
214215
}
215216
}
216217

218+
svOpts := []signature.LoadOption{
219+
signatureoptions.WithHash(crypto.SHA256),
220+
signatureoptions.WithED25519ph(),
221+
}
222+
217223
// Keys are optional!
218224
var pubKey signature.Verifier
219225
switch {
220226
case keyRef != "":
221-
pubKey, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm)
227+
pubKey, err = sigs.PublicKeyFromKeyRefWithOpts(ctx, keyRef, svOpts...)
222228
if err != nil {
223229
return fmt.Errorf("loading public key: %w", err)
224230
}
@@ -251,7 +257,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
251257
if err != nil {
252258
return fmt.Errorf("getting Fulcio intermediates: %w", err)
253259
}
254-
pubKey, err = cosign.ValidateAndUnpackCert(cert, co)
260+
pubKey, err = cosign.ValidateAndUnpackCertWithOpts(cert, co, cosign.WithSignerVerifierOptions(svOpts...))
255261
if err != nil {
256262
return err
257263
}
@@ -261,7 +267,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
261267
if err != nil {
262268
return err
263269
}
264-
pubKey, err = cosign.ValidateAndUnpackCertWithChain(cert, chain, co)
270+
pubKey, err = cosign.ValidateAndUnpackCertWithOpts(cert, co, cosign.WithChain(chain), cosign.WithSignerVerifierOptions(svOpts...))
265271
if err != nil {
266272
return err
267273
}
@@ -286,7 +292,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
286292

287293
for _, img := range images {
288294
if c.LocalImage {
289-
verified, bundleVerified, err := cosign.VerifyLocalImageSignatures(ctx, img, co)
295+
verified, bundleVerified, err := cosign.VerifyLocalImageSignaturesWithOpts(ctx, img, co, svOpts...)
290296
if err != nil {
291297
return err
292298
}
@@ -302,7 +308,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
302308
return fmt.Errorf("resolving attachment type %s for image %s: %w", c.Attachment, img, err)
303309
}
304310

305-
verified, bundleVerified, err := cosign.VerifyImageSignatures(ctx, ref, co)
311+
verified, bundleVerified, err := cosign.VerifyImageSignaturesWithOpts(ctx, ref, co, svOpts...)
306312
if err != nil {
307313
return cosignError.WrapError(err)
308314
}

cmd/cosign/cli/verify/verify_blob.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import (
4242
sigs "github.com/sigstore/cosign/v2/pkg/signature"
4343

4444
"github.com/sigstore/sigstore/pkg/cryptoutils"
45+
"github.com/sigstore/sigstore/pkg/signature"
46+
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
4547
)
4648

4749
func isb64(data []byte) bool {
@@ -171,10 +173,15 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
171173
}
172174
}
173175

176+
svOpts := []signature.LoadOption{
177+
signatureoptions.WithHash(crypto.SHA256),
178+
signatureoptions.WithED25519ph(),
179+
}
180+
174181
// Keys are optional!
175182
switch {
176183
case c.KeyRef != "":
177-
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
184+
co.SigVerifier, err = sigs.PublicKeyFromKeyRefWithOpts(ctx, c.KeyRef, svOpts...)
178185
if err != nil {
179186
return fmt.Errorf("loading public key: %w", err)
180187
}
@@ -219,7 +226,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
219226
bundleCert, err := loadCertFromPEM(certBytes)
220227
if err != nil {
221228
// check if cert is actually a public key
222-
co.SigVerifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256)
229+
co.SigVerifier, err = sigs.LoadPublicKeyRawWithOpts(certBytes, svOpts...)
223230
if err != nil {
224231
return fmt.Errorf("loading verifier from bundle: %w", err)
225232
}
@@ -298,7 +305,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
298305
if err != nil {
299306
return err
300307
}
301-
if _, err = cosign.VerifyBlobSignature(ctx, signature, co); err != nil {
308+
if _, err = cosign.VerifyBlobSignatureWithOpts(ctx, signature, co, svOpts...); err != nil {
302309
return err
303310
}
304311

cmd/cosign/cli/verify/verify_blob_attestation.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package verify
1818
import (
1919
"context"
2020
"crypto"
21-
"crypto/sha256"
2221
"crypto/x509"
2322
"encoding/base64"
2423
"encoding/hex"
@@ -118,7 +117,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
118117
}
119118
defer f.Close()
120119

121-
payload = internal.NewHashReader(f, sha256.New())
120+
payload = internal.NewHashReader(f, crypto.SHA256)
122121
if _, err := io.ReadAll(&payload); err != nil {
123122
return err
124123
}

go.mod

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,13 @@ require (
147147
github.com/go-jose/go-jose/v3 v3.0.2 // indirect
148148
github.com/go-logr/logr v1.4.1 // indirect
149149
github.com/go-logr/stdr v1.2.2 // indirect
150-
github.com/go-openapi/analysis v0.22.0 // indirect
150+
github.com/go-openapi/analysis v0.22.2 // indirect
151151
github.com/go-openapi/errors v0.21.0 // indirect
152152
github.com/go-openapi/jsonpointer v0.20.2 // indirect
153153
github.com/go-openapi/jsonreference v0.20.4 // indirect
154154
github.com/go-openapi/loads v0.21.5 // indirect
155155
github.com/go-openapi/spec v0.20.14 // indirect
156-
github.com/go-openapi/validate v0.22.6 // indirect
156+
github.com/go-openapi/validate v0.23.0 // indirect
157157
github.com/gobwas/glob v0.2.3 // indirect
158158
github.com/gogo/protobuf v1.3.2 // indirect
159159
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
@@ -188,7 +188,7 @@ require (
188188
github.com/jmespath/go-jmespath v0.4.0 // indirect
189189
github.com/josharian/intern v1.0.0 // indirect
190190
github.com/json-iterator/go v1.1.12 // indirect
191-
github.com/klauspost/compress v1.17.2 // indirect
191+
github.com/klauspost/compress v1.17.4 // indirect
192192
github.com/kylelemons/godebug v1.1.0 // indirect
193193
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
194194
github.com/magiconair/properties v1.8.7 // indirect
@@ -251,9 +251,9 @@ require (
251251
go.opentelemetry.io/otel/sdk v1.22.0 // indirect
252252
go.opentelemetry.io/otel/trace v1.23.0 // indirect
253253
go.uber.org/multierr v1.11.0 // indirect
254-
go.uber.org/zap v1.26.0 // indirect
254+
go.uber.org/zap v1.27.0 // indirect
255255
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
256-
golang.org/x/mod v0.14.0 // indirect
256+
golang.org/x/mod v0.15.0 // indirect
257257
golang.org/x/net v0.21.0 // indirect
258258
golang.org/x/sys v0.17.0 // indirect
259259
golang.org/x/text v0.14.0 // indirect
@@ -263,7 +263,7 @@ require (
263263
google.golang.org/genproto v0.0.0-20240205150955-31a09d347014 // indirect
264264
google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 // indirect
265265
google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 // indirect
266-
google.golang.org/grpc v1.61.1 // indirect
266+
google.golang.org/grpc v1.62.0 // indirect
267267
google.golang.org/protobuf v1.32.0 // indirect
268268
gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect
269269
gopkg.in/inf.v0 v0.9.1 // indirect
@@ -276,3 +276,5 @@ require (
276276
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
277277
sigs.k8s.io/yaml v1.4.0 // indirect
278278
)
279+
280+
replace github.com/sigstore/rekor => github.com/trail-of-forks/rekor v0.0.0-20240228223424-d5141b63a1f2

0 commit comments

Comments
 (0)