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
128 changes: 126 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

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.

No job builds the CMake sbom or install-sbom targets, which is how the problems above got through. Could you add one, plus a drift check of tools/sbom/ against the pin (wolfssl-compliance-tooling-sync --check, or the toolkit's sbom-reusable.yml)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in 2d0fc17. The new cmake job configures with an absolute CMAKE_INSTALL_LIBDIR, builds, and runs install-sbom alone under DESTDIR. It checks the three installed files, that nothing goes to the absolute directory, that no _sbom_staging stays, the library hash against cmake --install, the CycloneDX schema, uninstall-sbom, and that -DCMAKE_DISABLE_FIND_PACKAGE_Python3=ON configures and fails only the sbom target. The new drift job clones the toolkit at the pinned revision and runs wolfssl-compliance-tooling-sync --check.


- 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 Expand Up @@ -747,6 +748,129 @@ jobs:
if-no-files-found: warn
retention-days: 90

# The vendored tools/sbom/ must be the pinned toolkit revision, executable
# bits included. Change it with the sync tool only.
drift:
name: tools/sbom matches the toolkit pin
if: github.repository_owner == 'wolfssl'
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: wolfssl-compliance-tooling-sync --check
run: |
rev=$(cat tools/sbom/.wolfssl-compliance-tooling-rev)
git clone --filter=blob:none \
https://github.com/wolfSSL/wolfssl-compliance-tooling /tmp/tooling
git -C /tmp/tooling checkout --detach "$rev"
python3 /tmp/tooling/tools/wolfssl-compliance-tooling-sync \
--src /tmp/tooling --dest "$PWD" --check

# Tier 2 (CMake) - the sbom, install-sbom and uninstall-sbom targets of the
# CMake build. The library is installed to an absolute CMAKE_INSTALL_LIBDIR
# and install-sbom runs under DESTDIR, so the SBOM staging must keep both
# inside the build tree.
cmake:
name: SBOM CMake (linux)
if: github.repository_owner == 'wolfssl'
runs-on: ubuntu-24.04
needs: unit
timeout-minutes: 20
env:
ABS_LIBDIR: /opt/wolfssl-sbom-abs/lib
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install SBOM validators
run: |
python3 -m pip install --user --upgrade pip
python3 -m pip install --user \
'spdx-tools==0.8.*' \
'cyclonedx-bom==7.*'
echo "$HOME/.local/bin" >> "$GITHUB_PATH"

- name: Configure and build
run: |
cmake -B build -DCMAKE_INSTALL_LIBDIR="$ABS_LIBDIR"
cmake --build build -j"$(nproc)"

- name: install-sbom alone generates, validates and installs
run: |
DESTDIR=/tmp/_cm cmake --build build --target install-sbom
docdir=/tmp/_cm/usr/local/share/doc/wolfssl
ls "$docdir"/wolfssl-*.cdx.json \
"$docdir"/wolfssl-*.spdx.json \
"$docdir"/wolfssl-*.spdx
test ! -e "$ABS_LIBDIR" || \
{ echo "staging installed into $ABS_LIBDIR"; exit 1; }
test ! -e build/_sbom_staging || \
{ echo "build/_sbom_staging was left behind"; exit 1; }

- name: Library hash matches the SBOM
run: |
rm -rf /tmp/_cmi
DESTDIR=/tmp/_cmi cmake --install build >/dev/null
LIB=$(find "/tmp/_cmi$ABS_LIBDIR" -maxdepth 1 -type f \
-name 'libwolfssl.so*' | head -n 1)
test -n "$LIB" || { echo "no installed library found"; exit 1; }
EXPECTED=$(sha256sum "$LIB" | cut -d' ' -f1)
ACTUAL=$(python3 -c "
import json, glob
with open(glob.glob('build/wolfssl-*.spdx.json')[0]) as f:
d = json.load(f)
p = [x for x in d['packages'] if x['name'] == 'wolfssl'][0]
print(p['checksums'][0]['checksumValue'])")
test "$EXPECTED" = "$ACTUAL" || \
{ echo "hash mismatch: expected=$EXPECTED actual=$ACTUAL"; exit 1; }

- name: CycloneDX 1.6 - JSON schema validation
run: |
python3 - <<'PY'
import glob, sys
from cyclonedx.validation.json import JsonStrictValidator
from cyclonedx.schema import SchemaVersion
v = JsonStrictValidator(SchemaVersion.V1_6)
for path in glob.glob('build/wolfssl-*.cdx.json'):
with open(path) as f:
errors = v.validate_str(f.read())
if errors:
print(f"INVALID: {path}: {errors}", file=sys.stderr)
sys.exit(1)
print(f"OK: {path}")
PY

- name: uninstall-sbom removes the installed files
run: |
DESTDIR=/tmp/_cm cmake --build build --target uninstall-sbom
if ls /tmp/_cm/usr/local/share/doc/wolfssl/wolfssl-* 2>/dev/null; then
echo "uninstall-sbom did not remove the SBOM files"
exit 1
fi

- name: Missing python3 fails the sbom target, not configure
run: |
cmake -B build-nopy -DCMAKE_DISABLE_FIND_PACKAGE_Python3=ON
if cmake --build build-nopy --target sbom > /tmp/nopy.log 2>&1; then
cat /tmp/nopy.log
echo "sbom target should fail without python3"
exit 1
fi
cat /tmp/nopy.log
grep -q 'python3 was not found' /tmp/nopy.log

- name: Upload SBOM artefacts (cmake)
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: sbom-cmake-linux-${{ github.sha }}
path: |
build/wolfssl-*.spdx.json
build/wolfssl-*.cdx.json
build/wolfssl-*.spdx
if-no-files-found: warn
retention-days: 90

# Tier 2 (macOS) - smoke test that gen-sbom finds .dylib artefacts and
# that the autotools target works on Mach-O. Linux already exercises
# the heavy validation matrix; this job is intentionally minimal so the
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
24 changes: 24 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5616,4 +5616,28 @@ 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/. It stages the install, validates the SPDX file
# and writes the tag-value file. A missing python3 or pyspdxtools does not
# fail configure. The sbom target fails when someone runs it.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
# A parent project owns the sbom target name.
include(${CMAKE_CURRENT_SOURCE_DIR}/tools/sbom/build/sbom.cmake)
if(WOLFSSL_LIBZ)
set(_sbom_libz yes)
else()
set(_sbom_libz no)
endif()
wolfssl_compliance_tooling_add_sbom(
NAME wolfssl
VERSION ${wolfssl_VERSION}
STAGE_TARGET wolfssl
VALIDATE
OPTIONS_H ${OPTION_FILE}
LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSING
ROOT ${CMAKE_CURRENT_SOURCE_DIR}
DEP_LIBZ ${_sbom_libz})
endif()
endif()
Loading
Loading