Skip to content

feat: add make sbom target#536

Open
MarkAtwood wants to merge 3 commits into
wolfSSL:masterfrom
MarkAtwood:feat/add-sbom-make-target
Open

feat: add make sbom target#536
MarkAtwood wants to merge 3 commits into
wolfSSL:masterfrom
MarkAtwood:feat/add-sbom-make-target

Conversation

@MarkAtwood

@MarkAtwood MarkAtwood commented Jun 23, 2026

Copy link
Copy Markdown

Summary

Adds make sbom, make install-sbom, and make uninstall-sbom targets to the autotools build.

  • Stages a temporary install to extract the built .so for hashing
  • Dumps preprocessor defines via cc -dM -E for the options snapshot
  • Calls gen-sbom (from wolfssl scripts/gen-sbom) to produce CycloneDX and SPDX outputs
  • Validates SPDX with pyspdxtools

Usage

./configure --with-wolfssl=/path/to/wolfssl/install
make
make sbom WOLFSSL_DIR=/path/to/wolfssl/source

Outputs: wolftpm-<version>.cdx.json, wolftpm-<version>.spdx.json, wolftpm-<version>.spdx

Requirements

  • WOLFSSL_DIR must point to a wolfssl source tree containing scripts/gen-sbom (available on the feat/sbom-embedded branch of wolfssl)
  • python3 and pip install spdx-tools on the build host

Test plan

  • ./configure --with-wolfssl=... && make && make sbom WOLFSSL_DIR=...
  • Verify three output files are produced
  • pyspdxtools --infile wolftpm-*.spdx.json passes validation

CMake sbom target

The cmake build now has an equivalent sbom custom target, so SBOM generation works the same way whether you build with autotools or cmake.

cmake -B build -DWOLFSSL_DIR=/path/to/wolfssl/source .
cmake --build build
cmake --build build --target sbom

Outputs land in the build directory: wolftpm-<version>.cdx.json, wolftpm-<version>.spdx.json, wolftpm-<version>.spdx.

Notes:

  • Version is read directly from wolftpm/version.h (LIBWOLFTPM_VERSION_STRING), not from the cmake project() call, so the cmake and autotools SBOMs stay bit-identical in the version field even if the two drift.
  • The options fingerprint is taken from the generated wolftpm/options.h (the real compile-time option set) rather than a raw cc -dM dump, which would only capture compiler builtins. This keeps the cmake SBOM consistent with what autotools produces via --options-h.
  • WOLFSSL_DIR and python3/pyspdxtools are validated at configure time. A missing prerequisite does not break a normal cmake --build; the sbom target simply fails with a clear message when invoked. A wrong -DWOLFSSL_DIR= (explicit opt-in with a bad path) hard-errors at configure time.
  • On lib64 hosts, pass -DCMAKE_INSTALL_LIBDIR=lib if needed; the staged library is read from lib/.

Adds sbom, install-sbom, and uninstall-sbom targets.
Runs gen-sbom to produce CDX and SPDX outputs.
Requires WOLFSSL_DIR pointing to a wolfssl tree with
the feat/sbom-embedded branch (includes gen-sbom).
@MarkAtwood MarkAtwood requested review from Copilot and sameehj June 23, 2026 01:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds build-system support for generating and installing SBOM artifacts (CycloneDX + SPDX) via new make targets, integrating wolfSSL’s gen-sbom script and SPDX validation tooling.

Changes:

  • Split libtool version-info into separately substituted components for reuse in make rules.
  • Add sbom, install-sbom, and uninstall-sbom targets to generate/validate and install SBOM outputs.
  • Detect python3 and pyspdxtools at configure-time for use by the SBOM targets.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
configure.ac Exposes library version components and discovers SBOM tool dependencies (python3, pyspdxtools) for make targets.
Makefile.am Implements SBOM generation/validation and install/uninstall targets; wires output files into CLEANFILES.

