mirror of
https://github.com/slsa-framework/slsa-verifier.git
synced 2026-05-09 10:06:37 +00:00
feat: add slsa v1?draft provenance experimental support (#470)
* feat: add slsa v1?draft provenance support Signed-off-by: Asra Ali <asraa@google.com> Signed-off-by: Asra Ali <asraa@google.com>
This commit is contained in:
@@ -16,7 +16,6 @@ func check(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:deadcode
|
||||
func ExperimentalEnabled() bool {
|
||||
return os.Getenv("SLSA_VERIFIER_EXPERIMENTAL") == "1"
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ func verifyArtifactCmd() *cobra.Command {
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
v := verify.VerifyArtifactCommand{
|
||||
ProvenancePath: o.ProvenancePath,
|
||||
BundlePath: o.BundlePath,
|
||||
SourceURI: o.SourceURI,
|
||||
PrintProvenance: o.PrintProvenance,
|
||||
BuildWorkflowInputs: o.BuildWorkflowInputs.AsMap(),
|
||||
@@ -60,6 +61,21 @@ func verifyArtifactCmd() *cobra.Command {
|
||||
v.BuilderID = &o.BuilderID
|
||||
}
|
||||
|
||||
// In experimental mode, we allow either provenance or bundle path, but exactly
|
||||
// one must be set. We already check to ensure that they are mutually exclusive.
|
||||
if ExperimentalEnabled() {
|
||||
if !(cmd.Flags().Changed("provenance-path") ||
|
||||
cmd.Flags().Changed("bundle-path")) {
|
||||
fmt.Fprintf(os.Stderr, "%s\n%s", cmd.UsageString(),
|
||||
"exactly one of --provenance-path or --bundle-path must be supplied")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else if !cmd.Flags().Changed("provenance-path") {
|
||||
// --provenance-path must be set.
|
||||
fmt.Fprintf(os.Stderr, "%s\n%s\n", cmd.UsageString(), "--provenance-path must be supplied")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if _, err := v.Exec(cmd.Context(), args); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s: %v\n", FAILURE, err)
|
||||
os.Exit(1)
|
||||
@@ -70,7 +86,6 @@ func verifyArtifactCmd() *cobra.Command {
|
||||
}
|
||||
|
||||
o.AddFlags(cmd)
|
||||
cmd.MarkFlagRequired("provenance-path")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ type VerifyOptions struct {
|
||||
BuilderID string
|
||||
/* Other */
|
||||
ProvenancePath string
|
||||
BundlePath string
|
||||
PrintProvenance bool
|
||||
}
|
||||
|
||||
@@ -67,11 +68,17 @@ func (o *VerifyOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVar(&o.ProvenancePath, "provenance-path", "",
|
||||
"path to a provenance file")
|
||||
|
||||
cmd.Flags().StringVar(&o.BundlePath, "bundle-path", "",
|
||||
"path to a Sigstore provenance bundle file containing offline information.")
|
||||
|
||||
cmd.Flags().BoolVar(&o.PrintProvenance, "print-provenance", false,
|
||||
"[optional] print the verified provenance to stdout")
|
||||
|
||||
cmd.MarkFlagRequired("source-uri")
|
||||
cmd.MarkFlagsMutuallyExclusive("source-versioned-tag", "source-tag")
|
||||
|
||||
// Enforce exactly one of --provenance-path and --bundle-path.
|
||||
cmd.MarkFlagsMutuallyExclusive("provenance-path", "bundle-path")
|
||||
}
|
||||
|
||||
type workflowInputs struct {
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
// Note: nil branch, tag, version-tag and builder-id means we ignore them during verification.
|
||||
type VerifyArtifactCommand struct {
|
||||
ProvenancePath string
|
||||
BundlePath string
|
||||
BuilderID *string
|
||||
SourceURI string
|
||||
SourceBranch *string
|
||||
@@ -62,10 +63,20 @@ func (c *VerifyArtifactCommand) Exec(ctx context.Context, artifacts []string) (*
|
||||
ExpectedID: c.BuilderID,
|
||||
}
|
||||
|
||||
provenance, err := os.ReadFile(c.ProvenancePath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Verifying artifact %s: FAILED: %v\n\n", artifact, err)
|
||||
return nil, err
|
||||
var provenance []byte
|
||||
if c.ProvenancePath != "" {
|
||||
provenance, err = os.ReadFile(c.ProvenancePath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Verifying artifact %s: FAILED: %v\n\n", artifact, err)
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
bundle, err := os.ReadFile(c.BundlePath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Verifying artifact %s: FAILED: %v\n\n", artifact, err)
|
||||
return nil, err
|
||||
}
|
||||
provenanceOpts.ProvenanceBundle = bundle
|
||||
}
|
||||
|
||||
verifiedProvenance, outBuilderID, err := verifiers.VerifyArtifact(ctx, provenance, artifactHash, provenanceOpts, builderOpts)
|
||||
|
||||
29
go.mod
29
go.mod
@@ -7,7 +7,7 @@ require (
|
||||
github.com/go-openapi/runtime v0.25.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/trillian v1.5.1-0.20220819043421-0a389c4bb8d9 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.6.0
|
||||
github.com/in-toto/in-toto-golang v0.6.1-0.20230207212643-96dcb8c596fb
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0
|
||||
github.com/sigstore/rekor v1.0.1
|
||||
github.com/sigstore/sigstore v1.5.1
|
||||
@@ -23,21 +23,24 @@ require (
|
||||
github.com/slsa-framework/slsa-github-generator v1.4.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/transparency-dev/merkle v0.0.1
|
||||
golang.org/x/mod v0.7.0
|
||||
golang.org/x/mod v0.8.0
|
||||
sigs.k8s.io/release-utils v0.7.3
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/digitorus/pkcs7 v0.0.0-20221212123742-001c36b64ec3 // indirect
|
||||
github.com/digitorus/timestamp v0.0.0-20221019182153-ef3b63b79b31 // indirect
|
||||
github.com/sigstore/timestamp-authority v0.2.1 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.1.2 // indirect
|
||||
github.com/zeebo/errs v1.3.0 // indirect
|
||||
go.step.sm/crypto v0.23.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
bitbucket.org/creachadair/shell v0.0.7 // indirect
|
||||
cloud.google.com/go/compute v1.14.0 // indirect
|
||||
cloud.google.com/go/compute v1.15.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v67.3.0+incompatible // indirect
|
||||
@@ -82,12 +85,12 @@ require (
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.5.6 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b // indirect
|
||||
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.12.1 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.5.0 // indirect
|
||||
@@ -102,8 +105,8 @@ require (
|
||||
github.com/docker/docker v20.10.21+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.10.3 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/fullstorydev/grpcurl v1.8.7 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
@@ -144,7 +147,7 @@ require (
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect
|
||||
github.com/jhump/protoreflect v1.14.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
@@ -234,14 +237,14 @@ require (
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/oauth2 v0.4.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/term v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect
|
||||
google.golang.org/grpc v1.52.3 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
|
||||
41
go.sum
41
go.sum
@@ -56,6 +56,8 @@ cloud.google.com/go/compute v1.13.0 h1:AYrLkB8NPdDRslNp4Jxmzrhdr03fUAIDbiGFjLWow
|
||||
cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
|
||||
cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0=
|
||||
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
|
||||
cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE=
|
||||
cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=
|
||||
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/compute/metadata v0.2.2 h1:aWKAjYaBaOSrpKl57+jnS/3fJRQnxL7TvR/u1VVbt6k=
|
||||
cloud.google.com/go/compute/metadata v0.2.2/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
|
||||
@@ -156,6 +158,8 @@ github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0
|
||||
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
@@ -366,6 +370,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
@@ -373,6 +379,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 h1:XlpL9EHrPOBJMLDDOf35/G4t5rGAFNNAZQ3cDcWavtc=
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21/go.mod h1:Zlre/PVxuSI9y6/UV4NwGixQ48RHQDSPiUkofr6rbMU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@@ -387,6 +395,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
@@ -394,6 +404,9 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 h1:KwaoQzs/WeUxxJqiJsZ4euOly1Az/IgZXXSxlD/UBNk=
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b h1:ACGZRIr7HsgBKHsueQ1yM4WaVaXh21ynwqsF8M8tXhA=
|
||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||
@@ -492,10 +505,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/go-control-plane v0.10.3 h1:xdCVXxEe0Y3FQith+0cj2irwZudqGYvecuLB1HtdexY=
|
||||
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2 h1:JiO+kJTpmYGjEodY7O1Zk8oZcNz1+f30UtwtXoFUPzE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=
|
||||
@@ -899,9 +917,15 @@ github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF
|
||||
github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE=
|
||||
github.com/in-toto/in-toto-golang v0.6.0 h1:1s7cyzb5zGyzKPLgFsi4sC0o3EA24HLKlne8BrnOrSc=
|
||||
github.com/in-toto/in-toto-golang v0.6.0/go.mod h1:NaFLcsxtvZgbwQpyHwK8MlDXN9b+NuOMXqeIqxzfBoA=
|
||||
github.com/in-toto/in-toto-golang v0.6.1-0.20230207163334-3493691c6d9c h1:d50sx5hkklYL5PkZrxtg4TAM1yfjykNw5p0AgDW2cq8=
|
||||
github.com/in-toto/in-toto-golang v0.6.1-0.20230207163334-3493691c6d9c/go.mod h1:AoOsIJkpD8RHrZIAQxXqhGPm7M38IzT4JAdgPpf4OZc=
|
||||
github.com/in-toto/in-toto-golang v0.6.1-0.20230207212643-96dcb8c596fb h1:lUoNEu/QPf8P52025Pk46e5godp1uRUzSJ3CQknuFdE=
|
||||
github.com/in-toto/in-toto-golang v0.6.1-0.20230207212643-96dcb8c596fb/go.mod h1:AoOsIJkpD8RHrZIAQxXqhGPm7M38IzT4JAdgPpf4OZc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
@@ -990,6 +1014,7 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/linkedin/goavro v2.1.0+incompatible/go.mod h1:bBCwI2eGYpUI/4820s67MElg9tdeLbINjLjiM2xZFYM=
|
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -1235,6 +1260,7 @@ github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XF
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -1349,6 +1375,8 @@ github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
|
||||
github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
|
||||
github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
|
||||
github.com/spiffe/go-spiffe/v2 v2.1.2 h1:nfNwopOP7q0qsWU6AUASqmbtYViwHA6vuHyAtqFJtNc=
|
||||
github.com/spiffe/go-spiffe/v2 v2.1.2/go.mod h1:cbQmFrxsOpbm5tWURAYip9ZK0dOSFeoFG3/5Ub9Hvy0=
|
||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@@ -1447,6 +1475,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0=
|
||||
github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
|
||||
github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
@@ -1548,6 +1578,7 @@ go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48
|
||||
go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
|
||||
go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E=
|
||||
go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.step.sm/crypto v0.23.1 h1:Yr9vlzjGqIKVi88KcpZtEcNTcpDkt1nVR7tumW4h+CU=
|
||||
@@ -1665,6 +1696,8 @@ golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1911,6 +1944,8 @@ golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -2031,6 +2066,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4=
|
||||
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -2190,6 +2226,7 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2
|
||||
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
@@ -2210,6 +2247,8 @@ google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqd
|
||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||
google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa h1:qQPhfbPO23fwm/9lQr91L1u62Zo6cm+zI+slZT+uf+o=
|
||||
google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||
google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 h1:vArvWooPH749rNHpBGgVl+U9B9dATjiEhJzcWGlovNs=
|
||||
google.golang.org/genproto v0.0.0-20230202175211-008b39050e57/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@@ -2258,6 +2297,8 @@ google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
|
||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.52.3 h1:pf7sOysg4LdgBqduXveGKrcEwbStiK2rtfghdzlUYDQ=
|
||||
google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
||||
@@ -23,6 +23,9 @@ type ProvenanceOpts struct {
|
||||
|
||||
// ExpectedWorkflowInputs is a map of key=value inputs.
|
||||
ExpectedWorkflowInputs map[string]string
|
||||
|
||||
// Bundle containing information to verify the provenance offline.
|
||||
ProvenanceBundle []byte
|
||||
}
|
||||
|
||||
// BuildOpts are the options for checking the builder.
|
||||
|
||||
@@ -18,9 +18,11 @@ import (
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/options"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/utils"
|
||||
|
||||
// Load provenance types.
|
||||
_ "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v0.2"
|
||||
_ "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v1.0"
|
||||
)
|
||||
|
||||
// SignedAttestation contains a signed DSSE envelope
|
||||
@@ -240,25 +242,14 @@ func VerifyProvenance(env *dsselib.Envelope, provenanceOpts *options.ProvenanceO
|
||||
}
|
||||
|
||||
func VerifyWorkflowInputs(prov slsaprovenance.Provenance, inputs map[string]string) error {
|
||||
// Verify it's a workflow_dispatch trigger.
|
||||
triggerName, err := prov.GetStringFromEnvironment("github_event_name")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if triggerName != "workflow_dispatch" {
|
||||
return fmt.Errorf("%w: expected 'workflow_dispatch' trigger, got %s",
|
||||
serrors.ErrorMismatchWorkflowInputs, triggerName)
|
||||
}
|
||||
|
||||
// Assume no nested level.
|
||||
pyldInputs, err := prov.GetInputs()
|
||||
pyldInputs, err := prov.GetWorkflowInputs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Verify all inputs.
|
||||
for k, v := range inputs {
|
||||
value, err := getAsString(pyldInputs, k)
|
||||
value, err := utils.GetAsString(pyldInputs, k)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: cannot retrieve value of '%s'", serrors.ErrorMismatchWorkflowInputs, k)
|
||||
}
|
||||
@@ -273,7 +264,7 @@ func VerifyWorkflowInputs(prov slsaprovenance.Provenance, inputs map[string]stri
|
||||
}
|
||||
|
||||
func VerifyBranch(prov slsaprovenance.Provenance, expectedBranch string) error {
|
||||
branch, err := getBranch(prov)
|
||||
branch, err := prov.GetBranch()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -287,7 +278,7 @@ func VerifyBranch(prov slsaprovenance.Provenance, expectedBranch string) error {
|
||||
}
|
||||
|
||||
func VerifyTag(prov slsaprovenance.Provenance, expectedTag string) error {
|
||||
tag, err := getTag(prov)
|
||||
tag, err := prov.GetTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -310,7 +301,7 @@ func VerifyVersionedTag(prov slsaprovenance.Provenance, expectedTag string) erro
|
||||
// Note: prerelease is validated as part of patch validation
|
||||
// and must be equal. Build is discarded as per https://semver.org/:
|
||||
// "Build metadata MUST be ignored when determining version precedence",
|
||||
tag, err := getTag(prov)
|
||||
tag, err := prov.GetTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -379,166 +370,6 @@ func extractFromVersion(v string, i int) (string, error) {
|
||||
return parts[i], nil
|
||||
}
|
||||
|
||||
func getAsAny(payload map[string]any, field string) (any, error) {
|
||||
value, ok := payload[field]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("payload type for %s", field))
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func getAsString(pyld map[string]interface{}, field string) (string, error) {
|
||||
value, ok := pyld[field]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("environment type for %s", field))
|
||||
}
|
||||
|
||||
i, ok := value.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s '%s'", serrors.ErrorInvalidDssePayload, "environment type string", field)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func getEventPayload(prov slsaprovenance.Provenance) (map[string]interface{}, error) {
|
||||
eventPayload, err := prov.GetAnyFromEnvironment("github_event_payload")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
payload, ok := eventPayload.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type payload")
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
func getBaseRef(prov slsaprovenance.Provenance) (string, error) {
|
||||
baseRef, err := prov.GetStringFromEnvironment("github_base_ref")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// This `base_ref` seems to always be "".
|
||||
if baseRef != "" {
|
||||
return baseRef, nil
|
||||
}
|
||||
|
||||
// Look at the event payload instead.
|
||||
// We don't do that for all triggers because the payload
|
||||
// is event-specific; and only the `push` event seems to have a `base_ref`.
|
||||
eventName, err := prov.GetStringFromEnvironment("github_event_name")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if eventName != "push" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
payload, err := getEventPayload(prov)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
value, err := getAsAny(payload, "base_ref")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// The `base_ref` field may be nil if the build was from
|
||||
// a specific commit rather than a branch.
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func getTargetCommittish(prov slsaprovenance.Provenance) (string, error) {
|
||||
eventName, err := prov.GetStringFromEnvironment("github_event_name")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if eventName != "release" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
payload, err := getEventPayload(prov)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// For a release event, we look for release.target_commitish.
|
||||
releasePayload, ok := payload["release"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "release absent from payload")
|
||||
}
|
||||
|
||||
release, ok := releasePayload.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type releasePayload")
|
||||
}
|
||||
|
||||
branch, err := getAsString(release, "target_commitish")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: %s", err, "target_commitish not present")
|
||||
}
|
||||
|
||||
return "refs/heads/" + branch, nil
|
||||
}
|
||||
|
||||
func getBranchForTag(prov slsaprovenance.Provenance) (string, error) {
|
||||
// First try the base_ref.
|
||||
branch, err := getBaseRef(prov)
|
||||
if branch != "" || err != nil {
|
||||
return branch, err
|
||||
}
|
||||
|
||||
// Second try the target comittish.
|
||||
return getTargetCommittish(prov)
|
||||
}
|
||||
|
||||
// Get tag from the provenance invocation parameters.
|
||||
func getTag(prov slsaprovenance.Provenance) (string, error) {
|
||||
refType, err := prov.GetStringFromEnvironment("github_ref_type")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch refType {
|
||||
case "branch":
|
||||
return "", nil
|
||||
case "tag":
|
||||
return prov.GetStringFromEnvironment("github_ref")
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s %s", serrors.ErrorInvalidDssePayload,
|
||||
"unknown ref type", refType)
|
||||
}
|
||||
}
|
||||
|
||||
// Get branch from the provenance invocation parameters.
|
||||
func getBranch(prov slsaprovenance.Provenance) (string, error) {
|
||||
refType, err := prov.GetStringFromEnvironment("github_ref_type")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch refType {
|
||||
case "branch":
|
||||
return prov.GetStringFromEnvironment("github_ref")
|
||||
case "tag":
|
||||
return getBranchForTag(prov)
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s %s", serrors.ErrorInvalidDssePayload,
|
||||
"unknown ref type", refType)
|
||||
}
|
||||
}
|
||||
|
||||
// hasCertInEnvelope checks if a valid x509 certificate is present in the
|
||||
// envelope.
|
||||
func hasCertInEnvelope(provenance []byte) bool {
|
||||
|
||||
@@ -9,10 +9,12 @@ import (
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
slsacommon "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
|
||||
slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
|
||||
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1.0"
|
||||
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance"
|
||||
v02 "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v0.2"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v1.0"
|
||||
)
|
||||
|
||||
func provenanceFromBytes(payload []byte) (slsaprovenance.Provenance, error) {
|
||||
@@ -79,6 +81,58 @@ func Test_VerifySha256Subject(t *testing.T) {
|
||||
artifactHash: "04e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorMismatchHash,
|
||||
},
|
||||
{
|
||||
name: "slsa 1.0 invalid dsse: not SLSA predicate",
|
||||
path: "./testdata/dsse-not-slsa-v1.intoto.jsonl",
|
||||
artifactHash: "0ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorInvalidDssePayload,
|
||||
},
|
||||
|
||||
{
|
||||
name: "invalid dsse: nil subject",
|
||||
path: "./testdata/dsse-no-subject-v1.intoto.jsonl",
|
||||
artifactHash: "0ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorInvalidDssePayload,
|
||||
},
|
||||
|
||||
{
|
||||
name: "invalid dsse: no sha256 subject digest",
|
||||
path: "./testdata/dsse-no-subject-hash-v1.intoto.jsonl",
|
||||
artifactHash: "0ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorInvalidDssePayload,
|
||||
},
|
||||
{
|
||||
name: "mismatched artifact hash with env",
|
||||
path: "./testdata/dsse-valid-v1.intoto.jsonl",
|
||||
artifactHash: "1ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorMismatchHash,
|
||||
},
|
||||
|
||||
{
|
||||
name: "valid entry",
|
||||
path: "./testdata/dsse-valid-v1.intoto.jsonl",
|
||||
artifactHash: "0ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "valid entry multiple subjects last entry",
|
||||
path: "./testdata/dsse-valid-multi-subjects-v1.intoto.jsonl",
|
||||
artifactHash: "03e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "valid multiple subjects second entry",
|
||||
path: "./testdata/dsse-valid-multi-subjects-v1.intoto.jsonl",
|
||||
artifactHash: "02e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "multiple subjects invalid hash",
|
||||
path: "./testdata/dsse-valid-multi-subjects-v1.intoto.jsonl",
|
||||
artifactHash: "04e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
|
||||
expected: serrors.ErrorMismatchHash,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt // Re-initializing variable so it is not changed while executing the closure below
|
||||
@@ -109,6 +163,8 @@ func Test_verifySourceURI(t *testing.T) {
|
||||
prov *intoto.ProvenanceStatement
|
||||
sourceURI string
|
||||
expected error
|
||||
// v1 provenance does not include materials
|
||||
skipv1 bool
|
||||
}{
|
||||
{
|
||||
name: "source has no @",
|
||||
@@ -137,6 +193,7 @@ func Test_verifySourceURI(t *testing.T) {
|
||||
},
|
||||
sourceURI: "git+https://github.com/some/repo",
|
||||
expected: serrors.ErrorInvalidDssePayload,
|
||||
skipv1: true,
|
||||
},
|
||||
{
|
||||
name: "empty configSource",
|
||||
@@ -284,6 +341,7 @@ func Test_verifySourceURI(t *testing.T) {
|
||||
},
|
||||
},
|
||||
sourceURI: "git+https://github.com/some/repo",
|
||||
skipv1: true,
|
||||
expected: serrors.ErrorInvalidDssePayload,
|
||||
},
|
||||
{
|
||||
@@ -349,11 +407,32 @@ func Test_verifySourceURI(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
prov := &v02.ProvenanceV02{
|
||||
prov02 := &v02.ProvenanceV02{
|
||||
ProvenanceStatement: tt.prov,
|
||||
}
|
||||
|
||||
err := verifySourceURI(prov, tt.sourceURI)
|
||||
err := verifySourceURI(prov02, tt.sourceURI)
|
||||
if !errCmp(err, tt.expected) {
|
||||
t.Errorf(cmp.Diff(err, tt.expected))
|
||||
}
|
||||
|
||||
if tt.skipv1 {
|
||||
return
|
||||
}
|
||||
|
||||
// Update to v1 SLSA provenance.
|
||||
prov1 := &v1.ProvenanceV1{
|
||||
Predicate: slsa1.ProvenancePredicate{
|
||||
BuildDefinition: slsa1.ProvenanceBuildDefinition{
|
||||
ExternalParameters: map[string]interface{}{
|
||||
"source": slsa1.ArtifactReference{
|
||||
URI: tt.prov.Predicate.Invocation.ConfigSource.URI,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
err = verifySourceURI(prov1, tt.sourceURI)
|
||||
if !errCmp(err, tt.expected) {
|
||||
t.Errorf(cmp.Diff(err, tt.expected))
|
||||
}
|
||||
@@ -448,6 +527,22 @@ func Test_verifyBuilderIDExactMatch(t *testing.T) {
|
||||
if !errCmp(err, tt.expected) {
|
||||
t.Errorf(cmp.Diff(err, tt.expected))
|
||||
}
|
||||
|
||||
// Update to v1 SLSA provenance.
|
||||
prov1 := &v1.ProvenanceV1{
|
||||
Predicate: slsa1.ProvenancePredicate{
|
||||
RunDetails: slsa1.ProvenanaceRunDetails{
|
||||
Builder: slsa1.Builder{
|
||||
ID: tt.prov.Predicate.Builder.ID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = verifyBuilderIDExactMatch(prov1, tt.id)
|
||||
if !errCmp(err, tt.expected) {
|
||||
t.Errorf(cmp.Diff(err, tt.expected))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,15 @@ type Provenance interface {
|
||||
// Subject is the list of intoto subjects in the provenance.
|
||||
Subjects() ([]intoto.Subject, error)
|
||||
|
||||
// GetStringFromEnvironment retrieves a string parameter from the environment
|
||||
// attested to in the provenance.
|
||||
GetStringFromEnvironment(name string) (string, error)
|
||||
// GetBranch retrieves the branch name of the source from the provenance.
|
||||
GetBranch() (string, error)
|
||||
|
||||
// GetAnyFromEnvironment retrieves an object parameter from the environment
|
||||
// attested to in the provenance.
|
||||
GetAnyFromEnvironment(name string) (interface{}, error)
|
||||
// GetTag retrieves the tag of the source from the provenance.
|
||||
GetTag() (string, error)
|
||||
|
||||
// GetInputs retrieves the inputs from the provenance. Only succeeds for event
|
||||
// GetWorkflowInputs retrieves the inputs from the provenance. Only succeeds for event
|
||||
// relevant event types (workflow_inputs).
|
||||
GetInputs() (map[string]interface{}, error)
|
||||
GetWorkflowInputs() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ProvenanceMap stores the different provenance version types.
|
||||
|
||||
@@ -6,9 +6,10 @@ import (
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/utils"
|
||||
)
|
||||
|
||||
// TODO(asraa): Use a static mapping.
|
||||
// TODO(https://github.com/slsa-framework/slsa-verifier/issues/473): Use a static mapping.
|
||||
//
|
||||
//nolint:gochecknoinits
|
||||
func init() {
|
||||
@@ -49,49 +50,74 @@ func (prov *ProvenanceV02) Subjects() ([]intoto.Subject, error) {
|
||||
return subj, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV02) GetStringFromEnvironment(name string) (string, error) {
|
||||
func (prov *ProvenanceV02) GetBranch() (string, error) {
|
||||
// GetBranch gets the branch from the invocation parameters.
|
||||
environment, ok := prov.Predicate.Invocation.Environment.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type")
|
||||
}
|
||||
val, ok := environment[name]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("environment type for %s", name))
|
||||
|
||||
refType, err := utils.GetAsString(environment, "github_ref_type")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
i, ok := val.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s '%s'", serrors.ErrorInvalidDssePayload, "environment type string", name)
|
||||
|
||||
switch refType {
|
||||
case "branch":
|
||||
return utils.GetAsString(environment, "github_ref")
|
||||
case "tag":
|
||||
return getBranchForTag(prov)
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s %s", serrors.ErrorInvalidDssePayload,
|
||||
"unknown ref type", refType)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV02) GetAnyFromEnvironment(name string) (interface{}, error) {
|
||||
func (prov *ProvenanceV02) GetTag() (string, error) {
|
||||
environment, ok := prov.Predicate.Invocation.Environment.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type")
|
||||
}
|
||||
val, ok := environment[name]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("environment type for %s", name))
|
||||
|
||||
refType, err := utils.GetAsString(environment, "github_ref_type")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch refType {
|
||||
case "branch":
|
||||
return "", nil
|
||||
case "tag":
|
||||
return utils.GetAsString(environment, "github_ref")
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s %s", serrors.ErrorInvalidDssePayload,
|
||||
"unknown ref type", refType)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV02) GetInputs() (map[string]interface{}, error) {
|
||||
eventPayload, err := prov.GetAnyFromEnvironment("github_event_payload")
|
||||
func (prov *ProvenanceV02) GetWorkflowInputs() (map[string]interface{}, error) {
|
||||
// Verify it's a workflow_dispatch trigger.
|
||||
environment, ok := prov.Predicate.Invocation.Environment.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type")
|
||||
}
|
||||
|
||||
triggerName, err := utils.GetAsString(environment, "github_event_name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if triggerName != "workflow_dispatch" {
|
||||
return nil, fmt.Errorf("%w: expected 'workflow_dispatch' trigger, got %s",
|
||||
serrors.ErrorMismatchWorkflowInputs, triggerName)
|
||||
}
|
||||
|
||||
payload, err := getEventPayload(environment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
payload, ok := eventPayload.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type payload")
|
||||
}
|
||||
|
||||
payloadInputs, ok := payload["inputs"]
|
||||
if !ok {
|
||||
payloadInputs, err := getAsAny(payload, "inputs")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: error retrieving 'inputs': %v", serrors.ErrorInvalidDssePayload, err)
|
||||
}
|
||||
|
||||
@@ -101,3 +127,94 @@ func (prov *ProvenanceV02) GetInputs() (map[string]interface{}, error) {
|
||||
}
|
||||
return pyldInputs, nil
|
||||
}
|
||||
|
||||
func getBranchForTag(prov *ProvenanceV02) (string, error) {
|
||||
// First try the base_ref.
|
||||
environment, ok := prov.Predicate.Invocation.Environment.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type")
|
||||
}
|
||||
|
||||
baseRef, err := utils.GetAsString(environment, "github_base_ref")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// This `base_ref` seems to always be "".
|
||||
if baseRef != "" {
|
||||
return baseRef, nil
|
||||
}
|
||||
|
||||
// Look at the event payload instead.
|
||||
eventName, err := utils.GetAsString(environment, "github_event_name")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
payload, err := getEventPayload(environment)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// We don't do that for all triggers because the payload
|
||||
// is event-specific. Only `push` events seem to have a `base_ref`, and
|
||||
// `release` events specify a branch in `target_commitish`.
|
||||
switch eventName {
|
||||
case "push":
|
||||
value, err := getAsAny(payload, "base_ref")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// The `base_ref` field may be nil if the build was from
|
||||
// a specific commit rather than a branch.
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
return v, nil
|
||||
case "release":
|
||||
// For a release event, we look for release.target_commitish.
|
||||
releasePayload, ok := payload["release"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "release absent from payload")
|
||||
}
|
||||
|
||||
release, ok := releasePayload.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type releasePayload")
|
||||
}
|
||||
|
||||
branch, err := utils.GetAsString(release, "target_commitish")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: %s", err, "target_commitish not present")
|
||||
}
|
||||
|
||||
return "refs/heads/" + branch, nil
|
||||
default:
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
|
||||
func getAsAny(environment map[string]any, field string) (any, error) {
|
||||
value, ok := environment[field]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("environment type for %s", field))
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func getEventPayload(environment map[string]any) (map[string]any, error) {
|
||||
eventPayload, ok := environment["github_event_payload"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type event payload")
|
||||
}
|
||||
|
||||
payload, ok := eventPayload.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "parameters type payload")
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
77
verifiers/internal/gha/slsaprovenance/v1.0/provenance.go
Normal file
77
verifiers/internal/gha/slsaprovenance/v1.0/provenance.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1.0"
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance"
|
||||
)
|
||||
|
||||
// TODO(https://github.com/slsa-framework/slsa-verifier/issues/473): Use a static mapping.
|
||||
//
|
||||
//nolint:gochecknoinits
|
||||
func init() {
|
||||
slsaprovenance.ProvenanceMap.Store(
|
||||
"https://slsa.dev/provenance/v1.0?draft",
|
||||
New)
|
||||
}
|
||||
|
||||
type ProvenanceV1 struct {
|
||||
intoto.StatementHeader
|
||||
Predicate slsa1.ProvenancePredicate `json:"predicate"`
|
||||
}
|
||||
|
||||
// This returns a new, empty instance of the v0.2 provenance.
|
||||
func New() slsaprovenance.Provenance {
|
||||
return &ProvenanceV1{}
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) BuilderID() (string, error) {
|
||||
return prov.Predicate.RunDetails.Builder.ID, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) SourceURI() (string, error) {
|
||||
extParams, ok := prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type")
|
||||
}
|
||||
source, ok := extParams["source"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters source")
|
||||
}
|
||||
sourceRef, ok := source.(slsa1.ArtifactReference)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters source type")
|
||||
}
|
||||
return sourceRef.URI, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) ConfigURI() (string, error) {
|
||||
// The source and config are the same for GHA provenance.
|
||||
return prov.SourceURI()
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) Subjects() ([]intoto.Subject, error) {
|
||||
subj := prov.Subject
|
||||
if len(subj) == 0 {
|
||||
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "no subjects")
|
||||
}
|
||||
return subj, nil
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) GetBranch() (string, error) {
|
||||
// TODO(https://github.com/slsa-framework/slsa-verifier/issues/472): Add GetBranch() support.
|
||||
return "", errors.New("unimplemented")
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) GetTag() (string, error) {
|
||||
// TODO(https://github.com/slsa-framework/slsa-verifier/issues/472): Add GetTag() support.
|
||||
return "", errors.New("unimplemented")
|
||||
}
|
||||
|
||||
func (prov *ProvenanceV1) GetWorkflowInputs() (map[string]interface{}, error) {
|
||||
return nil, errors.New("unimplemented")
|
||||
}
|
||||
10
verifiers/internal/gha/testdata/dsse-no-subject-hash-v1.intoto.jsonl
vendored
Normal file
10
verifiers/internal/gha/testdata/dsse-no-subject-hash-v1.intoto.jsonl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.in-toto+json",
|
||||
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGExIjogIjQ1MDYyOTBlMmU4ZmViMWYzNGIyN2EwNDRmN2NjODYzYzgzMGVmNmIiCiAgICAgIH0sCiAgICAgICJuYW1lIjogImJpbmFyeS1saW51eC1hbWQ2NCIKICAgIH0KICBdLAogICJwcmVkaWNhdGVUeXBlIjogImh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MS4wP2RyYWZ0IiwKICAicHJlZGljYXRlIjogewogICAgImJ1aWxkRGVmaW5pdGlvbiI6IHsKICAgICAgImJ1aWxkTm90U0xTQSI6ICJodHRwczovL2dpdGh1Yi5jb20vQXR0ZXN0YXRpb25zL0dpdEh1YkFjdGlvbnNXb3JrZmxvd0B2MSIsCiAgICAgICJleHRlcm5hbFBhcmFtYXRlcnMiOiB7CiAgICAgICAgInNvdXJjZSI6IHsKICAgICAgICAgICJ1cmkiOiAiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9zbHNhLWZyYW1ld29yay9leGFtcGxlLXBhY2thZ2UiLAogICAgICAgICAgImRpZ2VzdCI6IHsKICAgICAgICAgICAgInNoYTEiOiAiNGU2YzVmNmQwYjRhMTI2ZmEyMzczZDdlNTdiN2EwYWYwNTEwODc5MSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0sCiAgICAicnVuRGV0YWlscyI6IHsKICAgICAgImJ1aWxkZXIiOiB7CiAgICAgICAgImlkIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViSG9zdGVkQWN0aW9uc0B2MSIKICAgICAgfSwKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJpbnZvY2F0aW9uSWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL3Nsc2EtZnJhbWV3b3JrL2V4YW1wbGUtcGFja2FnZS9hY3Rpb25zL3J1bnMvNDEzNTQ2Mzc0MS9hdHRlbXB0cy8xIgogICAgICB9CiAgICB9CiAgfQp9Cg==",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "",
|
||||
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
|
||||
}
|
||||
]
|
||||
}
|
||||
10
verifiers/internal/gha/testdata/dsse-no-subject-v1.intoto.jsonl
vendored
Normal file
10
verifiers/internal/gha/testdata/dsse-no-subject-v1.intoto.jsonl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.in-toto+json",
|
||||
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogW10sCiAgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YxLjA/ZHJhZnQiLAogICJwcmVkaWNhdGUiOiB7CiAgICAiYnVpbGREZWZpbml0aW9uIjogewogICAgICAiYnVpbGROb3RTTFNBIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViQWN0aW9uc1dvcmtmbG93QHYxIiwKICAgICAgImV4dGVybmFsUGFyYW1hdGVycyI6IHsKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInVyaSI6ICJnaXQraHR0cHM6Ly9naXRodWIuY29tL3Nsc2EtZnJhbWV3b3JrL2V4YW1wbGUtcGFja2FnZSIsCiAgICAgICAgICAiZGlnZXN0IjogewogICAgICAgICAgICAic2hhMSI6ICI0ZTZjNWY2ZDBiNGExMjZmYTIzNzNkN2U1N2I3YTBhZjA1MTA4NzkxIgogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICJydW5EZXRhaWxzIjogewogICAgICAiYnVpbGRlciI6IHsKICAgICAgICAiaWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL0F0dGVzdGF0aW9ucy9HaXRIdWJIb3N0ZWRBY3Rpb25zQHYxIgogICAgICB9LAogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImludm9jYXRpb25JZCI6ICJodHRwczovL2dpdGh1Yi5jb20vc2xzYS1mcmFtZXdvcmsvZXhhbXBsZS1wYWNrYWdlL2FjdGlvbnMvcnVucy80MTM1NDYzNzQxL2F0dGVtcHRzLzEiCiAgICAgIH0KICAgIH0KICB9Cn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJwcmVkaWNhdGUiOiB7CiAgICAiYnVpbGRUeXBlIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViQWN0aW9uc1dvcmtmbG93QHYxIiwKICAgICJidWlsZGVyIjogewogICAgICAiaWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL0F0dGVzdGF0aW9ucy9HaXRIdWJIb3N0ZWRBY3Rpb25zQHYxIgogICAgfSwKICAgICJpbnZvY2F0aW9uIjogewogICAgICAiY29uZmlnU291cmNlIjogewogICAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgICAiU0hBMSI6ICI0NTA2MjkwZTJlOGZlYjFmMzRiMjdhMDQ0ZjdjYzg2M2M4MzBlZjZiIgogICAgICAgIH0sCiAgICAgICAgImVudHJ5UG9pbnQiOiAiVGVzdCBTTFNBIiwKICAgICAgICAidXJpIjogImdpdCthc3JhYS9zbHNhLW9uLWdpdGh1Yi10ZXN0LmdpdCIKICAgICAgfSwKICAgICAgImVudmlyb25tZW50IjogewogICAgICAgICJhcmNoIjogImFtZDY0IiwKICAgICAgICAiZW52IjogewogICAgICAgICAgIkdJVEhVQl9FVkVOVF9OQU1FIjogIndvcmtmbG93X2Rpc3BhdGNoIiwKICAgICAgICAgICJHSVRIVUJfUlVOX0lEIjogIjE4OTM3OTkyMjAiLAogICAgICAgICAgIkdJVEhVQl9SVU5fTlVNQkVSIjogIjc2IgogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICJtYXRlcmlhbHMiOiBbCiAgICAgIHsKICAgICAgICAiZGlnZXN0IjogewogICAgICAgICAgIlNIQTEiOiAiNDUwNjI5MGUyZThmZWIxZjM0YjI3YTA0NGY3Y2M4NjNjODMwZWY2YiIKICAgICAgICB9LAogICAgICAgICJ1cmkiOiAiZ2l0K2FzcmFhL3Nsc2Etb24tZ2l0aHViLXRlc3QuZ2l0IgogICAgICB9CiAgICBdCiAgfSwKICAicHJlZGljYXRlVHlwZSI6ICJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjAuMiIsCn0K",
|
||||
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
|
||||
}
|
||||
]
|
||||
}
|
||||
10
verifiers/internal/gha/testdata/dsse-not-slsa-v1.intoto.jsonl
vendored
Normal file
10
verifiers/internal/gha/testdata/dsse-not-slsa-v1.intoto.jsonl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.in-toto+json",
|
||||
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGExIjogIjQ1MDYyOTBlMmU4ZmViMWYzNGIyN2EwNDRmN2NjODYzYzgzMGVmNmIiCiAgICAgIH0sCiAgICAgICJuYW1lIjogImJpbmFyeS1saW51eC1hbWQ2NCIKICAgIH0KICBdLAogICJwcmVkaWNhdGVUeXBlIjogImh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MS4wP2RyYWZ0IiwKICAicHJlZGljYXRlIjogewogICAgImJ1aWxkRGVmaW5pdGlvbiI6IHsKICAgICAgImJ1aWxkTm90U0xTQSI6ICJodHRwczovL2dpdGh1Yi5jb20vQXR0ZXN0YXRpb25zL0dpdEh1YkFjdGlvbnNXb3JrZmxvd0B2MSIsCiAgICAgICJleHRlcm5hbFBhcmFtYXRlcnMiOiB7CiAgICAgICAgInNvdXJjZSI6IHsKICAgICAgICAgICJ1cmkiOiAiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9zbHNhLWZyYW1ld29yay9leGFtcGxlLXBhY2thZ2UiLAogICAgICAgICAgImRpZ2VzdCI6IHsKICAgICAgICAgICAgInNoYTEiOiAiNGU2YzVmNmQwYjRhMTI2ZmEyMzczZDdlNTdiN2EwYWYwNTEwODc5MSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0sCiAgICAicnVuRGV0YWlscyI6IHsKICAgICAgImJ1aWxkZXIiOiB7CiAgICAgICAgImlkIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViSG9zdGVkQWN0aW9uc0B2MSIKICAgICAgfSwKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJpbnZvY2F0aW9uSWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL3Nsc2EtZnJhbWV3b3JrL2V4YW1wbGUtcGFja2FnZS9hY3Rpb25zL3J1bnMvNDEzNTQ2Mzc0MS9hdHRlbXB0cy8xIgogICAgICB9CiAgICB9CiAgfQp9Cg==",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "",
|
||||
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
|
||||
}
|
||||
]
|
||||
}
|
||||
10
verifiers/internal/gha/testdata/dsse-valid-multi-subjects-v1.intoto.jsonl
vendored
Normal file
10
verifiers/internal/gha/testdata/dsse-valid-multi-subjects-v1.intoto.jsonl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.in-toto+json",
|
||||
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGEyNTYiOiAiMDFlN2U0ZmE3MTY4NjUzODQ0MDAxMmVlMzZhMjYzNGRiYWExOWRmMmRkMTZhNDY2ZjUyNDExZmIzNDhiYmM0ZSIKICAgICAgfSwKICAgICAgIm5hbWUiOiAiYmluYXJ5LWxpbnV4LWFtZDY0LTEiCiAgICB9LAogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGEyNTYiOiAiMDJlN2U0ZmE3MTY4NjUzODQ0MDAxMmVlMzZhMjYzNGRiYWExOWRmMmRkMTZhNDY2ZjUyNDExZmIzNDhiYmM0ZSIKICAgICAgfSwKICAgICAgIm5hbWUiOiAiYmluYXJ5LWxpbnV4LWFtZDY0LTIiCiAgICB9LAogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGEyNTYiOiAiMDNlN2U0ZmE3MTY4NjUzODQ0MDAxMmVlMzZhMjYzNGRiYWExOWRmMmRkMTZhNDY2ZjUyNDExZmIzNDhiYmM0ZSIKICAgICAgfSwKICAgICAgIm5hbWUiOiAiYmluYXJ5LWxpbnV4LWFtZDY0LTMiCiAgICB9CiAgXSwKICAicHJlZGljYXRlVHlwZSI6ICJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEuMD9kcmFmdCIsCiAgInByZWRpY2F0ZSI6IHsKICAgICJidWlsZERlZmluaXRpb24iOiB7CiAgICAgICJidWlsZE5vdFNMU0EiOiAiaHR0cHM6Ly9naXRodWIuY29tL0F0dGVzdGF0aW9ucy9HaXRIdWJBY3Rpb25zV29ya2Zsb3dAdjEiLAogICAgICAiZXh0ZXJuYWxQYXJhbWF0ZXJzIjogewogICAgICAgICJzb3VyY2UiOiB7CiAgICAgICAgICAidXJpIjogImdpdCtodHRwczovL2dpdGh1Yi5jb20vc2xzYS1mcmFtZXdvcmsvZXhhbXBsZS1wYWNrYWdlIiwKICAgICAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgICAgICJzaGExIjogIjRlNmM1ZjZkMGI0YTEyNmZhMjM3M2Q3ZTU3YjdhMGFmMDUxMDg3OTEiCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgInJ1bkRldGFpbHMiOiB7CiAgICAgICJidWlsZGVyIjogewogICAgICAgICJpZCI6ICJodHRwczovL2dpdGh1Yi5jb20vQXR0ZXN0YXRpb25zL0dpdEh1Ykhvc3RlZEFjdGlvbnNAdjEiCiAgICAgIH0sCiAgICAgICJtZXRhZGF0YSI6IHsKICAgICAgICAiaW52b2NhdGlvbklkIjogImh0dHBzOi8vZ2l0aHViLmNvbS9zbHNhLWZyYW1ld29yay9leGFtcGxlLXBhY2thZ2UvYWN0aW9ucy9ydW5zLzQxMzU0NjM3NDEvYXR0ZW1wdHMvMSIKICAgICAgfQogICAgfQogIH0KfQo=",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "",
|
||||
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
|
||||
}
|
||||
]
|
||||
}
|
||||
10
verifiers/internal/gha/testdata/dsse-valid-v1.intoto.jsonl
vendored
Normal file
10
verifiers/internal/gha/testdata/dsse-valid-v1.intoto.jsonl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.in-toto+json",
|
||||
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAiZGlnZXN0IjogewogICAgICAgICJzaGEyNTYiOiAiMGFlN2U0ZmE3MTY4NjUzODQ0MDAxMmVlMzZhMjYzNGRiYWExOWRmMmRkMTZhNDY2ZjUyNDExZmIzNDhiYmM0ZSIKICAgICAgfSwKICAgICAgIm5hbWUiOiAiYmluYXJ5LWxpbnV4LWFtZDY0IgogICAgfQogIF0sCiAgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YxLjA/ZHJhZnQiLAogICJwcmVkaWNhdGUiOiB7CiAgICAiYnVpbGREZWZpbml0aW9uIjogewogICAgICAiYnVpbGROb3RTTFNBIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViQWN0aW9uc1dvcmtmbG93QHYxIiwKICAgICAgImV4dGVybmFsUGFyYW1hdGVycyI6IHsKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInVyaSI6ICJnaXQraHR0cHM6Ly9naXRodWIuY29tL3Nsc2EtZnJhbWV3b3JrL2V4YW1wbGUtcGFja2FnZSIsCiAgICAgICAgICAiZGlnZXN0IjogewogICAgICAgICAgICAic2hhMSI6ICI0ZTZjNWY2ZDBiNGExMjZmYTIzNzNkN2U1N2I3YTBhZjA1MTA4NzkxIgogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICJydW5EZXRhaWxzIjogewogICAgICAiYnVpbGRlciI6IHsKICAgICAgICAiaWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL0F0dGVzdGF0aW9ucy9HaXRIdWJIb3N0ZWRBY3Rpb25zQHYxIgogICAgICB9LAogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImludm9jYXRpb25JZCI6ICJodHRwczovL2dpdGh1Yi5jb20vc2xzYS1mcmFtZXdvcmsvZXhhbXBsZS1wYWNrYWdlL2FjdGlvbnMvcnVucy80MTM1NDYzNzQxL2F0dGVtcHRzLzEiCiAgICAgIH0KICAgIH0KICB9Cn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "",
|
||||
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -96,11 +96,15 @@ func (v *GHAVerifier) VerifyArtifact(ctx context.Context,
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var signedAtt *SignedAttestation
|
||||
/* Verify signature on the intoto attestation. */
|
||||
// TODO(https://github.com/slsa-framework/slsa-github-generator/issues/716):
|
||||
// We will also need to support bundles when those are complete.
|
||||
signedAtt, err := VerifyProvenanceSignature(ctx, trustedRoot, rClient,
|
||||
provenance, artifactHash)
|
||||
if provenanceOpts.ProvenanceBundle != nil {
|
||||
signedAtt, err = VerifyProvenanceBundle(ctx, provenanceOpts.ProvenanceBundle,
|
||||
trustedRoot)
|
||||
} else {
|
||||
signedAtt, err = VerifyProvenanceSignature(ctx, trustedRoot, rClient,
|
||||
provenance, artifactHash)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
21
verifiers/utils/provenance.go
Normal file
21
verifiers/utils/provenance.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
|
||||
)
|
||||
|
||||
func GetAsString(environment map[string]any, field string) (string, error) {
|
||||
value, ok := environment[field]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload,
|
||||
fmt.Sprintf("environment type for %s", field))
|
||||
}
|
||||
|
||||
i, ok := value.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: %s '%s'", serrors.ErrorInvalidDssePayload, "environment type string", field)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
Reference in New Issue
Block a user