-
Notifications
You must be signed in to change notification settings - Fork 970
feat: add CRA SBOM generation (make sbom) #10342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
Comment on lines
+393
to
+395
|
||
|
|
||
| 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) | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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)!])], | ||||||
|
|
@@ -2051,6 +2052,7 @@ AC_ARG_WITH([liblms], | |||||
|
|
||||||
| AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBLMS" | ||||||
| ENABLED_LIBLMS="yes" | ||||||
| LIBLMS_ROOT=$tryliblmsdir | ||||||
|
||||||
| LIBLMS_ROOT=$tryliblmsdir | |
| LIBLMS_ROOT="$tryliblmsdir" |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,107 @@ | ||||||||||
| # wolfSSL SBOM Generation | ||||||||||
|
|
||||||||||
| wolfSSL generates a Software Bill of Materials (SBOM) to support compliance | ||||||||||
| with the EU Cyber Resilience Act (CRA), which requires software products | ||||||||||
| placed on the EU market to provide a machine-readable SBOM identifying all | ||||||||||
| software components. | ||||||||||
|
|
||||||||||
| ## Quick Start | ||||||||||
|
|
||||||||||
| ```sh | ||||||||||
| ./configure | ||||||||||
| make | ||||||||||
| make sbom | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| This requires `python3` and `pyspdxtools` (`pip install spdx-tools`). | ||||||||||
| Both are detected by `configure`; `make sbom` fails with a clear error | ||||||||||
| message if either is missing. | ||||||||||
|
|
||||||||||
| ## Output Files | ||||||||||
|
|
||||||||||
| `make sbom` produces three files in the build directory: | ||||||||||
|
|
||||||||||
| | File | Format | Standard | Primary use | | ||||||||||
| |---|---|---|---| | ||||||||||
| | `wolfssl-<version>.cdx.json` | JSON | CycloneDX 1.6 | Supply-chain tooling, VEX | | ||||||||||
| | `wolfssl-<version>.spdx.json` | JSON | SPDX 2.3 | Machine processing | | ||||||||||
| | `wolfssl-<version>.spdx` | Tag-value | SPDX 2.3 | Human review, archival | | ||||||||||
|
|
||||||||||
| The `.spdx` tag-value file is produced by `pyspdxtools` converting the | ||||||||||
| `.spdx.json`. If the JSON fails SPDX validation, `make sbom` stops with | ||||||||||
| a non-zero exit and the tag-value file is not written. | ||||||||||
|
|
||||||||||
| ## Installing the SBOM | ||||||||||
|
|
||||||||||
| ```sh | ||||||||||
| make install-sbom # installs to $(datadir)/doc/wolfssl/ | ||||||||||
| make uninstall-sbom # removes the installed files | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The generated files are removed by `make clean`. | ||||||||||
|
|
||||||||||
| ## SBOM Contents | ||||||||||
|
|
||||||||||
| Both formats contain the same information: | ||||||||||
|
|
||||||||||
| | Field | Value | | ||||||||||
| |---|---| | ||||||||||
| | Name | `wolfssl` | | ||||||||||
| | Version | from `configure.ac` (`PACKAGE_VERSION`) | | ||||||||||
| | Type | library | | ||||||||||
| | Supplier | wolfSSL Inc. | | ||||||||||
| | License | detected from `LICENSING` file (currently `GPL-3.0-only`) | | ||||||||||
| | Copyright | `Copyright (C) 2006-<year> wolfSSL Inc.` | | ||||||||||
| | SHA-256 | hash of the installed `libwolfssl.so.X.Y.Z` | | ||||||||||
| | CPE | `cpe:2.3:a:wolfssl:wolfssl:<version>:*:*:*:*:*:*:*` | | ||||||||||
| | PURL | `pkg:generic/wolfssl@<version>` | | ||||||||||
| | Download location | `https://github.com/wolfSSL/wolfssl` | | ||||||||||
| | Third-party deps | none (wolfssl has no runtime dependencies in a default build) | | ||||||||||
|
|
||||||||||
| ### License detection | ||||||||||
|
|
||||||||||
| The license SPDX identifier is parsed from the `LICENSING` file at SBOM | ||||||||||
| generation time, not hardcoded. If the `LICENSING` file cannot be parsed, | ||||||||||
| `make sbom` warns and uses `NOASSERTION` rather than silently emitting a | ||||||||||
| wrong value. | ||||||||||
|
|
||||||||||
| ### Dual licensing | ||||||||||
|
|
||||||||||
| wolfSSL is available under `GPL-3.0-only` for open-source use, with a | ||||||||||
| commercial license for proprietary products. The SBOM reflects the | ||||||||||
| open-source license. Commercial licensees should update the `licenseConcluded` | ||||||||||
| field to `LicenseRef-wolfSSL-Commercial` or their applicable SPDX expression | ||||||||||
| when distributing under a commercial agreement. | ||||||||||
|
|
||||||||||
| ## Validating the SBOM Manually | ||||||||||
|
|
||||||||||
| ```sh | ||||||||||
| # Validate SPDX JSON | ||||||||||
| pyspdxtools --infile wolfssl-<version>.spdx.json | ||||||||||
|
|
||||||||||
| # Convert to another format (e.g. RDF) | ||||||||||
| pyspdxtools --infile wolfssl-<version>.spdx.json \ | ||||||||||
| --outfile wolfssl-<version>.spdx.rdf | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### External dependency version detection | ||||||||||
|
|
||||||||||
| For dependencies with pkg-config support (`liboqs`, `libz`), the version is | ||||||||||
| queried via `pkg-config --modversion` at generation time. | ||||||||||
|
|
||||||||||
| For dependencies without pkg-config (`libxmss`, `liblms`), wolfSSL is typically | ||||||||||
| built against a source checkout rather than an installed package. The generator | ||||||||||
| falls back to `git describe --tags --always` on the source tree root (passed via | ||||||||||
| `configure` as `XMSS_ROOT` / `LIBLMS_ROOT`). If the source tree has no tags, | ||||||||||
| `git describe` returns the short commit hash, which is recorded as-is. If the | ||||||||||
| source tree is unavailable or `git` is not found, version is recorded as | ||||||||||
| `NOASSERTION`. | ||||||||||
|
Comment on lines
+97
to
+98
|
||||||||||
| source tree is unavailable or `git` is not found, version is recorded as | |
| `NOASSERTION`. | |
| source tree is unavailable or `git` is not found, SPDX records `NOASSERTION` | |
| for `versionInfo`, while CycloneDX omits `version` and `purl`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The staging directory is only removed on the success path. If
make install,gen-sbom, orpyspdxtoolsfails,_sbom_stagingcan be left behind, which is messy and can affect subsequent runs (especially in CI). Consider making cleanup unconditional (e.g., using a shell trap or a single shell block that guaranteesrm -rf ...executes on exit/failure).