# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Subtree 08 -- Crypto-agility & inventory governance (Linux / Unix / macOS).

The foundational PQC control is knowing what cryptography you run: NIST, CISA,
NSA and OMB M-23-02 all make a cryptographic inventory (increasingly a CBOM --
a CycloneDX Cryptography Bill of Materials) the first migration step. This
subtree affirms the presence of a CBOM artifact and of post-quantum
tooling/libraries (liboqs, oqs-provider), and flags their absence as a
governance gap.

Read-only.
"""

from quantum.common import is_unix as _is_unix
from quantum.common import file_has as _file_has

const CBOM_GLOBS = {
    "/etc/cbom/*.json", "/var/lib/cbom/*.json", "/usr/share/cbom/*.json",
    "/opt/*/bom.json", "/opt/*/*.cdx.json", "/opt/*/sbom*.json",
    "/srv/*/*.cdx.json", "/srv/*/bom.json", "/var/lib/sbom/*.json",
    "/home/*/*.cdx.json", "/etc/sbom/*.json"
}

const PQC_TOOLING_GLOBS = {
    "/usr/lib/liboqs.so*", "/usr/lib64/liboqs.so*", "/usr/local/lib/liboqs.so*",
    "/opt/homebrew/lib/liboqs*",
    "/usr/lib/ossl-modules/oqsprovider.so", "/usr/lib64/ossl-modules/oqsprovider.so",
    "/usr/local/lib/ossl-modules/oqsprovider.so",
    "/usr/lib/x86_64-linux-gnu/ossl-modules/oqsprovider.so",
    "/opt/homebrew/lib/ossl-modules/oqsprovider.dylib",
    "/usr/bin/cbomkit", "/usr/local/bin/cbomkit"
}


proc check_cbom_present(host: Host):
    """Affirm a cryptographic inventory / CBOM on the host; flag its absence as
    a governance gap.
    """
    if not _is_unix(host):
        host.leave(0, "CBOM check is Unix/macOS-only")
    let n = host.integer()
    n.setvalue(0)
    for pat in CBOM_GLOBS:
        for f in host.glob({pat}):
            if f.exists and f.ftype == "file":
                if _file_has(host, f.filename, r"(?i).*(cryptographic-asset|cyclonedx|\x22bomFormat\x22)"):
                    host.compliance(0, "Cryptographic inventory / CBOM artifact present: %s", f.filename)
                    n.setvalue(n.getvalue() + 1)
    if n.getvalue() == 0:
        host.report("No cryptographic inventory / CBOM artifact found on host (the foundational PQC-migration control -- OMB M-23-02 / CISA quantum-readiness)")


proc check_pqc_tooling(host: Host):
    """Inventory post-quantum libraries / tooling (liboqs, oqs-provider,
    cbomkit) -- a crypto-agility signal.
    """
    if not _is_unix(host):
        host.leave(0, "PQC-tooling check is Unix/macOS-only")
    let n = host.integer()
    n.setvalue(0)
    for pat in PQC_TOOLING_GLOBS:
        for f in host.glob({pat}):
            if f.exists:
                host.compliance(0, "Post-quantum tooling/library present: %s", f.filename)
                n.setvalue(n.getvalue() + 1)
    if n.getvalue() == 0:
        host.report("No post-quantum libraries/tooling (liboqs / oqs-provider) detected -- limited crypto-agility for PQC migration")
