From 87bfa5b1c9fcf161c773559f3b470a36ddea4552 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Tue, 2 Jul 2024 08:26:42 -0400 Subject: [PATCH] Add user agent to online Rekor requests and TUF requests. (#216) For #143 --------- Signed-off-by: Zach Steindler --- Makefile | 11 +++----- cmd/conformance/main.go | 16 ++++++----- cmd/sigstore-go/main.go | 8 +++++- examples/oci-image-verification/go.mod | 4 +-- examples/oci-image-verification/go.sum | 10 +++---- examples/sigstore-go-signing/main.go | 10 ++++--- go.mod | 4 +-- go.sum | 12 ++++----- pkg/sign/certificate.go | 6 ++--- pkg/sign/timestamping.go | 16 +++-------- pkg/sign/transparency.go | 10 +++---- pkg/tuf/client.go | 7 +++++ pkg/util/util.go | 37 ++++++++++++++++++++++++++ pkg/verify/tlog.go | 3 ++- 14 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 pkg/util/util.go diff --git a/Makefile b/Makefile index f1a5da23..043033be 100644 --- a/Makefile +++ b/Makefile @@ -12,21 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION := `git describe --tags` -LDFLAGS = -ldflags "-X main.Version=$(VERSION)" - .PHONY: all all: build build-examples .PHONY: build build: - go build $(LDFLAGS) ./cmd/sigstore-go - go build $(LDFLAGS) -o conformance ./cmd/conformance + go build ./cmd/sigstore-go + go build -o conformance ./cmd/conformance .PHONY: build-examples build-examples: - go build -C ./examples/oci-image-verification $(LDFLAGS) -o oci-image-verification . - go build -C ./examples/sigstore-go-signing $(LDFLAGS) -o sigstore-go-signing . + go build -C ./examples/oci-image-verification -o oci-image-verification . + go build -C ./examples/sigstore-go-signing -o sigstore-go-signing . .PHONY: test test: diff --git a/cmd/conformance/main.go b/cmd/conformance/main.go index 5ce05275..4a7031ca 100644 --- a/cmd/conformance/main.go +++ b/cmd/conformance/main.go @@ -25,16 +25,17 @@ import ( protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1" protocommon "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1" + "github.com/theupdateframework/go-tuf/v2/metadata/fetcher" "google.golang.org/protobuf/encoding/protojson" "github.com/sigstore/sigstore-go/pkg/bundle" "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore-go/pkg/sign" "github.com/sigstore/sigstore-go/pkg/tuf" + "github.com/sigstore/sigstore-go/pkg/util" "github.com/sigstore/sigstore-go/pkg/verify" ) -var Version string var bundlePath *string var certPath *string var certOIDC *string @@ -60,6 +61,9 @@ func getTrustedRoot(staging bool) root.TrustedMaterial { trustedRootJSON, err = os.ReadFile(*trustedRootPath) } else { opts := tuf.DefaultOptions() + fetcher := fetcher.DefaultFetcher{} + fetcher.SetHTTPUserAgent(util.ConstructUserAgent()) + opts.Fetcher = &fetcher if staging { opts.Root = tuf.StagingRoot() @@ -132,9 +136,8 @@ func signBundle(withRekor bool) (*protobundle.Bundle, error) { } fulcioOpts := &sign.FulcioOptions{ - BaseURL: fmt.Sprintf("https://fulcio.%s.dev", instance), - Timeout: timeout, - LibraryVersion: Version, + BaseURL: fmt.Sprintf("https://fulcio.%s.dev", instance), + Timeout: timeout, } signingOptions.CertificateProvider = sign.NewFulcio(fulcioOpts) signingOptions.CertificateProviderOptions = &sign.CertificateProviderOptions{ @@ -143,9 +146,8 @@ func signBundle(withRekor bool) (*protobundle.Bundle, error) { if withRekor { rekorOpts := &sign.RekorOptions{ - BaseURL: fmt.Sprintf("https://rekor.%s.dev", instance), - Timeout: timeout, - LibraryVersion: Version, + BaseURL: fmt.Sprintf("https://rekor.%s.dev", instance), + Timeout: timeout, } signingOptions.TransparencyLogs = append(signingOptions.TransparencyLogs, sign.NewRekor(rekorOpts)) } diff --git a/cmd/sigstore-go/main.go b/cmd/sigstore-go/main.go index bb03d9a7..21abc587 100644 --- a/cmd/sigstore-go/main.go +++ b/cmd/sigstore-go/main.go @@ -27,11 +27,14 @@ import ( "os" "time" + "github.com/sigstore/sigstore/pkg/signature" + "github.com/theupdateframework/go-tuf/v2/metadata/fetcher" + "github.com/sigstore/sigstore-go/pkg/bundle" "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore-go/pkg/tuf" + "github.com/sigstore/sigstore-go/pkg/util" "github.com/sigstore/sigstore-go/pkg/verify" - "github.com/sigstore/sigstore/pkg/signature" ) var artifact *string @@ -129,6 +132,9 @@ func run() error { if *tufRootURL != "" { opts := tuf.DefaultOptions() opts.RepositoryBaseURL = *tufRootURL + fetcher := fetcher.DefaultFetcher{} + fetcher.SetHTTPUserAgent(util.ConstructUserAgent()) + opts.Fetcher = &fetcher // Load the tuf root.json if provided, if not use public good if *tufTrustedRoot != "" { diff --git a/examples/oci-image-verification/go.mod b/examples/oci-image-verification/go.mod index efec2d63..8d1ab739 100644 --- a/examples/oci-image-verification/go.mod +++ b/examples/oci-image-verification/go.mod @@ -68,12 +68,12 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.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.0-20240223092044-1e7978e83f63 // indirect + github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/transparency-dev/merkle v0.0.2 // indirect github.com/vbatts/tar-split v0.11.3 // indirect diff --git a/examples/oci-image-verification/go.sum b/examples/oci-image-verification/go.sum index 90eac161..b43f8bd8 100644 --- a/examples/oci-image-verification/go.sum +++ b/examples/oci-image-verification/go.sum @@ -71,7 +71,7 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AX github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= @@ -295,8 +295,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -317,8 +317,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= -github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 h1:27XWhDZHPD+cufF6qSdYx6PgGQvD2jJ6pq9sDvR6VBk= -github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63/go.mod h1:+gWwqe1pk4nvGeOKosGJqPgD+N/kbD9M0QVLL9TGIYU= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9 h1:AH/4455EGJqYHx6KcrWJ9Bv/h9xae+SP5EGgmmbQBSA= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= diff --git a/examples/sigstore-go-signing/main.go b/examples/sigstore-go-signing/main.go index fe7034d3..6548aa65 100644 --- a/examples/sigstore-go-signing/main.go +++ b/examples/sigstore-go-signing/main.go @@ -21,14 +21,15 @@ import ( "os" "time" + "github.com/theupdateframework/go-tuf/v2/metadata/fetcher" "google.golang.org/protobuf/encoding/protojson" "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore-go/pkg/sign" "github.com/sigstore/sigstore-go/pkg/tuf" + "github.com/sigstore/sigstore-go/pkg/util" ) -var Version string var idToken *string var intoto *bool var tsa *bool @@ -83,9 +84,13 @@ func main() { opts := sign.BundleOptions{} // Get trusted_root.json + fetcher := fetcher.DefaultFetcher{} + fetcher.SetHTTPUserAgent(util.ConstructUserAgent()) + tufOptions := &tuf.Options{ Root: tuf.StagingRoot(), RepositoryBaseURL: tuf.StagingMirror, + Fetcher: &fetcher, } tufClient, err := tuf.New(tufOptions) if err != nil { @@ -109,7 +114,6 @@ func main() { BaseURL: "https://fulcio.sigstage.dev", Timeout: time.Duration(30 * time.Second), Retries: 1, - LibraryVersion: Version, } opts.CertificateProvider = sign.NewFulcio(fulcioOpts) opts.CertificateProviderOptions = &sign.CertificateProviderOptions{ @@ -122,7 +126,6 @@ func main() { URL: "https://timestamp.githubapp.com/api/v1/timestamp", Timeout: time.Duration(30 * time.Second), Retries: 1, - LibraryVersion: Version, } opts.TimestampAuthorities = append(opts.TimestampAuthorities, sign.NewTimestampAuthority(tsaOpts)) @@ -135,7 +138,6 @@ func main() { BaseURL: "https://rekor.sigstage.dev", Timeout: time.Duration(90 * time.Second), Retries: 1, - LibraryVersion: Version, } opts.TransparencyLogs = append(opts.TransparencyLogs, sign.NewRekor(rekorOpts)) } diff --git a/go.mod b/go.mod index d910f2b7..39d0703f 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/sigstore/sigstore v1.8.4 github.com/sigstore/timestamp-authority v1.2.2 github.com/stretchr/testify v1.9.0 - github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 + github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9 golang.org/x/crypto v0.24.0 golang.org/x/mod v0.18.0 google.golang.org/protobuf v1.34.2 @@ -67,7 +67,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect diff --git a/go.sum b/go.sum index a9b61eba..55fc1f06 100644 --- a/go.sum +++ b/go.sum @@ -69,7 +69,7 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= @@ -273,16 +273,14 @@ github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 h1:h9G8j+Ds21zq github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3/go.mod h1:zgCeHOuqF6k7A7TTEvftcA9V3FRzB7mrPtHOhXAQBnc= github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE= github.com/sigstore/timestamp-authority v1.2.2/go.mod h1:nEah4Eq4wpliDjlY342rXclGSO7Kb9hoRrl9tqLW13A= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -301,8 +299,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= -github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 h1:27XWhDZHPD+cufF6qSdYx6PgGQvD2jJ6pq9sDvR6VBk= -github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63/go.mod h1:+gWwqe1pk4nvGeOKosGJqPgD+N/kbD9M0QVLL9TGIYU= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9 h1:AH/4455EGJqYHx6KcrWJ9Bv/h9xae+SP5EGgmmbQBSA= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240701122707-5abb6219c8d9/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= diff --git a/pkg/sign/certificate.go b/pkg/sign/certificate.go index 269be029..75ba7a6e 100644 --- a/pkg/sign/certificate.go +++ b/pkg/sign/certificate.go @@ -27,6 +27,8 @@ import ( "net/http" "strings" "time" + + "github.com/sigstore/sigstore-go/pkg/util" ) type CertificateProviderOptions struct { @@ -50,8 +52,6 @@ type FulcioOptions struct { Timeout time.Duration // Optional number of times to retry on HTTP 5XX Retries uint - // Optional version string for user agent - LibraryVersion string // Optional Transport (for dependency injection) Transport http.RoundTripper } @@ -169,7 +169,7 @@ func (f *Fulcio) GetCertificate(ctx context.Context, keypair Keypair, opts *Cert } request.Header.Add("Authorization", "Bearer "+opts.IDToken) request.Header.Add("Content-Type", "application/json") - request.Header.Add("User-Agent", constructUserAgent(f.options.LibraryVersion)) + request.Header.Add("User-Agent", util.ConstructUserAgent()) response, err = f.client.Do(request) if err != nil { diff --git a/pkg/sign/timestamping.go b/pkg/sign/timestamping.go index ce85b34d..55f25fa4 100644 --- a/pkg/sign/timestamping.go +++ b/pkg/sign/timestamping.go @@ -26,6 +26,8 @@ import ( "time" "github.com/digitorus/timestamp" + + "github.com/sigstore/sigstore-go/pkg/util" ) type TimestampAuthorityOptions struct { @@ -35,8 +37,6 @@ type TimestampAuthorityOptions struct { Timeout time.Duration // Optional number of times to retry on HTTP 5XX Retries uint - // Optional version string for user agent - LibraryVersion string // Optional Transport (for dependency injection) Transport http.RoundTripper } @@ -83,7 +83,7 @@ func (ta *TimestampAuthority) GetTimestamp(ctx context.Context, signature []byte return nil, err } request.Header.Add("Content-Type", "application/timestamp-query") - request.Header.Add("User-Agent", constructUserAgent(ta.options.LibraryVersion)) + request.Header.Add("User-Agent", util.ConstructUserAgent()) response, err = ta.client.Do(request) if err != nil { @@ -122,13 +122,3 @@ func (ta *TimestampAuthority) GetTimestamp(ctx context.Context, signature []byte return body, nil } - -func constructUserAgent(version string) string { - userAgent := "sigstore-go" - if version != "" { - userAgent += "/" - userAgent += version - } - - return userAgent -} diff --git a/pkg/sign/transparency.go b/pkg/sign/transparency.go index dcc45560..f8cc1ec5 100644 --- a/pkg/sign/transparency.go +++ b/pkg/sign/transparency.go @@ -31,11 +31,13 @@ import ( "github.com/sigstore/rekor/pkg/types" "github.com/sigstore/rekor/pkg/types/dsse" "github.com/sigstore/rekor/pkg/types/hashedrekord" - "github.com/sigstore/rekor/pkg/util" + rekorUtil "github.com/sigstore/rekor/pkg/util" // To initialize rekor types _ "github.com/sigstore/rekor/pkg/types/dsse/v0.0.1" _ "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" + + "github.com/sigstore/sigstore-go/pkg/util" ) type RekorClient interface { @@ -57,8 +59,6 @@ type RekorOptions struct { Timeout time.Duration // Optional number of times to retry Retries uint - // Optional version string for user agent - LibraryVersion string // Optional client (for dependency injection) Client RekorClient } @@ -105,7 +105,7 @@ func (r *Rekor) GetTransparencyLogEntry(pubKeyPEM []byte, b *protobundle.Bundle) artifactProperties.PKIFormat = string(pki.X509) artifactProperties.SignatureBytes = messageSignature.Signature - artifactProperties.ArtifactHash = util.PrefixSHA(hexDigest) + artifactProperties.ArtifactHash = rekorUtil.PrefixSHA(hexDigest) var err error proposedEntry, err = hashedrekordType.CreateProposedEntry(context.TODO(), "", artifactProperties) @@ -126,7 +126,7 @@ func (r *Rekor) GetTransparencyLogEntry(pubKeyPEM []byte, b *protobundle.Bundle) params.SetProposedEntry(proposedEntry) if r.options.Client == nil { - client, err := client.GetRekorClient(r.options.BaseURL, client.WithUserAgent(constructUserAgent(r.options.LibraryVersion)), client.WithRetryCount(r.options.Retries)) + client, err := client.GetRekorClient(r.options.BaseURL, client.WithUserAgent(util.ConstructUserAgent()), client.WithRetryCount(r.options.Retries)) if err != nil { return err } diff --git a/pkg/tuf/client.go b/pkg/tuf/client.go index f655f540..134b2d73 100644 --- a/pkg/tuf/client.go +++ b/pkg/tuf/client.go @@ -21,7 +21,10 @@ import ( "time" "github.com/theupdateframework/go-tuf/v2/metadata/config" + "github.com/theupdateframework/go-tuf/v2/metadata/fetcher" "github.com/theupdateframework/go-tuf/v2/metadata/updater" + + "github.com/sigstore/sigstore-go/pkg/util" ) // Client is a Sigstore TUF client @@ -56,6 +59,10 @@ func New(opts *Options) (*Client, error) { if opts.Fetcher != nil { c.cfg.Fetcher = opts.Fetcher + } else { + fetcher := fetcher.DefaultFetcher{} + fetcher.SetHTTPUserAgent(util.ConstructUserAgent()) + c.cfg.Fetcher = &fetcher } // Upon client creation, we may not perform a full TUF update, diff --git a/pkg/util/util.go b/pkg/util/util.go new file mode 100644 index 00000000..4ab68528 --- /dev/null +++ b/pkg/util/util.go @@ -0,0 +1,37 @@ +// Copyright 2024 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 util + +import ( + "runtime/debug" +) + +func ConstructUserAgent() string { + userAgent := "sigstore-go" + + buildInfo, ok := debug.ReadBuildInfo() + if !ok { + return userAgent + } + + for _, eachDep := range buildInfo.Deps { + if eachDep.Path == "github.com/sigstore/sigstore-go" { + userAgent += "/" + userAgent += eachDep.Version + } + } + + return userAgent +} diff --git a/pkg/verify/tlog.go b/pkg/verify/tlog.go index 6769b3bc..7cc82751 100644 --- a/pkg/verify/tlog.go +++ b/pkg/verify/tlog.go @@ -32,6 +32,7 @@ import ( "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore-go/pkg/tlog" + "github.com/sigstore/sigstore-go/pkg/util" ) // VerifyArtifactTransparencyLog verifies that the given entity has been logged @@ -199,7 +200,7 @@ func getVerifier(publicKey crypto.PublicKey, hashFunc crypto.Hash) (*signature.V } func getRekorClient(baseURL string) (*rekorGeneratedClient.Rekor, error) { - client, err := rekorClient.GetRekorClient(baseURL) + client, err := rekorClient.GetRekorClient(baseURL, rekorClient.WithUserAgent(util.ConstructUserAgent())) if err != nil { return nil, err }