Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions .github/workflows/selftest.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
name: wolfGlass self-test

# Runs the wolfGlass unit and integration tests on every change. The unit tests
# (scrub, version parse, validate) need no generator. The integration tests run
# only when a gen-sbom is available; this job checks out wolfSSL to provide one.
# Runs the wolfGlass unit and integration tests on every change. The vendored
# gen-sbom makes the integration path self-contained.

on:
push:
Expand All @@ -25,23 +24,19 @@ jobs:
run: |
python -m py_compile \
share/sbom-driver.py \
share/gen-sbom \
share/validate_sbom.py \
share/frontends/compdb_sbom.py \
share/frontends/iar_sbom.py \
share/frontends/zephyr_sbom.py \
central/gen-advisory \
provenance/bomsh_verify.py \
tools/wolfglass-sync \
tests/test_gen_sbom.py \
tests/test_sbom.py

- name: Checkout wolfSSL (for gen-sbom)
uses: actions/checkout@v4
continue-on-error: true
with:
repository: wolfSSL/wolfssl
path: _wolfssl
- name: Run generator unit tests
run: python -m unittest tests/test_gen_sbom.py

- name: Run self-test
run: |
if [ -f _wolfssl/scripts/gen-sbom ]; then
export WOLFSSL_DIR="$GITHUB_WORKSPACE/_wolfssl"
fi
python tests/test_sbom.py
run: python tests/test_sbom.py
55 changes: 38 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ wolfGlass is the single source of truth for the SBOM tools. Each product
repository vendors a small, pinned subset of these files. wolfGlass also runs the
central advisory tool and the optional build-provenance tool.

This repository now carries the shared SBOM generator, the shared build
fragments, the front ends, the advisory/VEX tooling, and the provenance
verifier. Product repositories vendor the SBOM layer from here.

## Goals

- Make one valid SBOM (CycloneDX 1.6 and SPDX 2.3) for every product.
Expand All @@ -16,15 +20,33 @@ central advisory tool and the optional build-provenance tool.

| Path | Purpose |
|---|---|
| `share/` | The only vendorable set. Products copy these files. |
| `central/` | The advisory tool. Runs for wolfSSL only. Not vendored. |
| `provenance/` | The bomsh provenance tool. Opt-in. Linux only. |
| `schemas/` | Pinned CDX 1.6 and SPDX 2.3 schemas for offline validation. |
| `tools/` | The sync tool and the out-of-tree driver. |
| `share/` | The vendorable SBOM driver, front ends, and build fragments. |
| `central/` | Planned home of the advisory/VEX tools. Not vendored. |
| `provenance/` | Planned home of the bomsh provenance tools. Opt-in. |
| `schemas/` | Planned home of pinned offline validation schemas. |
| `tools/` | The sync tool and the future out-of-tree driver. |
| `.github/workflows/` | Repository CI and reusable GitHub workflows. |
| `tests/` | Tool unit tests. Not vendored. |
| `docs/` | The program plan and integration guides. |

## Current State

Present now:

- Shared Python driver: `share/sbom-driver.py` and `share/sbom-driver`
- Shared generator: `share/gen-sbom`
- Shared autotools fragment: `share/sbom.am`
- Shared front ends: `frontends/compdb_sbom.py`, `iar_sbom.py`, `zephyr_sbom.py`
- Shared build fragments for Make, CMake, and autotools
- Central advisory/VEX tooling
- Central provenance verifier
- Sync tool, validator, self-test, and GitHub workflows

Not here yet:

- Offline schema bundle
- Full provenance driver wiring

## Quick start

Vendor the toolkit into a product and generate an SBOM:
Expand All @@ -34,8 +56,6 @@ Vendor the toolkit into a product and generate an SBOM:
tools/wolfglass-sync --dest /path/to/product

# 2. From the product build, call the driver (or the Make/CMake fragment).
# Point it at a gen-sbom until one is vendored (see Open decisions).
export WOLFSSL_DIR=/path/to/wolfssl
tools/sbom/sbom-driver --name wolfboot --srcs-file srcs.txt \
--cflags="$CFLAGS" --version-file include/wolfboot/version.h \
--version-macro LIBWOLFBOOT_VERSION_STRING
Expand All @@ -44,21 +64,22 @@ tools/sbom/sbom-driver --name wolfboot --srcs-file srcs.txt \
Run the self-test:

