Skip to content

Commit

Permalink
Allow checksum field usage in legacy SBOM
Browse files Browse the repository at this point in the history
  • Loading branch information
Sophie Wigmore authored and ryanmoran committed Sep 20, 2022
1 parent de1bc36 commit b5e27ef
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 54 deletions.
3 changes: 2 additions & 1 deletion paketosbom/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func GetBOMChecksumAlgorithm(alg string) (algorithm, error) {
}
}

return "", fmt.Errorf("failed to get supported BOM checksum algorithm: %s is not valid", alg)
return UNKNOWN, fmt.Errorf("failed to get supported BOM checksum algorithm: %s is not valid", alg)
}

const (
Expand All @@ -76,4 +76,5 @@ const (
BLAKE2B512 algorithm = "BLAKE2b-512"
BLAKE3 algorithm = "BLAKE3"
MD5 algorithm = "MD5"
UNKNOWN algorithm = "UNKNOWN"
)
3 changes: 2 additions & 1 deletion paketosbom/sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ func testPaketoSBOM(t *testing.T, context spec.G, it spec.S) {
context("failure cases", func() {
context("when the attempted BOM checksum algorithm is not supported", func() {
it("persists a build.toml", func() {
_, err := paketosbom.GetBOMChecksumAlgorithm("RANDOM-ALG")
alg, err := paketosbom.GetBOMChecksumAlgorithm("RANDOM-ALG")
Expect(alg).To(Equal(paketosbom.UNKNOWN))
Expect(err).To(MatchError("failed to get supported BOM checksum algorithm: RANDOM-ALG is not valid"))
})
})
Expand Down
42 changes: 38 additions & 4 deletions postal/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,32 @@ func (s Service) Deliver(dependency Dependency, cnbPath, layerPath, platformPath
func (s Service) GenerateBillOfMaterials(dependencies ...Dependency) []packit.BOMEntry {
var entries []packit.BOMEntry
for _, dependency := range dependencies {

algorithm, hash := determineChecksum(dependency.Checksum, dependency.SHA256)
paketoSbomAlgorithm, err := paketosbom.GetBOMChecksumAlgorithm(algorithm)
// GetBOMChecksumAlgorithm will set algorithm to UNKNOWN if there is an error
if err != nil {
hash = ""
}

srcAlgorithm, srcHash := determineChecksum(dependency.SourceChecksum, dependency.SourceSHA256)
paketoSbomSrcAlgorithm, err := paketosbom.GetBOMChecksumAlgorithm(srcAlgorithm)
// GetBOMChecksumAlgorithm will set algorithm to UNKNOWN if there is an error
if err != nil {
srcHash = ""
}

paketoBomMetadata := paketosbom.BOMMetadata{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA256,
Hash: dependency.SHA256,
Algorithm: paketoSbomAlgorithm,
Hash: hash,
},
URI: dependency.URI,
Version: dependency.Version,
Source: paketosbom.BOMSource{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA256,
Hash: dependency.SourceSHA256,
Algorithm: paketoSbomSrcAlgorithm,
Hash: srcHash,
},
URI: dependency.Source,
},
Expand Down Expand Up @@ -240,3 +255,22 @@ func (s Service) GenerateBillOfMaterials(dependencies ...Dependency) []packit.BO

return entries
}

func determineChecksum(checksumField, sha256Field string) (string, string) {
var algorithm string
var hash string

if sha256Field != "" {
algorithm = "SHA256"
hash = sha256Field
}

// A well-formed checksum field (algorithm:hash) takes precedence over a SHA256 field
checksumParts := strings.Split(checksumField, ":")
if len(checksumParts) > 1 {
algorithm = checksumParts[0]
hash = checksumParts[1]
}

return algorithm, hash
}
213 changes: 165 additions & 48 deletions postal/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -871,24 +871,24 @@ version = "this is super not semver"
it("returns a list of BOMEntry values", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Name: "Some Entry",
SHA256: "some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
ID: "some-entry",
Name: "Some Entry",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
postal.Dependency{
ID: "other-entry",
Name: "Other Entry",
SHA256: "other-sha",
Source: "other-source",
SourceSHA256: "other-source-sha",
Stacks: []string{"other-stack"},
URI: "other-uri",
Version: "4.5.6",
ID: "other-entry",
Name: "Other Entry",
Checksum: "sha256:other-sha",
Source: "other-source",
SourceChecksum: "sha256:other-source-sha",
Stacks: []string{"other-stack"},
URI: "other-uri",
Version: "4.5.6",
},
)
Expect(entries).To(Equal([]packit.BOMEntry{
Expand Down Expand Up @@ -937,15 +937,15 @@ version = "this is super not semver"
it("generates a BOM with the CPE", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
CPE: "some-cpe",
ID: "some-entry",
Name: "Some Entry",
SHA256: "some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
CPE: "some-cpe",
ID: "some-entry",
Name: "Some Entry",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expand Down Expand Up @@ -976,16 +976,16 @@ version = "this is super not semver"
it("uses CPE, ignores CPEs, for backward compatibility", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
CPE: "some-cpe",
CPEs: []string{"some-other-cpe"},
ID: "some-entry",
Name: "Some Entry",
SHA256: "some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
CPE: "some-cpe",
CPEs: []string{"some-other-cpe"},
ID: "some-entry",
Name: "Some Entry",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expand Down Expand Up @@ -1031,9 +1031,9 @@ version = "this is super not semver"
DeprecationDate: deprecationDate,
ID: "some-entry",
Name: "Some Entry",
SHA256: "some-sha",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
Expand Down Expand Up @@ -1069,15 +1069,15 @@ version = "this is super not semver"
it("generates a BOM with the license information", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Licenses: []string{"some-license"},
Name: "Some Entry",
SHA256: "some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
ID: "some-entry",
Licenses: []string{"some-license"},
Name: "Some Entry",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expand Down Expand Up @@ -1108,11 +1108,51 @@ version = "this is super not semver"

context("when there is a pURL", func() {
it("generates a BOM with the pURL", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Name: "Some Entry",
PURL: "some-purl",
Checksum: "sha256:some-sha",
Source: "some-source",
SourceChecksum: "sha256:some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expect(entries).To(Equal([]packit.BOMEntry{
{
Name: "Some Entry",
Metadata: paketosbom.BOMMetadata{
PURL: "some-purl",
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA256,
Hash: "some-sha",
},
Source: paketosbom.BOMSource{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA256,
Hash: "some-source-sha",
},
URI: "some-source",
},

URI: "some-uri",
Version: "1.2.3",
},
},
}))
})
})

context("when there is a SHA256 instead of Checksum", func() {
it("generates a BOM with the SHA256", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Name: "Some Entry",
PURL: "some-purl",
SHA256: "some-sha",
Source: "some-source",
SourceSHA256: "some-source-sha",
Expand All @@ -1126,7 +1166,6 @@ version = "this is super not semver"
{
Name: "Some Entry",
Metadata: paketosbom.BOMMetadata{
PURL: "some-purl",
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA256,
Hash: "some-sha",
Expand All @@ -1146,5 +1185,83 @@ version = "this is super not semver"
}))
})
})

context("when there is a checksum and SHA256", func() {
it("generates a BOM with the checksum", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Name: "Some Entry",
Checksum: "sha512:checksum-sha",
SHA256: "some-sha",
Source: "some-source",
SourceChecksum: "sha512:source-checksum-sha",
SourceSHA256: "some-source-sha",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expect(entries).To(Equal([]packit.BOMEntry{
{
Name: "Some Entry",
Metadata: paketosbom.BOMMetadata{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA512,
Hash: "checksum-sha",
},
Source: paketosbom.BOMSource{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.SHA512,
Hash: "source-checksum-sha",
},
URI: "some-source",
},

URI: "some-uri",
Version: "1.2.3",
},
},
}))
})
})

context("when there is no checksum or SHA256", func() {
it("generates a BOM with the empty/unknown checksum", func() {
entries := service.GenerateBillOfMaterials(
postal.Dependency{
ID: "some-entry",
Name: "Some Entry",
Source: "some-source",
Stacks: []string{"some-stack"},
URI: "some-uri",
Version: "1.2.3",
},
)

Expect(entries).To(Equal([]packit.BOMEntry{
{
Name: "Some Entry",
Metadata: paketosbom.BOMMetadata{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.UNKNOWN,
Hash: "",
},
Source: paketosbom.BOMSource{
Checksum: paketosbom.BOMChecksum{
Algorithm: paketosbom.UNKNOWN,
Hash: "",
},
URI: "some-source",
},

URI: "some-uri",
Version: "1.2.3",
},
},
}))
})
})
})
}

0 comments on commit b5e27ef

Please sign in to comment.