@@ -19,6 +19,7 @@ package cosign
1919import (
2020 "context"
2121 "crypto"
22+ "crypto/tls"
2223 "fmt"
2324 "sync"
2425 "time"
@@ -27,9 +28,10 @@ import (
2728 "github.com/google/go-containerregistry/pkg/v1/remote"
2829 "github.com/sigstore/cosign/v3/cmd/cosign/cli/fulcio"
2930 coptions "github.com/sigstore/cosign/v3/cmd/cosign/cli/options"
30- "github.com/sigstore/cosign/v3/cmd/cosign/cli/rekor"
3131 "github.com/sigstore/cosign/v3/pkg/cosign"
3232 "github.com/sigstore/cosign/v3/pkg/oci"
33+ rekorclient "github.com/sigstore/rekor/pkg/client"
34+ rekorgenclient "github.com/sigstore/rekor/pkg/generated/client"
3335
3436 ociremote "github.com/sigstore/cosign/v3/pkg/oci/remote"
3537 "github.com/sigstore/sigstore-go/pkg/root"
@@ -45,6 +47,8 @@ type options struct {
4547 rOpt []remote.Option
4648 identities []cosign.Identity
4749 trustedRoot []byte
50+ insecure bool
51+ tlsConfig * tls.Config
4852}
4953
5054// Options is a function that configures the options applied to a Verifier.
@@ -83,9 +87,27 @@ func WithTrustedRoot(trustedRoot []byte) Options {
8387 }
8488}
8589
90+ // WithInsecure sets the verifier to use HTTP when discovering v3 bundle
91+ // signatures from the container registry via OCI referrers tag fallback.
92+ // Does not affect Rekor connections.
93+ func WithInsecure (insecure bool ) Options {
94+ return func (opts * options ) {
95+ opts .insecure = insecure
96+ }
97+ }
98+
99+ // WithTLSConfig sets the TLS configuration for Rekor client connections.
100+ // When nil, the system trust store is used.
101+ func WithTLSConfig (tlsConfig * tls.Config ) Options {
102+ return func (opts * options ) {
103+ opts .tlsConfig = tlsConfig
104+ }
105+ }
106+
86107// CosignVerifier is a struct which is responsible for executing verification logic.
87108type CosignVerifier struct {
88- opts * cosign.CheckOpts
109+ opts * cosign.CheckOpts
110+ insecure bool
89111}
90112
91113// CosignVerifierFactory is a factory for creating Verifiers with shared state.
@@ -152,7 +174,7 @@ func (f *CosignVerifierFactory) NewCosignVerifier(ctx context.Context, opts ...O
152174 return nil , err
153175 }
154176
155- return & CosignVerifier {opts : checkOpts }, nil
177+ return & CosignVerifier {opts : checkOpts , insecure : o . insecure }, nil
156178 }
157179
158180 // Keyless verification: when a custom trusted root is provided, use it
@@ -171,16 +193,16 @@ func (f *CosignVerifierFactory) NewCosignVerifier(ctx context.Context, opts ...O
171193 return nil , fmt .Errorf ("unable to extract Rekor URL from trusted root: %w" , err )
172194 }
173195
174- checkOpts .RekorClient , err = rekor . NewClient (rekorURL )
196+ checkOpts .RekorClient , err = newRekorClient (rekorURL , o . tlsConfig )
175197 if err != nil {
176198 return nil , fmt .Errorf ("unable to create Rekor client: %w" , err )
177199 }
178200
179- return & CosignVerifier {opts : checkOpts }, nil
201+ return & CosignVerifier {opts : checkOpts , insecure : o . insecure }, nil
180202 }
181203
182204 // Keyless verification using the public Sigstore infrastructure.
183- checkOpts .RekorClient , err = rekor . NewClient (coptions .DefaultRekorURL )
205+ checkOpts .RekorClient , err = newRekorClient (coptions .DefaultRekorURL , o . tlsConfig )
184206 if err != nil {
185207 return nil , fmt .Errorf ("unable to create Rekor client: %w" , err )
186208 }
@@ -233,7 +255,17 @@ func (f *CosignVerifierFactory) NewCosignVerifier(ctx context.Context, opts ...O
233255 return nil , fmt .Errorf ("unable to get Fulcio intermediate certs: %w" , err )
234256 }
235257
236- return & CosignVerifier {opts : checkOpts }, nil
258+ return & CosignVerifier {opts : checkOpts , insecure : o .insecure }, nil
259+ }
260+
261+ // newRekorClient creates a Rekor client with optional TLS configuration.
262+ // If tlsConfig is nil, the default system trust store is used.
263+ func newRekorClient (rekorURL string , tlsConfig * tls.Config ) (* rekorgenclient.Rekor , error ) {
264+ opts := []rekorclient.Option {rekorclient .WithUserAgent (coptions .UserAgent ())}
265+ if tlsConfig != nil {
266+ opts = append (opts , rekorclient .WithTLSConfig (tlsConfig ))
267+ }
268+ return rekorclient .GetRekorClient (rekorURL , opts ... )
237269}
238270
239271// rekorURLFromTrustedRoot extracts the Rekor base URL from a trusted root's
@@ -265,14 +297,21 @@ func (v *CosignVerifier) Verify(ctx context.Context, ref name.Reference) (soci.V
265297 var signatures []oci.Signature
266298 // copy options since we'll need to change them based on bundle discovery on the ref
267299 opts := * v .opts
268- newBundles , _ , err := cosign .GetBundles (ctx , ref , opts .RegistryClientOpts )
300+
301+ // Pass insecure to GetBundles for internal bundle digest references.
302+ var nameOpts []name.Option
303+ if v .insecure {
304+ nameOpts = append (nameOpts , name .Insecure )
305+ }
306+
307+ newBundles , _ , err := cosign .GetBundles (ctx , ref , opts .RegistryClientOpts , nameOpts ... )
269308 // if no bundles are returned, let's fallback to the cosign v2 behavior, similar to the cosign CLI
270309 if len (newBundles ) == 0 || err != nil {
271310 opts .NewBundleFormat = false
272311 signatures , _ , err = cosign .VerifyImageSignatures (ctx , ref , & opts )
273312 } else {
274313 opts .NewBundleFormat = true
275- signatures , _ , err = cosign .VerifyImageAttestations (ctx , ref , & opts )
314+ signatures , _ , err = cosign .VerifyImageAttestations (ctx , ref , & opts , nameOpts ... )
276315 }
277316 if err != nil {
278317 return soci .VerificationResultFailed , err
0 commit comments