diff --git a/cmd/record.go b/cmd/record.go index cca47270..92aa2f14 100644 --- a/cmd/record.go +++ b/cmd/record.go @@ -126,6 +126,13 @@ operating systems. It is done by replacing all line separators with a new line character.`, ) + recordCmd.PersistentFlags().BoolVar( + &useDSSE, + "use-dsse", + false, + "Create metadata using DSSE instead of the legacy signature wrapper.", + ) + recordCmd.PersistentFlags().BoolVar( &followSymlinkDirs, "follow-symlink-dirs", @@ -165,7 +172,7 @@ command is executed. Symlinks are followed.`, } func recordStart(cmd *cobra.Command, args []string) error { - block, err := intoto.InTotoRecordStart(recordStepName, recordMaterialsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs) + block, err := intoto.InTotoRecordStart(recordStepName, recordMaterialsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE) if err != nil { return fmt.Errorf("failed to create start link file: %w", err) } @@ -181,14 +188,14 @@ func recordStart(cmd *cobra.Command, args []string) error { } func recordStop(cmd *cobra.Command, args []string) error { - var prelimLinkMb intoto.Metablock prelimLinkName := fmt.Sprintf(intoto.PreliminaryLinkNameFormat, recordStepName, key.KeyID) prelimLinkPath := filepath.Join(outDir, prelimLinkName) - if err := prelimLinkMb.Load(prelimLinkPath); err != nil { + prelimLinkMb, err := intoto.LoadMetadata(prelimLinkPath) + if err != nil { return fmt.Errorf("failed to load start link file at %s: %w", prelimLinkName, err) } - linkMb, err := intoto.InTotoRecordStop(prelimLinkMb, recordProductsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs) + linkMb, err := intoto.InTotoRecordStop(prelimLinkMb, recordProductsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE) if err != nil { return fmt.Errorf("failed to create stop link file: %w", err) } diff --git a/cmd/root.go b/cmd/root.go index c9842b88..299c6a43 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,6 +24,7 @@ var ( outDir string lineNormalization bool followSymlinkDirs bool + useDSSE bool ) var rootCmd = &cobra.Command{ diff --git a/cmd/run.go b/cmd/run.go index 38aad731..f0ac9eeb 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -149,6 +149,13 @@ toggles following linked directories only, linked files are always recorded independently of this parameter.`, ) + runCmd.PersistentFlags().BoolVar( + &useDSSE, + "use-dsse", + false, + "Create metadata using DSSE instead of the legacy signature wrapper.", + ) + runCmd.Flags().StringVar( &spiffeUDS, "spiffe-workload-api-path", @@ -167,15 +174,15 @@ func run(cmd *cobra.Command, args []string) error { return fmt.Errorf("no command arguments passed, please specify or use --no-command option") } - block, err := intoto.InTotoRun(stepName, runDir, materialsPaths, productsPaths, args, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs) + metadata, err := intoto.InTotoRun(stepName, runDir, materialsPaths, productsPaths, args, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE) if err != nil { return fmt.Errorf("failed to create link metadata: %w", err) } - linkName := fmt.Sprintf(intoto.LinkNameFormat, block.Signed.(intoto.Link).Name, key.KeyID) + linkName := fmt.Sprintf(intoto.LinkNameFormat, metadata.GetPayload().(intoto.Link).Name, key.KeyID) linkPath := filepath.Join(outDir, linkName) - err = block.Dump(linkPath) + err = metadata.Dump(linkPath) if err != nil { return fmt.Errorf("failed to write link metadata to %s: %w", linkPath, err) } diff --git a/cmd/sign.go b/cmd/sign.go index 2e5e4ca2..a3eed01b 100644 --- a/cmd/sign.go +++ b/cmd/sign.go @@ -60,9 +60,8 @@ root layout's signature(s). Passing exactly one key using } func sign(cmd *cobra.Command, args []string) error { - var layoutMb intoto.Metablock - - if err := layoutMb.Load(layoutPath); err != nil { + layoutEnv, err := intoto.LoadMetadata(layoutPath) + if err != nil { return fmt.Errorf("failed to load layout at %s: %w", layoutPath, err) } @@ -72,7 +71,7 @@ func sign(cmd *cobra.Command, args []string) error { } if verifyFile { - if err := layoutMb.VerifySignature(key); err != nil { + if err := layoutEnv.VerifySignature(key); err != nil { return fmt.Errorf("signature verification failed: %w", err) } return nil @@ -81,8 +80,9 @@ func sign(cmd *cobra.Command, args []string) error { if len(outputPath) == 0 { outputPath = layoutPath } - layoutMb.Sign(key) - layoutMb.Dump(outputPath) - return nil + if err := layoutEnv.Sign(key); err != nil { + return err + } + return layoutEnv.Dump(outputPath) } diff --git a/cmd/verify.go b/cmd/verify.go index e98b8744..cb18f7df 100644 --- a/cmd/verify.go +++ b/cmd/verify.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "io/ioutil" "os" intoto "github.com/in-toto/in-toto-golang/in_toto" @@ -82,9 +81,8 @@ with a new line character.`, } func verify(cmd *cobra.Command, args []string) error { - var layoutMb intoto.Metablock - - if err := layoutMb.Load(layoutPath); err != nil { + layoutMb, err := intoto.LoadMetadata(layoutPath) + if err != nil { return fmt.Errorf("failed to load layout at %s: %w", layoutPath, err) } @@ -102,25 +100,15 @@ func verify(cmd *cobra.Command, args []string) error { intermediatePems := make([][]byte, 0, len(intermediatePaths)) for _, intermediate := range intermediatePaths { - f, err := os.Open(intermediate) - if err != nil { - return fmt.Errorf("failed to open intermediate %s: %w", intermediate, err) - } - defer f.Close() - - pemBytes, err := ioutil.ReadAll(f) + pemBytes, err := os.ReadFile(intermediate) if err != nil { return fmt.Errorf("failed to read intermediate %s: %w", intermediate, err) } intermediatePems = append(intermediatePems, pemBytes) - - if err := f.Close(); err != nil { - return fmt.Errorf("could not close intermediate cert: %w", err) - } } - _, err := intoto.InTotoVerify(layoutMb, layoutKeys, linkDir, "", make(map[string]string), intermediatePems, lineNormalization) + _, err = intoto.InTotoVerify(layoutMb, layoutKeys, linkDir, "", make(map[string]string), intermediatePems, lineNormalization) if err != nil { return fmt.Errorf("inspection failed: %w", err) } diff --git a/doc/in-toto_record.md b/doc/in-toto_record.md index a7c5c007..6e4f7be6 100644 --- a/doc/in-toto_record.md +++ b/doc/in-toto_record.md @@ -40,6 +40,7 @@ failure and zero otherwise. operating systems. It is done by replacing all line separators with a new line character. --spiffe-workload-api-path string UDS path for SPIFFE workload API + --use-dsse Create metadata using DSSE instead of the legacy signature wrapper. ``` ### SEE ALSO diff --git a/doc/in-toto_record_start.md b/doc/in-toto_record_start.md index 8e0a82ef..da162041 100644 --- a/doc/in-toto_record_start.md +++ b/doc/in-toto_record_start.md @@ -51,6 +51,7 @@ in-toto record start [flags] operating systems. It is done by replacing all line separators with a new line character. --spiffe-workload-api-path string UDS path for SPIFFE workload API + --use-dsse Create metadata using DSSE instead of the legacy signature wrapper. ``` ### SEE ALSO diff --git a/doc/in-toto_record_stop.md b/doc/in-toto_record_stop.md index 1e0fe86e..257bfce5 100644 --- a/doc/in-toto_record_stop.md +++ b/doc/in-toto_record_stop.md @@ -52,6 +52,7 @@ in-toto record stop [flags] operating systems. It is done by replacing all line separators with a new line character. --spiffe-workload-api-path string UDS path for SPIFFE workload API + --use-dsse Create metadata using DSSE instead of the legacy signature wrapper. ``` ### SEE ALSO diff --git a/doc/in-toto_run.md b/doc/in-toto_run.md index e08f635c..f1018424 100644 --- a/doc/in-toto_run.md +++ b/doc/in-toto_run.md @@ -52,6 +52,7 @@ in-toto run [flags] calling process's current directory. The runDir directory must exist, be writable, and not be a symlink. --spiffe-workload-api-path string UDS path for SPIFFE workload API + --use-dsse Create metadata using DSSE instead of the legacy signature wrapper. ``` ### SEE ALSO diff --git a/go.mod b/go.mod index ce95fa26..20eb11a1 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/in-toto/in-toto-golang -go 1.17 +go 1.20 require ( github.com/google/go-cmp v0.5.9 - github.com/secure-systems-lab/go-securesystemslib v0.5.0 + github.com/secure-systems-lab/go-securesystemslib v0.5.1-0.20230502174335-9ebc3aa8b367 github.com/shibumi/go-pathspec v1.3.0 github.com/spf13/cobra v1.7.0 github.com/spiffe/go-spiffe/v2 v2.1.3 @@ -25,10 +25,10 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zeebo/errs v1.3.0 // indirect - golang.org/x/crypto v0.6.0 // indirect + golang.org/x/crypto v0.8.0 // indirect golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.6.0 // indirect google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/go.sum b/go.sum index c5c6df25..75a8c4c5 100644 --- a/go.sum +++ b/go.sum @@ -1,583 +1,34 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= -cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/secure-systems-lab/go-securesystemslib v0.5.0 h1:oTiNu0QnulMQgN/hLK124wJD/r2f9ZhIUuKIeBsCBT8= -github.com/secure-systems-lab/go-securesystemslib v0.5.0/go.mod h1:uoCqUC0Ap7jrBSEanxT+SdACYJTVplRXWLkGMuDjXqk= +github.com/secure-systems-lab/go-securesystemslib v0.5.1-0.20230502174335-9ebc3aa8b367 h1:/4TAXgXWlyaJgV2syWo3Xd2dQfK853+es/q4fhgGqfg= +github.com/secure-systems-lab/go-securesystemslib v0.5.1-0.20230502174335-9ebc3aa8b367/go.mod h1:8Mtpo9JKks/qhPG4HGZ2LGMvrPbzuxwfz/f/zLfEWkk= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -587,605 +38,44 @@ github.com/spiffe/go-spiffe/v2 v2.1.3/go.mod h1:eVDqm9xFvyqao6C+eQensb9ZPkyNEeaU github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 h1:znp6mq/drrY+6khTAlJUDNFFcDGV2ENLYKpMq8SyCds= google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/in_toto/envelope.go b/in_toto/envelope.go new file mode 100644 index 00000000..1616539c --- /dev/null +++ b/in_toto/envelope.go @@ -0,0 +1,197 @@ +package in_toto + +import ( + "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "os" + "reflect" + "strings" + "sync" + + "github.com/secure-systems-lab/go-securesystemslib/cjson" + "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/secure-systems-lab/go-securesystemslib/signerverifier" +) + +// PayloadType is the payload type used for links and layouts. +const PayloadType = "application/vnd.in-toto+json" + +// ErrInvalidPayloadType indicates that the envelope used an unknown payload type +var ErrInvalidPayloadType = errors.New("unknown payload type") + +type Envelope struct { + envelope *dsse.Envelope + payload any + decodePayloadOnce sync.Once +} + +func NewEnvelope() *Envelope { + return &Envelope{envelope: &dsse.Envelope{}} +} + +func (e *Envelope) SetPayload(payload any) error { + encodedBytes, err := cjson.EncodeCanonical(payload) + if err != nil { + return err + } + + e.payload = payload + e.envelope = &dsse.Envelope{ + Payload: base64.StdEncoding.EncodeToString(encodedBytes), + PayloadType: PayloadType, + } + + return nil +} + +func (e *Envelope) GetPayload() any { + e.decodePayloadOnce.Do(func() { + payloadBytes, err := e.envelope.DecodeB64Payload() + if err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + var payload map[string]any + if err := json.Unmarshal(payloadBytes, &payload); err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + if payload["_type"] == "link" { + var link Link + if err := checkRequiredJSONFields(payload, reflect.TypeOf(link)); err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + decoder := json.NewDecoder(strings.NewReader(string(payloadBytes))) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&link); err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + e.payload = link + } else if payload["_type"] == "layout" { + var layout Layout + if err := checkRequiredJSONFields(payload, reflect.TypeOf(layout)); err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + decoder := json.NewDecoder(strings.NewReader(string(payloadBytes))) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&layout); err != nil { + panic(fmt.Errorf("error decoding payload: %w", err)) + } + + e.payload = layout + } + }) + + return e.payload +} + +func (e *Envelope) VerifySignature(key Key) error { + verifier, err := getSignerVerifierFromKey(key) + if err != nil { + return err + } + + ev, err := dsse.NewEnvelopeVerifier(verifier) + if err != nil { + return err + } + + _, err = ev.Verify(context.Background(), e.envelope) + return err +} + +func (e *Envelope) Sign(key Key) error { + signer, err := getSignerVerifierFromKey(key) + if err != nil { + return err + } + + es, err := dsse.NewEnvelopeSigner(signer) + if err != nil { + return err + } + + payload, err := e.envelope.DecodeB64Payload() + if err != nil { + return err + } + + env, err := es.SignPayload(context.Background(), e.envelope.PayloadType, payload) + if err != nil { + return err + } + + e.envelope = env + return nil +} + +func (e *Envelope) Sigs() []Signature { + sigs := []Signature{} + for _, s := range e.envelope.Signatures { + sigs = append(sigs, Signature{ + KeyID: s.KeyID, + Sig: s.Sig, + }) + } + return sigs +} + +func (e *Envelope) GetSignatureForKeyID(keyID string) (Signature, error) { + for _, s := range e.Sigs() { + if s.KeyID == keyID { + return s, nil + } + } + + return Signature{}, fmt.Errorf("no signature found for key '%s'", keyID) +} + +func (e *Envelope) Dump(path string) error { + jsonBytes, err := json.MarshalIndent(e.envelope, "", " ") + if err != nil { + return err + } + + // Write JSON bytes to the passed path with permissions (-rw-r--r--) + err = os.WriteFile(path, jsonBytes, 0644) + if err != nil { + return err + } + + return nil +} + +func getSignerVerifierFromKey(key Key) (dsse.SignerVerifier, error) { + sslibKey := getSSLibKeyFromKey(key) + + switch sslibKey.KeyType { + case signerverifier.RSAKeyType: + return signerverifier.NewRSAPSSSignerVerifierFromSSLibKey(&sslibKey) + case signerverifier.ED25519KeyType: + return signerverifier.NewED25519SignerVerifierFromSSLibKey(&sslibKey) + case signerverifier.ECDSAKeyType: + return signerverifier.NewECDSASignerVerifierFromSSLibKey(&sslibKey) + } + + return nil, ErrUnsupportedKeyType +} + +func getSSLibKeyFromKey(key Key) signerverifier.SSLibKey { + return signerverifier.SSLibKey{ + KeyType: key.KeyType, + KeyIDHashAlgorithms: key.KeyIDHashAlgorithms, + KeyID: key.KeyID, + Scheme: key.Scheme, + KeyVal: signerverifier.KeyVal{ + Public: key.KeyVal.Public, + Private: key.KeyVal.Private, + Certificate: key.KeyVal.Certificate, + }, + } +} diff --git a/in_toto/envelope_test.go b/in_toto/envelope_test.go new file mode 100644 index 00000000..6025a59d --- /dev/null +++ b/in_toto/envelope_test.go @@ -0,0 +1,201 @@ +package in_toto + +import ( + "testing" + + "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/stretchr/testify/assert" +) + +func TestEnvelopeSetPayload(t *testing.T) { + t.Run("set layout payload", func(t *testing.T) { + env := NewEnvelope() + + payload := Layout{ + Type: "layout", + Steps: []Step{}, + Inspect: []Inspection{}, + Keys: map[string]Key{}, + Expires: "2030-01-01T12:00:00Z", + Readme: "readme", + } + + err := env.SetPayload(payload) + assert.Nil(t, err) + }) + + t.Run("set link payload", func(t *testing.T) { + env := NewEnvelope() + + payload := Link{ + Type: "link", + Name: "test", + Materials: map[string]any{}, + Products: map[string]any{}, + ByProducts: map[string]any{}, + Environment: map[string]any{}, + Command: []string{}, + } + err := env.SetPayload(payload) + assert.Nil(t, err) + }) +} + +func TestEnvelopeGetPayload(t *testing.T) { + t.Run("get layout payload", func(t *testing.T) { + env := NewEnvelope() + + payload := Layout{ + Type: "layout", + Steps: []Step{}, + Inspect: []Inspection{}, + Keys: map[string]Key{}, + Expires: "2030-01-01T12:00:00Z", + Readme: "readme", + } + + err := env.SetPayload(payload) + assert.Nil(t, err) + + storedPayload := env.GetPayload() + assert.Equal(t, payload, storedPayload.(Layout)) + }) + + t.Run("get link payload", func(t *testing.T) { + env := NewEnvelope() + + payload := Link{ + Type: "link", + Name: "test", + Materials: map[string]any{}, + Products: map[string]any{}, + ByProducts: map[string]any{}, + Environment: map[string]any{}, + Command: []string{}, + } + err := env.SetPayload(payload) + assert.Nil(t, err) + + storedPayload := env.GetPayload() + assert.Equal(t, payload, storedPayload.(Link)) + }) + + t.Run("get overwritten payload", func(t *testing.T) { + env := NewEnvelope() + + payload := Link{ + Type: "link", + Name: "test", + Materials: map[string]any{}, + Products: map[string]any{}, + ByProducts: map[string]any{}, + Environment: map[string]any{}, + Command: []string{}, + } + err := env.SetPayload(payload) + assert.Nil(t, err) + + storedPayload := env.GetPayload() + assert.Equal(t, payload, storedPayload.(Link)) + + newPayload := Layout{ + Type: "layout", + Steps: []Step{}, + Inspect: []Inspection{}, + Keys: map[string]Key{}, + Expires: "2030-01-01T12:00:00Z", + Readme: "readme", + } + + err = env.SetPayload(newPayload) + assert.Nil(t, err) + + storedPayload = env.GetPayload() + assert.Equal(t, newPayload, storedPayload.(Layout)) + }) +} + +func TestEnvelopeDump(t *testing.T) { + env := &Envelope{ + envelope: &dsse.Envelope{ + PayloadType: PayloadType, + Payload: "eyJfdHlwZSI6ICJsYXlvdXQiLCAiZXhwaXJlcyI6ICIyMDMwLTExLTE4VDE2OjA2OjM2WiIsICJpbnNwZWN0IjogW3siX3R5cGUiOiAiaW5zcGVjdGlvbiIsICJleHBlY3RlZF9tYXRlcmlhbHMiOiBbWyJNQVRDSCIsICJmb28udGFyLmd6IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJwYWNrYWdlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnRhci5neiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnB5Il1dLCAibmFtZSI6ICJ1bnRhciIsICJydW4iOiBbInRhciIsICJ4ZnoiLCAiZm9vLnRhci5neiJdfV0sICJrZXlzIjogeyJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIjogeyJrZXlpZCI6ICJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBeUNUaWs5ODk1M2hLbDYrQjZuNWxcbjhEVklEd0RudnJKZnBhc2JKMytSdzY2WWNhd09aaW5ScE14UFRxV0JLczdzUm9wN2pxc1FOY3NsVW9JWkxyWFBcbnIzZm9QSEY0NTVUbHJxUFZmQ1ppRlErTzRDYWZ4V09CNG1MMU5kZHZwRlhURWptVWl3RnJyTDdQY3ZRS01iWXpcbmVVSEg0dEg5TU56cUtXYmJKb2VrQnNEcENESXhwMU5iZ2l2R0JLd2pSR2EyODFzQ2xLZ3BkMFEwZWJsK1JUY1RcbnZwZlpWRGJYYXpRN1ZxWmtpZHQ3Z2VXcTJCaWRPWFpwL2Nqb1h5Vm5lS3gvZ1lpT1V2OHg5NHN2UU16U0VodzJcbkxGTVEwNEExS25HbjFqeE8zNS9mZDYvT1czMm5qeVdzOTZSS3U5VVFWYWNZSHNRZnNBQ1BXd21WcWduWC9zcDVcbnVqbHZTRGp5Zlp1N2M1eVVRMmFzWWZRUEx2bmpHK3U3UWNCdWtHZjhoQWZWZ3NlenpYOVFQaUszNUJLRGdCVS9cblZrNDNyaUpzMTY1VEpHWUdWdUxVaElFaEhnaVF0d284cFVUSlM1bnBFZTVYTUR1Wm9pZ2hOZHpvV1kybmZzQmZcbnA4MzQ4azZ2SnRETUIwOTMvdDZWOXNUR1lRY1NiZ0tQeUVRbzVQazZXZDRaQWdNQkFBRT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSJ9LCAic2NoZW1lIjogInJzYXNzYS1wc3Mtc2hhMjU2In0sICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIjogeyJrZXlpZCI6ICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeGN6OUF1Y05ia0piUXB3VEhsRUhcblJCK2grTWtZS1FqdzA2SWdaOFRYbFhHcXA1cGR3VEhJNW41aUZvbDAvcmtzbWlaeGF0SHdodGg3cnlZTkMzVmtcbjlnL0xBczlFNjB5V3l0aVNnVjkzRUt2NjVibWhZcWlTQWtKZHlhUEt2Q2I3Y0c5NzlCNGUrSFZwZFZ4NnM3RXhcbklvYURSWWNYM1ZJdDZWMjUvU1F6NWlOVWVWbGIrK1F0U2ZRRkVmM2xIYXVvRmhXWm9Dc2UyNG5XdFlabyszVXRcbnVUbXh5Z3A3dFUvOU5tWWIyQlhFZlVDZGdqb0NRMVVzRkxCUVE0aGFJZEpOT3RSRmw4S05ZMDl6Yk1VaWpLSWVcblgwWnZnVDg3N0xVdE15eWRLUEVvMDQvdTNERXI5WmJhL1NrSHc0M2pZRS9vamxYZWlrNXVWakxTcjNzSkxEU1Bcbkh3SURBUUFCXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0ifSwgInNjaGVtZSI6ICJyc2Fzc2EtcHNzLXNoYTI1NiJ9fSwgInJlYWRtZSI6ICIiLCAic3RlcHMiOiBbeyJfdHlwZSI6ICJzdGVwIiwgImV4cGVjdGVkX2NvbW1hbmQiOiBbXSwgImV4cGVjdGVkX21hdGVyaWFscyI6IFtdLCAiZXhwZWN0ZWRfcHJvZHVjdHMiOiBbWyJBTExPVyIsICJmb28ucHkiXV0sICJuYW1lIjogIndyaXRlLWNvZGUiLCAicHVia2V5cyI6IFsiYjdkNjQzZGVjMGEwNTEwOTZlZTVkODcyMjFiNWQ5MWEzM2RhYTY1ODY5OWQzMDkwM2UxY2VmYjkwYzQxODQwMSJdLCAidGhyZXNob2xkIjogMX0sIHsiX3R5cGUiOiAic3RlcCIsICJleHBlY3RlZF9jb21tYW5kIjogWyJ0YXIiLCAiemN2ZiIsICJmb28udGFyLmd6IiwgImZvby5weSJdLCAiZXhwZWN0ZWRfbWF0ZXJpYWxzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiKiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siQUxMT1ciLCAiZm9vLnRhci5neiJdLCBbIkFMTE9XIiwgImZvby5weSJdXSwgIm5hbWUiOiAicGFja2FnZSIsICJwdWJrZXlzIjogWyJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIl0sICJ0aHJlc2hvbGQiOiAxfV19", + Signatures: []dsse.Signature{ + { + KeyID: "70ca5750c2eda80b18f41f4ec5f92146789b5d68dd09577be422a0159bd13680", + Sig: "m5eJXn/whrDdgJ94u8pYI5BVUnQGpjkTQkhqjrB1nD0XFQ6+doHZLCZRzWwxO670vhZMxhLP6kPl5CK4yL42niG0+09tzKlAOsVAMnTsleJNkn6wy5SHsWBTELqlTvDyNs81FdhdEonvbm2zrQs6a0qstMVabBpkwPNVNf0jK463PAFU9jXwFV2dPDdqUCKoy7TcDi6kZOeNmXNANXhV5PGY6wh+FNAuxTWnTHMKGLiSnSyao92y8yKu+fxy4KoZkm923IQyYxSRNZT4DYTnehYDL3tJnDebWRssknZyZIuq9+aTAh7ospe8+Ak4CurdtAHjR7QBugR5iwCUIBKuww==", + }, + }, + }, + } + + existing := "demo.dsse.layout" + tmp := existing + ".tmp" + + if err := env.Dump(tmp); err != nil { + t.Error(err) + } + + savedMetadata, err := LoadMetadata(existing) + if err != nil { + t.Error(err) + } + + assert.Equal(t, env.envelope, savedMetadata.(*Envelope).envelope) + + tmpMetadata, err := LoadMetadata(tmp) + if err != nil { + t.Error(err) + } + + assert.Equal(t, env.envelope, tmpMetadata.(*Envelope).envelope) +} + +func TestEnvelopeVerifySignature(t *testing.T) { + env, err := LoadMetadata("demo.dsse.layout") + if err != nil { + t.Fatal(err) + } + + t.Run("successful signature verification", func(t *testing.T) { + var key Key + if err := key.LoadKey("alice.pub", "rsassa-pss-sha256", []string{"sha256", "sha512"}); err != nil { + t.Fatal(err) + } + + err = env.VerifySignature(key) + assert.Nil(t, err) + }) + + t.Run("fail signature verification", func(t *testing.T) { + var key Key + if err := key.LoadKey("carol.pub", "ed25519", []string{"sha256", "sha512"}); err != nil { + t.Fatal(err) + } + + err = env.VerifySignature(key) + assert.NotNil(t, err) + }) +} + +func TestEnvelopeSign(t *testing.T) { + env := &Envelope{ + envelope: &dsse.Envelope{ + PayloadType: PayloadType, + Payload: "eyJfdHlwZSI6ICJsYXlvdXQiLCAiZXhwaXJlcyI6ICIyMDMwLTExLTE4VDE2OjA2OjM2WiIsICJpbnNwZWN0IjogW3siX3R5cGUiOiAiaW5zcGVjdGlvbiIsICJleHBlY3RlZF9tYXRlcmlhbHMiOiBbWyJNQVRDSCIsICJmb28udGFyLmd6IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJwYWNrYWdlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnRhci5neiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnB5Il1dLCAibmFtZSI6ICJ1bnRhciIsICJydW4iOiBbInRhciIsICJ4ZnoiLCAiZm9vLnRhci5neiJdfV0sICJrZXlzIjogeyJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIjogeyJrZXlpZCI6ICJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBeUNUaWs5ODk1M2hLbDYrQjZuNWxcbjhEVklEd0RudnJKZnBhc2JKMytSdzY2WWNhd09aaW5ScE14UFRxV0JLczdzUm9wN2pxc1FOY3NsVW9JWkxyWFBcbnIzZm9QSEY0NTVUbHJxUFZmQ1ppRlErTzRDYWZ4V09CNG1MMU5kZHZwRlhURWptVWl3RnJyTDdQY3ZRS01iWXpcbmVVSEg0dEg5TU56cUtXYmJKb2VrQnNEcENESXhwMU5iZ2l2R0JLd2pSR2EyODFzQ2xLZ3BkMFEwZWJsK1JUY1RcbnZwZlpWRGJYYXpRN1ZxWmtpZHQ3Z2VXcTJCaWRPWFpwL2Nqb1h5Vm5lS3gvZ1lpT1V2OHg5NHN2UU16U0VodzJcbkxGTVEwNEExS25HbjFqeE8zNS9mZDYvT1czMm5qeVdzOTZSS3U5VVFWYWNZSHNRZnNBQ1BXd21WcWduWC9zcDVcbnVqbHZTRGp5Zlp1N2M1eVVRMmFzWWZRUEx2bmpHK3U3UWNCdWtHZjhoQWZWZ3NlenpYOVFQaUszNUJLRGdCVS9cblZrNDNyaUpzMTY1VEpHWUdWdUxVaElFaEhnaVF0d284cFVUSlM1bnBFZTVYTUR1Wm9pZ2hOZHpvV1kybmZzQmZcbnA4MzQ4azZ2SnRETUIwOTMvdDZWOXNUR1lRY1NiZ0tQeUVRbzVQazZXZDRaQWdNQkFBRT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSJ9LCAic2NoZW1lIjogInJzYXNzYS1wc3Mtc2hhMjU2In0sICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIjogeyJrZXlpZCI6ICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeGN6OUF1Y05ia0piUXB3VEhsRUhcblJCK2grTWtZS1FqdzA2SWdaOFRYbFhHcXA1cGR3VEhJNW41aUZvbDAvcmtzbWlaeGF0SHdodGg3cnlZTkMzVmtcbjlnL0xBczlFNjB5V3l0aVNnVjkzRUt2NjVibWhZcWlTQWtKZHlhUEt2Q2I3Y0c5NzlCNGUrSFZwZFZ4NnM3RXhcbklvYURSWWNYM1ZJdDZWMjUvU1F6NWlOVWVWbGIrK1F0U2ZRRkVmM2xIYXVvRmhXWm9Dc2UyNG5XdFlabyszVXRcbnVUbXh5Z3A3dFUvOU5tWWIyQlhFZlVDZGdqb0NRMVVzRkxCUVE0aGFJZEpOT3RSRmw4S05ZMDl6Yk1VaWpLSWVcblgwWnZnVDg3N0xVdE15eWRLUEVvMDQvdTNERXI5WmJhL1NrSHc0M2pZRS9vamxYZWlrNXVWakxTcjNzSkxEU1Bcbkh3SURBUUFCXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0ifSwgInNjaGVtZSI6ICJyc2Fzc2EtcHNzLXNoYTI1NiJ9fSwgInJlYWRtZSI6ICIiLCAic3RlcHMiOiBbeyJfdHlwZSI6ICJzdGVwIiwgImV4cGVjdGVkX2NvbW1hbmQiOiBbXSwgImV4cGVjdGVkX21hdGVyaWFscyI6IFtdLCAiZXhwZWN0ZWRfcHJvZHVjdHMiOiBbWyJBTExPVyIsICJmb28ucHkiXV0sICJuYW1lIjogIndyaXRlLWNvZGUiLCAicHVia2V5cyI6IFsiYjdkNjQzZGVjMGEwNTEwOTZlZTVkODcyMjFiNWQ5MWEzM2RhYTY1ODY5OWQzMDkwM2UxY2VmYjkwYzQxODQwMSJdLCAidGhyZXNob2xkIjogMX0sIHsiX3R5cGUiOiAic3RlcCIsICJleHBlY3RlZF9jb21tYW5kIjogWyJ0YXIiLCAiemN2ZiIsICJmb28udGFyLmd6IiwgImZvby5weSJdLCAiZXhwZWN0ZWRfbWF0ZXJpYWxzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiKiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siQUxMT1ciLCAiZm9vLnRhci5neiJdLCBbIkFMTE9XIiwgImZvby5weSJdXSwgIm5hbWUiOiAicGFja2FnZSIsICJwdWJrZXlzIjogWyJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIl0sICJ0aHJlc2hvbGQiOiAxfV19", + Signatures: []dsse.Signature{}, + }, + } + + var key Key + if err := key.LoadKey("carol", "ed25519", []string{"sha256", "sha512"}); err != nil { + t.Fatal(err) + } + + if err := env.Sign(key); err != nil { + t.Error(err) + } + + assert.Equal(t, "be6371bc627318218191ce0780fd3183cce6c36da02938a477d2e4dfae1804a6", env.envelope.Signatures[0].KeyID) + assert.Equal(t, "HeacKZDQD+EIYz1dLJ2NpXxcG70tn62BOzcxnAArFSKJcWIL0qcyzvdtpSJQ0pOyq8lBxMk5nIRO0Kr89SZoBA==", env.envelope.Signatures[0].Sig) +} diff --git a/in_toto/examples_test.go b/in_toto/examples_test.go index edc03770..20ce3369 100644 --- a/in_toto/examples_test.go +++ b/in_toto/examples_test.go @@ -33,11 +33,11 @@ func ExampleInTotoVerify() { // Perform in-toto software supply chain verification, using the provided // test data. - var layoutMb Metablock - if err := layoutMb.Load(LayoutPath); err != nil { + layoutMb, err := LoadMetadata(LayoutPath) + if err != nil { fmt.Printf("Unable to load layout metadata: %s", err) } - if err := validateLayout(layoutMb.Signed.(Layout)); err != nil { + if err := validateLayout(layoutMb.GetPayload().(Layout)); err != nil { fmt.Printf("Invalid metadata found: %s", err) } if _, err := InTotoVerify(layoutMb, layoutKeys, LinkDirectory, "", diff --git a/in_toto/model.go b/in_toto/model.go index 08092a81..1950f30c 100644 --- a/in_toto/model.go +++ b/in_toto/model.go @@ -1,7 +1,6 @@ package in_toto import ( - "context" "crypto/ecdsa" "crypto/rsa" "crypto/x509" @@ -17,7 +16,6 @@ import ( "time" "github.com/secure-systems-lab/go-securesystemslib/cjson" - "github.com/secure-systems-lab/go-securesystemslib/dsse" ) /* @@ -45,9 +43,6 @@ type Key struct { Scheme string `json:"scheme"` } -// PayloadType is the payload type used for links and layouts. -const PayloadType = "application/vnd.in-toto+json" - // ErrEmptyKeyField will be thrown if a field in our Key struct is empty. var ErrEmptyKeyField = errors.New("empty field in key") @@ -70,9 +65,6 @@ var ErrNoPublicKey = errors.New("the given key is not a public key") // for example: curve size = "521" and scheme = "ecdsa-sha2-nistp224" var ErrCurveSizeSchemeMismatch = errors.New("the scheme does not match the curve size") -// ErrInvalidPayloadType indicates that the envelope used an unkown payload type -var ErrInvalidPayloadType = errors.New("unknown payload type") - /* matchEcdsaScheme checks if the scheme suffix, matches the ecdsa key curve size. We do not need a full regex match here, because @@ -685,6 +677,105 @@ func validateLayout(layout Layout) error { return nil } +type Metadata interface { + Sign(Key) error + VerifySignature(Key) error + GetPayload() any + Sigs() []Signature + GetSignatureForKeyID(string) (Signature, error) + Dump(string) error +} + +func LoadMetadata(path string) (Metadata, error) { + jsonBytes, err := os.ReadFile(path) + if err != nil { + return nil, err + } + + var rawData map[string]*json.RawMessage + if err := json.Unmarshal(jsonBytes, &rawData); err != nil { + return nil, err + } + + if _, ok := rawData["payloadType"]; ok { + env := NewEnvelope() + if rawData["payload"] == nil || rawData["signatures"] == nil { + return nil, fmt.Errorf("in-toto metadata envelope requires 'payload' and 'signatures' parts") + } + + if err := json.Unmarshal(jsonBytes, env.envelope); err != nil { + return nil, err + } + + if env.envelope.PayloadType != PayloadType { + return nil, ErrInvalidPayloadType + } + + return env, nil + } + + mb := &Metablock{} + + // Error out on missing `signed` or `signatures` field or if + // one of them has a `null` value, which would lead to a nil pointer + // dereference in Unmarshal below. + if rawData["signed"] == nil || rawData["signatures"] == nil { + return nil, fmt.Errorf("in-toto metadata requires 'signed' and 'signatures' parts") + } + + // Fully unmarshal signatures part + if err := json.Unmarshal(*rawData["signatures"], &mb.Signatures); err != nil { + return nil, err + } + + // Temporarily copy signed to opaque map to inspect the `_type` of signed + // and create link or layout accordingly + var signed map[string]interface{} + if err := json.Unmarshal(*rawData["signed"], &signed); err != nil { + return nil, err + } + + if signed["_type"] == "link" { + var link Link + if err := checkRequiredJSONFields(signed, reflect.TypeOf(link)); err != nil { + return nil, err + } + + data, err := rawData["signed"].MarshalJSON() + if err != nil { + return nil, err + } + decoder := json.NewDecoder(strings.NewReader(string(data))) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&link); err != nil { + return nil, err + } + mb.Signed = link + + } else if signed["_type"] == "layout" { + var layout Layout + if err := checkRequiredJSONFields(signed, reflect.TypeOf(layout)); err != nil { + return nil, err + } + + data, err := rawData["signed"].MarshalJSON() + if err != nil { + return nil, err + } + decoder := json.NewDecoder(strings.NewReader(string(data))) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&layout); err != nil { + return nil, err + } + + mb.Signed = layout + } else { + return nil, fmt.Errorf("the '_type' field of the 'signed' part of in-toto metadata must be one of 'link' or 'layout'") + } + + return mb, nil +} + /* Metablock is a generic container for signable in-toto objects such as Layout or Link. It has two fields, one that contains the signable object and one that @@ -750,6 +841,9 @@ func checkRequiredJSONFields(obj map[string]interface{}, Load parses JSON formatted metadata at the passed path into the Metablock object on which it was called. It returns an error if it cannot parse a valid JSON formatted Metablock that contains a Link or Layout. + +Deprecated: Use LoadMetadata for a signature wrapper agnostic way to load an +envelope. */ func (mb *Metablock) Load(path string) error { // Open file and close before returning @@ -866,6 +960,14 @@ func (mb *Metablock) GetSignableRepresentation() ([]byte, error) { return cjson.EncodeCanonical(mb.Signed) } +func (mb *Metablock) GetPayload() any { + return mb.Signed +} + +func (mb *Metablock) Sigs() []Signature { + return mb.Signatures +} + /* VerifySignature verifies the first signature, corresponding to the passed Key, that it finds in the Signatures field of the Metablock on which it was called. diff --git a/in_toto/model_test.go b/in_toto/model_test.go index c6898437..45a672ab 100644 --- a/in_toto/model_test.go +++ b/in_toto/model_test.go @@ -2,12 +2,9 @@ package in_toto import ( "bytes" - "context" - "crypto" "crypto/x509" "crypto/x509/pkix" "encoding/hex" - "encoding/json" "errors" "fmt" "io/ioutil" @@ -17,11 +14,6 @@ import ( "testing" "time" - "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common" - slsa01 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1" - slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2" - - "github.com/secure-systems-lab/go-securesystemslib/dsse" "github.com/stretchr/testify/assert" ) @@ -1521,542 +1513,6 @@ func TestValidatePublicKey(t *testing.T) { } } -func TestDecodeProvenanceStatementSLSA02(t *testing.T) { - // Data from example in specification for generalized link format, - // subject and materials trimmed. - var data = ` -{ - "_type": "https://in-toto.io/Statement/v0.1", - "subject": [ - { "name": "curl-7.72.0.tar.bz2", - "digest": { "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef" }}, - { "name": "curl-7.72.0.tar.gz", - "digest": { "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2" }} - ], - "predicateType": "https://slsa.dev/provenance/v0.2", - "predicate": { - "builder": { "id": "https://github.com/Attestations/GitHubHostedActions@v1" }, - "buildType": "https://github.com/Attestations/GitHubActionsWorkflow@v1", - "invocation": { - "configSource": { - "uri": "git+https://github.com/curl/curl-docker@master", - "digest": { "sha1": "d6525c840a62b398424a78d792f457477135d0cf" }, - "entryPoint": "build.yaml:maketgz" - } - }, - "metadata": { - "buildStartedOn": "2020-08-19T08:38:00Z", - "completeness": { - "environment": true - } - }, - "materials": [ - { - "uri": "git+https://github.com/curl/curl-docker@master", - "digest": { "sha1": "d6525c840a62b398424a78d792f457477135d0cf" } - }, { - "uri": "github_hosted_vm:ubuntu-18.04:20210123.1" - } - ] - } -} -` - - var testTime = time.Unix(1597826280, 0) - var want = ProvenanceStatement{ - StatementHeader: StatementHeader{ - Type: StatementInTotoV01, - PredicateType: slsa02.PredicateSLSAProvenance, - Subject: []Subject{ - { - Name: "curl-7.72.0.tar.bz2", - Digest: common.DigestSet{ - "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef", - }, - }, - { - Name: "curl-7.72.0.tar.gz", - Digest: common.DigestSet{ - "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2", - }, - }, - }, - }, - Predicate: slsa02.ProvenancePredicate{ - Builder: common.ProvenanceBuilder{ - ID: "https://github.com/Attestations/GitHubHostedActions@v1", - }, - BuildType: "https://github.com/Attestations/GitHubActionsWorkflow@v1", - Invocation: slsa02.ProvenanceInvocation{ - ConfigSource: slsa02.ConfigSource{ - EntryPoint: "build.yaml:maketgz", - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - }, - }, - Metadata: &slsa02.ProvenanceMetadata{ - BuildStartedOn: &testTime, - Completeness: slsa02.ProvenanceComplete{ - Environment: true, - }, - }, - Materials: []common.ProvenanceMaterial{ - { - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - }, - { - URI: "github_hosted_vm:ubuntu-18.04:20210123.1", - }, - }, - }, - } - var got ProvenanceStatement - - if err := json.Unmarshal([]byte(data), &got); err != nil { - t.Errorf("failed to unmarshal json: %s\n", err) - return - } - - // Make sure parsed time have same location set, location is only used - // for display purposes. - loc := want.Predicate.Metadata.BuildStartedOn.Location() - tmp := got.Predicate.Metadata.BuildStartedOn.In(loc) - got.Predicate.Metadata.BuildStartedOn = &tmp - - assert.Equal(t, want, got, "Unexpexted object after decoding") -} - -func TestEncodeProvenanceStatementSLSA02(t *testing.T) { - var testTime = time.Unix(1597826280, 0) - var p = ProvenanceStatement{ - StatementHeader: StatementHeader{ - Type: StatementInTotoV01, - PredicateType: slsa02.PredicateSLSAProvenance, - Subject: []Subject{ - { - Name: "curl-7.72.0.tar.bz2", - Digest: common.DigestSet{ - "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef", - }, - }, - { - Name: "curl-7.72.0.tar.gz", - Digest: common.DigestSet{ - "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2", - }, - }, - }, - }, - Predicate: slsa02.ProvenancePredicate{ - Builder: common.ProvenanceBuilder{ - ID: "https://github.com/Attestations/GitHubHostedActions@v1", - }, - BuildType: "https://github.com/Attestations/GitHubActionsWorkflow@v1", - Invocation: slsa02.ProvenanceInvocation{ - ConfigSource: slsa02.ConfigSource{ - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - EntryPoint: "build.yaml:maketgz", - }, - }, - Metadata: &slsa02.ProvenanceMetadata{ - BuildStartedOn: &testTime, - BuildFinishedOn: &testTime, - Completeness: slsa02.ProvenanceComplete{ - Parameters: true, - Environment: false, - Materials: true, - }, - }, - Materials: []common.ProvenanceMaterial{ - { - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - }, - { - URI: "github_hosted_vm:ubuntu-18.04:20210123.1", - }, - { - URI: "git+https://github.com/curl/", - }, - }, - }, - } - var want = `{"_type":"https://in-toto.io/Statement/v0.1","predicateType":"https://slsa.dev/provenance/v0.2","subject":[{"name":"curl-7.72.0.tar.bz2","digest":{"sha256":"ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef"}},{"name":"curl-7.72.0.tar.gz","digest":{"sha256":"d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2"}}],"predicate":{"builder":{"id":"https://github.com/Attestations/GitHubHostedActions@v1"},"buildType":"https://github.com/Attestations/GitHubActionsWorkflow@v1","invocation":{"configSource":{"uri":"git+https://github.com/curl/curl-docker@master","digest":{"sha1":"d6525c840a62b398424a78d792f457477135d0cf"},"entryPoint":"build.yaml:maketgz"}},"metadata":{"buildStartedOn":"2020-08-19T08:38:00Z","buildFinishedOn":"2020-08-19T08:38:00Z","completeness":{"parameters":true,"environment":false,"materials":true},"reproducible":false},"materials":[{"uri":"git+https://github.com/curl/curl-docker@master","digest":{"sha1":"d6525c840a62b398424a78d792f457477135d0cf"}},{"uri":"github_hosted_vm:ubuntu-18.04:20210123.1"},{"uri":"git+https://github.com/curl/"}]}}` - - b, err := json.Marshal(&p) - assert.Nil(t, err, "Error during JSON marshal") - assert.Equal(t, want, string(b), "Wrong JSON produced") -} - -func TestDecodeProvenanceStatementSLSA01(t *testing.T) { - // Data from example in specification for generalized link format, - // subject and materials trimmed. - var data = ` -{ - "_type": "https://in-toto.io/Statement/v0.1", - "subject": [ - { "name": "curl-7.72.0.tar.bz2", - "digest": { "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef" }}, - { "name": "curl-7.72.0.tar.gz", - "digest": { "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2" }} - ], - "predicateType": "https://slsa.dev/provenance/v0.1", - "predicate": { - "builder": { "id": "https://github.com/Attestations/GitHubHostedActions@v1" }, - "recipe": { - "type": "https://github.com/Attestations/GitHubActionsWorkflow@v1", - "definedInMaterial": 0, - "entryPoint": "build.yaml:maketgz" - }, - "metadata": { - "buildStartedOn": "2020-08-19T08:38:00Z", - "completeness": { - "environment": true - } - }, - "materials": [ - { - "uri": "git+https://github.com/curl/curl-docker@master", - "digest": { "sha1": "d6525c840a62b398424a78d792f457477135d0cf" } - }, { - "uri": "github_hosted_vm:ubuntu-18.04:20210123.1" - } - ] - } -} -` - - var testTime = time.Unix(1597826280, 0) - var want = ProvenanceStatementSLSA01{ - StatementHeader: StatementHeader{ - Type: StatementInTotoV01, - PredicateType: slsa01.PredicateSLSAProvenance, - Subject: []Subject{ - { - Name: "curl-7.72.0.tar.bz2", - Digest: common.DigestSet{ - "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef", - }, - }, - { - Name: "curl-7.72.0.tar.gz", - Digest: common.DigestSet{ - "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2", - }, - }, - }, - }, - Predicate: slsa01.ProvenancePredicate{ - Builder: common.ProvenanceBuilder{ - ID: "https://github.com/Attestations/GitHubHostedActions@v1", - }, - Recipe: slsa01.ProvenanceRecipe{ - Type: "https://github.com/Attestations/GitHubActionsWorkflow@v1", - DefinedInMaterial: new(int), - EntryPoint: "build.yaml:maketgz", - }, - Metadata: &slsa01.ProvenanceMetadata{ - BuildStartedOn: &testTime, - Completeness: slsa01.ProvenanceComplete{ - Environment: true, - }, - }, - Materials: []common.ProvenanceMaterial{ - { - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - }, - { - URI: "github_hosted_vm:ubuntu-18.04:20210123.1", - }, - }, - }, - } - var got ProvenanceStatementSLSA01 - - if err := json.Unmarshal([]byte(data), &got); err != nil { - t.Errorf("failed to unmarshal json: %s\n", err) - return - } - - // Make sure parsed time have same location set, location is only used - // for display purposes. - loc := want.Predicate.Metadata.BuildStartedOn.Location() - tmp := got.Predicate.Metadata.BuildStartedOn.In(loc) - got.Predicate.Metadata.BuildStartedOn = &tmp - - assert.Equal(t, want, got, "Unexpexted object after decoding") -} - -func TestEncodeProvenanceStatementSLSA01(t *testing.T) { - var testTime = time.Unix(1597826280, 0) - var p = ProvenanceStatementSLSA01{ - StatementHeader: StatementHeader{ - Type: StatementInTotoV01, - PredicateType: slsa01.PredicateSLSAProvenance, - Subject: []Subject{ - { - Name: "curl-7.72.0.tar.bz2", - Digest: common.DigestSet{ - "sha256": "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef", - }, - }, - { - Name: "curl-7.72.0.tar.gz", - Digest: common.DigestSet{ - "sha256": "d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2", - }, - }, - }, - }, - Predicate: slsa01.ProvenancePredicate{ - Builder: common.ProvenanceBuilder{ - ID: "https://github.com/Attestations/GitHubHostedActions@v1", - }, - Recipe: slsa01.ProvenanceRecipe{ - Type: "https://github.com/Attestations/GitHubActionsWorkflow@v1", - DefinedInMaterial: new(int), - EntryPoint: "build.yaml:maketgz", - }, - Metadata: &slsa01.ProvenanceMetadata{ - BuildStartedOn: &testTime, - BuildFinishedOn: &testTime, - Completeness: slsa01.ProvenanceComplete{ - Arguments: true, - Environment: false, - Materials: true, - }, - }, - Materials: []common.ProvenanceMaterial{ - { - URI: "git+https://github.com/curl/curl-docker@master", - Digest: common.DigestSet{ - "sha1": "d6525c840a62b398424a78d792f457477135d0cf", - }, - }, - { - URI: "github_hosted_vm:ubuntu-18.04:20210123.1", - }, - { - URI: "git+https://github.com/curl/", - }, - }, - }, - } - var want = `{"_type":"https://in-toto.io/Statement/v0.1","predicateType":"https://slsa.dev/provenance/v0.1","subject":[{"name":"curl-7.72.0.tar.bz2","digest":{"sha256":"ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef"}},{"name":"curl-7.72.0.tar.gz","digest":{"sha256":"d4d5899a3868fbb6ae1856c3e55a32ce35913de3956d1973caccd37bd0174fa2"}}],"predicate":{"builder":{"id":"https://github.com/Attestations/GitHubHostedActions@v1"},"recipe":{"type":"https://github.com/Attestations/GitHubActionsWorkflow@v1","definedInMaterial":0,"entryPoint":"build.yaml:maketgz"},"metadata":{"buildStartedOn":"2020-08-19T08:38:00Z","buildFinishedOn":"2020-08-19T08:38:00Z","completeness":{"arguments":true,"environment":false,"materials":true},"reproducible":false},"materials":[{"uri":"git+https://github.com/curl/curl-docker@master","digest":{"sha1":"d6525c840a62b398424a78d792f457477135d0cf"}},{"uri":"github_hosted_vm:ubuntu-18.04:20210123.1"},{"uri":"git+https://github.com/curl/"}]}}` - - b, err := json.Marshal(&p) - assert.Nil(t, err, "Error during JSON marshal") - assert.Equal(t, want, string(b), "Wrong JSON produced") -} - -// Test that the default date (January 1, year 1, 00:00:00 UTC) is -// not marshalled -func TestMetadataNoTime(t *testing.T) { - var md = slsa02.ProvenanceMetadata{ - Completeness: slsa02.ProvenanceComplete{ - Parameters: true, - }, - Reproducible: true, - } - var want = `{"completeness":{"parameters":true,"environment":false,"materials":false},"reproducible":true}` - var got slsa02.ProvenanceMetadata - b, err := json.Marshal(&md) - - t.Run("Marshal", func(t *testing.T) { - assert.Nil(t, err, "Error during JSON marshal") - assert.Equal(t, want, string(b), "Wrong JSON produced") - }) - - t.Run("Unmashal", func(t *testing.T) { - err := json.Unmarshal(b, &got) - assert.Nil(t, err, "Error during JSON unmarshal") - assert.Equal(t, md, got, "Wrong struct after JSON unmarshal") - }) -} - -// Verify that the behaviour of definedInMaterial can be controlled, -// as there is a semantic difference in value present or 0. -func TestRecipe(t *testing.T) { - var r = slsa01.ProvenanceRecipe{ - Type: "testType", - EntryPoint: "testEntry", - } - var want = `{"type":"testType","entryPoint":"testEntry"}` - var got slsa01.ProvenanceRecipe - b, err := json.Marshal(&r) - - t.Run("No time/marshal", func(t *testing.T) { - assert.Nil(t, err, "Error during JSON marshal") - assert.Equal(t, want, string(b), "Wrong JSON produced") - }) - - t.Run("No time/unmarshal", func(t *testing.T) { - err = json.Unmarshal(b, &got) - assert.Nil(t, err, "Error during JSON unmarshal") - assert.Equal(t, r, got, "Wrong struct after JSON unmarshal") - }) - - // Set time to zero and run test again - r.DefinedInMaterial = new(int) - want = `{"type":"testType","definedInMaterial":0,"entryPoint":"testEntry"}` - b, err = json.Marshal(&r) - - t.Run("With time/marshal", func(t *testing.T) { - assert.Nil(t, err, "Error during JSON marshal") - assert.Equal(t, want, string(b), "Wrong JSON produced") - }) - - t.Run("With time/unmarshal", func(t *testing.T) { - err = json.Unmarshal(b, &got) - assert.Nil(t, err, "Error during JSON unmarshal") - assert.Equal(t, r, got, "Wrong struct after JSON unmarshal") - }) -} - -func TestLinkStatement(t *testing.T) { - var data = ` -{ - "subject": [ - {"name": "baz", - "digest": { "sha256": "hash1" }} - ], - "predicateType": "https://in-toto.io/Link/v1", - "predicate": { - "_type": "link", - "name": "name", - "command": ["cc", "-o", "baz", "baz.z"], - "materials": { - "kv": "vv" - }, - "products": { - "kp": "vp" - }, - "byproducts": { - "kb": "vb" - }, - "environment": { - "FOO": "BAR" - } - } -} -` - - var want = LinkStatement{ - StatementHeader: StatementHeader{ - PredicateType: PredicateLinkV1, - Subject: []Subject{ - { - Name: "baz", - Digest: common.DigestSet{ - "sha256": "hash1", - }, - }, - }, - }, - Predicate: Link{ - Type: "link", - Name: "name", - Materials: map[string]interface{}{ - "kv": "vv", - }, - Products: map[string]interface{}{ - "kp": "vp", - }, - ByProducts: map[string]interface{}{ - "kb": "vb", - }, - Environment: map[string]interface{}{ - "FOO": "BAR", - }, - Command: []string{"cc", "-o", "baz", "baz.z"}, - }, - } - var got LinkStatement - - if err := json.Unmarshal([]byte(data), &got); err != nil { - t.Errorf("failed to unmarshal json: %s\n", err) - return - } - - assert.Equal(t, want, got, "Unexpexted object after decoding") -} - -type nilsigner int - -func (n nilsigner) Sign(ctx context.Context, data []byte) ([]byte, error) { - return data, nil -} - -func (n nilsigner) Verify(ctx context.Context, data, sig []byte) error { - if len(data) != len(sig) { - return errLength - } - - for i := range data { - if data[i] != sig[i] { - return errVerify - } - } - return nil -} - -// KeyID implements dsse.SignVerifier -func (n nilsigner) KeyID() (string, error) { - return "nil", nil -} - -// Public implements dsse.SignVerifier -func (n nilsigner) Public() crypto.PublicKey { - return nil -} - -func TestDSSESigner(t *testing.T) { - t.Run("No signers provided", func(t *testing.T) { - s, err := NewDSSESigner([]dsse.SignVerifier{}...) - assert.Nil(t, s, "unexpected signer returned") - assert.NotNil(t, err, "error expected") - }) - - t.Run("Sign verify ok", func(t *testing.T) { - ctx := context.Background() - s, err := NewDSSESigner(nilsigner(0)) - assert.Nil(t, err, "unexpected error") - e, err := s.SignPayload(ctx, []byte("test data")) - assert.NotNil(t, e, "envelope expected") - assert.Nil(t, err, "unexpected error when creating signature") - err = s.Verify(ctx, e) - assert.Nil(t, err, "unexpected error when validating signature") - }) - - t.Run("Sign verify bad payload", func(t *testing.T) { - ctx := context.Background() - s, err := NewDSSESigner(nilsigner(0)) - assert.Nil(t, err, "unexpected error") - e, err := s.SignPayload(ctx, []byte("test data")) - assert.NotNil(t, e, "envelope expected") - assert.Nil(t, err, "unexpected error when creating signature") - - // Change payload type - e.PayloadType = "application/json; charset=utf-8" - - err = s.Verify(ctx, e) - assert.Equal(t, ErrInvalidPayloadType, err, "wrong error returned") - }) -} - func TestSignatureGetCertificate(t *testing.T) { sig := Signature{} _, err := sig.GetCertificate() @@ -2137,3 +1593,118 @@ func TestRootCAIDs(t *testing.T) { rootCAIDs := layout.RootCAIDs() assert.ElementsMatch(t, expectedCAIDs, rootCAIDs, "expected root ca ids don't match") } + +func TestLoadMetadata(t *testing.T) { + // Create a bunch of tmp json files with invalid format and test load errors: + // - invalid json + // - missing signatures and signed field + // - invalid signatures field + // - invalid signed field + // - invalid signed type + // - invalid signed field for type link + // - invalid signed field for type layout + invalidJSONBytes := [][]byte{ + []byte("{"), + []byte("{}"), + []byte(`{"signatures": null, "signed": {}}`), + []byte(`{"signatures": "string", "signed": {}}`), + []byte(`{"signatures": [], "signed": []}`), + []byte(`{"signatures": [], "signed": {"_type": "something else"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "name": "some name", "products": "invalid", + "byproducts": "invalid", "command": "some command", + "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "steps": "invalid", "inspect": "invalid", "readme": "some readme", + "keys": "some keys", "expires": "some date", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "inspect": "invalid", "readme": "some readme", "keys": "some keys", + "expires": "some date", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "steps": "invalid", "readme": "some readme", "keys": "some keys", + "expires": "some date", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "steps": "invalid", "inspect": "invalid", "readme": "some readme", + "expires": "some date", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "steps": "invalid", "inspect": "invalid", "readme": "some readme", + "keys": "some keys", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", + "steps": "invalid", "inspect": "invalid", + "keys": "some keys", "expires": "some date", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "layout", "steps": [], + "inspect": [], "readme": "some readme", "keys": {}, + "expires": "some date", "foo": "bar", "rootcas": [], "intermediatecas": []}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "products": "invalid", + "byproducts": "invalid", "command": "some command", + "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "name": "some name", "products": "invalid", + "byproducts": "invalid", "command": "some command", + "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "name": "some name", + "byproducts": "invalid", "command": "some command", + "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "name": "some name", "products": "invalid", + "command": "some command", + "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "name": "some name", "products": "invalid", + "byproducts": "invalid", "environment": "some list"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", + "materials": "invalid", "name": "some name", "products": "invalid", + "byproducts": "invalid", "command": "some command"}}`), + []byte(`{"signatures": [], "signed": {"_type": "link", "materials": {}, + "name": "some name", "products": {}, "byproducts": {}, + "command": [], "environment": {}, "foo": "bar"}}`), + []byte(`{"payloadType": "invalid", "payload": "eyJfdHlwZSI6ICJsaW5rIiwgIm1hdGVyaWFscyI6ICJpbnZhbGlkIiwgIm5hbWUiOiAic29tZSBuYW1lIiwgInByb2R1Y3RzIjogImludmFsaWQiLCAiYnlwcm9kdWN0cyI6ICJpbnZhbGlkIiwgImNvbW1hbmQiOiAic29tZSBjb21tYW5kIn0=", "signatures": []}`), + []byte(`{"payloadType": "application/vnd.in-toto+json", "payload": "eyJfdHlwZSI6ICJsaW5rIiwgIm1hdGVyaWFscyI6ICJpbnZhbGlkIiwgIm5hbWUiOiAic29tZSBuYW1lIiwgInByb2R1Y3RzIjogImludmFsaWQiLCAiYnlwcm9kdWN0cyI6ICJpbnZhbGlkIiwgImNvbW1hbmQiOiAic29tZSBjb21tYW5kIn0="}`), + []byte(`{"payloadType": "application/vnd.in-toto+json", "signatures": []}`), + } + + expectedErrors := []string{ + "unexpected end", + "requires 'signed' and 'signatures' parts", + "requires 'signed' and 'signatures' parts", + "cannot unmarshal string into Go value of type []in_toto.Signature", + "cannot unmarshal array into Go value of type map[string]interface {}", + "metadata must be one of 'link' or 'layout'", + "cannot unmarshal string into Go struct field Link.materials", + "cannot unmarshal string into Go struct field Layout.steps", + "required field steps missing", + "required field inspect missing", + "required field keys missing", + "required field expires missing", + "required field readme missing", + "json: unknown field \"foo\"", + "required field name missing", + "required field materials missing", + "required field products missing", + "required field byproducts missing", + "required field command missing", + "required field environment missing", + "json: unknown field \"foo\"", + ErrInvalidPayloadType.Error(), + "in-toto metadata envelope requires 'payload' and 'signatures' parts", + "in-toto metadata envelope requires 'payload' and 'signatures' parts", + } + + for i := 0; i < len(invalidJSONBytes); i++ { + fn := fmt.Sprintf("invalid-metadata-%v.tmp", i) + if err := ioutil.WriteFile(fn, invalidJSONBytes[i], 0644); err != nil { + fmt.Printf("Could not write file: %s", err) + } + _, err := LoadMetadata(fn) + if err == nil || !strings.Contains(err.Error(), expectedErrors[i]) { + t.Log(err) + t.Errorf("LoadMetadata returned '%s', expected '%s' error", err, + expectedErrors[i]) + } + if err := os.Remove(fn); err != nil { + t.Errorf("unable to remove directory %s: %s", fn, err) + } + } +} diff --git a/in_toto/runlib.go b/in_toto/runlib.go index aa8b99d8..c1d12af2 100644 --- a/in_toto/runlib.go +++ b/in_toto/runlib.go @@ -309,14 +309,10 @@ and materials at the passed materialPaths. The returned link is wrapped in a Metablock object. If command execution or artifact recording fails the first return value is an empty Metablock and the second return value is the error. */ -func InTotoRun(name string, runDir string, materialPaths []string, productPaths []string, - cmdArgs []string, key Key, hashAlgorithms []string, gitignorePatterns []string, - lStripPaths []string, lineNormalization bool, followSymlinkDirs bool) (Metablock, error) { - var linkMb Metablock - +func InTotoRun(name string, runDir string, materialPaths []string, productPaths []string, cmdArgs []string, key Key, hashAlgorithms []string, gitignorePatterns []string, lStripPaths []string, lineNormalization bool, followSymlinkDirs bool, useDSSE bool) (Metadata, error) { materials, err := RecordArtifacts(materialPaths, hashAlgorithms, gitignorePatterns, lStripPaths, lineNormalization, followSymlinkDirs) if err != nil { - return linkMb, err + return nil, err } // make sure that we only run RunCommand if cmdArgs is not nil or empty @@ -324,16 +320,16 @@ func InTotoRun(name string, runDir string, materialPaths []string, productPaths if len(cmdArgs) != 0 { byProducts, err = RunCommand(cmdArgs, runDir) if err != nil { - return linkMb, err + return nil, err } } products, err := RecordArtifacts(productPaths, hashAlgorithms, gitignorePatterns, lStripPaths, lineNormalization, followSymlinkDirs) if err != nil { - return linkMb, err + return nil, err } - linkMb.Signed = Link{ + link := Link{ Type: "link", Name: name, Materials: materials, @@ -343,14 +339,25 @@ func InTotoRun(name string, runDir string, materialPaths []string, productPaths Environment: map[string]interface{}{}, } - linkMb.Signatures = []Signature{} - // We use a new feature from Go1.13 here, to check the key struct. - // IsZero() will return True, if the key hasn't been initialized + if useDSSE { + env := NewEnvelope() + if err := env.SetPayload(link); err != nil { + return nil, err + } - // with other values than the default ones. + if !reflect.ValueOf(key).IsZero() { + if err := env.Sign(key); err != nil { + return nil, err + } + } + + return env, nil + } + + linkMb := &Metablock{Signed: link, Signatures: []Signature{}} if !reflect.ValueOf(key).IsZero() { if err := linkMb.Sign(key); err != nil { - return linkMb, err + return nil, err } } @@ -363,14 +370,13 @@ in order to provide evidence for supply chain steps that cannot be carries out by a single command. InTotoRecordStart collects the hashes of the materials before any commands are run, signs the unfinished link, and returns the link. */ -func InTotoRecordStart(name string, materialPaths []string, key Key, hashAlgorithms, gitignorePatterns []string, lStripPaths []string, lineNormalization bool, followSymlinkDirs bool) (Metablock, error) { - var linkMb Metablock +func InTotoRecordStart(name string, materialPaths []string, key Key, hashAlgorithms, gitignorePatterns []string, lStripPaths []string, lineNormalization bool, followSymlinkDirs bool, useDSSE bool) (Metadata, error) { materials, err := RecordArtifacts(materialPaths, hashAlgorithms, gitignorePatterns, lStripPaths, lineNormalization, followSymlinkDirs) if err != nil { - return linkMb, err + return nil, err } - linkMb.Signed = Link{ + link := Link{ Type: "link", Name: name, Materials: materials, @@ -380,9 +386,26 @@ func InTotoRecordStart(name string, materialPaths []string, key Key, hashAlgorit Environment: map[string]interface{}{}, } + if useDSSE { + env := NewEnvelope() + if err := env.SetPayload(link); err != nil { + return nil, err + } + + if !reflect.ValueOf(key).IsZero() { + if err := env.Sign(key); err != nil { + return nil, err + } + } + + return env, nil + } + + linkMb := &Metablock{Signed: link, Signatures: []Signature{}} + linkMb.Signatures = []Signature{} if !reflect.ValueOf(key).IsZero() { if err := linkMb.Sign(key); err != nil { - return linkMb, err + return nil, err } } @@ -396,25 +419,39 @@ created by InTotoRecordStart and records the hashes of any products creted by commands run between InTotoRecordStart and InTotoRecordStop. The resultant finished link metablock is then signed by the provided key and returned. */ -func InTotoRecordStop(prelimLinkMb Metablock, productPaths []string, key Key, hashAlgorithms, gitignorePatterns []string, lStripPaths []string, lineNormalization bool, followSymlinkDirs bool) (Metablock, error) { - var linkMb Metablock - if err := prelimLinkMb.VerifySignature(key); err != nil { - return linkMb, err +func InTotoRecordStop(prelimLinkEnv Metadata, productPaths []string, key Key, hashAlgorithms, gitignorePatterns []string, lStripPaths []string, lineNormalization bool, followSymlinkDirs bool, useDSSE bool) (Metadata, error) { + if err := prelimLinkEnv.VerifySignature(key); err != nil { + return nil, err } - link, ok := prelimLinkMb.Signed.(Link) + link, ok := prelimLinkEnv.GetPayload().(Link) if !ok { - return linkMb, errors.New("invalid metadata block") + return nil, errors.New("invalid metadata block") } products, err := RecordArtifacts(productPaths, hashAlgorithms, gitignorePatterns, lStripPaths, lineNormalization, followSymlinkDirs) if err != nil { - return linkMb, err + return nil, err } link.Products = products - linkMb.Signed = link + if useDSSE { + env := NewEnvelope() + if err := env.SetPayload(link); err != nil { + return nil, err + } + + if !reflect.ValueOf(key).IsZero() { + if err := env.Sign(key); err != nil { + return nil, err + } + } + + return env, nil + } + + linkMb := &Metablock{Signed: link, Signatures: []Signature{}} if !reflect.ValueOf(key).IsZero() { if err := linkMb.Sign(key); err != nil { return linkMb, err diff --git a/in_toto/runlib_test.go b/in_toto/runlib_test.go index c82da62b..45f93f86 100644 --- a/in_toto/runlib_test.go +++ b/in_toto/runlib_test.go @@ -11,6 +11,7 @@ import ( "runtime" "testing" + "github.com/secure-systems-lab/go-securesystemslib/dsse" "github.com/stretchr/testify/assert" ) @@ -409,9 +410,10 @@ func TestInTotoRun(t *testing.T) { cmdArgs []string key Key hashAlgorithms []string - result Metablock + useDSSE bool + result Metadata }{ - {[]string{"alice.pub"}, []string{"foo.tar.gz"}, []string{"sh", "-c", "printf out; printf err >&2"}, validKey, []string{"sha256"}, Metablock{ + {[]string{"alice.pub"}, []string{"foo.tar.gz"}, []string{"sh", "-c", "printf out; printf err >&2"}, validKey, []string{"sha256"}, false, &Metablock{ Signed: Link{ Name: linkName, Type: "link", @@ -437,7 +439,7 @@ func TestInTotoRun(t *testing.T) { }}, }, }, - {[]string{"alice.pub"}, []string{"foo.tar.gz"}, []string{}, validKey, []string{"sha256"}, Metablock{ + {[]string{"alice.pub"}, []string{"foo.tar.gz"}, []string{}, validKey, []string{"sha256"}, false, &Metablock{ Signed: Link{ Name: linkName, Type: "link", @@ -461,27 +463,42 @@ func TestInTotoRun(t *testing.T) { }}, }, }, + {[]string{"alice.pub"}, []string{"foo.tar.gz"}, []string{}, validKey, []string{"sha256"}, true, &Envelope{ + envelope: &dsse.Envelope{ + Payload: "eyJfdHlwZSI6ImxpbmsiLCJieXByb2R1Y3RzIjp7fSwiY29tbWFuZCI6W10sImVudmlyb25tZW50Ijp7fSwibWF0ZXJpYWxzIjp7ImFsaWNlLnB1YiI6eyJzaGEyNTYiOiJmMDUxZThiNTYxODM1YjdiMmFhNzc5MWRiN2JjNzJmMjYxMzQxMWIwYjdkNDI4YTBhYzMzZDQ1YjhjNTE4MDM5In19LCJuYW1lIjoiTmFtZSIsInByb2R1Y3RzIjp7ImZvby50YXIuZ3oiOnsic2hhMjU2IjoiNTI5NDdjYjc4YjkxYWQwMWZlODFjZDZhZWY0MmQxZjY4MTdlOTJiOWU2OTM2YzFlNWFhYmI3Yzk4NTE0ZjM1NSJ9fX0=", + PayloadType: PayloadType, + Signatures: []dsse.Signature{{ + KeyID: "be6371bc627318218191ce0780fd3183cce6c36da02938a477d2e4dfae1804a6", + Sig: "XgNp1Q5N/ivFxNyuUNHcjOarMIj3WXZpb00/ZVy2pxdiAeOZYKpJkXPa7wRAM5auuwrVph9TrwoJQuDpJrZaCw==", + }}, + }, + }}, } for _, table := range tablesCorrect { - result, err := InTotoRun(linkName, "", table.materialPaths, table.productPaths, table.cmdArgs, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false) - if !reflect.DeepEqual(result, table.result) { - t.Errorf("InTotoRun returned '(%s, %s)', expected '(%s, nil)'", result, err, table.result) + result, err := InTotoRun(linkName, "", table.materialPaths, table.productPaths, table.cmdArgs, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false, table.useDSSE) + if table.useDSSE { + assert.Equal(t, table.result.(*Envelope).envelope, result.(*Envelope).envelope, fmt.Sprintf("InTotoRun returned '(%s, %s)', expected '(%s, nil)'", result, err, table.result)) } else { - // we do not need to check if result == nil here, because our reflect.DeepEqual was successful + assert.True(t, reflect.DeepEqual(result.(*Metablock), table.result.(*Metablock)), fmt.Sprintf("InTotoRun returned '(%s, %s)', expected '(%s, nil)'", result, err, table.result)) + } + + if result != nil { if err := result.Dump(linkName + ".link"); err != nil { t.Errorf("error while dumping link metablock to file") } - var loadedResult Metablock - if err := loadedResult.Load(linkName + ".link"); err != nil { + loadedResult, err := LoadMetadata(linkName + ".link") + if err != nil { t.Errorf("error while loading link metablock from file") } - if !reflect.DeepEqual(loadedResult, result) { - t.Errorf("dump and loading of signed Link failed. Loaded result: '%s', dumped result '%s'", loadedResult, result) + if table.useDSSE { + assert.Equal(t, result.(*Envelope).envelope, loadedResult.(*Envelope).envelope, fmt.Sprintf("dump and loading of signed Link failed. Loaded result: '%s', dumped result '%s'", loadedResult, result)) } else { - if err := os.Remove(linkName + ".link"); err != nil { - t.Errorf("removing created link file failed") - } + assert.True(t, reflect.DeepEqual(loadedResult, result), fmt.Sprintf("dump and loading of signed Link failed. Loaded result: '%s', dumped result '%s'", loadedResult, result)) + } + + if err := os.Remove(linkName + ".link"); err != nil { + t.Errorf("removing created link file failed") } } } @@ -508,7 +525,7 @@ func TestInTotoRun(t *testing.T) { } for _, table := range tablesInvalid { - result, err := InTotoRun(linkName, "", table.materialPaths, table.productPaths, table.cmdArgs, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false) + result, err := InTotoRun(linkName, "", table.materialPaths, table.productPaths, table.cmdArgs, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false, false) if err == nil { t.Errorf("InTotoRun returned '(%s, %s)', expected error", result, err) @@ -530,10 +547,11 @@ func TestInTotoRecord(t *testing.T) { productPaths []string key Key hashAlgorithms []string - startResult Metablock - stopResult Metablock + useDSSE bool + startResult Metadata + stopResult Metadata }{ - {[]string{"alice.pub"}, []string{"foo.tar.gz"}, validKey, []string{"sha256"}, Metablock{ + {[]string{"alice.pub"}, []string{"foo.tar.gz"}, validKey, []string{"sha256"}, false, &Metablock{ Signed: Link{ Name: linkName, Type: "link", @@ -551,7 +569,7 @@ func TestInTotoRecord(t *testing.T) { KeyID: "be6371bc627318218191ce0780fd3183cce6c36da02938a477d2e4dfae1804a6", Sig: "f02db2e08d065840f266df850eaef7cfb5364bbe1808708945eb45373f4757cfe70c86f7ad5e4d5f746d41489410e0407921b4480788cfae5a7d695e3aa62f06", }}, - }, Metablock{ + }, &Metablock{ Signed: Link{ Name: linkName, Type: "link", @@ -575,15 +593,43 @@ func TestInTotoRecord(t *testing.T) { }}, }, }, + {[]string{"alice.pub"}, []string{"foo.tar.gz"}, validKey, []string{"sha256"}, true, &Envelope{ + envelope: &dsse.Envelope{ + PayloadType: PayloadType, + Payload: "eyJfdHlwZSI6ImxpbmsiLCJieXByb2R1Y3RzIjp7fSwiY29tbWFuZCI6W10sImVudmlyb25tZW50Ijp7fSwibWF0ZXJpYWxzIjp7ImFsaWNlLnB1YiI6eyJzaGEyNTYiOiJmMDUxZThiNTYxODM1YjdiMmFhNzc5MWRiN2JjNzJmMjYxMzQxMWIwYjdkNDI4YTBhYzMzZDQ1YjhjNTE4MDM5In19LCJuYW1lIjoiTmFtZSIsInByb2R1Y3RzIjp7fX0=", + Signatures: []dsse.Signature{{ + KeyID: "be6371bc627318218191ce0780fd3183cce6c36da02938a477d2e4dfae1804a6", + Sig: "1u46q3nVmmvqKz/exUviEBPyfRndXwxouG+Jk1GadqKvhyfZv8to//xLPQWC+zy4bPQTicOp1yIBHqFO0bNeBw==", + }}, + }, + }, &Envelope{ + envelope: &dsse.Envelope{ + PayloadType: PayloadType, + Payload: "eyJfdHlwZSI6ImxpbmsiLCJieXByb2R1Y3RzIjp7fSwiY29tbWFuZCI6W10sImVudmlyb25tZW50Ijp7fSwibWF0ZXJpYWxzIjp7ImFsaWNlLnB1YiI6eyJzaGEyNTYiOiJmMDUxZThiNTYxODM1YjdiMmFhNzc5MWRiN2JjNzJmMjYxMzQxMWIwYjdkNDI4YTBhYzMzZDQ1YjhjNTE4MDM5In19LCJuYW1lIjoiTmFtZSIsInByb2R1Y3RzIjp7ImZvby50YXIuZ3oiOnsic2hhMjU2IjoiNTI5NDdjYjc4YjkxYWQwMWZlODFjZDZhZWY0MmQxZjY4MTdlOTJiOWU2OTM2YzFlNWFhYmI3Yzk4NTE0ZjM1NSJ9fX0=", + Signatures: []dsse.Signature{{ + KeyID: "be6371bc627318218191ce0780fd3183cce6c36da02938a477d2e4dfae1804a6", + Sig: "XgNp1Q5N/ivFxNyuUNHcjOarMIj3WXZpb00/ZVy2pxdiAeOZYKpJkXPa7wRAM5auuwrVph9TrwoJQuDpJrZaCw==", + }}, + }, + }, + }, } for _, table := range tablesCorrect { - result, err := InTotoRecordStart(linkName, table.materialPaths, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false) + result, err := InTotoRecordStart(linkName, table.materialPaths, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false, table.useDSSE) assert.Nil(t, err, "unexpected error while running record start") - assert.Equal(t, table.startResult, result, "result from record start did not match expected result") - stopResult, err := InTotoRecordStop(result, table.productPaths, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false) + if table.useDSSE { + assert.Equal(t, table.startResult.(*Envelope).envelope, result.(*Envelope).envelope, "result from record start did not match expected result") + } else { + assert.Equal(t, table.startResult.(*Metablock), result.(*Metablock), "result from record start did not match expected result") + } + stopResult, err := InTotoRecordStop(result, table.productPaths, table.key, table.hashAlgorithms, nil, nil, testOSisWindows(), false, table.useDSSE) assert.Nil(t, err, "unexpected error while running record stop") - assert.Equal(t, table.stopResult, stopResult, "result from record stop did not match expected result") + if table.useDSSE { + assert.Equal(t, table.stopResult.(*Envelope).envelope, stopResult.(*Envelope).envelope, "result from record stop did not match expected result") + } else { + assert.Equal(t, table.stopResult.(*Metablock), stopResult.(*Metablock), "result from record stop did not match expected result") + } } } diff --git a/in_toto/verifylib.go b/in_toto/verifylib.go index 271d9ed2..65200b40 100644 --- a/in_toto/verifylib.go +++ b/in_toto/verifylib.go @@ -40,8 +40,8 @@ If executing the inspection command fails, or if the executed command has a non-zero exit code, the first return value is an empty Metablock map and the second return value is the error. */ -func RunInspections(layout Layout, runDir string, lineNormalization bool) (map[string]Metablock, error) { - inspectionMetadata := make(map[string]Metablock) +func RunInspections(layout Layout, runDir string, lineNormalization bool, useDSSE bool) (map[string]Metadata, error) { + inspectionMetadata := make(map[string]Metadata) for _, inspection := range layout.Inspect { @@ -50,14 +50,14 @@ func RunInspections(layout Layout, runDir string, lineNormalization bool) (map[s paths = []string{runDir} } - linkMb, err := InTotoRun(inspection.Name, runDir, paths, paths, - inspection.Run, Key{}, []string{"sha256"}, nil, nil, lineNormalization, false) + linkEnv, err := InTotoRun(inspection.Name, runDir, paths, paths, + inspection.Run, Key{}, []string{"sha256"}, nil, nil, lineNormalization, false, useDSSE) if err != nil { return nil, err } - retVal := linkMb.Signed.(Link).ByProducts["return-value"] + retVal := linkEnv.GetPayload().(Link).ByProducts["return-value"] if retVal != float64(0) { return nil, fmt.Errorf("inspection command '%s' of inspection '%s'"+ " returned a non-zero value: %d", inspection.Run, inspection.Name, @@ -66,11 +66,11 @@ func RunInspections(layout Layout, runDir string, lineNormalization bool) (map[s // Dump inspection link to cwd using the short link name format linkName := fmt.Sprintf(LinkNameFormatShort, inspection.Name) - if err := linkMb.Dump(linkName); err != nil { + if err := linkEnv.Dump(linkName); err != nil { fmt.Printf("JSON serialization or writing failed: %s", err) } - inspectionMetadata[inspection.Name] = linkMb + inspectionMetadata[inspection.Name] = linkEnv } return inspectionMetadata, nil } @@ -79,10 +79,10 @@ func RunInspections(layout Layout, runDir string, lineNormalization bool) (map[s // type MATCH. See VerifyArtifacts for more details. func verifyMatchRule(ruleData map[string]string, srcArtifacts map[string]interface{}, srcArtifactQueue Set, - itemsMetadata map[string]Metablock) Set { + itemsMetadata map[string]Metadata) Set { consumed := NewSet() // Get destination link metadata - dstLinkMb, exists := itemsMetadata[ruleData["dstName"]] + dstLinkEnv, exists := itemsMetadata[ruleData["dstName"]] if !exists { // Destination link does not exist, rule can't consume any // artifacts @@ -93,9 +93,9 @@ func verifyMatchRule(ruleData map[string]string, var dstArtifacts map[string]interface{} switch ruleData["dstType"] { case "materials": - dstArtifacts = dstLinkMb.Signed.(Link).Materials + dstArtifacts = dstLinkEnv.GetPayload().(Link).Materials case "products": - dstArtifacts = dstLinkMb.Signed.(Link).Products + dstArtifacts = dstLinkEnv.GetPayload().(Link).Products } // cleanup paths in pattern and artifact maps @@ -179,7 +179,7 @@ DISALLOW rule to fail overall verification, if artifacts are left in the queue that should have been consumed by preceding rules. */ func VerifyArtifacts(items []interface{}, - itemsMetadata map[string]Metablock) error { + itemsMetadata map[string]Metadata) error { // Verify artifact rules for each item in the layout for _, itemI := range items { // The layout item (interface) must be a Link or an Inspection we are only @@ -206,7 +206,7 @@ func VerifyArtifacts(items []interface{}, } // Use the item's name to extract the corresponding link - srcLinkMb, exists := itemsMetadata[itemName] + srcLinkEnv, exists := itemsMetadata[itemName] if !exists { return fmt.Errorf("VerifyArtifacts could not find metadata"+ " for item '%s', got: '%s'", itemName, itemsMetadata) @@ -214,8 +214,8 @@ func VerifyArtifacts(items []interface{}, // Create shortcuts to materials and products (including hashes) reported // by the item's link, required to verify "match" rules - materials := srcLinkMb.Signed.(Link).Materials - products := srcLinkMb.Signed.(Link).Products + materials := srcLinkEnv.GetPayload().(Link).Materials + products := srcLinkEnv.GetPayload().(Link).Products // All other rules only require the material or product paths (without // hashes). We extract them from the corresponding maps and store them as @@ -363,9 +363,9 @@ Products, the first return value is an empty Metablock map and the second return value is the error. */ func ReduceStepsMetadata(layout Layout, - stepsMetadata map[string]map[string]Metablock) (map[string]Metablock, + stepsMetadata map[string]map[string]Metadata) (map[string]Metadata, error) { - stepsMetadataReduced := make(map[string]Metablock) + stepsMetadataReduced := make(map[string]Metadata) for _, step := range layout.Steps { linksPerStep, ok := stepsMetadata[step.Name] @@ -378,16 +378,16 @@ func ReduceStepsMetadata(layout Layout, // Get the first link (could be any link) for the current step, which will // serve as reference link for below comparisons var referenceKeyID string - var referenceLinkMb Metablock - for keyID, linkMb := range linksPerStep { - referenceLinkMb = linkMb + var referenceLinkEnv Metadata + for keyID, linkEnv := range linksPerStep { + referenceLinkEnv = linkEnv referenceKeyID = keyID break } // Only one link, nothing to reduce, take the reference link if len(linksPerStep) == 1 { - stepsMetadataReduced[step.Name] = referenceLinkMb + stepsMetadataReduced[step.Name] = referenceLinkEnv // Multiple links, reduce but first check } else { @@ -395,11 +395,11 @@ func ReduceStepsMetadata(layout Layout, // TODO: What should we do if there are more links, than the // threshold requires, but not all of them are equal? Right now we would // also error. - for keyID, linkMb := range linksPerStep { - if !reflect.DeepEqual(linkMb.Signed.(Link).Materials, - referenceLinkMb.Signed.(Link).Materials) || - !reflect.DeepEqual(linkMb.Signed.(Link).Products, - referenceLinkMb.Signed.(Link).Products) { + for keyID, linkEnv := range linksPerStep { + if !reflect.DeepEqual(linkEnv.GetPayload().(Link).Materials, + referenceLinkEnv.GetPayload().(Link).Materials) || + !reflect.DeepEqual(linkEnv.GetPayload().(Link).Products, + referenceLinkEnv.GetPayload().(Link).Products) { return nil, fmt.Errorf("link '%s' and '%s' have different"+ " artifacts", fmt.Sprintf(LinkNameFormat, step.Name, referenceKeyID), @@ -407,7 +407,7 @@ func ReduceStepsMetadata(layout Layout, } } // We haven't errored out, so we can reduce (i.e take the reference link) - stepsMetadataReduced[step.Name] = referenceLinkMb + stepsMetadataReduced[step.Name] = referenceLinkEnv } } return stepsMetadataReduced, nil @@ -420,7 +420,7 @@ command, as per the layout. Soft verification means that, in case a command does not align, a warning is issued. */ func VerifyStepCommandAlignment(layout Layout, - stepsMetadata map[string]map[string]Metablock) { + stepsMetadata map[string]map[string]Metadata) { for _, step := range layout.Steps { linksPerStep, ok := stepsMetadata[step.Name] // We should never get here, layout verification must fail earlier @@ -429,9 +429,9 @@ func VerifyStepCommandAlignment(layout Layout, "', no link metadata found.") } - for signerKeyID, linkMb := range linksPerStep { + for signerKeyID, linkEnv := range linksPerStep { expectedCommandS := strings.Join(step.ExpectedCommand, " ") - executedCommandS := strings.Join(linkMb.Signed.(Link).Command, " ") + executedCommandS := strings.Join(linkEnv.GetPayload().(Link).Command, " ") if expectedCommandS != executedCommandS { linkName := fmt.Sprintf(LinkNameFormat, step.Name, signerKeyID) @@ -501,11 +501,11 @@ return value is an empty map of Metablock maps and the second return value is the error. */ func VerifyLinkSignatureThesholds(layout Layout, - stepsMetadata map[string]map[string]Metablock, rootCertPool, intermediateCertPool *x509.CertPool) ( - map[string]map[string]Metablock, error) { + stepsMetadata map[string]map[string]Metadata, rootCertPool, intermediateCertPool *x509.CertPool) ( + map[string]map[string]Metadata, error) { // This will stores links with valid signature from an authorized functionary // for all steps - stepsMetadataVerified := make(map[string]map[string]Metablock) + stepsMetadataVerified := make(map[string]map[string]Metadata) // Try to find enough (>= threshold) links each with a valid signature from // distinct authorized functionaries for each step @@ -514,7 +514,7 @@ func VerifyLinkSignatureThesholds(layout Layout, // This will store links with valid signature from an authorized // functionary for the given step - linksPerStepVerified := make(map[string]Metablock) + linksPerStepVerified := make(map[string]Metadata) // Check if there are any links at all for the given step linksPerStep, ok := stepsMetadata[step.Name] @@ -527,12 +527,12 @@ func VerifyLinkSignatureThesholds(layout Layout, // verification passes. Only good links are stored, to verify thresholds // below. isAuthorizedSignature := false - for signerKeyID, linkMb := range linksPerStep { + for signerKeyID, linkEnv := range linksPerStep { for _, authorizedKeyID := range step.PubKeys { if signerKeyID == authorizedKeyID { if verifierKey, ok := layout.Keys[authorizedKeyID]; ok { - if err := linkMb.VerifySignature(verifierKey); err == nil { - linksPerStepVerified[signerKeyID] = linkMb + if err := linkEnv.VerifySignature(verifierKey); err == nil { + linksPerStepVerified[signerKeyID] = linkEnv isAuthorizedSignature = true break } @@ -543,7 +543,7 @@ func VerifyLinkSignatureThesholds(layout Layout, // If the signer's key wasn't in our step's pubkeys array, check the cert pool to // see if the key is known to us. if !isAuthorizedSignature { - sig, err := linkMb.GetSignatureForKeyID(signerKeyID) + sig, err := linkEnv.GetSignatureForKeyID(signerKeyID) if err != nil { stepErr = err continue @@ -562,13 +562,13 @@ func VerifyLinkSignatureThesholds(layout Layout, continue } - err = linkMb.VerifySignature(cert) + err = linkEnv.VerifySignature(cert) if err != nil { stepErr = err continue } - linksPerStepVerified[signerKeyID] = linkMb + linksPerStepVerified[signerKeyID] = linkEnv } } @@ -613,11 +613,11 @@ ignored. Only a preliminary threshold check is performed, that is, if there aren't at least Threshold links for any given step, the first return value is an empty map of Metablock maps and the second return value is the error. */ -func LoadLinksForLayout(layout Layout, linkDir string) (map[string]map[string]Metablock, error) { - stepsMetadata := make(map[string]map[string]Metablock) +func LoadLinksForLayout(layout Layout, linkDir string) (map[string]map[string]Metadata, error) { + stepsMetadata := make(map[string]map[string]Metadata) for _, step := range layout.Steps { - linksPerStep := make(map[string]Metablock) + linksPerStep := make(map[string]Metadata) // Since we can verify against certificates belonging to a CA, we need to // load any possible links linkFiles, err := filepath.Glob(path.Join(linkDir, fmt.Sprintf(LinkGlobFormat, step.Name))) @@ -626,17 +626,17 @@ func LoadLinksForLayout(layout Layout, linkDir string) (map[string]map[string]Me } for _, linkPath := range linkFiles { - var linkMb Metablock - if err := linkMb.Load(linkPath); err != nil { + linkEnv, err := LoadMetadata(linkPath) + if err != nil { continue } // To get the full key from the metadata's signatures, we have to check // for one with the same short id... signerShortKeyID := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(linkPath), step.Name+"."), ".link") - for _, sig := range linkMb.Signatures { + for _, sig := range linkEnv.Sigs() { if strings.HasPrefix(sig.KeyID, signerShortKeyID) { - linksPerStep[sig.KeyID] = linkMb + linksPerStep[sig.KeyID] = linkEnv break } } @@ -676,14 +676,14 @@ Signatures and keys are associated by key id. If the key map is empty, or the Metablock's Signature field does not have a signature for one or more of the passed keys, or a matching signature is invalid, an error is returned. */ -func VerifyLayoutSignatures(layoutMb Metablock, +func VerifyLayoutSignatures(layoutEnv Metadata, layoutKeys map[string]Key) error { if len(layoutKeys) < 1 { return fmt.Errorf("layout verification requires at least one key") } for _, key := range layoutKeys { - if err := layoutMb.VerifySignature(key); err != nil { + if err := layoutEnv.VerifySignature(key); err != nil { return err } } @@ -699,29 +699,35 @@ NOTE: The assumption is that the steps mentioned in the layout are to be performed sequentially. So, the first step mentioned in the layout denotes what comes into the supply chain and the last step denotes what goes out. */ -func GetSummaryLink(layout Layout, stepsMetadataReduced map[string]Metablock, - stepName string) (Metablock, error) { +func GetSummaryLink(layout Layout, stepsMetadataReduced map[string]Metadata, + stepName string, useDSSE bool) (Metadata, error) { var summaryLink Link - var result Metablock if len(layout.Steps) > 0 { firstStepLink := stepsMetadataReduced[layout.Steps[0].Name] lastStepLink := stepsMetadataReduced[layout.Steps[len(layout.Steps)-1].Name] - summaryLink.Materials = firstStepLink.Signed.(Link).Materials + summaryLink.Materials = firstStepLink.GetPayload().(Link).Materials summaryLink.Name = stepName - summaryLink.Type = firstStepLink.Signed.(Link).Type + summaryLink.Type = firstStepLink.GetPayload().(Link).Type - summaryLink.Products = lastStepLink.Signed.(Link).Products - summaryLink.ByProducts = lastStepLink.Signed.(Link).ByProducts + summaryLink.Products = lastStepLink.GetPayload().(Link).Products + summaryLink.ByProducts = lastStepLink.GetPayload().(Link).ByProducts // Using the last command of the sublayout as the command // of the summary link can be misleading. Is it necessary to // include all the commands executed as part of sublayout? - summaryLink.Command = lastStepLink.Signed.(Link).Command + summaryLink.Command = lastStepLink.GetPayload().(Link).Command } - result.Signed = summaryLink + if useDSSE { + env := NewEnvelope() + if err := env.SetPayload(summaryLink); err != nil { + return nil, err + } + + return env, nil + } - return result, nil + return &Metablock{Signed: summaryLink}, nil } /* @@ -730,11 +736,11 @@ so, recursively resolves it and replaces it with a summary link summarizing the steps carried out in the sublayout. */ func VerifySublayouts(layout Layout, - stepsMetadataVerified map[string]map[string]Metablock, - superLayoutLinkPath string, intermediatePems [][]byte, lineNormalization bool) (map[string]map[string]Metablock, error) { + stepsMetadataVerified map[string]map[string]Metadata, + superLayoutLinkPath string, intermediatePems [][]byte, lineNormalization bool) (map[string]map[string]Metadata, error) { for stepName, linkData := range stepsMetadataVerified { for keyID, metadata := range linkData { - if _, ok := metadata.Signed.(Layout); ok { + if _, ok := metadata.GetPayload().(Layout); ok { layoutKeys := make(map[string]Key) layoutKeys[keyID] = layout.Keys[keyID] @@ -860,55 +866,57 @@ Metablock object. NOTE: Artifact rules of type "create", "modify" and "delete" are currently not supported. */ -func InTotoVerify(layoutMb Metablock, layoutKeys map[string]Key, +func InTotoVerify(layoutEnv Metadata, layoutKeys map[string]Key, linkDir string, stepName string, parameterDictionary map[string]string, intermediatePems [][]byte, lineNormalization bool) ( - Metablock, error) { - - var summaryLink Metablock - var err error + Metadata, error) { // Verify root signatures - if err := VerifyLayoutSignatures(layoutMb, layoutKeys); err != nil { - return summaryLink, err + if err := VerifyLayoutSignatures(layoutEnv, layoutKeys); err != nil { + return nil, err + } + + useDSSE := false + if _, ok := layoutEnv.(*Envelope); ok { + useDSSE = true } // Extract the layout from its Metablock container (for further processing) - layout := layoutMb.Signed.(Layout) + layout := layoutEnv.GetPayload().(Layout) // Verify layout expiration if err := VerifyLayoutExpiration(layout); err != nil { - return summaryLink, err + return nil, err } // Substitute parameters in layout - layout, err = SubstituteParameters(layout, parameterDictionary) + layout, err := SubstituteParameters(layout, parameterDictionary) if err != nil { - return summaryLink, err + return nil, err } rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(layout, intermediatePems) if err != nil { - return summaryLink, err + return nil, err } // Load links for layout stepsMetadata, err := LoadLinksForLayout(layout, linkDir) if err != nil { - return summaryLink, err + return nil, err } // Verify link signatures stepsMetadataVerified, err := VerifyLinkSignatureThesholds(layout, stepsMetadata, rootCertPool, intermediateCertPool) if err != nil { - return summaryLink, err + return nil, err } // Verify and resolve sublayouts stepsSublayoutVerified, err := VerifySublayouts(layout, stepsMetadataVerified, linkDir, intermediatePems, lineNormalization) if err != nil { - return summaryLink, err + return nil, err } // Verify command alignment (WARNING only) @@ -921,18 +929,18 @@ func InTotoVerify(layoutMb Metablock, layoutKeys map[string]Key, stepsMetadataReduced, err := ReduceStepsMetadata(layout, stepsSublayoutVerified) if err != nil { - return summaryLink, err + return nil, err } // Verify artifact rules if err = VerifyArtifacts(layout.stepsAsInterfaceSlice(), stepsMetadataReduced); err != nil { - return summaryLink, err + return nil, err } - inspectionMetadata, err := RunInspections(layout, "", lineNormalization) + inspectionMetadata, err := RunInspections(layout, "", lineNormalization, useDSSE) if err != nil { - return summaryLink, err + return nil, err } // Add steps metadata to inspection metadata, because inspection artifact @@ -943,51 +951,48 @@ func InTotoVerify(layoutMb Metablock, layoutKeys map[string]Key, if err = VerifyArtifacts(layout.inspectAsInterfaceSlice(), inspectionMetadata); err != nil { - return summaryLink, err + return nil, err } - summaryLink, err = GetSummaryLink(layout, stepsMetadataReduced, stepName) + summaryLink, err := GetSummaryLink(layout, stepsMetadataReduced, stepName, useDSSE) if err != nil { - return summaryLink, err + return nil, err } return summaryLink, nil } /* -InTotoVerifyWithDirectory provides the same functionality as IntotoVerify, but +InTotoVerifyWithDirectory provides the same functionality as InTotoVerify, but adds the possibility to select a local directory from where the inspections are run. */ -func InTotoVerifyWithDirectory(layoutMb Metablock, layoutKeys map[string]Key, +func InTotoVerifyWithDirectory(layoutEnv Metadata, layoutKeys map[string]Key, linkDir string, runDir string, stepName string, parameterDictionary map[string]string, intermediatePems [][]byte, lineNormalization bool) ( - Metablock, error) { - - var summaryLink Metablock - var err error + Metadata, error) { // runDir sanity checks // check if path exists info, err := os.Stat(runDir) if err != nil { - return Metablock{}, err + return nil, err } // check if runDir is a symlink if info.Mode()&os.ModeSymlink == os.ModeSymlink { - return Metablock{}, ErrInspectionRunDirIsSymlink + return nil, ErrInspectionRunDirIsSymlink } // check if runDir is writable and a directory err = isWritable(runDir) if err != nil { - return Metablock{}, err + return nil, err } // check if runDir is empty (we do not want to overwrite files) // We abuse File.Readdirnames for this action. f, err := os.Open(runDir) if err != nil { - return Metablock{}, err + return nil, err } defer f.Close() // We use Readdirnames(1) for performance reasons, one child node @@ -995,55 +1000,60 @@ func InTotoVerifyWithDirectory(layoutMb Metablock, layoutKeys map[string]Key, _, err = f.Readdirnames(1) // if io.EOF gets returned as error the directory is empty if err == io.EOF { - return Metablock{}, err + return nil, err } err = f.Close() if err != nil { - return Metablock{}, err + return nil, err } // Verify root signatures - if err := VerifyLayoutSignatures(layoutMb, layoutKeys); err != nil { - return summaryLink, err + if err := VerifyLayoutSignatures(layoutEnv, layoutKeys); err != nil { + return nil, err + } + + useDSSE := false + if _, ok := layoutEnv.(*Envelope); ok { + useDSSE = true } // Extract the layout from its Metablock container (for further processing) - layout := layoutMb.Signed.(Layout) + layout := layoutEnv.GetPayload().(Layout) // Verify layout expiration if err := VerifyLayoutExpiration(layout); err != nil { - return summaryLink, err + return nil, err } // Substitute parameters in layout layout, err = SubstituteParameters(layout, parameterDictionary) if err != nil { - return summaryLink, err + return nil, err } rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(layout, intermediatePems) if err != nil { - return summaryLink, err + return nil, err } // Load links for layout stepsMetadata, err := LoadLinksForLayout(layout, linkDir) if err != nil { - return summaryLink, err + return nil, err } // Verify link signatures stepsMetadataVerified, err := VerifyLinkSignatureThesholds(layout, stepsMetadata, rootCertPool, intermediateCertPool) if err != nil { - return summaryLink, err + return nil, err } // Verify and resolve sublayouts stepsSublayoutVerified, err := VerifySublayouts(layout, stepsMetadataVerified, linkDir, intermediatePems, lineNormalization) if err != nil { - return summaryLink, err + return nil, err } // Verify command alignment (WARNING only) @@ -1056,18 +1066,18 @@ func InTotoVerifyWithDirectory(layoutMb Metablock, layoutKeys map[string]Key, stepsMetadataReduced, err := ReduceStepsMetadata(layout, stepsSublayoutVerified) if err != nil { - return summaryLink, err + return nil, err } // Verify artifact rules if err = VerifyArtifacts(layout.stepsAsInterfaceSlice(), stepsMetadataReduced); err != nil { - return summaryLink, err + return nil, err } - inspectionMetadata, err := RunInspections(layout, runDir, lineNormalization) + inspectionMetadata, err := RunInspections(layout, runDir, lineNormalization, useDSSE) if err != nil { - return summaryLink, err + return nil, err } // Add steps metadata to inspection metadata, because inspection artifact @@ -1078,12 +1088,12 @@ func InTotoVerifyWithDirectory(layoutMb Metablock, layoutKeys map[string]Key, if err = VerifyArtifacts(layout.inspectAsInterfaceSlice(), inspectionMetadata); err != nil { - return summaryLink, err + return nil, err } - summaryLink, err = GetSummaryLink(layout, stepsMetadataReduced, stepName) + summaryLink, err := GetSummaryLink(layout, stepsMetadataReduced, stepName, useDSSE) if err != nil { - return summaryLink, err + return nil, err } return summaryLink, nil diff --git a/in_toto/verifylib_test.go b/in_toto/verifylib_test.go index 6ebcc6b9..e517f0ac 100644 --- a/in_toto/verifylib_test.go +++ b/in_toto/verifylib_test.go @@ -18,85 +18,112 @@ import ( ) func TestInTotoVerifyPass(t *testing.T) { - layoutPath := "demo.layout" - pubKeyPath := "alice.pub" - linkDir := "." + t.Run("metablock layout", func(t *testing.T) { + layoutPath := "demo.layout" + pubKeyPath := "alice.pub" + linkDir := "." + + layoutMb, err := LoadMetadata(layoutPath) + if err != nil { + t.Fatal(err) + } - var layoutMb Metablock - if err := layoutMb.Load(layoutPath); err != nil { - t.Error(err) - } + var pubKey Key + if err := pubKey.LoadKey(pubKeyPath, "rsassa-pss-sha256", []string{"sha256", "sha512"}); err != nil { + t.Error(err) + } - var pubKey Key - if err := pubKey.LoadKey(pubKeyPath, "rsassa-pss-sha256", []string{"sha256", "sha512"}); err != nil { - t.Error(err) - } + var layoutKeys = map[string]Key{ + pubKey.KeyID: pubKey, + } - var layouKeys = map[string]Key{ - pubKey.KeyID: pubKey, - } + // No error should occur + if _, err := InTotoVerify(layoutMb, layoutKeys, linkDir, "", + make(map[string]string), [][]byte{}, testOSisWindows()); err != nil { + t.Error(err) + } + }) - // No error should occur - if _, err := InTotoVerify(layoutMb, layouKeys, linkDir, "", - make(map[string]string), [][]byte{}, testOSisWindows()); err != nil { - t.Error(err) - } + t.Run("DSSE layout", func(t *testing.T) { + layoutPath := "demo.dsse.layout" // This layout is identical to demo.layout minus the signature wrapper + pubKeyPath := "alice.pub" + linkDir := "." + + layoutEnv, err := LoadMetadata(layoutPath) + if err != nil { + t.Fatal(err) + } + + var pubKey Key + if err := pubKey.LoadKey(pubKeyPath, "rsassa-pss-sha256", []string{"sha256", "sha512"}); err != nil { + t.Error(err) + } + + var layoutKeys = map[string]Key{ + pubKey.KeyID: pubKey, + } + + // No error should occur, verification is using a DSSE layout and Metablock links + if _, err := InTotoVerify(layoutEnv, layoutKeys, linkDir, "", + make(map[string]string), [][]byte{}, testOSisWindows()); err != nil { + t.Error(err) + } + }) } func TestGetSummaryLink(t *testing.T) { - var demoLayout Metablock - if err := demoLayout.Load("demo.layout"); err != nil { - t.Error(err) + demoLayout, err := LoadMetadata("demo.layout") + if err != nil { + t.Fatal(err) } - var codeLink Metablock - if err := codeLink.Load("write-code.b7d643de.link"); err != nil { + codeLink, err := LoadMetadata("write-code.b7d643de.link") + if err != nil { t.Error(err) } - var packageLink Metablock - if err := packageLink.Load("package.d3ffd108.link"); err != nil { + packageLink, err := LoadMetadata("package.d3ffd108.link") + if err != nil { t.Error(err) } - demoLink := make(map[string]Metablock) + demoLink := make(map[string]Metadata) demoLink["write-code"] = codeLink demoLink["package"] = packageLink - var summaryLink Metablock - var err error - if summaryLink, err = GetSummaryLink(demoLayout.Signed.(Layout), - demoLink, ""); err != nil { + var summaryLink Metadata + if summaryLink, err = GetSummaryLink(demoLayout.GetPayload().(Layout), + demoLink, "", false); err != nil { t.Error(err) } - if summaryLink.Signed.(Link).Type != codeLink.Signed.(Link).Type { + if summaryLink.GetPayload().(Link).Type != codeLink.GetPayload().(Link).Type { t.Errorf("summary Link isn't of type Link") } - if summaryLink.Signed.(Link).Name != "" { + if summaryLink.GetPayload().(Link).Name != "" { t.Errorf("summary Link name doesn't match. Expected '%s', returned "+ - "'%s", codeLink.Signed.(Link).Name, summaryLink.Signed.(Link).Name) + "'%s", codeLink.GetPayload().(Link).Name, summaryLink.GetPayload().(Link).Name) } - if !reflect.DeepEqual(summaryLink.Signed.(Link).Materials, - codeLink.Signed.(Link).Materials) { + if !reflect.DeepEqual(summaryLink.GetPayload().(Link).Materials, + codeLink.GetPayload().(Link).Materials) { t.Errorf("summary Link materials don't match. Expected '%s', "+ - "returned '%s", codeLink.Signed.(Link).Materials, - summaryLink.Signed.(Link).Materials) + "returned '%s", codeLink.GetPayload().(Link).Materials, + summaryLink.GetPayload().(Link).Materials) } - if !reflect.DeepEqual(summaryLink.Signed.(Link).Products, - packageLink.Signed.(Link).Products) { + if !reflect.DeepEqual(summaryLink.GetPayload().(Link).Products, + packageLink.GetPayload().(Link).Products) { t.Errorf("summary Link products don't match. Expected '%s', "+ - "returned '%s", packageLink.Signed.(Link).Products, - summaryLink.Signed.(Link).Products) + "returned '%s", packageLink.GetPayload().(Link).Products, + summaryLink.GetPayload().(Link).Products) } - if !reflect.DeepEqual(summaryLink.Signed.(Link).Command, - packageLink.Signed.(Link).Command) { + if !reflect.DeepEqual(summaryLink.GetPayload().(Link).Command, + packageLink.GetPayload().(Link).Command) { t.Errorf("summary Link command doesn't match. Expected '%s', "+ - "returned '%s", packageLink.Signed.(Link).Command, - summaryLink.Signed.(Link).Command) + "returned '%s", packageLink.GetPayload().(Link).Command, + summaryLink.GetPayload().(Link).Command) } - if !reflect.DeepEqual(summaryLink.Signed.(Link).ByProducts, - packageLink.Signed.(Link).ByProducts) { + if !reflect.DeepEqual(summaryLink.GetPayload().(Link).ByProducts, + packageLink.GetPayload().(Link).ByProducts) { t.Errorf("summary Link by-products don't match. Expected '%s', "+ - "returned '%s", packageLink.Signed.(Link).ByProducts, - summaryLink.Signed.(Link).ByProducts) + "returned '%s", packageLink.GetPayload().(Link).ByProducts, + summaryLink.GetPayload().(Link).ByProducts) } } @@ -126,28 +153,28 @@ func TestVerifySublayouts(t *testing.T) { t.Errorf("unable to link package metadata") } - var superLayoutMb Metablock - if err := superLayoutMb.Load("super.layout"); err != nil { + superLayoutMb, err := LoadMetadata("super.layout") + if err != nil { t.Errorf("unable to load super layout") } - stepsMetadata, err := LoadLinksForLayout(superLayoutMb.Signed.(Layout), ".") + stepsMetadata, err := LoadLinksForLayout(superLayoutMb.GetPayload().(Layout), ".") if err != nil { t.Errorf("unable to load link metadata for super layout") } - rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(superLayoutMb.Signed.(Layout), [][]byte{}) + rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(superLayoutMb.GetPayload().(Layout), [][]byte{}) if err != nil { t.Errorf("unable to load layout certificates") } stepsMetadataVerified, err := VerifyLinkSignatureThesholds( - superLayoutMb.Signed.(Layout), stepsMetadata, rootCertPool, intermediateCertPool) + superLayoutMb.GetPayload().(Layout), stepsMetadata, rootCertPool, intermediateCertPool) if err != nil { t.Errorf("unable to verify link threshold values: %v", err) } - result, err := VerifySublayouts(superLayoutMb.Signed.(Layout), + result, err := VerifySublayouts(superLayoutMb.GetPayload().(Layout), stepsMetadataVerified, ".", [][]byte{}, testOSisWindows()) if err != nil { t.Errorf("unable to verify sublayouts: %v", err) @@ -155,7 +182,7 @@ func TestVerifySublayouts(t *testing.T) { for _, stepData := range result { for _, metadata := range stepData { - if _, ok := metadata.Signed.(Link); !ok { + if _, ok := metadata.GetPayload().(Link); !ok { t.Errorf("sublayout expansion error: found non link") } } @@ -164,11 +191,11 @@ func TestVerifySublayouts(t *testing.T) { func TestRunInspections(t *testing.T) { // Load layout template used as basis for all tests - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to parse template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) // Test 1 // Successfully run two inspections foo and bar, testing that each generates @@ -186,7 +213,7 @@ func TestRunInspections(t *testing.T) { // Make a list of files in current dir (all must be recorded as artifacts) availableFiles, _ := filepath.Glob("*") - result, err := RunInspections(layout, "", testOSisWindows()) + result, err := RunInspections(layout, "", testOSisWindows(), false) // Error must be nil if err != nil { @@ -201,8 +228,8 @@ func TestRunInspections(t *testing.T) { sort.Strings(availableFiles) // Compare material and products (only file names) to files that were // in the directory before calling RunInspections - materialNames := InterfaceKeyStrings(result[inspectionName].Signed.(Link).Materials) - productNames := InterfaceKeyStrings(result[inspectionName].Signed.(Link).Products) + materialNames := InterfaceKeyStrings(result[inspectionName].GetPayload().(Link).Materials) + productNames := InterfaceKeyStrings(result[inspectionName].GetPayload().(Link).Products) sort.Strings(materialNames) sort.Strings(productNames) if !reflect.DeepEqual(materialNames, availableFiles) || @@ -232,7 +259,7 @@ func TestRunInspections(t *testing.T) { }, } - result, err = RunInspections(layout, "", testOSisWindows()) + result, err = RunInspections(layout, "", testOSisWindows(), false) if result != nil || err == nil { t.Errorf("RunInspections returned '(%s, %s)', expected"+ " '(nil, *exec.Error)'", result, err) @@ -246,7 +273,7 @@ func TestRunInspections(t *testing.T) { Run: []string{"sh", "-c", "false"}, }, } - result, err = RunInspections(layout, "", testOSisWindows()) + result, err = RunInspections(layout, "", testOSisWindows(), false) if result != nil || err == nil { t.Errorf("RunInspections returned '(%s, %s)', expected"+ " '(nil, *exec.Error)'", result, err) @@ -257,7 +284,7 @@ func TestVerifyArtifact(t *testing.T) { var testCases = []struct { name string item []interface{} - metadata map[string]Metablock + metadata map[string]Metadata expectErr string }{ { @@ -284,8 +311,8 @@ func TestVerifyArtifact(t *testing.T) { }, }, }, - metadata: map[string]Metablock{ - "foo": { + metadata: map[string]Metadata{ + "foo": &Metablock{ Signed: Link{ Name: "foo", Materials: map[string]interface{}{ @@ -318,8 +345,8 @@ func TestVerifyArtifact(t *testing.T) { }, }, }, - metadata: map[string]Metablock{ - "foo": { + metadata: map[string]Metadata{ + "foo": &Metablock{ Signed: Link{ Name: "foo", Materials: map[string]interface{}{ @@ -328,7 +355,7 @@ func TestVerifyArtifact(t *testing.T) { }, }, }, - "bar": { + "bar": &Metablock{ Signed: Link{ Name: "bar", Products: map[string]interface{}{ @@ -353,8 +380,8 @@ func TestVerifyArtifact(t *testing.T) { }, }, }, - metadata: map[string]Metablock{ - "foo": { + metadata: map[string]Metadata{ + "foo": &Metablock{ Signed: Link{ Name: "foo", Materials: map[string]interface{}{ @@ -363,7 +390,7 @@ func TestVerifyArtifact(t *testing.T) { }, }, }, - "bar": { + "bar": &Metablock{ Signed: Link{ Name: "bar", Products: map[string]interface{}{ @@ -378,139 +405,139 @@ func TestVerifyArtifact(t *testing.T) { { name: "Item must be one of step or inspection", item: []interface{}{nil}, - metadata: map[string]Metablock{}, + metadata: map[string]Metadata{}, expectErr: "item of invalid type", }, { name: "Can't find link metadata for step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo"}}}, - metadata: map[string]Metablock{}, + metadata: map[string]Metadata{}, expectErr: "could not find metadata", }, { name: "Can't find link metadata for inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo"}}}, - metadata: map[string]Metablock{}, + metadata: map[string]Metadata{}, expectErr: "could not find metadata", }, { name: "Wrong step expected material", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"INVALID", "rule"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo"}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo"}}}, expectErr: "rule format", }, { name: "Wrong step expected product", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"INVALID", "rule"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo"}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo"}}}, expectErr: "rule format", }, { name: "Wrong inspection expected material", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"INVALID", "rule"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo"}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo"}}}, expectErr: "rule format", }, { name: "Wrong inspection expected product", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"INVALID", "rule"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo"}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo"}}}, expectErr: "rule format", }, { name: "Disallowed material in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials [foo.py] disallowed by rule", }, { name: "Disallowed product in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products [foo.py] disallowed by rule", }, { name: "Disallowed material in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials [foo.py] disallowed by rule", }, { name: "Disallowed product in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products [foo.py] disallowed by rule", }, { name: "Required but missing material in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"REQUIRE", "foo"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials in REQUIRE 'foo'", }, { name: "Required but missing product in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"REQUIRE", "foo"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products in REQUIRE 'foo'", }, { name: "Required but missing material in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"REQUIRE", "foo"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials in REQUIRE 'foo'", }, { name: "Required but missing product in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"REQUIRE", "foo"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products in REQUIRE 'foo'", }, { name: "Disallowed subdirectory material in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials [dir/foo.py] disallowed by rule", }, { name: "Disallowed subdirectory product in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products [dir/foo.py] disallowed by rule", }, { name: "Disallowed subdirectory material in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "materials [dir/foo.py] disallowed by rule", }, { name: "Disallowed subdirectory product in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"dir/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "products [dir/foo.py] disallowed by rule", }, { name: "Consuming filename material in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"ALLOW", "foo.py"}, {"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "", }, { name: "Consuming filename product in step", item: []interface{}{Step{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"ALLOW", "foo.py"}, {"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "", }, { name: "Consuming filename material in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedMaterials: [][]string{{"ALLOW", "foo.py"}, {"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "", }, { name: "Consuming filename product in inspection", item: []interface{}{Inspection{SupplyChainItem: SupplyChainItem{Name: "foo", ExpectedProducts: [][]string{{"ALLOW", "foo.py"}, {"DISALLOW", "*"}}}}}, - metadata: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Products: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + metadata: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Products: map[string]interface{}{"./bar/..//foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectErr: "", }, } @@ -533,63 +560,63 @@ func TestVerifyMatchRule(t *testing.T) { name string rule map[string]string srcArtifact map[string]interface{} - item map[string]Metablock + item map[string]Metadata expectSet Set }{ { name: "Can't find destination link (invalid rule)", rule: map[string]string{}, srcArtifact: map[string]interface{}{}, - item: map[string]Metablock{}, + item: map[string]Metadata{}, expectSet: NewSet(), }, { name: "Can't find destination link (empty metadata map)", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials"}, srcArtifact: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{}, + item: map[string]Metadata{}, expectSet: NewSet(), }, { name: "Match material foo.py", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials"}, srcArtifact: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet("foo.py"), }, { name: "Match material foo.py with foo.d/foo.py", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials", "dstPrefix": "foo.d"}, srcArtifact: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.d/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.d/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet("foo.py"), }, { name: "Match material foo.d/foo.py with foo.py", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials", "srcPrefix": "foo.d"}, srcArtifact: map[string]interface{}{"foo.d/foo.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet("foo.d/foo.py"), }, { name: "Don't match material (different name)", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials"}, srcArtifact: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet(), }, { name: "Don't match material (different hash)", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials"}, srcArtifact: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "dead"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet(), }, { name: "Match material in sub-directories dir/foo.py", rule: map[string]string{"pattern": "*", "dstName": "foo", "dstType": "materials"}, srcArtifact: map[string]interface{}{"bar/foo.py": map[string]interface{}{"sha265": "abc"}}, - item: map[string]Metablock{"foo": {Signed: Link{Name: "foo", Materials: map[string]interface{}{"bar/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, + item: map[string]Metadata{"foo": &Metablock{Signed: Link{Name: "foo", Materials: map[string]interface{}{"bar/foo.py": map[string]interface{}{"sha265": "abc"}}}}}, expectSet: NewSet("bar/foo.py"), }, } @@ -606,23 +633,23 @@ func TestVerifyMatchRule(t *testing.T) { } func TestReduceStepsMetadata(t *testing.T) { - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to parse template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) layout.Steps = []Step{{SupplyChainItem: SupplyChainItem{Name: "foo"}}} // Test 1: Successful reduction of multiple links for one step (foo) - stepsMetadata := map[string]map[string]Metablock{ + stepsMetadata := map[string]map[string]Metadata{ "foo": { - "a": Metablock{Signed: Link{ + "a": &Metablock{Signed: Link{ Type: "link", Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}, Products: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "cde"}}, }}, - "b": Metablock{Signed: Link{ + "b": &Metablock{Signed: Link{ Type: "link", Name: "foo", Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}, @@ -643,22 +670,22 @@ func TestReduceStepsMetadata(t *testing.T) { // - Different materials (name) // - Different products (hash) // - Different products (name) - stepsMetadataList := []map[string]map[string]Metablock{ + stepsMetadataList := []map[string]map[string]Metadata{ {"foo": { - "a": Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, - "b": Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "def"}}}}, + "a": &Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, + "b": &Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "def"}}}}, }}, {"foo": { - "a": Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, - "b": Metablock{Signed: Link{Materials: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "abc"}}}}, + "a": &Metablock{Signed: Link{Materials: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, + "b": &Metablock{Signed: Link{Materials: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "abc"}}}}, }}, {"foo": { - "a": Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, - "b": Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "def"}}}}, + "a": &Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, + "b": &Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "def"}}}}, }}, {"foo": { - "a": Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, - "b": Metablock{Signed: Link{Products: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "abc"}}}}, + "a": &Metablock{Signed: Link{Products: map[string]interface{}{"foo.py": map[string]interface{}{"sha265": "abc"}}}}, + "b": &Metablock{Signed: Link{Products: map[string]interface{}{"bar.py": map[string]interface{}{"sha265": "abc"}}}}, }}, } @@ -685,11 +712,11 @@ func TestReduceStepsMetadata(t *testing.T) { } func TestVerifyStepCommandAlignment(t *testing.T) { - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to load template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) layout.Steps = []Step{ { SupplyChainItem: SupplyChainItem{Name: "foo"}, @@ -697,8 +724,8 @@ func TestVerifyStepCommandAlignment(t *testing.T) { }, } - stepsMetadata := map[string]map[string]Metablock{ - "foo": {"a": Metablock{Signed: Link{Command: []string{"rm", "-rf", "/"}}}}, + stepsMetadata := map[string]map[string]Metadata{ + "foo": {"a": &Metablock{Signed: Link{Command: []string{"rm", "-rf", "/"}}}}, } // Test warning due to non-aligning commands // FIXME: Assert warning? @@ -723,30 +750,30 @@ func TestVerifyLinkSignatureThesholds(t *testing.T) { keyID2 := "d3ffd1086938b3698618adf088bf14b13db4c8ae19e4e78d73da49ee88492710" keyID3 := "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabca" - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to load template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) layout.Steps = []Step{{SupplyChainItem: SupplyChainItem{ Name: "foo"}, Threshold: 2, PubKeys: []string{keyID1, keyID2, keyID3}}} - var mbLink1 Metablock - if err := mbLink1.Load("foo.b7d643de.link"); err != nil { + mbLink1, err := LoadMetadata("foo.b7d643de.link") + if err != nil { t.Errorf("unable to load link file: %s", err) } - var mbLink2 Metablock - if err := mbLink2.Load("foo.d3ffd108.link"); err != nil { + mbLink2, err := LoadMetadata("foo.d3ffd108.link") + if err != nil { t.Errorf("unable to load link file: %s", err) } - var mbLinkBroken Metablock - if err := mbLinkBroken.Load("foo.d3ffd108.link"); err != nil { + mbLinkBroken, err := LoadMetadata("foo.d3ffd108.link") + if err != nil { t.Errorf("unable to load link file: %s", err) } - mbLinkBroken.Signatures[0].Sig = "breaksignature" + mbLinkBroken.Sigs()[0].Sig = "breaksignature" // Test less then threshold distinct valid links errors: // - Missing step name in step metadata map @@ -754,7 +781,7 @@ func TestVerifyLinkSignatureThesholds(t *testing.T) { // - Less than threshold links for step // - Less than threshold distinct links for step // - Less than threshold validly signed links for step - stepsMetadata := []map[string]map[string]Metablock{ + stepsMetadata := []map[string]map[string]Metadata{ {"bar": nil}, {"foo": nil}, {"foo": {keyID1: mbLink1}}, @@ -772,7 +799,7 @@ func TestVerifyLinkSignatureThesholds(t *testing.T) { // Test successfully return threshold distinct valid links: // - Threshold 2, two valid links // - Threshold 2, two valid links, one invalid link ignored - stepsMetadata = []map[string]map[string]Metablock{ + stepsMetadata = []map[string]map[string]Metadata{ {"foo": {keyID1: mbLink1, keyID2: mbLink2}}, {"foo": {keyID1: mbLink1, keyID2: mbLink2, keyID3: mbLinkBroken}}, } @@ -789,11 +816,11 @@ func TestVerifyLinkSignatureThesholds(t *testing.T) { func TestLoadLinksForLayout(t *testing.T) { keyID1 := "d3ffd1086938b3698618adf088bf14b13db4c8ae19e4e78d73da49ee88492710" keyID2 := "b7d643dec0a051096ee5d87221b5d91a33daa658699d30903e1cefb90c418401" - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to load template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) layout.Steps = []Step{{SupplyChainItem: SupplyChainItem{ Name: "foo"}, @@ -822,11 +849,11 @@ func TestLoadLinksForLayout(t *testing.T) { } func TestVerifyLayoutExpiration(t *testing.T) { - var mb Metablock - if err := mb.Load("demo.layout"); err != nil { + mb, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to load template file: %s", err) } - layout := mb.Signed.(Layout) + layout := mb.GetPayload().(Layout) // Test layout expiration check failure: // - invalid date @@ -845,15 +872,15 @@ func TestVerifyLayoutExpiration(t *testing.T) { // Test not (yet) expired layout :) layout.Expires = "3000-01-01T00:00:00Z" - err := VerifyLayoutExpiration(layout) + err = VerifyLayoutExpiration(layout) if err != nil { t.Errorf("VerifyLayoutExpiration returned '%s', expected nil", err) } } func TestVerifyLayoutSignatures(t *testing.T) { - var mbLayout Metablock - if err := mbLayout.Load("demo.layout"); err != nil { + mbLayout, err := LoadMetadata("demo.layout") + if err != nil { t.Errorf("unable to load template file: %s", err) } var layoutKey Key @@ -876,7 +903,7 @@ func TestVerifyLayoutSignatures(t *testing.T) { } // Test successful layout signature verification - err := VerifyLayoutSignatures(mbLayout, map[string]Key{layoutKey.KeyID: layoutKey}) + err = VerifyLayoutSignatures(mbLayout, map[string]Key{layoutKey.KeyID: layoutKey}) if err != nil { t.Errorf("VerifyLayoutSignatures returned '%s', expected nil", err) @@ -978,8 +1005,8 @@ func TestInTotoVerifyWithDirectory(t *testing.T) { pubKeyPath := "alice.pub" linkDir := "." - var layoutMb Metablock - if err := layoutMb.Load(layoutPath); err != nil { + layoutMb, err := LoadMetadata(layoutPath) + if err != nil { t.Error(err) } diff --git a/test/data/demo.dsse.layout b/test/data/demo.dsse.layout new file mode 100644 index 00000000..7ba1049b --- /dev/null +++ b/test/data/demo.dsse.layout @@ -0,0 +1,10 @@ +{ + "payload": "eyJfdHlwZSI6ICJsYXlvdXQiLCAiZXhwaXJlcyI6ICIyMDMwLTExLTE4VDE2OjA2OjM2WiIsICJpbnNwZWN0IjogW3siX3R5cGUiOiAiaW5zcGVjdGlvbiIsICJleHBlY3RlZF9tYXRlcmlhbHMiOiBbWyJNQVRDSCIsICJmb28udGFyLmd6IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJwYWNrYWdlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnRhci5neiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiZm9vLnB5Il1dLCAibmFtZSI6ICJ1bnRhciIsICJydW4iOiBbInRhciIsICJ4ZnoiLCAiZm9vLnRhci5neiJdfV0sICJrZXlzIjogeyJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIjogeyJrZXlpZCI6ICJiN2Q2NDNkZWMwYTA1MTA5NmVlNWQ4NzIyMWI1ZDkxYTMzZGFhNjU4Njk5ZDMwOTAzZTFjZWZiOTBjNDE4NDAxIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBeUNUaWs5ODk1M2hLbDYrQjZuNWxcbjhEVklEd0RudnJKZnBhc2JKMytSdzY2WWNhd09aaW5ScE14UFRxV0JLczdzUm9wN2pxc1FOY3NsVW9JWkxyWFBcbnIzZm9QSEY0NTVUbHJxUFZmQ1ppRlErTzRDYWZ4V09CNG1MMU5kZHZwRlhURWptVWl3RnJyTDdQY3ZRS01iWXpcbmVVSEg0dEg5TU56cUtXYmJKb2VrQnNEcENESXhwMU5iZ2l2R0JLd2pSR2EyODFzQ2xLZ3BkMFEwZWJsK1JUY1RcbnZwZlpWRGJYYXpRN1ZxWmtpZHQ3Z2VXcTJCaWRPWFpwL2Nqb1h5Vm5lS3gvZ1lpT1V2OHg5NHN2UU16U0VodzJcbkxGTVEwNEExS25HbjFqeE8zNS9mZDYvT1czMm5qeVdzOTZSS3U5VVFWYWNZSHNRZnNBQ1BXd21WcWduWC9zcDVcbnVqbHZTRGp5Zlp1N2M1eVVRMmFzWWZRUEx2bmpHK3U3UWNCdWtHZjhoQWZWZ3NlenpYOVFQaUszNUJLRGdCVS9cblZrNDNyaUpzMTY1VEpHWUdWdUxVaElFaEhnaVF0d284cFVUSlM1bnBFZTVYTUR1Wm9pZ2hOZHpvV1kybmZzQmZcbnA4MzQ4azZ2SnRETUIwOTMvdDZWOXNUR1lRY1NiZ0tQeUVRbzVQazZXZDRaQWdNQkFBRT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSJ9LCAic2NoZW1lIjogInJzYXNzYS1wc3Mtc2hhMjU2In0sICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIjogeyJrZXlpZCI6ICJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIiwgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsic2hhMjU2IiwgInNoYTUxMiJdLCAia2V5dHlwZSI6ICJyc2EiLCAia2V5dmFsIjogeyJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeGN6OUF1Y05ia0piUXB3VEhsRUhcblJCK2grTWtZS1FqdzA2SWdaOFRYbFhHcXA1cGR3VEhJNW41aUZvbDAvcmtzbWlaeGF0SHdodGg3cnlZTkMzVmtcbjlnL0xBczlFNjB5V3l0aVNnVjkzRUt2NjVibWhZcWlTQWtKZHlhUEt2Q2I3Y0c5NzlCNGUrSFZwZFZ4NnM3RXhcbklvYURSWWNYM1ZJdDZWMjUvU1F6NWlOVWVWbGIrK1F0U2ZRRkVmM2xIYXVvRmhXWm9Dc2UyNG5XdFlabyszVXRcbnVUbXh5Z3A3dFUvOU5tWWIyQlhFZlVDZGdqb0NRMVVzRkxCUVE0aGFJZEpOT3RSRmw4S05ZMDl6Yk1VaWpLSWVcblgwWnZnVDg3N0xVdE15eWRLUEVvMDQvdTNERXI5WmJhL1NrSHc0M2pZRS9vamxYZWlrNXVWakxTcjNzSkxEU1Bcbkh3SURBUUFCXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0ifSwgInNjaGVtZSI6ICJyc2Fzc2EtcHNzLXNoYTI1NiJ9fSwgInJlYWRtZSI6ICIiLCAic3RlcHMiOiBbeyJfdHlwZSI6ICJzdGVwIiwgImV4cGVjdGVkX2NvbW1hbmQiOiBbXSwgImV4cGVjdGVkX21hdGVyaWFscyI6IFtdLCAiZXhwZWN0ZWRfcHJvZHVjdHMiOiBbWyJBTExPVyIsICJmb28ucHkiXV0sICJuYW1lIjogIndyaXRlLWNvZGUiLCAicHVia2V5cyI6IFsiYjdkNjQzZGVjMGEwNTEwOTZlZTVkODcyMjFiNWQ5MWEzM2RhYTY1ODY5OWQzMDkwM2UxY2VmYjkwYzQxODQwMSJdLCAidGhyZXNob2xkIjogMX0sIHsiX3R5cGUiOiAic3RlcCIsICJleHBlY3RlZF9jb21tYW5kIjogWyJ0YXIiLCAiemN2ZiIsICJmb28udGFyLmd6IiwgImZvby5weSJdLCAiZXhwZWN0ZWRfbWF0ZXJpYWxzIjogW1siTUFUQ0giLCAiZm9vLnB5IiwgIldJVEgiLCAiUFJPRFVDVFMiLCAiRlJPTSIsICJ3cml0ZS1jb2RlIl0sIFsiRElTQUxMT1ciLCAiKiJdXSwgImV4cGVjdGVkX3Byb2R1Y3RzIjogW1siQUxMT1ciLCAiZm9vLnRhci5neiJdLCBbIkFMTE9XIiwgImZvby5weSJdXSwgIm5hbWUiOiAicGFja2FnZSIsICJwdWJrZXlzIjogWyJkM2ZmZDEwODY5MzhiMzY5ODYxOGFkZjA4OGJmMTRiMTNkYjRjOGFlMTllNGU3OGQ3M2RhNDllZTg4NDkyNzEwIl0sICJ0aHJlc2hvbGQiOiAxfV19", + "payloadType": "application/vnd.in-toto+json", + "signatures": [ + { + "keyid": "70ca5750c2eda80b18f41f4ec5f92146789b5d68dd09577be422a0159bd13680", + "sig": "m5eJXn/whrDdgJ94u8pYI5BVUnQGpjkTQkhqjrB1nD0XFQ6+doHZLCZRzWwxO670vhZMxhLP6kPl5CK4yL42niG0+09tzKlAOsVAMnTsleJNkn6wy5SHsWBTELqlTvDyNs81FdhdEonvbm2zrQs6a0qstMVabBpkwPNVNf0jK463PAFU9jXwFV2dPDdqUCKoy7TcDi6kZOeNmXNANXhV5PGY6wh+FNAuxTWnTHMKGLiSnSyao92y8yKu+fxy4KoZkm923IQyYxSRNZT4DYTnehYDL3tJnDebWRssknZyZIuq9+aTAh7ospe8+Ak4CurdtAHjR7QBugR5iwCUIBKuww==" + } + ] +} \ No newline at end of file