summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/includes/gnutls/pkcs11.h1
-rw-r--r--lib/pkcs11.c31
-rwxr-xr-xtests/p11-kit-load.sh56
-rw-r--r--tests/pkcs11/list-tokens.c37
4 files changed, 86 insertions, 39 deletions
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 2436069849..fc4031e47d 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -67,6 +67,7 @@ typedef struct gnutls_pkcs11_obj_st *gnutls_pkcs11_obj_t;
#define GNUTLS_PKCS11_FLAG_MANUAL 0 /* Manual loading of libraries */
#define GNUTLS_PKCS11_FLAG_AUTO 1 /* Automatically load libraries by reading /etc/gnutls/pkcs11.conf */
#define GNUTLS_PKCS11_FLAG_AUTO_TRUSTED (1<<1) /* Automatically load trusted libraries by reading /etc/gnutls/pkcs11.conf */
+#define GNUTLS_PKCS11_FLAG_IGNORE_DUPLICATE (1<<2) /* Ignore modules with duplicate module info when loading */
/* pkcs11.conf format:
* load = /lib/xxx-pkcs11.so
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 0d5e83a0c6..c4f848a44a 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -228,7 +228,8 @@ static int scan_slots(struct gnutls_pkcs11_provider_st *p,
}
static int
-pkcs11_add_module(const char* name, struct ck_function_list *module, unsigned custom_init, const char *params)
+pkcs11_add_module(const char* name, struct ck_function_list *module,
+ unsigned custom_init, const char *params, unsigned flags)
{
unsigned int i;
struct ck_info info;
@@ -241,13 +242,15 @@ pkcs11_add_module(const char* name, struct ck_function_list *module, unsigned cu
memset(&info, 0, sizeof(info));
pkcs11_get_module_info(module, &info);
- /* initially check if this module is a duplicate */
- for (i = 0; i < active_providers; i++) {
- /* already loaded, skip the rest */
- if (module == providers[i].module ||
- memcmp(&info, &providers[i].info, sizeof(info)) == 0) {
- _gnutls_debug_log("p11: module %s is already loaded.\n", name);
- return GNUTLS_E_INT_RET_0;
+ if (flags & GNUTLS_PKCS11_FLAG_IGNORE_DUPLICATE) {
+ /* initially check if this module is a duplicate */
+ for (i = 0; i < active_providers; i++) {
+ /* already loaded, skip the rest */
+ if (module == providers[i].module ||
+ memcmp(&info, &providers[i].info, sizeof(info)) == 0) {
+ _gnutls_debug_log("p11: module %s is already loaded.\n", name);
+ return GNUTLS_E_INT_RET_0;
+ }
}
}
@@ -415,7 +418,7 @@ int gnutls_pkcs11_add_provider(const char *name, const char *params)
return pkcs11_rv_to_err(ret);
}
- ret = pkcs11_add_module(name, module, custom_init, params);
+ ret = pkcs11_add_module(name, module, custom_init, params, 0);
if (ret != 0) {
if (ret == GNUTLS_E_INT_RET_0)
ret = 0;
@@ -925,13 +928,13 @@ static void compat_load(const char *configfile)
return;
}
-static int auto_load(unsigned trusted)
+static int auto_load(unsigned flags)
{
struct ck_function_list **modules;
int i, ret;
char* name;
- modules = p11_kit_modules_load_and_initialize(trusted?P11_KIT_MODULE_TRUSTED:0);
+ modules = p11_kit_modules_load_and_initialize((flags & GNUTLS_PKCS11_FLAG_AUTO_TRUSTED)?P11_KIT_MODULE_TRUSTED:0);
if (modules == NULL) {
gnutls_assert();
_gnutls_debug_log
@@ -945,7 +948,7 @@ static int auto_load(unsigned trusted)
_gnutls_debug_log
("p11: Initializing module: %s\n", name);
- ret = pkcs11_add_module(name, modules[i], 0, NULL);
+ ret = pkcs11_add_module(name, modules[i], 0, NULL, flags);
if (ret < 0) {
gnutls_assert();
_gnutls_debug_log
@@ -1004,7 +1007,7 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file)
return 0;
} else if (flags & GNUTLS_PKCS11_FLAG_AUTO) {
if (deprecated_config_file == NULL)
- ret = auto_load(0);
+ ret = auto_load(flags);
compat_load(deprecated_config_file);
@@ -1012,7 +1015,7 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file)
return ret;
} else if (flags & GNUTLS_PKCS11_FLAG_AUTO_TRUSTED) {
- ret = auto_load(1);
+ ret = auto_load(flags);
providers_initialized = PROV_INIT_TRUSTED;
diff --git a/tests/p11-kit-load.sh b/tests/p11-kit-load.sh
index 36629241da..39b26d456a 100755
--- a/tests/p11-kit-load.sh
+++ b/tests/p11-kit-load.sh
@@ -26,6 +26,7 @@
: ${DIFF=diff}
: ${PKG_CONFIG=pkg-config}
TMP_SOFTHSM_DIR="./softhsm-load.$$.tmp"
+TMP_SOFTHSM_REMOTE_DIR="./softhsm-remote.$$.tmp"
P11DIR="p11-kit-conf.$$.tmp"
PIN=1234
PUK=1234
@@ -64,8 +65,8 @@ if ! test -f "${SOFTHSM_MODULE}"; then
exit 77
fi
-# Create pkcs11.conf with two modules, a trusted (p11-kit-trust)
-# and softhsm (not trusted)
+# Create pkcs11.conf with three modules, a trusted (p11-kit-trust)
+# and two non-trusted softhsm modules (local and remote)
mkdir -p ${P11DIR}
cat <<_EOF_ >${P11DIR}/p11-kit-trust.module
@@ -77,7 +78,11 @@ cat <<_EOF_ >${P11DIR}/softhsm.module
module: libsofthsm2.so
_EOF_
-# Setup softhsm
+cat <<_EOF_ >${P11DIR}/softhsm-remote.module
+remote: |env - SOFTHSM2_CONF=${TMP_SOFTHSM_REMOTE_DIR}/conf p11-kit remote ${SOFTHSM_MODULE}
+_EOF_
+
+# Setup local softhsm
rm -rf ${TMP_SOFTHSM_DIR}
mkdir -p ${TMP_SOFTHSM_DIR}
SOFTHSM2_CONF=${TMP_SOFTHSM_DIR}/conf
@@ -97,15 +102,48 @@ if test $? != 0; then
exit 1
fi
+# Setup remote softhsm
+rm -rf ${TMP_SOFTHSM_REMOTE_DIR}
+mkdir -p ${TMP_SOFTHSM_REMOTE_DIR}
+SOFTHSM2_CONF=${TMP_SOFTHSM_REMOTE_DIR}/conf
+export SOFTHSM2_CONF
+echo "objectstore.backend = file" > "${SOFTHSM2_CONF}"
+echo "directories.tokendir = ${TMP_SOFTHSM_REMOTE_DIR}" >> "${SOFTHSM2_CONF}"
+
+softhsm2-util --init-token --slot 0 --label "GnuTLS-Remote" --so-pin "${PUK}" --pin "${PIN}" >/dev/null #2>&1
+if test $? != 0; then
+ echo "failed to initialize softhsm"
+ exit 1
+fi
+
+GNUTLS_PIN="${PIN}" ${P11TOOL} --login --label GnuTLS-Test-RSA --generate-privkey rsa --provider "${SOFTHSM_MODULE}" pkcs11: --outfile /dev/null
+if test $? != 0; then
+ echo "failed to generate privkey"
+ exit 1
+fi
+
+# Use the local softhsm configuration throughout the tests, unless
+# explicitly specified with the module configuration
+SOFTHSM2_CONF=${TMP_SOFTHSM_DIR}/conf
+export SOFTHSM2_CONF
+
FILTERTOKEN="sed s/token=.*//g"
# Check whether both are listed
-
nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -a|${FILTERTOKEN}|sort -u|wc -l)
#nr=$(${P11TOOL} --list-tokens|grep 'Module:'|sort -u|wc -l)
+if test "$nr" != 3;then
+ echo "Error: did not find 3 modules ($nr)"
+ ${builddir}/pkcs11/list-tokens -o ${P11DIR} -a
+ exit 1
+fi
+
+# Check whether duplicate modules are filtered
+nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -a -i|${FILTERTOKEN}|sort -u|wc -l)
+#nr=$(${P11TOOL} --list-tokens|grep 'Module:'|sort -u|wc -l)
if test "$nr" != 2;then
echo "Error: did not find 2 modules ($nr)"
- ${builddir}/pkcs11/list-tokens -o ${P11DIR}
+ ${builddir}/pkcs11/list-tokens -o ${P11DIR} -a -i
exit 1
fi
@@ -123,8 +161,8 @@ fi
# Check whether both modules are found when gnutls_pkcs11_init
# is not called but a pkcs11 operation is called.
nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -d|${FILTERTOKEN}|sort -u|wc -l)
-if test "$nr" != 2;then
- echo "Error in test 1: did not find 2 modules"
+if test "$nr" != 3;then
+ echo "Error in test 1: did not find 3 modules"
${builddir}/pkcs11/list-tokens -o ${P11DIR} -d
exit 1
fi
@@ -132,8 +170,8 @@ fi
# Check whether both modules are found when gnutls_pkcs11_init
# is called with the auto flag
nr=$(${builddir}/pkcs11/list-tokens -o ${P11DIR} -a|${FILTERTOKEN}|sort -u|wc -l)
-if test "$nr" != 2;then
- echo "Error in test 2: did not find 2 modules"
+if test "$nr" != 3;then
+ echo "Error in test 2: did not find 3 modules"
${builddir}/pkcs11/list-tokens -o ${P11DIR} -a
exit 1
fi
diff --git a/tests/pkcs11/list-tokens.c b/tests/pkcs11/list-tokens.c
index 39cd730842..ccd0ad6e72 100644
--- a/tests/pkcs11/list-tokens.c
+++ b/tests/pkcs11/list-tokens.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -63,6 +64,8 @@ int main(int argc, char **argv)
gnutls_pkcs11_privkey_t key;
unsigned flag = 1;
unsigned int status;
+ bool need_init = false;
+ unsigned init_flags = 0;
ret = gnutls_global_init();
if (ret != 0) {
@@ -73,7 +76,7 @@ int main(int argc, char **argv)
gnutls_global_set_log_function(tls_log_func);
//gnutls_global_set_log_level(4711);
- while((opt = getopt(argc, argv, "s:o:mvatdp")) != -1) {
+ while((opt = getopt(argc, argv, "s:o:mvatdpi")) != -1) {
switch(opt) {
case 'o':
mod = strdup(optarg);
@@ -81,11 +84,8 @@ int main(int argc, char **argv)
break;
case 'm':
/* initialize manually - i.e., do no module loading */
- ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
- if (ret != 0) {
- fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
- exit(1);
- }
+ need_init = true;
+ init_flags |= GNUTLS_PKCS11_FLAG_MANUAL;
break;
case 's':
/* load module */
@@ -108,19 +108,17 @@ int main(int argc, char **argv)
break;
case 'a':
/* initialize auto - i.e., do module loading */
- ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
- if (ret != 0) {
- fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
- exit(1);
- }
+ need_init = true;
+ init_flags |= GNUTLS_PKCS11_FLAG_AUTO;
break;
case 't':
/* do trusted module loading */
- ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO_TRUSTED, NULL);
- if (ret != 0) {
- fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
- exit(1);
- }
+ need_init = true;
+ init_flags |= GNUTLS_PKCS11_FLAG_AUTO_TRUSTED;
+ break;
+ case 'i':
+ /* ignore duplicate modules */
+ init_flags |= GNUTLS_PKCS11_FLAG_IGNORE_DUPLICATE;
break;
case 'v':
/* do verification which should trigger trusted module loading */
@@ -139,6 +137,13 @@ int main(int argc, char **argv)
}
}
+ if (need_init) {
+ ret = gnutls_pkcs11_init(init_flags, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "error at %d: %s\n", __LINE__, gnutls_strerror(ret));
+ exit(1);
+ }
+ }
for (i=0;;i++) {
ret = _gnutls_pkcs11_token_get_url(i, 0, &url, flag);