Comment thread Makefile.am
Comment on lines +175 to +185
$(PYTHON3) $(WOLFSSL_DIR)/scripts/gen-sbom \
--name wolftpm \
--version $(PACKAGE_VERSION) \
--supplier "wolfSSL Inc." \
--license-file $(srcdir)/LICENSE \
--options-h $(abs_builddir)/wolftpm/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@ \
$(if $(SBOM_LICENSE_OVERRIDE),--license-override $(SBOM_LICENSE_OVERRIDE)) \
$(if $(SBOM_LICENSE_TEXT),--license-text $(SBOM_LICENSE_TEXT)) \
--cdx-out $(abs_builddir)/$(SBOM_CDX) \
--spdx-out $(abs_builddir)/$(SBOM_SPDX)
Comment thread Makefile.am
fi
rm -rf $(abs_builddir)/_sbom_staging
$(MAKE) install DESTDIR=$(abs_builddir)/_sbom_staging
$(PYTHON3) $(WOLFSSL_DIR)/scripts/gen-sbom \
Comment thread Makefile.am
Comment on lines +179 to +185
--license-file $(srcdir)/LICENSE \
--options-h $(abs_builddir)/wolftpm/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@ \
$(if $(SBOM_LICENSE_OVERRIDE),--license-override $(SBOM_LICENSE_OVERRIDE)) \
$(if $(SBOM_LICENSE_TEXT),--license-text $(SBOM_LICENSE_TEXT)) \
--cdx-out $(abs_builddir)/$(SBOM_CDX) \
--spdx-out $(abs_builddir)/$(SBOM_SPDX)
Comment thread Makefile.am
--supplier "wolfSSL Inc." \
--license-file $(srcdir)/LICENSE \
--options-h $(abs_builddir)/wolftpm/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@ \

@aidangarske aidangarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skoll Multi-Scan Review

Modes: review + review-security + bugsOverall recommendation: REQUEST_CHANGES
Findings: 7 total — 7 posted, 0 skipped
7 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [High] [review+review-security+bugs] Autotools sbom target reconstructs the libtool library filename incorrectly; breaks on next version-info bump and on macOS/static buildsMakefile.am:181
  • [High] [review+review-security+bugs] CMake sbom target hard-codes Unix shared-library layout; fails on Windows, static, and multi-config buildsCMakeLists.txt:860-884
  • [Medium] [bugs] CMake sbom target uses cmake -E rm, unavailable on the declared minimum CMake 3.16CMakeLists.txt:874,891
  • [Medium] [review] New SBOM targets have no automated coverageMakefile.am:144-188
  • [Low] [review] install-sbom mixes absolute and relative artifact paths; only works when run from the build dirMakefile.am:184-194
  • [Low] [review+review-security] CMake return() used at directory scope to skip the SBOM block; fragile if code is appendedCMakeLists.txt:844-853
  • [Low] [review-security] CMake version.h regex uses [ \t] which does not match a tab in CMake's regex dialectCMakeLists.txt:803-806

Review generated by Skoll

Comment thread Makefile.am
--supplier "wolfSSL Inc." \
--license-file $(srcdir)/LICENSE \
--options-h $(abs_builddir)/wolftpm/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@ \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 [High] Autotools sbom target reconstructs the libtool library filename incorrectly; breaks on next version-info bump and on… · Logic

The sbom target points gen-sbom --lib at libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@, i.e. libwolftpm.so.\<current>.\<revision>.\<age>, reconstructed from libtool's current:revision:age version-info fields (currently 17:0:0). libtool actually installs the real ELF file as libNAME.so.(current-age).age.revision: the first component should be current-age (not current) and the trailing two are age.revision, swapped relative to this recipe's revision.age. configure.ac's own comments confirm the installed soname is current-age, making the mapping internally inconsistent. It works today only because all three components collapse to 17.0.0 for 17:0:0; the next release with a nonzero revision/age (e.g. 17:1:0) makes libtool install libwolftpm.so.17.0.1 while the recipe looks for libwolftpm.so.17.1.0, so --lib points at a nonexistent file and make sbom fails. The hardcoded .so.X.Y.Z and $(libdir) are also non-portable: macOS installs libwolftpm.\<n>.dylib, static-only builds produce libwolftpm.a, and MinGW installs the DLL runtime under $(bindir) — none of which this path can locate. Severity views across modes: review=High/BLOCK, bugs=Medium, review-security=Low; strictest kept.

