From 4ed76b2fa2e5d53dcc2044851e36d62ca3bd9f89 Mon Sep 17 00:00:00 2001 From: Ben Selwyn-Smith Date: Thu, 16 Jan 2025 19:12:15 +1000 Subject: [PATCH] chore: allow for variance in SLSA verifier output Signed-off-by: Ben Selwyn-Smith --- src/macaron/database/db_custom_types.py | 4 ++-- src/macaron/provenance/provenance_verifier.py | 15 ++++++++++----- .../slsa_analyzer/checks/provenance_l3_check.py | 7 ++++++- .../checks/provenance_verified_check.py | 7 +++---- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/macaron/database/db_custom_types.py b/src/macaron/database/db_custom_types.py index 182fdb734..f4bfe71c6 100644 --- a/src/macaron/database/db_custom_types.py +++ b/src/macaron/database/db_custom_types.py @@ -149,9 +149,9 @@ def process_result_value(self, value: str | None, dialect: Any) -> InTotoPayload raise TypeError("Missing keys in dict for ProvenancePayload type.") payload = payload_dict["payload"] - if payload["payload_type"] == "InTotoV01Payload": + if payload_dict["payload_type"] == "InTotoV01Payload": return InTotoV01Payload(statement=payload) - if payload["payload_type"] == "InTotoV1Payload": + if payload_dict["payload_type"] == "InTotoV1Payload": return InTotoV1Payload(statement=payload) return validate_intoto_payload(payload) diff --git a/src/macaron/provenance/provenance_verifier.py b/src/macaron/provenance/provenance_verifier.py index 7cb6776a2..04f43cd35 100644 --- a/src/macaron/provenance/provenance_verifier.py +++ b/src/macaron/provenance/provenance_verifier.py @@ -6,6 +6,7 @@ import hashlib import logging import os +import re import subprocess # nosec B404 import tarfile import zipfile @@ -16,7 +17,7 @@ from macaron.config.defaults import defaults from macaron.config.global_config import global_config -from macaron.json_tools import json_extract +from macaron.provenance.provenance_extractor import ProvenancePredicate from macaron.repo_finder.commit_finder import AbstractPurlType, determine_abstract_purl_type from macaron.slsa_analyzer.analyze_context import AnalyzeContext from macaron.slsa_analyzer.asset import AssetLocator @@ -199,6 +200,7 @@ def verify_ci_provenance(analyze_ctx: AnalyzeContext, ci_info: CIInfo, download_ ) if not sub_verified: + logger.info("Sub asset not verified: %s", sub_asset["name"]) return False if sub_verified: @@ -324,7 +326,12 @@ def _verify_slsa( ) output = verifier_output.stdout.decode("utf-8") - verified = "PASSED: Verified SLSA provenance" in output + for line in output.splitlines(): + if not line: + continue + if re.match("^PASSED:.+SLSA.+", line): + verified = True + break log_path = os.path.join(global_config.build_log_path, f"{os.path.basename(source_path)}.slsa_verifier.log") with open(log_path, mode="a", encoding="utf-8") as log_file: @@ -385,9 +392,7 @@ def determine_provenance_slsa_level( predicate = provenance_payload.statement.get("predicate") build_type = None if predicate: - build_type = json_extract(predicate, ["buildDefinition", "buildType"], str) - if not build_type: - build_type = json_extract(predicate, ["buildType"], str) + build_type = ProvenancePredicate.get_build_type(provenance_payload.statement) if build_type == "https://github.com/slsa-framework/slsa-github-generator/generic@v1" and verified_l3: # 3. Provenance is created by the SLSA GitHub generator and verified. diff --git a/src/macaron/slsa_analyzer/checks/provenance_l3_check.py b/src/macaron/slsa_analyzer/checks/provenance_l3_check.py index ee22aff3f..a8d0e5af7 100644 --- a/src/macaron/slsa_analyzer/checks/provenance_l3_check.py +++ b/src/macaron/slsa_analyzer/checks/provenance_l3_check.py @@ -68,7 +68,12 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData: """ result_tables: list[CheckFacts] = [] result_value = CheckResultType.FAILED - if ctx.dynamic_data["provenance_info"] and ctx.dynamic_data["provenance_info"].slsa_level == 3: + prov = ctx.dynamic_data["provenance_info"] or None + slsa = 0 + if prov: + slsa = prov.slsa_level + + if prov and slsa == 3: result_tables.append(ProvenanceL3VerifiedFacts(confidence=Confidence.HIGH)) result_value = CheckResultType.PASSED diff --git a/src/macaron/slsa_analyzer/checks/provenance_verified_check.py b/src/macaron/slsa_analyzer/checks/provenance_verified_check.py index 9b0746296..65f028ec0 100644 --- a/src/macaron/slsa_analyzer/checks/provenance_verified_check.py +++ b/src/macaron/slsa_analyzer/checks/provenance_verified_check.py @@ -8,7 +8,7 @@ from sqlalchemy.orm import Mapped, mapped_column from macaron.database.table_definitions import CheckFacts -from macaron.json_tools import json_extract +from macaron.provenance.provenance_extractor import ProvenancePredicate from macaron.slsa_analyzer.analyze_context import AnalyzeContext from macaron.slsa_analyzer.checks.base_check import BaseCheck from macaron.slsa_analyzer.checks.check_result import CheckResultData, CheckResultType, Confidence, JustificationType @@ -69,10 +69,9 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData: """ build_type = None provenance_info = ctx.dynamic_data["provenance_info"] + if provenance_info and provenance_info.provenance_payload: - predicate = provenance_info.provenance_payload.statement.get("predicate") - if predicate: - build_type = json_extract(predicate, ["buildDefinition", "buildType"], str) + build_type = ProvenancePredicate.get_build_type(provenance_info.provenance_payload.statement) slsa_level = 0 if provenance_info: