@@ -14,14 +14,16 @@ import (
1414 "github.com/spdx/tools-golang/tagvalue"
1515 "golang.org/x/xerrors"
1616
17+ "github.com/aquasecurity/trivy/pkg/digest"
18+ "github.com/aquasecurity/trivy/pkg/log"
1719 "github.com/aquasecurity/trivy/pkg/sbom/core"
1820)
1921
2022type SPDX struct {
2123 * core.BOM
2224
23- trivySBOM bool
24- pkgFilePaths map [common.ElementID ]string
25+ trivySBOM bool
26+ pkgFiles map [common.ElementID ]core. File
2527}
2628
2729func NewTVDecoder (r io.Reader ) * TVDecoder {
@@ -68,8 +70,8 @@ func (s *SPDX) UnmarshalJSON(b []byte) error {
6870func (s * SPDX ) unmarshal (spdxDocument * spdx.Document ) error {
6971 s .trivySBOM = s .isTrivySBOM (spdxDocument )
7072
71- if s .pkgFilePaths == nil {
72- s .pkgFilePaths = make (map [common.ElementID ]string )
73+ if s .pkgFiles == nil {
74+ s .pkgFiles = make (map [common.ElementID ]core. File )
7375 }
7476
7577 // Parse files and find file paths for packages
@@ -125,7 +127,10 @@ func (s *SPDX) parseFiles(spdxDocument *spdx.Document) {
125127 if ok {
126128 // Save filePaths for packages
127129 // Insert filepath will be later
128- s .pkgFilePaths [rel .RefA .ElementRefID ] = file .FileName
130+ s .pkgFiles [rel .RefA .ElementRefID ] = core.File {
131+ Path : file .FileName ,
132+ Digests : s .unmarshalChecksums (file .Checksums ),
133+ }
129134 }
130135 continue
131136 }
@@ -184,15 +189,24 @@ func (s *SPDX) parsePackage(spdxPkg spdx.Package) (*core.Component, error) {
184189 }
185190
186191 // Files
187- // TODO: handle checksums as well
188- if path , ok := s . pkgFilePaths [ spdxPkg . PackageSPDXIdentifier ]; ok {
189- component . Files = []core. File {
190- { Path : path },
191- }
192+ var file core. File
193+ // Take filePath + digest from Files components
194+ if f , ok := s . pkgFiles [ spdxPkg . PackageSPDXIdentifier ]; ok {
195+ file = f
196+ // Take filePath + digest from Package.Files (old format)
192197 } else if len (spdxPkg .Files ) > 0 {
193- component .Files = []core.File {
194- {Path : spdxPkg .Files [0 ].FileName }, // Take the first file name
198+ spdxFile := spdxPkg .Files [0 ] // Take the first file name
199+ file = core.File {
200+ Path : spdxFile .FileName ,
201+ Digests : s .unmarshalChecksums (spdxFile .Checksums ),
195202 }
203+ // Take digest from Package.Checksums
204+ } else if len (spdxPkg .PackageChecksums ) > 0 {
205+ file .Digests = s .unmarshalChecksums (spdxPkg .PackageChecksums )
206+ }
207+
208+ if ! file .IsEmpty () {
209+ component .Files = append (component .Files , file )
196210 }
197211
198212 // Trivy stores properties in Annotations
@@ -232,6 +246,31 @@ func (s *SPDX) parsePackage(spdxPkg spdx.Package) (*core.Component, error) {
232246 return component , nil
233247}
234248
249+ func (s * SPDX ) unmarshalChecksums (checksums []spdx.Checksum ) []digest.Digest {
250+ if checksums == nil {
251+ return nil
252+ }
253+ var digests []digest.Digest
254+ for _ , h := range checksums {
255+ var alg digest.Algorithm
256+ switch h .Algorithm {
257+ case common .SHA1 :
258+ alg = digest .SHA1
259+ case common .SHA256 :
260+ alg = digest .SHA256
261+ case common .SHA512 :
262+ alg = digest .SHA512
263+ case common .MD5 :
264+ alg = digest .MD5
265+ default :
266+ log .Warn ("Unsupported hash algorithm" , log .String ("algorithm" , string (h .Algorithm )))
267+ continue
268+ }
269+ digests = append (digests , digest .NewDigestFromString (alg , h .Value ))
270+ }
271+ return digests
272+ }
273+
235274func (s * SPDX ) parseType (pkg spdx.Package ) core.ComponentType {
236275 id := string (pkg .PackageSPDXIdentifier )
237276 switch {
0 commit comments