Skip to content

Commit 66d9738

Browse files
committed
Add new option to enable unit testing for replace default mode, directly initializing the openssl default provider
1 parent 823dab8 commit 66d9738

File tree

5 files changed

+328
-4
lines changed

5 files changed

+328
-4
lines changed

scripts/build-wolfprovider.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ show_help() {
2222
echo " --debian --enable-fips Build a Debian package with FIPS support"
2323
echo " --quicktest Disable some tests for a faster testing suite"
2424
echo " --replace-default Patch OpenSSL and build it so that wolfProvider is the default provider"
25+
echo " --enable-replace-default-testing"
26+
echo " Enable direct provider loading in unit tests. This option patches openssl to export additional symbols."
27+
echo " Note: This should only be used for test builds, and not in production."
2528
echo " --leave-silent Enable leave silent mode to suppress logging of return 0 in probing functions where expected failures may occur."
2629
echo " Note: This only affects logging; the calling function is still responsible for handling all return values appropriately."
2730
echo ""
@@ -37,6 +40,7 @@ show_help() {
3740
echo " WOLFPROV_LOG_FILE Path to log file for wolfProvider debug output (alternative to stderr)"
3841
echo " WOLFPROV_QUICKTEST If set to 1, disables some tests in the test suite to increase test speed"
3942
echo " WOLFPROV_DISABLE_ERR_TRACE If set to 1, wolfSSL will not be configured with --enable-debug-trace-errcodes=backtrace"
43+
echo " WOLFPROV_REPLACE_DEFAULT_TESTING If set to 1, enables direct provider loading in unit tests"
4044
echo " WOLFPROV_LEAVE_SILENT If set to 1, suppress logging of return 0 in functions where return 0 is expected behavior sometimes."
4145
echo ""
4246
}
@@ -118,6 +122,9 @@ for arg in "$@"; do
118122
--replace-default)
119123
WOLFPROV_REPLACE_DEFAULT=1
120124
;;
125+
--enable-replace-default-testing)
126+
WOLFPROV_REPLACE_DEFAULT_TESTING=1
127+
;;
121128
--leave-silent)
122129
WOLFPROV_LEAVE_SILENT=1
123130
;;

scripts/patch-libcrypto-exports.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash
2+
#
3+
# Copyright (C) 2006-2024 wolfSSL Inc.
4+
#
5+
# This file is part of wolfProvider.
6+
#
7+
# wolfProvider is free software; you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation; either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# wolfProvider is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with wolfProvider. If not, see <http://www.gnu.org/licenses/>.
19+
#
20+
21+
#
22+
# Patch libcrypto.num to export internal provider functions
23+
#
24+
# This script appends 6 internal provider symbols to OpenSSL's libcrypto.num
25+
# file, making them available for direct provider loading in wolfprovider unit tests.
26+
#
27+
28+
set -e
29+
30+
# OPENSSL_SOURCE_DIR should be set by the caller (utils-openssl.sh)
31+
if [ -z "$OPENSSL_SOURCE_DIR" ]; then
32+
echo "ERROR: OPENSSL_SOURCE_DIR not set"
33+
exit 1
34+
fi
35+
36+
LIBCRYPTO_NUM="${OPENSSL_SOURCE_DIR}/util/libcrypto.num"
37+
38+
# Check if file exists
39+
if [ ! -f "$LIBCRYPTO_NUM" ]; then
40+
echo "ERROR: libcrypto.num not found at: $LIBCRYPTO_NUM"
41+
exit 1
42+
fi
43+
44+
# Check if already patched
45+
if grep -q "^ossl_provider_new" "$LIBCRYPTO_NUM"; then
46+
echo "libcrypto.num already patched (provider symbols present)"
47+
exit 0
48+
fi
49+
50+
# Get the last symbol number
51+
LAST_NUM=$(awk '{print $2}' "$LIBCRYPTO_NUM" | grep -E '^[0-9]+$' | sort -n | tail -1)
52+
53+
if [ -z "$LAST_NUM" ]; then
54+
echo "ERROR: Could not determine last symbol number from libcrypto.num"
55+
exit 1
56+
fi
57+
58+
# Get the version tag from the last line (column 3)
59+
LAST_VERSION=$(tail -1 "$LIBCRYPTO_NUM" | awk '{print $3}')
60+
61+
if [ -z "$LAST_VERSION" ]; then
62+
echo "ERROR: Could not determine version tag from libcrypto.num"
63+
exit 1
64+
fi
65+
66+
# Calculate new symbol numbers
67+
NUM1=$((LAST_NUM + 1))
68+
NUM2=$((LAST_NUM + 2))
69+
NUM3=$((LAST_NUM + 3))
70+
NUM4=$((LAST_NUM + 4))
71+
NUM5=$((LAST_NUM + 5))
72+
NUM6=$((LAST_NUM + 6))
73+
74+
# Append the 6 provider symbols
75+
# Format matches existing entries: name (40 chars) TAB number TAB version TAB specification
76+
# Use printf to ensure proper tab characters
77+
{
78+
printf "ossl_provider_new %s\t%s\tEXIST::FUNCTION:\n" "${NUM1}" "${LAST_VERSION}"
79+
printf "ossl_provider_activate %s\t%s\tEXIST::FUNCTION:\n" "${NUM2}" "${LAST_VERSION}"
80+
printf "ossl_provider_deactivate %s\t%s\tEXIST::FUNCTION:\n" "${NUM3}" "${LAST_VERSION}"
81+
printf "ossl_provider_add_to_store %s\t%s\tEXIST::FUNCTION:\n" "${NUM4}" "${LAST_VERSION}"
82+
printf "ossl_provider_free %s\t%s\tEXIST::FUNCTION:\n" "${NUM5}" "${LAST_VERSION}"
83+
printf "ossl_default_provider_init %s\t%s\tEXIST::FUNCTION:\n" "${NUM6}" "${LAST_VERSION}"
84+
} >> "$LIBCRYPTO_NUM"
85+
86+
echo "Successfully patched libcrypto.num: Added symbols ${NUM1}-${NUM6} with version ${LAST_VERSION}"
87+
exit 0
88+

