11package format
22
33import (
4+ "crypto/sha256"
5+ "encoding/hex"
46 "encoding/json"
57 "io"
8+ "sort"
9+ "strings"
610
711 "github.com/xmirrorsecurity/opensca-cli/v3/cmd/detail"
812 "github.com/xmirrorsecurity/opensca-cli/v3/opensca/model"
@@ -20,6 +24,9 @@ func BomSWJson(report Report, out string) {
2024func bomSWDoc (report Report ) * model.BomSWDocument {
2125
2226 doc := model .NewBomSWDocument (report .TaskInfo .AppName , "opensca-cli" )
27+ defer func () {
28+ doc .SbomHashCheck = calculateSbomHashCheck (doc )
29+ }()
2330
2431 report .DepDetailGraph .ForEach (func (n * detail.DepDetailGraph ) bool {
2532
@@ -52,3 +59,54 @@ func bomSWDoc(report Report) *model.BomSWDocument {
5259
5360 return doc
5461}
62+
63+ func calculateSbomHashCheck (doc * model.BomSWDocument ) string {
64+ sha256Hash := sha256 .New ()
65+ writeHash := func (v string ) { sha256Hash .Write ([]byte (v )) }
66+ // basic info
67+ writeHash (doc .Basic .DocumentName )
68+ writeHash (doc .Basic .DocumentVersion )
69+ writeHash (doc .Basic .DocumentTime )
70+ writeHash (doc .Basic .SbomFormat )
71+ writeHash (doc .Basic .ToolInfo )
72+ writeHash (doc .Basic .SbomAuthor )
73+ writeHash (doc .Basic .SbomAuthorComments )
74+ writeHash (doc .Basic .SbomComments )
75+ // components
76+ for _ , component := range doc .Software .Components {
77+ writeHash (sortMapString (component .Author ))
78+ writeHash (sortMapString (component .Provider ))
79+ writeHash (component .Name )
80+ writeHash (component .Version )
81+ for _ , hash := range component .HashValue {
82+ writeHash (hash .Algorithm + ":" + hash .Value )
83+ }
84+ writeHash (component .ID )
85+ for _ , lic := range component .License {
86+ writeHash (lic )
87+ }
88+ writeHash (component .Timestamp )
89+ }
90+ // dependencies
91+ for _ , deps := range doc .Software .Dependencies {
92+ writeHash (deps .Ref )
93+ for _ , depsOn := range deps .DependsOn {
94+ writeHash (depsOn .Ref )
95+ }
96+ }
97+ hashStr := hex .EncodeToString (sha256Hash .Sum (nil )[:])
98+ return hashStr
99+ }
100+
101+ func sortMapString (v map [string ]string ) string {
102+ keys := []string {}
103+ for key := range v {
104+ keys = append (keys , key )
105+ }
106+ sort .Strings (keys )
107+ res := strings.Builder {}
108+ for _ , key := range keys {
109+ res .WriteString (key + ":" + v [key ])
110+ }
111+ return res .String ()
112+ }
0 commit comments