Skip to content

Commit

Permalink
re structure fields to ntia complaince report
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Kumar Sahu <[email protected]>
  • Loading branch information
viveksahu26 committed Aug 7, 2024
1 parent 4240071 commit 0a6bd27
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 83 deletions.
109 changes: 60 additions & 49 deletions pkg/compliance/ntia.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ package compliance

import (
"context"
"strings"
"fmt"
"time"

"github.com/interlynk-io/sbomqs/pkg/logger"
"github.com/interlynk-io/sbomqs/pkg/sbom"
"github.com/samber/lo"
)

func ntiaResult(ctx context.Context, doc sbom.Document, fileName string, outFormat string) {
Expand All @@ -30,8 +29,7 @@ func ntiaResult(ctx context.Context, doc sbom.Document, fileName string, outForm

db := newDB()

db.addRecord(ntiaSpec(doc))
db.addRecord(ntiaSpecVersion(doc))
db.addRecord(ntiaAutomationSpec(doc))
db.addRecord(ntiaSbomCreator(doc))
db.addRecord(ntiaSbomCreatedTimestamp(doc))
db.addRecords(ntiaComponents(doc))
Expand All @@ -53,41 +51,17 @@ func ntiaResult(ctx context.Context, doc sbom.Document, fileName string, outForm
}

// format
func ntiaSpec(doc sbom.Document) *record {
v := doc.Spec().GetSpecType()
v_to_lower := strings.Trim(strings.ToLower(v), " ")
result, score := "", 0.0

if v_to_lower == "spdx" {
result = v
score = 10.0
} else if v_to_lower == "cyclonedx" {
result = v
score = 10.0
}
return newRecordStmt(SBOM_SPEC, "SBOM format", result, score)
}

func ntiaSpecVersion(doc sbom.Document) *record {
func ntiaAutomationSpec(doc sbom.Document) *record {
spec := doc.Spec().GetSpecType()
version := doc.Spec().GetVersion()

result, score := "", 0.0

if spec == "spdx" {
count := lo.Count(valid_cra_spdx_versions, version)
if count > 0 {
result = version
score = 10.0
}
} else if spec == "cyclonedx" {
count := lo.Count(valid_cra_cdx_versions, version)
if count > 0 {
result = version
score = 10.0
}
if fileFormat := doc.Spec().FileFormat(); fileFormat == "json" || fileFormat == "tag-value" {
result = spec + ", " + fileFormat
score = 10.0
} else {
result = spec + ", " + fileFormat
}
return newRecordStmt(SBOM_SPEC_VERSION, "SBOM format", result, score)
return newRecordStmt(SBOM_MACHINE_FORMAT, "Automation Support", result, score)
}

// Required Sbom stuffs
Expand All @@ -106,7 +80,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}
}
}
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)

} else if spec == "cyclonedx" {

Expand All @@ -119,7 +93,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

supplier := doc.Supplier()
Expand All @@ -131,7 +105,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

if supplier.GetUrl() != "" {
Expand All @@ -140,7 +114,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

if supplier.GetContacts() != nil {
Expand All @@ -153,7 +127,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}
}
}
Expand All @@ -167,7 +141,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

if manufacturer.Url() != "" {
Expand All @@ -176,7 +150,7 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

if manufacturer.Contacts() != nil {
Expand All @@ -189,12 +163,12 @@ func ntiaSbomCreator(doc sbom.Document) *record {
}

if result != "" {
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}
}
}
}
return newRecordStmt(SBOM_CREATOR, "doc", result, score)
return newRecordStmt(SBOM_CREATOR, "SBOM Data Fields", result, score)
}

func ntiaSbomCreatedTimestamp(doc sbom.Document) *record {
Expand All @@ -209,7 +183,7 @@ func ntiaSbomCreatedTimestamp(doc sbom.Document) *record {
score = 10.0
}
}
return newRecordStmt(SBOM_TIMESTAMP, "doc", result, score)
return newRecordStmt(SBOM_TIMESTAMP, "SBOM Data Fields", result, score)
}

