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
5 changes: 3 additions & 2 deletions .github/workflows/sbom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Syntax check
run: python3 -m py_compile scripts/gen-sbom
run: python3 -m py_compile scripts/gen-sbom tools/sbom/gen-sbom

- name: Install pcpp
# pcpp is the in-Python C preprocessor that drives the
Expand Down Expand Up @@ -524,7 +524,8 @@ jobs:
refs = {r['referenceType']: r['referenceLocator']
for r in d['packages'][0]['externalRefs']}
assert re.match(r'cpe:2\.3:a:wolfssl:wolfssl:[\d.]+:', refs['cpe23Type']), refs
assert re.match(r'pkg:github/wolfSSL/wolfssl@v[\d.]+', refs['purl']), refs
assert re.fullmatch(
r'pkg:github/wolfssl/wolfssl@v[\d.]+-stable', refs['purl']), refs
assert refs['advisory'] == \
'https://github.com/wolfSSL/wolfssl/security/advisories', refs
print('identifiers ok:', refs)
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ NTRU_algorithm/
NTRU/
build-test/
build/
# tools/sbom/build is vendored source, not a compiler output directory.
!tools/sbom/build/
!tools/sbom/build/**
# Out-of-tree build dirs created by .github/scripts/parallel-make-check.py
/build-*/
cyassl.xcodeproj/
Expand Down
10 changes: 5 additions & 5 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -838,11 +838,11 @@ WC_HASH_CUSTOM_MAX_DIGEST_SIZE
WC_HASH_CUSTOM_MIN_DIGEST_SIZE
WC_HAVE_FIPS_INDICATOR
WC_INIT_ERROR_WHEN_CONTENDED
WC_LINUXKM_FORCE_SVR_DYNAMIC_AUDITING
WC_LINUXKM_NO_ENTROPY_DAEMON
WC_LINUXKM_NO_SVR_DYNAMIC_AUDITING
WC_LINUXKM_NO_USE_HEAP_WRAPPERS
WC_LINUXKM_SPIN_IN_ATOMIC
WC_LINUXKM_FORCE_SVR_DYNAMIC_AUDITING
WC_MLDSA_NO_ASM
WC_MLKEM_KERNEL_ASM
WC_MPFS_ATHENA_NO_BASE_ADDR
Expand Down Expand Up @@ -1227,10 +1227,6 @@ WOLFSSL_STSAFE_TAKES_SLOT
WOLFSSL_TELIT_M2MB
WOLFSSL_TEMPLATE_EXAMPLE
WOLFSSL_THREADED_CRYPT
WOLFSSL_TI_AM64X_R5
WOLFSSL_TI_AM64X_RNG_CTR_DRBG
WOLFSSL_TI_AM64X_NO_AES
WOLFSSL_TI_AM64X_NO_SHA
WOLFSSL_TICKET_DECRYPT_NO_CREATE
WOLFSSL_TICKET_ENC_AES128_GCM
WOLFSSL_TICKET_ENC_AES256_CBC
Expand All @@ -1240,6 +1236,10 @@ WOLFSSL_TICKET_ENC_CHACHA20_POLY1305
WOLFSSL_TICKET_ENC_HMAC_SHA384
WOLFSSL_TICKET_ENC_HMAC_SHA512
WOLFSSL_TINY_TLS13_NO_DEFAULT_CURVE
WOLFSSL_TI_AM64X_NO_AES
WOLFSSL_TI_AM64X_NO_SHA
WOLFSSL_TI_AM64X_R5
WOLFSSL_TI_AM64X_RNG_CTR_DRBG
WOLFSSL_TI_CURRTIME
WOLFSSL_TLS13_DRAFT
WOLFSSL_TLS13_IGNORE_AEAD_LIMITS
Expand Down
71 changes: 71 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5616,4 +5616,75 @@ if(WOLFSSL_INSTALL)
${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl
)

# SBOM. Hashes the installed library and reads wolfssl/options.h, the same
# inputs as `make sbom`. The helper is the vendored wolfssl-compliance-tooling
# snapshot in tools/sbom/. A missing python3 or pyspdxtools does not fail
# configure. The sbom target fails when someone runs it.
find_program(PYTHON3_CMD python3)
find_program(PYSPDXTOOLS_CMD pyspdxtools)
if(NOT PYTHON3_CMD)
set(_sbom_error "'python3' not found in PATH. Cannot generate SBOM.")
elseif(NOT PYSPDXTOOLS_CMD)
set(_sbom_error
"'pyspdxtools' not found in PATH (install: pip install spdx-tools)")
else()
set(_sbom_error "")
endif()

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 "")
add_custom_target(sbom
VERBATIM
COMMAND ${CMAKE_COMMAND} -E echo "sbom: ${_sbom_error}"
COMMAND ${CMAKE_COMMAND} -E false
COMMENT "SBOM prerequisites missing")
else()
include(${CMAKE_CURRENT_SOURCE_DIR}/tools/sbom/build/sbom.cmake)

set(SBOM_CDX "${CMAKE_BINARY_DIR}/wolfssl-${wolfssl_VERSION}.cdx.json")
set(SBOM_SPDX "${CMAKE_BINARY_DIR}/wolfssl-${wolfssl_VERSION}.spdx.json")
set(SBOM_SPDX_TV "${CMAKE_BINARY_DIR}/wolfssl-${wolfssl_VERSION}.spdx")
set(SBOM_STAGING "${CMAKE_BINARY_DIR}/_sbom_staging")

if(WIN32 AND BUILD_SHARED_LIBS)
set(SBOM_LIB "${SBOM_STAGING}/${CMAKE_INSTALL_BINDIR}/$<TARGET_FILE_NAME:wolfssl>")
else()
set(SBOM_LIB "${SBOM_STAGING}/${CMAKE_INSTALL_LIBDIR}/$<TARGET_FILE_NAME:wolfssl>")
endif()

set(_sbom_args
NAME wolfssl
VERSION ${wolfssl_VERSION}
LIB ${SBOM_LIB}
OPTIONS_H ${OPTION_FILE}
LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSING
ROOT ${CMAKE_CURRENT_SOURCE_DIR}
CDX_OUT ${SBOM_CDX}
SPDX_OUT ${SBOM_SPDX}
TARGET_NAME wolfssl-sbom-gen)
if(WOLFSSL_LIBZ)
list(APPEND _sbom_args DEP_LIBZ yes)
else()
list(APPEND _sbom_args DEP_LIBZ no)
endif()
wolfssl_compliance_tooling_add_sbom(${_sbom_args})

add_custom_target(wolfssl-sbom-stage
COMMAND ${CMAKE_COMMAND} -E remove_directory ${SBOM_STAGING}
COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR}
--prefix ${SBOM_STAGING} --config $<CONFIG>
DEPENDS wolfssl
VERBATIM
COMMENT "Staging libwolfssl for the SBOM")
add_dependencies(wolfssl-sbom-gen wolfssl-sbom-stage)
add_custom_target(sbom
COMMAND ${PYSPDXTOOLS_CMD} --infile ${SBOM_SPDX}
--outfile ${SBOM_SPDX_TV}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${SBOM_STAGING}
DEPENDS wolfssl-sbom-gen
VERBATIM
COMMENT "Validating wolfSSL SBOM")
endif()
endif()
180 changes: 38 additions & 142 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -452,154 +452,50 @@ 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
# Use Automake's $(docdir) so a user's --docdir override is honoured (this
# equals $(datadir)/doc/$(PACKAGE) by default).
sbomdir = $(docdir)

# Shared-library / Mach-O basenames in priority order (versioned first).
# Both `sbom:` and `bomsh:` glob for these under their own search prefixes;
# adding a new platform-specific dynamic-library extension here updates
# both targets at once. Static (.a) and Windows (.dll/.lib) variants are
# listed inline at each call-site because their ordering and prefixes
# differ between the install tree and the build tree.
# SBOM generation. The recipe and the generator are the vendored
# wolfssl-compliance-tooling snapshot in tools/sbom/ (pinned by
# tools/sbom/.wolfssl-compliance-tooling-rev). wolfSSL records the configured
# feature set from wolfssl/options.h and whether this build links zlib.
#
# User-overridable variables (defined by tools/sbom/sbom.am):
# SBOM_LICENSE_OVERRIDE, SBOM_LICENSE_TEXT, SBOM_COPYRIGHT_START,
# SBOM_DOCUMENT_NAMESPACE, SBOM_DEP_VERSIONS, SBOM_LIB_OVERRIDE.
# `make bomsh` sets SBOM_LIB_OVERRIDE so the SBOM hash and the OmniBOR
# gitoid name the traced library. A private install relinks a different file.
SBOM_PKGNAME = wolfssl
SBOM_LICENSE_FILE = $(srcdir)/LICENSING
SBOM_OPTIONS_H = $(abs_builddir)/wolfssl/options.h
SBOM_DEP_LIBZ = $(ENABLED_LIBZ)

