2727 */
2828
2929#include "util.h"
30+ #include "p11_pthread.h"
3031#include <stdio.h>
3132#include <string.h>
3233
@@ -70,6 +71,8 @@ struct util_ctx_st {
7071 PKCS11_CTX * pkcs11_ctx ;
7172 PKCS11_SLOT * slot_list ;
7273 unsigned int slot_count ;
74+ pthread_mutex_t lock ;
75+
7376};
7477
7578/******************************************************************************/
@@ -83,6 +86,7 @@ UTIL_CTX *UTIL_CTX_new()
8386 ctx = OPENSSL_malloc (sizeof (UTIL_CTX ));
8487 if (ctx )
8588 memset (ctx , 0 , sizeof (UTIL_CTX ));
89+ pthread_mutex_init (& ctx -> lock , 0 );
8690 return ctx ;
8791}
8892
@@ -91,6 +95,7 @@ void UTIL_CTX_free(UTIL_CTX *ctx)
9195 UTIL_CTX_set_pin (ctx , NULL );
9296 OPENSSL_free (ctx -> module );
9397 OPENSSL_free (ctx -> init_args );
98+ pthread_mutex_destroy (& ctx -> lock );
9499 OPENSSL_free (ctx );
95100}
96101
@@ -117,7 +122,7 @@ int UTIL_CTX_set_ui_method(UTIL_CTX *ctx, UI_METHOD *ui_method, void *ui_data)
117122 return 1 ;
118123}
119124
120- int UTIL_CTX_enumerate_slots (UTIL_CTX * ctx )
125+ static int UTIL_CTX_enumerate_slots_unlocked (UTIL_CTX * ctx )
121126{
122127 if (!ctx -> pkcs11_ctx )
123128 UTIL_CTX_init_libp11 (ctx );
@@ -134,7 +139,18 @@ int UTIL_CTX_enumerate_slots(UTIL_CTX *ctx)
134139 return 1 ;
135140}
136141
142+ int UTIL_CTX_enumerate_slots (UTIL_CTX * ctx )
143+ {
144+ int rv ;
145+
146+ pthread_mutex_lock (& ctx -> lock );
147+ rv = UTIL_CTX_enumerate_slots_unlocked (ctx );
148+ pthread_mutex_unlock (& ctx -> lock );
149+ return rv ;
150+ }
151+
137152/* Initialize libp11 data: ctx->pkcs11_ctx and ctx->slot_list */
153+
138154int UTIL_CTX_init_libp11 (UTIL_CTX * ctx )
139155{
140156 PKCS11_CTX * pkcs11_ctx ;
@@ -155,7 +171,7 @@ int UTIL_CTX_init_libp11(UTIL_CTX *ctx)
155171 }
156172 ctx -> pkcs11_ctx = pkcs11_ctx ;
157173
158- if (UTIL_CTX_enumerate_slots (ctx ) != 1 )
174+ if (UTIL_CTX_enumerate_slots_unlocked (ctx ) != 1 )
159175 return -1 ;
160176
161177 return ctx -> pkcs11_ctx && ctx -> slot_list ? 0 : -1 ;
@@ -382,19 +398,20 @@ int UTIL_CTX_set_pin(UTIL_CTX *ctx, const char *pin)
382398 * passed to the user interface implemented by an application. Only the
383399 * application knows how to interpret the call-back data.
384400 * A (strdup'ed) copy of the PIN code will be stored in the pin variable. */
385- static int util_ctx_get_pin (UTIL_CTX * ctx , const char * token_label )
401+ static int util_ctx_get_pin (UTIL_CTX * ctx , const char * token_label ,
402+ UI_METHOD * ui_method , void * ui_data )
386403{
387404 UI * ui ;
388405 char * prompt ;
389406
390407 /* call ui to ask for a pin */
391- ui = UI_new_method (ctx -> ui_method );
408+ ui = UI_new_method (ui_method );
392409 if (!ui ) {
393410 UTIL_CTX_log (ctx , LOG_ERR , "UI_new failed\n" );
394411 return 0 ;
395412 }
396- if (ctx -> ui_data )
397- UI_add_user_data (ui , ctx -> ui_data );
413+ if (ui_data )
414+ UI_add_user_data (ui , ui_data );
398415
399416 UTIL_CTX_set_pin (ctx , NULL );
400417 ctx -> pin = OPENSSL_malloc (MAX_PIN_LENGTH + 1 );
@@ -447,7 +464,8 @@ static int slot_logged_in(UTIL_CTX *ctx, PKCS11_SLOT *slot) {
447464 * @tok is PKCS11 token to log in (??? could be derived as @slot->token)
448465 * @return 1 on success, 0 on error.
449466 */
450- static int util_ctx_login (UTIL_CTX * ctx , PKCS11_SLOT * slot , PKCS11_TOKEN * tok )
467+ static int util_ctx_login (UTIL_CTX * ctx , PKCS11_SLOT * slot , PKCS11_TOKEN * tok ,
468+ UI_METHOD * ui_method , void * ui_data )
451469{
452470 if (!(ctx -> force_login || tok -> loginRequired ) || slot_logged_in (ctx , slot ))
453471 return 1 ;
@@ -466,7 +484,7 @@ static int util_ctx_login(UTIL_CTX *ctx, PKCS11_SLOT *slot, PKCS11_TOKEN *tok)
466484 return 0 ;
467485 }
468486 memset (ctx -> pin , 0 , MAX_PIN_LENGTH + 1 );
469- if (!util_ctx_get_pin (ctx , tok -> label )) {
487+ if (!util_ctx_get_pin (ctx , tok -> label , ui_method , ui_data )) {
470488 UTIL_CTX_set_pin (ctx , NULL );
471489 UTIL_CTX_log (ctx , LOG_ERR , "No PIN code was entered\n" );
472490 return 0 ;
@@ -826,7 +844,8 @@ static void *util_ctx_try_load_object(UTIL_CTX *ctx,
826844 const char * object_typestr ,
827845 void * (* match_func )(UTIL_CTX * , PKCS11_TOKEN * ,
828846 const char * , size_t , const char * ),
829- const char * object_uri , const int login )
847+ const char * object_uri , UI_METHOD * ui_method , void * ui_data ,
848+ const int login )
830849{
831850 PKCS11_SLOT * slot ;
832851 PKCS11_SLOT * found_slot = NULL , * * matched_slots = NULL ;
@@ -1003,7 +1022,7 @@ static void *util_ctx_try_load_object(UTIL_CTX *ctx,
10031022
10041023 /* Only try to login if login is required */
10051024 if (slot -> token -> loginRequired || ctx -> force_login ) {
1006- if (!util_ctx_login (ctx , slot , slot -> token )) {
1025+ if (!util_ctx_login (ctx , slot , slot -> token , ui_method , ui_data )) {
10071026 UTIL_CTX_log (ctx , LOG_ERR , "Login to token failed, returning NULL...\n" );
10081027 goto cleanup ; /* failed */
10091028 }
@@ -1052,7 +1071,7 @@ static void *util_ctx_try_load_object(UTIL_CTX *ctx,
10521071
10531072 /* Only try to login if login is required */
10541073 if (slot -> token -> loginRequired || ctx -> force_login ) {
1055- if (!util_ctx_login (ctx , slot , slot -> token )) {
1074+ if (!util_ctx_login (ctx , slot , slot -> token , ui_method , ui_data )) {
10561075 UTIL_CTX_log (ctx , LOG_ERR , "Login to token failed, returning NULL...\n" );
10571076 free (init_slots );
10581077 free (uninit_slots );
@@ -1137,27 +1156,36 @@ static void *util_ctx_load_object(UTIL_CTX *ctx,
11371156 const char * object_typestr ,
11381157 void * (* match_func )(UTIL_CTX * , PKCS11_TOKEN * ,
11391158 const char * , size_t , const char * ),
1140- const char * object_uri )
1159+ const char * object_uri , UI_METHOD * ui_method , void * ui_data )
11411160{
11421161 void * obj = NULL ;
11431162
1163+ pthread_mutex_lock (& ctx -> lock );
1164+
1165+ if (UTIL_CTX_init_libp11 (ctx )) {
1166+ pthread_mutex_unlock (& ctx -> lock );
1167+ return NULL ;
1168+ }
1169+
11441170 if (!ctx -> force_login ) {
11451171 ERR_clear_error ();
11461172 obj = util_ctx_try_load_object (ctx , object_typestr , match_func ,
1147- object_uri , 0 );
1173+ object_uri , ui_method , ui_data , 0 );
11481174 }
11491175
11501176 if (!obj ) {
11511177 /* Try again with login */
11521178 ERR_clear_error ();
11531179 obj = util_ctx_try_load_object (ctx , object_typestr , match_func ,
1154- object_uri , 1 );
1180+ object_uri , ui_method , ui_data , 1 );
11551181 if (!obj ) {
11561182 UTIL_CTX_log (ctx , LOG_ERR , "The %s was not found at: %s\n" ,
11571183 object_typestr , object_uri );
11581184 }
11591185 }
11601186
1187+ pthread_mutex_unlock (& ctx -> lock );
1188+
11611189 return obj ;
11621190}
11631191
@@ -1315,11 +1343,13 @@ static void *match_cert(UTIL_CTX *ctx, PKCS11_TOKEN *tok,
13151343 return selected_cert ;
13161344}
13171345
1318- X509 * UTIL_CTX_get_cert_from_uri (UTIL_CTX * ctx , const char * object_uri )
1346+ X509 * UTIL_CTX_get_cert_from_uri (UTIL_CTX * ctx , const char * uri ,
1347+ UI_METHOD * ui_method , void * ui_data )
13191348{
13201349 PKCS11_CERT * cert ;
13211350
1322- cert = util_ctx_load_object (ctx , "certificate" , match_cert , object_uri );
1351+ cert = util_ctx_load_object (ctx , "certificate" ,
1352+ match_cert , uri , ui_method , ui_data );
13231353 return cert ? X509_dup (cert -> x509 ) : NULL ;
13241354}
13251355
@@ -1448,21 +1478,23 @@ static void *match_private_key(UTIL_CTX *ctx, PKCS11_TOKEN *tok,
14481478 return match_key_int (ctx , tok , 1 , obj_id , obj_id_len , obj_label );
14491479}
14501480
1451- EVP_PKEY * UTIL_CTX_get_pubkey_from_uri (UTIL_CTX * ctx , const char * s_key_id )
1481+ EVP_PKEY * UTIL_CTX_get_pubkey_from_uri (UTIL_CTX * ctx , const char * uri ,
1482+ UI_METHOD * ui_method , void * ui_data )
14521483{
14531484 PKCS11_KEY * key ;
14541485
14551486 key = util_ctx_load_object (ctx , "public key" ,
1456- match_public_key , s_key_id );
1487+ match_public_key , uri , ui_method , ui_data );
14571488 return key ? PKCS11_get_public_key (key ) : NULL ;
14581489}
14591490
1460- EVP_PKEY * UTIL_CTX_get_privkey_from_uri (UTIL_CTX * ctx , const char * s_key_id )
1491+ EVP_PKEY * UTIL_CTX_get_privkey_from_uri (UTIL_CTX * ctx , const char * uri ,
1492+ UI_METHOD * ui_method , void * ui_data )
14611493{
14621494 PKCS11_KEY * key ;
14631495
14641496 key = util_ctx_load_object (ctx , "private key" ,
1465- match_private_key , s_key_id );
1497+ match_private_key , uri , ui_method , ui_data );
14661498 return key ? PKCS11_get_private_key (key ) : NULL ;
14671499}
14681500
0 commit comments