summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-10-30 11:29:38 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-11-03 16:10:56 +0000
commit00ae9ab6d51929b17c43e1424b434a951a59bd58 (patch)
tree3abbff5d6a448a24ae46cdfd3571e2114b4baa5d
parente85d0a63b6ffd4421a89bba86d58ec8cf9635aac (diff)
downloadgnutls-00ae9ab6d51929b17c43e1424b434a951a59bd58.tar.gz
pkcs11: allow loading trusted modules when pkcs11 was initialized in manual mode
When a PKCS#11 trust module is used in the system, but gnutls_pkcs11_init() is explicitly called with GNUTLS_PKCS11_FLAG_MANUAL flag, then the PKCS#11 trust store was not loaded, and thus prevent any certificate validation. This change allows initializing the trust modules only even if generic PKCS#11 support is disabled by the application. Relates #316 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/pkcs11.c36
-rw-r--r--lib/pkcs11_int.h16
-rw-r--r--lib/pkcs11_privkey.c2
3 files changed, 26 insertions, 28 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 521aa3d5dd..ceb05bbe8d 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -109,12 +109,6 @@ struct find_cert_st {
static struct gnutls_pkcs11_provider_st providers[MAX_PROVIDERS];
static unsigned int active_providers = 0;
-typedef enum init_level_t {
- PROV_UNINITIALIZED = 0,
- PROV_INIT_TRUSTED,
- PROV_INIT_ALL
-} init_level_t;
-
static init_level_t providers_initialized = PROV_UNINITIALIZED;
static unsigned int pkcs11_forkid = 0;
@@ -123,6 +117,8 @@ static int _gnutls_pkcs11_reinit(void);
gnutls_pkcs11_token_callback_t _gnutls_token_func;
void *_gnutls_token_data;
+static int auto_load(unsigned trusted);
+
int pkcs11_rv_to_err(ck_rv_t rv)
{
switch (rv) {
@@ -268,15 +264,9 @@ pkcs11_add_module(const char* name, struct ck_function_list *module, unsigned cu
* The output value of the callback will be returned if it is
* a negative one (indicating failure).
*/
-int _gnutls_pkcs11_check_init(unsigned trusted, void *priv, pkcs11_reinit_function cb)
+int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_function cb)
{
int ret;
- init_level_t req_level = PROV_UNINITIALIZED;
-
- if (trusted)
- req_level = PROV_INIT_TRUSTED;
- else
- req_level = PROV_INIT_ALL;
ret = gnutls_mutex_lock(&_gnutls_pkcs11_mutex);
if (ret != 0)
@@ -301,16 +291,16 @@ int _gnutls_pkcs11_check_init(unsigned trusted, void *priv, pkcs11_reinit_functi
gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
return ret;
- } else if (providers_initialized < req_level) {
- /* when upgrading initialization level, deinitialize
- * and re-initialize everything. */
- gnutls_pkcs11_deinit();
- }
+ } else if (providers_initialized < req_level &&
+ (req_level == PROV_INIT_TRUSTED)) {
+ _gnutls_debug_log("Initializing needed PKCS #11 modules\n");
+ ret = auto_load(1);
- _gnutls_debug_log("Initializing PKCS #11 modules\n");
- ret = gnutls_pkcs11_init(
- trusted?GNUTLS_PKCS11_FLAG_AUTO_TRUSTED:GNUTLS_PKCS11_FLAG_AUTO,
- NULL);
+ providers_initialized = PROV_INIT_TRUSTED;
+ } else {
+ _gnutls_debug_log("Initializing all PKCS #11 modules\n");
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_AUTO, NULL);
+ }
gnutls_mutex_unlock(&_gnutls_pkcs11_mutex);
@@ -836,7 +826,7 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file)
if (flags == GNUTLS_PKCS11_FLAG_MANUAL) {
/* if manual configuration is requested then don't
* bother loading any other providers */
- providers_initialized = PROV_INIT_ALL;
+ providers_initialized = PROV_INIT_MANUAL;
return 0;
} else if (flags & GNUTLS_PKCS11_FLAG_AUTO) {
if (deprecated_config_file == NULL)
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 23b45fe36a..de9afbdee5 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -82,7 +82,15 @@ struct gnutls_pkcs11_privkey_st {
* directly. It can be provided a callback function to run when a reinitialization
* occurs. */
typedef int (*pkcs11_reinit_function)(void *priv);
-int _gnutls_pkcs11_check_init(unsigned trusted, void *priv, pkcs11_reinit_function cb);
+
+typedef enum init_level_t {
+ PROV_UNINITIALIZED = 0,
+ PROV_INIT_MANUAL,
+ PROV_INIT_TRUSTED,
+ PROV_INIT_ALL
+} init_level_t;
+
+int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_function cb);
#define FIX_KEY_USAGE(pk, usage) \
if (usage == 0) { \
@@ -93,17 +101,17 @@ int _gnutls_pkcs11_check_init(unsigned trusted, void *priv, pkcs11_reinit_functi
}
#define PKCS11_CHECK_INIT \
- ret = _gnutls_pkcs11_check_init(0, NULL, NULL); \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(ret)
#define PKCS11_CHECK_INIT_TRUSTED \
- ret = _gnutls_pkcs11_check_init(1, NULL, NULL); \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_TRUSTED, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(ret)
#define PKCS11_CHECK_INIT_RET(x) \
- ret = _gnutls_pkcs11_check_init(0, NULL, NULL); \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, NULL, NULL); \
if (ret < 0) \
return gnutls_assert_val(x)
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 1665cf33f3..afe831ee9b 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -36,7 +36,7 @@
/* In case of a fork, it will invalidate the open session
* in the privkey and start another */
#define PKCS11_CHECK_INIT_PRIVKEY(k) \
- ret = _gnutls_pkcs11_check_init(0, k, reopen_privkey_session); \
+ ret = _gnutls_pkcs11_check_init(PROV_INIT_MANUAL, k, reopen_privkey_session); \
if (ret < 0) \
return gnutls_assert_val(ret)