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