Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update TUF client to support options and add LiveTrustedRoot #41

Merged
merged 35 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
444736a
Update TUF client to support options and add LiveTrustedRoot
codysoyland Dec 11, 2023
035c084
Make sure DefaultOptions never fails
kommendorkapten Dec 22, 2023
5f4fafa
avoid empty strings for arguments, use named attributes
kommendorkapten Dec 22, 2023
511a0b9
Ignore emacs backup files
kommendorkapten Dec 22, 2023
e680b4f
Created a bascig config file for the tuf client
kommendorkapten Dec 22, 2023
7be28c0
Style fixes
kommendorkapten Dec 22, 2023
780beb3
Made consistent snapshot configurable
kommendorkapten Dec 22, 2023
b1f195f
Clarified the use of unsafe local mode
kommendorkapten Dec 22, 2023
3e2ab65
Updated to go-tuf/v2@master
kommendorkapten Jan 29, 2024
8297aeb
Resolved merge conflict
kommendorkapten Jan 29, 2024
9c4e1c4
Merge branch 'main' into tuf-client-2
kommendorkapten Jan 29, 2024
11dedbd
Fixed errors from linter
kommendorkapten Jan 29, 2024
dc7e979
Use short variable declaration syntax
codysoyland Jan 29, 2024
8bc63cf
Remove old unused embedded root
codysoyland Jan 29, 2024
c270ed8
Add func to fetch TUF root with given options
codysoyland Jan 29, 2024
a8fd9e0
Add chainable functional options to Options struct
codysoyland Jan 29, 2024
95168ba
Update CodeQL action
codysoyland Jan 29, 2024
4f6cb84
Setup Go version in CodeQL workflwo
codysoyland Jan 29, 2024
c2e715e
Don't specify minor go version
kommendorkapten Jan 30, 2024
e87063c
Added a simple test for an offline cliant
kommendorkapten Jan 30, 2024
96326fa
Add TUF repo creation and basic test to create a client
codysoyland Feb 5, 2024
057aa83
Made the tuf root file configurable via the command line
kommendorkapten Feb 6, 2024
4ac2b31
Merge branch 'main' into tuf-client-2
kommendorkapten Feb 6, 2024
72edefd
Use consts from go-tuf
codysoyland Feb 6, 2024
0def807
Add test to fetch target
codysoyland Feb 6, 2024
f4d0556
Breakout publish
codysoyland Feb 7, 2024
ee12af4
Add target support and refresh test
codysoyland Feb 7, 2024
fe78b34
Add TUF caching tests
codysoyland Feb 7, 2024
651aff1
Remove unreachable code, add more tests
codysoyland Feb 7, 2024
fd475da
Updated go-tuf
kommendorkapten Feb 9, 2024
616ee98
Updated to latest go-tuf
kommendorkapten Feb 9, 2024
51aaf34
Clarified that the updates is replaced, not the actual tuf client
kommendorkapten Feb 9, 2024
10be16d
Updated to new error type (pointer)
kommendorkapten Feb 9, 2024
1d0f156
Use 0 days for default CacheValidity
codysoyland Feb 9, 2024
37bb81f
Clarify CacheValidity option and add NoCache/MaxCache consts
codysoyland Feb 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,19 @@ jobs:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Setup Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version-file: ./go.mod

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@65c74964a9ed8c44ed9f19d4bbc5757a6a8e9ab9 # v2.16.1
uses: github/codeql-action/init@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
with:
languages: ${{ matrix.language }}

- name: Autobuild
uses: github/codeql-action/autobuild@65c74964a9ed8c44ed9f19d4bbc5757a6a8e9ab9 # v2.16.1
uses: github/codeql-action/autobuild@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@65c74964a9ed8c44ed9f19d4bbc5757a6a8e9ab9 # v2.16.1
uses: github/codeql-action/analyze@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.idea
.DS_Store
*~
/sigstore-go
/tufdata
/conformance
14 changes: 10 additions & 4 deletions cmd/conformance/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@ func getTrustedRoot() root.TrustedMaterial {
if !ok {
log.Fatal("unable to get path")
}

tufDir := path.Join(path.Dir(filename), "tufdata")

trustedRootJSON, err = tuf.GetTrustedrootJSON("tuf-repo-cdn.sigstore.dev", tufDir)
opts := tuf.DefaultOptions()
opts.CachePath = path.Join(path.Dir(filename), "tufdata")
client, err := tuf.New(opts)
if err != nil {
log.Fatal(err)
}
trustedRootJSON, err = client.GetTarget("trusted_root.json")
if err != nil {
log.Fatal(err)
}
}

