Skip to content

Commit

Permalink
add support for v3 framing sbom
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Kumar Sahu <[email protected]>

add fsct functionalities

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add omnibor id

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add report and score for fsct

Signed-off-by: Vivek Kumar Sahu <[email protected]>

fix fsct

Signed-off-by: Vivek Kumar Sahu <[email protected]>

fix small issues

Signed-off-by: Vivek Kumar Sahu <[email protected]>

sort o/p and make table colorful

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add test

Signed-off-by: Vivek Kumar Sahu <[email protected]>

fix variables

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add many more tests for spdx and cyclonedx

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add test for dependencies

Signed-off-by: Vivek Kumar Sahu <[email protected]>

fix spdx and cyclonedx dependency

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add remaining comp test

Signed-off-by: Vivek Kumar Sahu <[email protected]>

add test for uniq ids

Signed-off-by: Vivek Kumar Sahu <[email protected]>

fix golang ci

Signed-off-by: Vivek Kumar Sahu <[email protected]>
  • Loading branch information
viveksahu26 committed Sep 26, 2024
1 parent 989c02b commit c5af10a
Show file tree
Hide file tree
Showing 31 changed files with 3,462 additions and 194 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
with:
go-version: '1.22'
check-latest: true
go-version-file: go.mod
cache: false

