diff --git a/Makefile b/Makefile index 7d4e0496..1b386cae 100644 --- a/Makefile +++ b/Makefile @@ -10,3 +10,6 @@ binary: @echo "Making $@ ..." @docker pull neuvector/build_fleet:${BUILD_IMAGE_TAG} @docker run --rm -ia STDOUT --name build --net=none -v $(CURDIR):/go/src/github.com/neuvector/sigstore-interface -w /go/src/github.com/neuvector/sigstore-interface --entrypoint ./make_bin.sh neuvector/build_fleet:${BUILD_IMAGE_TAG} + +test: + go build -ldflags='-s -w' -buildvcs=false . && bash ./integration-test.sh \ No newline at end of file diff --git a/go.mod b/go.mod index 74680a66..50900b60 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ toolchain go1.22.5 require ( github.com/google/go-containerregistry v0.19.1 github.com/sigstore/cosign/v2 v2.2.4 + github.com/sigstore/rekor v1.3.6 github.com/sigstore/sigstore v1.8.3 github.com/theupdateframework/go-tuf v0.7.0 ) @@ -82,7 +83,6 @@ require ( github.com/sassoftware/relic v7.2.1+incompatible // indirect github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect - github.com/sigstore/rekor v1.3.6 // indirect github.com/sigstore/timestamp-authority v1.2.2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/integration-test.sh b/integration-test.sh new file mode 100644 index 00000000..92725b78 --- /dev/null +++ b/integration-test.sh @@ -0,0 +1,16 @@ +echo "#############################" +echo "testing rootless keypair only" +echo "#############################" +./sigstore-interface --config-file testing/cases/rootless-keypair-only.json +echo "" + +echo "#############################" +echo "testing public keypair" +echo "#############################" +./sigstore-interface --config-file testing/cases/public-keypair.json +echo "" + +echo "#############################" +echo "testing suse app collection" +echo "#############################" +./sigstore-interface --config-file testing/cases/suse-app-collection.json \ No newline at end of file diff --git a/main.go b/main.go index a459dc06..61939179 100644 --- a/main.go +++ b/main.go @@ -19,10 +19,13 @@ import ( "github.com/sigstore/cosign/v2/pkg/oci" "github.com/sigstore/cosign/v2/pkg/oci/signature" sig "github.com/sigstore/cosign/v2/pkg/signature" + rekor "github.com/sigstore/rekor/pkg/client" "github.com/sigstore/sigstore/pkg/cryptoutils" sigtuf "github.com/sigstore/sigstore/pkg/tuf" ) +const DEFAULT_REKOR_URL string = "https://rekor.sigstore.dev" + type Configuration struct { ImageDigest string `json:"ImageDigest"` RootsOfTrust []RootOfTrust `json:"RootsOfTrust"` @@ -159,6 +162,10 @@ func generateCosignSignatureObjects(sigData SignatureData) ([]oci.Signature, err return signatures, nil } +func printWarningLine(message string) { + fmt.Printf("\033[33m%s\033[0m\n", message) +} + func verify(imgDigest v1.Hash, rootOfTrust RootOfTrust, sigs []oci.Signature, proxy Proxy) (satisfiedVerifiers []string, err error) { ctx := context.Background() cosignOptions := cosign.CheckOpts{ClaimVerifier: cosign.SimpleClaimVerifier} @@ -169,22 +176,35 @@ func verify(imgDigest v1.Hash, rootOfTrust RootOfTrust, sigs []oci.Signature, pr for _, verifier := range rootOfTrust.Verifiers { cosignOptions.SigVerifier = nil cosignOptions.Identities = nil + fmt.Printf(">> checking verifier %s\n", verifier.Name) err = setVerifierCosignOptions(&cosignOptions, verifier, rootOfTrust, ctx) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) - } else { - for i, signature := range sigs { - fmt.Printf("verifying signature %d\n", i) - _, err := cosign.VerifyImageSignature(ctx, signature, imgDigest, &cosignOptions) - if err != nil { - // the image is not signed by this verifier - fmt.Printf("signature not verified: %s\n", err.Error()) - } else { - fmt.Printf("signature %d satisfies verifier %s\n", i, verifier.Name) - satisfiedVerifiers = append(satisfiedVerifiers, fmt.Sprintf("%s/%s", rootOfTrust.Name, verifier.Name)) - break - } + fmt.Println("could not create valid cosign options for verifier, skipping verifier") + continue + } + + for i, signature := range sigs { + bundle, err := signature.Bundle() + if err != nil { + fmt.Printf("error when retrieving bundle for signature, skipping signature: %s\n", err.Error()) + continue + } + if bundle == nil { + printWarningLine("no bundle found, any tlog verification must happen through network") + } else { + fmt.Printf("signature bundle: %s\n", bundle.Payload.LogID) + } + fmt.Printf("verifying signature %d\n", i) + _, err = cosign.VerifyImageSignature(ctx, signature, imgDigest, &cosignOptions) + if err != nil { + // the image is not signed by this verifier + fmt.Printf("signature not verified: %s\n", err.Error()) + } else { + fmt.Printf("signature %d satisfies verifier %s\n", i, verifier.Name) + satisfiedVerifiers = append(satisfiedVerifiers, fmt.Sprintf("%s/%s", rootOfTrust.Name, verifier.Name)) + break } } } @@ -319,6 +339,12 @@ func setVerifierCosignOptions(cosignOptions *cosign.CheckOpts, verifier Verifier if rootOfTrust.SCTPublicKey == "" { cosignOptions.IgnoreSCT = true } + } else { + rekorClient, err := rekor.GetRekorClient(DEFAULT_REKOR_URL) + if err != nil { + return fmt.Errorf("could not get rekor client for online tlog validation: %s", err.Error()) + } + cosignOptions.RekorClient = rekorClient } if rootOfTrust.RootlessKeypairsOnly { cosignOptions.IgnoreSCT = true diff --git a/testing/cases/public-keypair.json b/testing/cases/public-keypair.json new file mode 100644 index 00000000..80d713e8 --- /dev/null +++ b/testing/cases/public-keypair.json @@ -0,0 +1,28 @@ +{ + "ImageDigest": "sha256:c2ced31c5dda37cb805f481e3fa34b742cc8980f439b20af3111b08e66cff8e1", + "RootsOfTrust": [ + { + "Name": "public-root-of-trust", + "RootlessKeypairsOnly": false, + "Verifiers": [ + { + "Name": "esther-keypair", + "Type": "keypair", + "KeyPairOptions": { + "PublicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbAOAuM6OwpU/buX7td4VvyKUGyI6\nwXPSUQjeQwc2wzr4wNveeQ4LbZbtH8bAohoOwfgeHUiVFwpgGIB6d+J3hw==\n-----END PUBLIC KEY-----" + }, + "KeylessOptions": { + "CertIssuer": "", + "CertSubject": "" + } + } + ] + } + ], + "SignatureData": { + "Manifest": "{\"schemaVersion\":2,\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"size\":243,\"digest\":\"sha256:ff9575f3be16905499996bc3f8045d86ce9d9f8aabdd192c47eb3824f7df30da\"},\"layers\":[{\"mediaType\":\"application/vnd.dev.cosign.simplesigning.v1+json\",\"size\":243,\"digest\":\"sha256:19cf962d284f30ff6d6b5744e61f8f200311c35aac53e5f50019aea690582e4b\",\"annotations\":{\"dev.cosignproject.cosign/signature\":\"MEYCIQCz8Hg3Ad/d5Pe5/I+jWlgIpKsRyY8YKvwiuqYPrQK2DgIhAMe/lJN08Ylieb22rJ9D7LEP5QJHruAX6GGgQ+RZyi5N\",\"dev.sigstore.cosign/bundle\":\"{\\\"SignedEntryTimestamp\\\":\\\"MEUCIHol8ZGEFFDNSIDL36wuBwOwRmqzLMcUxHVDbFB0jkW7AiEAsI1nquIgcg6/jvDOt2Tj6dMJdvIR4/dgyrUgG3VgNd0=\\\",\\\"Payload\\\":{\\\"body\\\":\\\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIxOWNmOTYyZDI4NGYzMGZmNmQ2YjU3NDRlNjFmOGYyMDAzMTFjMzVhYWM1M2U1ZjUwMDE5YWVhNjkwNTgyZTRiIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUN6OEhnM0FkL2Q1UGU1L0kraldsZ0lwS3NSeVk4WUt2d2l1cVlQclFLMkRnSWhBTWUvbEpOMDhZbGllYjIycko5RDdMRVA1UUpIcnVBWDZHR2dRK1JaeWk1TiIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGWWtGUFFYVk5OazkzY0ZVdlluVllOM1JrTkZaMmVVdFZSM2xKTmdwM1dGQlRWVkZxWlZGM1l6SjNlbkkwZDA1MlpXVlJORXhpV21KMFNEaGlRVzlvYjA5M1ptZGxTRlZwVmtaM2NHZEhTVUkyWkN0S00yaDNQVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0=\\\",\\\"integratedTime\\\":1685639122,\\\"logIndex\\\":22394206,\\\"logID\\\":\\\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\\\"}}\"}}]}", + "Payloads": { + "sha256:19cf962d284f30ff6d6b5744e61f8f200311c35aac53e5f50019aea690582e4b": "{\"critical\":{\"identity\":{\"docker-reference\":\"quay.io/nvlab/cosign-esther\"},\"image\":{\"docker-manifest-digest\":\"sha256:c2ced31c5dda37cb805f481e3fa34b742cc8980f439b20af3111b08e66cff8e1\"},\"type\":\"cosign container image signature\"},\"optional\":null}" + } + } +} \ No newline at end of file diff --git a/testing/cases/rootless-keypair-only.json b/testing/cases/rootless-keypair-only.json new file mode 100644 index 00000000..a2b7d73f --- /dev/null +++ b/testing/cases/rootless-keypair-only.json @@ -0,0 +1,28 @@ +{ + "ImageDigest": "sha256:c2ced31c5dda37cb805f481e3fa34b742cc8980f439b20af3111b08e66cff8e1", + "RootsOfTrust": [ + { + "Name": "public-root-of-trust", + "RootlessKeypairsOnly": true, + "Verifiers": [ + { + "Name": "esther-keypair", + "Type": "keypair", + "KeyPairOptions": { + "PublicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbAOAuM6OwpU/buX7td4VvyKUGyI6\nwXPSUQjeQwc2wzr4wNveeQ4LbZbtH8bAohoOwfgeHUiVFwpgGIB6d+J3hw==\n-----END PUBLIC KEY-----" + }, + "KeylessOptions": { + "CertIssuer": "", + "CertSubject": "" + } + } + ] + } + ], + "SignatureData": { + "Manifest": "{\"schemaVersion\":2,\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"size\":243,\"digest\":\"sha256:ff9575f3be16905499996bc3f8045d86ce9d9f8aabdd192c47eb3824f7df30da\"},\"layers\":[{\"mediaType\":\"application/vnd.dev.cosign.simplesigning.v1+json\",\"size\":243,\"digest\":\"sha256:19cf962d284f30ff6d6b5744e61f8f200311c35aac53e5f50019aea690582e4b\",\"annotations\":{\"dev.cosignproject.cosign/signature\":\"MEYCIQCz8Hg3Ad/d5Pe5/I+jWlgIpKsRyY8YKvwiuqYPrQK2DgIhAMe/lJN08Ylieb22rJ9D7LEP5QJHruAX6GGgQ+RZyi5N\",\"dev.sigstore.cosign/bundle\":\"{\\\"SignedEntryTimestamp\\\":\\\"MEUCIHol8ZGEFFDNSIDL36wuBwOwRmqzLMcUxHVDbFB0jkW7AiEAsI1nquIgcg6/jvDOt2Tj6dMJdvIR4/dgyrUgG3VgNd0=\\\",\\\"Payload\\\":{\\\"body\\\":\\\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIxOWNmOTYyZDI4NGYzMGZmNmQ2YjU3NDRlNjFmOGYyMDAzMTFjMzVhYWM1M2U1ZjUwMDE5YWVhNjkwNTgyZTRiIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUN6OEhnM0FkL2Q1UGU1L0kraldsZ0lwS3NSeVk4WUt2d2l1cVlQclFLMkRnSWhBTWUvbEpOMDhZbGllYjIycko5RDdMRVA1UUpIcnVBWDZHR2dRK1JaeWk1TiIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGWWtGUFFYVk5OazkzY0ZVdlluVllOM1JrTkZaMmVVdFZSM2xKTmdwM1dGQlRWVkZxWlZGM1l6SjNlbkkwZDA1MlpXVlJORXhpV21KMFNEaGlRVzlvYjA5M1ptZGxTRlZwVmtaM2NHZEhTVUkyWkN0S00yaDNQVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0=\\\",\\\"integratedTime\\\":1685639122,\\\"logIndex\\\":22394206,\\\"logID\\\":\\\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\\\"}}\"}}]}", + "Payloads": { + "sha256:19cf962d284f30ff6d6b5744e61f8f200311c35aac53e5f50019aea690582e4b": "{\"critical\":{\"identity\":{\"docker-reference\":\"quay.io/nvlab/cosign-esther\"},\"image\":{\"docker-manifest-digest\":\"sha256:c2ced31c5dda37cb805f481e3fa34b742cc8980f439b20af3111b08e66cff8e1\"},\"type\":\"cosign container image signature\"},\"optional\":null}" + } + } +} \ No newline at end of file diff --git a/testing/cases/suse-app-collection.json b/testing/cases/suse-app-collection.json new file mode 100644 index 00000000..addf8462 --- /dev/null +++ b/testing/cases/suse-app-collection.json @@ -0,0 +1,24 @@ +{ + "ImageDigest": "sha256:30e637c70f75c9f22ee0f2b4d0c3471ad3ed2f153f994ec5fe1031ab27d4282c", + "RootsOfTrust": [ + { + "Name": "public-root", + "Verifiers": [ + { + "Name": "suse-app-collection-key", + "Type": "keypair", + "KeypairOptions": { + "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA02FtEt5gBywiyxbmkVsb\nCujcBg5lur0kpEbfDk10gCcs9shVEqEO3ZsOXHursgoaDAWqdPtsYhsgczGeJz9w\nAw+r6BuRV8YOkE37A8s/7IOQUW0tlqtnt11OKhIiZ9+e5l3ed2H1ymKQO3dgreSy\nrShqYdA3hrItswyp41ApF6zhjSPlR6lAmq3X4wMYLAPptmzfxigTnR4hxB5UNPhs\ni2qA4vLrUM/i+NohECuLr1EAymvupH26HLEdM+eZnlQn+WbhIP5Grc4ba7XrBv7K\nkywgTC7CxkiJZR0mUcUD2wTX/Je8Ewj6oPSalx09e2jtzvmU5Kr9XUyMF7Zsj5CA\nIwIDAQAB\n-----END PUBLIC KEY-----" + }, + "KeylessOptions": {} + } + ] + } + ], + "SignatureData": { + "Manifest": "{\"schemaVersion\":2,\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"size\":233,\"digest\":\"sha256:d68903a35c7e4df921427de185d2fb6238c26fbe98e87151b3245900732ba626\"},\"layers\":[{\"mediaType\":\"application/vnd.dev.cosign.simplesigning.v1+json\",\"size\":266,\"digest\":\"sha256:f29eb2be43ee8b54274fcf03e548e3029e96c3babaad27dcdd39a7e13ff82ddb\",\"annotations\":{\"dev.cosignproject.cosign/signature\":\"gj5seEtnOF6Ct4aBkHT/axoiG5rvcJ1zcUv06pnwWCELpRpg7Tp8PFfSP5wjCfO24B1joWpljU16vFKgebYO/yumcNYGy4z7b8tls46QG9dEmMDgwg/bhYk6/r9avVqpdTvcsyEWyR6ewcT9Pk6E3c3BKUytlz14utwFK3rULvZRX+3MrNYH0DL7Kmc3x/FYAzzrz4ewjOAHF1lc77nxgn2u22lWo+h+9a68AquLhuyV+MUP4PD5uNP+ty+NZTa4zdwgVohNk5gEzD/ZugKVonRRMH0ACniQdm/x5A2oMF0Nw0kBBsiOwhIElLlQGpfW6joarqEZB2wSAhJbhe+rsQ==\",\"org.open-build-service.cosign.cookie\":\"a5e6be82775da3e0f4ea85e70fd6024a7d03ecee62536e0ecb179a40ae750b31\"}}]}", + "Payloads": { + "sha256:f29eb2be43ee8b54274fcf03e548e3029e96c3babaad27dcdd39a7e13ff82ddb": "{\"critical\":{\"identity\":{\"docker-reference\":\"dp.apps.rancher.io/containers/openjdk\"},\"image\":{\"docker-manifest-digest\":\"sha256:30e637c70f75c9f22ee0f2b4d0c3471ad3ed2f153f994ec5fe1031ab27d4282c\"},\"type\":\"cosign container image signature\"},\"optional\":{\"creator\":\"OBS\"}}" + } + } +} \ No newline at end of file diff --git a/vendor/github.com/sigstore/rekor/pkg/client/options.go b/vendor/github.com/sigstore/rekor/pkg/client/options.go new file mode 100644 index 00000000..f42b6598 --- /dev/null +++ b/vendor/github.com/sigstore/rekor/pkg/client/options.go @@ -0,0 +1,104 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "net/http" + + "github.com/hashicorp/go-retryablehttp" +) + +// Option is a functional option for customizing static signatures. +type Option func(*options) + +type options struct { + UserAgent string + RetryCount uint + InsecureTLS bool + Logger interface{} +} + +const ( + // DefaultRetryCount is the default number of retries. + DefaultRetryCount = 3 +) + +func makeOptions(opts ...Option) *options { + o := &options{ + UserAgent: "", + RetryCount: DefaultRetryCount, + } + + for _, opt := range opts { + opt(o) + } + + return o +} + +// WithUserAgent sets the media type of the signature. +func WithUserAgent(userAgent string) Option { + return func(o *options) { + o.UserAgent = userAgent + } +} + +// WithRetryCount sets the number of retries. +func WithRetryCount(retryCount uint) Option { + return func(o *options) { + o.RetryCount = retryCount + } +} + +// WithLogger sets the logger; it must implement either retryablehttp.Logger or retryablehttp.LeveledLogger; if not, this will not take effect. +func WithLogger(logger interface{}) Option { + return func(o *options) { + switch logger.(type) { + case retryablehttp.Logger, retryablehttp.LeveledLogger: + o.Logger = logger + } + } +} + +func WithInsecureTLS(enabled bool) Option { + return func(o *options) { + o.InsecureTLS = enabled + } +} + +type roundTripper struct { + http.RoundTripper + UserAgent string +} + +// RoundTrip implements `http.RoundTripper` +func (rt *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set("User-Agent", rt.UserAgent) + return rt.RoundTripper.RoundTrip(req) +} + +func createRoundTripper(inner http.RoundTripper, o *options) http.RoundTripper { + if inner == nil { + inner = http.DefaultTransport + } + if o.UserAgent == "" { + // There's nothing to do... + return inner + } + return &roundTripper{ + RoundTripper: inner, + UserAgent: o.UserAgent, + } +} diff --git a/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go b/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go new file mode 100644 index 00000000..601dd9d3 --- /dev/null +++ b/vendor/github.com/sigstore/rekor/pkg/client/rekor_client.go @@ -0,0 +1,66 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "crypto/tls" + "net/http" + "net/url" + + "github.com/go-openapi/runtime" + httptransport "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + "github.com/hashicorp/go-cleanhttp" + retryablehttp "github.com/hashicorp/go-retryablehttp" + "github.com/sigstore/rekor/pkg/generated/client" + "github.com/sigstore/rekor/pkg/util" +) + +func GetRekorClient(rekorServerURL string, opts ...Option) (*client.Rekor, error) { + url, err := url.Parse(rekorServerURL) + if err != nil { + return nil, err + } + o := makeOptions(opts...) + + retryableClient := retryablehttp.NewClient() + defaultTransport := cleanhttp.DefaultTransport() + if o.InsecureTLS { + /* #nosec G402 */ + defaultTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + retryableClient.HTTPClient = &http.Client{ + Transport: defaultTransport, + } + retryableClient.RetryMax = int(o.RetryCount) + retryableClient.Logger = o.Logger + + httpClient := retryableClient.StandardClient() + httpClient.Transport = createRoundTripper(httpClient.Transport, o) + + // sanitize path + if url.Path == "" { + url.Path = client.DefaultBasePath + } + + rt := httptransport.NewWithClient(url.Host, url.Path, []string{url.Scheme}, httpClient) + rt.Consumers["application/json"] = runtime.JSONConsumer() + rt.Consumers["application/x-pem-file"] = runtime.TextConsumer() + rt.Producers["application/json"] = runtime.JSONProducer() + + registry := strfmt.Default + registry.Add("signedCheckpoint", &util.SignedNote{}, util.SignedCheckpointValidator) + return client.New(rt, registry), nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index fafd8bbf..b49db59d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -364,6 +364,7 @@ github.com/sigstore/cosign/v2/pkg/signature github.com/sigstore/cosign/v2/pkg/types # github.com/sigstore/rekor v1.3.6 ## explicit; go 1.21 +github.com/sigstore/rekor/pkg/client github.com/sigstore/rekor/pkg/generated/client github.com/sigstore/rekor/pkg/generated/client/entries github.com/sigstore/rekor/pkg/generated/client/index