Skip to content

Commit

Permalink
Add support for Sigstore Bundles using sigstore-go verifier (#151)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
codysoyland and malancas authored Jun 3, 2024
1 parent af217e4 commit 00470e1
Show file tree
Hide file tree
Showing 16 changed files with 746 additions and 30 deletions.
6 changes: 6 additions & 0 deletions config/300-clusterimagepolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/api-types/index-v1alpha1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
1 change: 1 addition & 0 deletions docs/api-types/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
13 changes: 8 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
30 changes: 18 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand All @@ -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=
Expand Down Expand Up @@ -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=
Expand All @@ -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=
Expand Down Expand Up @@ -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=
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/policy/v1alpha1/clusterimagepolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/policy/v1beta1/clusterimagepolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions pkg/tuf/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
}
139 changes: 139 additions & 0 deletions pkg/webhook/bundle.go
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit 00470e1

Please sign in to comment.