From ceb9f9d5e84e77d6a8fe71db2eba89bae0f69747 Mon Sep 17 00:00:00 2001 From: luotianqi777 Date: Sat, 6 Dec 2025 15:35:09 +0800 Subject: [PATCH] feat: bomsw hash check --- cmd/format/bomsw.go | 58 ++++++++++++++++++++++++++++++++++++++++++ opensca/model/bomsw.go | 5 ++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/cmd/format/bomsw.go b/cmd/format/bomsw.go index 86d980ce..908af3f8 100644 --- a/cmd/format/bomsw.go +++ b/cmd/format/bomsw.go @@ -1,8 +1,12 @@ package format import ( + "crypto/sha256" + "encoding/hex" "encoding/json" "io" + "sort" + "strings" "github.com/xmirrorsecurity/opensca-cli/v3/cmd/detail" "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model" @@ -20,6 +24,9 @@ func BomSWJson(report Report, out string) { func bomSWDoc(report Report) *model.BomSWDocument { doc := model.NewBomSWDocument(report.TaskInfo.AppName, "opensca-cli") + defer func() { + doc.SbomHashCheck = calculateSbomHashCheck(doc) + }() report.DepDetailGraph.ForEach(func(n *detail.DepDetailGraph) bool { @@ -52,3 +59,54 @@ func bomSWDoc(report Report) *model.BomSWDocument { return doc } + +func calculateSbomHashCheck(doc *model.BomSWDocument) string { + sha256Hash := sha256.New() + writeHash := func(v string) { sha256Hash.Write([]byte(v)) } + // basic info + writeHash(doc.Basic.DocumentName) + writeHash(doc.Basic.DocumentVersion) + writeHash(doc.Basic.DocumentTime) + writeHash(doc.Basic.SbomFormat) + writeHash(doc.Basic.ToolInfo) + writeHash(doc.Basic.SbomAuthor) + writeHash(doc.Basic.SbomAuthorComments) + writeHash(doc.Basic.SbomComments) + // components + for _, component := range doc.Software.Components { + writeHash(sortMapString(component.Author)) + writeHash(sortMapString(component.Provider)) + writeHash(component.Name) + writeHash(component.Version) + for _, hash := range component.HashValue { + writeHash(hash.Algorithm + ":" + hash.Value) + } + writeHash(component.ID) + for _, lic := range component.License { + writeHash(lic) + } + writeHash(component.Timestamp) + } + // dependencies + for _, deps := range doc.Software.Dependencies { + writeHash(deps.Ref) + for _, depsOn := range deps.DependsOn { + writeHash(depsOn.Ref) + } + } + hashStr := hex.EncodeToString(sha256Hash.Sum(nil)[:]) + return hashStr +} + +func sortMapString(v map[string]string) string { + keys := []string{} + for key := range v { + keys = append(keys, key) + } + sort.Strings(keys) + res := strings.Builder{} + for _, key := range keys { + res.WriteString(key + ":" + v[key]) + } + return res.String() +} diff --git a/opensca/model/bomsw.go b/opensca/model/bomsw.go index 1cde5304..cb2ab312 100644 --- a/opensca/model/bomsw.go +++ b/opensca/model/bomsw.go @@ -5,8 +5,9 @@ import ( ) type BomSWDocument struct { - Basic swBasicInfo `json:"documentBasicInfo"` - Software swSoftwareCompositionInfo `json:"softwareCompositionInfo"` + Basic swBasicInfo `json:"documentBasicInfo"` + Software swSoftwareCompositionInfo `json:"softwareCompositionInfo"` + SbomHashCheck string `json:"BOM-SW1.0-SBOM-HASH"` } type swBasicInfo struct {