Skip to content

Commit

Permalink
Merge pull request #210 from interlynk-io/198-new-check-existence-of-…
Browse files Browse the repository at this point in the history
…primary-component-must-be-checked
  • Loading branch information
riteshnoronha committed Jan 6, 2024
2 parents cd7e60f + fde1057 commit fefa007
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 26 deletions.
36 changes: 27 additions & 9 deletions pkg/sbom/cdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ var cdx_file_formats = []string{"json", "xml"}
var cdx_primary_purpose = []string{"application", "framework", "library", "container", "operating-system", "device", "firmware", "file"}

type cdxDoc struct {
doc *cydx.BOM
format FileFormat
ctx context.Context
spec *spec
comps []Component
authors []Author
tools []Tool
rels []Relation
logs []string
doc *cydx.BOM
format FileFormat
ctx context.Context
spec *spec
comps []Component
authors []Author
tools []Tool
rels []Relation
logs []string
primaryComponent bool
}

func newCDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Document, error) {
Expand Down Expand Up @@ -100,12 +101,17 @@ func (c cdxDoc) Logs() []string {
return c.logs
}

func (c cdxDoc) PrimaryComponent() bool {
return c.primaryComponent
}

func (c *cdxDoc) parse() {
c.parseSpec()
c.parseComps()
c.parseAuthors()
c.parseTool()
c.parseRels()
c.parsePrimaryComponent()
}

func (c *cdxDoc) addToLogs(log string) {
Expand Down Expand Up @@ -393,3 +399,15 @@ func (c *cdxDoc) addSupplierName(comp *cydx.Component) string {
}
return name
}

func (c *cdxDoc) parsePrimaryComponent() {
if c.doc.Metadata == nil {
return
}

if c.doc.Metadata.Component == nil {
return
}

c.primaryComponent = true
}
6 changes: 4 additions & 2 deletions pkg/sbom/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
package sbom

//counterfeiter:generate . Component
import "github.com/interlynk-io/sbomqs/pkg/cpe"
import "github.com/interlynk-io/sbomqs/pkg/purl"
import (
"github.com/interlynk-io/sbomqs/pkg/cpe"
"github.com/interlynk-io/sbomqs/pkg/purl"
)

type Component interface {
ID() string
Expand Down
2 changes: 2 additions & 0 deletions pkg/sbom/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ type Document interface {
Authors() []Author
Tools() []Tool
Logs() []string

PrimaryComponent() bool
}
65 changes: 65 additions & 0 deletions pkg/sbom/sbomfakes/fake_document.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 36 additions & 14 deletions pkg/sbom/spdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ var spdx_spec_versions = []string{"SPDX-2.1", "SPDX-2.2", "SPDX-2.3"}
var spdx_primary_purpose = []string{"application", "framework", "library", "container", "operating-system", "device", "firmware", "source", "archive", "file", "install", "other"}

type spdxDoc struct {
doc *v2_3.Document
format FileFormat
ctx context.Context
spec *spec
comps []Component
authors []Author
tools []Tool
rels []Relation
logs []string
doc *v2_3.Document
format FileFormat
ctx context.Context
spec *spec
comps []Component
authors []Author
tools []Tool
rels []Relation
logs []string
primaryComponent bool
}

func newSPDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Document, error) {
Expand Down Expand Up @@ -108,12 +109,17 @@ func (s spdxDoc) Logs() []string {
return s.logs
}

func (s spdxDoc) PrimaryComponent() bool {
return s.primaryComponent
}

func (s *spdxDoc) parse() {
s.parseSpec()
s.parseComps()
s.parseAuthors()
s.parseTool()
s.parseRels()
s.parsePrimaryComponent()
}

func (s *spdxDoc) parseSpec() {
Expand Down Expand Up @@ -184,13 +190,11 @@ func (s *spdxDoc) parseRels() {
for _, r := range s.doc.Relationships {
nr := relation{}
switch strings.ToUpper(r.Relationship) {
case spdx_common.TypeRelationshipDescribe, spdx_common.TypeRelationshipDescribeBy:
fallthrough
case spdx_common.TypeRelationshipContains, spdx_common.TypeRelationshipContainedBy:
case spdx_common.TypeRelationshipDescribe:
fallthrough
case spdx_common.TypeRelationshipDependsOn, spdx_common.TypeRelationshipDependencyOf:
case spdx_common.TypeRelationshipContains:
fallthrough
case spdx_common.TypeRelationshipPrerequisiteFor, spdx_common.TypeRelationshipHasPrerequisite:
case spdx_common.TypeRelationshipDependsOn:
aBytes, err = r.RefA.MarshalJSON()
if err != nil {
continue
Expand Down Expand Up @@ -511,3 +515,21 @@ func (s *spdxDoc) addSupplierName(index int) string {

return ""
}

func (s *spdxDoc) parsePrimaryComponent() {
pkgIds := make(map[string]bool)

for _, pkg := range s.doc.Packages {
pkgIds[string(pkg.PackageSPDXIdentifier)] = true
}

for _, r := range s.doc.Relationships {
if strings.ToUpper(r.Relationship) == spdx_common.TypeRelationshipDescribe {
_, ok := pkgIds[string(r.RefB.ElementRefID)]
if ok {
s.primaryComponent = true
return
}
}
}
}
1 change: 1 addition & 0 deletions pkg/scorer/criteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ var checks = []check{
{string(quality), "comp_with_any_vuln_lookup_id", false, "components with any vulnerability lookup id", compWithAnyLookupIdCheck},
{string(quality), "comp_with_multi_vuln_lookup_id", false, "components with multiple vulnerability lookup id", compWithMultipleIdCheck},
{string(quality), "sbom_with_creator_and_version", false, "sbom has creator and version", docWithCreatorCheck},
{string(quality), "sbom_with_primary_component", false, "sbom has primary component", docWithPrimaryComponentCheck},

//sharing
{string(sharing), "sbom_sharable", false, "sbom document has a sharable license", sharableLicenseCheck},
Expand Down
15 changes: 15 additions & 0 deletions pkg/scorer/quality.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,18 @@ func docWithCreatorCheck(d sbom.Document, c *check) score {
s.setDesc(fmt.Sprintf("%d/%d tools have creator and version", withCreatorAndVersion, totalTools))
return *s
}

func docWithPrimaryComponentCheck(d sbom.Document, c *check) score {
s := newScoreFromCheck(c)

if d.PrimaryComponent() {
s.setScore(10.0)
s.setDesc("primary component found")
return *s
} else {
s.setScore(0.0)
s.setDesc("no primary component found")
return *s
}
return *s
}
2 changes: 1 addition & 1 deletion pkg/scorer/scorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/interlynk-io/sbomqs/pkg/sbom"
)

const EngineVersion = "5"
const EngineVersion = "6"

type FilterType int

Expand Down

0 comments on commit fefa007

Please sign in to comment.