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
27 changes: 13 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,23 @@ 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 \
central/test_gen_advisory.py \
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 advisory generator unit tests
run: python -m unittest central/test_gen_advisory.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
122 changes: 122 additions & 0 deletions advisories/records/CVE-2026-5501.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"cveMetadata": {
"cveId": "CVE-2026-5501",
"assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27",
"state": "PUBLISHED",
"assignerShortName": "wolfSSL",
"dateReserved": "2026-04-03T15:46:09.302Z",
"datePublished": "2026-04-10T03:07:39.604Z",
"dateUpdated": "2026-04-22T13:59:28.514Z"
},
"containers": {
"cna": {
"providerMetadata": {
"orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27",
"shortName": "wolfSSL",
"dateUpdated": "2026-04-10T03:07:39.604Z"
},
"title": "Improper Certificate Signature Verification in X.509 Chain Validation Allows Forged Leaf Certificates",
"problemTypes": [
{
"descriptions": [
{
"lang": "en",
"cweId": "CWE-295",
"description": "CWE-295 Improper certificate validation",
"type": "CWE"
}
]
}
],
"affected": [
{
"vendor": "wolfSSL",
"product": "wolfSSL",
"modules": [
"wolfSSL_X509_verify_cert"
],
"programFiles": [
"src/x509_str.c"
],
"versions": [
{
"status": "affected",
"version": "0",
"lessThanOrEqual": "5.9.0",
"versionType": "semver"
}
],
"defaultStatus": "unaffected"
}
],
"descriptions": [
{
"lang": "en",
"value": "wolfSSL_X509_verify_cert in the OpenSSL compatibility layer accepts a certificate chain in which the leaf's signature is not checked, if the attacker supplies an untrusted intermediate with Basic Constraints `CA:FALSE` that is legitimately signed by a trusted root. An attacker who obtains any leaf certificate from a trusted CA (e.g. a free DV cert from Let's Encrypt) can forge a certificate for any subject name with any public key and arbitrary signature bytes, and the function returns `WOLFSSL_SUCCESS` / `X509_V_OK`. The native wolfSSL TLS handshake path (`ProcessPeerCerts`) is not susceptible and the issue is limited to applications using the OpenSSL compatibility API directly, which would include integrations of wolfSSL into nginx and haproxy.",
"supportingMedia": [
{
"type": "text/html",
"base64": false,
"value": "wolfSSL_X509_verify_cert in the OpenSSL compatibility layer accepts a certificate chain in which the leaf's signature is not checked, if the attacker supplies an untrusted intermediate with Basic Constraints `CA:FALSE` that is legitimately signed by a trusted root. An attacker who obtains any leaf certificate from a trusted CA (e.g. a free DV cert from Let's Encrypt) can forge a certificate for any subject name with any public key and arbitrary signature bytes, and the function returns `WOLFSSL_SUCCESS` / `X509_V_OK`. The native wolfSSL TLS handshake path (`ProcessPeerCerts`) is not susceptible and the issue is limited to applications using the OpenSSL compatibility API directly, which would include integrations of wolfSSL into nginx and haproxy."
}
]
}
],
"references": [
{
"url": "https://github.com/wolfSSL/wolfssl/pull/10102"
}
],
"metrics": [
{
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
],
"cvssV4_0": {
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"vulnConfidentialityImpact": "HIGH",
"subConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "HIGH",
"subIntegrityImpact": "NONE",
"vulnAvailabilityImpact": "NONE",
"subAvailabilityImpact": "NONE",
"exploitMaturity": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"valueDensity": "NOT_DEFINED",
"vulnerabilityResponseEffort": "NOT_DEFINED",
"providerUrgency": "NOT_DEFINED",
"version": "4.0",
"baseSeverity": "CRITICAL",
"baseScore": 9.3,
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N"
}
}
],
"credits": [
{
"lang": "en",
"value": "Calif.io in collaboration with Claude and Anthropic Research",
"type": "finder"
}
],
"source": {
"discovery": "EXTERNAL"
},
"x_generator": {
"engine": "Vulnogram 1.0.1"
}
}
}
}
122 changes: 122 additions & 0 deletions advisories/records/CVE-2026-5778.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"cveMetadata": {
"cveId": "CVE-2026-5778",
"assignerOrgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27",
"state": "PUBLISHED",
"assignerShortName": "wolfSSL",
"dateReserved": "2026-04-08T08:25:15.400Z",
"datePublished": "2026-04-09T21:45:09.053Z",
"dateUpdated": "2026-04-10T13:53:29.181Z"
},
"containers": {
"cna": {
"providerMetadata": {
"orgId": "50d2cd11-d01a-48ed-9441-5bfce9d63b27",
"shortName": "wolfSSL",
"dateUpdated": "2026-04-09T21:45:09.053Z"
},
"title": "Integer underflow leads to out-of-bounds access in sniffer ChaCha decrypt path.",
"problemTypes": [
{
"descriptions": [
{
"lang": "en",
"cweId": "CWE-191",
"description": "CWE-191 Integer underflow (wrap or wraparound)",
"type": "CWE"
}
]
}
],
"affected": [
{
"vendor": "wolfSSL",
"product": "wolfSSL",
"modules": [
"Packet sniffer"
],
"programFiles": [
"src/sniffer.c"
],
"versions": [
{
"status": "affected",
"version": "0",
"lessThanOrEqual": "5.9.0",
"versionType": "semver"
}
],
"defaultStatus": "unaffected"
}
],
"descriptions": [
{
"lang": "en",
"value": "Integer underflow in wolfSSL packet sniffer <= 5.9.0 allows an attacker to cause a program crash in the AEAD decryption path by injecting a TLS record shorter than the explicit IV plus authentication tag into traffic inspected by ssl_DecodePacket. The underflow wraps a 16-bit length to a large value that is passed to AEAD decryption routines, causing a large out-of-bounds read and crash. An unauthenticated attacker can trigger this remotely via malformed TLS Application Data records.",
"supportingMedia": [
{
"type": "text/html",
"base64": false,
"value": "Integer underflow in wolfSSL packet sniffer &lt;= 5.9.0 allows an attacker to cause a program crash in the AEAD decryption path by injecting a TLS record shorter than the explicit IV plus authentication tag into traffic inspected by ssl_DecodePacket. The underflow wraps a 16-bit length to a large value that is passed to AEAD decryption routines, causing a large out-of-bounds read and crash. An unauthenticated attacker can trigger this remotely via malformed TLS Application Data records."
}
]
}
],
"references": [
{
"url": "https://github.com/wolfSSL/wolfssl/pull/10125"
}
],
"metrics": [
{
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
],
"cvssV4_0": {
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"vulnConfidentialityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"subIntegrityImpact": "NONE",
"vulnAvailabilityImpact": "HIGH",
"subAvailabilityImpact": "NONE",
"exploitMaturity": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"valueDensity": "NOT_DEFINED",
"vulnerabilityResponseEffort": "NOT_DEFINED",
"providerUrgency": "NOT_DEFINED",
"version": "4.0",
"baseSeverity": "HIGH",
"baseScore": 8.2,
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"
}
}
],
"credits": [
{
"lang": "en",
"value": "Zou Dikai",
"type": "finder"
}
],
"source": {
"discovery": "EXTERNAL"
},
"x_generator": {
"engine": "Vulnogram 1.0.1"
}
}
}
}
Loading
Loading