diff --git a/go.mod b/go.mod index 31b07f2cf..cd3aa90cf 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 + github.com/theupdateframework/go-tuf/v2 v2.0.2 github.com/zalando/go-keyring v0.2.5 golang.org/x/crypto v0.37.0 golang.org/x/sync v0.13.0 @@ -59,6 +60,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +replace github.com/theupdateframework/go-tuf/v2 => github.com/theupdateframework/go-tuf/v2 e9e0d485966d571ea6870670d1e42553f1b3b2db + require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -165,7 +168,6 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/theupdateframework/go-tuf v0.7.0 // indirect - github.com/theupdateframework/go-tuf/v2 v2.0.2 // indirect github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/transparency-dev/merkle v0.0.2 // indirect diff --git a/pkg/cmd/attestation/verification/sigstore.go b/pkg/cmd/attestation/verification/sigstore.go index 190ea5c0f..34558a4cc 100644 --- a/pkg/cmd/attestation/verification/sigstore.go +++ b/pkg/cmd/attestation/verification/sigstore.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "errors" "fmt" + "net/http" "os" "github.com/cli/cli/v2/pkg/cmd/attestation/api" @@ -33,6 +34,7 @@ type SigstoreConfig struct { TrustedRoot string Logger *io.Handler NoPublicGood bool + HttpClient *http.Client // If tenancy mode is not used, trust domain is empty TrustDomain string // TUFMetadataDir @@ -77,7 +79,7 @@ func NewLiveSigstoreVerifier(config SigstoreConfig) (*LiveSigstoreVerifier, erro } liveVerifier.PublicGood = publicGoodVerifier } - github, err := newGitHubVerifier(config.TrustDomain, config.TUFMetadataDir) + github, err := newGitHubVerifier(config.TrustDomain, config.TUFMetadataDir, config.HttpClient) if err != nil { return nil, err } @@ -314,10 +316,10 @@ func newCustomVerifier(trustedRoot *root.TrustedRoot) (*verify.SignedEntityVerif return gv, nil } -func newGitHubVerifier(trustDomain string, tufMetadataDir o.Option[string]) (*verify.SignedEntityVerifier, error) { +func newGitHubVerifier(trustDomain string, tufMetadataDir o.Option[string], hc *http.Client) (*verify.SignedEntityVerifier, error) { var tr string - opts := GitHubTUFOptions(tufMetadataDir) + opts := GitHubTUFOptions(tufMetadataDir, hc) client, err := tuf.New(opts) if err != nil { return nil, fmt.Errorf("failed to create TUF client: %v", err) diff --git a/pkg/cmd/attestation/verification/tuf.go b/pkg/cmd/attestation/verification/tuf.go index dcfdd0b32..94455d343 100644 --- a/pkg/cmd/attestation/verification/tuf.go +++ b/pkg/cmd/attestation/verification/tuf.go @@ -8,6 +8,7 @@ import ( o "github.com/cli/cli/v2/pkg/option" "github.com/cli/go-gh/v2/pkg/config" "github.com/sigstore/sigstore-go/pkg/tuf" + "github.com/theupdateframework/go-tuf/v2/metadata/fetcher" ) //go:embed embed/tuf-repo.github.com/root.json @@ -15,7 +16,7 @@ var githubRoot []byte const GitHubTUFMirror = "https://tuf-repo.github.com" -func DefaultOptionsWithCacheSetting(tufMetadataDir o.Option[string]) *tuf.Options { +func DefaultOptionsWithCacheSetting(tufMetadataDir o.Option[string], hc *http.Client) *tuf.Options { opts := tuf.DefaultOptions() // The CODESPACES environment variable will be set to true in a Codespaces workspace @@ -32,10 +33,16 @@ func DefaultOptionsWithCacheSetting(tufMetadataDir o.Option[string]) *tuf.Option // Allow TUF cache for 1 day opts.CacheValidity = 1 + // configure fetcher timeout and retry + f := fetcher.DefaultFetcher{} + f.SetHTTPClient(hc) + retryOptions := []backoff.RetryOption{backoff.WithMaxTries(3)} + f.SetRetryOptions(retryOptions...) + return opts } -func GitHubTUFOptions(tufMetadataDir o.Option[string]) *tuf.Options { +func GitHubTUFOptions(tufMetadataDir o.Option[string], hc *http.Client) *tuf.Options { opts := DefaultOptionsWithCacheSetting(tufMetadataDir) opts.Root = githubRoot