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
169 changes: 169 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3249,3 +3249,172 @@ if(WOLFSSL_INSTALL)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl
)
endif()

####################################################
# SBOM generation
####################################################
#
# Targets:
# sbom -- Generate CycloneDX 1.6 + SPDX 2.3 artifacts in CMAKE_BINARY_DIR
# install-sbom -- Copy artifacts to CMAKE_INSTALL_DOCDIR (triggers sbom first)
# uninstall-sbom -- Remove installed artifacts
#
# All three targets are always defined. If required tools were not found at
# configure time the targets fail with a clear error; re-run cmake after
# installing the tools to re-detect them.
#
# Output filenames match the autotools convention exactly so that CRA Kit
# scripts can locate them with the same pattern:
# wolfssl-<version>.cdx.json CycloneDX 1.6
# wolfssl-<version>.spdx.json SPDX 2.3 JSON (input to pyspdxtools)
# wolfssl-<version>.spdx SPDX 2.3 tag-value (pyspdxtools output)
#
# Equivalent autotools targets: make sbom / make install-sbom / make uninstall-sbom

find_program(WOLFSSL_SBOM_PYTHON3
NAMES python3
DOC "Python 3 interpreter for SBOM generation (scripts/gen-sbom)")
Comment on lines +3274 to +3276
find_program(WOLFSSL_SBOM_PYSPDXTOOLS
NAMES pyspdxtools
DOC "pyspdxtools SPDX validator for SBOM generation (pip install spdx-tools)")
find_program(WOLFSSL_SBOM_GIT
NAMES git
DOC "git binary for version detection by gen-sbom (optional; empty string if absent)")

# git is optional: gen-sbom accepts --git "" and falls back to other version sources.
# find_program sets the variable to <VAR>-NOTFOUND when the program is absent;
# normalise that to an empty string so VERBATIM does not pass the literal
# "WOLFSSL_SBOM_GIT-NOTFOUND" string to gen-sbom.
if(NOT WOLFSSL_SBOM_GIT)
set(WOLFSSL_SBOM_GIT "")
endif()

# SBOM output file paths (build directory, matching autotools naming).
set(WOLFSSL_SBOM_CDX "${CMAKE_BINARY_DIR}/wolfssl-${PROJECT_VERSION}.cdx.json")
set(WOLFSSL_SBOM_SPDX "${CMAKE_BINARY_DIR}/wolfssl-${PROJECT_VERSION}.spdx.json")
set(WOLFSSL_SBOM_TV "${CMAKE_BINARY_DIR}/wolfssl-${PROJECT_VERSION}.spdx")

# Map CMake feature options to gen-sbom --dep-* flags.
#
# libz: not yet implemented in the CMake build; see "TODO: - LIBZ" comment
# earlier in this file. Hardcoded "no" until a WOLFSSL_LIBZ option is
# added and wired up here.
#
# liblms / libxmss: being removed in wolfssl PR #10292. Mapped here so the
# SBOM remains accurate for builds that still enable them. The
# autotools --dep-libxmss-root and --dep-liblms-root arguments are
# omitted because CMakeLists.txt has no XMSS_ROOT / LIBLMS_ROOT
# equivalents.
set(_wolfssl_sbom_dep_liboqs "$<IF:$<BOOL:${WOLFSSL_OQS}>,yes,no>")
set(_wolfssl_sbom_dep_libxmss "$<IF:$<BOOL:${WOLFSSL_XMSS}>,yes,no>")
set(_wolfssl_sbom_dep_liblms "$<IF:$<BOOL:${WOLFSSL_LMS}>,yes,no>")
set(_wolfssl_sbom_dep_libz "no")

if(NOT WOLFSSL_SBOM_PYTHON3 OR NOT WOLFSSL_SBOM_PYSPDXTOOLS)
# Stub targets: always defined so that cmake --build --target sbom produces a
# clear diagnostic rather than "No rule to make target 'sbom'".
# Re-run cmake after installing the missing tools to enable the real targets.
set(_wolfssl_sbom_missing "")
if(NOT WOLFSSL_SBOM_PYTHON3)
message(STATUS "SBOM: python3 not found -- 'sbom' target disabled")
string(APPEND _wolfssl_sbom_missing " python3")
endif()
if(NOT WOLFSSL_SBOM_PYSPDXTOOLS)
message(STATUS
"SBOM: pyspdxtools not found -- 'sbom' target disabled (pip install spdx-tools)")
string(APPEND _wolfssl_sbom_missing " pyspdxtools")
endif()

