Files
wolfssl/scripts/crl-revoked.test
T
Tobias Frauenschläger 1f36572941 Reset the ready-file wait counter on each server start
The scripts that wait for a server to publish its ready file declare
counter at file scope and never reset it, so the retry budget is shared
by every server start in the script instead of applying to each one.
Once the early cases have used it up, every later create_port() falls
straight through to "NO ready file ending test", kills a server that was
starting normally, and the client then fails with "port number cannot be
0". Retry loops do not help, since the budget is already spent when they
run.

The failure needs only a build whose server start-up is slow enough to
consume a few tenths of a second each time. It showed up in the FIPS
dev-no-POST kernel-settings-all-pqc-asm job, where the server pays for
the CASTs, the PQC algorithms and the vector-register fallback fuzzer:
psk.test gave up after exactly 20 waits and tls13.test after exactly 51,
both the full script budget rather than a per-case one.

Reset counter where the wait begins, which is what the ocsp-stapling
scripts already do. Reproduced with a wrapper that delays the server by
one second: psk.test then fails on its third case before the change and
passes after it.
2026-08-06 10:52:58 +02:00

260 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# timeout(1) is GNU coreutils and absent on macOS; where it's missing, run the
# command unbounded (the flaky hang this guards against is Linux-only CI).
if ! command -v timeout >/dev/null 2>&1; then
timeout() { while [ "${1:-}" = "-s" ] || [ "${1:-}" = "-k" ]; do shift 2; done; shift; "$@"; }
fi
[ ! -x ./examples/client/client ] && printf '\n\n%s\n' "Client doesn't exist" \
&& exit 1
if ./examples/client/client -? 2>&1 | grep "Client not compiled in!" ; then
echo 'skipping crl-revoked.test because client not compiled in.' 1>&2
exit 77
fi
if ./examples/server/server -? 2>&1 | grep "Server not compiled in!" ; then
echo 'skipping crl-revoked.test because server not compiled in.' 1>&2
exit 77
fi
#crl.test
# if we can, isolate the network namespace to eliminate port collisions.
if [[ -n "$NETWORK_UNSHARE_HELPER" ]]; then
if [[ -z "$NETWORK_UNSHARE_HELPER_CALLED" ]]; then
export NETWORK_UNSHARE_HELPER_CALLED=yes
exec "$NETWORK_UNSHARE_HELPER" "$0" "$@" || exit $?
fi
elif [ "${AM_BWRAPPED-}" != "yes" ]; then
bwrap_path="$(command -v bwrap)"
if [ -n "$bwrap_path" ]; then
export AM_BWRAPPED=yes
exec "$bwrap_path" --unshare-net --dev-bind / / "$0" "$@"
fi
unset AM_BWRAPPED
fi
revocation_code="-361"
revocation_code_openssl="23"
exit_code=1
counter=0
# need a unique resume port since may run the same time as testsuite
# use server port zero hack to get one
crl_port=0
#no_pid tells us process was never started if -1
no_pid=-1
#server_pid captured on startup, stores the id of the server process
server_pid=$no_pid
# let's use absolute path to a local dir (make distcheck may be in sub dir)
# also let's add some randomness by adding pid in case multiple 'make check's
# per source tree
ready_file=`pwd`/wolfssl_crl_ready$$
remove_ready_file() {
rm -f "$ready_file"
}
# trap this function so if user aborts with ^C or other kill signal we still
# get an exit that will in turn clean up the file system
abort_trap() {
echo "script aborted"
if [ $server_pid != $no_pid ] && kill -0 $server_pid 2>&-
then
# sleep to give sanitizers time to dump backtraces.
sleep 1
echo "killing server"
kill -9 $server_pid
fi
exit_code=2 #different exit code in case of user interrupt
echo "got abort signal, exiting with $exit_code"
exit $exit_code
}
trap abort_trap INT TERM
# trap this function so that if we exit on an error the file system will still
# be restored and the other tests may still pass. Never call this function
# instead use "exit <some value>" and this function will run automatically
restore_file_system() {
remove_ready_file
if [ -n "$TMP_DIR" ]; then
rm -rf "$TMP_DIR"
fi
}
trap restore_file_system EXIT
# Workaround to not pollute the certs folder with our files that can impact other tests
TMP_DIR=$(mktemp -d) || exit $?
SRC_DIR="$PWD"
pushd "$TMP_DIR" || exit $?
if ! cp -R --symbolic-link "${SRC_DIR}/certs" . 2>/dev/null; then
cp -pR "${SRC_DIR}/certs" . || exit $?
fi
popd || exit $?
CERT_DIR="${TMP_DIR}/certs"
run_test() {
echo -e "\nStarting example server for crl test...\n"
remove_ready_file
# starts the server on crl_port, -R generates ready file to be used as a
# mutex lock, -c loads the revoked certificate. We capture the processid
# into the variable server_pid
timeout -s KILL 2m ./examples/server/server -R "$ready_file" -p $crl_port \
-c ${CERT_DIR}/server-revoked-cert.pem \
-k ${CERT_DIR}/server-revoked-key.pem &
server_pid=$!
counter=0
while [ ! -s "$ready_file" -a "$counter" -lt 20 ]; do
echo -e "waiting for ready file..."
sleep 0.1
counter=$((counter+ 1))
done
# sleep for an additional 0.1 to mitigate race on write/read of $ready_file:
sleep 0.1
if test -e "$ready_file"; then
echo -e "found ready file, starting client..."
else
echo -e "NO ready file ending test..."
exit 1
fi
# get created port 0 ephemeral port
crl_port="$(cat "$ready_file")"
# starts client on crl_port and captures the output from client
capture_out=$(cd "${CERT_DIR}/.." && "${SRC_DIR}/examples/client/client" -p $crl_port 2>&1)
client_result=$?
wait $server_pid
server_result=$?
case "$capture_out" in
*"$revocation_code"*|*"$revocation_code_openssl"*)
# only exit with zero on detection of the expected error code
echo ""
echo "Successful Revocation!!!!"
echo ""
if [ $exit_hash_dir_code -ne 0 ]; then
exit_code=1
else
exit_code=0
echo "exiting with $exit_code"
exit $exit_code
fi
;;
*)
echo ""
echo "Certificate was not revoked saw this instead: $capture_out"
echo ""
echo "configure with --enable-crl and run this script again"
echo ""
esac
}
run_hashdir_test() {
echo -e "\n\nHash dir with CRL and Certificate loading"
remove_ready_file
# create hashed cert and crl
pushd ${CERT_DIR}
# ca file
ca_hash_name=`openssl x509 -in ca-cert.pem -hash -noout`
if [ -f "$ca_hash_name".0 ]; then
rm "$ca_hash_name".0
fi
ln -s ca-cert.pem "$ca_hash_name".0
# crl file
crl_hash_name=`openssl crl -in ./crl/crl.pem -hash -noout`
if [ -f "$crl_hash_name".r0 ]; then
rm "$crl_hash_name".r0
fi
ln -s ./crl/crl.pem "$crl_hash_name".r0
popd
# starts the server on crl_port, -R generates ready file to be used as a
# mutex lock, -c loads the revoked certificate. We capture the processid
# into the variable server_pid
timeout -s KILL 2m ./examples/server/server -R "$ready_file" -p $crl_port \
-c ${CERT_DIR}/server-revoked-cert.pem \
-k ${CERT_DIR}/server-revoked-key.pem &
server_pid=$!
counter=0
while [ ! -s "$ready_file" -a "$counter" -lt 20 ]; do
echo -e "waiting for ready file..."
sleep 0.1
counter=$((counter+ 1))
done
# get created port 0 ephemeral port
crl_port="$(cat "$ready_file")"
# starts client on crl_port and captures the output from client
capture_out=$(cd "${CERT_DIR}/.." && "${SRC_DIR}/examples/client/client" -p $crl_port -9 2>&1)
client_result=$?
wait $server_pid
server_result=$?
case "$capture_out" in
*"$revocation_code"*|*"$revocation_code_openssl"*)
# only exit with zero on detection of the expected error code
echo ""
echo "Successful Revocation!!!! with hash dir"
echo ""
exit_hash_dir_code=0
;;
*)
echo ""
echo "Certificate was not revoked saw this instead: $capture_out"
echo ""
echo "configure with --enable-crl and run this script again"
echo ""
exit_hash_dir_code=1
esac
# clean up hashed cert and crl
pushd ${CERT_DIR}
rm "$ca_hash_name".0
rm "$crl_hash_name".r0
popd
}
######### begin program #########
# Check for enabling hash dir feature
./examples/client/client -? 2>&1 | grep -- 'hash dir'
if [ $? -eq 0 ]; then
hash_dir=yes
exit_hash_dir_code=1
fi
if [ "$hash_dir" = "yes" ]; then
run_hashdir_test
else
exit_hash_dir_code=0
fi
# Check that server is enabled
./examples/server/server -? 2>&1 | grep -- 'Create Ready file'
if [ $? -eq 0 ]; then
# run the test
run_test
else
exit_code=0
fi
# If we get to this exit, exit_code will be a 1 signaling failure
echo "exiting with $exit_code certificate was not revoked"
exit $exit_code
########## end program ##########