// Required component stuffs
Expand All @@ -222,14 +196,14 @@ func ntiaComponents(doc sbom.Document) []*record {
}

for _, component := range doc.Components() {
records = append(records, ntiaComponentCreator(doc, component))
records = append(records, ntiaComponentName(component))
records = append(records, ntiaComponentCreator(doc, component))
records = append(records, ntiaComponentVersion(component))
records = append(records, ntiaComponentOtherUniqIds(doc, component))
records = append(records, ntiaComponentDependencies(doc, component))

}
records = append(records, newRecordStmt(SBOM_COMPONENTS, "doc", "present", 10.0))
records = append(records, newRecordStmt(SBOM_COMPONENTS, "SBOM Data Fields", "present", 10.0))
return records
}

Expand Down Expand Up @@ -367,9 +341,46 @@ func ntiaComponentOtherUniqIds(doc sbom.Document, component sbom.GetComponent) *
spec := doc.Spec().GetSpecType()

if spec == "spdx" {
return octPackageExternalRefs(component)
result, score, totalElements, containPurlElement := "", 0.0, 0, 0

if extRefs := component.ExternalReferences(); extRefs != nil {
for _, extRef := range extRefs {
totalElements++
result = extRef.GetRefType()
if result == "purl" {
containPurlElement++
}
}
}
if containPurlElement != 0 {
score = (float64(containPurlElement) / float64(totalElements)) * 10.0
x := fmt.Sprintf(":(%d/%d)", containPurlElement, totalElements)
result = result + x
}
return newRecordStmt(COMP_OTHER_UNIQ_IDS, component.GetID(), result, score)
} else if spec == "cyclonedx" {
return craComponentOtherUniqIds(component)
result := ""
score := 0.0

purl := component.GetPurls()

if len(purl) > 0 {
result = string(purl[0])
score = 10.0

return newRecordStmtOptional(COMP_OTHER_UNIQ_IDS, component.GetID(), result, score)
}

cpes := component.GetCpes()

if len(cpes) > 0 {
result = string(cpes[0])
score = 10.0

return newRecordStmtOptional(COMP_OTHER_UNIQ_IDS, component.GetID(), result, score)
}

return newRecordStmtOptional(COMP_OTHER_UNIQ_IDS, component.GetID(), "", 0.0)
}
return newRecordStmt(COMP_OTHER_UNIQ_IDS, component.GetID(), "", 0.0)
}
Expand Down
26 changes: 12 additions & 14 deletions pkg/compliance/ntia_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@ import (
)

var ntiaSectionDetails = map[int]ntiaSection{
SBOM_SPEC: {Title: "SBOM Format", Id: "1", Required: true, DataField: "SBOM data format"},
SBOM_SPEC_VERSION: {Title: "SPDX Format", Id: "1.1", Required: true, DataField: "Spec version"},
SBOM_CREATOR: {Title: "Required fields sboms ", Id: "2", Required: true, DataField: "creator of sbom"},
SBOM_TIMESTAMP: {Title: "Required fields sboms", Id: "2.1", Required: true, DataField: "SBOM timestamp"},
SBOM_COMPONENTS: {Title: "Required sbom component", Id: "2.2", Required: true, DataField: "SBOM components"},
COMP_NAME: {Title: "Required fields components", Id: "3", Required: true, DataField: "component name"},
COMP_VERSION: {Title: "Required fields components", Id: "3.1", Required: true, DataField: "component version"},
COMP_DEPTH: {Title: "Required fields components", Id: "3.2", Required: true, DataField: "Dependencies on other components"},
COMP_CREATOR: {Title: "Required fields component", Id: "3.3", Required: true, DataField: "component creator"},
PACK_SUPPLIER: {Title: "Required fields component", Id: "3.3", Required: true, DataField: "Package supplier"},
COMP_OTHER_UNIQ_IDS: {Title: "Required fields component", Id: "3.5", Required: true, DataField: "Other unique identifiers"},
PACK_EXT_REF: {Title: "Required fields component", Id: "3.5", Required: true, DataField: "Package external References"},
SBOM_MACHINE_FORMAT: {Title: "Automation Support", Id: "2.1", Required: true, DataField: "Machine-Readable Formats"},
SBOM_CREATOR: {Title: "Required fields sboms ", Id: "1.1", Required: true, DataField: "Author"},
SBOM_TIMESTAMP: {Title: "Required fields sboms", Id: "1.2", Required: true, DataField: "Timestamp"},
SBOM_COMPONENTS: {Title: "Required sbom component", Id: "1.4", Required: true, DataField: "Packages"},
COMP_NAME: {Title: "Required fields components", Id: "1.5", Required: true, DataField: "Package Name"},
COMP_DEPTH: {Title: "Required fields components", Id: "1.3", Required: true, DataField: "Dependencies on other components"},
COMP_CREATOR: {Title: "Required fields component", Id: "1.6", Required: true, DataField: "Package Supplier"},
PACK_SUPPLIER: {Title: "Required fields component", Id: "1.6", Required: true, DataField: "Package Supplier"},
COMP_VERSION: {Title: "Required fields components", Id: "1.7", Required: true, DataField: "Package Version"},
COMP_OTHER_UNIQ_IDS: {Title: "Required fields component", Id: "1.8", Required: true, DataField: "Other Uniq IDs"},
}