```sh
WOLFSSL_DIR=/path/to/wolfssl python3 tests/test_sbom.py
python3 tests/test_sbom.py
```

## Status

Phase 1 is complete: the product-neutral engine (`share/`), the front ends, the
build fragments, the sync tool, the self-test, and the CI workflows are in place
and tested. The full program plan is in [`docs/PLAN.md`](docs/PLAN.md). It lists
the problem, the solution, the benefits, the product tiers, the design, the CI
strategy, and the migration phases. The authoritative product-by-front-end
matrix and the dictionary are in [`docs/TIERS.md`](docs/TIERS.md).
The shared SBOM layer is ready for product adoption now: the product-neutral
engine (`share/`), the vendored generator, the Make/CMake/autotools fragments,
the front ends, the sync tool, the validator, the self-test, and the CI
workflows are in place.

`gen-sbom` now lives in `share/` and is discovered there by default. A product
can still override it with `--gen-sbom` if it needs to pin a different copy for
testing.

The one item that gates full air-gapped use is the generator home: `gen-sbom` is
not vendored yet. The driver discovers it through `--gen-sbom` or `WOLFSSL_DIR`
until that decision is signed off. See "Open decisions" in the plan.
The full program plan is in [`docs/PLAN.md`](docs/PLAN.md). The authoritative
product-by-front-end matrix and dictionary are in [`docs/TIERS.md`](docs/TIERS.md).

## License

Expand Down
45 changes: 45 additions & 0 deletions central/advisory-vex-overlay.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"_comment": "Human-authored VEX determinations keyed by CVE id. The CVE Program record carries the structural facts (CWE/CVSS/affected ranges); this overlay carries what it cannot express in machine-readable form: the analysis state, the not-affected justification, the response, free-text scope detail, the mainline fixed release version(s), an optional separately-modelled FIPS product entry, and an optional no-cost build-reachability hedge (requires_defines / default_status). The FIPS module_version and cmvp_cert values below are ILLUSTRATIVE placeholders; substitute the real validated module version and CMVP certificate number. gen-advisory folds these into both the CSAF and CycloneDX VEX outputs. requires_defines/default_status are recorded as informational notes only -- this tool does not compute per-build reachability.",

"CVE-2026-5501": {
"state": "exploitable",
"response": ["update"],
"detail": "Limited to applications using the OpenSSL compatibility API directly (wolfSSL_X509_verify_cert), such as nginx and haproxy integrations. The native wolfSSL TLS handshake path (ProcessPeerCerts) is not susceptible.",
"fixed_versions": ["5.9.1"],
"remediation": "Update to wolfSSL 5.9.1 or later, or avoid relying on wolfSSL_X509_verify_cert in the OpenSSL compatibility layer for chain validation.",
"fips": {
"name": "wolfCrypt FIPS 140-3 Module",
"module_version": "5.2.1",
"cmvp_cert": "4718",
"status": "not_affected",
"justification": "code_not_present",
"remediation": "No action required for the FIPS-validated module: the affected OpenSSL compatibility layer (wolfSSL_X509_verify_cert) is outside the wolfCrypt FIPS module boundary."
}
},

"CVE-2026-5778": {
"state": "exploitable",
"response": ["update"],
"detail": "Integer underflow in the ChaCha20-Poly1305 decryption path of the packet sniffer.",
"requires_defines": ["WOLFSSL_SNIFFER", "HAVE_CHACHA", "HAVE_POLY1305"],
"default_status": "off",
"fixed_versions": ["5.9.1"],
"remediation": "Update to wolfSSL 5.9.1 or later. Builds without --enable-sniffer are not affected.",
"fips": {
"name": "wolfCrypt FIPS 140-3 Module",
"module_version": "5.2.1",
"cmvp_cert": "4718",
"status": "not_affected",
"justification": "code_not_present",
"remediation": "No action required for the FIPS-validated module: the packet sniffer (src/sniffer.c) is outside the wolfCrypt FIPS module boundary."
}
},

