Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions scripts/build-wolfprovider.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ show_help() {
echo " --debian --enable-fips Build a Debian package with FIPS support"
echo " --quicktest Disable some tests for a faster testing suite"
echo " --replace-default Patch OpenSSL and build it so that wolfProvider is the default provider"
echo " --enable-replace-default-testing"
echo " Enable direct provider loading in unit tests. This option patches openssl to export additional symbols."
echo " Note: This should only be used for test builds, and not in production."
echo " --leave-silent Enable leave silent mode to suppress logging of return 0 in probing functions where expected failures may occur."
echo " Note: This only affects logging; the calling function is still responsible for handling all return values appropriately."
echo ""
Expand All @@ -37,6 +40,7 @@ show_help() {
echo " WOLFPROV_LOG_FILE Path to log file for wolfProvider debug output (alternative to stderr)"
echo " WOLFPROV_QUICKTEST If set to 1, disables some tests in the test suite to increase test speed"
echo " WOLFPROV_DISABLE_ERR_TRACE If set to 1, wolfSSL will not be configured with --enable-debug-trace-errcodes=backtrace"
echo " WOLFPROV_REPLACE_DEFAULT_TESTING If set to 1, enables direct provider loading in unit tests"
echo " WOLFPROV_LEAVE_SILENT If set to 1, suppress logging of return 0 in functions where return 0 is expected behavior sometimes."
echo ""
}
Expand Down Expand Up @@ -118,6 +122,9 @@ for arg in "$@"; do
--replace-default)
WOLFPROV_REPLACE_DEFAULT=1
;;
--enable-replace-default-testing)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should error out if --replace-default is not also set in the cmd line options. Alternatively, force it on whenever this new arg is set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now errors if replace default not also set

WOLFPROV_REPLACE_DEFAULT_TESTING=1
Copy link
Contributor

Choose a reason for hiding this comment

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

In the C code this is called WP_ENABLE_REPLACE_DEFAULT_UNIT_TEST. In the scripts, we have WOLFPROV_REPLACE_DEFAULT_TESTING. Can we make the names more closely aligned?

Fwiw: there are no other WP_ENABLE_* defines...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Name updated to be consistent

;;
--leave-silent)
WOLFPROV_LEAVE_SILENT=1
;;
Expand Down
88 changes: 88 additions & 0 deletions scripts/patch-libcrypto-exports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash
#
# Copyright (C) 2006-2024 wolfSSL Inc.
#
# This file is part of wolfProvider.
#
# wolfProvider is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# wolfProvider is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with wolfProvider. If not, see <http://www.gnu.org/licenses/>.
#

#
# Patch libcrypto.num to export internal provider functions
#
# This script appends 6 internal provider symbols to OpenSSL's libcrypto.num
# file, making them available for direct provider loading in wolfprovider unit tests.
#

set -e

# OPENSSL_SOURCE_DIR should be set by the caller (utils-openssl.sh)
if [ -z "$OPENSSL_SOURCE_DIR" ]; then
echo "ERROR: OPENSSL_SOURCE_DIR not set"
exit 1
fi

LIBCRYPTO_NUM="${OPENSSL_SOURCE_DIR}/util/libcrypto.num"

# Check if file exists
if [ ! -f "$LIBCRYPTO_NUM" ]; then
echo "ERROR: libcrypto.num not found at: $LIBCRYPTO_NUM"
exit 1
fi

# Check if already patched
if grep -q "^ossl_provider_new" "$LIBCRYPTO_NUM"; then
echo "libcrypto.num already patched (provider symbols present)"
exit 0
fi

# Get the last symbol number
LAST_NUM=$(awk '{print $2}' "$LIBCRYPTO_NUM" | grep -E '^[0-9]+$' | sort -n | tail -1)

if [ -z "$LAST_NUM" ]; then
echo "ERROR: Could not determine last symbol number from libcrypto.num"
exit 1
fi

# Get the version tag from the last line (column 3)
LAST_VERSION=$(tail -1 "$LIBCRYPTO_NUM" | awk '{print $3}')

if [ -z "$LAST_VERSION" ]; then
echo "ERROR: Could not determine version tag from libcrypto.num"
exit 1
fi

