Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Provenance tests #628

Merged
merged 6 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions cli/slsa-verifier/main_regression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,14 @@ func Test_runVerifyGHAArtifactPath(t *testing.T) {
artifacts: []string{"binary-linux-amd64-workflow_dispatch"},
source: "github.com/slsa-framework/example-package",
ptag: pString("v1.2.3"),
err: serrors.ErrorMismatchTag,
err: serrors.ErrorInvalidRef,
},
{
name: "versioned tag no match empty tag workflow_dispatch",
artifacts: []string{"binary-linux-amd64-workflow_dispatch"},
source: "github.com/slsa-framework/example-package",
pversiontag: pString("v1"),
err: serrors.ErrorInvalidSemver,
err: serrors.ErrorInvalidRef,
},
// Provenance contains tag = v13.0.30.
{
Expand Down Expand Up @@ -477,7 +477,7 @@ func Test_runVerifyGHAArtifactPath(t *testing.T) {
source: "github.com/asraa/slsa-on-github-test",
pversiontag: pString("v1.5.0"),
pbranch: pString("main"),
err: serrors.ErrorMismatchBranch,
err: serrors.ErrorInvalidRef,
noversion: true,
},
// Workflow inputs.
Expand Down Expand Up @@ -746,14 +746,14 @@ func Test_runVerifyGHAArtifactImage(t *testing.T) {
artifact: "container_workflow_dispatch",
source: "github.com/slsa-framework/example-package",
ptag: pString("v1.2.3"),
err: serrors.ErrorMismatchTag,
err: serrors.ErrorInvalidRef,
},
{
name: "versioned tag no match empty tag workflow_dispatch",
artifact: "container_workflow_dispatch",
source: "github.com/slsa-framework/example-package",
pversiontag: pString("v1"),
err: serrors.ErrorInvalidSemver,
err: serrors.ErrorInvalidRef,
},
}
for _, tt := range tests {
Expand Down Expand Up @@ -1327,14 +1327,14 @@ func Test_runVerifyGHAContainerBased(t *testing.T) {
artifacts: []string{"workflow_dispatch.main.default"},
source: "github.com/slsa-framework/example-package",
pversiontag: pString("v1"),
err: serrors.ErrorInvalidSemver,
err: serrors.ErrorInvalidRef,
},
{
name: "tag no match empty tag workflow_dispatch",
artifacts: []string{"workflow_dispatch.main.default"},
source: "github.com/slsa-framework/example-package",
ptag: pString("v1.2.3"),
err: serrors.ErrorMismatchTag,
err: serrors.ErrorInvalidRef,
},
{
name: "wrong branch master",
Expand Down
45 changes: 36 additions & 9 deletions verifiers/internal/gha/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,19 @@ func verifyDigest(prov slsaprovenance.Provenance, expectedHash string) error {
}

// 8 bit represented in hex, so 8/2=4.
l := len(expectedHash) * 4
bitLength := len(expectedHash) * 4
expectedAlgo := fmt.Sprintf("sha%v", bitLength)
// TODO(#630): Add subject digest minimum bit length check.
// sha1 is 160 bit (FWIW).
ianlewis marked this conversation as resolved.
Show resolved Hide resolved
if bitLength == 160 {
expectedAlgo = "sha1"
}

for _, subject := range subjects {
digestSet := subject.Digest
hash, exists := digestSet[fmt.Sprintf("sha%v", l)]
hash, exists := digestSet[expectedAlgo]
if !exists {
return fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, fmt.Sprintf("no sha%v subject digest", l))
continue
}
if hash == expectedHash {
return nil
Expand Down Expand Up @@ -383,44 +390,64 @@ func VerifyWorkflowInputs(prov slsaprovenance.Provenance, inputs map[string]stri
return nil
}

// VerifyBranch verifies that the source branch in the provenance matches the
// expected value.
func VerifyBranch(prov slsaprovenance.Provenance, expectedBranch string) error {
branch, err := prov.GetBranch()
ref, err := prov.GetBranch()
if err != nil {
return err
}

expectedBranch = "refs/heads/" + expectedBranch
branch, err := utils.BranchFromGitRef(ref)
if err != nil {
return fmt.Errorf("verifying branch: %w", err)
}

if branch != expectedBranch {
return fmt.Errorf("expected branch '%s', got '%s': %w", expectedBranch, branch, serrors.ErrorMismatchBranch)
}

return nil
}

// VerifyTag verifies that the source tag in the provenance matches the
// expected value.
func VerifyTag(prov slsaprovenance.Provenance, expectedTag string) error {
tag, err := prov.GetTag()
ref, err := prov.GetTag()
if err != nil {
return err
}

expectedTag = "refs/tags/" + expectedTag
tag, err := utils.TagFromGitRef(ref)
if err != nil {
return fmt.Errorf("verifying tag: %w", err)
}

if tag != expectedTag {
return fmt.Errorf("expected tag '%s', got '%s': %w", expectedTag, tag, serrors.ErrorMismatchTag)
}

return nil
}

// VerifyVersionedTag verifies that the source tag in the provenance matches the
// expected semver value.
func VerifyVersionedTag(prov slsaprovenance.Provenance, expectedTag string) error {
// Retrieve, validate and canonicalize the provenance tag.
// 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 := prov.GetTag()
ref, err := prov.GetTag()
if err != nil {
return err
}
return utils.VerifyVersionedTag(strings.TrimPrefix(tag, "refs/tags/"), expectedTag)

tag, err := utils.TagFromGitRef(ref)
if err != nil {
return fmt.Errorf("verifying tag: %w", err)
}

return utils.VerifyVersionedTag(tag, expectedTag)
}

// hasCertInEnvelope checks if a valid x509 certificate is present in the
Expand Down
Loading