From 7b4997d59c8e1aa620c615131511319b648f3692 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 30 Dec 2025 16:13:31 -0800 Subject: [PATCH] Fix wolfProvider Command-Line Tests for Provider Switching --- .github/workflows/cmdline.yml | 1 + .github/workflows/debian-package.yml | 2 +- .github/workflows/fips-ready.yml | 1 + scripts/cmd_test/cmd-test-common.sh | 159 ++++++++++++++++++++------- scripts/cmd_test/do-cmd-tests.sh | 9 +- scripts/env-setup | 93 +++++++++++++--- scripts/utils-general.sh | 34 +++++- 7 files changed, 232 insertions(+), 67 deletions(-) diff --git a/.github/workflows/cmdline.yml b/.github/workflows/cmdline.yml index 586d62fa..7183fcaf 100644 --- a/.github/workflows/cmdline.yml +++ b/.github/workflows/cmdline.yml @@ -35,4 +35,5 @@ jobs: - name: Run tests run: | + source scripts/env-setup ${{ matrix.force_fail }} ${{ matrix.debug }} ./scripts/cmd_test/do-cmd-tests.sh diff --git a/.github/workflows/debian-package.yml b/.github/workflows/debian-package.yml index 4ce8508f..27504d4e 100644 --- a/.github/workflows/debian-package.yml +++ b/.github/workflows/debian-package.yml @@ -86,7 +86,7 @@ jobs: run: | # Run the do-cmd-test.sh script to execute interoperability tests echo "Running OpenSSL provider interoperability tests..." - OPENSSL_BIN=$(eval which openssl) ${{ matrix.force_fail }} ${{ matrix.fips_ref == 'FIPS' && 'WOLFSSL_ISFIPS=1' || '' }} ./scripts/cmd_test/do-cmd-tests.sh + OPENSSL_BIN=$(eval which openssl) ${{ matrix.replace_default && 'WOLFPROV_REPLACE_DEFAULT=1' || '' }} ${{ matrix.force_fail }} ${{ matrix.fips_ref == 'FIPS' && 'WOLFSSL_ISFIPS=1' || '' }} ./scripts/cmd_test/do-cmd-tests.sh echo "PASS: All provider interoperability tests successful" - name: Uninstall package and verify cleanup diff --git a/.github/workflows/fips-ready.yml b/.github/workflows/fips-ready.yml index 9790a54b..d5d0d1e1 100644 --- a/.github/workflows/fips-ready.yml +++ b/.github/workflows/fips-ready.yml @@ -57,5 +57,6 @@ jobs: # Run cmd tests to verify functionality export WOLFSSL_ISFIPS=1 export ${{matrix.force_fail}} + source scripts/env-setup ${{ matrix.force_fail }} ./scripts/cmd_test/do-cmd-tests.sh diff --git a/scripts/cmd_test/cmd-test-common.sh b/scripts/cmd_test/cmd-test-common.sh index 910eb01c..59ac9c19 100644 --- a/scripts/cmd_test/cmd-test-common.sh +++ b/scripts/cmd_test/cmd-test-common.sh @@ -31,7 +31,15 @@ source "${CMD_TEST_DIR}/../utils-general.sh" # Function to setup the environment for the command-line tests cmd_test_env_setup() { - export OPENSSL_BIN=${OPENSSL_BIN:-$(which openssl)} + # Use OPENSSL_BIN if explicitly set, otherwise auto-detect + if [ -z "${OPENSSL_BIN:-}" ]; then + OPENSSL_BIN=$(which openssl 2>/dev/null || echo "") + if [ -z "$OPENSSL_BIN" ]; then + echo "ERROR: Cannot find openssl binary. Please set OPENSSL_BIN environment variable." + exit 1 + fi + fi + export OPENSSL_BIN printf "Using OPENSSL_BIN: %s\n" "$OPENSSL_BIN" OPENSSL_CONF_ORIG="${OPENSSL_CONF:-}" @@ -59,32 +67,37 @@ cmd_test_init() { # Function to use default provider only use_default_provider() { - return 0 - - if [ -z "${OPENSSL_CONF_ORIG:-}" ]; then - export OPENSSL_CONF="/dev/null" - export OPENSSL_MODULES="/dev/null" - else - unset OPENSSL_CONF - unset OPENSSL_MODULES - fi + # Detect mode BEFORE modifying environment variables detect_wolfprovider_mode - + # Check if wolfProvider is in replace-default mode - if [ "$is_openssl_replace_default" = "1" ]; then - echo "INFO: wolfProvider is installed in replace-default mode" - echo "INFO: wolfProvider IS the default provider and cannot be switched off" - - # Verify that wolfProvider (as default) is active - if [ "$is_wp_active" = "1" ] && [ "$is_wp_default" = "1" ]; then + if [ "$is_openssl_replace_default" = "1" ] || [ "${WOLFPROV_REPLACE_DEFAULT:-0}" = "1" ]; then + # In replace-default mode, wolfProvider IS the default provider + # No provider switching possible - just verify it's active + echo "replace-default is set, using default provider" + + # In replace-default mode, don't modify environment variables + # Just verify that wolfProvider is active as the default + if [ "$is_wp_active" = "1" ] && [ "$is_wp_default" = "1" ]; then echo "Using default provider (wolfProvider in replace-default mode)" + return 0 else echo "FAIL: Expected wolfProvider as default, but is_wp_active: $is_wp_active and is_wp_default: $is_wp_default" exit 1 fi else # In non-replace-default mode, unsetting OPENSSL_MODULES should disable wolfProvider - echo "INFO: wolfProvider is installed in non-replace-default mode" + # Disable wolfProvider by setting OPENSSL_CONF and OPENSSL_MODULES to /dev/null + if [ -z "${OPENSSL_CONF_ORIG:-}" ]; then + export OPENSSL_CONF="/dev/null" + export OPENSSL_MODULES="/dev/null" + else + unset OPENSSL_CONF + unset OPENSSL_MODULES + fi + + # Re-detect after disabling + detect_wolfprovider_mode # Verify that we are using the OpenSSL default provider (not wolfProvider) if [ "$is_openssl_default_provider" != "1" ]; then @@ -92,34 +105,28 @@ use_default_provider() { echo "is_openssl_default_provider: $is_openssl_default_provider" exit 1 fi - echo "INFO: Switched to default provider (OpenSSL)" + echo "INFO: Switched to OpenSSL default provider" + return 0 fi } # Function to use wolf provider only use_wolf_provider() { - return 0 - - if [ -z "${OPENSSL_CONF_ORIG:-}" ]; then - unset OPENSSL_CONF - unset OPENSSL_MODULES - else - export OPENSSL_CONF="${OPENSSL_CONF_ORIG:-}" - export OPENSSL_MODULES="${OPENSSL_MODULES_ORIG:-}" - fi + # Detect mode BEFORE modifying environment variables detect_wolfprovider_mode - + # Check if wolfProvider is in replace-default mode - if [ "$is_openssl_replace_default" = "1" ]; then - # In replace-default mode, wolfProvider is already the default - # No need to set OPENSSL_MODULES or OPENSSL_CONF - echo "INFO: wolfProvider is installed in replace-default mode" - echo "INFO: wolfProvider is already active as the default provider" - - # Verify that wolfProvider is active - if [ "$is_wp_active" = "1" ] && [ "$is_wp_default" = "1" ]; then + if [ "$is_openssl_replace_default" = "1" ] || [ "${WOLFPROV_REPLACE_DEFAULT:-0}" = "1" ]; then + # In replace-default mode, wolfProvider IS the default provider + # No provider switching possible - just verify it's active + echo "replace-default is set, using default provider" + + # In replace-default mode, don't modify environment variables + # Just verify that wolfProvider is active as the default + if [ "$is_wp_active" = "1" ] && [ "$is_wp_default" = "1" ]; then echo "Using wolfProvider (replace-default mode)" + return 0 else echo "FAIL: wolfProvider is not active" echo "is_wp_active: $is_wp_active" @@ -127,19 +134,87 @@ use_wolf_provider() { exit 1 fi else - # In non-replace-default mode, we need to set OPENSSL_MODULES and OPENSSL_CONF - echo "INFO: wolfProvider is installed in non-replace-default mode" + # In non-replace-default mode, we need to set OPENSSL_MODULES and OPENSSL_CONF to enable wolfProvider + echo "INFO: Switched to libwolfprov" + + # Get paths to enable wolfProvider + # Use WOLFPROV_PATH/WOLFPROV_CONFIG if set (from env-setup), otherwise derive from OPENSSL_BIN path + local wolfprov_lib_path="${WOLFPROV_PATH:-}" + local provider_conf="${WOLFPROV_CONFIG:-}" + + # If not set, try to find library path + if [ -z "$wolfprov_lib_path" ]; then + # Try MODULESDIR from openssl version -a (simplest approach) + local openssl_modules_dir="" + openssl_modules_dir=$($OPENSSL_BIN version -a 2>/dev/null | grep -i "^MODULESDIR" | sed -E 's/.*["'\'']([^"'\'']+)["'\''].*/\1/' | head -1) + if [ -n "$openssl_modules_dir" ] && [ -d "$openssl_modules_dir" ]; then + # Check if provider library exists + if [ -f "$openssl_modules_dir/libwolfprov.so" ] || \ + [ -f "$openssl_modules_dir/libwolfprov.so.0" ] || \ + [ -f "$openssl_modules_dir/libwolfprov.so.0.0.0" ]; then + wolfprov_lib_path="$openssl_modules_dir" + fi + fi + + # If still not found, try local build location + if [ -z "$wolfprov_lib_path" ]; then + local openssl_install_dir=$(dirname "$(dirname "$OPENSSL_BIN")" 2>/dev/null || echo "") + local repo_root=$(dirname "$openssl_install_dir" 2>/dev/null || echo "") + if [ -n "$repo_root" ] && [ -d "$repo_root/wolfprov-install/lib" ]; then + wolfprov_lib_path="$repo_root/wolfprov-install/lib" + fi + fi + fi + + # If not set, try to find config file (optional - system installs may not need it) + if [ -z "$provider_conf" ]; then + # Try system location first + if [ -f "/etc/ssl/openssl.cnf.d/wolfprovider.conf" ]; then + provider_conf="/etc/ssl/openssl.cnf.d/wolfprovider.conf" + else + # Try local build location + local openssl_install_dir=$(dirname "$(dirname "$OPENSSL_BIN")" 2>/dev/null || echo "") + local repo_root=$(dirname "$openssl_install_dir" 2>/dev/null || echo "") + if [ -n "$repo_root" ]; then + if [ "${WOLFSSL_ISFIPS:-0}" = "1" ] && [ -f "$repo_root/provider-fips.conf" ]; then + provider_conf="$repo_root/provider-fips.conf" + elif [ -f "$repo_root/provider.conf" ]; then + provider_conf="$repo_root/provider.conf" + fi + fi + fi + fi + + # Set environment variables to enable wolfProvider + # In system installations, the provider may be auto-loaded via openssl.cnf, + # so library path is optional - only set it if we found it + if [ -n "$wolfprov_lib_path" ] && [ -d "$wolfprov_lib_path" ]; then + export OPENSSL_MODULES="$wolfprov_lib_path" + else + # Library path not found - this is OK for system installs with openssl.cnf configuration + # Just warn about it, don't fail + echo "WARNING: Cannot find wolfProvider library path - will rely on system openssl.cnf configuration" + echo " WOLFPROV_PATH: ${WOLFPROV_PATH:-not set}" + echo " OPENSSL_BIN: ${OPENSSL_BIN:-not set}" + $OPENSSL_BIN version -a 2>&1 | grep -i "^MODULESDIR" || echo " MODULESDIR not found in openssl version output" + fi + + # Config file is optional - system installs may use openssl.cnf instead + if [ -n "$provider_conf" ] && [ -f "$provider_conf" ]; then + export OPENSSL_CONF="$provider_conf" + fi + + # Re-detect after setting environment + detect_wolfprovider_mode # Verify that we are using wolfProvider if [ "$is_wp_active" != "1" ]; then echo "FAIL: unable to switch to wolfProvider, default provider is still active" - $OPENSSL_BIN list -providers echo "is_wp_active: $is_wp_active" echo "is_wp_default: $is_wp_default" exit 1 fi - echo "INFO: Switched to wolfProvider" - $OPENSSL_BIN list -providers + return 0 fi } diff --git a/scripts/cmd_test/do-cmd-tests.sh b/scripts/cmd_test/do-cmd-tests.sh index 88a0a5f6..3ab64dda 100755 --- a/scripts/cmd_test/do-cmd-tests.sh +++ b/scripts/cmd_test/do-cmd-tests.sh @@ -51,10 +51,11 @@ TESTS (if none specified, all tests run): ecc Run ECC key generation test req Run certificate request test -ENVIRONMENT VARIABLES (env vars get detected from verify-install.sh): - OPENSSL_BIN Path to OpenSSL binary (auto-detected with which(openssl) if not set) - WOLFSSL_ISFIPS Set to 1 for FIPS mode (or use --fips flag) - WOLFPROV_FORCE_FAIL Set to 1 for force-fail mode (or use --force-fail flag) +ENVIRONMENT VARIABLES: + OPENSSL_BIN Path to OpenSSL binary (auto-detected with which(openssl) if not set) + WOLFSSL_ISFIPS Set to 1 for FIPS mode (auto-detected from OpenSSL if not set) + WOLFPROV_REPLACE_DEFAULT Set to 1 to force replace-default mode (auto-detected from OpenSSL version if not set) + WOLFPROV_FORCE_FAIL Set to 1 for force-fail mode EOF exit 0 diff --git a/scripts/env-setup b/scripts/env-setup index 168949b1..032d2220 100755 --- a/scripts/env-setup +++ b/scripts/env-setup @@ -3,6 +3,8 @@ # 'source' this file, don't run it directly # To disable wolfProvider, run 'unset OPENSSL_CONF' # To enable FIPS mode, set WOLFSSL_ISFIPS=1 before sourcing this file +# To use replace-default mode, set WOLFPROV_REPLACE_DEFAULT=1 before sourcing this file +# (or the script will auto-detect replace-default mode from OpenSSL version) if [[ -n "${ZSH_VERSION:-}" ]]; then [[ $ZSH_EVAL_CONTEXT =~ :file$ ]] && is_sourced=1 || is_sourced=0 @@ -57,22 +59,58 @@ WOLFPROV_LIB_PATH="$REPO_ROOT/wolfprov-install/lib" # ${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} expands to :$LD_LIBRARY_PATH only if LD_LIBRARY_PATH was already set export LD_LIBRARY_PATH="$WOLFPROV_LIB_PATH:$WOLFSSL_LIB_PATH:$OPENSSL_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" -# Auto-detect FIPS mode and use appropriate config -if [ "${WOLFSSL_ISFIPS:-0}" = "1" ]; then - DEFAULT_PROVIDER_CONF="$REPO_ROOT/provider-fips.conf" - echo "FIPS mode detected, using provider-fips.conf" -else - DEFAULT_PROVIDER_CONF="$REPO_ROOT/provider.conf" +# Set OPENSSL_BIN - use existing if set, otherwise use local build +if [ -z "${OPENSSL_BIN:-}" ]; then + export OPENSSL_BIN="${REPO_ROOT}/openssl-install/bin/openssl" fi -export OPENSSL_CONF="${OPENSSL_CONF:=$DEFAULT_PROVIDER_CONF}" - -export OPENSSL_MODULES="${OPENSSL_MODULES:=$WOLFPROV_LIB_PATH}" -export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:=$OPENSSL_LIB_PATH/pkgconfig}" # Other variables used by test scripts export WOLFPROV_PATH="${WOLFPROV_LIB_PATH}" -export WOLFPROV_CONFIG="${DEFAULT_PROVIDER_CONF}" -export OPENSSL_BIN="${REPO_ROOT}/openssl-install/bin/openssl" + +# Detect if we're in replace-default mode +# Check environment variable first, then check OpenSSL version string and providers +WOLFPROV_IN_REPLACE_DEFAULT_MODE=0 +if [ "${WOLFPROV_REPLACE_DEFAULT:-0}" = "1" ]; then + WOLFPROV_IN_REPLACE_DEFAULT_MODE=1 +else + # Try to detect from OpenSSL version and provider list if OPENSSL_BIN exists + if [ -f "$OPENSSL_BIN" ]; then + openssl_version=$($OPENSSL_BIN version 2>/dev/null) + openssl_providers=$($OPENSSL_BIN list -providers 2>/dev/null) + # Check for "replace-default" in version string + if echo "$openssl_version" | grep -qi "replace-default"; then + WOLFPROV_IN_REPLACE_DEFAULT_MODE=1 + # Or check if provider list shows "default" with "wolfSSL Provider" name but NOT "OpenSSL Default Provider" + elif echo "$openssl_providers" | grep -q "^ default$" && \ + echo "$openssl_providers" | grep -q "wolfSSL Provider" && \ + ! echo "$openssl_providers" | grep -q "OpenSSL Default Provider"; then + WOLFPROV_IN_REPLACE_DEFAULT_MODE=1 + fi + fi +fi + +if [ "$WOLFPROV_IN_REPLACE_DEFAULT_MODE" = "1" ]; then + echo "using default provider" + # In replace-default mode, don't set OPENSSL_CONF or OPENSSL_MODULES + # Let OpenSSL use the default provider behavior (wolfProvider IS the default) + unset OPENSSL_CONF + unset OPENSSL_MODULES + export WOLFPROV_CONFIG="" +else + echo "loading wolfProvider as a module provider" + # Auto-detect FIPS mode and use appropriate config + if [ "${WOLFSSL_ISFIPS:-0}" = "1" ]; then + DEFAULT_PROVIDER_CONF="$REPO_ROOT/provider-fips.conf" + echo "FIPS mode detected, using provider-fips.conf" + else + DEFAULT_PROVIDER_CONF="$REPO_ROOT/provider.conf" + fi + export OPENSSL_CONF="${OPENSSL_CONF:=$DEFAULT_PROVIDER_CONF}" + export OPENSSL_MODULES="${OPENSSL_MODULES:=$WOLFPROV_LIB_PATH}" + export WOLFPROV_CONFIG="${DEFAULT_PROVIDER_CONF}" +fi + +export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:=$OPENSSL_LIB_PATH/pkgconfig}" # If openssl-install does not exist, exit with failure status to terminate # any workflows which depend on the result. @@ -87,12 +125,31 @@ fi echo "Checking OpenSSL providers:" PROVIDER_LIST=$(mktemp -t provider-list.XXXXXX) -$OPENSSL_BIN list -providers | tee $PROVIDER_LIST -if grep -q libwolfprov $PROVIDER_LIST; then - echo "libwolfprov found in OpenSSL providers" +$OPENSSL_BIN list -providers 2>&1 | tee $PROVIDER_LIST + +# Check if wolfProvider is available +# In replace-default mode: provider appears as "default" with name "wolfSSL Provider" +# In normal mode: provider appears as "libwolfprov" with name "wolfSSL Provider" +if [ "$WOLFPROV_IN_REPLACE_DEFAULT_MODE" = "1" ]; then + # In replace-default mode, check for "default" provider with "wolfSSL Provider" name + # Or just check that "default" provider exists (since it IS wolfProvider) + if grep -qi "wolfSSL Provider" $PROVIDER_LIST || grep -q "^ default$" $PROVIDER_LIST; then + echo "wolfProvider found as default provider" + else + echo "ERROR: wolfProvider (default provider) not found in OpenSSL providers" + rm -f $PROVIDER_LIST + return 1 + fi else - echo "ERROR: libwolfprov not found in OpenSSL providers" - return 1 -fi + # In normal mode, check for "libwolfprov" or "wolfSSL Provider" + if grep -qi "wolfSSL Provider" $PROVIDER_LIST || grep -q libwolfprov $PROVIDER_LIST; then + echo "wolfProvider found in OpenSSL providers" + else + echo "ERROR: wolfProvider not found in OpenSSL providers" + rm -f $PROVIDER_LIST + return 1 + fi +fi +rm -f $PROVIDER_LIST echo "Done!" diff --git a/scripts/utils-general.sh b/scripts/utils-general.sh index 92fdea5e..bec1c3a0 100644 --- a/scripts/utils-general.sh +++ b/scripts/utils-general.sh @@ -75,10 +75,40 @@ if [ "$UTILS_GENERAL_LOADED" != "yes" ]; then # only set once local openssl_version=$(${OPENSSL_BIN} version 2>/dev/null) local openssl_providers=$(${OPENSSL_BIN} list -providers 2>/dev/null) - is_openssl_replace_default=$(echo "$openssl_version" | grep -qi "wolfProvider-replace-default" && echo 1 || echo 0) + # Check for "replace-default" in version string OR environment variable + is_openssl_replace_default=$(echo "$openssl_version" | grep -qi "replace-default" && echo 1 || echo 0) + if [ "$is_openssl_replace_default" = "0" ] && [ "${WOLFPROV_REPLACE_DEFAULT:-0}" = "1" ]; then + is_openssl_replace_default=1 + fi + + # In replace-default mode, "default" provider has "wolfSSL Provider" name + if [ "$is_openssl_replace_default" = "0" ]; then + # Check if provider list shows "default" with "wolfSSL Provider" name but NOT "OpenSSL Default Provider" + # This indicates replace-default mode + if echo "$openssl_providers" | grep -q "^ default$" && \ + echo "$openssl_providers" | grep -q "wolfSSL Provider" && \ + ! echo "$openssl_providers" | grep -q "OpenSSL Default Provider"; then + is_openssl_replace_default=1 + fi + fi + + # In replace-default mode, there's no "OpenSSL Default Provider" - wolfProvider IS the default is_openssl_default_provider=$(echo "$openssl_providers" | grep -qi "OpenSSL Default Provider" && echo 1 || echo 0) is_wp_active=$(echo "$openssl_providers" | grep -qi "wolfSSL Provider" && echo 1 || echo 0) - is_wp_default=$(echo "$openssl_providers" | grep -q -Pzo 'Providers:\s*\n\s*default\s*\n\s*name:\s*wolfSSL Provider' && echo 1 || echo 0) + + # Check if wolfProvider is the default provider + if [ "$is_openssl_replace_default" = "1" ]; then + # In replace-default mode, wolfProvider IS the default provider + is_wp_default=1 + # Also mark as active if we're in replace-default mode + if [ "$is_wp_active" = "0" ]; then + # In replace-default mode, the "default" provider IS wolfProvider + is_wp_active=1 + fi + else + # In normal mode, check if default provider is wolfProvider + is_wp_default=$(echo "$openssl_providers" | grep -q -Pzo 'Providers:\s*\n\s*default\s*\n\s*name:\s*wolfSSL Provider' && echo 1 || echo 0) + fi is_wp_fips=$(echo "$openssl_providers" | grep -qi "wolfSSL Provider FIPS" && echo 1 || echo 0) } fi \ No newline at end of file