foreach(_wolfssl_sbom_stub IN ITEMS sbom install-sbom uninstall-sbom)
add_custom_target(${_wolfssl_sbom_stub}
COMMAND ${CMAKE_COMMAND} -E echo
"ERROR: Required SBOM tools not found at configure time:${_wolfssl_sbom_missing}"
COMMAND ${CMAKE_COMMAND} -E echo
" Install the missing tools, re-run cmake, then retry."
COMMAND ${CMAKE_COMMAND} -E false
COMMENT "SBOM prerequisites missing -- re-run cmake to re-detect"
)
endforeach()
unset(_wolfssl_sbom_stub)
unset(_wolfssl_sbom_missing)
else()
# gen-sbom reads wolfssl/options.h for build-configuration #defines.
# That file is produced by configure_file(cmake/options.h.in ...) during
# the cmake configure step, so it is always present before the sbom target
# runs and does not require a separate build step.
#
# --lib uses $<TARGET_FILE:wolfssl> (the built library in the build tree)
# rather than a staging-install path. The autotools target stages an
# install solely to obtain the versioned .so path for SHA-256 hashing;
# the build-tree file is byte-for-byte identical and avoids that overhead.
add_custom_target(sbom
COMMAND "${WOLFSSL_SBOM_PYTHON3}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-sbom"
--name wolfssl
--version "${PROJECT_VERSION}"
--license-file "${CMAKE_CURRENT_SOURCE_DIR}/LICENSING"
--options-h "${WOLFSSL_OUTPUT_BASE}/wolfssl/options.h"
--lib "$<TARGET_FILE:wolfssl>"
--dep-liboqs "${_wolfssl_sbom_dep_liboqs}"
--dep-libxmss "${_wolfssl_sbom_dep_libxmss}"
--dep-liblms "${_wolfssl_sbom_dep_liblms}"
--dep-libz "${_wolfssl_sbom_dep_libz}"
--git "${WOLFSSL_SBOM_GIT}"
--cdx-out "${WOLFSSL_SBOM_CDX}"
--spdx-out "${WOLFSSL_SBOM_SPDX}"
COMMAND "${WOLFSSL_SBOM_PYSPDXTOOLS}"
--infile "${WOLFSSL_SBOM_SPDX}"
--outfile "${WOLFSSL_SBOM_TV}"
COMMENT "Generating wolfSSL SBOM (CycloneDX 1.6 + SPDX 2.3)"
VERBATIM
)
# wolfssl must be built before gen-sbom can hash $<TARGET_FILE:wolfssl>.
add_dependencies(sbom wolfssl)

# install-sbom: copy SBOM artifacts to the documentation install directory.
# Mirrors autotools: sbomdir = $(datadir)/doc/$(PACKAGE).
#
# Delegates to cmake/install-sbom.cmake so that DESTDIR is read from the
# environment at build time rather than configure time. This matches the
# autotools behaviour: DESTDIR=/staging make install-sbom.
# CMake equivalent: DESTDIR=/staging cmake --build <dir> --target install-sbom
add_custom_target(install-sbom
COMMAND ${CMAKE_COMMAND}
"-DWOLFSSL_SBOM_CDX=${WOLFSSL_SBOM_CDX}"
"-DWOLFSSL_SBOM_SPDX=${WOLFSSL_SBOM_SPDX}"
"-DWOLFSSL_SBOM_TV=${WOLFSSL_SBOM_TV}"
"-DWOLFSSL_VERSION=${PROJECT_VERSION}"
"-DWOLFSSL_INSTALL_DOCDIR=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/install-sbom.cmake"
COMMENT "Installing wolfSSL SBOM to ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}"
Comment on lines +3385 to +3388
VERBATIM
)
# sbom must complete before install-sbom copies its outputs.
add_dependencies(install-sbom sbom)

# uninstall-sbom: remove installed artifacts.
# Delegates to cmake/uninstall-sbom.cmake for the same DESTDIR reason.
# file(REMOVE ...) in that script is a no-op for absent files, matching
# autotools `rm -f`.
add_custom_target(uninstall-sbom
COMMAND ${CMAKE_COMMAND}
"-DWOLFSSL_VERSION=${PROJECT_VERSION}"
"-DWOLFSSL_INSTALL_DOCDIR=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall-sbom.cmake"
COMMENT
"Uninstalling wolfSSL SBOM from ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}"
Comment on lines +3400 to +3404
VERBATIM
)

