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 "%Z%%M% %I% %E% 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 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_fini(); 124 125 /* 126 * Ensure that before a fork, all mutexes are taken. 127 * Order: 128 * 1. globalmutex 129 * 2. slottable->st_mutex 130 * 3. all slottable->st_slots' mutexes 131 */ 132 static void 133 pkcs11_fork_prepare(void) 134 { 135 int i; 136 (void) pthread_mutex_lock(&globalmutex); 137 if (slottable != NULL) { 138 (void) pthread_mutex_lock(&slottable->st_mutex); 139 140 /* Take the sl_mutex of all slots */ 141 for (i = slottable->st_first; i <= slottable->st_last; i++) { 142 if (slottable->st_slots[i] != NULL) { 143 (void) pthread_mutex_lock( 144 &slottable->st_slots[i]->sl_mutex); 145 } 146 } 147 } 148 } 149 150 151 /* 152 * Ensure that after a fork, in the parent, all mutexes are released in opposite 153 * order to pkcs11_fork_prepare(). 154 */ 155 static void 156 pkcs11_fork_parent(void) 157 { 158 int i; 159 if (slottable != NULL) { 160 /* Release the sl_mutex of all slots */ 161 for (i = slottable->st_first; i <= slottable->st_last; i++) { 162 if (slottable->st_slots[i] != NULL) { 163 (void) pthread_mutex_unlock( 164 &slottable->st_slots[i]->sl_mutex); 165 } 166 } 167 (void) pthread_mutex_unlock(&slottable->st_mutex); 168 } 169 (void) pthread_mutex_unlock(&globalmutex); 170 } 171 172 173 /* 174 * Ensure that after a fork, in the child, all mutexes are released in opposite 175 * order to pkcs11_fork_prepare() and cleanup is done. 176 */ 177 static void 178 pkcs11_fork_child(void) 179 { 180 int i; 181 if (slottable != NULL) { 182 /* Release the sl_mutex of all slots */ 183 for (i = slottable->st_first; i <= slottable->st_last; i++) { 184 if (slottable->st_slots[i] != NULL) { 185 (void) pthread_mutex_unlock( 186 &slottable->st_slots[i]->sl_mutex); 187 } 188 } 189 (void) pthread_mutex_unlock(&slottable->st_mutex); 190 } 191 (void) pthread_mutex_unlock(&globalmutex); 192 pkcs11_fini(); 193 } 194 195 CK_RV 196 C_Initialize(CK_VOID_PTR pInitArgs) 197 { 198 CK_RV rv; 199 uentrylist_t *pliblist = NULL; 200 int initialize_pid; 201 202 /* 203 * Grab lock to insure only one thread enters 204 * this function at a time. 205 */ 206 (void) pthread_mutex_lock(&globalmutex); 207 208 initialize_pid = getpid(); 209 210 /* Make sure function hasn't been called twice */ 211 if (pkcs11_initialized) { 212 if (initialize_pid == pkcs11_pid) { 213 (void) pthread_mutex_unlock(&globalmutex); 214 return (CKR_CRYPTOKI_ALREADY_INITIALIZED); 215 } else { 216 /* 217 * A fork has happened and the child is 218 * reinitializing. Do a finalize_common() to close 219 * out any state from the parent, and then 220 * continue on. 221 */ 222 (void) finalize_common(NULL); 223 } 224 } 225 226 /* Check if application has provided mutex-handling functions */ 227 if (pInitArgs != NULL) { 228 CK_C_INITIALIZE_ARGS_PTR initargs = 229 (CK_C_INITIALIZE_ARGS_PTR) pInitArgs; 230 231 /* pReserved should not be set */ 232 if (initargs->pReserved != NULL) { 233 rv = CKR_ARGUMENTS_BAD; 234 goto errorexit; 235 } 236 237 /* 238 * Make sure function pointers are either all NULL or 239 * all set. 240 */ 241 if (!(((initargs->CreateMutex != NULL) && 242 (initargs->LockMutex != NULL) && 243 (initargs->UnlockMutex != NULL) && 244 (initargs->DestroyMutex != NULL)) || 245 ((initargs->CreateMutex == NULL) && 246 (initargs->LockMutex == NULL) && 247 (initargs->UnlockMutex == NULL) && 248 (initargs->DestroyMutex == NULL)))) { 249 rv = CKR_ARGUMENTS_BAD; 250 goto errorexit; 251 } 252 253 if (!(initargs->flags & CKF_OS_LOCKING_OK)) { 254 if (initargs->CreateMutex != NULL) { 255 /* 256 * Do not accept application supplied 257 * locking primitives. 258 */ 259 rv = CKR_CANT_LOCK; 260 goto errorexit; 261 } 262 263 } 264 if (initargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) { 265 /* 266 * Calling application does not want the library 267 * to create threads. This will effect 268 * C_WaitForSlotEvent(). 269 */ 270 pkcs11_cant_create_threads = B_TRUE; 271 } 272 } 273 274 /* Initialize slot table */ 275 rv = pkcs11_slottable_initialize(); 276 277 if (rv != CKR_OK) 278 goto errorexit; 279 280 /* Get the list of providers */ 281 if (get_pkcs11conf_info(&pliblist) != SUCCESS) { 282 rv = CKR_FUNCTION_FAILED; 283 goto errorexit; 284 } 285 286 /* 287 * Load each provider, check for accessible slots, 288 * and populate slottable. If metaslot is enabled, 289 * it will be initialized as well. 290 */ 291 rv = pkcs11_slot_mapping(pliblist, pInitArgs); 292 293 if (rv != CKR_OK) 294 goto errorexit; 295 296 pkcs11_initialized = B_TRUE; 297 pkcs11_pid = initialize_pid; 298 /* Children inherit parent's atfork handlers */ 299 if (!pkcs11_atfork_initialized) { 300 (void) pthread_atfork(pkcs11_fork_prepare, 301 pkcs11_fork_parent, pkcs11_fork_child); 302 pkcs11_atfork_initialized = B_TRUE; 303 } 304 (void) pthread_mutex_unlock(&globalmutex); 305 306 /* Cleanup data structures no longer needed */ 307 free_uentrylist(pliblist); 308 309 return (CKR_OK); 310 311 errorexit: 312 /* Cleanup any data structures that have already been allocated */ 313 if (slottable) 314 (void) pkcs11_slottable_delete(); 315 if (pliblist) 316 (void) free_uentrylist(pliblist); 317 318 (void) pthread_mutex_unlock(&globalmutex); 319 return (rv); 320 321 } 322 323 /* 324 * C_Finalize is a wrapper around finalize_common. The 325 * globalmutex should be locked by C_Finalize(). 326 * 327 * When an explicit C_Finalize() call is received, all 328 * plugins currently in the slottable will also be 329 * finalized. This must occur, even if libpkcs11(3lib) 330 * was not the first one to initialize the plugins, since it 331 * is the only way in PKCS#11 to force a refresh of the 332 * slot listings (ie to get new hardware devices). 333 */ 334 CK_RV 335 C_Finalize(CK_VOID_PTR pReserved) 336 { 337 338 CK_RV rv; 339 340 (void) pthread_mutex_lock(&globalmutex); 341 342 rv = finalize_common(pReserved); 343 344 (void) pthread_mutex_unlock(&globalmutex); 345 346 return (rv); 347 } 348 349 /* 350 * finalize_common() does the work for C_Finalize. globalmutex 351 * must be held before calling this function. 352 */ 353 static CK_RV 354 finalize_common(CK_VOID_PTR pReserved) 355 { 356 357 CK_RV rv; 358 359 if (!pkcs11_initialized) { 360 return (CKR_CRYPTOKI_NOT_INITIALIZED); 361 } 362 363 if (pReserved != NULL) { 364 return (CKR_ARGUMENTS_BAD); 365 } 366 367 purefastpath = B_FALSE; 368 policyfastpath = B_FALSE; 369 fast_funcs = NULL; 370 fast_slot = 0; 371 pkcs11_initialized = B_FALSE; 372 pkcs11_cant_create_threads = B_FALSE; 373 pkcs11_pid = 0; 374 375 /* Check if C_WaitForSlotEvent() is currently active */ 376 (void) pthread_mutex_lock(&slottable->st_mutex); 377 if (slottable->st_wfse_active) { 378 /* 379 * Wait for this thread to proceed far enough to block or 380 * end on its own. Otherwise, teardown of slottable may 381 * occurr before this active function completes. 382 */ 383 while (slottable->st_wfse_active) { 384 /* 385 * If C_WaitForSlotEvent is blocking, wake it up and 386 * return error to calling application. 387 */ 388 if (slottable->st_blocking) { 389 slottable->st_list_signaled = B_TRUE; 390 (void) pthread_cond_signal( 391 &slottable->st_wait_cond); 392 (void) pthread_mutex_unlock( 393 &slottable->st_mutex); 394 (void) pthread_join(slottable->st_tid, NULL); 395 } 396 } 397 } else { 398 (void) pthread_mutex_unlock(&slottable->st_mutex); 399 } 400 401 rv = pkcs11_slottable_delete(); 402 403 return (rv); 404 } 405 406 /* 407 * pkcs11_fini() function required to make sure complete cleanup 408 * is done of plugins if the framework is ever unloaded without 409 * a C_Finalize() call. This would be common when applications 410 * load and unload other libraries that use libpkcs11(3lib), since 411 * shared libraries should not call C_Finalize(). 412 * 413 * If pkcs11_fini() is used, we set fini_called to B_TRUE so that 414 * pkcs11_slottable_delete() will not call C_Finalize() on the plugins. 415 * 416 * This is to protect in cases where the application has dlopened 417 * an object (for example, dlobj) that links to libpkcs11(3lib), but 418 * the application is unaware that the object is doing PKCS#11 calls 419 * underneath. This application may later directly dlopen one of the 420 * plugins (like pkcs11_softtoken.so, or any other 3rd party provided 421 * plugin) in order to directly perform PKCS#11 operations. 422 * 423 * While it is still actively using the PKCS#11 plugin directly, 424 * the application may finish with dlobj and dlclose it. As the 425 * reference count for libpkcs11(3lib) has become 0, pkcs11_fini() 426 * will be run by the linker. Even though libpkcs11(3lib) was the 427 * first to initialize the plugin in this case, it is not safe for 428 * libpkcs11(3lib) to finalize the plugin, as the application would 429 * lose state. 430 */ 431 static void 432 pkcs11_fini() 433 { 434 (void) pthread_mutex_lock(&globalmutex); 435 436 /* if we're not initilized, do not attempt to finalize */ 437 if (!pkcs11_initialized) { 438 (void) pthread_mutex_unlock(&globalmutex); 439 return; 440 } 441 442 fini_called = B_TRUE; 443 444 (void) finalize_common(NULL_PTR); 445 446 (void) pthread_mutex_unlock(&globalmutex); 447 448 } 449 450 CK_RV 451 C_GetInfo(CK_INFO_PTR pInfo) 452 { 453 454 /* Check for a fastpath */ 455 if (purefastpath || policyfastpath) { 456 return (fast_funcs->C_GetInfo(pInfo)); 457 } 458 459 if (!pkcs11_initialized) 460 return (CKR_CRYPTOKI_NOT_INITIALIZED); 461 462 if (pInfo == NULL) { 463 return (CKR_ARGUMENTS_BAD); 464 } 465 466 /* 467 * Copy data into the provided buffer, use strncpy() instead 468 * of strlcpy() so that the strings are NOT NULL terminated, 469 * as required by the PKCS#11 standard 470 */ 471 (void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID, 472 PKCS11_STRING_LENGTH); 473 (void) strncpy((char *)pInfo->libraryDescription, 474 LIBRARY_DESCRIPTION, PKCS11_STRING_LENGTH); 475 476 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; 477 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; 478 pInfo->flags = 0; 479 pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR; 480 pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR; 481 482 return (CKR_OK); 483 } 484 485 /* 486 * This function is unaffected by the fast-path, since it is likely 487 * called before C_Initialize is, so we will not yet know the status 488 * of the fast-path. Additionally, policy will still need to be 489 * enforced if applicable. 490 */ 491 CK_RV 492 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 493 { 494 if (ppFunctionList == NULL) { 495 return (CKR_ARGUMENTS_BAD); 496 } 497 498 *ppFunctionList = &functionList; 499 500 return (CKR_OK); 501 } 502 503 504 /* 505 * This function is no longer supported in this revision of the PKCS#11 506 * standard. It is maintained for backwards compatibility only. 507 */ 508 /*ARGSUSED*/ 509 CK_RV 510 C_GetFunctionStatus(CK_SESSION_HANDLE hSession) 511 { 512 return (CKR_FUNCTION_NOT_PARALLEL); 513 } 514 515 516 /* 517 * This function is no longer supported in this revision of the PKCS#11 518 * standard. It is maintained for backwards compatibility only. 519 */ 520 /*ARGSUSED*/ 521 CK_RV 522 C_CancelFunction(CK_SESSION_HANDLE hSession) 523 { 524 return (CKR_FUNCTION_NOT_PARALLEL); 525 } 526