Fix: Do not reconstruct the versioned name from version-info components. After the staged install, discover the actual installed artifact under the staged $(libdir)/$(bindir) (glob libwolftpm.so.*, libwolftpm*.dylib, *wolftpm*.dll, or dereference the unversioned libwolftpm.so dev symlink) and fail clearly if none is found. If the versioned name must be kept, compute the first component as current-age and order the trailing components as age.revision.

Comment thread CMakeLists.txt
set(SBOM_SPDX_TV "${CMAKE_BINARY_DIR}/wolftpm-${SBOM_VERSION}.spdx")
set(SBOM_STAGING "${CMAKE_BINARY_DIR}/_sbom_staging")

# Staged install path. install(TARGETS wolftpm) above hardcodes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 [High] CMake sbom target hard-codes Unix shared-library layout; fails on Windows, static, and multi-config builds · Logic

The CMake sbom target computes SBOM_LIB = ${SBOM_STAGING}/lib/libwolftpm${CMAKE_SHARED_LIBRARY_SUFFIX} and passes it to gen-sbom after cmake --install, hard-coding both the lib/ staging subdir and a Unix shared-object name rather than the real target artifact. This diverges from the actual install layout in several supported configurations: (1) With -DBUILD_SHARED_LIBS=OFF (option defaults ON at line 73) the installed artifact is libwolftpm.a under ARCHIVE DESTINATION lib, so --lib points at a .so/.dylib that was never produced. (2) On Windows shared builds, install(TARGETS) uses RUNTIME DESTINATION bin, DLLs go under bin/ and typically drop the lib prefix (wolftpm.dll), so the path never matches. (3) For multi-config generators (Visual Studio, Xcode) the cmake --install omits --config $\<CONFIG>, so building the sbom target can install/hash the wrong or unbuilt configuration. In each case gen-sbom fails with a bare file-not-found. Severity views: review=High/BLOCK, bugs=Medium, review-security=Low; strictest kept.

Fix: Derive the artifact from CMake target metadata via generator expressions ($\<TARGET_FILE_NAME:wolftpm> plus the platform-specific staged destination — bin/ on Windows, lib/ elsewhere), add --config $\<CONFIG> to the install for multi-config generators, and either support static builds explicitly or reject BUILD_SHARED_LIBS=OFF for the sbom target with a clear FATAL_ERROR.

Comment thread CMakeLists.txt
VERBATIM
# Stage a clean install so gen-sbom inspects the same artifact layout
# the user would actually ship.
COMMAND ${CMAKE_COMMAND} -E rm -rf ${SBOM_STAGING}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 [Medium] CMake sbom target uses cmake -E rm, unavailable on the declared minimum CMake 3.16 · API Contract Violations

The sbom custom target runs ${CMAKE_COMMAND} -E rm -rf ${SBOM_STAGING} twice (lines 874 and 891). The cmake -E rm subcommand was introduced in CMake 3.17, but this file declares cmake_minimum_required(VERSION 3.16) (line 22). On a host with exactly CMake 3.16 — a version the project claims to support — cmake --build build --target sbom fails with cmake -E rm: unknown command before any SBOM is produced. The main build is unaffected; only the new opt-in target breaks.

Fix: Use the 3.16-compatible ${CMAKE_COMMAND} -E remove_directory ${SBOM_STAGING} (handles a missing directory gracefully and matches rm -rf intent), or raise the minimum CMake version for this target path.

Comment thread Makefile.am

