From 00470e1724948c894ff01d3a8f90c6a8163a6b29 Mon Sep 17 00:00:00 2001 From: Cody Soyland Date: Mon, 3 Jun 2024 14:52:58 -0400 Subject: [PATCH] Add support for Sigstore Bundles using sigstore-go verifier (#151) * Remove dependabot for this fork (#159) * Add Actions release and attest job (#147) * update release workflow Signed-off-by: Meredith Lancaster * Grab image digest for attestation step Signed-off-by: Meredith Lancaster * comment Signed-off-by: Meredith Lancaster * update workflow name Signed-off-by: Meredith Lancaster * add release directions Signed-off-by: Meredith Lancaster * undo ko config changes Signed-off-by: Meredith Lancaster * add fork specific options to ko build call Signed-off-by: Meredith Lancaster * Change version format --------- Signed-off-by: Meredith Lancaster Co-authored-by: Cody Soyland * set release as target branch (#161) Signed-off-by: Meredith Lancaster * Add support for Sigstore Bundles using sigstore-go verifier Signed-off-by: Cody Soyland * Update docs Signed-off-by: Cody Soyland * Rename func Signed-off-by: Cody Soyland * Comment on observe timestamp setting Signed-off-by: Cody Soyland * Refactor trusted material, add support for default TUF repo in bundle verifier Signed-off-by: Cody Soyland * Remove accidental code Signed-off-by: Cody Soyland * Fix tlog verification options Signed-off-by: Cody Soyland --------- Signed-off-by: Meredith Lancaster Signed-off-by: Cody Soyland Co-authored-by: Meredith Lancaster --- config/300-clusterimagepolicy.yaml | 6 + docs/api-types/index-v1alpha1.md | 1 + docs/api-types/index.md | 1 + go.mod | 13 +- go.sum | 30 +-- .../v1alpha1/clusterimagepolicy_types.go | 4 + .../v1beta1/clusterimagepolicy_types.go | 4 + pkg/tuf/repo.go | 31 +++ pkg/webhook/bundle.go | 139 ++++++++++++ .../clusterimagepolicy_types.go | 3 + pkg/webhook/validation.go | 19 +- pkg/webhook/validator.go | 114 +++++++++- .../sigstore/sigstore-go/pkg/LICENSE | 201 ++++++++++++++++++ .../go-tuf/v2/metadata/LICENSE | 201 ++++++++++++++++++ .../go-tuf/v2/metadata/NOTICE | 9 + .../golang.org/x/mod/{sumdb/note => }/LICENSE | 0 16 files changed, 746 insertions(+), 30 deletions(-) create mode 100644 pkg/webhook/bundle.go create mode 100644 third_party/VENDOR-LICENSE/github.com/sigstore/sigstore-go/pkg/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/NOTICE rename third_party/VENDOR-LICENSE/golang.org/x/mod/{sumdb/note => }/LICENSE (100%) diff --git a/config/300-clusterimagepolicy.yaml b/config/300-clusterimagepolicy.yaml index 7558f574..b31e0617 100644 --- a/config/300-clusterimagepolicy.yaml +++ b/config/300-clusterimagepolicy.yaml @@ -209,6 +209,9 @@ spec: trustRootRef: description: Use the Certificate Chain from the referred TrustRoot.TimeStampAuthorities type: string + signatureFormat: + description: SignatureFormat specifies the format the authority expects. Supported formats are "simplesigning" and "bundle". If not specified, the default is "simplesigning" (cosign's default). + type: string source: description: Sources sets the configuration to specify the sources from where to consume the signatures. type: array @@ -545,6 +548,9 @@ spec: trustRootRef: description: Use the Certificate Chain from the referred TrustRoot.TimeStampAuthorities type: string + signatureFormat: + description: SignatureFormat specifies the format the authority expects. Supported formats are "simplesigning" and "bundle". If not specified, the default is "simplesigning" (cosign's default). + type: string source: description: Sources sets the configuration to specify the sources from where to consume the signatures. type: array diff --git a/docs/api-types/index-v1alpha1.md b/docs/api-types/index-v1alpha1.md index ab0903de..3cc115f2 100644 --- a/docs/api-types/index-v1alpha1.md +++ b/docs/api-types/index-v1alpha1.md @@ -170,6 +170,7 @@ Attestation defines the type of attestation to validate and optionally apply a p | ctlog | CTLog sets the configuration to verify the authority against a Rekor instance. | [TLog](#tlog) | false | | attestations | Attestations is a list of individual attestations for this authority, once the signature for this authority has been verified. | [][Attestation](#attestation) | false | | rfc3161timestamp | RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. | [RFC3161Timestamp](#rfc3161timestamp) | false | +| signatureFormat | SignatureFormat specifies the format the authority expects. Supported formats are \"simplesigning\" and \"bundle\". If not specified, the default is \"simplesigning\" (cosign's default). | string | false | [Back to TOC](#table-of-contents) diff --git a/docs/api-types/index.md b/docs/api-types/index.md index c3cdbb51..6498e433 100644 --- a/docs/api-types/index.md +++ b/docs/api-types/index.md @@ -49,6 +49,7 @@ The authorities block defines the rules for discovering and validating signature | ctlog | CTLog sets the configuration to verify the authority against a Rekor instance. | [TLog](#tlog) | false | | attestations | Attestations is a list of individual attestations for this authority, once the signature for this authority has been verified. | [][Attestation](#attestation) | false | | rfc3161timestamp | RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. | [RFC3161Timestamp](#rfc3161timestamp) | false | +| signatureFormat | SignatureFormat specifies the format the authority expects. Supported formats are \"simplesigning\" and \"bundle\". If not specified, the default is \"simplesigning\" (cosign's default). | string | false | [Back to TOC](#table-of-contents) diff --git a/go.mod b/go.mod index 88404c7f..4788b42d 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/ryanuber/go-glob v1.0.0 - github.com/sigstore/cosign/v2 v2.2.4 + github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c github.com/sigstore/rekor v1.3.6 github.com/sigstore/sigstore v1.8.3 github.com/stretchr/testify v1.9.0 @@ -68,10 +68,11 @@ require ( github.com/go-jose/go-jose/v3 v3.0.3 github.com/sigstore/protobuf-specs v0.3.2 github.com/sigstore/scaffolding v0.7.1 + github.com/sigstore/sigstore-go v0.3.0 github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 - github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 + github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4 github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 - github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 + github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 github.com/spf13/viper v1.18.2 gopkg.in/go-jose/go-jose.v2 v2.6.3 ) @@ -161,6 +162,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-ini/ini v1.67.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -192,7 +194,7 @@ require ( github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect - github.com/hashicorp/vault/api v1.12.2 // indirect + github.com/hashicorp/vault/api v1.14.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -242,10 +244,11 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/thales-e-security/pool v0.0.2 // indirect + github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect github.com/transparency-dev/merkle v0.0.2 // indirect github.com/vbatts/tar-split v0.11.5 // indirect - github.com/xanzy/go-gitlab v0.103.0 // indirect + github.com/xanzy/go-gitlab v0.105.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect diff --git a/go.sum b/go.sum index fa6d7e09..fd1c7c09 100644 --- a/go.sum +++ b/go.sum @@ -528,8 +528,8 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE= -github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE= +github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= +github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -732,10 +732,12 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/sigstore/cosign/v2 v2.2.4 h1:iY4vtEacmu2hkNj1Fh+8EBqBwKs2DHM27/lbNWDFJro= -github.com/sigstore/cosign/v2 v2.2.4/go.mod h1:JZlRD2uaEjVAvZ1XJ3QkkZJhTqSDVtLaet+C/TMR81Y= +github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c h1:boQtk23mqEBMNmnEqgy7HOlCCT8mQCTxtduJzxSRjTs= +github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c/go.mod h1:sZCaRMNL7abS0Rs1+Wedk+izweNpKYniCusLdoywgf8= github.com/sigstore/fulcio v1.4.5 h1:WWNnrOknD0DbruuZWCbN+86WRROpEl3Xts+WT2Ek1yc= github.com/sigstore/fulcio v1.4.5/go.mod h1:oz3Qwlma8dWcSS/IENR/6SjbW4ipN0cxpRVfgdsjMU8= github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWwQvORuRQo= @@ -746,14 +748,16 @@ github.com/sigstore/scaffolding v0.7.1 h1:oeOwZEzBjGrMGCmGJxCU9qmtbfreLIDMixlC0a github.com/sigstore/scaffolding v0.7.1/go.mod h1:1QBaVStYud8AwzUkQez16k+o8FYyjWAxi5YUNKyn3SQ= github.com/sigstore/sigstore v1.8.3 h1:G7LVXqL+ekgYtYdksBks9B38dPoIsbscjQJX/MGWkA4= github.com/sigstore/sigstore v1.8.3/go.mod h1:mqbTEariiGA94cn6G3xnDiV6BD8eSLdL/eA7bvJ0fVs= +github.com/sigstore/sigstore-go v0.3.0 h1:SxYqfonBrEhw8bNDelMieymxhdv7R9itiNZmtjOwKKU= +github.com/sigstore/sigstore-go v0.3.0/go.mod h1:oJOH7UP8aTjAGnIVwq9sDif8M4CSCik84yN1vBuESbE= github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 h1:okxaVlaTrQowE1FA4UQ3rw54f7BUjdnzERIxbZTBZuc= github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4/go.mod h1:jkcPErmnCECuSJajUaUq5pwCMOeBF19VzQo6bv4l1D0= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 h1:xgbPRCr2npmmsuVVteJqi/ERw9+I13Wou7kq0Yk4D8g= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3/go.mod h1:G4+I83FILPX6MtnoaUdmv/bRGEVtR3JdLeJa/kXdk/0= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4 h1:1G6uLTZaqvu867DbgH7p75L6Y7Tu8LLnYJGZnWsTUu8= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4/go.mod h1:QtKKb8DChi1mRi9xSNr8ImSQu6m+0MZAV0sYIoPOta0= github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 h1:fjnDR5Lw9ElfOSRUGKkgwjaynqj93nLu0twAw+QxhHE= github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4/go.mod h1:9KFn5MwelyNoFXu3gNyVzvN/yAhcL6FE053oxih9+vM= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 h1:h9G8j+Ds21zqqulDbA/R/ft64oQQIyp8S7wJYABYSlg= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3/go.mod h1:zgCeHOuqF6k7A7TTEvftcA9V3FRzB7mrPtHOhXAQBnc= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 h1:QEXOb+feQmNOyLVT+FrghBqKKK4QDMP5dyic8RZHXdE= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4/go.mod h1:ohOhV9zclcIpNAWS0kq2ASB3EPPuRce2HjgXXaU3pKQ= github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE= github.com/sigstore/timestamp-authority v1.2.2/go.mod h1:nEah4Eq4wpliDjlY342rXclGSO7Kb9hoRrl9tqLW13A= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -810,6 +814,8 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 h1:27XWhDZHPD+cufF6qSdYx6PgGQvD2jJ6pq9sDvR6VBk= +github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63/go.mod h1:+gWwqe1pk4nvGeOKosGJqPgD+N/kbD9M0QVLL9TGIYU= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= @@ -819,8 +825,8 @@ github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= -github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w= -github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM= +github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -867,8 +873,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= -go.step.sm/crypto v0.44.2 h1:t3p3uQ7raP2jp2ha9P6xkQF85TJZh+87xmjSLaib+jk= -go.step.sm/crypto v0.44.2/go.mod h1:x1439EnFhadzhkuaGX7sz03LEMQ+jV4gRamf5LCZJQQ= +go.step.sm/crypto v0.44.8 h1:jDSHL6FdB1UTA0d56ECNx9XtLVkewzeg38Vy3HWB3N8= +go.step.sm/crypto v0.44.8/go.mod h1:QEmu4T9YewrDuaJnrV1I0zWZ15aJ/mqRUfL5w3R2WgU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= diff --git a/pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go b/pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go index 32cf7978..8e3bd900 100644 --- a/pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go +++ b/pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go @@ -144,6 +144,10 @@ type Authority struct { // RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. // +optional RFC3161Timestamp *RFC3161Timestamp `json:"rfc3161timestamp,omitempty"` + // SignatureFormat specifies the format the authority expects. Supported + // formats are "simplesigning" and "bundle". If not specified, the default + // is "simplesigning" (cosign's default). + SignatureFormat string `json:"signatureFormat,omitempty"` } // This references a public verification key stored in diff --git a/pkg/apis/policy/v1beta1/clusterimagepolicy_types.go b/pkg/apis/policy/v1beta1/clusterimagepolicy_types.go index 8e1b1b8b..8934b3e0 100644 --- a/pkg/apis/policy/v1beta1/clusterimagepolicy_types.go +++ b/pkg/apis/policy/v1beta1/clusterimagepolicy_types.go @@ -143,6 +143,10 @@ type Authority struct { // RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. // +optional RFC3161Timestamp *RFC3161Timestamp `json:"rfc3161timestamp,omitempty"` + // SignatureFormat specifies the format the authority expects. Supported + // formats are "simplesigning" and "bundle". If not specified, the default + // is "simplesigning" (cosign's default). + SignatureFormat string `json:"signatureFormat,omitempty"` } // This references a public verification key stored in diff --git a/pkg/tuf/repo.go b/pkg/tuf/repo.go index 6fb02964..2e71b3ea 100644 --- a/pkg/tuf/repo.go +++ b/pkg/tuf/repo.go @@ -28,9 +28,12 @@ import ( "path/filepath" "runtime" "strings" + "sync" "testing/fstest" "time" + "github.com/sigstore/sigstore-go/pkg/root" + "github.com/sigstore/sigstore/pkg/tuf" "github.com/theupdateframework/go-tuf/client" "sigs.k8s.io/release-utils/version" ) @@ -288,3 +291,31 @@ func ClientFromRemote(_ context.Context, mirror string, rootJSON []byte, targets } return tufClient, nil } + +var ( + once sync.Once + trustedRoot *root.TrustedRoot + singletonRootError error +) + +// GetTrustedRoot returns the trusted root for the TUF repository. +func GetTrustedRoot() (*root.TrustedRoot, error) { + once.Do(func() { + tufClient, err := tuf.NewFromEnv(context.Background()) + if err != nil { + singletonRootError = fmt.Errorf("initializing tuf: %w", err) + return + } + // TODO: add support for custom trusted root path + targetBytes, err := tufClient.GetTarget("trusted_root.json") + if err != nil { + singletonRootError = fmt.Errorf("error getting targets: %w", err) + return + } + trustedRoot, singletonRootError = root.NewTrustedRootFromJSON(targetBytes) + }) + if singletonRootError != nil { + return nil, singletonRootError + } + return trustedRoot, nil +} diff --git a/pkg/webhook/bundle.go b/pkg/webhook/bundle.go new file mode 100644 index 00000000..3d2dbf1b --- /dev/null +++ b/pkg/webhook/bundle.go @@ -0,0 +1,139 @@ +package webhook + +import ( + "crypto/x509" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "strings" + + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/remote" + + "github.com/sigstore/sigstore-go/pkg/bundle" + "github.com/sigstore/sigstore-go/pkg/root" + "github.com/sigstore/sigstore-go/pkg/verify" +) + +type VerifiedBundle struct { + SGBundle *bundle.ProtobufBundle + Result *verify.VerificationResult + Hash v1.Hash +} + +// VerifiedBundle implements Signature +var _ Signature = &VerifiedBundle{} + +func (vb *VerifiedBundle) Digest() (v1.Hash, error) { + return vb.Hash, nil +} + +func (vb *VerifiedBundle) Payload() ([]byte, error) { + // todo: this should return the json-serialized dsse envelope + envelope := vb.SGBundle.GetDsseEnvelope() + if envelope == nil { + return nil, fmt.Errorf("no dsse envelope found") + } + return json.Marshal(envelope) +} + +func (vb *VerifiedBundle) Signature() ([]byte, error) { + // TODO: implement this + return []byte{}, nil +} + +func (vb *VerifiedBundle) Cert() (*x509.Certificate, error) { + vc, err := vb.SGBundle.VerificationContent() + if err != nil { + return nil, err + } + if cert, ok := vc.HasCertificate(); ok { + return &cert, nil + } + return nil, errors.New("bundle does not contain a certificate") +} + +func VerifiedBundles(ref name.Reference, trustedMaterial root.TrustedMaterial, remoteOpts []remote.Option, policyOptions []verify.PolicyOption, verifierOptions []verify.VerifierOption) ([]Signature, error) { + sev, err := verify.NewSignedEntityVerifier(trustedMaterial, verifierOptions...) + if err != nil { + return nil, err + } + + bundles, hash, err := getBundles(ref, remoteOpts) + if err != nil { + return nil, err + } + + digestBytes, err := hex.DecodeString(hash.Hex) + if err != nil { + return nil, err + } + artifactPolicy := verify.WithArtifactDigest(hash.Algorithm, digestBytes) + policy := verify.NewPolicy(artifactPolicy, policyOptions...) + + verifiedBundles := make([]Signature, 0) + for _, b := range bundles { + // TODO: should these be done in parallel? (as is done in cosign?) + result, err := sev.Verify(b, policy) + if err == nil { + verifiedBundles = append(verifiedBundles, &VerifiedBundle{SGBundle: b, Result: result, Hash: *hash}) + } + } + return verifiedBundles, nil +} + +func getBundles(ref name.Reference, remoteOpts []remote.Option) ([]*bundle.ProtobufBundle, *v1.Hash, error) { + desc, err := remote.Get(ref, remoteOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error getting image descriptor: %w", err) + } + + digest := ref.Context().Digest(desc.Digest.String()) + + referrers, err := remote.Referrers(digest, remoteOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error getting referrers: %w", err) + } + refManifest, err := referrers.IndexManifest() + if err != nil { + return nil, nil, fmt.Errorf("error getting referrers manifest: %w", err) + } + + bundles := make([]*bundle.ProtobufBundle, 0) + + for _, refDesc := range refManifest.Manifests { + if !strings.HasPrefix(refDesc.ArtifactType, "application/vnd.dev.sigstore.bundle") { + continue + } + + refImg, err := remote.Image(ref.Context().Digest(refDesc.Digest.String()), remoteOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error getting referrer image: %w", err) + } + layers, err := refImg.Layers() + if err != nil { + return nil, nil, fmt.Errorf("error getting referrer image: %w", err) + } + layer0, err := layers[0].Uncompressed() + if err != nil { + return nil, nil, fmt.Errorf("error getting referrer image: %w", err) + } + bundleBytes, err := io.ReadAll(layer0) + if err != nil { + return nil, nil, fmt.Errorf("error getting referrer image: %w", err) + } + b := &bundle.ProtobufBundle{} + err = b.UnmarshalJSON(bundleBytes) + if err != nil { + return nil, nil, fmt.Errorf("error unmarshalling bundle: %w", err) + } + bundles = append(bundles, b) + } + if len(bundles) == 0 { + return nil, nil, fmt.Errorf("no bundle found in referrers") + } + return bundles, &desc.Digest, nil +} diff --git a/pkg/webhook/clusterimagepolicy/clusterimagepolicy_types.go b/pkg/webhook/clusterimagepolicy/clusterimagepolicy_types.go index a01235eb..e022d5d6 100644 --- a/pkg/webhook/clusterimagepolicy/clusterimagepolicy_types.go +++ b/pkg/webhook/clusterimagepolicy/clusterimagepolicy_types.go @@ -86,6 +86,8 @@ type Authority struct { Attestations []AttestationPolicy `json:"attestations,omitempty"` // +optional RFC3161Timestamp *RFC3161Timestamp `json:"rfc3161timestamp,omitempty"` + // +optional + SignatureFormat string `json:"signatureFormat,omitempty"` } // This references a public verification key stored in @@ -325,6 +327,7 @@ func convertAuthorityV1Alpha1ToWebhook(in v1alpha1.Authority) *Authority { CTLog: in.CTLog, RFC3161Timestamp: rfc3161Timestamp, Attestations: attestations, + SignatureFormat: in.SignatureFormat, } } diff --git a/pkg/webhook/validation.go b/pkg/webhook/validation.go index 91621116..a13ad196 100644 --- a/pkg/webhook/validation.go +++ b/pkg/webhook/validation.go @@ -24,11 +24,10 @@ import ( "knative.dev/pkg/logging" "github.com/sigstore/cosign/v2/pkg/cosign" - "github.com/sigstore/cosign/v2/pkg/oci" "github.com/sigstore/sigstore/pkg/signature" ) -func valid(ctx context.Context, ref name.Reference, keys []crypto.PublicKey, hashAlgo crypto.Hash, checkOpts *cosign.CheckOpts) ([]oci.Signature, error) { +func valid(ctx context.Context, ref name.Reference, keys []crypto.PublicKey, hashAlgo crypto.Hash, checkOpts *cosign.CheckOpts) ([]Signature, error) { if len(keys) == 0 { return validSignatures(ctx, ref, checkOpts) } @@ -58,16 +57,24 @@ func valid(ctx context.Context, ref name.Reference, keys []crypto.PublicKey, has var cosignVerifySignatures = cosign.VerifyImageSignatures var cosignVerifyAttestations = cosign.VerifyImageAttestations -func validSignatures(ctx context.Context, ref name.Reference, checkOpts *cosign.CheckOpts) ([]oci.Signature, error) { +func validSignatures(ctx context.Context, ref name.Reference, checkOpts *cosign.CheckOpts) ([]Signature, error) { checkOpts.ClaimVerifier = cosign.SimpleClaimVerifier sigs, _, err := cosignVerifySignatures(ctx, ref, checkOpts) - return sigs, err + sigList := make([]Signature, len(sigs)) + for i, s := range sigs { + sigList[i] = s + } + return sigList, err } -func validAttestations(ctx context.Context, ref name.Reference, checkOpts *cosign.CheckOpts) ([]oci.Signature, error) { +func validAttestations(ctx context.Context, ref name.Reference, checkOpts *cosign.CheckOpts) ([]Signature, error) { checkOpts.ClaimVerifier = cosign.IntotoSubjectClaimVerifier attestations, _, err := cosignVerifyAttestations(ctx, ref, checkOpts) - return attestations, err + sigList := make([]Signature, len(attestations)) + for i, s := range attestations { + sigList[i] = s + } + return sigList, err } func parsePems(b []byte) []*pem.Block { diff --git a/pkg/webhook/validator.go b/pkg/webhook/validator.go index 52bae194..11e54f6a 100644 --- a/pkg/webhook/validator.go +++ b/pkg/webhook/validator.go @@ -35,12 +35,12 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/v2/pkg/cosign" - "github.com/sigstore/cosign/v2/pkg/oci" ociremote "github.com/sigstore/cosign/v2/pkg/oci/remote" "github.com/sigstore/cosign/v2/pkg/policy" "github.com/sigstore/policy-controller/pkg/apis/config" policyduckv1beta1 "github.com/sigstore/policy-controller/pkg/apis/duck/v1beta1" policycontrollerconfig "github.com/sigstore/policy-controller/pkg/config" + pctuf "github.com/sigstore/policy-controller/pkg/tuf" webhookcip "github.com/sigstore/policy-controller/pkg/webhook/clusterimagepolicy" "github.com/sigstore/policy-controller/pkg/webhook/registryauth" rekor "github.com/sigstore/rekor/pkg/client" @@ -57,8 +57,22 @@ import ( kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/logging" + + sgroot "github.com/sigstore/sigstore-go/pkg/root" + "github.com/sigstore/sigstore-go/pkg/verify" ) +type Signature interface { + Digest() (v1.Hash, error) + Payload() ([]byte, error) + Signature() ([]byte, error) + Cert() (*x509.Certificate, error) +} + +// Assert that Signature implements policy.PayloadProvider (used by +// policy.AttestationToPayloadJSON) +var _ policy.PayloadProvider = (Signature)(nil) + type Validator struct{} func NewValidator(_ context.Context) *Validator { @@ -524,8 +538,12 @@ func ValidatePolicy(ctx context.Context, namespace string, ref name.Reference, c result.static = true case len(authority.Attestations) > 0: - // We're doing the verify-attestations path, so validate (.att) - result.attestations, result.err = ValidatePolicyAttestationsForAuthority(ctx, ref, authority, authorityRemoteOpts...) + if authority.SignatureFormat == "bundle" { + result.attestations, result.err = ValidatePolicyAttestationsForAuthorityWithBundle(ctx, ref, authority, kc) + } else { + // We're doing the verify-attestations path, so validate (.att) + result.attestations, result.err = ValidatePolicyAttestationsForAuthority(ctx, ref, authority, authorityRemoteOpts...) + } default: result.signatures, result.err = ValidatePolicySignaturesForAuthority(ctx, ref, authority, authorityRemoteOpts...) @@ -639,7 +657,7 @@ func ValidatePolicy(ctx context.Context, namespace string, ref name.Reference, c return policyResult, authorityErrors } -func ociSignatureToPolicySignature(ctx context.Context, sigs []oci.Signature) []PolicySignature { +func ociSignatureToPolicySignature(ctx context.Context, sigs []Signature) []PolicySignature { ret := make([]PolicySignature, 0, len(sigs)) for _, ociSig := range sigs { logging.FromContext(ctx).Debugf("Converting signature %+v", ociSig) @@ -681,7 +699,7 @@ func ociSignatureToPolicySignature(ctx context.Context, sigs []oci.Signature) [] } // signatureID creates a unique hash for the Signature, using both the signature itself + the cert. -func signatureID(sig oci.Signature) (string, error) { +func signatureID(sig Signature) (string, error) { h := sha256.New() s, err := sig.Signature() if err != nil { @@ -713,7 +731,7 @@ func signatureID(sig oci.Signature) (string, error) { // PolicyAttestations upon completion without needing to refetch any of the // parts. type attestation struct { - oci.Signature + Signature PredicateType string Payload []byte @@ -833,7 +851,7 @@ func ValidatePolicyAttestationsForAuthority(ctx context.Context, ref name.Refere return nil, fmt.Errorf("creating CheckOpts: %w", err) } - verifiedAttestations := []oci.Signature{} + verifiedAttestations := []Signature{} switch { case authority.Key != nil && len(authority.Key.PublicKeys) > 0: for _, k := range authority.Key.PublicKeys { @@ -878,6 +896,10 @@ func ValidatePolicyAttestationsForAuthority(ctx context.Context, ref name.Refere } logging.FromContext(ctx).Debugf("Found %d valid attestations, validating policies for them", len(verifiedAttestations)) + return checkPredicates(ctx, authority, verifiedAttestations) +} + +func checkPredicates(ctx context.Context, authority webhookcip.Authority, verifiedAttestations []Signature) (map[string][]PolicyAttestation, error) { // Now spin through the Attestations that the user specified and validate // them. // TODO(vaikas): Pretty inefficient here, figure out a better way if @@ -965,6 +987,84 @@ func ValidatePolicyAttestationsForAuthority(ctx context.Context, ref name.Refere return ret, nil } +func ValidatePolicyAttestationsForAuthorityWithBundle(ctx context.Context, ref name.Reference, authority webhookcip.Authority, kc authn.Keychain) (map[string][]PolicyAttestation, error) { + // TODO: Apply authority.Source options (Tag prefix, alternative registry, and signature pull secrets) + remoteOpts := []remote.Option{ + remote.WithContext(ctx), + remote.WithAuthFromKeychain(kc), + } + + trustedMaterial, err := trustedMaterialFromAuthority(ctx, authority) + if err != nil { + return nil, fmt.Errorf("failed to get trusted material: %w", err) + } + + // TODO: what if not keyless? + if authority.Keyless.Identities == nil { + return nil, errors.New("must specify at least one identity for keyless authority") + } + + policyOptions := make([]verify.PolicyOption, 0, len(authority.Keyless.Identities)) + for _, id := range authority.Keyless.Identities { + // The sanType is intentionally left blank, as there is currently no means + // to specify it in the policy, and its absence means it will just not + // verify the type. + id, err := verify.NewShortCertificateIdentity(id.Issuer, id.Subject, "", id.SubjectRegExp) + if err != nil { + return nil, fmt.Errorf("failed to create certificate identity: %w", err) + } + policyOptions = append(policyOptions, verify.WithCertificateIdentity(id)) + } + + // If the authority requires a timestamp, use it, otherwise use transparency log + // TODO: We should allow this to be configurable in ClusterImagePolicy. Current behavior is equivalent to the legacy verifier behavior. + var verifierOptions []verify.VerifierOption + if authority.RFC3161Timestamp != nil { + verifierOptions = append(verifierOptions, verify.WithSignedTimestamps(1)) + } else { + verifierOptions = append(verifierOptions, verify.WithTransparencyLog(1), verify.WithObserverTimestamps(1)) + } + + verifiedBundles, err := VerifiedBundles(ref, trustedMaterial, remoteOpts, policyOptions, verifierOptions) + if err != nil { + return nil, err + } + + if len(verifiedBundles) == 0 { + return nil, errors.New("no verified bundles found") + } + + return checkPredicates(ctx, authority, verifiedBundles) +} + +func trustedMaterialFromAuthority(ctx context.Context, authority webhookcip.Authority) (sgroot.TrustedMaterial, error) { + var trustedMaterial sgroot.TrustedMaterial + if authority.Keyless != nil { + if authority.Keyless.TrustRootRef != "" { + trustRoot, err := sigstoreKeysFromContext(ctx, authority.Keyless.TrustRootRef) + if err != nil { + return nil, fmt.Errorf("failed to get trusted root from context: %w", err) + } + if pbTrustedRoot, ok := trustRoot.SigstoreKeys[authority.Keyless.TrustRootRef]; ok { + trustedMaterial, err = sgroot.NewTrustedRootFromProtobuf(pbTrustedRoot) + if err != nil { + return nil, fmt.Errorf("failed to parse trusted root from protobuf: %w", err) + } + return trustedMaterial, nil + } else { + return nil, fmt.Errorf("trusted root \"%s\" does not exist", authority.Keyless.TrustRootRef) + } + } + trustedMaterial, err := pctuf.GetTrustedRoot() + if err != nil { + return nil, fmt.Errorf("failed to parse trusted root from protobuf: %w", err) + } + + return trustedMaterial, nil + } + return nil, errors.New("no trusted material specified") // TODO: better error message +} + // ResolvePodScalable implements policyduckv1beta1.PodScalableValidator func (v *Validator) ResolvePodScalable(ctx context.Context, ps *policyduckv1beta1.PodScalable) { // Don't mess with things that are being deleted or already deleted or diff --git a/third_party/VENDOR-LICENSE/github.com/sigstore/sigstore-go/pkg/LICENSE b/third_party/VENDOR-LICENSE/github.com/sigstore/sigstore-go/pkg/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/sigstore/sigstore-go/pkg/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/LICENSE b/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/LICENSE new file mode 100644 index 00000000..85541be2 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 The Update Framework Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/NOTICE b/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/NOTICE new file mode 100644 index 00000000..09005219 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/theupdateframework/go-tuf/v2/metadata/NOTICE @@ -0,0 +1,9 @@ +Copyright 2024 The Update Framework Authors + +Apache 2.0 License +Copyright 2024 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (/). + +SPDX-License-Identifier: Apache-2.0 diff --git a/third_party/VENDOR-LICENSE/golang.org/x/mod/sumdb/note/LICENSE b/third_party/VENDOR-LICENSE/golang.org/x/mod/LICENSE similarity index 100% rename from third_party/VENDOR-LICENSE/golang.org/x/mod/sumdb/note/LICENSE rename to third_party/VENDOR-LICENSE/golang.org/x/mod/LICENSE