Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <unistd.h>
     27 #include <string.h>
     28 #include <cryptoutil.h>
     29 #include <pthread.h>
     30 
     31 #include <security/cryptoki.h>
     32 #include "pkcs11Global.h"
     33 #include "pkcs11Slot.h"
     34 #include "pkcs11Conf.h"
     35 #include "pkcs11Session.h"
     36 #include "metaGlobal.h"
     37 
     38 #pragma init(pkcs11_init)
     39 #pragma fini(pkcs11_fini)
     40 
     41 static struct CK_FUNCTION_LIST functionList = {
     42 	{ 2, 20 },	/* version */
     43 	C_Initialize,
     44 	C_Finalize,
     45 	C_GetInfo,
     46 	C_GetFunctionList,
     47 	C_GetSlotList,
     48 	C_GetSlotInfo,
     49 	C_GetTokenInfo,
     50 	C_GetMechanismList,
     51 	C_GetMechanismInfo,
     52 	C_InitToken,
     53 	C_InitPIN,
     54 	C_SetPIN,
     55 	C_OpenSession,
     56 	C_CloseSession,
     57 	C_CloseAllSessions,
     58 	C_GetSessionInfo,
     59 	C_GetOperationState,
     60 	C_SetOperationState,
     61 	C_Login,
     62 	C_Logout,
     63 	C_CreateObject,
     64 	C_CopyObject,
     65 	C_DestroyObject,
     66 	C_GetObjectSize,
     67 	C_GetAttributeValue,
     68 	C_SetAttributeValue,
     69 	C_FindObjectsInit,
     70 	C_FindObjects,
     71 	C_FindObjectsFinal,
     72 	C_EncryptInit,
     73 	C_Encrypt,
     74 	C_EncryptUpdate,
     75 	C_EncryptFinal,
     76 	C_DecryptInit,
     77 	C_Decrypt,
     78 	C_DecryptUpdate,
     79 	C_DecryptFinal,
     80 	C_DigestInit,
     81 	C_Digest,
     82 	C_DigestUpdate,
     83 	C_DigestKey,
     84 	C_DigestFinal,
     85 	C_SignInit,
     86 	C_Sign,
     87 	C_SignUpdate,
     88 	C_SignFinal,
     89 	C_SignRecoverInit,
     90 	C_SignRecover,
     91 	C_VerifyInit,
     92 	C_Verify,
     93 	C_VerifyUpdate,
     94 	C_VerifyFinal,
     95 	C_VerifyRecoverInit,
     96 	C_VerifyRecover,
     97 	C_DigestEncryptUpdate,
     98 	C_DecryptDigestUpdate,
     99 	C_SignEncryptUpdate,
    100 	C_DecryptVerifyUpdate,
    101 	C_GenerateKey,
    102 	C_GenerateKeyPair,
    103 	C_WrapKey,
    104 	C_UnwrapKey,
    105 	C_DeriveKey,
    106 	C_SeedRandom,
    107 	C_GenerateRandom,
    108 	C_GetFunctionStatus,
    109 	C_CancelFunction,
    110 	C_WaitForSlotEvent
    111 };
    112 
    113 boolean_t pkcs11_initialized = B_FALSE;
    114 boolean_t pkcs11_cant_create_threads = B_FALSE;
    115 boolean_t fini_called = B_FALSE;
    116 static boolean_t pkcs11_atfork_initialized = B_FALSE;
    117 static pid_t pkcs11_pid = 0;
    118 
    119 /* protects pkcs11_[initialized|pid], and fastpath */
    120 static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER;
    121 
    122 static CK_RV finalize_common(CK_VOID_PTR pReserved);
    123 static void pkcs11_init();
    124 static void pkcs11_fini();
    125 
    126 /*
    127  * Ensure that before a fork, all mutexes are taken.
    128  * We cannot acquire globalmutex, because it can cause deadlock when
    129  * atfork() and fork() are called in parallel. It can happen when
    130  * C_Ininitialize() tries to dlopen() a provider. The dlopen() operation
    131  * is protected by globalmutex and when another thread calls fork()
    132  * pkcs11_fork_prepare cannot acquire the mutex again and thus it must wait.
    133  * When a provider tries to register its atfork handler, atfork() must
    134  * wait on fork(). See the comment in fork() libc function for more details.
    135  *
    136  * Order:
    137  * 1. slottable->st_mutex
    138  * 2. all slottable->st_slots' mutexes
    139  */
    140 static void
    141 pkcs11_fork_prepare(void)
    142 {
    143 	int i;
    144 	if (pkcs11_initialized) {
    145 		if (slottable != NULL) {
    146 			(void) pthread_mutex_lock(&slottable->st_mutex);
    147 
    148 			/* Take the sl_mutex of all slots */
    149 			for (i = slottable->st_first;
    150 			    i <= slottable->st_last; i++) {
    151 				if (slottable->st_slots[i] != NULL) {
    152 					(void) pthread_mutex_lock(
    153 					    &slottable->st_slots[i]->sl_mutex);
    154 				}
    155 			}
    156 		}
    157 	}
    158 }
    159 
    160 
    161 /*
    162  * Ensure that after a fork, in the parent, all mutexes are released in opposite
    163  * order to pkcs11_fork_prepare().
    164  */
    165 static void
    166 pkcs11_fork_parent(void)
    167 {
    168 	int i;
    169 	if (pkcs11_initialized) {
    170 		if (slottable != NULL) {
    171 			/* Release the sl_mutex of all slots */
    172 			for (i = slottable->st_first;
    173 			    i <= slottable->st_last; i++) {
    174 				if (slottable->st_slots[i] != NULL) {
    175 					(void) pthread_mutex_unlock(
    176 					    &slottable->st_slots[i]->sl_mutex);
    177 				}
    178 			}
    179 		}
    180 		(void) pthread_mutex_unlock(&slottable->st_mutex);
    181 	}
    182 }
    183 
    184 
    185 /*
    186  * Ensure that after a fork, in the child, all mutexes are released in opposite
    187  * order to pkcs11_fork_prepare() and cleanup is done.
    188  * Because we need to handle fork correctly before library is initialized two
    189  * handlers are necessary.
    190  *
    191  * 1) pkcs11_fork_child() - unlock mutexes
    192  * 2) pkcs11_fork_child_fini() - cleanup library after fork, it is registered in
    193  *                               C_Initialize() after providers initialization.
    194  */
    195 static void
    196 pkcs11_fork_child(void)
    197 {
    198 	int i;
    199 	if (pkcs11_initialized) {
    200 		if (slottable != NULL) {
    201 			/* Release the sl_mutex of all slots */
    202 			for (i = slottable->st_first;
    203 			    i <= slottable->st_last; i++) {
    204 				if (slottable->st_slots[i] != NULL) {
    205 					(void) pthread_mutex_unlock(
    206 					    &slottable->st_slots[i]->sl_mutex);
    207 				}
    208 			}
    209 		}
    210 		(void) pthread_mutex_unlock(&slottable->st_mutex);
    211 	}
    212 
    213 	(void) pthread_mutex_destroy(&globalmutex);
    214 	(void) pthread_mutex_init(&globalmutex, NULL);
    215 }
    216 
    217 /* Library cleanup have to be last afterfork child handler. */
    218 static void
    219 pkcs11_fork_child_fini(void)
    220 {
    221 	pkcs11_fini();
    222 }
    223 
    224 CK_RV
    225 C_Initialize(CK_VOID_PTR pInitArgs)
    226 {
    227 	CK_RV rv;
    228 	uentrylist_t *pliblist = NULL;
    229 	int initialize_pid;
    230 
    231 	/*
    232 	 * Grab lock to insure only one thread enters
    233 	 * this function at a time.
    234 	 */
    235 	(void) pthread_mutex_lock(&globalmutex);
    236 
    237 	initialize_pid = getpid();
    238 
    239 	/* Make sure function hasn't been called twice */
    240 	if (pkcs11_initialized) {
    241 		if (initialize_pid == pkcs11_pid) {
    242 			(void) pthread_mutex_unlock(&globalmutex);
    243 			return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
    244 		} else {
    245 			/*
    246 			 * A fork has happened and the child is
    247 			 * reinitializing.  Do a finalize_common() to close
    248 			 * out any state from the parent, and then
    249 			 * continue on.
    250 			 */
    251 			(void) finalize_common(NULL);
    252 		}
    253 	}
    254 
    255 	/* Check if application has provided mutex-handling functions */
    256 	if (pInitArgs != NULL) {
    257 		CK_C_INITIALIZE_ARGS_PTR initargs =
    258 		    (CK_C_INITIALIZE_ARGS_PTR) pInitArgs;
    259 
    260 		/* pReserved should not be set */
    261 		if (initargs->pReserved != NULL) {
    262 			rv = CKR_ARGUMENTS_BAD;
    263 			goto errorexit;
    264 		}
    265 
    266 		/*
    267 		 * Make sure function pointers are either all NULL or
    268 		 * all set.
    269 		 */
    270 		if (!(((initargs->CreateMutex   != NULL) &&
    271 		    (initargs->LockMutex    != NULL) &&
    272 		    (initargs->UnlockMutex  != NULL) &&
    273 		    (initargs->DestroyMutex != NULL)) ||
    274 		    ((initargs->CreateMutex == NULL) &&
    275 		    (initargs->LockMutex    == NULL) &&
    276 		    (initargs->UnlockMutex  == NULL) &&
    277 		    (initargs->DestroyMutex == NULL)))) {
    278 			rv = CKR_ARGUMENTS_BAD;
    279 			goto errorexit;
    280 		}
    281 
    282 		if (!(initargs->flags & CKF_OS_LOCKING_OK)) {
    283 			if (initargs->CreateMutex != NULL) {
    284 				/*
    285 				 * Do not accept application supplied
    286 				 * locking primitives.
    287 				 */
    288 				rv = CKR_CANT_LOCK;
    289 				goto errorexit;
    290 			}
    291 
    292 		}
    293 		if (initargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
    294 			/*
    295 			 * Calling application does not want the library
    296 			 * to create threads.  This will effect
    297 			 * C_WaitForSlotEvent().
    298 			 */
    299 			pkcs11_cant_create_threads = B_TRUE;
    300 		}
    301 	}
    302 
    303 	/* Initialize slot table */
    304 	rv = pkcs11_slottable_initialize();
    305 
    306 	if (rv != CKR_OK)
    307 		goto errorexit;
    308 
    309 	/* Get the list of providers */
    310 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
    311 		rv = CKR_FUNCTION_FAILED;
    312 		goto errorexit;
    313 	}
    314 
    315 	/*
    316 	 * Load each provider, check for accessible slots,
    317 	 * and populate slottable.  If metaslot is enabled,
    318 	 * it will be initialized as well.
    319 	 */
    320 	rv = pkcs11_slot_mapping(pliblist, pInitArgs);
    321 
    322 	if (rv != CKR_OK)
    323 		goto errorexit;
    324 
    325 	pkcs11_initialized = B_TRUE;
    326 	pkcs11_pid = initialize_pid;
    327 	/* Children inherit parent's atfork handlers */
    328 	if (!pkcs11_atfork_initialized) {
    329 		(void) pthread_atfork(NULL, NULL, pkcs11_fork_child_fini);
    330 		pkcs11_atfork_initialized = B_TRUE;
    331 	}
    332 
    333 	(void) pthread_mutex_unlock(&globalmutex);
    334 
    335 	/* Cleanup data structures no longer needed */
    336 	free_uentrylist(pliblist);
    337 
    338 	return (CKR_OK);
    339 
    340 errorexit:
    341 	/* Cleanup any data structures that have already been allocated */
    342 	if (slottable)
    343 		(void) pkcs11_slottable_delete();
    344 	if (pliblist)
    345 		(void) free_uentrylist(pliblist);
    346 
    347 	(void) pthread_mutex_unlock(&globalmutex);
    348 	return (rv);
    349 
    350 }
    351 
    352 /*
    353  * C_Finalize is a wrapper around finalize_common. The
    354  * globalmutex should be locked by C_Finalize().
    355  *
    356  * When an explicit C_Finalize() call is received, all
    357  * plugins currently in the slottable will also be
    358  * finalized.  This must occur, even if libpkcs11(3lib)
    359  * was not the first one to initialize the plugins, since it
    360  * is the only way in PKCS#11 to force a refresh of the
    361  * slot listings (ie to get new hardware devices).
    362  */
    363 CK_RV
    364 C_Finalize(CK_VOID_PTR pReserved)
    365 {
    366 
    367 	CK_RV rv;
    368 
    369 	(void) pthread_mutex_lock(&globalmutex);
    370 
    371 	rv = finalize_common(pReserved);
    372 
    373 	(void) pthread_mutex_unlock(&globalmutex);
    374 
    375 	return (rv);
    376 }
    377 
    378 /*
    379  * finalize_common() does the work for C_Finalize.  globalmutex
    380  * must be held before calling this function.
    381  */
    382 static CK_RV
    383 finalize_common(CK_VOID_PTR pReserved)
    384 {
    385 
    386 	CK_RV rv;
    387 
    388 	if (!pkcs11_initialized) {
    389 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
    390 	}
    391 
    392 	if (pReserved != NULL) {
    393 		return (CKR_ARGUMENTS_BAD);
    394 	}
    395 
    396 	purefastpath = B_FALSE;
    397 	policyfastpath = B_FALSE;
    398 	fast_funcs = NULL;
    399 	fast_slot = 0;
    400 	pkcs11_initialized = B_FALSE;
    401 	pkcs11_cant_create_threads = B_FALSE;
    402 	pkcs11_pid = 0;
    403 
    404 	/* Check if C_WaitForSlotEvent() is currently active */
    405 	(void) pthread_mutex_lock(&slottable->st_mutex);
    406 	if (slottable->st_wfse_active) {
    407 		/*
    408 		 * Wait for this thread to proceed far enough to block or
    409 		 * end on its own.  Otherwise, teardown of slottable may
    410 		 * occurr before this active function completes.
    411 		 */
    412 		while (slottable->st_wfse_active) {
    413 			/*
    414 			 * If C_WaitForSlotEvent is blocking, wake it up and
    415 			 * return error to calling application.
    416 			 */
    417 			if (slottable->st_blocking) {
    418 				slottable->st_list_signaled = B_TRUE;
    419 				(void) pthread_cond_signal(
    420 				    &slottable->st_wait_cond);
    421 				(void) pthread_mutex_unlock(
    422 				    &slottable->st_mutex);
    423 				(void) pthread_join(slottable->st_tid, NULL);
    424 			}
    425 		}
    426 	} else {
    427 		(void) pthread_mutex_unlock(&slottable->st_mutex);
    428 	}
    429 
    430 	rv = pkcs11_slottable_delete();
    431 
    432 	return (rv);
    433 }
    434 
    435 static void
    436 pkcs11_init()
    437 {
    438 	(void) pthread_atfork(pkcs11_fork_prepare,
    439 	    pkcs11_fork_parent, pkcs11_fork_child);
    440 }
    441 
    442 /*
    443  * pkcs11_fini() function required to make sure complete cleanup
    444  * is done of plugins if the framework is ever unloaded without
    445  * a C_Finalize() call.  This would be common when applications
    446  * load and unload other libraries that use libpkcs11(3lib), since
    447  * shared libraries should not call C_Finalize().
    448  *
    449  * If pkcs11_fini() is used, we set fini_called to B_TRUE so that
    450  * pkcs11_slottable_delete() will not call C_Finalize() on the plugins.
    451  *
    452  * This is to protect in cases where the application has dlopened
    453  * an object (for example, dlobj) that links to libpkcs11(3lib), but
    454  * the application is unaware that the object is doing PKCS#11 calls
    455  * underneath.  This application may later directly dlopen one of the
    456  * plugins (like pkcs11_softtoken.so, or any other 3rd party provided
    457  * plugin) in order to directly perform PKCS#11 operations.
    458  *
    459  * While it is still actively using the PKCS#11 plugin directly,
    460  * the application may finish with dlobj and dlclose it.  As the
    461  * reference count for libpkcs11(3lib) has become 0, pkcs11_fini()
    462  * will be run by the linker.  Even though libpkcs11(3lib) was the
    463  * first to initialize the plugin in this case, it is not safe for
    464  * libpkcs11(3lib) to finalize the plugin, as the application would
    465  * lose state.
    466  */
    467 static void
    468 pkcs11_fini()
    469 {
    470 	(void) pthread_mutex_lock(&globalmutex);
    471 
    472 	/* if we're not initilized, do not attempt to finalize */
    473 	if (!pkcs11_initialized) {
    474 		(void) pthread_mutex_unlock(&globalmutex);
    475 		return;
    476 	}
    477 
    478 	fini_called = B_TRUE;
    479 
    480 	(void) finalize_common(NULL_PTR);
    481 
    482 	(void) pthread_mutex_unlock(&globalmutex);
    483 
    484 }
    485 
    486 CK_RV
    487 C_GetInfo(CK_INFO_PTR pInfo)
    488 {
    489 
    490 	/* Check for a fastpath */
    491 	if (purefastpath || policyfastpath) {
    492 		return (fast_funcs->C_GetInfo(pInfo));
    493 	}
    494 
    495 	if (!pkcs11_initialized)
    496 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
    497 
    498 	if (pInfo == NULL) {
    499 		return (CKR_ARGUMENTS_BAD);
    500 	}
    501 
    502 	/*
    503 	 * Copy data into the provided buffer, use strncpy() instead
    504 	 * of strlcpy() so that the strings are NOT NULL terminated,
    505 	 * as required by the PKCS#11 standard
    506 	 */
    507 	(void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID,
    508 	    PKCS11_STRING_LENGTH);
    509 	(void) strncpy((char *)pInfo->libraryDescription,
    510 	    LIBRARY_DESCRIPTION, PKCS11_STRING_LENGTH);
    511 
    512 	pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
    513 	pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
    514 	pInfo->flags = 0;
    515 	pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR;
    516 	pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR;
    517 
    518 	return (CKR_OK);
    519 }
    520 
    521 /*
    522  * This function is unaffected by the fast-path, since it is likely
    523  * called before C_Initialize is, so we will not yet know the status
    524  * of the fast-path.  Additionally, policy will still need to be
    525  * enforced if applicable.
    526  */
    527 CK_RV
    528 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
    529 {
    530 	if (ppFunctionList == NULL) {
    531 		return (CKR_ARGUMENTS_BAD);
    532 	}
    533 
    534 	*ppFunctionList = &functionList;
    535 
    536 	return (CKR_OK);
    537 }
    538 
    539 
    540 /*
    541  * This function is no longer supported in this revision of the PKCS#11
    542  * standard.  It is maintained for backwards compatibility only.
    543  */
    544 /*ARGSUSED*/
    545 CK_RV
    546 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
    547 {
    548 	return (CKR_FUNCTION_NOT_PARALLEL);
    549 }
    550 
    551 
    552 /*
    553  * This function is no longer supported in this revision of the PKCS#11
    554  * standard.  It is maintained for backwards compatibility only.
    555  */
    556 /*ARGSUSED*/
    557 CK_RV
    558 C_CancelFunction(CK_SESSION_HANDLE hSession)
    559 {
    560 	return (CKR_FUNCTION_NOT_PARALLEL);
    561 }
    562