1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00
Files
wolfssl/scripts/openssl_srtp.test
Juliusz Sosinowicz 1fa1228ba1 Address review: make the hang guards actually fire
Three ways the bounds added here failed to do their job:

- get_first_free_port ended the scan cap with 'exit 1', but every caller
  runs it in a command substitution, so only the subshell died. The port
  variable came back empty, the next $((port + 1)) evaluated to 1, and the
  run limped on to a confusing wait_for_readyFile failure. Forcing the cap
  on ocsp-stapling.test: before, the script ran on and hung until an outer
  timeout killed it; now it exits 1 at the error. Return instead, and check
  the status at all 25 call sites across the six scripts.

- The macOS timeout shim was a shell function. Backgrounding a function
  forks a subshell, so $! was the subshell and cleanup killed that while
  the server it was meant to stop leaked. Use a prefix variable that
  expands to nothing when timeout(1) is absent, keeping $! the real pid.

- timeout -s KILL exits 137, not 124. Sites that read $? and treat any
  non-zero as 'feature not compiled in' turned a hang into exit 0, so the
  bound made a hang less visible than before. Add timed_out() and check it
  before those skip branches; use it for the version probes too, which
  matched any status >= 124.
2026-08-13 15:52:17 +00:00

213 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Test WolfSSL/OpenSSL srtp interoperability
#
# TODO: add OpenSSL client with WolfSSL server
# 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).
# A prefix variable rather than a shell function: backgrounding a function
# makes $! the forked subshell, so a later "kill $server_pid" would stop the
# wrapper and orphan the server it was meant to kill.
if command -v timeout >/dev/null 2>&1; then
TIMEOUT_KILL_2M="timeout -s KILL 2m"
else
TIMEOUT_KILL_2M=""
fi
set -e
# 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
if ! test -n "$WOLFSSL_OPENSSL_TEST"; then
echo "WOLFSSL_OPENSSL_TEST NOT set, won't run"
exit 0
fi
OPENSSL=${OPENSSL:="openssl"}
WOLFSSL_CLIENT=${WOLFSSL_CLIENT:="./examples/client/client"}
# need a unique port since may run the same time as testsuite
# Track ports already assigned in this script run to prevent intra-run collisions
used_ports=()
generate_port() {
#-------------------------------------------------------------------------#
# Generate a random port number, guaranteed unique within this script run.
# Checks both the intra-run used_ports list and system-level bound ports.
#-------------------------------------------------------------------------#
local attempts=0 collision p
while true; do
if [[ "$OSTYPE" == "linux"* ]]; then
p=$(($(od -An -N2 /dev/urandom) % (65535-49512) + 49512))
elif [[ "$OSTYPE" == "darwin"* ]]; then
p=$(($(od -An -N2 /dev/random) % (65535-49512) + 49512))
else
echo "Unknown OS TYPE"
exit 1
fi
# Check against ports already assigned in this run
collision=0
for up in "${used_ports[@]}"; do
if [ "$up" = "$p" ]; then
collision=1
break
fi
done
# Also check if the port is already bound on this system
if [ "$collision" -eq 0 ]; then
if command -v ss &>/dev/null; then
ss -lnt 2>/dev/null | grep -q ":${p}[[:space:]]" && collision=1
elif command -v netstat &>/dev/null; then
netstat -lnt 2>/dev/null | grep -q ":${p}[[:space:]]" && collision=1
fi
fi
[ "$collision" -eq 0 ] && break
attempts=$((attempts + 1))
if [ "$attempts" -ge 100 ]; then
echo "ERROR: generate_port could not find a free port after 100 attempts"
exit 1
fi
done
port=$p
used_ports+=("$p")
}
# get size of key material based on the profile
# $1 srtp profile
get_key_material_size() {
case "$1" in
"SRTP_AES128_CM_SHA1_80")
ekm_size=60 ;;
"SRTP_AES128_CM_SHA1_32")
ekm_size=60 ;;
"SRTP_NULL_SHA1_80")
ekm_size=28 ;;
"SRTP_NULL_SHA1_32")
ekm_size=27 ;;
"SRTP_AEAD_AES_128_GCM")
ekm_size=56;;
"SRTP_AEAD_AES_256_GCM")
ekm_size=88;;
*)
echo "SRTP profile $1 unsupported"
exit 1
esac
}
# Start an OpenSSL server dtls with srtp
# $1: dtsl version [1.0, 1.2]
# $2: srtp profile string
start_openssl_server() {
generate_port
server_port=$port
srtp_profile=$2
if [ "$1" = "1.0" ]; then
dtls_version=dtls1
elif [ "$1" = "1.2" ]; then
dtls_version=dtls1_2
fi
get_key_material_size "$srtp_profile"
server_output_file=/tmp/openssl_srtp_out
# hackish but OpenSSL doesn't work if input is fed before handshaking and
# the wolfSSL client needs a reply to stop
(sleep 1;echo -n "I hear you fa shizzle...") | \
${OPENSSL} s_server \
-${dtls_version} \
-port "${server_port}" \
-debug \
-use_srtp "${srtp_profile}" \
-keymatexport EXTRACTOR-dtls_srtp \
-keymatexportlen "$ekm_size" \
-cert ./certs/server-cert.pem \
-key ./certs/server-key.pem >"$server_output_file" &
# make sure the server is up
sleep 0.1
}
# Start an wolfssl client dtls with srtp
# $1: dtsl version [1.0, 1.2]
# $2: srtp profile string
start_wolfssl_client() {
srtp_profile=$2
if [ "$1" = "1.0" ]; then
dtls_version=2
elif [ "$1" = "1.2" ]; then
dtls_version=3
fi
client_output_file=/tmp/wolfssl_srtp_out
$TIMEOUT_KILL_2M ${WOLFSSL_CLIENT} -u\
-x \
-v${dtls_version} \
--srtp "${srtp_profile}" \
-p${server_port} >"$client_output_file"
}
# $1 openssl file
# $2 wolfssl file
check_ekm() {
openssl_ekm=$(grep "Keying material: " < "$1" | cut -d ':' -f 2)
echo "OPENSSL EKM: $openssl_ekm"
wolfssl_ekm=$(grep "DTLS SRTP: Exported key material: " < "$2" | cut -d ':' -f 3)
echo "WOLFSSL EKM: $wolfssl_ekm"
if [ "$openssl_ekm" = "$wolfssl_ekm" ];then
check_ret=0
else
check_ret=1
fi
}
# $1 dtsl version
# $2 srtp profile
check_dtls_srtp() {
start_openssl_server "$1" "$2"
start_wolfssl_client "$1" "$2"
check_ekm "$server_output_file" "$client_output_file"
echo -n "check dtls $1 $2... "
if [ "$check_ret" -ne 0 ];then
echo "failed"
exit 1
else
echo "ok"
fi
}
# SRTP_NULL_SHA1_80" and SRTP_NULL_SHA1_32 aren't supported by OpenSSL
PROFILES="SRTP_AES128_CM_SHA1_80 \
SRTP_AES128_CM_SHA1_32 \
SRTP_AEAD_AES_128_GCM \
SRTP_AEAD_AES_256_GCM"
for DTLS in 1.0 1.2;do
for SRTP_PROF in $PROFILES;do
check_dtls_srtp "$DTLS" "$SRTP_PROF"
done
done