Skip to content

Commit

Permalink
sbomnix: add more properties to SPDX and CDX sboms
Browse files Browse the repository at this point in the history
- Add more properties to SPDX sbom: package summary, downloadLocation
- Add more properties to CDX sbom: component description, fetch_url,
  homepage
- Read 'unfree' and 'description' from each nix package meta information
  if available

Signed-off-by: Henri Rosten <[email protected]>
  • Loading branch information
henrirosten committed Feb 16, 2023
1 parent 92bf2f7 commit 4666d6e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
51 changes: 38 additions & 13 deletions sbomnix/sbomdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,18 @@ def _drv_to_spdx_license_list(drv):

def _drv_to_spdx_extrefs(drv):
extrefs = []
cpe_ref = {}
cpe_ref["referenceCategory"] = "SECURITY"
cpe_ref["referenceType"] = "cpe23Type"
cpe_ref["referenceLocator"] = drv.cpe
extrefs.append(cpe_ref)
purl_ref = {}
purl_ref["referenceCategory"] = "PACKAGE-MANAGER"
purl_ref["referenceType"] = "purl"
purl_ref["referenceLocator"] = drv.purl
extrefs.append(purl_ref)
if drv.cpe:
cpe_ref = {}
cpe_ref["referenceCategory"] = "SECURITY"
cpe_ref["referenceType"] = "cpe23Type"
cpe_ref["referenceLocator"] = drv.cpe
extrefs.append(cpe_ref)
if drv.purl:
purl_ref = {}
purl_ref["referenceCategory"] = "PACKAGE-MANAGER"
purl_ref["referenceType"] = "purl"
purl_ref["referenceLocator"] = drv.purl
extrefs.append(purl_ref)
return extrefs


Expand All @@ -272,16 +274,22 @@ def _drv_to_spdx_package(drv, uid="store_path"):
pkg["SPDXID"] = _str_to_spdxid(getattr(drv, uid))
pkg["versionInfo"] = drv.version
pkg["downloadLocation"] = "NOASSERTION"
if drv.urls:
pkg["downloadLocation"] = drv.urls
if "meta_homepage" in drv._asdict() and drv.meta_homepage:
pkg["homepage"] = drv.meta_homepage
if "meta_description" in drv._asdict() and drv.meta_description:
pkg["summary"] = drv.meta_description
licenses = _drv_to_spdx_license_list(drv)
if licenses:
pkg["licenseInfoFromFiles"] = licenses
licence_entry = licenses[0] if len(licenses) == 1 else "NOASSERTION"
pkg["licenseConcluded"] = licence_entry
pkg["licenseDeclared"] = licence_entry
pkg["copyrightText"] = "NOASSERTION"
pkg["externalRefs"] = _drv_to_spdx_extrefs(drv)
extrefs = _drv_to_spdx_extrefs(drv)
if extrefs:
pkg["externalRefs"] = extrefs
return pkg


Expand Down Expand Up @@ -352,8 +360,12 @@ def _drv_to_cdx_component(drv, uid="store_path"):
component["bom-ref"] = getattr(drv, uid)
component["name"] = drv.pname
component["version"] = drv.version
component["purl"] = drv.purl
component["cpe"] = drv.cpe
if drv.purl:
component["purl"] = drv.purl
if drv.cpe:
component["cpe"] = drv.cpe
if "meta_description" in drv._asdict() and drv.meta_description:
component["description"] = drv.meta_description
_cdx_component_add_licenses(component, drv)
properties = []
for out_path in drv.out:
Expand All @@ -366,6 +378,17 @@ def _drv_to_cdx_component(drv, uid="store_path"):
prop["name"] = "nix:drv_path"
prop["value"] = drv.store_path
properties.append(prop)
# To externalReferences?
if drv.urls:
prop = {}
prop["name"] = "nix:fetch_url"
prop["value"] = drv.urls
properties.append(prop)
if "meta_homepage" in drv._asdict() and drv.meta_homepage:
prop = {}
prop["name"] = "homepage"
prop["value"] = drv.meta_homepage
properties.append(prop)
if properties:
component["properties"] = properties
return component
Expand Down Expand Up @@ -413,6 +436,8 @@ def _parse_json_metadata(json_filename):
meta = pkg.get("meta", {})
setcol("meta_homepage", []).append(meta.get("homepage", ""))
setcol("meta_position", []).append(meta.get("position", ""))
setcol("meta_unfree", []).append(meta.get("unfree", ""))
setcol("meta_description", []).append(meta.get("description", ""))
# meta.license
meta_license = meta.get("license", {})
license_short = _parse_meta_entry(meta_license, key="shortName")
Expand Down
3 changes: 0 additions & 3 deletions tests/compare_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ def _parse_sbom(path):
outpaths.append(prop_dict["value"])
elif "drv_path" in prop_dict["name"]:
setcol("drv_path", []).append(prop_dict["value"])
else:
_LOG.fatal("Unexpected property: %s", prop_dict)
sys.exit(1)
setcol("out_path", []).append(outpaths)
df_components = pd.DataFrame(comp_parsed_dict)

Expand Down

0 comments on commit 4666d6e

Please sign in to comment.