Skip to content

Commit 5e7405f

Browse files
committed
feat(sbom): add evidence for all products
Duplicate paths in all_product_data to add evidence paths in SBOM for all products including ones with no CVEs Signed-off-by: Fabrice Fontaine <[email protected]>
1 parent b1b4ef8 commit 5e7405f

File tree

6 files changed

+32
-21
lines changed

6 files changed

+32
-21
lines changed

cve_bin_tool/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,8 +1169,8 @@ def main(argv=None):
11691169
else:
11701170
# In no-scan mode, still populate all_product_data for display
11711171
if product_info not in cve_scanner.all_product_data:
1172-
cve_scanner.all_product_data[product_info] = 0
1173-
cve_scanner.all_product_data[product_info] = 0
1172+
cve_scanner.all_product_data[product_info]["cves_total"] = 0
1173+
cve_scanner.all_product_data[product_info]["cves_total"] = 0
11741174
total_files = version_scanner.total_scanned_files
11751175
LOGGER.info(f"Total files: {total_files}")
11761176

cve_bin_tool/cve_scanner.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(
6262
self.products_without_cve = 0
6363
self.all_cve_data = defaultdict(lambda: {"cves": [], "paths": set()})
6464
self.all_cve_version_info = dict()
65-
self.all_product_data = dict()
65+
self.all_product_data = defaultdict(lambda: {"cves_total": 0, "paths": set()})
6666

6767
def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
6868
"""Get CVEs against a specific version of a product.
@@ -81,22 +81,23 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
8181
# In no-scan mode, just populate the product data without CVE scanning
8282
if product_info not in self.all_product_data:
8383
self.logger.debug(f"Add product {product_info} (no-scan mode)")
84-
self.all_product_data[product_info] = 0
84+
self.all_product_data[product_info]["cves_total"] = 0
8585

8686
# Also populate all_cve_data with empty CVE list and paths
8787
if product_info not in self.all_cve_data:
8888
self.all_cve_data[product_info] = {"cves": [], "paths": set()}
8989

9090
# Update paths
9191
self.all_cve_data[product_info]["paths"] |= set(triage_data["paths"])
92+
self.all_product_data[product_info]["paths"] |= set(triage_data["paths"])
9293
return
9394

9495
if product_info.vendor == "UNKNOWN":
9596
# Add product
9697
if product_info not in self.all_product_data:
9798
self.logger.debug(f"Add product {product_info}")
9899
# Number of CVEs is 0
99-
self.all_product_data[product_info] = 0
100+
self.all_product_data[product_info]["cves_total"] = 0
100101
return
101102

102103
if product_info in self.all_cve_data:
@@ -396,7 +397,10 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
396397
)
397398

398399
if product_info not in self.all_product_data:
399-
self.all_product_data[product_info] = len(cves)
400+
self.all_product_data[product_info]["cves_total"] = len(cves)
401+
402+
# Update paths
403+
self.all_product_data[product_info]["paths"] |= set(triage_data["paths"])
400404

401405
def filter_triage_data(self):
402406
"""

cve_bin_tool/output_engine/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ def output_pdf(
601601
products_with_cves = list(map(lambda x: x[1], all_cve_data))
602602
for product_data in all_product_data:
603603
if (
604-
all_product_data[product_data] == 0
604+
all_product_data[product_data]["cves_total"] == 0
605605
and product_data.product not in products_with_cves
606606
):
607607
product_entry = [

cve_bin_tool/output_engine/console.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def _output_console_nowrap(
158158
if color is None and count > 0:
159159
color = summary_color[severity.split("-")[0]]
160160

161-
if all_product_data[product_data] != 0 or no_scan:
161+
if all_product_data[product_data]["cves_total"] != 0 or no_scan:
162162
if no_scan:
163163
latest_stable_version = "NA"
164164
elif offline:
@@ -185,7 +185,9 @@ def _output_console_nowrap(
185185
Text.styled(str(count), color),
186186
]
187187
cells += [
188-
Text.styled(str(all_product_data[product_data]), color),
188+
Text.styled(
189+
str(all_product_data[product_data]["cves_total"]), color
190+
),
189191
]
190192
table.add_row(*cells)
191193
# Print the table to the console
@@ -373,7 +375,7 @@ def validate_cell_length(cell_name, cell_type):
373375

374376
for product_data in all_product_data:
375377
if (
376-
all_product_data[product_data] == 0
378+
all_product_data[product_data]["cves_total"] == 0
377379
and product_data.product not in products_with_cves
378380
):
379381
cells = [

cve_bin_tool/sbom_manager/generate.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,19 @@ def generate_sbom(self) -> None:
110110
and product_data.vendor == "unknown"
111111
):
112112
# In no-scan mode, we still want to include path information if available
113-
if self.all_cve_data.get(product_data) and self.all_cve_data[
113+
if self.all_product_data.get(product_data) and self.all_product_data[
114114
product_data
115115
].get("paths"):
116-
for path in self.all_cve_data[product_data]["paths"]:
117-
with open(path.split()[0], "rb") as f:
118-
file_data = f.read()
119-
sha256_hash = hashlib.sha256(file_data)
120-
my_package.set_checksum("SHA256", sha256_hash.hexdigest())
116+
for path in self.all_product_data[product_data]["paths"]:
117+
try:
118+
with open(path.split()[0], "rb") as f:
119+
file_data = f.read()
120+
sha256_hash = hashlib.sha256(file_data)
121+
my_package.set_checksum("SHA256", sha256_hash.hexdigest())
122+
except FileNotFoundError:
123+
self.logger.debug(
124+
f"{path} not found, no checksum added to SBOM"
125+
)
121126
if self.strip_scan_dir:
122127
evidence = strip_path(path, self.sbom_root)
123128
else:

test/test_output_engine.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -940,18 +940,18 @@ class TestOutputEngine(unittest.TestCase):
940940
)
941941

942942
def setUp(self) -> None:
943-
self.all_product_data = [
943+
self.all_product_data = {
944944
ProductInfo(
945945
product="product1",
946946
version="1.0",
947947
vendor="VendorA",
948-
),
948+
): {"cves_total": 0, "paths": {"/path/to/test"}},
949949
ProductInfo(
950950
product="product2",
951951
version="2.0",
952952
vendor="unknown",
953-
),
954-
]
953+
): {"cves_total": 0, "paths": {"/path/to/test"}},
954+
}
955955
self.output_engine = OutputEngine(
956956
all_cve_data=self.MOCK_OUTPUT,
957957
scanned_dir="",
@@ -1070,7 +1070,7 @@ def test_console_output_no_scan_mode_latest_version(self):
10701070
all_product_data = {
10711071
ProductInfo(
10721072
vendor="test_vendor", product="test_product", version="1.0.0"
1073-
): 0,
1073+
): {"cves_total": 0, "paths": {"/path/to/test"}}
10741074
}
10751075

10761076
all_cve_data = {

0 commit comments

Comments
 (0)