Skip to content

Commit 00470e1

Browse files
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 <[email protected]> * Grab image digest for attestation step Signed-off-by: Meredith Lancaster <[email protected]> * comment Signed-off-by: Meredith Lancaster <[email protected]> * update workflow name Signed-off-by: Meredith Lancaster <[email protected]> * add release directions Signed-off-by: Meredith Lancaster <[email protected]> * undo ko config changes Signed-off-by: Meredith Lancaster <[email protected]> * add fork specific options to ko build call Signed-off-by: Meredith Lancaster <[email protected]> * Change version format --------- Signed-off-by: Meredith Lancaster <[email protected]> Co-authored-by: Cody Soyland <[email protected]> * set release as target branch (#161) Signed-off-by: Meredith Lancaster <[email protected]> * Add support for Sigstore Bundles using sigstore-go verifier Signed-off-by: Cody Soyland <[email protected]> * Update docs Signed-off-by: Cody Soyland <[email protected]> * Rename func Signed-off-by: Cody Soyland <[email protected]> * Comment on observe timestamp setting Signed-off-by: Cody Soyland <[email protected]> * Refactor trusted material, add support for default TUF repo in bundle verifier Signed-off-by: Cody Soyland <[email protected]> * Remove accidental code Signed-off-by: Cody Soyland <[email protected]> * Fix tlog verification options Signed-off-by: Cody Soyland <[email protected]> --------- Signed-off-by: Meredith Lancaster <[email protected]> Signed-off-by: Cody Soyland <[email protected]> Co-authored-by: Meredith Lancaster <[email protected]>
1 parent af217e4 commit 00470e1

File tree

16 files changed

+746
-30
lines changed

16 files changed

+746
-30
lines changed

Diff for: config/300-clusterimagepolicy.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ spec:
209209
trustRootRef:
210210
description: Use the Certificate Chain from the referred TrustRoot.TimeStampAuthorities
211211
type: string
212+
signatureFormat:
213+
description: SignatureFormat specifies the format the authority expects. Supported formats are "simplesigning" and "bundle". If not specified, the default is "simplesigning" (cosign's default).
214+
type: string
212215
source:
213216
description: Sources sets the configuration to specify the sources from where to consume the signatures.
214217
type: array
@@ -545,6 +548,9 @@ spec:
545548
trustRootRef:
546549
description: Use the Certificate Chain from the referred TrustRoot.TimeStampAuthorities
547550
type: string
551+
signatureFormat:
552+
description: SignatureFormat specifies the format the authority expects. Supported formats are "simplesigning" and "bundle". If not specified, the default is "simplesigning" (cosign's default).
553+
type: string
548554
source:
549555
description: Sources sets the configuration to specify the sources from where to consume the signatures.
550556
type: array

Diff for: docs/api-types/index-v1alpha1.md

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ Attestation defines the type of attestation to validate and optionally apply a p
170170
| ctlog | CTLog sets the configuration to verify the authority against a Rekor instance. | [TLog](#tlog) | false |
171171
| attestations | Attestations is a list of individual attestations for this authority, once the signature for this authority has been verified. | [][Attestation](#attestation) | false |
172172
| rfc3161timestamp | RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. | [RFC3161Timestamp](#rfc3161timestamp) | false |
173+
| 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 |
173174

174175
[Back to TOC](#table-of-contents)
175176

Diff for: docs/api-types/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The authorities block defines the rules for discovering and validating signature
4949
| ctlog | CTLog sets the configuration to verify the authority against a Rekor instance. | [TLog](#tlog) | false |
5050
| attestations | Attestations is a list of individual attestations for this authority, once the signature for this authority has been verified. | [][Attestation](#attestation) | false |
5151
| rfc3161timestamp | RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance. | [RFC3161Timestamp](#rfc3161timestamp) | false |
52+
| 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 |
5253

5354
[Back to TOC](#table-of-contents)
5455

Diff for: go.mod

+8-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ require (
2929
github.com/mitchellh/go-homedir v1.1.0
3030
github.com/mitchellh/mapstructure v1.5.0
3131
github.com/ryanuber/go-glob v1.0.0
32-
github.com/sigstore/cosign/v2 v2.2.4
32+
github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c
3333
github.com/sigstore/rekor v1.3.6
3434
github.com/sigstore/sigstore v1.8.3
3535
github.com/stretchr/testify v1.9.0
@@ -68,10 +68,11 @@ require (
6868
github.com/go-jose/go-jose/v3 v3.0.3
6969
github.com/sigstore/protobuf-specs v0.3.2
7070
github.com/sigstore/scaffolding v0.7.1
71+
github.com/sigstore/sigstore-go v0.3.0
7172
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4
72-
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3
73+
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4
7374
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4
74-
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3
75+
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4
7576
github.com/spf13/viper v1.18.2
7677
gopkg.in/go-jose/go-jose.v2 v2.6.3
7778
)
@@ -161,6 +162,7 @@ require (
161162
github.com/fsnotify/fsnotify v1.7.0 // indirect
162163
github.com/go-chi/chi v4.1.2+incompatible // indirect
163164
github.com/go-ini/ini v1.67.0 // indirect
165+
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
164166
github.com/go-kit/log v0.2.1 // indirect
165167
github.com/go-logfmt/logfmt v0.5.1 // indirect
166168
github.com/go-logr/logr v1.4.1 // indirect
@@ -192,7 +194,7 @@ require (
192194
github.com/googleapis/gax-go/v2 v2.12.4 // indirect
193195
github.com/gorilla/mux v1.8.1 // indirect
194196
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
195-
github.com/hashicorp/vault/api v1.12.2 // indirect
197+
github.com/hashicorp/vault/api v1.14.0 // indirect
196198
github.com/imdario/mergo v0.3.16 // indirect
197199
github.com/in-toto/in-toto-golang v0.9.0 // indirect
198200
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -242,10 +244,11 @@ require (
242244
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
243245
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
244246
github.com/thales-e-security/pool v0.0.2 // indirect
247+
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 // indirect
245248
github.com/tjfoc/gmsm v1.4.1 // indirect
246249
github.com/transparency-dev/merkle v0.0.2 // indirect
247250
github.com/vbatts/tar-split v0.11.5 // indirect
248-
github.com/xanzy/go-gitlab v0.103.0 // indirect
251+
github.com/xanzy/go-gitlab v0.105.0 // indirect
249252
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
250253
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
251254
github.com/yashtewari/glob-intersection v0.2.0 // indirect

Diff for: go.sum

+18-12
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,8 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP
528528
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
529529
github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
530530
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
531-
github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE=
532-
github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE=
531+
github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU=
532+
github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk=
533533
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM=
534534
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
535535
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
732732
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
733733
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
734734
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
735+
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
736+
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
735737
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
736738
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
737-
github.com/sigstore/cosign/v2 v2.2.4 h1:iY4vtEacmu2hkNj1Fh+8EBqBwKs2DHM27/lbNWDFJro=
738-
github.com/sigstore/cosign/v2 v2.2.4/go.mod h1:JZlRD2uaEjVAvZ1XJ3QkkZJhTqSDVtLaet+C/TMR81Y=
739+
github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c h1:boQtk23mqEBMNmnEqgy7HOlCCT8mQCTxtduJzxSRjTs=
740+
github.com/sigstore/cosign/v2 v2.2.5-0.20240513173329-121115774e8c/go.mod h1:sZCaRMNL7abS0Rs1+Wedk+izweNpKYniCusLdoywgf8=
739741
github.com/sigstore/fulcio v1.4.5 h1:WWNnrOknD0DbruuZWCbN+86WRROpEl3Xts+WT2Ek1yc=
740742
github.com/sigstore/fulcio v1.4.5/go.mod h1:oz3Qwlma8dWcSS/IENR/6SjbW4ipN0cxpRVfgdsjMU8=
741743
github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWwQvORuRQo=
@@ -746,14 +748,16 @@ github.com/sigstore/scaffolding v0.7.1 h1:oeOwZEzBjGrMGCmGJxCU9qmtbfreLIDMixlC0a
746748
github.com/sigstore/scaffolding v0.7.1/go.mod h1:1QBaVStYud8AwzUkQez16k+o8FYyjWAxi5YUNKyn3SQ=
747749
github.com/sigstore/sigstore v1.8.3 h1:G7LVXqL+ekgYtYdksBks9B38dPoIsbscjQJX/MGWkA4=
748750
github.com/sigstore/sigstore v1.8.3/go.mod h1:mqbTEariiGA94cn6G3xnDiV6BD8eSLdL/eA7bvJ0fVs=
751+
github.com/sigstore/sigstore-go v0.3.0 h1:SxYqfonBrEhw8bNDelMieymxhdv7R9itiNZmtjOwKKU=
752+
github.com/sigstore/sigstore-go v0.3.0/go.mod h1:oJOH7UP8aTjAGnIVwq9sDif8M4CSCik84yN1vBuESbE=
749753
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 h1:okxaVlaTrQowE1FA4UQ3rw54f7BUjdnzERIxbZTBZuc=
750754
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4/go.mod h1:jkcPErmnCECuSJajUaUq5pwCMOeBF19VzQo6bv4l1D0=
751-
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 h1:xgbPRCr2npmmsuVVteJqi/ERw9+I13Wou7kq0Yk4D8g=
752-
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3/go.mod h1:G4+I83FILPX6MtnoaUdmv/bRGEVtR3JdLeJa/kXdk/0=
755+
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4 h1:1G6uLTZaqvu867DbgH7p75L6Y7Tu8LLnYJGZnWsTUu8=
756+
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.4/go.mod h1:QtKKb8DChi1mRi9xSNr8ImSQu6m+0MZAV0sYIoPOta0=
753757
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 h1:fjnDR5Lw9ElfOSRUGKkgwjaynqj93nLu0twAw+QxhHE=
754758
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4/go.mod h1:9KFn5MwelyNoFXu3gNyVzvN/yAhcL6FE053oxih9+vM=
755-
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 h1:h9G8j+Ds21zqqulDbA/R/ft64oQQIyp8S7wJYABYSlg=
756-
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3/go.mod h1:zgCeHOuqF6k7A7TTEvftcA9V3FRzB7mrPtHOhXAQBnc=
759+
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 h1:QEXOb+feQmNOyLVT+FrghBqKKK4QDMP5dyic8RZHXdE=
760+
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4/go.mod h1:ohOhV9zclcIpNAWS0kq2ASB3EPPuRce2HjgXXaU3pKQ=
757761
github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE=
758762
github.com/sigstore/timestamp-authority v1.2.2/go.mod h1:nEah4Eq4wpliDjlY342rXclGSO7Kb9hoRrl9tqLW13A=
759763
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
810814
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
811815
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
812816
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
817+
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 h1:27XWhDZHPD+cufF6qSdYx6PgGQvD2jJ6pq9sDvR6VBk=
818+
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63/go.mod h1:+gWwqe1pk4nvGeOKosGJqPgD+N/kbD9M0QVLL9TGIYU=
813819
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
814820
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
815821
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
819825
github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
820826
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
821827
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
822-
github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w=
823-
github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
828+
github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM=
829+
github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
824830
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
825831
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
826832
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
867873
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
868874
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
869875
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
870-
go.step.sm/crypto v0.44.2 h1:t3p3uQ7raP2jp2ha9P6xkQF85TJZh+87xmjSLaib+jk=
871-
go.step.sm/crypto v0.44.2/go.mod h1:x1439EnFhadzhkuaGX7sz03LEMQ+jV4gRamf5LCZJQQ=
876+
go.step.sm/crypto v0.44.8 h1:jDSHL6FdB1UTA0d56ECNx9XtLVkewzeg38Vy3HWB3N8=
877+
go.step.sm/crypto v0.44.8/go.mod h1:QEmu4T9YewrDuaJnrV1I0zWZ15aJ/mqRUfL5w3R2WgU=
872878
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
873879
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
874880
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=

Diff for: pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go

+4
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ type Authority struct {
144144
// RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance.
145145
// +optional
146146
RFC3161Timestamp *RFC3161Timestamp `json:"rfc3161timestamp,omitempty"`
147+
// SignatureFormat specifies the format the authority expects. Supported
148+
// formats are "simplesigning" and "bundle". If not specified, the default
149+
// is "simplesigning" (cosign's default).
150+
SignatureFormat string `json:"signatureFormat,omitempty"`
147151
}
148152

149153
// This references a public verification key stored in

Diff for: pkg/apis/policy/v1beta1/clusterimagepolicy_types.go

+4
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ type Authority struct {
143143
// RFC3161Timestamp sets the configuration to verify the signature timestamp against a RFC3161 time-stamping instance.
144144
// +optional
145145
RFC3161Timestamp *RFC3161Timestamp `json:"rfc3161timestamp,omitempty"`
146+
// SignatureFormat specifies the format the authority expects. Supported
147+
// formats are "simplesigning" and "bundle". If not specified, the default
148+
// is "simplesigning" (cosign's default).
149+
SignatureFormat string `json:"signatureFormat,omitempty"`
146150
}
147151

148152
// This references a public verification key stored in

Diff for: pkg/tuf/repo.go

+31
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ import (
2828
"path/filepath"
2929
"runtime"
3030
"strings"
31+
"sync"
3132
"testing/fstest"
3233
"time"
3334

35+
"github.com/sigstore/sigstore-go/pkg/root"
36+
"github.com/sigstore/sigstore/pkg/tuf"
3437
"github.com/theupdateframework/go-tuf/client"
3538
"sigs.k8s.io/release-utils/version"
3639
)
@@ -288,3 +291,31 @@ func ClientFromRemote(_ context.Context, mirror string, rootJSON []byte, targets
288291
}
289292
return tufClient, nil
290293
}
294+
295+
var (
296+
once sync.Once
297+
trustedRoot *root.TrustedRoot
298+
singletonRootError error
299+
)
300+
301+
// GetTrustedRoot returns the trusted root for the TUF repository.
302+
func GetTrustedRoot() (*root.TrustedRoot, error) {
303+
once.Do(func() {
304+
tufClient, err := tuf.NewFromEnv(context.Background())
305+
if err != nil {
306+
singletonRootError = fmt.Errorf("initializing tuf: %w", err)
307+
return
308+
}
309+
// TODO: add support for custom trusted root path
310+
targetBytes, err := tufClient.GetTarget("trusted_root.json")
311+
if err != nil {
312+
singletonRootError = fmt.Errorf("error getting targets: %w", err)
313+
return
314+
}
315+
trustedRoot, singletonRootError = root.NewTrustedRootFromJSON(targetBytes)
316+
})
317+
if singletonRootError != nil {
318+
return nil, singletonRootError
319+
}
320+
return trustedRoot, nil
321+
}

Diff for: pkg/webhook/bundle.go

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package webhook
2+
3+
import (
4+
"crypto/x509"
5+
"encoding/hex"
6+
"encoding/json"
7+
"errors"
8+
"fmt"
9+
"io"
10+
"strings"
11+
12+
"github.com/google/go-containerregistry/pkg/name"
13+
v1 "github.com/google/go-containerregistry/pkg/v1"
14+
"github.com/google/go-containerregistry/pkg/v1/remote"
15+
16+
"github.com/sigstore/sigstore-go/pkg/bundle"
17+
"github.com/sigstore/sigstore-go/pkg/root"
18+
"github.com/sigstore/sigstore-go/pkg/verify"
19+
)
20+
21+
type VerifiedBundle struct {
22+
SGBundle *bundle.ProtobufBundle
23+
Result *verify.VerificationResult
24+
Hash v1.Hash
25+
}
26+
27+
// VerifiedBundle implements Signature
28+
var _ Signature = &VerifiedBundle{}
29+
30+
func (vb *VerifiedBundle) Digest() (v1.Hash, error) {
31+
return vb.Hash, nil
32+
}
33+
34+
func (vb *VerifiedBundle) Payload() ([]byte, error) {
35+
// todo: this should return the json-serialized dsse envelope
36+
envelope := vb.SGBundle.GetDsseEnvelope()
37+
if envelope == nil {
38+
return nil, fmt.Errorf("no dsse envelope found")
39+
}
40+
return json.Marshal(envelope)
41+
}
42+
43+
func (vb *VerifiedBundle) Signature() ([]byte, error) {
44+
// TODO: implement this
45+
return []byte{}, nil
46+
}
47+
48+
func (vb *VerifiedBundle) Cert() (*x509.Certificate, error) {
49+
vc, err := vb.SGBundle.VerificationContent()
50+
if err != nil {
51+
return nil, err
52+
}
53+
if cert, ok := vc.HasCertificate(); ok {
54+
return &cert, nil
55+
}
56+
return nil, errors.New("bundle does not contain a certificate")
57+
}
58+
59+
func VerifiedBundles(ref name.Reference, trustedMaterial root.TrustedMaterial, remoteOpts []remote.Option, policyOptions []verify.PolicyOption, verifierOptions []verify.VerifierOption) ([]Signature, error) {
60+
sev, err := verify.NewSignedEntityVerifier(trustedMaterial, verifierOptions...)
61+
if err != nil {
62+
return nil, err
63+
}
64+
65+
bundles, hash, err := getBundles(ref, remoteOpts)
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
digestBytes, err := hex.DecodeString(hash.Hex)
71+
if err != nil {
72+
return nil, err
73+
}
74+
artifactPolicy := verify.WithArtifactDigest(hash.Algorithm, digestBytes)
75+
policy := verify.NewPolicy(artifactPolicy, policyOptions...)
76+
77+
verifiedBundles := make([]Signature, 0)
78+
for _, b := range bundles {
79+
// TODO: should these be done in parallel? (as is done in cosign?)
80+
result, err := sev.Verify(b, policy)
81+
if err == nil {
82+
verifiedBundles = append(verifiedBundles, &VerifiedBundle{SGBundle: b, Result: result, Hash: *hash})
83+
}
84+
}
85+
return verifiedBundles, nil
86+
}
87+
88+
func getBundles(ref name.Reference, remoteOpts []remote.Option) ([]*bundle.ProtobufBundle, *v1.Hash, error) {
89+
desc, err := remote.Get(ref, remoteOpts...)
90+
if err != nil {
91+
return nil, nil, fmt.Errorf("error getting image descriptor: %w", err)
92+
}
93+
94+
digest := ref.Context().Digest(desc.Digest.String())
95+
96+
referrers, err := remote.Referrers(digest, remoteOpts...)
97+
if err != nil {
98+
return nil, nil, fmt.Errorf("error getting referrers: %w", err)
99+
}
100+
refManifest, err := referrers.IndexManifest()
101+
if err != nil {
102+
return nil, nil, fmt.Errorf("error getting referrers manifest: %w", err)
103+
}
104+
105+
bundles := make([]*bundle.ProtobufBundle, 0)
106+
107+
for _, refDesc := range refManifest.Manifests {
108+
if !strings.HasPrefix(refDesc.ArtifactType, "application/vnd.dev.sigstore.bundle") {
109+
continue
110+
}
111+
112+
refImg, err := remote.Image(ref.Context().Digest(refDesc.Digest.String()), remoteOpts...)
113+
if err != nil {
114+
return nil, nil, fmt.Errorf("error getting referrer image: %w", err)
115+
}
116+
layers, err := refImg.Layers()
117+
if err != nil {
118+
return nil, nil, fmt.Errorf("error getting referrer image: %w", err)
119+
}
120+
layer0, err := layers[0].Uncompressed()
121+
if err != nil {
122+
return nil, nil, fmt.Errorf("error getting referrer image: %w", err)
123+
}
124+
bundleBytes, err := io.ReadAll(layer0)
125+
if err != nil {
126+
return nil, nil, fmt.Errorf("error getting referrer image: %w", err)
127+
}
128+
b := &bundle.ProtobufBundle{}
129+
err = b.UnmarshalJSON(bundleBytes)
130+
if err != nil {
131+
return nil, nil, fmt.Errorf("error unmarshalling bundle: %w", err)
132+
}
133+
bundles = append(bundles, b)
134+
}
135+
if len(bundles) == 0 {
136+
return nil, nil, fmt.Errorf("no bundle found in referrers")
137+
}
138+
return bundles, &desc.Digest, nil
139+
}

0 commit comments

Comments
 (0)