Skip to content

Commit e8f915a

Browse files
Bump sigstore-go, support alternative hash algorithms with keys
sigstore-go now handles non-ECDSA-P-256 signatures with Rekor v2. To support verification, we also need a way to provide alternative hash algorithms to the default SHA-256. cosign verify already had a flag for this, so I added the flag to all verify commands. In the future, when we are only processing bundles, we can lookup the default hash algorithm given the key. Signed-off-by: Hayden <[email protected]>
1 parent 62a960c commit e8f915a

File tree

12 files changed

+120
-23
lines changed

12 files changed

+120
-23
lines changed

cmd/cosign/cli/options/verify.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ type VerifyAttestationOptions struct {
137137
CertVerify CertVerifyOptions
138138
Registry RegistryOptions
139139
Predicate PredicateRemoteOptions
140+
SignatureDigest SignatureDigestOptions
140141
Policies []string
141142
LocalImage bool
142143
}
@@ -151,6 +152,7 @@ func (o *VerifyAttestationOptions) AddFlags(cmd *cobra.Command) {
151152
o.Registry.AddFlags(cmd)
152153
o.Predicate.AddFlags(cmd)
153154
o.CommonVerifyOptions.AddFlags(cmd)
155+
o.SignatureDigest.AddFlags(cmd)
154156

155157
cmd.Flags().StringVar(&o.Key, "key", "",
156158
"path to the public key file, KMS URI or Kubernetes Secret")
@@ -178,6 +180,7 @@ type VerifyBlobOptions struct {
178180
CertVerify CertVerifyOptions
179181
Rekor RekorOptions
180182
CommonVerifyOptions CommonVerifyOptions
183+
SignatureDigest SignatureDigestOptions
181184

182185
RFC3161TimestampPath string
183186
}
@@ -190,6 +193,7 @@ func (o *VerifyBlobOptions) AddFlags(cmd *cobra.Command) {
190193
o.Rekor.AddFlags(cmd)
191194
o.CertVerify.AddFlags(cmd)
192195
o.CommonVerifyOptions.AddFlags(cmd)
196+
o.SignatureDigest.AddFlags(cmd)
193197

194198
cmd.Flags().StringVar(&o.Key, "key", "",
195199
"path to the public key file, KMS URI or Kubernetes Secret")
@@ -233,6 +237,7 @@ type VerifyBlobAttestationOptions struct {
233237
CertVerify CertVerifyOptions
234238
Rekor RekorOptions
235239
CommonVerifyOptions CommonVerifyOptions
240+
SignatureDigest SignatureDigestOptions
236241

237242
RFC3161TimestampPath string
238243

@@ -249,6 +254,7 @@ func (o *VerifyBlobAttestationOptions) AddFlags(cmd *cobra.Command) {
249254
o.Rekor.AddFlags(cmd)
250255
o.CertVerify.AddFlags(cmd)
251256
o.CommonVerifyOptions.AddFlags(cmd)
257+
o.SignatureDigest.AddFlags(cmd)
252258

253259
cmd.Flags().StringVar(&o.Key, "key", "",
254260
"path to the public key file, KMS URI or Kubernetes Secret")

cmd/cosign/cli/verify.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ against the transparency log.`,
218218
o.CommonVerifyOptions.IgnoreTlog = true
219219
}
220220

221+
hashAlgorithm, err := o.SignatureDigest.HashAlgorithm()
222+
if err != nil {
223+
return err
224+
}
225+
221226
v := &verify.VerifyAttestationCommand{
222227
RegistryOptions: o.Registry,
223228
CommonVerifyOptions: o.CommonVerifyOptions,
@@ -247,6 +252,7 @@ against the transparency log.`,
247252
TSACertChainPath: o.CommonVerifyOptions.TSACertChainPath,
248253
IgnoreTlog: o.CommonVerifyOptions.IgnoreTlog,
249254
MaxWorkers: o.CommonVerifyOptions.MaxWorkers,
255+
HashAlgorithm: hashAlgorithm,
250256
UseSignedTimestamps: o.CommonVerifyOptions.UseSignedTimestamps,
251257
}
252258

@@ -330,6 +336,11 @@ The blob may be specified as a path to a file or - for stdin.`,
330336
o.CommonVerifyOptions.IgnoreTlog = true
331337
}
332338

339+
hashAlgorithm, err := o.SignatureDigest.HashAlgorithm()
340+
if err != nil {
341+
return err
342+
}
343+
333344
ko := options.KeyOpts{
334345
KeyRef: o.Key,
335346
Sk: o.SecurityKey.Use,
@@ -359,6 +370,7 @@ The blob may be specified as a path to a file or - for stdin.`,
359370
IgnoreTlog: o.CommonVerifyOptions.IgnoreTlog,
360371
UseSignedTimestamps: o.CommonVerifyOptions.UseSignedTimestamps,
361372
TrustedRootPath: o.CommonVerifyOptions.TrustedRootPath,
373+
HashAlgorithm: hashAlgorithm,
362374
}
363375

364376
ctx, cancel := context.WithTimeout(cmd.Context(), ro.Timeout)
@@ -401,6 +413,11 @@ The blob may be specified as a path to a file.`,
401413
o.CommonVerifyOptions.IgnoreTlog = true
402414
}
403415

416+
hashAlgorithm, err := o.SignatureDigest.HashAlgorithm()
417+
if err != nil {
418+
return err
419+
}
420+
404421
ko := options.KeyOpts{
405422
KeyRef: o.Key,
406423
Sk: o.SecurityKey.Use,
@@ -434,6 +451,7 @@ The blob may be specified as a path to a file.`,
434451
TrustedRootPath: o.CommonVerifyOptions.TrustedRootPath,
435452
Digest: o.Digest,
436453
DigestAlg: o.DigestAlg,
454+
HashAlgorithm: hashAlgorithm,
437455
}
438456
// We only use the blob if we are checking claims.
439457
if o.CheckClaims && len(args) == 0 && (o.Digest == "" || o.DigestAlg == "") {

cmd/cosign/cli/verify/verify_attestation.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package verify
1717

1818
import (
1919
"context"
20+
"crypto"
2021
"errors"
2122
"flag"
2223
"fmt"
@@ -73,6 +74,7 @@ type VerifyAttestationCommand struct {
7374
IgnoreTlog bool
7475
MaxWorkers int
7576
UseSignedTimestamps bool
77+
HashAlgorithm crypto.Hash
7678
}
7779

7880
// Exec runs the verification command
@@ -81,6 +83,11 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (e
8183
return flag.ErrHelp
8284
}
8385

86+
// always default to sha256 if the algorithm hasn't been explicitly set
87+
if c.HashAlgorithm == 0 {
88+
c.HashAlgorithm = crypto.SHA256
89+
}
90+
8491
// We can't have both a key and a security key
8592
if options.NOf(c.KeyRef, c.Sk) > 1 {
8693
return &options.KeyParseError{}
@@ -191,7 +198,7 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (e
191198
// Keys are optional!
192199
switch {
193200
case keyRef != "":
194-
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, keyRef)
201+
co.SigVerifier, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm)
195202
if err != nil {
196203
return fmt.Errorf("loading public key: %w", err)
197204
}

cmd/cosign/cli/verify/verify_blob.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,16 @@ type VerifyBlobCmd struct {
7474
Offline bool
7575
UseSignedTimestamps bool
7676
IgnoreTlog bool
77+
HashAlgorithm crypto.Hash
7778
}
7879

7980
// nolint
8081
func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
82+
// always default to sha256 if the algorithm hasn't been explicitly set
83+
if c.HashAlgorithm == 0 {
84+
c.HashAlgorithm = crypto.SHA256
85+
}
86+
8187
// Require a certificate/key OR a local bundle file that has the cert.
8288
if options.NOf(c.KeyRef, c.CertRef, c.Sk, c.BundlePath) == 0 {
8389
return fmt.Errorf("provide a key with --key or --sk, a certificate to verify against with --certificate, or a bundle with --bundle")
@@ -116,7 +122,7 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
116122
opts := make([]static.Option, 0)
117123
switch {
118124
case c.KeyRef != "":
119-
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
125+
co.SigVerifier, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, c.KeyRef, c.HashAlgorithm)
120126
if err != nil {
121127
return fmt.Errorf("loading public key: %w", err)
122128
}

cmd/cosign/cli/verify/verify_blob_attestation.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ type VerifyBlobAttestationCommand struct {
7979
SignaturePath string // Path to the signature
8080
UseSignedTimestamps bool
8181

82-
Digest string
83-
DigestAlg string
82+
Digest string
83+
DigestAlg string
84+
HashAlgorithm crypto.Hash
8485
}
8586

8687
// Exec runs the verification command
@@ -89,6 +90,11 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
8990
return fmt.Errorf("please specify path to the DSSE envelope signature via --signature or --bundle")
9091
}
9192

93+
// always default to sha256 if the algorithm hasn't been explicitly set
94+
if c.HashAlgorithm == 0 {
95+
c.HashAlgorithm = crypto.SHA256
96+
}
97+
9298
// Require a certificate/key OR a local bundle file that has the cert.
9399
if options.NOf(c.KeyRef, c.CertRef, c.Sk, c.BundlePath) == 0 {
94100
return fmt.Errorf("provide a key with --key or --sk, a certificate to verify against with --certificate, or a bundle with --bundle")
@@ -126,7 +132,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
126132
opts := make([]static.Option, 0)
127133
switch {
128134
case c.KeyRef != "":
129-
co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, c.KeyRef)
135+
co.SigVerifier, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, c.KeyRef, c.HashAlgorithm)
130136
if err != nil {
131137
return fmt.Errorf("loading public key: %w", err)
132138
}

doc/cosign_verify-attestation.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/cosign_verify-blob-attestation.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/cosign_verify-blob.md

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/go-jose/go-jose/v4 v4.1.2
1616
github.com/go-openapi/runtime v0.28.0
1717
github.com/go-openapi/strfmt v0.23.0
18-
github.com/go-openapi/swag v0.23.1
18+
github.com/go-openapi/swag v0.24.1
1919
github.com/go-piv/piv-go/v2 v2.4.0
2020
github.com/google/certificate-transparency-go v1.3.2
2121
github.com/google/go-cmp v0.7.0
@@ -34,10 +34,10 @@ require (
3434
github.com/secure-systems-lab/go-securesystemslib v0.9.1
3535
github.com/sigstore/fulcio v1.7.1
3636
github.com/sigstore/protobuf-specs v0.5.0
37-
github.com/sigstore/rekor v1.4.1
37+
github.com/sigstore/rekor v1.4.2
3838
github.com/sigstore/rekor-tiles v0.1.10
3939
github.com/sigstore/sigstore v1.9.6-0.20250729224751-181c5d3339b3
40-
github.com/sigstore/sigstore-go v1.1.2-0.20250811211025-bac873564adb
40+
github.com/sigstore/sigstore-go v1.1.2
4141
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.9.5
4242
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.9.5
4343
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.9.6-0.20250729224751-181c5d3339b3
@@ -163,7 +163,7 @@ require (
163163
github.com/fsnotify/fsnotify v1.9.0 // indirect
164164
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
165165
github.com/go-chi/chi v4.1.2+incompatible // indirect
166-
github.com/go-chi/chi/v5 v5.2.2 // indirect
166+
github.com/go-chi/chi/v5 v5.2.3 // indirect
167167
github.com/go-ini/ini v1.67.0 // indirect
168168
github.com/go-logr/logr v1.4.3 // indirect
169169
github.com/go-logr/stdr v1.2.2 // indirect
@@ -173,6 +173,17 @@ require (
173173
github.com/go-openapi/jsonreference v0.21.0 // indirect
174174
github.com/go-openapi/loads v0.22.0 // indirect
175175
github.com/go-openapi/spec v0.21.0 // indirect
176+
github.com/go-openapi/swag/cmdutils v0.24.0 // indirect
177+
github.com/go-openapi/swag/conv v0.24.0 // indirect
178+
github.com/go-openapi/swag/fileutils v0.24.0 // indirect
179+
github.com/go-openapi/swag/jsonname v0.24.0 // indirect
180+
github.com/go-openapi/swag/jsonutils v0.24.0 // indirect
181+
github.com/go-openapi/swag/loading v0.24.0 // indirect
182+
github.com/go-openapi/swag/mangling v0.24.0 // indirect
183+
github.com/go-openapi/swag/netutils v0.24.0 // indirect
184+
github.com/go-openapi/swag/stringutils v0.24.0 // indirect
185+
github.com/go-openapi/swag/typeutils v0.24.0 // indirect
186+
github.com/go-openapi/swag/yamlutils v0.24.0 // indirect
176187
github.com/go-openapi/validate v0.24.0 // indirect
177188
github.com/go-sql-driver/mysql v1.9.3 // indirect
178189
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
@@ -296,12 +307,12 @@ require (
296307
go.yaml.in/yaml/v2 v2.4.2 // indirect
297308
go.yaml.in/yaml/v3 v3.0.4 // indirect
298309
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
299-
golang.org/x/mod v0.27.0 // indirect
310+
golang.org/x/mod v0.28.0 // indirect
300311
golang.org/x/net v0.43.0 // indirect
301312
golang.org/x/sys v0.35.0 // indirect
302313
golang.org/x/text v0.28.0 // indirect
303314
golang.org/x/time v0.12.0 // indirect
304-
golang.org/x/tools v0.35.0 // indirect
315+
golang.org/x/tools v0.36.0 // indirect
305316
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
306317
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
307318
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect

0 commit comments

Comments
 (0)