-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Ramon Petgrave <[email protected]>
- Loading branch information
1 parent
f865241
commit 4981e1e
Showing
3 changed files
with
61 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,14 @@ import ( | |
"github.com/slsa-framework/slsa-verifier/v2/verifiers/utils" | ||
) | ||
|
||
var ( | ||
refs123 = "@refs/tags/v1.2.3" | ||
githubWorkflows = "/.github/workflows/" | ||
builderGoSlsa3 = githubWorkflows + "builder_go_slsa3.yml" | ||
delegatorGenericSlsa3 = githubWorkflows + "delegator_generic_slsa3.yml" | ||
generatorGenericSlsa3 = githubWorkflows + "generator_generic_slsa3.yml" | ||
) | ||
|
||
// Must checks the error and panics if not nil. | ||
func Must[T any](val T, err error) T { | ||
if err != nil { | ||
|
@@ -77,7 +85,7 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: "https://bad.issuer.com", | ||
}, | ||
|
@@ -89,72 +97,72 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: trustedBuilderRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: "https://token.actions.githubusercontent.com", | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid generic delegator builder without tag", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: trustedBuilderRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GenericDelegatorBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GenericDelegatorBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: "https://token.actions.githubusercontent.com", | ||
}, | ||
defaults: defaultBYOBReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/delegator_generic_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + delegatorGenericSlsa3, | ||
byob: true, | ||
}, | ||
{ | ||
name: "valid low-perms delegator builder with short tag", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: trustedBuilderRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GenericLowPermsDelegatorBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GenericLowPermsDelegatorBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: "https://token.actions.githubusercontent.com", | ||
}, | ||
defaults: defaultBYOBReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/[email protected]", | ||
builderID: httpsGithubCom + trustedBuilderRepository + "/.github/workflows/[email protected]", | ||
byob: true, | ||
}, | ||
{ | ||
name: "valid main ref for e2e test", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: e2eTestRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid main ref for e2e test - match builderID", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: e2eTestRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
buildOpts: &options.BuilderOpts{ | ||
ExpectedID: asStringPointer("https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml"), | ||
ExpectedID: asStringPointer(httpsGithubCom + trustedBuilderRepository + builderGoSlsa3), | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid main ref for e2e test - mismatch builderID", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: e2eTestRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -169,22 +177,22 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
buildOpts: &options.BuilderOpts{ | ||
ExpectedID: asStringPointer("https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml"), | ||
ExpectedID: asStringPointer(httpsGithubCom + trustedBuilderRepository + builderGoSlsa3), | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid workflow identity - mismatch builderID", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -205,7 +213,7 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
}, | ||
err: serrors.ErrorInvalidRef, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "invalid workflow identity with build", | ||
|
@@ -236,48 +244,48 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid workflow identity with fully qualified source - no default", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
buildOpts: &options.BuilderOpts{ | ||
ExpectedID: asStringPointer("https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml"), | ||
ExpectedID: asStringPointer(httpsGithubCom + trustedBuilderRepository + builderGoSlsa3), | ||
}, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid workflow identity with fully qualified source - match builderID", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
buildOpts: &options.BuilderOpts{ | ||
ExpectedID: asStringPointer("https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml"), | ||
ExpectedID: asStringPointer(httpsGithubCom + trustedBuilderRepository + builderGoSlsa3), | ||
}, | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
builderID: "https://github.com/" + trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml", | ||
builderID: httpsGithubCom + trustedBuilderRepository + builderGoSlsa3, | ||
}, | ||
{ | ||
name: "valid workflow identity with fully qualified source - mismatch builderID", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -292,7 +300,7 @@ func Test_VerifyBuilderIdentity(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -388,7 +396,7 @@ func Test_VerifyCertficateSourceRepository(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "asraa/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -399,7 +407,7 @@ func Test_VerifyCertficateSourceRepository(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: e2eTestRepository, | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -410,7 +418,7 @@ func Test_VerifyCertficateSourceRepository(t *testing.T) { | |
name: "valid main ref for builder", | ||
workflow: &WorkflowIdentity{ | ||
SourceRepository: trustedBuilderRepository, | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -422,7 +430,7 @@ func Test_VerifyCertficateSourceRepository(t *testing.T) { | |
workflow: &WorkflowIdentity{ | ||
SourceRepository: "malicious/slsa-on-github-test", | ||
SourceSha1: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b", | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + "@refs/tags/v1.2.3")), | ||
SubjectWorkflow: Must(url.Parse(common.GoBuilderID + refs123)), | ||
BuildTrigger: "workflow_dispatch", | ||
Issuer: certOidcIssuer, | ||
}, | ||
|
@@ -459,19 +467,19 @@ func Test_verifyTrustedBuilderID(t *testing.T) { | |
}{ | ||
{ | ||
name: "default trusted short tag", | ||
path: trustedBuilderRepository + "/.github/workflows/generator_generic_slsa3.yml", | ||
path: trustedBuilderRepository + generatorGenericSlsa3, | ||
tag: "v1.2.3", | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
}, | ||
{ | ||
name: "default trusted long tag", | ||
path: trustedBuilderRepository + "/.github/workflows/generator_generic_slsa3.yml", | ||
path: trustedBuilderRepository + generatorGenericSlsa3, | ||
tag: "refs/tags/v1.2.3", | ||
defaults: defaultArtifactTrustedReusableWorkflows, | ||
}, | ||
{ | ||
name: "generic delegator workflow long tag", | ||
path: trustedBuilderRepository + "/.github/workflows/delegator_generic_slsa3.yml", | ||
path: trustedBuilderRepository + delegatorGenericSlsa3, | ||
id: asStringPointer(trustedBuilderRepository + "/.github/workflows/delegator_generic_slsa3.yml@refs/tags/v1.2.3"), | ||
tag: "refs/tags/v1.2.3", | ||
defaults: defaultBYOBReusableWorkflows, | ||
|
@@ -481,7 +489,7 @@ func Test_verifyTrustedBuilderID(t *testing.T) { | |
// This is a BYOB workflow without an id that tests non-compulsory builder-id | ||
// feature of slsa-verifier and expects byob to be true | ||
name: "generic delegator workflow no id", | ||
path: trustedBuilderRepository + "/.github/workflows/delegator_generic_slsa3.yml", | ||
path: trustedBuilderRepository + delegatorGenericSlsa3, | ||
// NOTE: id is nil. | ||
id: nil, | ||
tag: "refs/tags/v1.2.3", | ||
|
@@ -509,7 +517,7 @@ func Test_verifyTrustedBuilderID(t *testing.T) { | |
}, | ||
{ | ||
name: "default mismatch against container defaults long tag", | ||
path: trustedBuilderRepository + "/.github/workflows/generator_generic_slsa3.yml", | ||
path: trustedBuilderRepository + generatorGenericSlsa3, | ||
tag: "refs/tags/v1.2.3", | ||
defaults: defaultContainerTrustedReusableWorkflows, | ||
err: serrors.ErrorUntrustedReusableWorkflow, | ||
|
@@ -828,7 +836,7 @@ func Test_GetWorkflowInfoFromCertificate(t *testing.T) { | |
t.Errorf(err.Error()) | ||
} | ||
repo := "org/repo" | ||
encodedRepoURI, err := asn1.MarshalWithParams("https://github.com/"+repo, "utf8") | ||
encodedRepoURI, err := asn1.MarshalWithParams(httpsGithubCom+repo, "utf8") | ||
if err != nil { | ||
t.Errorf(err.Error()) | ||
} | ||
|
@@ -869,13 +877,13 @@ func Test_GetWorkflowInfoFromCertificate(t *testing.T) { | |
t.Errorf(err.Error()) | ||
} | ||
buildConfigPath := "path/to/workflow" | ||
encodedBuildConfigURI, err := asn1.MarshalWithParams("https://github.com/"+repo+"/"+buildConfigPath+"@"+ref, "utf8") | ||
encodedBuildConfigURI, err := asn1.MarshalWithParams(httpsGithubCom+repo+"/"+buildConfigPath+"@"+ref, "utf8") | ||
if err != nil { | ||
t.Errorf(err.Error()) | ||
} | ||
|
||
invocationID := "9207262" | ||
encodedInvocationURI, err := asn1.MarshalWithParams("https://github.com/"+repo+"/actions/runs/"+invocationID, "utf8") | ||
encodedInvocationURI, err := asn1.MarshalWithParams(httpsGithubCom+repo+"/actions/runs/"+invocationID, "utf8") | ||
if err != nil { | ||
t.Errorf(err.Error()) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ import ( | |
"github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/iface" | ||
) | ||
|
||
var gitPrefix = "git+" | ||
|
||
type testProvenance struct { | ||
builderID string | ||
buildType string | ||
|
@@ -430,48 +432,48 @@ func Test_isValidDelegatorBuilderID(t *testing.T) { | |
{ | ||
name: "no @", | ||
builderID: "some/builderID", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
err: serrors.ErrorInvalidBuilderID, | ||
}, | ||
{ | ||
name: "invalid ref", | ||
builderID: "some/[email protected]", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
err: serrors.ErrorInvalidRef, | ||
}, | ||
{ | ||
name: "invalid ref not tag", | ||
builderID: "some/builderID@refs/head/v1.2.3", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
err: serrors.ErrorInvalidRef, | ||
}, | ||
{ | ||
name: "invalid ref not full semver", | ||
builderID: "some/builderID@refs/heads/v1.2", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
err: serrors.ErrorInvalidRef, | ||
}, | ||
{ | ||
name: "valid builder", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
builderID: "some/builderID@refs/tags/v1.2.3", | ||
}, | ||
{ | ||
name: "invalid builder ref not e2e repo with testing enabled", | ||
sourceURI: "git+" + httpsGithubCom + "some/repo", | ||
sourceURI: gitPrefix + httpsGithubCom + "some/repo", | ||
builderID: "some/builderID@refs/heads/main", | ||
testingEnabled: true, | ||
err: serrors.ErrorInvalidRef, | ||
}, | ||
{ | ||
name: "invalid builder ref e2e repo with testing enabled", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
builderID: "some/builderID@refs/heads/main", | ||
testingEnabled: true, | ||
}, | ||
{ | ||
name: "invalid builder ref e2e repo", | ||
sourceURI: "git+" + httpsGithubCom + e2eTestRepository, | ||
sourceURI: gitPrefix + httpsGithubCom + e2eTestRepository, | ||
builderID: "some/builderID@refs/heads/main", | ||
err: serrors.ErrorInvalidRef, | ||
}, | ||
|