scripts/utils-openssl.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,23 @@ is_openssl_patched() {
117117
return 1
118118
}
119119

120+
is_libcrypto_num_patched() {
121+
# Return 0 if patched with provider symbols, 1 if not
122+
local dir="${OPENSSL_SOURCE_DIR:?OPENSSL_SOURCE_DIR not set}"
123+
local file="${dir%/}/util/libcrypto.num"
124+
125+
# File must exist to be patched
126+
[[ -f "$file" ]] || return 1
127+
128+
# Check for our provider symbol exports
129+
if grep -q '^ossl_provider_new' -- "$file"; then
130+
return 0
131+
fi
132+
133+
# Not patched
134+
return 1
135+
}
136+
120137
patch_openssl_version() {
121138
# Patch the OpenSSL version (wolfProvider/openssl-source/VERSION.dat)
122139
# with our BUILD_METADATA, depending on the FIPS flag. Either "wolfProvider" or "wolfProvider-fips".
@@ -171,6 +188,41 @@ patch_openssl() {
171188
printf "Done.\n"
172189
popd &> /dev/null
173190
fi
191+
192+
# Patch libcrypto.num for replace-default-testing mode
193+
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ]; then
194+
if [ -d "${OPENSSL_INSTALL_DIR}" ]; then
195+
# OpenSSL already installed, skip patching
196+
return 0
197+
fi
198+
199+
printf "\tPatching libcrypto.num for provider symbol exports ... "
200+
export OPENSSL_SOURCE_DIR
201+
${SCRIPT_DIR}/patch-libcrypto-exports.sh >>$LOG_FILE 2>&1
202+
if [ $? != 0 ]; then
203+
printf "ERROR.\n"
204+
printf "\n\nLibcrypto.num patch failed. Last 40 lines of log:\n"
205+
tail -n 40 $LOG_FILE
206+
do_cleanup
207+
exit 1
208+
fi
209+
printf "Done.\n"
210+
211+
printf "\n"
212+
printf " ╔════════════════════════════════════════════════════════════════════╗\n"
213+
printf " ║ *** WARNING *** ║\n"
214+
printf " ╠════════════════════════════════════════════════════════════════════╣\n"
215+
printf " ║ OpenSSL has been PATCHED to export internal provider symbols ║\n"
216+
printf " ║ for unit testing purposes. ║\n"
217+
printf " ║ ║\n"
218+
printf " ║ >> DO NOT USE THIS BUILD IN PRODUCTION ║\n"
219+
printf " ║ >> This build is for TESTING ONLY ║\n"
220+
printf " ║ ║\n"
221+
printf " ║ Internal symbols exported: ossl_provider_new, ossl_provider_* ║\n"
222+
printf " ║ ossl_default_provider_init ║\n"
223+
printf " ╚════════════════════════════════════════════════════════════════════╝\n"
224+
printf "\n"
225+
fi
174226
}
175227