EXTRA_DIST += tools/sbom/sbom-driver
EXTRA_DIST += tools/sbom/sbom-driver.py
EXTRA_DIST += tools/sbom/gen-sbom
EXTRA_DIST += tools/sbom/sbom.am
EXTRA_DIST += tools/sbom/validate_sbom.py
EXTRA_DIST += tools/sbom/README.md
EXTRA_DIST += tools/sbom/VERSION
EXTRA_DIST += tools/sbom/.wolfssl-compliance-tooling-rev
EXTRA_DIST += tools/sbom/build/sbom.cmake
EXTRA_DIST += tools/sbom/build/sbom.mk
EXTRA_DIST += tools/sbom/build/install-sbom.cmake
EXTRA_DIST += tools/sbom/build/uninstall-sbom.cmake
EXTRA_DIST += tools/sbom/build/sbom-paths.cmake
EXTRA_DIST += tools/sbom/build/sbom-with-sde.cmake
EXTRA_DIST += tools/sbom/frontends/compdb_sbom.py
EXTRA_DIST += tools/sbom/frontends/iar_sbom.py
EXTRA_DIST += tools/sbom/frontends/included_sources.py
EXTRA_DIST += tools/sbom/frontends/zephyr_sbom.py

include scripts/sbom.am

# Mach-O / ELF basenames. `make bomsh` searches src/.libs for these.
# Static and Windows names are listed at the bomsh call site.
WOLFSSL_LIB_DSO_BASENAMES = \
libwolfssl.so.[0-9]* \
libwolfssl.so \
libwolfssl.[0-9]*.dylib \
libwolfssl.dylib

.PHONY: sbom install-sbom uninstall-sbom

