summaryrefslogtreecommitdiff
path: root/lib/pkcs11.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-03-10 17:37:10 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-03-13 08:29:54 +0100
commit7332b6c2b9586d02a87a1950124a3b447f6aec22 (patch)
tree5f227bb14c61de2ff1a9012b24ea38ffc1daaabc /lib/pkcs11.c
parent8a3773782f59df8ac9ad6ff3758c330559e860ad (diff)
downloadgnutls-7332b6c2b9586d02a87a1950124a3b447f6aec22.tar.gz
pkcs11: re-open private key session inside a locked section
This prevents clashes when the same operation is carried in other threads. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/pkcs11.c')
-rw-r--r--lib/pkcs11.c69
1 files changed, 45 insertions, 24 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index a7b2c2b2f6..ed843aa3ed 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -3,7 +3,7 @@
* Copyright (C) 2010-2014 Free Software Foundation, Inc.
* Copyright (C) 2008 Joe Orton <joe@manyfish.co.uk>
* Copyright (C) 2013 Nikos Mavrogiannopoulos
- * Copyright (C) 2014 Red Hat
+ * Copyright (C) 2014-2017 Red Hat
*
* Authors: Nikos Mavrogiannopoulos, Stef Walter
*
@@ -109,6 +109,8 @@ static unsigned int active_providers = 0;
static unsigned int providers_initialized = 0;
static unsigned int pkcs11_forkid = 0;
+static int _gnutls_pkcs11_reinit(void);
+
gnutls_pkcs11_token_callback_t _gnutls_token_func;
void *_gnutls_token_data;
@@ -251,9 +253,12 @@ pkcs11_add_module(const char* name, struct ck_function_list *module, const char
/* Returns:
* - negative error code on error,
* - 0 on success
- * - 1 on success (and a fork was detected)
- */
-int _gnutls_pkcs11_check_init(void)
+ * - 1 on success (and a fork was detected - cb was run)
+ *
+ * The output value of the callback will be returned if it is
+ * a negative one (indicating failure).
+*/
+int _gnutls_pkcs11_check_init(void *priv, pkcs11_reinit_function cb)
{
int ret;
@@ -266,9 +271,16 @@ int _gnutls_pkcs11_check_init(void)
if (_gnutls_detect_fork(pkcs11_forkid)) {
/* if we are initialized but a fork is detected */
- ret = gnutls_pkcs11_reinit();
- if (ret == 0)
+ ret = _gnutls_pkcs11_reinit();
+ if (ret == 0) {
ret = 1;
+ if (cb) {
+ int ret2 = cb(priv);
+ if (ret2 < 0)
+ ret = ret2;
+ }
+ pkcs11_forkid = _gnutls_get_forkid();
+ }
}
gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
@@ -794,6 +806,30 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file)
return 0;
}
+static int _gnutls_pkcs11_reinit(void)
+{
+ unsigned i;
+ ck_rv_t rv;
+
+ for (i = 0; i < active_providers; i++) {
+ if (providers[i].module != NULL) {
+ rv = p11_kit_module_initialize(providers
+ [i].module);
+ if (rv == CKR_OK || rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+ providers[i].active = 1;
+ } else {
+ providers[i].active = 0;
+ _gnutls_debug_log
+ ("Cannot re-initialize registered module '%.*s': %s\n",
+ (int)32, providers[i].info.library_description,
+ p11_kit_strerror(rv));
+ }
+ }
+ }
+
+ return 0;
+}
+
/**
* gnutls_pkcs11_reinit:
*
@@ -811,32 +847,17 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file)
**/
int gnutls_pkcs11_reinit(void)
{
- unsigned i;
- ck_rv_t rv;
+ int ret;
/* make sure that we don't call more than once after a fork */
if (_gnutls_detect_fork(pkcs11_forkid) == 0)
return 0;
- for (i = 0; i < active_providers; i++) {
- if (providers[i].module != NULL) {
- rv = p11_kit_module_initialize(providers
- [i].module);
- if (rv == CKR_OK || rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
- providers[i].active = 1;
- } else {
- providers[i].active = 0;
- _gnutls_debug_log
- ("Cannot re-initialize registered module '%.*s': %s\n",
- (int)32, providers[i].info.library_description,
- p11_kit_strerror(rv));
- }
- }
- }
+ ret = _gnutls_pkcs11_reinit();
pkcs11_forkid = _gnutls_get_forkid();
- return 0;
+ return ret;
}
/**