Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
136 changes: 136 additions & 0 deletions .github/workflows/static-wolfssl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
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
- 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
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
- 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
38 changes: 37 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down Expand Up @@ -631,6 +636,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
Expand Down Expand Up @@ -728,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})
Expand Down Expand Up @@ -775,6 +810,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
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions cmake/consumer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
32 changes: 32 additions & 0 deletions cmake/consumer/main.c
Original file line number Diff line number Diff line change
@@ -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 <wolfpkcs11/pkcs11.h>

int main(void)
{
CK_FUNCTION_LIST_PTR funcList = NULL;

if (C_GetFunctionList(&funcList) != CKR_OK || funcList == NULL) {
return 1;
}
return 0;
}
4 changes: 3 additions & 1 deletion cmake/wolfpkcs11Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
8 changes: 5 additions & 3 deletions cmake/wolfpkcs11Targets.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
43 changes: 41 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -645,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])

Expand All @@ -660,7 +699,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
Expand Down
Loading
Loading