if err != nil {
Expand Down
41 changes: 31 additions & 10 deletions cmd/sigstore-go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var onlineTlog *bool
var trustedPublicKey *string
var trustedrootJSONpath *string
var tufRootURL *string
var tufDirectory *string
var tufTrustedRoot *string

func init() {
artifact = flag.String("artifact", "", "Path to artifact to verify")
Expand All @@ -63,7 +63,7 @@ func init() {
trustedPublicKey = flag.String("publicKey", "", "Path to trusted public key")
trustedrootJSONpath = flag.String("trustedrootJSONpath", "examples/trusted-root-public-good.json", "Path to trustedroot JSON file")
tufRootURL = flag.String("tufRootURL", "", "URL of TUF root containing trusted root JSON file")
tufDirectory = flag.String("tufDirectory", "tufdata", "Directory to store TUF metadata")
tufTrustedRoot = flag.String("tufTrustedRoot", "", "Path to the trusted TUF root.json to bootstrap trust in the remote TUF repository")
flag.Parse()
if flag.NArg() == 0 {
usage()
Expand Down Expand Up @@ -120,20 +120,41 @@ func run() error {
identityPolicies = append(identityPolicies, verify.WithCertificateIdentity(certID))

var trustedMaterial = make(root.TrustedMaterialCollection, 0)
var trustedrootJSON []byte
var trustedRootJSON []byte

if *tufRootURL != "" {
trustedrootJSON, err = tuf.GetTrustedrootJSON(*tufRootURL, *tufDirectory)
opts := tuf.DefaultOptions()
opts.RepositoryBaseURL = *tufRootURL

// Load the tuf root.json if provided, if not use public good
if *tufTrustedRoot != "" {
rb, err := os.ReadFile(*tufTrustedRoot)
if err != nil {
return fmt.Errorf("failed to read %s: %w",
*tufTrustedRoot, err)
}
opts.Root = rb
}

client, err := tuf.New(opts)
if err != nil {
return err
}
trustedRootJSON, err = client.GetTarget("trusted_root.json")
if err != nil {
return err
}
} else if *trustedrootJSONpath != "" {
trustedrootJSON, err = os.ReadFile(*trustedrootJSONpath)
}
if err != nil {
return err
trustedRootJSON, err = os.ReadFile(*trustedrootJSONpath)
if err != nil {
return fmt.Errorf("failed to read %s: %w",
*trustedrootJSONpath, err)
}
}

if len(trustedrootJSON) > 0 {
if len(trustedRootJSON) > 0 {
var trustedRoot *root.TrustedRoot
trustedRoot, err = root.NewTrustedRootFromJSON(trustedrootJSON)
trustedRoot, err = root.NewTrustedRootFromJSON(trustedRootJSON)
if err != nil {
return err
}
Expand Down
11 changes: 7 additions & 4 deletions examples/oci-image-verification/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/sigstore/sigstore-go/examples/oci-image-verification

go 1.21
go 1.21.5
kommendorkapten marked this conversation as resolved.
Show resolved Hide resolved

replace github.com/sigstore/sigstore-go => ../../

require (
github.com/google/go-containerregistry v0.19.0
Expand Down Expand Up @@ -29,11 +31,11 @@ require (
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/runtime v0.26.2 // indirect
github.com/go-openapi/runtime v0.27.1 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-openapi/validate v0.22.3 // indirect
github.com/go-openapi/swag v0.22.9 // indirect
github.com/go-openapi/validate v0.22.4 // indirect
github.com/google/certificate-transparency-go v1.1.7 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand Down Expand Up @@ -71,6 +73,7 @@ require (
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-20240129093820-4e440e28cdf6 // 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
Expand Down
17 changes: 8 additions & 9 deletions examples/oci-image-verification/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,16 @@ github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdX
github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0=
github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8=
github.com/go-openapi/runtime v0.26.2 h1:elWyB9MacRzvIVgAZCBJmqTi7hBzU0hlKD4IvfX0Zl0=
github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw=
github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqvJYto=
github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU=
github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkIaE=
github.com/go-openapi/spec v0.20.13/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw=
github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI=
github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4=
github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8=
github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0=
github.com/go-openapi/validate v0.22.3 h1:KxG9mu5HBRYbecRb37KRCihvGGtND2aXziBAv0NNfyI=
github.com/go-openapi/validate v0.22.3/go.mod h1:kVxh31KbfsxU8ZyoHaDbLBWU5CnMdqBUEtadQ2G4d5M=
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
github.com/go-openapi/validate v0.22.4 h1:5v3jmMyIPKTR8Lv9syBAIRxG6lY0RqeBPB1LKEijzk8=
github.com/go-openapi/validate v0.22.4/go.mod h1:qm6O8ZIcPVdSY5219468Jv7kBdGvkiZLPOmqnqTUZ2A=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
Expand Down Expand Up @@ -279,8 +279,6 @@ github.com/sigstore/rekor v1.3.4 h1:RGIia1iOZU7fOiiP2UY/WFYhhp50S5aUm7YrM8aiA6E=
github.com/sigstore/rekor v1.3.4/go.mod h1:1GubPVO2yO+K0m0wt/3SHFqnilr/hWbsjSOe7Vzxrlg=
github.com/sigstore/sigstore v1.8.1 h1:mAVposMb14oplk2h/bayPmIVdzbq2IhCgy4g6R0ZSjo=
github.com/sigstore/sigstore v1.8.1/go.mod h1:02SL1158BSj15bZyOFz7m+/nJzLZfFd9A8ab3Kz7w/E=
github.com/sigstore/sigstore-go v0.1.0 h1:jHzjZcZnrxtzi8wKTTYlLFNixp2H6H4tKsefHv5/Xro=
github.com/sigstore/sigstore-go v0.1.0/go.mod h1:E9vlpY082JIbdOnQxc+BZTk4DmnDfX/t0Gi2mp+s7GA=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.0 h1:nLaaOX85YjBKQOQHWY2UlDkbx+je8ozTEM+t1ySAb78=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.0/go.mod h1:fLxrKqPP9lIz/B3UBD4ZK6j6984eX2czu/0zxm99fkE=
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.0 h1:Txd7Fjei2NVb/sjBNYybrl+FcZGptO6FXXH4pVNBQMs=
Expand Down Expand Up @@ -321,6 +319,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-20240129093820-4e440e28cdf6 h1:bg4vq6E9GhRioNFR10pWdX8Ntrh9ROpQWmLCDifDT90=
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240129093820-4e440e28cdf6/go.mod h1:BEDk+xfD0uVATjx1FLvIAjtDhWJnNeffL3i863gqbkM=
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=
Expand Down Expand Up @@ -431,7 +431,6 @@ gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4
gopkg.in/go-jose/go-jose.v2 v2.6.1/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
19 changes: 14 additions & 5 deletions examples/oci-image-verification/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,20 +142,29 @@ func run() error {
}

var trustedMaterial = make(root.TrustedMaterialCollection, 0)
var trustedrootJSON []byte
var trustedRootJSON []byte

if *tufRootURL != "" {
trustedrootJSON, err = tuf.GetTrustedrootJSON(*tufRootURL, *tufDirectory)
opts := tuf.DefaultOptions()
opts.RepositoryBaseURL = *tufRootURL
client, err := tuf.New(opts)
if err != nil {
return err
}
trustedRootJSON, err = client.GetTarget("trusted_root.json")
if err != nil {
return err
}
} else if *trustedrootJSONpath != "" {
trustedrootJSON, err = os.ReadFile(*trustedrootJSONpath)
trustedRootJSON, err = os.ReadFile(*trustedrootJSONpath)
}
if err != nil {
return err
}

if len(trustedrootJSON) > 0 {
if len(trustedRootJSON) > 0 {
var trustedRoot *root.TrustedRoot
trustedRoot, err = root.NewTrustedRootFromJSON(trustedrootJSON)
trustedRoot, err = root.NewTrustedRootFromJSON(trustedRootJSON)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ require (
github.com/sigstore/sigstore v1.8.1
github.com/sigstore/timestamp-authority v1.2.1
github.com/stretchr/testify v1.8.4
github.com/theupdateframework/go-tuf v0.7.0
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240130081036-9d5773172084
golang.org/x/crypto v0.18.0
golang.org/x/mod v0.14.0
google.golang.org/protobuf v1.32.0
)
Expand Down Expand Up @@ -66,6 +67,7 @@ require (
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/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/transparency-dev/merkle v0.0.2 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
Expand All @@ -74,7 +76,6 @@ require (
go.opentelemetry.io/otel/trace v1.22.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sync v0.6.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.1 h1:9Ki0qudKpc1F
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.1/go.mod h1:nhIgyu4YwwNgalIwTGsoAzam16jjAn3ADRSWKbWPwGI=
github.com/sigstore/timestamp-authority v1.2.1 h1:j9RmqSAdvKgSofeltPO4x7d+1M3AXaROBzUJ+AA7L5Q=
github.com/sigstore/timestamp-authority v1.2.1/go.mod h1:Ce+vWWEf0QaKLY2u6mpwEJbmYXEVeOfUk4fQ69kE6ck=
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=
Expand All @@ -297,6 +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-20240130081036-9d5773172084 h1:hIsOD11D9EubZYAMsR59dQ21vlckBFBSFny/q04KWxE=
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240130081036-9d5773172084/go.mod h1:pDMnUv9xAuOPbmq9SQXav7WA1bGd0F8MxbMlGrDU+A8=
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=
Expand Down
102 changes: 102 additions & 0 deletions pkg/root/trusted_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import (
"crypto/x509"
"encoding/hex"
"fmt"
"log"
"os"
"sync"
"time"

protocommon "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1"
prototrustroot "github.com/sigstore/protobuf-specs/gen/pb-go/trustroot/v1"
"github.com/sigstore/sigstore-go/pkg/tuf"
"google.golang.org/protobuf/encoding/protojson"
)

Expand Down Expand Up @@ -256,3 +259,102 @@ func NewTrustedRootProtobuf(rootJSON []byte) (*prototrustroot.TrustedRoot, error
}
return pbTrustedRoot, nil
}

// FetchTrustedRoot fetches the Sigstore trusted root from TUF and returns it.
func FetchTrustedRoot() (*TrustedRoot, error) {
haydentherapper marked this conversation as resolved.
Show resolved Hide resolved
return FetchTrustedRootWithOptions(tuf.DefaultOptions())
}

// FetchTrustedRootWithOptions fetches the trusted root from TUF with the given options and returns it.
func FetchTrustedRootWithOptions(opts *tuf.Options) (*TrustedRoot, error) {
client, err := tuf.New(opts)
if err != nil {
return nil, err
}
return GetTrustedRoot(client)
}

// GetTrustedRoot returns the trusted root
func GetTrustedRoot(c *tuf.Client) (*TrustedRoot, error) {
jsonBytes, err := c.GetTarget("trusted_root.json")
if err != nil {
return nil, err
}
return NewTrustedRootFromJSON(jsonBytes)
}

// LiveTrustedRoot is a wrapper around TrustedRoot that periodically
// refreshes the trusted root from TUF. This is needed for long-running
// processes to ensure that the trusted root does not expire.
type LiveTrustedRoot struct {
*TrustedRoot
mu sync.RWMutex
}

// NewLiveTrustedRoot returns a LiveTrustedRoot that will periodically
// refresh the trusted root from TUF.
func NewLiveTrustedRoot(opts *tuf.Options) (*LiveTrustedRoot, error) {
haydentherapper marked this conversation as resolved.
Show resolved Hide resolved
client, err := tuf.New(opts)
if err != nil {
return nil, err
}
tr, err := GetTrustedRoot(client)
if err != nil {
return nil, err
}
ltr := &LiveTrustedRoot{
TrustedRoot: tr,
mu: sync.RWMutex{},
}
ticker := time.NewTicker(time.Hour * 24)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be configurable if metadata expires more frequently than 24 hours.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me, however since tuf.Options.CacheValidity is using days as the unit, I wonder if we should also change that? If that config value is >= 1, then this ticker will have no effect if configured <= 24 hours, as it will just pull the cached data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To confirm, cache validity ignores whether the metadata is still valid?

Maybe it should be max(24 hours, CacheValidity)? If cache validity is set, just refresh once the cache expires, otherwise refresh every 24 hours?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more on this, I think it's simpler to leave this as-is and let the client initialization handle the check for cache validity. Worst case, it just means an unnecessary reinitialization of the TUF client from disk.

go func() {
for {
select {
case <-ticker.C:
client, err = tuf.New(opts)
if err != nil {
log.Printf("error creating TUF client: %v", err)
}
newTr, err := GetTrustedRoot(client)
if err != nil {
log.Printf("error fetching trusted root: %v", err)
continue
}
ltr.mu.Lock()
ltr.TrustedRoot = newTr
ltr.mu.Unlock()
}
}
}()
return ltr, nil
}

func (l *LiveTrustedRoot) TSACertificateAuthorities() []CertificateAuthority {
l.mu.RLock()
defer l.mu.RUnlock()
return l.TrustedRoot.TSACertificateAuthorities()
}

func (l *LiveTrustedRoot) FulcioCertificateAuthorities() []CertificateAuthority {
l.mu.RLock()
defer l.mu.RUnlock()
return l.TrustedRoot.FulcioCertificateAuthorities()
}

func (l *LiveTrustedRoot) TlogAuthorities() map[string]*TlogAuthority {
l.mu.RLock()
defer l.mu.RUnlock()
return l.TrustedRoot.TlogAuthorities()
}

func (l *LiveTrustedRoot) CTlogAuthorities() map[string]*TlogAuthority {
l.mu.RLock()
defer l.mu.RUnlock()
return l.TrustedRoot.CTlogAuthorities()
}

func (l *LiveTrustedRoot) PublicKeyVerifier(keyID string) (TimeConstrainedVerifier, error) {
l.mu.RLock()
defer l.mu.RUnlock()
return l.TrustedRoot.PublicKeyVerifier(keyID)
}
Loading
Loading