# Register SBOM outputs with cmake's clean target so they are removed by
# cmake --build . --target clean alongside compiled artifacts.
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_CLEAN_FILES
"${WOLFSSL_SBOM_CDX}"
"${WOLFSSL_SBOM_SPDX}"
"${WOLFSSL_SBOM_TV}")
endif()

unset(_wolfssl_sbom_dep_liboqs)
unset(_wolfssl_sbom_dep_libxmss)
unset(_wolfssl_sbom_dep_liblms)
unset(_wolfssl_sbom_dep_libz)
36 changes: 36 additions & 0 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,39 @@ 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

Comment on lines +335 to +340
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
Comment on lines +350 to +356

The generated files are removed by make clean.

For details on the SBOM contents and CRA context, see doc/SBOM.md.
56 changes: 56 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,59 @@ 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) \
--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)
rm -rf $(abs_builddir)/_sbom_staging
$(PYSPDXTOOLS) --infile $(abs_builddir)/$(SBOM_SPDX) \
--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)
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ 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.
Comment on lines +35 to +36

## Notes, Please Read

### Note 1
Expand Down
38 changes: 38 additions & 0 deletions cmake/install-sbom.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# cmake -P script: install wolfSSL SBOM artifacts.
# Invoked by the install-sbom custom target. Reads DESTDIR from the
# environment at script-execution time (build time), so staging installs
# work correctly:
#
# DESTDIR=/staging cmake --build <dir> --target install-sbom
#
# Required -D arguments (passed by add_custom_target in CMakeLists.txt):
# WOLFSSL_SBOM_CDX path to generated CycloneDX JSON
# WOLFSSL_SBOM_SPDX path to generated SPDX JSON
# WOLFSSL_SBOM_TV path to generated SPDX tag-value
# WOLFSSL_VERSION project version string
# WOLFSSL_INSTALL_DOCDIR resolved install doc directory (absolute)

foreach(_var WOLFSSL_SBOM_CDX WOLFSSL_SBOM_SPDX WOLFSSL_SBOM_TV
WOLFSSL_VERSION WOLFSSL_INSTALL_DOCDIR)
if(NOT DEFINED ${_var})
message(FATAL_ERROR "install-sbom.cmake: required variable ${_var} not set")
endif()
endforeach()

# DESTDIR is read from the environment at script-execution time so that
# `DESTDIR=/staging cmake --build . --target install-sbom` works the same
# way as `make install-sbom DESTDIR=/staging` with autotools.
if(DEFINED ENV{DESTDIR})
set(_destdir "$ENV{DESTDIR}")
else()
set(_destdir "")
endif()

set(_dest "${_destdir}${WOLFSSL_INSTALL_DOCDIR}")

file(MAKE_DIRECTORY "${_dest}")
file(COPY "${WOLFSSL_SBOM_CDX}" DESTINATION "${_dest}")
file(COPY "${WOLFSSL_SBOM_SPDX}" DESTINATION "${_dest}")
file(COPY "${WOLFSSL_SBOM_TV}" DESTINATION "${_dest}")

message(STATUS "Installed wolfSSL SBOM to ${_dest}")
29 changes: 29 additions & 0 deletions cmake/uninstall-sbom.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# cmake -P script: uninstall wolfSSL SBOM artifacts.
# Invoked by the uninstall-sbom custom target. Reads DESTDIR from the
# environment at script-execution time (build time).
#
# Required -D arguments (passed by add_custom_target in CMakeLists.txt):
# WOLFSSL_VERSION project version string
# WOLFSSL_INSTALL_DOCDIR resolved install doc directory (absolute)

foreach(_var WOLFSSL_VERSION WOLFSSL_INSTALL_DOCDIR)
if(NOT DEFINED ${_var})
message(FATAL_ERROR "uninstall-sbom.cmake: required variable ${_var} not set")
endif()
endforeach()

if(DEFINED ENV{DESTDIR})
set(_destdir "$ENV{DESTDIR}")
else()
set(_destdir "")
endif()

set(_dest "${_destdir}${WOLFSSL_INSTALL_DOCDIR}")

# file(REMOVE ...) is a no-op for absent files, matching autotools `rm -f`.
file(REMOVE
"${_dest}/wolfssl-${WOLFSSL_VERSION}.cdx.json"
"${_dest}/wolfssl-${WOLFSSL_VERSION}.spdx.json"
"${_dest}/wolfssl-${WOLFSSL_VERSION}.spdx")

message(STATUS "Uninstalled wolfSSL SBOM from ${_dest}")
12 changes: 12 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,16 @@ 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])

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