From 8c834a2b5236821f312d84ddf213295262a17cff Mon Sep 17 00:00:00 2001 From: Tobias Frauenschlaeger Date: Sat, 17 Oct 2026 16:15:42 +0000 Subject: [PATCH 1/5] Hide internal symbols in the CMake build The autotools build compiles with -fvisibility=hidden and gets HAVE_VISIBILITY from gl_VISIBILITY, so WP11_LOCAL functions stay out of the dynamic symbol table. The CMake build set neither, so libwolfpkcs11.so exported about 200 internal functions next to the PKCS#11 API. Build the library with hidden visibility on GCC and Clang and define HAVE_VISIBILITY. The PKCS#11 v3.0 and v3.2 functions were declared without WP11_API, so hidden visibility would drop them, and the autotools build did not export them either. Declare them with WP11_API so both builds export the whole C_* API and nothing else. Also register debug_test with skip code 77. It exits 77 when DEBUG_WOLFPKCS11 is not defined, and CTest counted that as a failure, so ctest failed on every non-debug CMake build. --- CMakeLists.txt | 5 ++++ wolfpkcs11/pkcs11.h | 64 ++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3989eaad..c518a53a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -631,6 +631,10 @@ set_target_properties(wolfpkcs11 ) target_compile_definitions(wolfpkcs11 PRIVATE "BUILDING_WOLFPKCS11") +if(NOT WIN32 AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + set_target_properties(wolfpkcs11 PROPERTIES C_VISIBILITY_PRESET hidden) + target_compile_definitions(wolfpkcs11 PRIVATE "HAVE_VISIBILITY=1") +endif() target_compile_definitions(wolfpkcs11 PRIVATE ${WOLFPKCS11_DEFINITIONS}) # Determine library filename for WOLFPKCS11_DLL_FILENAME @@ -775,6 +779,7 @@ if(WOLFPKCS11_TESTS) add_wpkcs11_test(${test_target} ${CMAKE_CURRENT_SOURCE_DIR}/tests/${test_target}.c) endforeach() + set_tests_properties(debug_test PROPERTIES SKIP_RETURN_CODE 77) # HBS (LMS/HSS, XMSS/XMSS^MT) public-key persistence test. Only built when # the feature is enabled; the test exits 77 (skip) when no token store is diff --git a/wolfpkcs11/pkcs11.h b/wolfpkcs11/pkcs11.h index 03bd305e..94f3c389 100644 --- a/wolfpkcs11/pkcs11.h +++ b/wolfpkcs11/pkcs11.h @@ -1149,92 +1149,92 @@ WP11_API CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags); -CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, +WP11_API CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen); -CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags); -CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, +WP11_API CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags); +WP11_API CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen); -CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen); -CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags); -CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, CK_ULONG_PTR pulPlaintextLen); -CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, CK_ULONG ulAssociatedDataLen); -CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags); -CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); -CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen); -CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); -CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession); -CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); -CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen); -CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, +WP11_API CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession); /* PKCS#11 V 3.2 functions */ -CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey); -CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPrivateKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, CK_ULONG ulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey); -CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, +WP11_API CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); -CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, +WP11_API CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen); -CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, +WP11_API CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen); -CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession); -CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, +WP11_API CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession); +WP11_API CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, CK_FLAGS * pFlags); -CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ASYNC_DATA_PTR pResult); -CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ULONG_PTR pulID); -CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, +WP11_API CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData); From 9228837ee60a6afd20def1ac0bf97e2ae7f6e971 Mon Sep 17 00:00:00 2001 From: Tobias Frauenschlaeger Date: Sat, 17 Oct 2026 16:15:52 +0000 Subject: [PATCH 2/5] Let the wolfSSL interop test load any wolfPKCS11 module The test never called wolfCrypt_Init() itself. It only worked because the module, linked against the same libwolfcrypt, called wolfCrypt_Init() in C_Initialize and so set up the crypto callback table on the test's behalf. Against a module with its own wolfSSL, wc_CryptoCb_RegisterDevice() fails with BUFFER_E. Initialize and clean up wolfCrypt in main(). The test binary no longer links the module, which it only loads through wc_Pkcs11_Initialize(), and WOLFPKCS11_MODULE selects the module to test, defaulting to the one the Makefile builds. The debug probe now keeps its handle open until cleanup. Closing it right away unloaded the module whenever nothing else held it, which reset the debug flag before wc_Pkcs11_Initialize() loaded the module again, so the debug build of the module never logged. The test and debug targets refuse a module that depends on libwolfssl. Its wolfSSL calls would bind to the test's own wolfCrypt build, which has a different configuration, and crash. --- tests/wolfssl-interoperability/Makefile | 26 +++++++++++---- .../wolfssl-interoperability/pkcs11_interop.c | 32 ++++++++++++------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/tests/wolfssl-interoperability/Makefile b/tests/wolfssl-interoperability/Makefile index 06bc49fb..85316aaf 100644 --- a/tests/wolfssl-interoperability/Makefile +++ b/tests/wolfssl-interoperability/Makefile @@ -9,6 +9,8 @@ WOLFSSL_DIR ?= ../../wolfssl WOLFPKCS11_DIR ?= ../.. BUILD_DIR := build +INTEROP_MODULE := $(BUILD_DIR)/libwolfpkcs11-interop.so +WOLFPKCS11_MODULE ?= $(INTEROP_MODULE) COMMON_CPPFLAGS := -DWOLFSSL_USER_SETTINGS -DWOLFPKCS11_USER_SETTINGS -I. -I.. \ -I$(WOLFSSL_DIR) -I$(WOLFSSL_DIR)/wolfssl -I$(WOLFSSL_DIR)/wolfssl/wolfcrypt \ @@ -64,7 +66,7 @@ TEST_OBJS := $(patsubst %.c,$(BUILD_DIR)/interop-test/%.o,$(TEST_SRCS)) all: test -interop: $(BUILD_DIR)/pkcs11_interop +interop: $(BUILD_DIR)/pkcs11_interop check-module $(BUILD_DIR)/wolfssl/%.o: $(WOLFSSL_DIR)/%.c @mkdir -p $(dir $@) @@ -86,14 +88,24 @@ $(BUILD_DIR)/libwolfpkcs11-interop.so: $(ENGINE_OBJS) $(BUILD_DIR)/libwolfcrypt- @mkdir -p $(dir $@) $(CC) -shared -o $@ $(ENGINE_OBJS) -L$(BUILD_DIR) -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) -$(BUILD_DIR)/pkcs11_interop: $(TEST_OBJS) $(BUILD_DIR)/libwolfpkcs11-interop.so $(BUILD_DIR)/libwolfcrypt-interop.so - $(CC) -o $@ $(TEST_OBJS) -L$(BUILD_DIR) -lwolfpkcs11-interop -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) +$(BUILD_DIR)/pkcs11_interop: $(TEST_OBJS) $(BUILD_DIR)/libwolfcrypt-interop.so + $(CC) -o $@ $(TEST_OBJS) -L$(BUILD_DIR) -lwolfcrypt-interop $(LDFLAGS) $(LDLIBS) + +.PHONY: check-module +check-module: $(WOLFPKCS11_MODULE) +ifneq ($(WOLFPKCS11_MODULE),$(INTEROP_MODULE)) + @dyn=$$(readelf -d $(WOLFPKCS11_MODULE)) || exit 1; \ + if echo "$$dyn" | grep -q 'NEEDED.*libwolfssl'; then \ + echo "$(WOLFPKCS11_MODULE) depends on libwolfssl; use the interop module or a --with-static-wolfssl build"; \ + exit 1; \ + fi +endif .PHONY: test -test: $(BUILD_DIR)/pkcs11_interop - WOLFPKCS11_MODULE=$(BUILD_DIR)/libwolfpkcs11-interop.so LD_LIBRARY_PATH=$(BUILD_DIR) $(BUILD_DIR)/pkcs11_interop -debug: $(BUILD_DIR)/pkcs11_interop - WOLFPKCS11_MODULE=$(BUILD_DIR)/libwolfpkcs11-interop.so LD_LIBRARY_PATH=$(BUILD_DIR) gdb $(BUILD_DIR)/pkcs11_interop +test: $(BUILD_DIR)/pkcs11_interop check-module + WOLFPKCS11_MODULE=$(WOLFPKCS11_MODULE) LD_LIBRARY_PATH=$(BUILD_DIR) $(BUILD_DIR)/pkcs11_interop +debug: $(BUILD_DIR)/pkcs11_interop check-module + WOLFPKCS11_MODULE=$(WOLFPKCS11_MODULE) LD_LIBRARY_PATH=$(BUILD_DIR) gdb $(BUILD_DIR)/pkcs11_interop .PHONY: clean clean: diff --git a/tests/wolfssl-interoperability/pkcs11_interop.c b/tests/wolfssl-interoperability/pkcs11_interop.c index 8cff984f..8bf71e39 100644 --- a/tests/wolfssl-interoperability/pkcs11_interop.c +++ b/tests/wolfssl-interoperability/pkcs11_interop.c @@ -1141,6 +1141,8 @@ int main(int argc, char** argv) int dev_id = 23; int ret; int failures = 0; + void* probe; + void (*debug_on)(void); if (module_path == NULL) { module_path = (argc > 1) ? argv[1] : "./build/libwolfpkcs11-interop.so"; @@ -1155,22 +1157,28 @@ int main(int argc, char** argv) memset(&dev, 0, sizeof(dev)); memset(&token, 0, sizeof(token)); - { - void* probe = dlopen(module_path, RTLD_NOW | RTLD_LOCAL); - if (probe == NULL) { - fprintf(stderr, "dlopen failed for %s: %s\n", module_path, dlerror()); - return EXIT_FAILURE; - } - void (*debug_on)(void) = (void (*)(void))dlsym(probe, - "wolfPKCS11_Debugging_On"); - if (debug_on != NULL) - debug_on(); + probe = dlopen(module_path, RTLD_NOW | RTLD_LOCAL); + if (probe == NULL) { + fprintf(stderr, "dlopen failed for %s: %s\n", module_path, dlerror()); + return EXIT_FAILURE; + } + debug_on = (void (*)(void))dlsym(probe, "wolfPKCS11_Debugging_On"); + if (debug_on != NULL) + debug_on(); + + ret = wolfCrypt_Init(); + if (ret != 0) { + fprintf(stderr, "wolfCrypt_Init failed: %d\n", ret); dlclose(probe); + return EXIT_FAILURE; } ret = init_token(module_path, &dev, &token, &slot_id); - if (ret != 0) + if (ret != 0) { + wolfCrypt_Cleanup(); + dlclose(probe); return EXIT_FAILURE; + } ret = wc_CryptoCb_RegisterDevice(dev_id, wc_Pkcs11_CryptoDevCb, &token); if (ret != 0) { @@ -1366,6 +1374,8 @@ int main(int argc, char** argv) wc_Pkcs11Token_Close(&token); wc_Pkcs11Token_Final(&token); wc_Pkcs11_Finalize(&dev); + wolfCrypt_Cleanup(); + dlclose(probe); if (failures == 0) { printf("All wolfPKCS11 interoperability tests passed.\n"); From dbe48eda055287a86ab7ee035f6cf773e2b44bab Mon Sep 17 00:00:00 2001 From: Tobias Frauenschlaeger Date: Sat, 17 Oct 2026 16:16:00 +0000 Subject: [PATCH 3/5] Add an option to link a static wolfSSL into libwolfpkcs11 --with-static-wolfssl=FILE (autotools) and WOLFPKCS11_STATIC_WOLFSSL (CMake) link a static, position independent libwolfssl into the shared library, so it has no run time dependency on libwolfssl. Both need an ELF linker, accept only a static wolfSSL and build only the shared library. The wolfSSL symbols are hidden with --exclude-libs,ALL. Without that the embedded wolfSSL exports its whole API, and in a process that already has a libwolfssl.so, such as a wolfSSL application loading the module through wc_Pkcs11_Initialize(), the module's calls bind to the application's copy even though it is loaded with RTLD_LOCAL. With a different wolfSSL configuration that crashes. -Bsymbolic also binds the module's own C_* functions to itself, and -z text turns text relocations from an archive built without PIC into a link error. -z defs does the same for a wolfSSL function missing from the archive, which the loader would otherwise resolve against the application's libwolfssl. It also rules out sanitizer builds whose runtime is not linked into shared objects, such as clang's AddressSanitizer. The archive comes first in LIBS, so libraries it needs can follow it, and the library is relinked when the archive changes. The installed CMake package and the wolfpkcs11-config script no longer refer to wolfssl in this mode. wolfTPM support is rejected in this mode, because libwolftpm links its own wolfSSL and the TPM crypto callback would be registered there rather than in the copy the module uses. Eleven tests set allocators with wolfSSL_SetAllocators() to inject allocation failures, track allocations or inspect freed memory. In this mode that call configures the test's own wolfSSL rather than the module's, so these tests are not run. The default build still runs them. A new workflow builds both variants against a static wolfSSL, checks that the library has no libwolfssl dependency or text relocations and exports only C_* functions, including the v3.0 ones, then runs the tests and the wolfSSL interop test against it. --- .github/workflows/static-wolfssl.yml | 119 +++++++++++++++++++++++++++ CMakeLists.txt | 33 +++++++- README.md | 34 ++++++++ cmake/wolfpkcs11Config.cmake.in | 4 +- cmake/wolfpkcs11Targets.cmake.in | 8 +- configure.ac | 37 ++++++++- src/include.am | 5 +- tests/include.am | 25 +++--- 8 files changed, 246 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/static-wolfssl.yml diff --git a/.github/workflows/static-wolfssl.yml b/.github/workflows/static-wolfssl.yml new file mode 100644 index 00000000..46b564b3 --- /dev/null +++ b/.github/workflows/static-wolfssl.yml @@ -0,0 +1,119 @@ +name: wolfPKCS11 static wolfSSL tests + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +permissions: + contents: read + +jobs: + autotools: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: +#pull wolfPKCS11 + - uses: actions/checkout@v4 + with: + submodules: true + persist-credentials: false + +#setup wolfssl + - uses: actions/checkout@v4 + with: + repository: wolfssl/wolfssl + path: wolfssl + persist-credentials: false + - name: Build static wolfSSL + working-directory: ./wolfssl + run: | + ./autogen.sh + ./configure --prefix=$GITHUB_WORKSPACE/wolfssl-install \ + --enable-static --disable-shared --with-pic --enable-cryptonly \ + --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --enable-md5 \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" + make + make install + +#setup wolfPKCS11 + - name: Build wolfPKCS11 + run: | + ./autogen.sh + ./configure CPPFLAGS=-I$GITHUB_WORKSPACE/wolfssl-install/include \ + --with-static-wolfssl=$GITHUB_WORKSPACE/wolfssl-install/lib/libwolfssl.a + make + - name: Check the library is self-contained + run: | + lib=$(readlink -f src/.libs/libwolfpkcs11.so) + dyn=$(readelf -d "$lib") + syms=$(nm -D --defined-only "$lib") + if grep -E 'NEEDED.*libwolfssl|TEXTREL' <<<"$dyn"; then exit 1; fi + if grep -v ' C_' <<<"$syms"; then exit 1; fi + for f in C_GetFunctionList C_GetInterface C_LoginUser; do + grep -qw "$f" <<<"$syms" + done + - name: wolfpkcs11 make check + run: make check + - name: Run the wolfSSL interoperability test against the library + run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/src/.libs/libwolfpkcs11.so + +# capture logs on failure + - name: Upload failure logs + if: failure() || cancelled() + uses: actions/upload-artifact@v4 + with: + name: wolfpkcs11-static-wolfssl-logs + path: | + test-suite.log + tests/*.log + retention-days: 5 + + cmake: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: +#pull wolfPKCS11 + - uses: actions/checkout@v4 + with: + submodules: true + persist-credentials: false + +#setup wolfssl + - uses: actions/checkout@v4 + with: + repository: wolfssl/wolfssl + path: wolfssl + persist-credentials: false + - name: Build static wolfSSL + working-directory: ./wolfssl + run: | + cmake -B build -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/wolfssl-install \ + -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release \ + -DWOLFSSL_CRYPT_ONLY=yes -DWOLFSSL_AESCFB=yes -DWOLFSSL_AESECB=yes -DWOLFSSL_AESCTR=yes \ + -DWOLFSSL_AESKEYWRAP=yes -DWOLFSSL_RSA_PSS=yes -DWOLFSSL_KEYGEN=yes -DWOLFSSL_PWDBASED=yes \ + -DWOLFSSL_MD5=yes -DWOLFSSL_SHA224=yes -DWOLFSSL_HKDF=yes -DWOLFSSL_PUBLIC_MP=yes \ + -DWOLFSSL_WC_RSA_DIRECT=yes -DWOLFSSL_EXAMPLES=no -DWOLFSSL_CRYPT_TESTS=no + cmake --build build + cmake --install build + +#setup wolfPKCS11 + - name: Build and test wolfPKCS11 + run: | + cmake -B build -DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/wolfssl-install \ + -DWOLFPKCS11_STATIC_WOLFSSL=yes -DWOLFPKCS11_PBKDF2=yes + cmake --build build + ctest --test-dir build --output-on-failure + - name: Check the library is self-contained + run: | + lib=$(readlink -f build/libwolfpkcs11.so) + dyn=$(readelf -d "$lib") + syms=$(nm -D --defined-only "$lib") + if grep -E 'NEEDED.*libwolfssl|TEXTREL' <<<"$dyn"; then exit 1; fi + if grep -v ' C_' <<<"$syms"; then exit 1; fi + for f in C_GetFunctionList C_GetInterface C_LoginUser; do + grep -qw "$f" <<<"$syms" + done + - name: Run the wolfSSL interoperability test against the library + run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/build/libwolfpkcs11.so diff --git a/CMakeLists.txt b/CMakeLists.txt index c518a53a..897bf2a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -599,6 +599,11 @@ set(LIB_SOURCES src/slot.c src/crypto.c ) + +add_option("WOLFPKCS11_STATIC_WOLFSSL" + "Link a static wolfSSL into the shared library and hide its symbols (default: disabled)" + "no" "yes;no") + if(BUILD_SHARED_LIBS) message(STATUS "BUILD_SHARED_LIBS enabled: ${LIB_SOURCES}") add_library(wolfpkcs11 SHARED ${LIB_SOURCES}) @@ -732,7 +737,33 @@ else() # Try to find wolfSSL as an installed package find_package(wolfssl REQUIRED) endif() -list(APPEND WOLFPKCS11_LINK_LIBS wolfssl::wolfssl) + +if(WOLFPKCS11_STATIC_WOLFSSL) + get_target_property(WOLFSSL_LIB_TYPE wolfssl::wolfssl TYPE) + if(WOLFSSL_LIB_TYPE STREQUAL "UNKNOWN_LIBRARY") + get_target_property(WOLFSSL_LIB_PATH wolfssl::wolfssl IMPORTED_LOCATION) + if(WOLFSSL_LIB_PATH MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") + set(WOLFSSL_LIB_TYPE "STATIC_LIBRARY") + endif() + endif() + + if(NOT BUILD_SHARED_LIBS) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs BUILD_SHARED_LIBS") + elseif(APPLE OR WIN32) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs an ELF linker") + elseif(WOLFPKCS11_TPM) + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL cannot be combined with WOLFPKCS11_TPM") + elseif(NOT WOLFSSL_LIB_TYPE STREQUAL "STATIC_LIBRARY") + message(FATAL_ERROR "WOLFPKCS11_STATIC_WOLFSSL needs a static wolfSSL library") + endif() + + target_link_libraries(wolfpkcs11 PRIVATE wolfssl::wolfssl) + target_link_options(wolfpkcs11 PRIVATE + "LINKER:--exclude-libs,ALL" "LINKER:-Bsymbolic" "LINKER:-z,text" + "LINKER:-z,defs") +else() + list(APPEND WOLFPKCS11_LINK_LIBS wolfssl::wolfssl) +endif() # Other libraries target_link_libraries(wolfpkcs11 PUBLIC ${WOLFPKCS11_LINK_LIBS}) diff --git a/README.md b/README.md index dc44f1a6..f9a1e02d 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,39 @@ As ML-KEM is a feature of PKCS#11 version 3.2, support for that is required, too. Hence, to enable all in wolfPKCS11, add `--enable-pkcs11v32 --enable-mlkem` during the configure step. +### Optional: Self-contained library with static wolfSSL + +By default libwolfpkcs11 loads libwolfssl at run time. To ship a single +library instead, build wolfSSL as a static library with position independent +code and link it into libwolfpkcs11: + +```sh +cd wolfssl +./configure --enable-static --disable-shared --with-pic --enable-cryptonly \ + --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased \ + --enable-scrypt \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" +make +sudo make install + +cd ../wolfPKCS11 +./configure --with-static-wolfssl=/usr/local/lib/libwolfssl.a +make +``` + +The wolfSSL symbols stay hidden inside libwolfpkcs11, so an application using +its own wolfSSL, even with a different configuration, can load the module with +`dlopen()` or `wc_Pkcs11_Initialize()`. Settings the application makes on its +own wolfSSL, such as `wolfSSL_SetAllocators()`, do not reach the module. A +wolfSSL update requires rebuilding libwolfpkcs11. This option needs an ELF +linker (GNU ld, gold or lld) and cannot be combined with wolfTPM support. If +the static wolfSSL needs other libraries, such as zlib, pass them in `LIBS`: +the ones `pkg-config --static --libs wolfssl` lists after `-lwolfssl`. + +With CMake, build wolfSSL with `-DBUILD_SHARED_LIBS=OFF` and +`-DCMAKE_POSITION_INDEPENDENT_CODE=ON`, then configure wolfPKCS11 with +`-DWOLFPKCS11_STATIC_WOLFSSL=yes`. + ### Build options and defines #### Define WOLFPKCS11_TPM_STORE @@ -295,6 +328,7 @@ cmake -DCMAKE_PREFIX_PATH=/path/to/wolfssl/install .. | `WOLFPKCS11_DEFAULT_TOKEN_PATH` | `""` | Default token storage path compiled into library | | `WOLFPKCS11_BUILD_OUT_OF_TREE` | `yes` | Generate build artifacts outside source tree | | `BUILD_SHARED_LIBS` | `ON` | Build shared (`ON`) or static (`OFF`) library | +| `WOLFPKCS11_STATIC_WOLFSSL` | `no` | Link a static wolfSSL into the shared library and hide its symbols | Note: wolfSSL must be built with the corresponding features enabled for the options above to work (e.g. enabling `WOLFPKCS11_AESCCM` requires wolfSSL built diff --git a/cmake/wolfpkcs11Config.cmake.in b/cmake/wolfpkcs11Config.cmake.in index ca33f0c0..57da0aae 100644 --- a/cmake/wolfpkcs11Config.cmake.in +++ b/cmake/wolfpkcs11Config.cmake.in @@ -5,7 +5,9 @@ if("@HAVE_PTHREAD@" STREQUAL "1") endif() include(CMakeFindDependencyMacro) -find_dependency(wolfssl) +if(NOT "@WOLFPKCS11_STATIC_WOLFSSL@" STREQUAL "yes") + find_dependency(wolfssl) +endif() if (_wolfpkcs11_needs_threads) find_dependency(Threads) endif() diff --git a/cmake/wolfpkcs11Targets.cmake.in b/cmake/wolfpkcs11Targets.cmake.in index dcd83dcb..21b8b556 100644 --- a/cmake/wolfpkcs11Targets.cmake.in +++ b/cmake/wolfpkcs11Targets.cmake.in @@ -19,9 +19,11 @@ if (NOT TARGET wolfpkcs11::wolfpkcs11) INTERFACE_INCLUDE_DIRECTORIES "${_wolfpkcs11_includedir}" ) - set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY - INTERFACE_LINK_LIBRARIES wolfssl::wolfssl - ) + if (NOT "@WOLFPKCS11_STATIC_WOLFSSL@" STREQUAL "yes") + set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY + INTERFACE_LINK_LIBRARIES wolfssl::wolfssl + ) + endif() if (@HAVE_PTHREAD@) set_property(TARGET wolfpkcs11::wolfpkcs11 APPEND PROPERTY diff --git a/configure.ac b/configure.ac index 24ea49bc..4c4d6b52 100644 --- a/configure.ac +++ b/configure.ac @@ -629,13 +629,46 @@ fi AM_CONDITIONAL([BUILD_STATIC],[test "x$enable_shared" = "xno"]) +# STATIC WOLFSSL +AC_ARG_WITH([static-wolfssl], + [AS_HELP_STRING([--with-static-wolfssl=FILE],[Link the wolfSSL static library FILE into the shared library and hide its symbols (default: disabled)])], + [ STATIC_WOLFSSL=$withval ], + [ STATIC_WOLFSSL=no ]) + +WOLFPKCS11_STATIC_WOLFSSL=no +STATIC_WOLFSSL_DEP= +AS_IF([test "x$STATIC_WOLFSSL" != "xno"],[ + AS_CASE([$STATIC_WOLFSSL], + [*.a],[AS_IF([test ! -f "$STATIC_WOLFSSL"], + [AC_MSG_ERROR([--with-static-wolfssl: $STATIC_WOLFSSL not found])])], + [AC_MSG_ERROR([--with-static-wolfssl needs the path to libwolfssl.a])]) + AS_IF([test "x$enable_shared" = "xno"], + [AC_MSG_ERROR([--with-static-wolfssl needs a shared library build])]) + AS_IF([test "x$enable_static" = "xyes"], + [AC_MSG_ERROR([--with-static-wolfssl cannot be combined with --enable-static])]) + AS_IF([test "x$ENABLED_TPM" = "xyes"], + [AC_MSG_ERROR([--with-static-wolfssl cannot be combined with --enable-wolftpm])]) + AX_CHECK_LINK_FLAG([-Wl,--exclude-libs,ALL -Wl,-Bsymbolic -Wl,-z,text -Wl,-z,defs],[], + [AC_MSG_ERROR([--with-static-wolfssl needs a linker supporting --exclude-libs, -Bsymbolic, -z text and -z defs])]) + WOLFPKCS11_STATIC_WOLFSSL=yes + STATIC_WOLFSSL_DEP="$STATIC_WOLFSSL" + ]) +AM_CONDITIONAL([BUILD_STATIC_WOLFSSL],[test "x$WOLFPKCS11_STATIC_WOLFSSL" = "xyes"]) +AC_SUBST([WOLFPKCS11_STATIC_WOLFSSL]) +AC_SUBST([STATIC_WOLFSSL_DEP]) + + # HARDEN FLAGS AX_HARDEN_CC_COMPILER_FLAGS OPTION_FLAGS="$CFLAGS $CPPFLAGS $AM_CFLAGS" -LIBS="$LIBS -lwolfssl -lm" +AS_IF([test "x$WOLFPKCS11_STATIC_WOLFSSL" = "xyes"], + [WOLFPKCS11_CONFIG_LIBS="$LIBS -lm" + LIBS="$STATIC_WOLFSSL $LIBS -lm"], + [LIBS="$LIBS -lwolfssl -lm" + WOLFPKCS11_CONFIG_LIBS="$LIBS"]) CREATE_HEX_VERSION AC_SUBST([AM_CPPFLAGS]) @@ -660,7 +693,7 @@ AS_IF([test "x$ENABLED_CMAKE_INSTALL" = "xyes"],[ AC_CONFIG_FILES([cmake/wolfpkcs11ConfigVersion.cmake:cmake/wolfpkcs11ConfigVersion.cmake.in]) ]) -AX_CREATE_GENERIC_CONFIG +AX_CREATE_GENERIC_CONFIG([$PACKAGE $WOLFPKCS11_CONFIG_LIBS]) AX_AM_JOBSERVER([yes]) AC_OUTPUT diff --git a/src/include.am b/src/include.am index f54ea410..2c5d4e50 100644 --- a/src/include.am +++ b/src/include.am @@ -13,6 +13,9 @@ src_libwolfpkcs11_la_SOURCES = \ src_libwolfpkcs11_la_CFLAGS = -DBUILDING_WOLFPKCS11 $(AM_CFLAGS) src_libwolfpkcs11_la_CPPFLAGS = -DBUILDING_WOLFPKCS11 $(AM_CPPFLAGS) src_libwolfpkcs11_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-number ${WOLFPKCS11_LIBRARY_VERSION} +if BUILD_STATIC_WOLFSSL +src_libwolfpkcs11_la_LDFLAGS += -Wl,--exclude-libs,ALL -Wl,-Bsymbolic -Wl,-z,text -Wl,-z,defs +endif -#src_libwolfpkcs11_la_DEPENDENCIES = +src_libwolfpkcs11_la_DEPENDENCIES = $(STATIC_WOLFSSL_DEP) #EXTRA_DIST += diff --git a/tests/include.am b/tests/include.am index 8d234f41..6227e4f4 100644 --- a/tests/include.am +++ b/tests/include.am @@ -240,7 +240,6 @@ noinst_PROGRAMS += tests/aes_keywrap_pad_test tests_aes_keywrap_pad_test_SOURCES = tests/aes_keywrap_pad_test.c tests_aes_keywrap_pad_test_LDADD = -check_PROGRAMS += tests/mlkem_secret_scrub_test noinst_PROGRAMS += tests/mlkem_secret_scrub_test tests_mlkem_secret_scrub_test_SOURCES = tests/mlkem_secret_scrub_test.c tests_mlkem_secret_scrub_test_LDADD = @@ -285,11 +284,9 @@ noinst_PROGRAMS += tests/unique_id_test tests_unique_id_test_SOURCES = tests/unique_id_test.c tests_unique_id_test_LDADD = -check_PROGRAMS += tests/token_reset_fail_test noinst_PROGRAMS += tests/token_reset_fail_test tests_token_reset_fail_test_SOURCES = tests/token_reset_fail_test.c tests_token_reset_fail_test_LDADD = -check_PROGRAMS += tests/token_store_test noinst_PROGRAMS += tests/token_store_test tests_token_store_test_SOURCES = tests/token_store_test.c tests_token_store_test_LDADD = @@ -339,7 +336,6 @@ noinst_PROGRAMS += tests/nss_configdir_prefix_test tests_nss_configdir_prefix_test_SOURCES = tests/nss_configdir_prefix_test.c tests_nss_configdir_prefix_test_LDADD = -check_PROGRAMS += tests/logout_retire_test noinst_PROGRAMS += tests/logout_retire_test tests_logout_retire_test_SOURCES = tests/logout_retire_test.c tests_logout_retire_test_LDADD = @@ -349,7 +345,6 @@ noinst_PROGRAMS += tests/login_pin_state_test tests_login_pin_state_test_SOURCES = tests/login_pin_state_test.c tests_login_pin_state_test_LDADD = -check_PROGRAMS += tests/object_store_decode_test noinst_PROGRAMS += tests/object_store_decode_test tests_object_store_decode_test_SOURCES = tests/object_store_decode_test.c tests_object_store_decode_test_LDADD = @@ -360,22 +355,18 @@ tests_object_policy_integrity_test_SOURCES = \ tests/object_policy_integrity_test.c tests_object_policy_integrity_test_LDADD = -check_PROGRAMS += tests/session_op_lifecycle_test noinst_PROGRAMS += tests/session_op_lifecycle_test tests_session_op_lifecycle_test_SOURCES = tests/session_op_lifecycle_test.c tests_session_op_lifecycle_test_LDADD = -check_PROGRAMS += tests/info_mech_table_test noinst_PROGRAMS += tests/info_mech_table_test tests_info_mech_table_test_SOURCES = tests/info_mech_table_test.c tests_info_mech_table_test_LDADD = -check_PROGRAMS += tests/attribute_validation_test noinst_PROGRAMS += tests/attribute_validation_test tests_attribute_validation_test_SOURCES = tests/attribute_validation_test.c tests_attribute_validation_test_LDADD = -check_PROGRAMS += tests/key_material_update_test noinst_PROGRAMS += tests/key_material_update_test tests_key_material_update_test_SOURCES = tests/key_material_update_test.c tests_key_material_update_test_LDADD = @@ -400,12 +391,10 @@ noinst_PROGRAMS += tests/digest_length_test tests_digest_length_test_SOURCES = tests/digest_length_test.c tests_digest_length_test_LDADD = -check_PROGRAMS += tests/secret_scrub_test noinst_PROGRAMS += tests/secret_scrub_test tests_secret_scrub_test_SOURCES = tests/secret_scrub_test.c tests_secret_scrub_test_LDADD = -check_PROGRAMS += tests/unwrap_keygen_test noinst_PROGRAMS += tests/unwrap_keygen_test tests_unwrap_keygen_test_SOURCES = tests/unwrap_keygen_test.c tests_unwrap_keygen_test_LDADD = @@ -415,6 +404,20 @@ noinst_PROGRAMS += tests/token_partial_store_test tests_token_partial_store_test_SOURCES = tests/token_partial_store_test.c tests_token_partial_store_test_LDADD = +if !BUILD_STATIC_WOLFSSL +check_PROGRAMS += tests/token_store_test +check_PROGRAMS += tests/logout_retire_test +check_PROGRAMS += tests/session_op_lifecycle_test +check_PROGRAMS += tests/info_mech_table_test +check_PROGRAMS += tests/attribute_validation_test +check_PROGRAMS += tests/key_material_update_test +check_PROGRAMS += tests/secret_scrub_test +check_PROGRAMS += tests/object_store_decode_test +check_PROGRAMS += tests/mlkem_secret_scrub_test +check_PROGRAMS += tests/token_reset_fail_test +check_PROGRAMS += tests/unwrap_keygen_test +endif + if BUILD_STATIC tests_pkcs11test_LDADD += src/libwolfpkcs11.la tests_pkcs11mtt_LDADD += src/libwolfpkcs11.la From 30150d8885ee79ebb1eceea21d1feaf932d98780 Mon Sep 17 00:00:00 2001 From: Tobias Frauenschlaeger Date: Sat, 17 Oct 2026 20:57:14 +0000 Subject: [PATCH 4/5] Expand install paths in the autotools CMake package without --prefix configure expands libdir and includedir into WOLFPKCS11_LIBDIR_ABS and WOLFPKCS11_INCLUDEDIR_ABS for the installed wolfpkcs11Targets.cmake. It did so while prefix and exec_prefix still held NONE, because autoconf only applies the default prefix when it writes config.status. Without --prefix the package therefore pointed at NONE/lib and NONE/include, and find_package(wolfpkcs11) failed on the missing include directory. Expand them with the default prefix in place and restore both variables afterwards. --- configure.ac | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configure.ac b/configure.ac index 4c4d6b52..44950f26 100644 --- a/configure.ac +++ b/configure.ac @@ -678,8 +678,14 @@ AC_SUBST([AM_LDFLAGS]) PACKAGE_INIT='get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)' AC_SUBST([PACKAGE_INIT]) +wolfpkcs11_save_prefix=$prefix +wolfpkcs11_save_exec_prefix=$exec_prefix +test "x$prefix" = "xNONE" && prefix=$ac_default_prefix +test "x$exec_prefix" = "xNONE" && exec_prefix=$prefix WOLFPKCS11_LIBDIR_ABS=`eval echo "$libdir"` WOLFPKCS11_INCLUDEDIR_ABS=`eval echo "$includedir"` +prefix=$wolfpkcs11_save_prefix +exec_prefix=$wolfpkcs11_save_exec_prefix AC_SUBST([WOLFPKCS11_LIBDIR_ABS]) AC_SUBST([WOLFPKCS11_INCLUDEDIR_ABS]) From 3bff88cb7b50e76a10cbeb793395ce568b74c56f Mon Sep 17 00:00:00 2001 From: Tobias Frauenschlaeger Date: Sat, 17 Oct 2026 21:36:11 +0000 Subject: [PATCH 5/5] Install and consume the library in the static wolfSSL workflow Nothing in CI installed wolfPKCS11 or used the installed package, so the static-mode changes to the CMake package files and wolfpkcs11-config, and the expanded install paths, were never exercised. Both jobs now install the library and build a small find_package(wolfpkcs11) project from cmake/consumer with no wolfSSL on the search path, then run it. The autotools job installs to the default prefix, which covers the install paths written into the package, and checks that wolfpkcs11-config --libs no longer names wolfssl. --- .github/workflows/static-wolfssl.yml | 17 +++++++++++++++ cmake/consumer/CMakeLists.txt | 8 +++++++ cmake/consumer/main.c | 32 ++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 cmake/consumer/CMakeLists.txt create mode 100644 cmake/consumer/main.c diff --git a/.github/workflows/static-wolfssl.yml b/.github/workflows/static-wolfssl.yml index 46b564b3..11bc1709 100644 --- a/.github/workflows/static-wolfssl.yml +++ b/.github/workflows/static-wolfssl.yml @@ -58,6 +58,17 @@ jobs: run: make check - name: Run the wolfSSL interoperability test against the library run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/src/.libs/libwolfpkcs11.so + - name: Install wolfPKCS11 + run: | + sudo make install + sudo ldconfig + - name: Build a find_package consumer without wolfSSL + run: | + libs=$(wolfpkcs11-config --libs) + if grep wolfssl <<<"$libs"; then exit 1; fi + cmake -S cmake/consumer -B consumer-build + cmake --build consumer-build + ./consumer-build/wolfpkcs11_consumer # capture logs on failure - name: Upload failure logs @@ -117,3 +128,9 @@ jobs: done - name: Run the wolfSSL interoperability test against the library run: make -C tests/wolfssl-interoperability WOLFPKCS11_MODULE=$PWD/build/libwolfpkcs11.so + - name: Build a find_package consumer without wolfSSL + run: | + cmake --install build --prefix $RUNNER_TEMP/wolfpkcs11 + cmake -S cmake/consumer -B consumer-build -DCMAKE_PREFIX_PATH=$RUNNER_TEMP/wolfpkcs11 + cmake --build consumer-build + LD_LIBRARY_PATH=$RUNNER_TEMP/wolfpkcs11/lib ./consumer-build/wolfpkcs11_consumer diff --git a/cmake/consumer/CMakeLists.txt b/cmake/consumer/CMakeLists.txt new file mode 100644 index 00000000..a4c2d040 --- /dev/null +++ b/cmake/consumer/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) + +project(wolfpkcs11_consumer C) + +find_package(wolfpkcs11 REQUIRED) + +add_executable(wolfpkcs11_consumer main.c) +target_link_libraries(wolfpkcs11_consumer PRIVATE wolfpkcs11::wolfpkcs11) diff --git a/cmake/consumer/main.c b/cmake/consumer/main.c new file mode 100644 index 00000000..9db6b98a --- /dev/null +++ b/cmake/consumer/main.c @@ -0,0 +1,32 @@ +/* main.c + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfPKCS11. + * + * wolfPKCS11 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. + * + * wolfPKCS11 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +int main(void) +{ + CK_FUNCTION_LIST_PTR funcList = NULL; + + if (C_GetFunctionList(&funcList) != CKR_OK || funcList == NULL) { + return 1; + } + return 0; +}