diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-10 17:12:50 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-13 08:29:54 +0100 |
commit | 8a3773782f59df8ac9ad6ff3758c330559e860ad (patch) | |
tree | 18437c5e7db6dad45aab6f6d3065e13810787930 /lib/pkcs11_privkey.c | |
parent | b012133ddf21d7d349369a1cf2f196d305db4e79 (diff) | |
download | gnutls-8a3773782f59df8ac9ad6ff3758c330559e860ad.tar.gz |
pkcs11: introduced locks to PKCS#11 private key structure
This allows to run PKCS#11 private key operations such as signing
and decryption in parallel.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/pkcs11_privkey.c')
-rw-r--r-- | lib/pkcs11_privkey.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index bb9b286b1c..220d718ddc 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -1,6 +1,7 @@ /* * GnuTLS PKCS#11 support * Copyright (C) 2010-2012 Free Software Foundation, Inc. + * Copyright (C) 2017 Red Hat, Inc. * * Authors: Nikos Mavrogiannopoulos, Stef Walter * @@ -29,6 +30,7 @@ #include <pk.h> #include <fips.h> #include "urls.h" +#include "locks.h" #include <p11-kit/uri.h> /* In case of a fork, it will invalidate the open session @@ -71,6 +73,8 @@ struct gnutls_pkcs11_privkey_st { ck_object_handle_t ref; /* the key in the session */ unsigned reauth; /* whether we need to login on each operation */ + void *mutex; /* lock for operations requiring co-ordination */ + struct pin_info_st pin; }; @@ -85,6 +89,7 @@ struct gnutls_pkcs11_privkey_st { **/ int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key) { + int ret; FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st)); @@ -100,6 +105,14 @@ int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key) return GNUTLS_E_MEMORY_ERROR; } + ret = gnutls_mutex_init(&(*key)->mutex); + if (ret < 0) { + gnutls_assert(); + p11_kit_uri_free((*key)->uinfo); + free(*key); + return GNUTLS_E_LOCKING_ERROR; + } + return 0; } @@ -135,6 +148,7 @@ void gnutls_pkcs11_privkey_deinit(gnutls_pkcs11_privkey_t key) gnutls_free(key->url); if (key->sinfo.init != 0) pkcs11_close_session(&key->sinfo); + gnutls_mutex_deinit(&key->mutex); gnutls_free(key); } @@ -261,6 +275,10 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, mech.parameter = NULL; mech.parameter_len = 0; + ret = gnutls_mutex_lock(&key->mutex); + if (ret != 0) + return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR); + /* Initialize signing operation; using the private key discovered * earlier. */ rv = pkcs11_sign_init(sinfo->module, sinfo->pks, &mech, key->ref); @@ -335,6 +353,7 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, ret = 0; cleanup: + gnutls_mutex_unlock(&key->mutex); if (sinfo != &key->sinfo) pkcs11_close_session(sinfo); if (ret < 0) @@ -519,6 +538,10 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, mech.parameter = NULL; mech.parameter_len = 0; + ret = gnutls_mutex_lock(&key->mutex); + if (ret != 0) + return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR); + /* Initialize signing operation; using the private key discovered * earlier. */ rv = pkcs11_decrypt_init(key->sinfo.module, key->sinfo.pks, &mech, key->ref); @@ -565,6 +588,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, ret = 0; cleanup: + gnutls_mutex_unlock(&key->mutex); return ret; } |