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
73 changes: 73 additions & 0 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,76 @@ We also have vcpkg ports for wolftpm, wolfmqtt and curl.

Deprecated. wolfSSL now has its own XMMS/XMSS^MT implementation in
wolfCrypt.

21. Generating an SBOM (Software Bill of Materials)

wolfSSL can generate a Software Bill of Materials for EU Cyber Resilience
Act (CRA) compliance after a normal build and install.

Prerequisites:
- python3 (detected automatically by configure)
- pyspdxtools (pip install spdx-tools)

Usage:

$ ./configure
$ make
$ make sbom

This produces three files in the build directory:

wolfssl-<version>.cdx.json CycloneDX 1.6 JSON
wolfssl-<version>.spdx.json SPDX 2.3 JSON
wolfssl-<version>.spdx SPDX 2.3 tag-value (validated by pyspdxtools)

The SPDX JSON is validated by pyspdxtools before the tag-value file is
written; make sbom fails if validation fails.

To install the SBOM files to $(datadir)/doc/wolfssl/:

$ make install-sbom

To remove installed SBOM files:

$ make uninstall-sbom

The generated files are removed by make clean.

For details on the SBOM contents and CRA context, see doc/SBOM.md.

22. Generating OmniBOR build artifact graph (Bomsh)

wolfSSL supports generating an OmniBOR artifact dependency graph using
the Bomsh project (https://github.com/omnibor/bomsh). OmniBOR provides
cryptographic traceability from every binary artifact back to the exact
source files that produced it.

Prerequisites:
- bomtrace3 (build from https://github.com/omnibor/bomsh)
- bomsh_create_bom.py (from the bomsh scripts/ directory, in PATH)
- bomsh_sbom.py (optional; from bomsh scripts/, for SPDX enrichment)

Both bomtrace3 and the Python scripts are detected by configure.
make bomsh fails with a clear error message if either required tool
is missing.

Usage:

$ ./configure
$ make
$ make bomsh

This performs a clean rebuild of wolfSSL under bomtrace3 tracing,
then produces an OmniBOR artifact graph in omnibor/ in the build
directory. If bomsh_sbom.py is available and a wolfssl-<ver>.spdx.json
exists (from 'make sbom'), it also produces an OmniBOR-enriched SPDX
document omnibor.wolfssl-<ver>.spdx.json.

To install:

$ make install-bomsh # installs omnibor/ to $(datadir)/doc/wolfssl/
$ make uninstall-bomsh # removes installed files

The generated files are removed by make clean.

See doc/SBOM.md for full details.
110 changes: 110 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,113 @@ merge-clean:

.cu.lo:
$(LIBTOOL) --tag=CC --mode=compile $(COMPILE) --compile -o $@ $< -static

# SBOM generation (CRA compliance)
SBOM_CDX = wolfssl-$(PACKAGE_VERSION).cdx.json
SBOM_SPDX = wolfssl-$(PACKAGE_VERSION).spdx.json
SBOM_SPDX_TV = wolfssl-$(PACKAGE_VERSION).spdx
sbomdir = $(datadir)/doc/$(PACKAGE)

.PHONY: sbom install-sbom uninstall-sbom

sbom:
@if test -z "$(PYTHON3)"; then \
echo ""; \
echo "ERROR: 'python3' not found in PATH. Cannot generate SBOM."; \
echo ""; \
exit 1; \
fi
@if test -z "$(PYSPDXTOOLS)"; then \
echo ""; \
echo "ERROR: 'pyspdxtools' not found in PATH. Cannot validate SBOM."; \
echo " Install: pip install spdx-tools"; \
echo ""; \
exit 1; \
fi
rm -rf $(abs_builddir)/_sbom_staging
$(MAKE) install DESTDIR=$(abs_builddir)/_sbom_staging
$(PYTHON3) $(srcdir)/scripts/gen-sbom \
--name $(PACKAGE) \
--version $(PACKAGE_VERSION) \
--license-file $(srcdir)/LICENSING \
--options-h $(abs_builddir)/wolfssl/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolfssl.so.$(WOLFSSL_LIBRARY_VERSION_FIRST).$(WOLFSSL_LIBRARY_VERSION_SECOND).$(WOLFSSL_LIBRARY_VERSION_THIRD) \
Comment on lines +378 to +383
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

The SBOM hash input path is hard-coded to libwolfssl.so.<first>.<second>.<third>. This will fail on configurations that disable shared libraries (e.g., --disable-shared, and also when --with-libxmss / --with-liblms forces enable_shared=no in configure.ac). Please detect the installed library artifact dynamically (shared vs static, platform suffixes) or fall back to hashing the static archive when the .so is not present.

Suggested change
$(PYTHON3) $(srcdir)/scripts/gen-sbom \
--name $(PACKAGE) \
--version $(PACKAGE_VERSION) \
--license-file $(srcdir)/LICENSING \
--options-h $(abs_builddir)/wolfssl/options.h \
--lib $(abs_builddir)/_sbom_staging$(libdir)/libwolfssl.so.$(WOLFSSL_LIBRARY_VERSION_FIRST).$(WOLFSSL_LIBRARY_VERSION_SECOND).$(WOLFSSL_LIBRARY_VERSION_THIRD) \
@sbom_lib=""; \
for lib in \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.so.* \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.so \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.dylib \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.*.dylib \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.dll \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.dll.a \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.lib \
"$(abs_builddir)/_sbom_staging$(libdir)"/wolfssl.lib \
"$(abs_builddir)/_sbom_staging$(libdir)"/libwolfssl.a; do \
if test -f "$$lib"; then \
sbom_lib="$$lib"; \
break; \
fi; \
done; \
if test -z "$$sbom_lib"; then \
echo ""; \
echo "ERROR: Unable to locate installed wolfSSL library artifact for SBOM generation."; \
echo " Searched in $(abs_builddir)/_sbom_staging$(libdir) for shared and static library outputs."; \
echo ""; \
rm -rf $(abs_builddir)/_sbom_staging; \
exit 1; \
fi; \
$(PYTHON3) $(srcdir)/scripts/gen-sbom \
--name $(PACKAGE) \
--version $(PACKAGE_VERSION) \
--license-file $(srcdir)/LICENSING \
--options-h $(abs_builddir)/wolfssl/options.h \
--lib "$$sbom_lib" \

Copilot uses AI. Check for mistakes.
--dep-liboqs $(ENABLED_LIBOQS) \
--dep-libxmss $(ENABLED_LIBXMSS) \
--dep-libxmss-root '$(XMSS_ROOT)' \
--dep-liblms $(ENABLED_LIBLMS) \
--dep-liblms-root '$(LIBLMS_ROOT)' \
--dep-libz $(ENABLED_LIBZ) \
--git '$(GIT)' \
--cdx-out $(abs_builddir)/$(SBOM_CDX) \
--spdx-out $(abs_builddir)/$(SBOM_SPDX)
Comment on lines +378 to +392
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

scripts/gen-sbom is invoked from make sbom, but it is not currently listed in scripts/include.am’s EXTRA_DIST/dist_noinst_SCRIPTS. As a result, make dist tarballs are likely to omit the generator and make sbom will fail for users building from release archives. Please add scripts/gen-sbom to the distribution list.

Copilot uses AI. Check for mistakes.
rm -rf $(abs_builddir)/_sbom_staging
$(PYSPDXTOOLS) --infile $(abs_builddir)/$(SBOM_SPDX) \
Comment on lines +376 to +394
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

If scripts/gen-sbom fails, the _sbom_staging directory is not cleaned up because rm -rf only runs after the generator completes successfully. Consider ensuring staging cleanup happens even on failure (e.g., trap/cleanup handler or chaining cleanup with ||), to avoid leaving large staged installs behind.

Copilot uses AI. Check for mistakes.
--outfile $(abs_builddir)/$(SBOM_SPDX_TV)

install-sbom: sbom
$(MKDIR_P) $(DESTDIR)$(sbomdir)
$(INSTALL_DATA) $(SBOM_CDX) $(DESTDIR)$(sbomdir)/
$(INSTALL_DATA) $(SBOM_SPDX) $(DESTDIR)$(sbomdir)/
$(INSTALL_DATA) $(SBOM_SPDX_TV) $(DESTDIR)$(sbomdir)/

uninstall-sbom:
-rm -f $(DESTDIR)$(sbomdir)/$(SBOM_CDX)
-rm -f $(DESTDIR)$(sbomdir)/$(SBOM_SPDX)
-rm -f $(DESTDIR)$(sbomdir)/$(SBOM_SPDX_TV)

CLEANFILES += $(SBOM_CDX) $(SBOM_SPDX) $(SBOM_SPDX_TV)

# Bomsh (OmniBOR build artifact tracing + SBOM enrichment)
BOMSH_RAWLOG_BASE = $(abs_builddir)/bomsh_raw_logfile
BOMSH_RAWLOG = $(BOMSH_RAWLOG_BASE).sha1
BOMSH_CONF = $(abs_builddir)/_bomsh.conf
BOMSH_OMNIBORDIR = $(abs_builddir)/omnibor
BOMSH_SPDX_OUT = omnibor.wolfssl-$(PACKAGE_VERSION).spdx.json
bomshdir = $(datadir)/doc/$(PACKAGE)

.PHONY: bomsh install-bomsh uninstall-bomsh

bomsh:
@if test -z "$(BOMTRACE3)"; then \
echo ""; \
echo "ERROR: 'bomtrace3' not found in PATH. Cannot generate OmniBOR data."; \
echo " Build bomtrace3 from: https://github.com/omnibor/bomsh"; \
echo ""; \
exit 1; \
fi
@if test -z "$(BOMSH_CREATE_BOM)"; then \
echo ""; \
echo "ERROR: 'bomsh_create_bom.py' not found in PATH. Cannot process OmniBOR data."; \
echo " Install from: https://github.com/omnibor/bomsh"; \
echo ""; \
exit 1; \
fi
$(MAKE) clean
@printf 'raw_logfile=%s\n' '$(BOMSH_RAWLOG_BASE)' > '$(BOMSH_CONF)'
$(BOMTRACE3) -c '$(BOMSH_CONF)' $(MAKE)
$(BOMSH_CREATE_BOM) -r '$(BOMSH_RAWLOG)' -b '$(BOMSH_OMNIBORDIR)'
@if test -n "$(BOMSH_SBOM)" && test -f '$(abs_builddir)/wolfssl-$(PACKAGE_VERSION).spdx.json'; then \
echo "Enriching SPDX with OmniBOR ExternalRefs..."; \
Comment on lines +435 to +440
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

make bomsh starts with $(MAKE) clean), but make clean removes the SBOM outputs (they’re in CLEANFILES). That means even if the user runs make sbom first, the subsequent test -f wolfssl-$(PACKAGE_VERSION).spdx.json will be false and the SPDX enrichment step won’t run. Consider preserving/regenerating the SPDX after the traced rebuild (e.g., run the SBOM generator after the bomtrace3 rebuild, or copy the SPDX aside before clean and restore it).

Copilot uses AI. Check for mistakes.
$(BOMSH_SBOM) \
-b '$(BOMSH_OMNIBORDIR)' \
-i '$(abs_builddir)/wolfssl-$(PACKAGE_VERSION).spdx.json' \
-f '$(abs_builddir)/src/.libs/libwolfssl.so.$(WOLFSSL_LIBRARY_VERSION_FIRST).$(WOLFSSL_LIBRARY_VERSION_SECOND).$(WOLFSSL_LIBRARY_VERSION_THIRD)' \
-s spdx-json \
-O '$(abs_builddir)'; \
Comment on lines +440 to +446
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

The Bomsh SPDX enrichment uses a hard-coded shared-library path (src/.libs/libwolfssl.so.<...>). This will fail on static-only builds and on non-ELF platforms (e.g., macOS .dylib). Consider resolving the built artifact path in a platform/config-aware way (or passing the installed artifact from the staging area, similar to make sbom).

Suggested change
echo "Enriching SPDX with OmniBOR ExternalRefs..."; \
$(BOMSH_SBOM) \
-b '$(BOMSH_OMNIBORDIR)' \
-i '$(abs_builddir)/wolfssl-$(PACKAGE_VERSION).spdx.json' \
-f '$(abs_builddir)/src/.libs/libwolfssl.so.$(WOLFSSL_LIBRARY_VERSION_FIRST).$(WOLFSSL_LIBRARY_VERSION_SECOND).$(WOLFSSL_LIBRARY_VERSION_THIRD)' \
-s spdx-json \
-O '$(abs_builddir)'; \
bomsh_artifact=""; \
for candidate in \
$(abs_builddir)/src/.libs/libwolfssl.so \
$(abs_builddir)/src/.libs/libwolfssl.so.* \
$(abs_builddir)/src/.libs/libwolfssl.dylib \
$(abs_builddir)/src/.libs/libwolfssl.*.dylib \
$(abs_builddir)/src/.libs/libwolfssl.a \
$(abs_builddir)/src/libwolfssl.a; do \
if test -f "$$candidate"; then \
bomsh_artifact="$$candidate"; \
break; \
fi; \
done; \
if test -n "$$bomsh_artifact"; then \
echo "Enriching SPDX with OmniBOR ExternalRefs..."; \
$(BOMSH_SBOM) \
-b '$(BOMSH_OMNIBORDIR)' \
-i '$(abs_builddir)/wolfssl-$(PACKAGE_VERSION).spdx.json' \
-f "$$bomsh_artifact" \
-s spdx-json \
-O '$(abs_builddir)'; \
else \
echo "NOTE: unable to locate a built libwolfssl artifact for SPDX enrichment."; \
fi; \

Copilot uses AI. Check for mistakes.
elif test -n "$(BOMSH_SBOM)"; then \
echo "NOTE: run 'make sbom' first, then 'make bomsh' for OmniBOR-enriched SPDX."; \
fi

install-bomsh: bomsh
$(MKDIR_P) $(DESTDIR)$(bomshdir)
cp -r '$(BOMSH_OMNIBORDIR)' '$(DESTDIR)$(bomshdir)/omnibor'
Comment on lines +452 to +453
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

install-bomsh uses cp -r to install the omnibor/ tree. This bypasses standard install tooling (permissions, verbosity, portability, $(INSTALL) overrides) and can behave differently across platforms. Consider using an Automake-friendly install approach (e.g., create the dir then copy files with $(INSTALL_DATA) via find, or use tar piping) so packaging/install behaves consistently.

Suggested change
$(MKDIR_P) $(DESTDIR)$(bomshdir)
cp -r '$(BOMSH_OMNIBORDIR)' '$(DESTDIR)$(bomshdir)/omnibor'
$(MKDIR_P) '$(DESTDIR)$(bomshdir)'
$(MKDIR_P) '$(DESTDIR)$(bomshdir)/omnibor'
@if test -d '$(BOMSH_OMNIBORDIR)'; then \
cd '$(BOMSH_OMNIBORDIR)' && tar cf - . | \
(cd '$(DESTDIR)$(bomshdir)/omnibor' && tar xpf -); \
fi

Copilot uses AI. Check for mistakes.
@if test -f '$(abs_builddir)/$(BOMSH_SPDX_OUT)'; then \
$(INSTALL_DATA) '$(abs_builddir)/$(BOMSH_SPDX_OUT)' '$(DESTDIR)$(bomshdir)/'; \
fi

uninstall-bomsh:
-rm -rf '$(DESTDIR)$(bomshdir)/omnibor'
-rm -f '$(DESTDIR)$(bomshdir)/$(BOMSH_SPDX_OUT)'

CLEANFILES += $(BOMSH_RAWLOG) $(BOMSH_RAWLOG_BASE).sha256 $(BOMSH_CONF) $(BOMSH_SPDX_OUT)
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ applications which have previously used the OpenSSL package. For a complete
feature list, see [Chapter 4](https://www.wolfssl.com/docs/wolfssl-manual/ch4/)
of the wolfSSL manual.

## SBOM / CRA Compliance

wolfSSL provides a Software Bill of Materials (SBOM) for EU Cyber Resilience
Act (CRA) compliance via `make sbom`. See `doc/SBOM.md` for details.

## OmniBOR / Bomsh

wolfSSL supports generating an OmniBOR artifact dependency graph via
`make bomsh`, providing cryptographic traceability from the installed
library back to every source file that produced it. See `doc/SBOM.md`
for details.

## Notes, Please Read

### Note 1
Expand Down
17 changes: 17 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1989,6 +1989,7 @@ done
# liblms
# Get the path to the hash-sigs LMS HSS lib.
ENABLED_LIBLMS="no"
LIBLMS_ROOT=""
tryliblmsdir=""
AC_ARG_WITH([liblms],
[AS_HELP_STRING([--with-liblms=PATH],[PATH to hash-sigs LMS/HSS install (default /usr/local) (requires --enable-experimental)!])],
Expand Down Expand Up @@ -2051,6 +2052,7 @@ AC_ARG_WITH([liblms],

AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBLMS"
ENABLED_LIBLMS="yes"
LIBLMS_ROOT=$tryliblmsdir
]
)

Expand Down Expand Up @@ -11756,6 +11758,21 @@ AC_SUBST([WOLFSSL_PREFIX_ABS])
AC_SUBST([WOLFSSL_LIBDIR_ABS])
AC_SUBST([WOLFSSL_INCLUDEDIR_ABS])

# SBOM generation
AC_PATH_PROG([PYTHON3], [python3])
AC_PATH_PROG([PYSPDXTOOLS], [pyspdxtools])
AC_PATH_PROG([GIT], [git])
AC_SUBST([ENABLED_LIBOQS])
AC_SUBST([ENABLED_LIBXMSS])
AC_SUBST([ENABLED_LIBLMS])
AC_SUBST([ENABLED_LIBZ])
AC_SUBST([LIBLMS_ROOT])

# Bomsh (OmniBOR build artifact tracing + SBOM enrichment)
AC_PATH_PROG([BOMTRACE3], [bomtrace3])
AC_PATH_PROG([BOMSH_CREATE_BOM], [bomsh_create_bom.py])
AC_PATH_PROG([BOMSH_SBOM], [bomsh_sbom.py])

# FINAL
AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
AC_CONFIG_FILES([Makefile
Expand Down
Loading
Loading