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