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