# Calculate new symbol numbers
NUM1=$((LAST_NUM + 1))
NUM2=$((LAST_NUM + 2))
NUM3=$((LAST_NUM + 3))
NUM4=$((LAST_NUM + 4))
NUM5=$((LAST_NUM + 5))
NUM6=$((LAST_NUM + 6))

# Append the 6 provider symbols
# Format matches existing entries: name (40 chars) TAB number TAB version TAB specification
# Use printf to ensure proper tab characters
{
printf "ossl_provider_new %s\t%s\tEXIST::FUNCTION:\n" "${NUM1}" "${LAST_VERSION}"
printf "ossl_provider_activate %s\t%s\tEXIST::FUNCTION:\n" "${NUM2}" "${LAST_VERSION}"
printf "ossl_provider_deactivate %s\t%s\tEXIST::FUNCTION:\n" "${NUM3}" "${LAST_VERSION}"
printf "ossl_provider_add_to_store %s\t%s\tEXIST::FUNCTION:\n" "${NUM4}" "${LAST_VERSION}"
printf "ossl_provider_free %s\t%s\tEXIST::FUNCTION:\n" "${NUM5}" "${LAST_VERSION}"
printf "ossl_default_provider_init %s\t%s\tEXIST::FUNCTION:\n" "${NUM6}" "${LAST_VERSION}"
} >> "$LIBCRYPTO_NUM"

echo "Successfully patched libcrypto.num: Added symbols ${NUM1}-${NUM6} with version ${LAST_VERSION}"
exit 0

81 changes: 81 additions & 0 deletions scripts/utils-openssl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ is_openssl_patched() {
return 1
}

is_libcrypto_num_patched() {
# Return 0 if patched with provider symbols, 1 if not
local dir="${OPENSSL_SOURCE_DIR:?OPENSSL_SOURCE_DIR not set}"
local file="${dir%/}/util/libcrypto.num"

# File must exist to be patched
[[ -f "$file" ]] || return 1

# Check for our provider symbol exports
if grep -q '^ossl_provider_new' -- "$file"; then
return 0
fi

# Not patched
return 1
}