.PHONY: sbom install-sbom uninstall-sbom

sbom:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 [Medium] New SBOM targets have no automated coverage · test

The PR adds non-trivial autotools and CMake SBOM generation paths, but includes no automated smoke coverage for either target; the PR body lists only manual test steps. A lightweight test would have caught the artifact-path and platform assumptions in the new target logic (see the autotools libtool-filename and CMake shared-library-layout findings).

Fix: Add CI or a build-system smoke test that provides a minimal fake WOLFSSL_DIR/scripts/gen-sbom, runs make sbom and cmake --build --target sbom, and asserts the expected output files are produced or that prerequisite errors are clear.

Comment thread Makefile.am
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolftpm.so.@WOLFTPM_LIBRARY_VERSION_FIRST@.@WOLFTPM_LIBRARY_VERSION_SECOND@.@WOLFTPM_LIBRARY_VERSION_THIRD@ \
$(if $(SBOM_LICENSE_OVERRIDE),--license-override $(SBOM_LICENSE_OVERRIDE)) \
$(if $(SBOM_LICENSE_TEXT),--license-text $(SBOM_LICENSE_TEXT)) \
--cdx-out $(abs_builddir)/$(SBOM_CDX) \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] install-sbom mixes absolute and relative artifact paths; only works when run from the build dir · convention

The sbom recipe writes outputs to $(abs_builddir)/$(SBOM_CDX) (absolute) at line 184, while install-sbom installs the bare $(SBOM_CDX), $(SBOM_SPDX), and $(SBOM_SPDX_TV) relative to the current directory at line 192. These only line up when make install-sbom runs from the build directory; VPATH/out-of-tree distcheck-style builds or invoking from a subdir would look in the wrong place.

Fix: Use $(abs_builddir)/$(SBOM_*) consistently in install-sbom (and CLEANFILES) to match where the sbom target actually writes the artifacts.

Comment thread CMakeLists.txt
"'pyspdxtools' not found in PATH (install: pip install spdx-tools)")
endif()

if(NOT _sbom_error STREQUAL "")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] CMake return() used at directory scope to skip the SBOM block; fragile if code is appended · Logic

When an SBOM prerequisite (python3/pyspdxtools/WOLFSSL_DIR) is missing, the code defines a failing fallback sbom target and then calls return(). This block is guarded by if(BUILD_WOLFTPM_LIB) at top-level directory scope (not inside a function), so return() ends processing of the remainder of CMakeLists.txt, not just the SBOM if block. It is harmless today only because the SBOM section is the last block in the file (ends at the endif() on line 896); any install(), target, or export logic added after it would be silently skipped in the common no-SBOM build. Severity views: review=Low/NIT, review-security=Info; strictest kept.

Fix: Avoid return() at directory scope for control flow. Select the fallback vs. real target with if()/else() (or a nested-if scoped to the SBOM section), or move the SBOM logic into a function/included module so the early exit cannot skip future directives.

Comment thread CMakeLists.txt
# this file drifts out of sync with the header.
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/wolftpm/version.h"
_sbom_version_line
REGEX "^#define[ \t]+LIBWOLFTPM_VERSION_STRING[ \t]+\"")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] CMake version.h regex uses [ \t] which does not match a tab in CMake's regex dialect · Logic

The SBOM version is parsed with REGEX "^#define[ \t]+LIBWOLFTPM_VERSION_STRING[ \t]+\"". CMake's regex engine does not interpret \t as a tab escape; inside the bracket expression [ \t] is the literal set {space, backslash, 't'}. It matches today only because the distributed wolftpm/version.h uses space separators. If version.h were ever regenerated with tab separators, file(STRINGS ... REGEX) would return no match, _sbom_version_line would be empty, and the target would abort via the FATAL_ERROR at 807-811. Currently benign — defense-in-depth only.

Fix: Since version.h is generated with single spaces, match [ ]+ explicitly, or embed a literal tab in the character class if tab tolerance is actually desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants