Skip to content

Commit

Permalink
add primary component properties
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Kumar Sahu <[email protected]>
  • Loading branch information
viveksahu26 committed Sep 5, 2024
1 parent 45d2e30 commit 80ae86f
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 87 deletions.
3 changes: 2 additions & 1 deletion Compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ The [NTIA](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Tech
| Automation Support | 1.1 | `Machine Readable Format` | BomFormat & data forrmat | SPDXversion & data forrmat | optional |
| SBOM Data Fields | 2.1 | `SBOM Authors` | metadata->authors, metadata->supplier | creator->Person, creator->organization or creator->tool | Mandatory |
| | 2.2 | `SBOM Timestamp` | metadata->timestamp | created | Mandatory |
| | 2.3 | `SBOM Dependencies` | dependencies | relationships | Mandatory(number of dependencies primary comp have) |
| Package Data Fields | 2.4 | `Component Name` | component->name | package->name | Mandatory |
| | 2.5 | `SBOM Dependencies` | dependencies | relationships | Mandatory |
| | 2.3 | `Component Dependencies` | dependencies | relationships | Optional(Component to component dependencies) |
| | 2.6 | `Component Supplier Name` | component->supplier | packageSupplier, packageOriginator | Mandatory |
| | 2.7 | `Component Version` | component->version | package->version | Mandatory |
| | 2.8 | `Component with Uniq IDs` | component->cpe, component->purl | externalRef->cpe, externalRef->purl | Mandatory |
Expand Down
2 changes: 1 addition & 1 deletion pkg/compliance/bsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func bsiBuildPhase(doc sbom.Document) *record {
}

func bsiSbomDepth(doc sbom.Document) *record {
if !doc.PrimaryComponent() {
if !doc.PrimaryComp().Present() {
return newRecordStmt(SBOM_DEPTH, "doc", "no-primary", 0.0)
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/compliance/ntia.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ func ntiaAutomationSpec(doc sbom.Document) *record {

func ntiaSBOMDependency(doc sbom.Document) *record {
result, score := "", 0.0
// for doc.Components()
totalDependencies := doc.PrimaryComp().Dependencies()

withDependencies := len(doc.Relations())
if withDependencies > 0 {
if totalDependencies > 0 {
score = 10.0
}
result = fmt.Sprintf("doc has %d depedencies", withDependencies)
result = fmt.Sprintf("doc has %d depedencies", totalDependencies)

return newRecordStmt(SBOM_DEPENDENCY, "SBOM Data Fields", result, score)
}
Expand Down
72 changes: 36 additions & 36 deletions pkg/sbom/cdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,20 @@ var (
)

type CdxDoc struct {
doc *cydx.BOM
format FileFormat
ctx context.Context
CdxSpec *Specs
Comps []GetComponent
CdxAuthors []GetAuthor
CdxTools []GetTool
rels []GetRelation
logs []string
primaryComponent bool
lifecycles []string
supplier GetSupplier
manufacturer Manufacturer
primaryComponentID string
compositions map[string]string
doc *cydx.BOM
format FileFormat
ctx context.Context
CdxSpec *Specs
Comps []GetComponent
CdxAuthors []GetAuthor
CdxTools []GetTool
rels []GetRelation
logs []string
lifecycles []string
supplier GetSupplier
manufacturer Manufacturer
compositions map[string]string
primaryComp primaryComp
}

func newCDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Document, error) {
Expand Down Expand Up @@ -90,6 +89,10 @@ func newCDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Documen
return doc, err
}

func (c CdxDoc) PrimaryComp() PrimaryComp {
return &c.primaryComp
}

func (c CdxDoc) Spec() Spec {
return *c.CdxSpec
}
Expand All @@ -114,10 +117,6 @@ func (c CdxDoc) Logs() []string {
return c.logs
}

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

func (c CdxDoc) Lifecycles() []string {
return c.lifecycles
}
Expand All @@ -137,9 +136,8 @@ func (c *CdxDoc) parse() {
c.parseSupplier()
c.parseManufacturer()
c.parseTool()
c.parsePrimaryComponent()
c.parseCompositions()
c.parseRels()
c.parseRelsAndPrimaryComp()
c.parseComps()
}

Expand Down Expand Up @@ -286,7 +284,7 @@ func copyC(cdxc *cydx.Component, c *CdxDoc) *Component {
}
}

if cdxc.BOMRef == c.primaryComponentID {
if cdxc.BOMRef == c.primaryComp.id {
nc.isPrimary = true
}

Expand Down Expand Up @@ -547,17 +545,32 @@ func (c *CdxDoc) parseManufacturer() {
c.manufacturer = m
}

func (c *CdxDoc) parseRels() {
func (c *CdxDoc) parseRelsAndPrimaryComp() {
if c.doc.Metadata == nil {
return
}

if c.doc.Metadata.Component == nil {
return
}
c.primaryComp.present = true
c.primaryComp.id = c.doc.Metadata.Component.BOMRef
var totalDependencies int

c.rels = []GetRelation{}

for _, r := range lo.FromPtr(c.doc.Dependencies) {
for _, d := range lo.FromPtr(r.Dependencies) {
nr := Relation{}
nr.From = r.Ref
if r.Ref == c.primaryComp.id {
totalDependencies++
}
nr.To = d
c.rels = append(c.rels, nr)
}
}
c.primaryComp.dependecies = totalDependencies
}

func (c *CdxDoc) assignSupplier(comp *cydx.Component) *Supplier {
Expand Down Expand Up @@ -588,19 +601,6 @@ func (c *CdxDoc) assignSupplier(comp *cydx.Component) *Supplier {
return &supplier
}

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

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

c.primaryComponent = true
c.primaryComponentID = c.doc.Metadata.Component.BOMRef
}

func (c *CdxDoc) parseCompositions() {
if c.doc.Compositions == nil {
c.compositions = map[string]string{}
Expand Down
4 changes: 2 additions & 2 deletions pkg/sbom/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ type Document interface {
Tools() []GetTool
Logs() []string

PrimaryComponent() bool

Lifecycles() []string
Manufacturer() Manufacturer
Supplier() GetSupplier

PrimaryComp() PrimaryComp
}
39 changes: 39 additions & 0 deletions pkg/sbom/primarycomp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 Interlynk.io
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sbom

type PrimaryComp interface {
Present() bool
ID() string
Dependencies() int
}

type primaryComp struct {
present bool
id string
dependecies int
}

func (pc *primaryComp) Present() bool {
return pc.present
}

func (pc *primaryComp) ID() string {
return pc.id
}

func (pc *primaryComp) Dependencies() int {
return pc.dependecies
}
63 changes: 23 additions & 40 deletions pkg/sbom/spdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,17 @@ var (
)

type SpdxDoc struct {
doc *spdx.Document
format FileFormat
ctx context.Context
SpdxSpec *Specs
Comps []GetComponent
authors []GetAuthor
SpdxTools []GetTool
Rels []GetRelation
logs []string
primaryComponent bool
primaryComponentID string
lifecycles string
doc *spdx.Document
format FileFormat
ctx context.Context
SpdxSpec *Specs
Comps []GetComponent
authors []GetAuthor
SpdxTools []GetTool
Rels []GetRelation
logs []string
primaryComp primaryComp
lifecycles string
}

func newSPDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Document, error) {
Expand Down Expand Up @@ -96,6 +95,10 @@ func newSPDXDoc(ctx context.Context, f io.ReadSeeker, format FileFormat) (Docume
return doc, err
}

func (c SpdxDoc) PrimaryComp() PrimaryComp {
return &c.primaryComp
}

func (s SpdxDoc) Spec() Spec {
return *s.SpdxSpec
}
Expand All @@ -120,10 +123,6 @@ func (s SpdxDoc) Logs() []string {
return s.logs
}

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

func (s SpdxDoc) Lifecycles() []string {
return []string{s.lifecycles}
}
Expand All @@ -140,8 +139,7 @@ func (s *SpdxDoc) parse() {
s.parseSpec()
s.parseAuthors()
s.parseTool()
s.parseRels()
s.parsePrimaryComponent()
s.parseRelsAndPrimaryComp()
s.parseComps()
}

Expand Down Expand Up @@ -230,7 +228,7 @@ func (s *SpdxDoc) parseComps() {
nc.DownloadLocation = sc.PackageDownloadLocation
}

nc.isPrimary = s.primaryComponentID == string(sc.PackageSPDXIdentifier)
nc.isPrimary = s.primaryComp.id == string(sc.PackageSPDXIdentifier)

fromRelsPresent := func(rels []GetRelation, id string) bool {
for _, r := range rels {
Expand Down Expand Up @@ -272,12 +270,12 @@ func (s *SpdxDoc) parseAuthors() {
}
}

func (s *SpdxDoc) parseRels() {
func (s *SpdxDoc) parseRelsAndPrimaryComp() {
s.Rels = []GetRelation{}

var err error
var aBytes, bBytes []byte
var primaryComponent string
var totalDependencies int

for _, r := range s.doc.Relationships {
if strings.ToUpper(r.Relationship) == spdx_common.TypeRelationshipDescribe {
Expand All @@ -286,6 +284,8 @@ func (s *SpdxDoc) parseRels() {
continue
}
primaryComponent = string(bBytes)
s.primaryComp.id = primaryComponent
s.primaryComp.present = true
}
}
// If no primary component found, return early
Expand Down Expand Up @@ -314,6 +314,7 @@ func (s *SpdxDoc) parseRels() {
From: primaryComponent,
To: string(bBytes),
}
totalDependencies++

s.Rels = append(s.Rels, nr)
} else {
Expand All @@ -325,6 +326,7 @@ func (s *SpdxDoc) parseRels() {
}
}
}
s.primaryComp.dependecies = totalDependencies
}

// creationInfo.Creators.Tool
Expand Down Expand Up @@ -641,25 +643,6 @@ func (s *SpdxDoc) addSupplierName(index int) string {
return ""
}

func (s *SpdxDoc) parsePrimaryComponent() {
pkgIDs := make(map[string]*spdx.Package)

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

for _, r := range s.doc.Relationships {
if strings.ToUpper(r.Relationship) == spdx_common.TypeRelationshipDescribe {
_, ok := pkgIDs[string(r.RefB.ElementRefID)]
if ok {
s.primaryComponentID = string(r.RefB.ElementRefID)
s.primaryComponent = true
return
}
}
}
}

type entity struct {
name string
email string
Expand Down
6 changes: 3 additions & 3 deletions pkg/scorer/ntia.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ func compWithUniqIDCheck(d sbom.Document, c *check) score {

func docWithDepedenciesCheck(d sbom.Document, c *check) score {
s := newScoreFromCheck(c)
withRelations := len(d.Relations())
if withRelations > 0 {
totalDependencies := d.PrimaryComp().Dependencies()
if totalDependencies > 0 {
s.setScore(10.0)
}
s.setDesc(fmt.Sprintf("doc has %d relationships ", withRelations))
s.setDesc(fmt.Sprintf("doc has %d dependencies ", totalDependencies))
return *s
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/scorer/quality.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func docWithCreatorCheck(d sbom.Document, c *check) score {
func docWithPrimaryComponentCheck(d sbom.Document, c *check) score {
s := newScoreFromCheck(c)

if d.PrimaryComponent() {
if d.PrimaryComp().Present() {
s.setScore(10.0)
s.setDesc("primary component found")
return *s
Expand Down

0 comments on commit 80ae86f

Please sign in to comment.