diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-10 17:37:10 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-13 08:29:54 +0100 |
commit | 7332b6c2b9586d02a87a1950124a3b447f6aec22 (patch) | |
tree | 5f227bb14c61de2ff1a9012b24ea38ffc1daaabc /lib/pkcs11.c | |
parent | 8a3773782f59df8ac9ad6ff3758c330559e860ad (diff) | |
download | gnutls-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.c | 69 |
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; } /** |