"CVE-2026-5999": {
"state": "exploitable",
"response": ["update"],
"detail": "Synthetic fixture overlay: a simple mainline-only finding (no separate FIPS product) used to exercise the CVSS v3.1 scores[] path.",
"fixed_versions": ["5.9.1"],
"remediation": "Update to wolfSSL 5.9.1 or later."
}
}
118 changes: 118 additions & 0 deletions central/advisory-vex-overlay.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://www.wolfssl.com/schema/advisory-vex-overlay-1.json",
"title": "wolfSSL gen-advisory VEX overlay",
"description": "Human-authored VEX determinations keyed by CVE id, consumed by scripts/gen-advisory. The CVE Program record supplies the structural facts (CWE/CVSS/affected ranges); this overlay supplies what the record cannot express in machine-readable form. Enum values mirror the CycloneDX 1.6 vulnerability analysis vocabulary so the same terms map cleanly into both the CSAF and CycloneDX VEX outputs.",
"type": "object",
"properties": {
"_comment": {
"type": "string",
"description": "Free-text note ignored by gen-advisory."
}
},
"patternProperties": {
"^CVE-[0-9]{4}-[0-9]{4,}$": { "$ref": "#/$defs/overlayEntry" }
},
"additionalProperties": false,
"$defs": {
"analysisState": {
"type": "string",
"description": "CycloneDX 1.6 vulnerability analysis state.",
"enum": [
"resolved",
"resolved_with_pedigree",
"exploitable",
"in_triage",
"false_positive",
"not_affected"
]
},
"justification": {
"type": "string",
"description": "CycloneDX 1.6 impact analysis justification (required by gen-advisory when state is not_affected so a CSAF flag can be emitted).",
"enum": [
"code_not_present",
"code_not_reachable",
"requires_configuration",
"requires_dependency",
"requires_environment",
"protected_by_compiler",
"protected_at_perimeter",
"protected_at_runtime",
"protected_by_mitigating_control"
]
},
"response": {
"type": "array",
"description": "CycloneDX 1.6 vulnerability analysis response.",
"items": {
"type": "string",
"enum": [
"can_not_fix",
"will_not_fix",
"update",
"rollback",
"workaround_available"
]
}
},
"versionList": {
"type": "array",
"items": { "type": "string", "minLength": 1 },
"minItems": 1
},
"fips": {
"type": "object",
"description": "Optional separately-modelled FIPS product entry. FIPS customers cannot freely upgrade and many CVEs fall outside the validated module boundary, so FIPS is modelled as its own product with its own status and remediation.",
"properties": {
"name": { "type": "string", "minLength": 1 },
"module_version": { "type": "string", "minLength": 1 },
"cmvp_cert": {
"type": "string",
"minLength": 1,
"description": "CMVP certificate number, recorded as a CSAF model_number / CycloneDX property."
},
"status": { "$ref": "#/$defs/analysisState" },
"justification": { "$ref": "#/$defs/justification" },
"fixed_versions": { "$ref": "#/$defs/versionList" },
"remediation": { "type": "string", "minLength": 1 }
},
"additionalProperties": false,
"allOf": [
{
"if": { "properties": { "status": { "const": "not_affected" } }, "required": ["status"] },
"then": { "required": ["justification"] }
}
]
},
"overlayEntry": {
"type": "object",
"properties": {
"state": { "$ref": "#/$defs/analysisState" },
"justification": { "$ref": "#/$defs/justification" },
"response": { "$ref": "#/$defs/response" },
"detail": { "type": "string" },
"fixed_versions": { "$ref": "#/$defs/versionList" },
"remediation": { "type": "string", "minLength": 1 },
"requires_defines": {
"type": "array",
"items": { "type": "string", "minLength": 1 },
"description": "Build flags that gate the vulnerable code. Recorded as an informational note only; gen-advisory does NOT compute per-build reachability."
},
"default_status": {
"type": "string",
"enum": ["on", "off", "enabled", "disabled"]
},
"fips": { "$ref": "#/$defs/fips" }
},
"required": ["state"],
"additionalProperties": false,
"allOf": [
{
"if": { "properties": { "state": { "const": "not_affected" } }, "required": ["state"] },
"then": { "required": ["justification"] }
}
]
}
}
}
Loading
Loading