type ntiaSection struct {
Expand All @@ -48,7 +46,7 @@ type ntiaComplianceReport struct {

func newNtiaJsonReport() *ntiaComplianceReport {
return &ntiaComplianceReport{
Name: "NTIA Report",
Name: "NTIA Compliance Report",
Subtitle: "Part 2: Software Bill of Materials (SBOM)",
Revision: "",
Run: run{
Expand Down Expand Up @@ -120,7 +118,7 @@ func ntiaDetailedReport(db *db, fileName string) {
fmt.Printf("NTIA Report\n")
fmt.Printf("Compliance score by Interlynk Score:%0.1f RequiredScore:%0.1f OptionalScore:%0.1f for %s\n", score.totalScore(), score.totalRequiredScore(), score.totalOptionalScore(), fileName)
fmt.Printf("* indicates optional fields\n")
table.SetHeader([]string{"ElementId", "Section", "Datafield", "Element Result", "Score"})
table.SetHeader([]string{"ELEMENT ID", "Section ID", "NTIA minimum elements", "Result", "Score"})
table.SetRowLine(true)
table.SetAutoMergeCellsByColumnIndex([]int{0})

Expand Down
22 changes: 2 additions & 20 deletions pkg/compliance/ntia_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestNtiaSpdxSbomPass(t *testing.T) {
expected desiredNtia
}{
{
actual: ntiaSpec(doc),
actual: ntiaAutomationSpec(doc),
expected: desiredNtia{
score: 10.0,
result: "spdx",
Expand All @@ -87,15 +87,6 @@ func TestNtiaSpdxSbomPass(t *testing.T) {
id: "doc",
},
},
{
actual: ntiaSpecVersion(doc),
expected: desiredNtia{
score: 10.0,
result: "SPDX-2.3",
key: SBOM_SPEC_VERSION,
id: "SBOM format",
},
},
{
actual: ntiaSbomCreatedTimestamp(doc),
expected: desiredNtia{
Expand Down Expand Up @@ -212,7 +203,7 @@ func TestNtiaCdxSbomPass(t *testing.T) {
expected desiredNtia
}{
{
actual: ntiaSpec(doc),
actual: ntiaAutomationSpec(doc),
expected: desiredNtia{
score: 10.0,
result: "cyclonedx",
Expand All @@ -229,15 +220,6 @@ func TestNtiaCdxSbomPass(t *testing.T) {
id: "doc",
},
},
{
actual: ntiaSpecVersion(doc),
expected: desiredNtia{
score: 10.0,
result: "1.4",
key: SBOM_SPEC_VERSION,
id: "SBOM format",
},
},
{
actual: ntiaSbomCreatedTimestamp(doc),
expected: desiredNtia{
Expand Down

0 comments on commit 0a6bd27

Please sign in to comment.