diff options
Diffstat (limited to 'debian/patches/p11kit-switch-to-dlopen.patch')
-rw-r--r-- | debian/patches/p11kit-switch-to-dlopen.patch | 743 |
1 files changed, 743 insertions, 0 deletions
diff --git a/debian/patches/p11kit-switch-to-dlopen.patch b/debian/patches/p11kit-switch-to-dlopen.patch new file mode 100644 index 0000000..b22bf58 --- /dev/null +++ b/debian/patches/p11kit-switch-to-dlopen.patch @@ -0,0 +1,743 @@ +From: Luca Boccassi <bluca@debian.org> +Date: Sat, 17 Dec 2022 01:33:46 +0000 +Subject: p11kit: switch to dlopen() + +--- + meson.build | 2 + + src/shared/meson.build | 2 +- + src/shared/pkcs11-util.c | 215 ++++++++++++++++++++++++++++++++++------------ + src/shared/pkcs11-util.h | 28 +++++- + src/test/meson.build | 4 +- + src/test/test-dlopen-so.c | 5 ++ + test/test-functions | 6 +- + 7 files changed, 202 insertions(+), 60 deletions(-) + +diff --git a/meson.build b/meson.build +index 9de2309..27d95e7 100644 +--- a/meson.build ++++ b/meson.build +@@ -1462,8 +1462,10 @@ if want_p11kit != 'false' and not skip_deps + version : '>= 0.23.3', + required : want_p11kit == 'true') + have = libp11kit.found() ++ libp11kit_cflags = libp11kit.partial_dependency(includes: true, compile_args: true) + else + have = false ++ libp11kit_cflags = [] + libp11kit = [] + endif + conf.set10('HAVE_P11KIT', have) +diff --git a/src/shared/meson.build b/src/shared/meson.build +index 3e2f327..9c47d2d 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -459,7 +459,7 @@ libshared_deps = [threads, + liblz4, + libmount, + libopenssl, +- libp11kit, ++ libp11kit_cflags, + libpam, + librt, + libseccomp, +diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c +index 752a21d..5f5dbae 100644 +--- a/src/shared/pkcs11-util.c ++++ b/src/shared/pkcs11-util.c +@@ -3,6 +3,7 @@ + #include <fcntl.h> + + #include "ask-password-api.h" ++#include "dlfcn-util.h" + #include "env-util.h" + #include "escape.h" + #include "fd-util.h" +@@ -40,17 +41,59 @@ bool pkcs11_uri_valid(const char *uri) { + + #if HAVE_P11KIT + ++static void *p11kit_dl = NULL; ++ ++char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module); ++void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules); ++CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags); ++const char *(*sym_p11_kit_strerror)(CK_RV rv); ++int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string); ++void (*sym_p11_kit_uri_free)(P11KitUri *uri); ++CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs); ++CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri); ++CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri); ++CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri); ++int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info); ++const char *(*sym_p11_kit_uri_message)(int code); ++P11KitUri *(*sym_p11_kit_uri_new)(void); ++int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri); ++ ++int dlopen_p11kit(void) { ++ return dlopen_many_sym_or_warn( ++ &p11kit_dl, ++ "libp11-kit.so.0", LOG_DEBUG, ++ DLSYM_ARG(p11_kit_module_get_name), ++ DLSYM_ARG(p11_kit_modules_finalize_and_release), ++ DLSYM_ARG(p11_kit_modules_load_and_initialize), ++ DLSYM_ARG(p11_kit_strerror), ++ DLSYM_ARG(p11_kit_uri_format), ++ DLSYM_ARG(p11_kit_uri_free), ++ DLSYM_ARG(p11_kit_uri_get_attributes), ++ DLSYM_ARG(p11_kit_uri_get_module_info), ++ DLSYM_ARG(p11_kit_uri_get_slot_info), ++ DLSYM_ARG(p11_kit_uri_get_token_info), ++ DLSYM_ARG(p11_kit_uri_match_token_info), ++ DLSYM_ARG(p11_kit_uri_message), ++ DLSYM_ARG(p11_kit_uri_new), ++ DLSYM_ARG(p11_kit_uri_parse)); ++} ++ + int uri_from_string(const char *p, P11KitUri **ret) { +- _cleanup_(p11_kit_uri_freep) P11KitUri *uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *uri = NULL; ++ int r; + + assert(p); + assert(ret); + +- uri = p11_kit_uri_new(); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return -ENOMEM; + +- if (p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK) ++ if (sym_p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK) + return -EINVAL; + + *ret = TAKE_PTR(uri); +@@ -62,11 +105,14 @@ P11KitUri *uri_from_module_info(const CK_INFO *info) { + + assert(info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_module_info(uri) = *info; ++ *sym_p11_kit_uri_get_module_info(uri) = *info; + return uri; + } + +@@ -75,11 +121,14 @@ P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info) { + + assert(slot_info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_slot_info(uri) = *slot_info; ++ *sym_p11_kit_uri_get_slot_info(uri) = *slot_info; + return uri; + } + +@@ -88,11 +137,14 @@ P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info) { + + assert(token_info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_token_info(uri) = *token_info; ++ *sym_p11_kit_uri_get_token_info(uri) = *token_info; + return uri; + } + +@@ -184,15 +236,20 @@ int pkcs11_token_login_by_pin( + size_t pin_size) { + + CK_RV rv; ++ int r; + + assert(m); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + if (FLAGS_SET(token_info->flags, CKF_PROTECTED_AUTHENTICATION_PATH)) { + rv = m->C_Login(session, CKU_USER, NULL, 0); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + log_info("Successfully logged into security token '%s' via protected authentication path.", token_label); + return 0; +@@ -217,7 +274,7 @@ int pkcs11_token_login_by_pin( + "PIN has been locked, please reset PIN of security token '%s'.", token_label); + if (!IN_SET(rv, CKR_PIN_INCORRECT, CKR_PIN_LEN_RANGE)) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + return log_notice_errno(SYNTHETIC_ERRNO(ENOLCK), + "PIN for token '%s' is incorrect, please try again.", +@@ -239,7 +296,7 @@ int pkcs11_token_login( + char **ret_used_pin) { + + _cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + CK_TOKEN_INFO updated_token_info; + int uri_result, r; + CK_RV rv; +@@ -247,6 +304,10 @@ int pkcs11_token_login( + assert(m); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + token_label = pkcs11_token_label(token_info); + if (!token_label) + return log_oom(); +@@ -255,9 +316,9 @@ int pkcs11_token_login( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + r = pkcs11_token_login_by_pin(m, session, token_info, token_label, /* pin= */ NULL, 0); + if (r == 0 && ret_used_pin) +@@ -336,7 +397,7 @@ int pkcs11_token_login( + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to acquire updated security token information for slot %lu: %s", +- slotid, p11_kit_strerror(rv)); ++ slotid, sym_p11_kit_strerror(rv)); + + token_info = &updated_token_info; + } +@@ -357,12 +418,17 @@ int pkcs11_token_find_x509_certificate( + CK_ATTRIBUTE *attributes = NULL; + CK_OBJECT_HANDLE objects[2]; + CK_RV rv, rv2; ++ int r; + + assert(m); + assert(search_uri); + assert(ret_object); + +- attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes); + for (a = 0; a < n_attributes; a++) { + + /* We use the URI's included match attributes, but make them more strict. This allows users +@@ -435,16 +501,16 @@ int pkcs11_token_find_x509_certificate( + rv = m->C_FindObjectsInit(session, attributes, n_attributes); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv)); + + rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects); + rv2 = m->C_FindObjectsFinal(session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to find objects: %s", p11_kit_strerror(rv)); ++ "Failed to find objects: %s", sym_p11_kit_strerror(rv)); + if (rv2 != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to finalize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv)); + if (n_objects == 0) + return log_error_errno(SYNTHETIC_ERRNO(ENOENT), + "Failed to find selected X509 certificate on token."); +@@ -472,11 +538,16 @@ int pkcs11_token_read_x509_certificate( + _cleanup_(X509_freep) X509 *x509 = NULL; + X509_NAME *name = NULL; + const unsigned char *p; ++ int r; ++ ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; + + rv = m->C_GetAttributeValue(session, object, &attribute, 1); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to read X.509 certificate size off token: %s", p11_kit_strerror(rv)); ++ "Failed to read X.509 certificate size off token: %s", sym_p11_kit_strerror(rv)); + + buffer = malloc(attribute.ulValueLen); + if (!buffer) +@@ -487,7 +558,7 @@ int pkcs11_token_read_x509_certificate( + rv = m->C_GetAttributeValue(session, object, &attribute, 1); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to read X.509 certificate data off token: %s", p11_kit_strerror(rv)); ++ "Failed to read X.509 certificate data off token: %s", sym_p11_kit_strerror(rv)); + + p = attribute.pValue; + x509 = d2i_X509(NULL, &p, attribute.ulValueLen); +@@ -521,12 +592,17 @@ int pkcs11_token_find_private_key( + CK_ATTRIBUTE *attributes = NULL; + CK_OBJECT_HANDLE objects[2]; + CK_RV rv, rv2; ++ int r; + + assert(m); + assert(search_uri); + assert(ret_object); + +- attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes); + for (a = 0; a < n_attributes; a++) { + + /* We use the URI's included match attributes, but make them more strict. This allows users +@@ -625,16 +701,16 @@ int pkcs11_token_find_private_key( + rv = m->C_FindObjectsInit(session, attributes, n_attributes); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv)); + + rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects); + rv2 = m->C_FindObjectsFinal(session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to find objects: %s", p11_kit_strerror(rv)); ++ "Failed to find objects: %s", sym_p11_kit_strerror(rv)); + if (rv2 != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to finalize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv)); + if (n_objects == 0) + return log_error_errno(SYNTHETIC_ERRNO(ENOENT), + "Failed to find selected private key suitable for decryption on token."); +@@ -661,6 +737,7 @@ int pkcs11_token_decrypt_data( + _cleanup_(erase_and_freep) CK_BYTE *dbuffer = NULL; + CK_ULONG dbuffer_size = 0; + CK_RV rv; ++ int r; + + assert(m); + assert(encrypted_data); +@@ -668,10 +745,14 @@ int pkcs11_token_decrypt_data( + assert(ret_decrypted_data); + assert(ret_decrypted_data_size); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + rv = m->C_DecryptInit(session, (CK_MECHANISM*) &mechanism, object); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize decryption on security token: %s", p11_kit_strerror(rv)); ++ "Failed to initialize decryption on security token: %s", sym_p11_kit_strerror(rv)); + + dbuffer_size = encrypted_data_size; /* Start with something reasonable */ + dbuffer = malloc(dbuffer_size); +@@ -690,7 +771,7 @@ int pkcs11_token_decrypt_data( + } + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to decrypt key on security token: %s", p11_kit_strerror(rv)); ++ "Failed to decrypt key on security token: %s", sym_p11_kit_strerror(rv)); + + log_info("Successfully decrypted key with security token."); + +@@ -710,6 +791,10 @@ int pkcs11_token_acquire_rng( + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* While we are at it, let's read some RNG data from the PKCS#11 token and pass it to the kernel + * random pool. This should be cheap if we are talking to the device already. Note that we don't + * credit any entropy, since we don't know about the quality of the pkcs#11 token's RNG. Why bother +@@ -726,7 +811,7 @@ int pkcs11_token_acquire_rng( + rv = m->C_GenerateRandom(session, buffer, rps); + if (rv != CKR_OK) + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), +- "Failed to generate RNG data on security token: %s", p11_kit_strerror(rv)); ++ "Failed to generate RNG data on security token: %s", sym_p11_kit_strerror(rv)); + + r = random_write_entropy(-1, buffer, rps, false); + if (r < 0) +@@ -762,7 +847,7 @@ static int token_process( + rv = m->C_OpenSession(slotid, CKF_SERIAL_SESSION, NULL, NULL, &session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to create session for security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to create session for security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + if (callback) + r = callback(m, session, slotid, slot_info, token_info, search_uri, userdata); +@@ -771,7 +856,7 @@ static int token_process( + + rv = m->C_CloseSession(session); + if (rv != CKR_OK) +- log_warning("Failed to close session on PKCS#11 token, ignoring: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to close session on PKCS#11 token, ignoring: %s", sym_p11_kit_strerror(rv)); + + return r; + } +@@ -783,21 +868,25 @@ static int slot_process( + pkcs11_find_token_callback_t callback, + void *userdata) { + +- _cleanup_(p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL; + _cleanup_free_ char *token_uri_string = NULL; + CK_TOKEN_INFO token_info; + CK_SLOT_INFO slot_info; +- int uri_result; ++ int uri_result, r; + CK_RV rv; + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We return -EAGAIN for all failures we can attribute to a specific slot in some way, so that the + * caller might try other slots before giving up. */ + + rv = m->C_GetSlotInfo(slotid, &slot_info); + if (rv != CKR_OK) { +- log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv)); ++ log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -808,9 +897,9 @@ static int slot_process( + if (DEBUG_LOGGING) { + _cleanup_free_ char *slot_uri_string = NULL; + +- uri_result = p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string); ++ uri_result = sym_p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format slot URI, ignoring slot: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format slot URI, ignoring slot: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +@@ -822,7 +911,7 @@ static int slot_process( + return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), + "Token not present in slot, ignoring."); + } else if (rv != CKR_OK) { +- log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv)); ++ log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -830,13 +919,13 @@ static int slot_process( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +- if (search_uri && !p11_kit_uri_match_token_info(search_uri, &token_info)) ++ if (search_uri && !sym_p11_kit_uri_match_token_info(search_uri, &token_info)) + return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), + "Found non-matching token with URI %s.", + token_uri_string); +@@ -859,8 +948,8 @@ static int module_process( + pkcs11_find_token_callback_t callback, + void *userdata) { + ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri* module_uri = NULL; + _cleanup_free_ char *name = NULL, *module_uri_string = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri* module_uri = NULL; + _cleanup_free_ CK_SLOT_ID *slotids = NULL; + CK_ULONG n_slotids = 0; + int uri_result; +@@ -871,11 +960,15 @@ static int module_process( + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We ignore most errors from modules here, in order to skip over faulty modules: one faulty module + * should not have the effect that we don't try the others anymore. We indicate such per-module + * failures with -EAGAIN, which let's the caller try the next module. */ + +- name = p11_kit_module_get_name(m); ++ name = sym_p11_kit_module_get_name(m); + if (!name) + return log_oom(); + +@@ -883,7 +976,7 @@ static int module_process( + + rv = m->C_GetInfo(&info); + if (rv != CKR_OK) { +- log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -891,9 +984,9 @@ static int module_process( + if (!module_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string); ++ uri_result = sym_p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format module URI, ignoring module: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format module URI, ignoring module: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +@@ -901,7 +994,7 @@ static int module_process( + + rv = pkcs11_get_slot_list_malloc(m, &slotids, &n_slotids); + if (rv != CKR_OK) { +- log_warning("Failed to get slot list, ignoring module: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to get slot list, ignoring module: %s", sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + if (n_slotids == 0) +@@ -927,10 +1020,14 @@ int pkcs11_find_token( + pkcs11_find_token_callback_t callback, + void *userdata) { + +- _cleanup_(p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *search_uri = NULL; ++ _cleanup_(sym_p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *search_uri = NULL; + int r; + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* Execute the specified callback for each matching token found. If nothing is found returns + * -EAGAIN. Logs about all errors, except for EAGAIN, which the caller has to log about. */ + +@@ -940,7 +1037,7 @@ int pkcs11_find_token( + return log_error_errno(r, "Failed to parse PKCS#11 URI '%s': %m", pkcs11_uri); + } + +- modules = p11_kit_modules_load_and_initialize(0); ++ modules = sym_p11_kit_modules_load_and_initialize(0); + if (!modules) + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize pkcs11 modules"); + +@@ -1068,13 +1165,17 @@ static int list_callback( + void *userdata) { + + _cleanup_free_ char *token_uri_string = NULL, *token_label = NULL, *token_manufacturer_id = NULL, *token_model = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + Table *t = userdata; + int uri_result, r; + + assert(slot_info); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We only care about hardware devices here with a token inserted. Let's filter everything else + * out. (Note that the user can explicitly specify non-hardware tokens if they like, but during + * enumeration we'll filter those, since software tokens are typically the system certificate store +@@ -1098,9 +1199,9 @@ static int list_callback( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + r = table_add_many( + t, +@@ -1154,13 +1255,17 @@ static int auto_callback( + P11KitUri *uri, + void *userdata) { + +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + char **t = userdata; +- int uri_result; ++ int uri_result, r; + + assert(slot_info); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) + return -EAGAIN; + +@@ -1172,9 +1277,9 @@ static int auto_callback( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + return 0; + } +diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h +index 7c88848..5bc23c1 100644 +--- a/src/shared/pkcs11-util.h ++++ b/src/shared/pkcs11-util.h +@@ -16,14 +16,30 @@ + bool pkcs11_uri_valid(const char *uri); + + #if HAVE_P11KIT ++ ++extern char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module); ++extern void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules); ++extern CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags); ++extern const char *(*sym_p11_kit_strerror)(CK_RV rv); ++extern int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string); ++extern void (*sym_p11_kit_uri_free)(P11KitUri *uri); ++extern CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs); ++extern CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri); ++extern CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri); ++extern CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri); ++extern int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info); ++extern const char *(*sym_p11_kit_uri_message)(int code); ++extern P11KitUri *(*sym_p11_kit_uri_new)(void); ++extern int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri); ++ + int uri_from_string(const char *p, P11KitUri **ret); + + P11KitUri *uri_from_module_info(const CK_INFO *info); + P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info); + P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info); + +-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, p11_kit_uri_free, NULL); +-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, p11_kit_modules_finalize_and_release, NULL); ++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, sym_p11_kit_uri_free, NULL); ++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, sym_p11_kit_modules_finalize_and_release, NULL); + + CK_RV pkcs11_get_slot_list_malloc(CK_FUNCTION_LIST *m, CK_SLOT_ID **ret_slotids, CK_ULONG *ret_n_slotids); + +@@ -74,6 +90,14 @@ int pkcs11_crypt_device_callback( + P11KitUri *uri, + void *userdata); + ++int dlopen_p11kit(void); ++ ++#else ++ ++static inline int dlopen_p11kit(void) { ++ return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "p11kit support is not compiled in."); ++} ++ + #endif + + typedef struct { +diff --git a/src/test/meson.build b/src/test/meson.build +index 2a4dfe2..082566b 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -74,7 +74,9 @@ tests += [ + [], + core_includes], + +- [files('test-dlopen-so.c')], ++ [files('test-dlopen-so.c'), ++ [], ++ libp11kit_cflags], + + [files('test-job-type.c'), + [libcore, +diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c +index 85dbb81..55728c2 100644 +--- a/src/test/test-dlopen-so.c ++++ b/src/test/test-dlopen-so.c +@@ -11,6 +11,7 @@ + #include "macro.h" + #include "main-func.h" + #include "pcre2-util.h" ++#include "pkcs11-util.h" + #include "pwquality-util.h" + #include "qrcode-util.h" + #include "tests.h" +@@ -60,6 +61,10 @@ static int run(int argc, char **argv) { + assert_se(dlopen_pcre2() >= 0); + #endif + ++#if HAVE_P11KIT ++ assert_se(dlopen_p11kit() >= 0); ++#endif ++ + return 0; + } + +diff --git a/test/test-functions b/test/test-functions +index 73fbef8..0ba7ce2 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1386,7 +1386,7 @@ install_missing_libraries() { + local lib path + # A number of dependencies is now optional via dlopen, so the install + # script will not pick them up, since it looks at linkage. +- for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon; do ++ for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1; do + ddebug "Searching for $lib via pkg-config" + if pkg-config --exists "$lib"; then + path="$(pkg-config --variable=libdir "$lib")" +@@ -1398,6 +1398,10 @@ install_missing_libraries() { + if ! [[ ${lib} =~ ^lib ]]; then + lib="lib${lib}" + fi ++ # p11-kit-1's .so doesn't have the API level in the name ++ if [[ ${lib} =~ p11-kit-1$ ]]; then ++ lib="libp11-kit" ++ fi + # Some pkg-config files are broken and give out the wrong paths + # (eg: libcryptsetup), so just ignore them + inst_libs "${path}/${lib}.so" || true |