[pkg-opensc-commit] [libp11] 27/67: Locking for multithreaded operations

Eric Dorland eric at moszumanska.debian.org
Sat Jan 30 05:34:14 UTC 2016


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository libp11.

commit 1ea84bfe1bc506bd13aecca41a37e0777a1b3b13
Author: Michał Trojnara <Michal.Trojnara at mirt.net>
Date:   Tue Dec 22 16:42:30 2015 +0100

    Locking for multithreaded operations
---
 README.md        | 12 +++++++++---
 src/libp11-int.h |  3 +++
 src/p11_ops.c    |  6 ++++++
 src/p11_slot.c   |  2 ++
 4 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 42d5a17..090606e 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,15 @@ Build state
 libp11 README -- Information for developers
 ===========================================
 
-This is a higher than PKCS #11 library to access PKCS #11 objects.
-It is designed to integrate with applications that use openssl. Note, however,
-that the libp11 library is not thread safe.
+This library provides a higher-level (compared to the PKCS#11 library)
+interface to access PKCS#11 objects.  It is designed to integrate with
+applications that use OpenSSL.
+
+Thread-safety requires dynamic callbacks to be registered by the calling
+application with the following OpenSSL functions:
+* CRYPTO_set_dynlock_create_callback
+* CRYPTO_set_dynlock_destroy_callback
+* CRYPTO_set_dynlock_lock_callback
 
 The wiki page for this project is at https://github.com/OpenSC/libp11/wiki
 and includes a bug tracker and source browser.
diff --git a/src/libp11-int.h b/src/libp11-int.h
index b2b1263..494daec 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -62,6 +62,9 @@ typedef struct pkcs11_slot_private {
 	/* options used in last PKCS11_login */
 	char *prev_pin;
 	int prev_so;
+
+	/* per-slot lock */
+	int lockid;
 } PKCS11_SLOT_private;
 #define PRIVSLOT(slot)		((PKCS11_SLOT_private *) (slot->_private))
 #define SLOT2CTX(slot)		(PRIVSLOT(slot)->parent)
diff --git a/src/p11_ops.c b/src/p11_ops.c
index aa5af81..82b96ac 100644
--- a/src/p11_ops.c
+++ b/src/p11_ops.c
@@ -51,12 +51,14 @@ PKCS11_ecdsa_sign(const unsigned char *m, unsigned int m_len,
 	memset(&mechanism, 0, sizeof(mechanism));
 	mechanism.mechanism = CKM_ECDSA;
 
+	CRYPTO_w_lock(PRIVSLOT(slot)->lockid);
 	if((rv = CRYPTOKI_call(ctx, C_SignInit
 			       (session, &mechanism, priv->object))) == 0) {
 		rv = CRYPTOKI_call(ctx, C_Sign
 				   (session, (CK_BYTE *) m, m_len,
 				    sigret, &ck_sigsize));
 	}
+	CRYPTO_w_unlock(PRIVSLOT(slot)->lockid);
 
 	if (rv) {
 		PKCS11err(PKCS11_F_PKCS11_EC_KEY_SIGN, pkcs11_map_err(rv));
@@ -174,6 +176,7 @@ PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
 
 	session = PRIVSLOT(slot)->session;
 
+	CRYPTO_w_lock(PRIVSLOT(slot)->lockid);
 	/* API is somewhat fishy here. *siglen is 0 on entry (cleared
 	 * by OpenSSL). The library assumes that the memory passed
 	 * by the caller is always big enough */
@@ -183,6 +186,7 @@ PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
 				   (session, (CK_BYTE *) from, flen,
 				    to, &ck_sigsize));
 	}
+	CRYPTO_w_unlock(PRIVSLOT(slot)->lockid);
 
 	if (rv) {
 		PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
@@ -226,11 +230,13 @@ PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
 	mechanism.mechanism = CKM_RSA_PKCS;
 
 
+	CRYPTO_w_lock(PRIVSLOT(slot)->lockid);
 	if( (rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, priv->object))) == 0) {
 		rv = CRYPTOKI_call(ctx, C_Decrypt
 			   (session, (CK_BYTE *) from, (CK_ULONG)flen,
 	   		    (CK_BYTE_PTR)to, &size));
 	}
+	CRYPTO_w_unlock(PRIVSLOT(slot)->lockid);
 
 	if (rv) {
 		PKCS11err(PKCS11_F_PKCS11_RSA_DECRYPT, pkcs11_map_err(rv));
diff --git a/src/p11_slot.c b/src/p11_slot.c
index 40a7972..2b85eb6 100644
--- a/src/p11_slot.c
+++ b/src/p11_slot.c
@@ -436,6 +436,7 @@ static int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id)
 	priv->prev_rw = 0;
 	priv->prev_pin = NULL;
 	priv->prev_so = 0;
+	priv->lockid = CRYPTO_get_new_dynlockid();
 
 	slot->description = PKCS11_DUP(info.slotDescription);
 	slot->manufacturer = PKCS11_DUP(info.manufacturerID);
@@ -466,6 +467,7 @@ void pkcs11_release_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
 			OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin));
 			OPENSSL_free(priv->prev_pin);
 		}
+		CRYPTO_destroy_dynlockid(priv->lockid);
 		CRYPTOKI_call(ctx, C_CloseAllSessions(priv->id));
 	}
 	OPENSSL_free(slot->_private);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/libp11.git



More information about the pkg-opensc-commit mailing list