Repository navigation
Conversation
|
There was a problem hiding this comment.
🟡 Changes recommended
Driver contract mismatches and CMake portability and embedding defects currently break supported SBOM routes.
5 open findings
CMake SBOM target cannot launch POSIX wrapper on Windows · New SBOM license metadata uses consuming project paths · New Driver incorrectly combines no-hash mode with a hash source · New SBOM user settings route bypasses effective settings.h configuration · New Generator discovery references nonexistent share/gen-sbom path · New
What changed in this PR
Vendors pinned SBOM tooling and routes wolfSSL’s Autotools, CMake, and standalone generation through it.
Changes:
- Adds the pinned generator, drivers, validators, and build-system frontends.
- Rewires
make sbom, CMake, packaging, and legacy entry points. - Updates tests, CI, documentation, and wolfSSL PURLs.
| File | Description |
|---|---|
.gitignore |
Tracks vendored SBOM build helpers. |
.github/workflows/sbom.yml |
Updates syntax and PURL checks. |
CMakeLists.txt |
Adds the CMake SBOM target. |
Makefile.am |
Uses and packages vendored tooling. |
doc/CRA.md |
Documents new paths and PURL. |
doc/SBOM.md |
Documents vendored generation flow. |
scripts/gen-sbom |
Forwards to the vendored generator. |
scripts/include.am |
Packages compatibility entry points. |
scripts/sbom.am |
Includes the vendored recipe. |
scripts/test_gen_sbom.py |
Tests vendored behavior and identifiers. |
tools/sbom/.wolfssl-compliance-tooling-rev |
Records the pinned revision. |
tools/sbom/README.md |
Describes the vendored toolkit. |
tools/sbom/VERSION |
Records toolkit version. |
tools/sbom/build/sbom.cmake |
Provides reusable CMake integration. |
tools/sbom/build/sbom.mk |
Provides reusable Make integration. |
tools/sbom/frontends/compdb_sbom.py |
Adds compilation-database extraction. |
tools/sbom/frontends/iar_sbom.py |
Adds IAR project extraction. |
tools/sbom/frontends/zephyr_sbom.py |
Adds Zephyr source extraction. |
tools/sbom/gen-sbom |
Implements SBOM generation. |
tools/sbom/sbom-driver |
Adds the shell driver wrapper. |
tools/sbom/sbom-driver.py |
Coordinates generator inputs. |
tools/sbom/sbom.am |
Provides the shared Automake recipe. |
tools/sbom/validate_sbom.py |
Adds structural validation. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| set(_cmd ${CMAKE_COMMAND} -E env HOSTCC=${SB_HOSTCC} | ||
| ${_WOLFSSL_COMPLIANCE_TOOLING_DRIVER} | ||
| --name ${SB_NAME} |
There was a problem hiding this comment.
The CMake helper now runs sbom-driver.py with the Python interpreter. A native Windows generator can start that file. The extensionless sbom-driver shell wrapper remains the Make and shell entry point.
The change is in wolfssl-compliance-tooling 27f7a31. This pull request pins that commit in 3d868e7bf.
| LICENSE ${CMAKE_SOURCE_DIR}/LICENSING | ||
| ROOT ${CMAKE_SOURCE_DIR} |
There was a problem hiding this comment.
LICENSE and ROOT now use CMAKE_CURRENT_SOURCE_DIR. An add_subdirectory() or FetchContent build reads this tree's LICENSING file. The helper already defaulted ROOT to that directory. This call was overriding it.
Fixed in 3d868e7bf.
| if args.lib: | ||
| cmd += ["--lib", args.lib] | ||
| if args.no_artifact_hash: | ||
| cmd += ["--no-artifact-hash"] |
There was a problem hiding this comment.
The failure was real. The driver was sending --lib and --no-artifact-hash together, and gen-sbom accepts one checksum source.
The driver now sends only --no-artifact-hash. --lib or --srcs-file still names the as-built artifact for the caller, and that path is not a second checksum source. gen-sbom is unchanged. scripts/test_gen_sbom.py and doc/SBOM.md still require the two flags together to fail.
The change is in wolfssl-compliance-tooling 27f7a31. This pull request pins that commit in 3d868e7bf.
| if args.user_settings: | ||
| if not os.path.isfile(args.user_settings): | ||
| sys.exit(f"ERROR: --user-settings '{args.user_settings}' " | ||
| f"does not exist.") | ||
| cmd += ["--user-settings", args.user_settings] |
There was a problem hiding this comment.
--user-settings is now the path to wolfssl/wolfcrypt/settings.h. The driver also requires --user-settings-include and --user-settings-define WOLFSSL_USER_SETTINGS, and it forwards all three. A user_settings.h path alone is rejected, because that file does not carry the macros settings.h derives. Make and CMake take the same three values.
The change is in wolfssl-compliance-tooling 27f7a31. This pull request pins that commit in 3d868e7bf.
| The shared driver is product-neutral and calls the vendored `share/gen-sbom` by | ||
| default. Pass `--gen-sbom` only when you want to override that copy. |
There was a problem hiding this comment.
The README now says the driver calls the gen-sbom file in the same directory. That sentence is true in the toolkit tree and in this tree.
The change is in wolfssl-compliance-tooling 27f7a31. This pull request pins that commit in 3d868e7bf.
|
@MarkAtwood the description now matches the pin in Please review this after toolkit #37 is on master. |
MarkAtwood
left a comment
There was a problem hiding this comment.
lgtm, make sbom, make sbom from the make dist tarball and the cmake sbom target all hash the same lib sha256sum does, default autotools and cmake builds untouched, the -1798 all moved into tools/sbom/sbom.am with nothing dropped. socat is the usual flake, test 23 DUALSYSTEMFDSFLUSH has no tls in it and it's failed on 9 other prs this month. two things before merge, the target name one inline, and re-pin .wolfssl-compliance-tooling-rev to whatever wolfSSL/wolfssl-compliance-tooling#37 lands as, it's 27f7a31 and #37 head is 6536aa0 now. fyi the cdx build properties go from "1" to "" for bare #defines, nothing in wolfssl reads them, just an output change
| set(_sbom_error "") | ||
| endif() | ||
|
|
||
| if(NOT _sbom_error STREQUAL "") |
There was a problem hiding this comment.
configure breaks when wolfssl gets pulled in with add_subdirectory by a project that has its own sbom target, wolftpm's -DWITH_WOLFSSL_TREE does exactly that. add_custom_target cannot create target "sbom" because another target with the same name already exists, master configures fine. PROJECT_IS_TOP_LEVEL is 3.21 so it's out, and NOT TARGET sbom doesn't help since wolftpm adds wolfssl before its own sbom. this configures under a parent with its own sbom and standalone sbom still writes both files
| if(NOT _sbom_error STREQUAL "") | |
| if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) | |
| # added as a subproject, the parent owns the sbom target name | |
| elseif(NOT _sbom_error STREQUAL "") |
There was a problem hiding this comment.
Fixed in f9947fb. The sbom target is created only when CMAKE_SOURCE_DIR equals CMAKE_CURRENT_SOURCE_DIR. A parent such as wolfTPM that adds wolfSSL with add_subdirectory() keeps its own sbom target. A standalone build still creates sbom.
b94ed34 moves the tools/sbom pin to 443ef5fc53e1b80809012043890ab182c9bc6b99, current toolkit master. That includes the merge of wolfssl-compliance-tooling #37 and the later commits on master. A top-level wolfSSL build also gets install-sbom and uninstall-sbom from that snapshot. A subproject still does not create those targets.
The library SBOM now comes from the pinned tools/sbom snapshot. scripts/gen-sbom forwards to that generator, and make bomsh still passes SBOM_LIB_OVERRIDE so the traced library is the hashed file.
The Linux SBOM job now requires pkg:github/wolfssl/wolfssl@v<version>-stable. scripts/gen-sbom stays importable and forwards to tools/sbom/gen-sbom. scripts/sbom.am includes the vendored recipe so the old include path still works.
.gitignore ignored every build/ directory, so a clone omitted tools/sbom/build. CMake includes those files.
LICENSE and ROOT follow CMAKE_CURRENT_SOURCE_DIR, so an add_subdirectory build reads this project's LICENSING file. The pin moves to the driver that starts under Python, sends one checksum source, and forwards settings.h with its include path and WOLFSSL_USER_SETTINGS.
A parent that already has an sbom target, such as wolfTPM built with WITH_WOLFSSL_TREE, failed to configure. Create the target only when wolfSSL is the top project. Pin tools/sbom to 77296bc, the merge of wolfssl-compliance-tooling pull request 37.
Move tools/sbom to 443ef5fc. That commit includes the merge of toolkit wolfSSL#37 and the later install-sbom scripts. A subproject still does not create the sbom target.
WC_LINUXKM_FORCE_SVR_DYNAMIC_AUDITING and the WOLFSSL_TI_AM64X_* entries were out of order, which fails the known-macro check. The bad order also caused false "unneeded entries" reports for the entries between them.
The source-text check rejects hard tabs in tools/sbom/build/sbom.mk. The toolkit now starts each recipe line with $(SBOM_TAB) instead of a literal tab. Pin the toolkit to that revision.
b94ed34 to
5bd3e93
Compare
wolfssl-compliance-tooling PR 52 now makes SBOM_TAB an override and stops with a clear error when $(shell printf '\t') is empty. Vendor that sbom.mk and pin the toolkit to the new head of PR 52. The file still has no hard tabs.
Frauschi
left a comment
There was a problem hiding this comment.
make sbom (from the tree and from a make dist tarball) and the CMake sbom target all produce valid SBOMs with the right library hash. The CMake staging, validation and python handling are generic and wolfTPM has the same bugs, so could you fix them in a wolfssl-compliance-tooling PR first, then re-pin with the sync tool and drop the local CMake code? Details inline.
| if __name__ == "__main__": | ||
| if not os.path.isfile(_target): | ||
| sys.exit(_MISSING) | ||
| os.execv(sys.executable, [sys.executable, _target, *sys.argv[1:]]) |
There was a problem hiding this comment.
On Windows os.execv doesn't replace the process: the parent exits 0 immediately and arguments with spaces aren't quoted. This is the entry point doc/SBOM.md gives Keil/IAR users, so running the generator as a child is safer.
Something like:
import subprocess
sys.exit(subprocess.call([sys.executable, _target, *sys.argv[1:]]))
There was a problem hiding this comment.
Fixed in 2d0fc17. scripts/gen-sbom now runs the generator with subprocess.call([sys.executable, target, *argv]) and exits with its status. A list argument is quoted correctly on Windows. test_wrapper_returns_the_generator_exit_status checks status 0 for --help and status 2 for a bad option.
| | SHA-256 | hash of the installed `libwolfssl.so.X.Y.Z` | | ||
| | CPE | `cpe:2.3:a:wolfssl:wolfssl:<version>:*:*:*:*:*:*:*` | | ||
| | PURL | `pkg:github/wolfSSL/wolfssl@v<version>` (resolves directly in OSV / GHSA / Snyk / Trivy without per-vendor mapping) | | ||
| | PURL | `pkg:github/wolfssl/wolfssl@v<version>-stable` (resolves directly in OSV / GHSA / Snyk / Trivy without per-vendor mapping) | |
There was a problem hiding this comment.
The SBOM purl is now pkg:github/wolfssl/wolfssl@v<version>-stable, but scripts/gen-advisory still emits pkg:github/wolfSSL/wolfssl@v<version>, so scanners won't match the VEX to the SBOM. test_gen_advisory.py pins the old form. The toolkit's central/gen-advisory already uses the new one.
There was a problem hiding this comment.
Fixed in 2d0fc17. scripts/gen-advisory now has the GITHUB_TAG_FORMS table of gen-sbom and emits pkg:github/wolfssl/wolfssl@v<version>-stable. The unversioned component purl is lowercase too. test_purl pins the new form, and test_purl_matches_the_sbom loads tools/sbom/gen-sbom and compares the table and the purls of both scripts, so they cannot drift again.
| else() | ||
| list(APPEND _sbom_args DEP_LIBZ no) | ||
| endif() | ||
| wolfssl_compliance_tooling_add_sbom(${_sbom_args}) |
There was a problem hiding this comment.
install-sbom depends on wolfssl-sbom-gen, not sbom, so on its own it skips pyspdxtools, never installs the .spdx file, and leaves _sbom_staging behind. wolfTPM has the same wiring. Could you make the toolkit helper own validation and have its install-sbom depend on it, then re-pin and drop the local sbom target here?
There was a problem hiding this comment.
Fixed. The toolkit helper now owns validation: wolfSSL/wolfssl-compliance-tooling#55 adds VALIDATE, which runs pyspdxtools and writes the tag-value file in the same target. install-sbom depends on that target, so it validates and installs the .spdx file. The staging directory is removed after the driver runs, also on failure. 2d0fc17 pins #55 with the sync tool and replaces the local CMake code with one helper call (STAGE_TARGET wolfssl, VALIDATE). I will pin again to the merge commit when #55 merges. wolfTPM can use the same options.
|
|
||
| add_custom_target(wolfssl-sbom-stage | ||
| COMMAND ${CMAKE_COMMAND} -E remove_directory ${SBOM_STAGING} | ||
| COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} |
There was a problem hiding this comment.
cmake --install --prefix still honours DESTDIR, and absolute install dirs ignore the prefix. With DESTDIR the driver can't find the library, and with an absolute CMAKE_INSTALL_LIBDIR this installs into the real directory. wolfTPM has the same block. Could you move staging into the toolkit's sbom.cmake, then re-pin and drop this block? Staging via DESTDIR works in my testing:
COMMAND ${CMAKE_COMMAND} -E env DESTDIR=${SBOM_STAGING}
${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --config $<CONFIG>hashing ${SBOM_STAGING}${CMAKE_INSTALL_FULL_LIBDIR}/....
There was a problem hiding this comment.
Fixed in the toolkit (wolfSSL/wolfssl-compliance-tooling#55) and pinned in 2d0fc17. STAGE_TARGET installs with DESTDIR=<build>/_sbom_staging and the real prefix, not with --prefix. The caller's DESTDIR is saved and restored around the staging install, and an absolute CMAKE_INSTALL_LIBDIR stays inside the staging tree. The bytes are the same as a real install (same RPATH and install name). I tested wolfSSL with -DCMAKE_INSTALL_LIBDIR=/tmp/wsb-abs/lib and DESTDIR=/tmp/wsb-dest cmake --build build --target install-sbom. Nothing was written to the absolute directory, and the SBOM hash was equal to the hash of cmake --install output.
|
|
||
| - name: Syntax check | ||
| run: python3 -m py_compile scripts/gen-sbom | ||
| run: python3 -m py_compile scripts/gen-sbom tools/sbom/gen-sbom |
There was a problem hiding this comment.
No job builds the CMake sbom or install-sbom targets, which is how the problems above got through. Could you add one, plus a drift check of tools/sbom/ against the pin (wolfssl-compliance-tooling-sync --check, or the toolkit's sbom-reusable.yml)?
There was a problem hiding this comment.
Added in 2d0fc17. The new cmake job configures with an absolute CMAKE_INSTALL_LIBDIR, builds, and runs install-sbom alone under DESTDIR. It checks the three installed files, that nothing goes to the absolute directory, that no _sbom_staging stays, the library hash against cmake --install, the CycloneDX schema, uninstall-sbom, and that -DCMAKE_DISABLE_FIND_PACKAGE_Python3=ON configures and fails only the sbom target. The new drift job clones the toolkit at the pinned revision and runs wolfssl-compliance-tooling-sync --check.
| | `python3 scripts/gen-sbom …` (standalone) | Embedded / RTOS customers building with their own Makefile, Keil, IAR, STM32CubeIDE, ESP-IDF, Zephyr, plain CMake, etc. | Any | | ||
| | `make sbom` (autotools wrapper) | Linux server / Debian / RPM / Yocto / FIPS-Ready customers running `./configure && make` | Autotools | | ||
|
|
||
| `scripts/gen-sbom` forwards to the vendored generator at `tools/sbom/gen-sbom`. |
There was a problem hiding this comment.
The UUIDs now also hash the config and artifact, not just name and version. Line 95 here and doc/CRA.md:230 still say name and version only. Could you update both?
There was a problem hiding this comment.
Fixed in 2d0fc17. doc/SBOM.md (the --document-namespace row) and doc/CRA.md (Reproducible SBOMs) now say that the UUIDs are derived from the name, the version, the build configuration and the library hash, and that two configurations of one release get different UUIDs.
| @@ -0,0 +1 @@ | |||
| 9a2dd6e6c7f6864037e6fca21993005c461facd5 | |||
There was a problem hiding this comment.
sbom-driver.py, validate_sbom.py and the three frontends lost their executable bit, so wolfssl-compliance-tooling-sync --check reports drift. When you re-pin, could you use the sync tool? That also picks up wolfSSL/wolfssl-compliance-tooling#46.
There was a problem hiding this comment.
Fixed in 2d0fc17. I pinned again with wolfssl-compliance-tooling-sync --dest . --prune. That restored the executable bits, and it brought wolfSSL/wolfssl-compliance-tooling#46 (the Zephyr frontend) and the #55 CMake changes. --check now reports no drift, and the new drift CI job runs it.
| SBOM_OPTIONS_H = $(abs_builddir)/wolfssl/options.h | ||
| SBOM_DEP_LIBZ = $(ENABLED_LIBZ) | ||
|
|
||
| EXTRA_DIST += tools/sbom/sbom-driver |
There was a problem hiding this comment.
Every toolkit bump that adds a file needs an edit here. EXTRA_DIST += tools/sbom would also ship __pycache__, so a dist-hook glob like the one for advisories/records would be better.
There was a problem hiding this comment.
Fixed in 2d0fc17. The EXTRA_DIST list is removed. dist-hook now copies every file of tools/sbom/ with cp -p and skips __pycache__ and *.pyc, as the hook does for advisories/records. I ran the hook commands on a tree with a __pycache__ directory and .pyc files: the copy was equal to tools/sbom/, executable bits included, without the cache files.
| if __name__ == '__main__': | ||
| main() | ||
| _skip = {"__name__", "__package__", "__loader__", "__spec__", "__cached__"} | ||
| globals().update({ |
There was a problem hiding this comment.
Copying the runpy globals leaves two namespaces: __file__ points at tools/sbom/gen-sbom and patching the wrapper has no effect. Putting the loaded module in sys.modules[__name__] avoids that.
There was a problem hiding this comment.
Fixed in 2d0fc17. The wrapper loads the generator with SourceFileLoader and puts that module in sys.modules[__name__], so the importer gets one namespace. test_wrapper_loads_generator checks that main.__globals__ is the module namespace and that __file__ is tools/sbom/gen-sbom.
| @@ -0,0 +1,89 @@ | |||
| # share/ | |||
There was a problem hiding this comment.
This README is titled # share/ and points at a sync tool wolfSSL doesn't have. Could you fix share/README.md in the same toolkit PR?
There was a problem hiding this comment.
Fixed in share/README.md in wolfSSL/wolfssl-compliance-tooling#55 and pinned here in 2d0fc17. The title now names the toolkit. The README says that the sync tool is in a toolkit checkout and is not vendored, and it gives the --dest command and --check.
Pin wolfssl-compliance-tooling with the sync tool. The pin brings the CMake helper's STAGE_TARGET and VALIDATE options, the Zephyr frontend from compliance-tooling wolfSSL#46, the executable bits of the vendored files, and the corrected tools/sbom/README.md. - CMakeLists.txt: one wolfssl_compliance_tooling_add_sbom() call with STAGE_TARGET wolfssl and VALIDATE replaces the local staging and pyspdxtools targets. install-sbom now validates and installs the .spdx file, the staging ignores DESTDIR and absolute install directories, and a missing python3 fails the sbom target only. - Makefile.am: ship tools/sbom/ through dist-hook, without __pycache__, so a new toolkit file needs no edit here. - scripts/gen-sbom: run the generator with subprocess.call. On Windows os.execv returned 0 at once and did not quote arguments. An importer now gets the generator module itself through sys.modules. - scripts/gen-advisory: emit pkg:github/wolfssl/wolfssl@v<version>-stable, the purl of the SBOM, so a scanner matches the VEX to the SBOM. - doc/SBOM.md, doc/CRA.md: the UUIDs also hash the build configuration and the artifact. - sbom.yml: a CMake job for sbom, install-sbom and uninstall-sbom, and a drift check of tools/sbom/ against the pin.
|
@Frauschi, thank you for the review. I did the work in the order that you asked:
Local results: |



Summary
tools/sbom/.scripts/gen-sbomforwards totools/sbom/gen-sbom.scripts/sbom.amincludestools/sbom/sbom.am.make sbomand the CMakesbomtarget use that snapshot.make bomshstill passesSBOM_LIB_OVERRIDEso the traced library is the hashed file.make advisoryis unchanged.pkg:github/wolfssl/wolfssl@v<version>-stable..gitignoreno longer dropstools/sbom/build/.9a2dd6e6c7f6864037e6fca21993005c461facd5, the head of fix(sbom.mk): start recipe lines without a literal tab wolfssl-compliance-tooling#52. That change removes the hard tabs fromtools/sbom/build/sbom.mk, which the source-text check rejects. After ER: Support for 32-bit version of Ed25519 #52 merges, this pull request moves the pin to the ER: Support for 32-bit version of Ed25519 #52 commit on toolkit master. Merge this pull request after that.Test plan
python3 -m unittest scripts/test_gen_sbom.py./configure --enable-shared --enable-static && make sbomntia-checker -c ntia wolfssl-*.spdx.jsonis conformant and the CycloneDX 1.6 strict validator acceptswolfssl-*.cdx.json.pkg:github/wolfssl/wolfssl@v<version>-stable.tools/sbom/build/sbom.cmakeis present in the clone.