176228
check_openssl_replace_default_mismatch() {
@@ -200,11 +252,40 @@ check_openssl_replace_default_mismatch() {
200252
fi
201253
}
202254

255+
check_replace_default_testing_mismatch() {
256+
local libcrypto_is_patched=0
257+
258+
# Check if libcrypto.num was patched for --enable-replace-default-testing
259+
if is_libcrypto_num_patched; then
260+
libcrypto_is_patched=1
261+
printf "INFO: OpenSSL libcrypto.num patched with internal provider symbol exports (testing build).\n"
262+
fi
263+
264+
# Check for mismatch
265+
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ] && [ "$libcrypto_is_patched" = "0" ]; then
266+
printf "ERROR: --enable-replace-default-testing build mode mismatch!\n"
267+
printf "Existing OpenSSL was built WITHOUT libcrypto.num patch\n"
268+
printf "Current request: --enable-replace-default-testing build\n\n"
269+
printf "Fix: ./scripts/build-wolfprovider.sh --distclean\n"
270+
printf "Then rebuild with desired configuration.\n"
271+
exit 1
272+
elif [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" != "1" ] && [ "$libcrypto_is_patched" = "1" ]; then
273+
printf "ERROR: Standard build mode mismatch!\n"
274+
printf "Existing OpenSSL was built WITH libcrypto.num patch (testing mode)\n"
275+
printf "Current request: standard build\n\n"
276+
printf "This OpenSSL build exports internal provider symbols and should NOT be used.\n"
277+
printf "Fix: ./scripts/build-wolfprovider.sh --distclean\n"
278+
printf "Then rebuild with desired configuration.\n"
279+
exit 1
280+
fi
281+
}
282+
203283
install_openssl() {
204284
printf "\nInstalling OpenSSL ${OPENSSL_TAG} ...\n"
205285
clone_openssl
206286
patch_openssl
207287
check_openssl_replace_default_mismatch
288+
check_replace_default_testing_mismatch
208289

209290
pushd ${OPENSSL_SOURCE_DIR} &> /dev/null
210291

scripts/utils-wolfprovider.sh

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ if [ "${WOLFPROV_QUICKTEST}" = "1" ]; then
4949
WOLFPROV_CONFIG_CFLAGS="${WOLFPROV_CONFIG_CFLAGS} -DWOLFPROV_QUICKTEST"
5050
fi
5151

52+
if [ "${WOLFPROV_REPLACE_DEFAULT_TESTING}" = "1" ]; then
53+
WOLFPROV_CONFIG_CFLAGS="${WOLFPROV_CONFIG_CFLAGS} -DWP_ENABLE_REPLACE_DEFAULT_UNIT_TEST"
54+
fi
55+
5256
if [ "$WOLFSSL_ISFIPS" -eq "1" ] || [ -n "$WOLFSSL_FIPS_BUNDLE" ]; then
5357
WOLFPROV_CONFIG=${WOLFPROV_CONFIG:-"$WOLFPROV_SOURCE_DIR/provider-fips.conf"}
5458
else
@@ -143,8 +147,8 @@ install_wolfprov() {
143147

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

173+
# Final warning for replace-default-testing builds
174+
if [ "$WOLFPROV_REPLACE_DEFAULT_TESTING" = "1" ]; then
175+
printf "\n"
176+
printf "╔══════════════════════════════════════════════════════════════════════════╗\n"
177+
printf "║ *** TESTING BUILD COMPLETE *** ║\n"
178+
printf "╠══════════════════════════════════════════════════════════════════════════╣\n"
179+
printf "║ This OpenSSL build has been patched with INTERNAL SYMBOL EXPORTS ║\n"
180+
printf "║ for unit testing with --enable-replace-default-testing ║\n"
181+
printf "║ ║\n"
182+
printf "║ >> DO NOT DEPLOY TO PRODUCTION ║\n"
183+
printf "║ >> FOR DEVELOPMENT AND TESTING USE ONLY ║\n"
184+
printf "║ ║\n"
185+
printf "║ To build a production version, rebuild WITHOUT this flag. ║\n"
186+
printf "╚══════════════════════════════════════════════════════════════════════════╝\n"
187+
printf "\n"
188+
fi
189+
169190
popd &> /dev/null
170191
}
171192

0 commit comments

Comments
 (0)