patch_openssl_version() {
# Patch the OpenSSL version (wolfProvider/openssl-source/VERSION.dat)
# with our BUILD_METADATA, depending on the FIPS flag. Either "wolfProvider" or "wolfProvider-fips".
Expand Down Expand Up @@ -171,6 +188,41 @@ patch_openssl() {
printf "Done.\n"
popd &> /dev/null
fi

# Patch libcrypto.num for replace-default-testing mode
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we also require "$WOLFPROV_REPLACE_DEFAULT" = "1" here?

if [ -d "${OPENSSL_INSTALL_DIR}" ]; then
# OpenSSL already installed, skip patching
return 0
fi

printf "\tPatching libcrypto.num for provider symbol exports ... "
export OPENSSL_SOURCE_DIR
${SCRIPT_DIR}/patch-libcrypto-exports.sh >>$LOG_FILE 2>&1
if [ $? != 0 ]; then
printf "ERROR.\n"
printf "\n\nLibcrypto.num patch failed. Last 40 lines of log:\n"
tail -n 40 $LOG_FILE
do_cleanup
exit 1
fi
printf "Done.\n"

printf "\n"
printf " ╔════════════════════════════════════════════════════════════════════╗\n"
printf " ║ *** WARNING *** ║\n"
printf " ╠════════════════════════════════════════════════════════════════════╣\n"
printf " ║ OpenSSL has been PATCHED to export internal provider symbols ║\n"
printf " ║ for unit testing purposes. ║\n"
printf " ║ ║\n"
printf " ║ >> DO NOT USE THIS BUILD IN PRODUCTION ║\n"
printf " ║ >> This build is for TESTING ONLY ║\n"
printf " ║ ║\n"
printf " ║ Internal symbols exported: ossl_provider_new, ossl_provider_* ║\n"
printf " ║ ossl_default_provider_init ║\n"
printf " ╚════════════════════════════════════════════════════════════════════╝\n"
printf "\n"
fi
}

check_openssl_replace_default_mismatch() {
Expand Down Expand Up @@ -200,11 +252,40 @@ check_openssl_replace_default_mismatch() {
fi
}

check_replace_default_testing_mismatch() {
local libcrypto_is_patched=0

# Check if libcrypto.num was patched for --enable-replace-default-testing
if is_libcrypto_num_patched; then
libcrypto_is_patched=1
printf "INFO: OpenSSL libcrypto.num patched with internal provider symbol exports (testing build).\n"
fi

# Check for mismatch
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ] && [ "$libcrypto_is_patched" = "0" ]; then
printf "ERROR: --enable-replace-default-testing build mode mismatch!\n"
printf "Existing OpenSSL was built WITHOUT libcrypto.num patch\n"
printf "Current request: --enable-replace-default-testing build\n\n"
printf "Fix: ./scripts/build-wolfprovider.sh --distclean\n"
printf "Then rebuild with desired configuration.\n"
exit 1
elif [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" != "1" ] && [ "$libcrypto_is_patched" = "1" ]; then
printf "ERROR: Standard build mode mismatch!\n"
printf "Existing OpenSSL was built WITH libcrypto.num patch (testing mode)\n"
printf "Current request: standard build\n\n"
printf "This OpenSSL build exports internal provider symbols and should NOT be used.\n"
printf "Fix: ./scripts/build-wolfprovider.sh --distclean\n"
printf "Then rebuild with desired configuration.\n"
exit 1
fi
}

install_openssl() {
printf "\nInstalling OpenSSL ${OPENSSL_TAG} ...\n"
clone_openssl
patch_openssl
check_openssl_replace_default_mismatch
check_replace_default_testing_mismatch

pushd ${OPENSSL_SOURCE_DIR} &> /dev/null

Expand Down
25 changes: 23 additions & 2 deletions scripts/utils-wolfprovider.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ if [ "${WOLFPROV_QUICKTEST}" = "1" ]; then
WOLFPROV_CONFIG_CFLAGS="${WOLFPROV_CONFIG_CFLAGS} -DWOLFPROV_QUICKTEST"
fi

if [ "${WOLFPROV_REPLACE_DEFAULT_TESTING}" = "1" ]; then
WOLFPROV_CONFIG_CFLAGS="${WOLFPROV_CONFIG_CFLAGS} -DWP_ENABLE_REPLACE_DEFAULT_UNIT_TEST"
fi

if [ "$WOLFSSL_ISFIPS" -eq "1" ] || [ -n "$WOLFSSL_FIPS_BUNDLE" ]; then
WOLFPROV_CONFIG=${WOLFPROV_CONFIG:-"$WOLFPROV_SOURCE_DIR/provider-fips.conf"}
else
Expand Down Expand Up @@ -143,8 +147,8 @@ install_wolfprov() {

# Build the replacement default library after wolfprov to avoid linker errors
# but before testing so that the library is present if needed
if [ "$WOLFPROV_REPLACE_DEFAULT" = "1" ]; then
printf "\tWARNING: Skipping tests in replace mode...\n"
if [ "$WOLFPROV_REPLACE_DEFAULT" = "1" ] && [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" != "1" ]; then
printf "\tWARNING: Skipping tests in replace mode (use --enable-replace-default-testing to enable)...\n"
else
# Setup the environment to ensure we use the local builds of wolfprov, wolfssl, and openssl.
if ! source ${SCRIPT_DIR}/env-setup >/dev/null 2>&1; then
Expand All @@ -166,6 +170,23 @@ install_wolfprov() {
printf "Done.\n"
fi

# Final warning for replace-default-testing builds
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ]; then
printf "\n"
printf "╔══════════════════════════════════════════════════════════════════════════╗\n"
Copy link
Contributor

@padelsbach padelsbach Nov 13, 2025

Choose a reason for hiding this comment

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

Consider deleting/cleaning the outputs at this point to ensure this version doesn't remain beyond this point. I believe the sole purpose of this build is to run the unit tests.

printf "║ *** TESTING BUILD COMPLETE *** ║\n"
printf "╠══════════════════════════════════════════════════════════════════════════╣\n"
printf "║ This OpenSSL build has been patched with INTERNAL SYMBOL EXPORTS ║\n"
printf "║ for unit testing with --enable-replace-default-testing ║\n"
printf "║ ║\n"
printf "║ >> DO NOT DEPLOY TO PRODUCTION ║\n"
printf "║ >> FOR DEVELOPMENT AND TESTING USE ONLY ║\n"
printf "║ ║\n"
printf "║ To build a production version, rebuild WITHOUT this flag. ║\n"
printf "╚══════════════════════════════════════════════════════════════════════════╝\n"
printf "\n"
fi

popd &> /dev/null
}

Expand Down
Loading
Loading