# Stage a `make install` into a private tree, discover the installed library
# artifact (shared or static, ELF/Mach-O/PE), hash it, generate SPDX+CDX,
# validate the SPDX, then convert to tag-value. The staging tree is removed
# unconditionally via `trap`, even if any step fails. Honors SOURCE_DATE_EPOCH
# for reproducible builds (set by the recipe to `git log -1 --format=%ct` when
# unset and a git tree is available).
#
# User-overridable variables:
# SBOM_LICENSE_OVERRIDE SPDX expression to use instead of the GPL ID
# parsed from LICENSING (e.g. for commercial
# licensees: LicenseRef-wolfSSL-Commercial).
# SBOM_LICENSE_TEXT Path to the actual licence text for any
# LicenseRef-* in SBOM_LICENSE_OVERRIDE. Required
# for SPDX 2.3 conformance whenever a custom
# LicenseRef is in use; `make sbom` exits with an
# error if it is missing.
# SBOM_DOCUMENT_NAMESPACE Override the SPDX documentNamespace. Default
# is a deterministic urn:uuid (SPDX 2.3 sec. 6.5
# requires only uniqueness, not resolvability).
# Downstream packagers re-hosting the SBOM under
# their own URL should set this to a URI they
# actually serve (e.g.
# https://example.com/sbom/wolfssl-X.Y.Z.spdx.json).
# SBOM_DEP_VERSIONS Space-separated KEY=VERSION list forwarded to
# gen-sbom as repeated --dep-version flags (KEY is
# one of the known deps, e.g. libz / openssl). Use
# this on build/packaging hosts that lack the dep's
# pkg-config .pc file, where version detection would
# otherwise fall back to NOASSERTION (SPDX) / an
# omitted version+purl (CycloneDX). Example:
# make sbom SBOM_DEP_VERSIONS='libz=1.3.1 openssl=3.5.0'.
# SBOM_LIB_OVERRIDE Absolute path to the library artefact whose
# SHA-256 should land in the SBOM, INSTEAD of
# discovering one via a private staging install.
# Set by `make bomsh` so the SBOM hash and the
# OmniBOR enrichment refer to the SAME bomsh-
# traced binary; without this override `make
# sbom` would re-link via `make install` and
# hash a different artefact than `bomsh_sbom.py`
# fingerprints, leaving the SHA-256 in
# `checksums[]` and the gitoid in `externalRefs`
# describing two unrelated files.
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
@set -e; \
trap 'rm -rf $(abs_builddir)/_sbom_staging' EXIT INT TERM HUP; \
if test -n "$(SBOM_LIB_OVERRIDE)"; then \
if test ! -f "$(SBOM_LIB_OVERRIDE)"; then \
echo ""; \
echo "ERROR: SBOM_LIB_OVERRIDE=$(SBOM_LIB_OVERRIDE) does not exist."; \
echo ""; \
exit 1; \
fi; \
sbom_lib="$(SBOM_LIB_OVERRIDE)"; \
else \
$(MAKE) install DESTDIR=$(abs_builddir)/_sbom_staging; \
sbom_lib=""; \
for lib in \
$(addprefix "$(abs_builddir)/_sbom_staging$(libdir)"/,$(WOLFSSL_LIB_DSO_BASENAMES)) \
"$(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: No installed wolfSSL library artifact found for SBOM."; \
echo " Searched in $(abs_builddir)/_sbom_staging$(libdir)"; \
echo " (configure with --enable-shared or --enable-static)"; \
echo ""; \
exit 1; \
fi; \
fi; \
echo "SBOM: hashing $$sbom_lib"; \
if test -z "$${SOURCE_DATE_EPOCH:-}" && test -n "$(GIT)" && \
$(GIT) -C "$(srcdir)" rev-parse --git-dir >/dev/null 2>&1; then \
sde=`$(GIT) -C "$(srcdir)" log -1 --format=%ct 2>/dev/null`; \
if test -n "$$sde"; then \
SOURCE_DATE_EPOCH="$$sde"; \
export SOURCE_DATE_EPOCH; \
fi; \
fi; \
$(PYTHON3) $(srcdir)/scripts/gen-sbom \
--name $(PACKAGE) \
--version $(PACKAGE_VERSION) \
--license-file $(srcdir)/LICENSING \
$(if $(SBOM_LICENSE_OVERRIDE),--license-override '$(SBOM_LICENSE_OVERRIDE)') \
$(if $(SBOM_LICENSE_TEXT),--license-text '$(SBOM_LICENSE_TEXT)') \
$(if $(SBOM_DOCUMENT_NAMESPACE),--document-namespace '$(SBOM_DOCUMENT_NAMESPACE)') \
--options-h $(abs_builddir)/wolfssl/options.h \
--lib "$$sbom_lib" \
--dep-libz "$(ENABLED_LIBZ)" \
$(foreach dv,$(SBOM_DEP_VERSIONS),--dep-version '$(dv)') \
--cdx-out $(abs_builddir)/$(SBOM_CDX) \
--spdx-out $(abs_builddir)/$(SBOM_SPDX); \
$(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)

# Security advisory generation (CSAF 2.0 + CycloneDX 1.6 VEX)
#
# `make advisory` is a thin wrapper around scripts/gen-advisory: it feeds the
Expand Down
6 changes: 3 additions & 3 deletions doc/CRA.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ make sbom # produces wolfssl-<version>.spdx.json, .cdx.json, .spdx
make bomsh # optional: produces omnibor/ + OmniBOR-enriched SPDX
```

`make sbom` is a convenience wrapper around the same `scripts/gen-sbom`
script the embedded path uses.
`make sbom` uses `scripts/sbom.am`, which includes `tools/sbom/sbom.am`.
That recipe calls the same generator as `scripts/gen-sbom`.

See `doc/SBOM.md` for prerequisites and full details on both entry
points.
Expand Down Expand Up @@ -155,7 +155,7 @@ under which your distribution mirrors `wolfssl-<version>.cdx.json`.
"type": "library",
"name": "wolfssl",
"version": "<version>",
"purl": "pkg:github/wolfSSL/wolfssl@v<version>",
"purl": "pkg:github/wolfssl/wolfssl@v<version>-stable",
"cpe": "cpe:2.3:a:wolfssl:wolfssl:<version>:*:*:*:*:*:*:*",
"licenses": [{ "license": { "id": "GPL-3.0-only" } }],
"externalReferences": [
Expand Down
Loading
Loading