Skip to content

Commit

Permalink
feat: Add purl support for SBOMs (#3373)
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonyharrison committed Oct 9, 2023
1 parent 2847879 commit fa8e6d8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 14 deletions.
51 changes: 42 additions & 9 deletions cve_bin_tool/sbom_manager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
from pathlib import Path

import defusedxml.ElementTree as ET
from lib4sbom.parser import SBOMParser
from packageurl import PackageURL

from cve_bin_tool.cvedb import CVEDB
from cve_bin_tool.input_engine import TriageData
from cve_bin_tool.log import LOGGER
from cve_bin_tool.util import ProductInfo, Remarks
from cve_bin_tool.validator import validate_cyclonedx, validate_spdx

from .cyclonedx_parser import CycloneParser
from .spdx_parser import SPDXParser
from .swid_parser import SWIDParser


Expand Down Expand Up @@ -47,15 +48,11 @@ def scan_file(self) -> dict[ProductInfo, TriageData]:
modules = []
try:
if Path(self.filename).exists():
if self.type == "spdx":
spdx = SPDXParser(self.validate)
modules = spdx.parse(self.filename)
elif self.type == "cyclonedx":
cyclone = CycloneParser(self.validate)
modules = cyclone.parse(self.filename)
elif self.type == "swid":
if self.type == "swid":
swid = SWIDParser(self.validate)
modules = swid.parse(self.filename)
else:
modules = self.parse_sbom()
except (KeyError, FileNotFoundError, ET.ParseError) as e:
LOGGER.debug(e, exc_info=True)

Expand Down Expand Up @@ -100,6 +97,42 @@ def get_vendor(self, product: str) -> list:
vendorlist.append("UNKNOWN")
return vendorlist

def parse_sbom(self):
"""parse SBOM, using PURL identifiers preferentially if found"""
# Set up SBOM parser
sbom_parser = SBOMParser(sbom_type=self.type)
# Load SBOM
sbom_parser.parse_file(self.filename)
modules = []
if self.validate and self.filename.endswith(".xml"):
# Only for XML files
if sbom_parser.get_type() == "spdx":
valid_xml = validate_spdx(self.filename)
else:
valid_xml = validate_cyclonedx(self.filename)
if not valid_xml:
return modules
packages = [x for x in sbom_parser.get_sbom()["packages"].values()]
LOGGER.debug(f"Parsed SBOM {self.filename} {packages}")
for package in packages:
purl_found = False
# If PURL record found, use this data in preference to package data
ext_ref = package.get("externalreference")
if ext_ref is not None:
for ref in ext_ref:
if ref[1] == "purl":
# Process purl identifier
purl_info = PackageURL.from_string(ref[2]).to_dict()
modules.append([purl_info["name"], purl_info["version"]])
purl_found = True
if not purl_found:
if package.get("version") is not None:
modules.append([package["name"], package["version"]])
else:
LOGGER.debug(f"No version found in {package}")
LOGGER.debug(f"Parsed SBOM {self.filename} {modules}")
return modules


if __name__ == "__main__":
import sys
Expand Down
1 change: 1 addition & 0 deletions requirements.csv
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ python_not_in_db,packaging
python_not_in_db,importlib_resources
vsajip_not_in_db,python-gnupg
anthonyharrison_not_in_db,lib4sbom
the_purl_authors_not_in_db,packageurl-python
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ importlib_metadata>=3.6; python_version < "3.10"
importlib_resources; python_version < "3.9"
jinja2>=2.11.3
jsonschema>=3.0.2
lib4sbom>=0.3.0
lib4sbom>=0.5.0
python-gnupg
packageurl-python
packaging<22.0
plotly
pyyaml>=5.4
Expand Down
4 changes: 0 additions & 4 deletions test/test_sbom.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ class TestSBOM:
"default": {"remarks": Remarks.NewFound, "comments": "", "severity": ""},
"paths": {""},
},
ProductInfo(vendor="apache", product="jena", version="3.12.0"): {
"default": {"remarks": Remarks.NewFound, "comments": "", "severity": ""},
"paths": {""},
},
ProductInfo(vendor="saxon", product="saxon", version="8.8"): {
"default": {"remarks": Remarks.NewFound, "comments": "", "severity": ""},
"paths": {""},
Expand Down

0 comments on commit fa8e6d8

Please sign in to comment.