Skip to content

Commit

Permalink
Locking for multithreaded operations
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrojnar committed Dec 30, 2015
1 parent e903c8c commit 1ea84bf
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 3 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions src/libp11-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/p11_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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 */
Expand All @@ -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));
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 2 additions & 0 deletions src/p11_slot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 1ea84bf

Please sign in to comment.