Skip to content

Commit 9731cfe

Browse files
MarkAtwoodejohnstown
authored andcommitted
test: assert SBOM wolfSSL version comes from WOLFSSL_DIR
The dependency assertion checked only that wolfssl was present with a DEPENDS_ON edge, never that the recorded version matched WOLFSSL_DIR, so the SBOM could attest a version wolfSSH was not built against and still pass. Compare versionInfo against the tree. That assertion alone would not have caught it: the runner installs wolfssl from the same tree it passes as WOLFSSL_DIR, so pkg-config and wolfssl/version.h always agree and a wrong source is indistinguishable from a right one. Add a step that forces them apart -- a stub pkg-config reports a sentinel version, and a distclean'd copy of the tree has no generated version.h, so the configure.ac fallback is the only route to a correct answer. Reverting the recipe fix makes this step fail with the sentinel, and the fallback path now has CI coverage it lacked.
1 parent 48fc50c commit 9731cfe

1 file changed

Lines changed: 71 additions & 1 deletion

File tree

.github/workflows/sbom.yml

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ jobs:
146146
- name: wolfssl recorded as a dependency + wolfssh identity
147147
if: steps.gate.outputs.have == 'yes' && steps.gate.outputs.dep_wolfssl == 'yes'
148148
working-directory: wolfssh
149+
env:
150+
WOLFSSL_DIR: ${{ github.workspace }}/wolfssl
149151
run: |
150152
python3 - <<'PY'
151153
import glob, json
@@ -160,7 +162,75 @@ jobs:
160162
r['relatedSpdxElement']) for r in d['relationships']]
161163
assert ('SPDXRef-Package-wolfssh', 'DEPENDS_ON',
162164
'SPDXRef-Package-wolfssl') in rels, rels
163-
print('wolfssl dependency + wolfssh identity ok')
165+
# The recorded version must be the one from WOLFSSL_DIR. Presence
166+
# alone passed while the version was silently taken from the
167+
# installed wolfSSL instead of the source tree.
168+
import os, re
169+
wd = os.environ['WOLFSSL_DIR']
170+
want = None
171+
vh = os.path.join(wd, 'wolfssl', 'version.h')
172+
if os.path.exists(vh):
173+
m = re.search(r'LIBWOLFSSL_VERSION_STRING\s+"([^"]+)"',
174+
open(vh).read())
175+
want = m and m.group(1)
176+
if not want:
177+
m = re.search(r'^AC_INIT\(\[[^]]*\],\[([^]]*)\]',
178+
open(os.path.join(wd, 'configure.ac')).read(), re.M)
179+
want = m and m.group(1)
180+
assert want, 'could not determine expected wolfSSL version'
181+
got = pkgs['wolfssl'].get('versionInfo')
182+
assert got == want, f'SBOM says wolfssl {got!r}, WOLFSSL_DIR says {want!r}'
183+
print(f'wolfssl dependency + wolfssh identity ok (version {got})')
184+
PY
185+
186+
# The runner installs wolfssl from the very tree it passes as
187+
# WOLFSSL_DIR, so pkg-config and wolfssl/version.h always agree and a
188+
# version taken from the wrong source is indistinguishable from the
189+
# right one. Force them apart: a stub pkg-config reports a sentinel,
190+
# and a distclean'd copy of the tree has no generated version.h, so the
191+
# configure.ac fallback is the only path to a correct answer. This is
192+
# the shape that reached a user -- `make sbom` reported the installed
193+
# wolfSSL's version and exited 0.
194+
- name: Version comes from WOLFSSL_DIR, not the installed wolfSSL
195+
if: steps.gate.outputs.have == 'yes' && steps.gate.outputs.dep_wolfssl == 'yes'
196+
env:
197+
SENTINEL: 0.0.0-sentinel
198+
run: |
199+
set -euo pipefail
200+
cp -a wolfssl wolfssl-distclean
201+
( cd wolfssl-distclean && make distclean >/dev/null 2>&1 || true )
202+
if [ -f wolfssl-distclean/wolfssl/version.h ]; then
203+
echo "::error::distclean left wolfssl/version.h in place; this test needs it gone to exercise the configure.ac fallback."
204+
exit 1
205+
fi
206+
mkdir -p "$RUNNER_TEMP/stubbin"
207+
REAL_PKGCONFIG="$(command -v pkg-config)"
208+
cat > "$RUNNER_TEMP/stubbin/pkg-config" <<STUB
209+
#!/bin/bash
210+
if [ "\$1" = --modversion ] && [ "\$2" = wolfssl ]; then
211+
echo "$SENTINEL"; exit 0
212+
fi
213+
exec "$REAL_PKGCONFIG" "\$@"
214+
STUB
215+
chmod +x "$RUNNER_TEMP/stubbin/pkg-config"
216+
test "$(PATH="$RUNNER_TEMP/stubbin:$PATH" pkg-config --modversion wolfssl)" = "$SENTINEL"
217+
cd wolfssh
218+
PATH="$RUNNER_TEMP/stubbin:$PATH" \
219+
make sbom WOLFSSL_DIR="$GITHUB_WORKSPACE/wolfssl-distclean"
220+
python3 - <<'PY'
221+
import glob, json, os, re
222+
d = json.load(open(glob.glob('wolfssh-*.spdx.json')[0]))
223+
pkgs = {p['name']: p for p in d['packages']}
224+
got = pkgs['wolfssl'].get('versionInfo')
225+
sentinel = os.environ['SENTINEL']
226+
assert got != sentinel, (
227+
f'SBOM recorded {got!r}: the version came from pkg-config, i.e. '
228+
'the installed wolfSSL, not WOLFSSL_DIR')
229+
src = open(os.path.join(os.environ['GITHUB_WORKSPACE'],
230+
'wolfssl-distclean', 'configure.ac')).read()
231+
want = re.search(r'^AC_INIT\(\[[^]]*\],\[([^]]*)\]', src, re.M).group(1)
232+
assert got == want, f'SBOM says {got!r}, configure.ac says {want!r}'
233+
print(f'version resolved from WOLFSSL_DIR via configure.ac fallback: {got}')
164234
PY
165235
166236
# ---- Embedded / IDE path (no autotools) ----------------------------

0 commit comments

Comments
 (0)