- name: Run golangci-lint
uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1
Expand Down
8 changes: 8 additions & 0 deletions cmd/compliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ var complianceCmd = &cobra.Command{
# Check a OpenChain Telco compliance against a SBOM in a JSON output
sbomqs compliance --oct --json samples/sbomqs-spdx-syft.json
# Check a V3 Framing document compliance against a SBOM in a table output
sbomqs compliance --fsct-v3 <sbom>
# Check a V3 Framing document compliance against a SBOM in a JSON output
sbomqs compliance --fsct-v3 -j <sbom>
`,
Args: func(cmd *cobra.Command, args []string) error {
if err := cobra.ExactArgs(1)(cmd, args); err != nil {
Expand Down Expand Up @@ -75,6 +81,7 @@ func setupEngineParams(cmd *cobra.Command, args []string) *engine.Params {
// engParams.Ntia, _ = cmd.Flags().GetBool("ntia")
engParams.Bsi, _ = cmd.Flags().GetBool("bsi")
engParams.Oct, _ = cmd.Flags().GetBool("oct")
engParams.Fsct, _ = cmd.Flags().GetBool("fsct")

engParams.Debug, _ = cmd.Flags().GetBool("debug")

Expand All @@ -101,4 +108,5 @@ func init() {
complianceCmd.Flags().BoolP("bsi", "c", false, "BSI TR-03183-2 v1.1 compliance")
// complianceCmd.MarkFlagsMutuallyExclusive("ntia", "cra")
complianceCmd.Flags().BoolP("oct", "t", false, "OpenChainTelco compliance")
complianceCmd.Flags().BoolP("fsct", "f", false, "V3 Framing document compliance")
}
98 changes: 50 additions & 48 deletions pkg/compliance/bsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const (
SBOM_DELIVERY_METHOD
SBOM_SCOPE
PACK_INFO
SBOM_TYPE
PACK_EXT_REF
)

Expand Down Expand Up @@ -120,7 +121,7 @@ func bsiSpec(doc sbom.Document) *db.Record {
result = v
score = 10.0
}
return db.NewRecordStmt(SBOM_SPEC, "doc", result, score)
return db.NewRecordStmt(SBOM_SPEC, "doc", result, score, "")
}

func bsiSpecVersion(doc sbom.Document) *db.Record {
Expand All @@ -144,7 +145,7 @@ func bsiSpecVersion(doc sbom.Document) *db.Record {
}
}

return db.NewRecordStmt(SBOM_SPEC_VERSION, "doc", result, score)
return db.NewRecordStmt(SBOM_SPEC_VERSION, "doc", result, score, "")
}

func bsiBuildPhase(doc sbom.Document) *db.Record {
Expand All @@ -159,7 +160,7 @@ func bsiBuildPhase(doc sbom.Document) *db.Record {
score = 10.0
}

return db.NewRecordStmt(SBOM_BUILD, "doc", result, score)
return db.NewRecordStmt(SBOM_BUILD, "doc", result, score, "")
}

func bsiSbomDepth(doc sbom.Document) *db.Record {
Expand All @@ -173,26 +174,26 @@ func bsiSbomDepth(doc sbom.Document) *db.Record {
result = fmt.Sprintf("doc has %d dependencies", totalDependencies)

if len(doc.Relations()) == 0 {
return db.NewRecordStmt(SBOM_DEPTH, "doc", "no-relationships", 0.0)
return db.NewRecordStmt(SBOM_DEPTH, "doc", "no-relationships", 0.0, "")
}

primary, _ := lo.Find(doc.Components(), func(c sbom.GetComponent) bool {
return c.IsPrimaryComponent()
})

if !primary.HasRelationShips() {
return db.NewRecordStmt(SBOM_DEPTH, "doc", "no-primary-relationships", 0.0)
return db.NewRecordStmt(SBOM_DEPTH, "doc", "no-primary-relationships", 0.0, "")
}

if primary.RelationShipState() == "complete" {
return db.NewRecordStmt(SBOM_DEPTH, "doc", "complete", 10.0)
return db.NewRecordStmt(SBOM_DEPTH, "doc", "complete", 10.0, "")
}

if primary.HasRelationShips() {
return db.NewRecordStmt(SBOM_DEPTH, "doc", "unattested-has-relationships", 5.0)
return db.NewRecordStmt(SBOM_DEPTH, "doc", "unattested-has-relationships", 5.0, "")
}

return db.NewRecordStmt(SBOM_DEPTH, "doc", result, score)
return db.NewRecordStmt(SBOM_DEPTH, "doc", result, score, "")
}

func bsiCreator(doc sbom.Document) *db.Record {
Expand All @@ -208,7 +209,7 @@ func bsiCreator(doc sbom.Document) *db.Record {
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}

supplier := doc.Supplier()
Expand All @@ -220,7 +221,7 @@ func bsiCreator(doc sbom.Document) *db.Record {
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}

if supplier.GetURL() != "" {
Expand All @@ -229,20 +230,20 @@ func bsiCreator(doc sbom.Document) *db.Record {
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}

if supplier.GetContacts() != nil {
for _, contact := range supplier.GetContacts() {
if contact.Email() != "" {
result = contact.Email()
if contact.GetEmail() != "" {
result = contact.GetEmail()
score = 10.0
break
}
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}
}
}
Expand All @@ -256,7 +257,7 @@ func bsiCreator(doc sbom.Document) *db.Record {
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}

if manufacturer.GetURL() != "" {
Expand All @@ -265,24 +266,24 @@ func bsiCreator(doc sbom.Document) *db.Record {
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}

if manufacturer.GetContacts() != nil {
for _, contact := range manufacturer.GetContacts() {
if contact.Email() != "" {
result = contact.Email()
if contact.GetEmail() != "" {
result = contact.GetEmail()
score = 10.0
break
}
}

if result != "" {
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score)
return db.NewRecordStmt(SBOM_CREATOR, "doc", result, score, "")
}
}
}
return db.NewRecordStmt(SBOM_CREATOR, "doc", "", 0.0)
return db.NewRecordStmt(SBOM_CREATOR, "doc", "", 0.0, "")
}

func bsiTimestamp(doc sbom.Document) *db.Record {
Expand All @@ -293,24 +294,24 @@ func bsiTimestamp(doc sbom.Document) *db.Record {
score = 10.0
}

return db.NewRecordStmt(SBOM_TIMESTAMP, "doc", result, score)
return db.NewRecordStmt(SBOM_TIMESTAMP, "doc", result, score, "")
}

func bsiSbomURI(doc sbom.Document) *db.Record {
uri := doc.Spec().URI()

if uri != "" {
return db.NewRecordStmt(SBOM_URI, "doc", uri, 10.0)
return db.NewRecordStmt(SBOM_URI, "doc", uri, 10.0, "")
}

return db.NewRecordStmt(SBOM_URI, "doc", "", 0)
return db.NewRecordStmt(SBOM_URI, "doc", "", 0, "")
}

func bsiComponents(doc sbom.Document) []*db.Record {
records := []*db.Record{}

if len(doc.Components()) == 0 {
records := append(records, db.NewRecordStmt(SBOM_COMPONENTS, "doc", "", 0.0))
records := append(records, db.NewRecordStmt(SBOM_COMPONENTS, "doc", "", 0.0, ""))
return records
}
// map package ID to Package Name
Expand All @@ -331,33 +332,34 @@ func bsiComponents(doc sbom.Document) []*db.Record {
records = append(records, bsiComponentOtherUniqIDs(component))
}

records = append(records, db.NewRecordStmt(SBOM_COMPONENTS, "doc", "present", 10.0))
records = append(records, db.NewRecordStmt(SBOM_COMPONENTS, "doc", "present", 10.0, ""))

return records
}

func bsiComponentDepth(component sbom.GetComponent) *db.Record {
if !component.HasRelationShips() {
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "no-relationships", 0.0)
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "no-relationships", 0.0, "")
}

if component.RelationShipState() == "complete" {
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "complete", 10.0)
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "complete", 10.0, "")
}

if component.HasRelationShips() {
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "unattested-has-relationships", 5.0)
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "unattested-has-relationships", 5.0, "")
}

return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "non-compliant", 0.0)
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "non-compliant", 0.0, "")
}

func bsiComponentLicense(component sbom.GetComponent) *db.Record {
licenses := component.Licenses()
score := 0.0

if len(licenses) == 0 {
return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "not-compliant", score)
// fmt.Printf("component %s : %s has no licenses\n", component.Name(), component.Version())
return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "not-compliant", score, "")
}

var spdx, aboutcode, custom int
Expand Down Expand Up @@ -385,10 +387,10 @@ func bsiComponentLicense(component sbom.GetComponent) *db.Record {

if total != len(licenses) {
score = 0.0
return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "not-compliant", score)
return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "not-compliant", score, "")
}

return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "compliant", 10.0)
return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "compliant", 10.0, "")
}

func bsiComponentSourceHash(component sbom.GetComponent) *db.Record {
Expand Down Expand Up @@ -462,27 +464,27 @@ func bsiComponentHash(component sbom.GetComponent) *db.Record {
}
}

return db.NewRecordStmt(COMP_HASH, component.GetName(), result, score)
return db.NewRecordStmt(COMP_HASH, component.GetID(), result, score, "")
}

func bsiComponentVersion(component sbom.GetComponent) *db.Record {
result := component.GetVersion()

if result != "" {
return db.NewRecordStmt(COMP_VERSION, component.GetName(), result, 10.0)
return db.NewRecordStmt(COMP_VERSION, component.GetID(), result, 10.0, "")
}

return db.NewRecordStmt(COMP_VERSION, component.GetName(), "", 0.0)
return db.NewRecordStmt(COMP_VERSION, component.GetID(), "", 0.0, "")
}

func bsiComponentName(component sbom.GetComponent) *db.Record {
result := component.GetName()

if result != "" {
return db.NewRecordStmt(COMP_NAME, component.GetName(), result, 10.0)
return db.NewRecordStmt(COMP_NAME, component.GetID(), result, 10.0, "")
}

return db.NewRecordStmt(COMP_NAME, component.GetName(), "", 0.0)
return db.NewRecordStmt(COMP_NAME, component.GetID(), "", 0.0, "")
}

func bsiComponentCreator(component sbom.GetComponent) *db.Record {
Expand All @@ -497,7 +499,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}

if supplier.GetURL() != "" {
Expand All @@ -506,20 +508,20 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}

if supplier.GetContacts() != nil {
for _, contact := range supplier.GetContacts() {
if contact.Email() != "" {
result = contact.Email()
if contact.GetEmail() != "" {
result = contact.GetEmail()
score = 10.0
break
}
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}
}
}
Expand All @@ -533,7 +535,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}

if manufacturer.GetURL() != "" {
Expand All @@ -542,23 +544,23 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}

if manufacturer.GetContacts() != nil {
for _, contact := range manufacturer.GetContacts() {
if contact.Email() != "" {
result = contact.Email()
if contact.GetEmail() != "" {
result = contact.GetEmail()
score = 10.0
break
}
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
}
}
}

return db.NewRecordStmt(COMP_CREATOR, component.GetName(), "", 0.0)
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), "", 0.0, "")
}
Loading

0 comments on commit c5af10a

Please sign in to comment.