instance.c (31084B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* 6 * instance.c 7 * 8 * This file implements the NSSCKFWInstance type and methods. 9 */ 10 11 #ifndef CK_T 12 #include "ck.h" 13 #endif /* CK_T */ 14 15 #include <stdint.h> 16 17 /* 18 * NSSCKFWInstance 19 * 20 * -- create/destroy -- 21 * nssCKFWInstance_Create 22 * nssCKFWInstance_Destroy 23 * 24 * -- public accessors -- 25 * NSSCKFWInstance_GetMDInstance 26 * NSSCKFWInstance_GetArena 27 * NSSCKFWInstance_MayCreatePthreads 28 * NSSCKFWInstance_CreateMutex 29 * NSSCKFWInstance_GetConfigurationData 30 * NSSCKFWInstance_GetInitArgs 31 * NSSCKFWInstance_DestroySessionHandle 32 * NSSCKFWInstance_FindSessionHandle 33 * 34 * -- implement public accessors -- 35 * nssCKFWInstance_GetMDInstance 36 * nssCKFWInstance_GetArena 37 * nssCKFWInstance_MayCreatePthreads 38 * nssCKFWInstance_CreateMutex 39 * nssCKFWInstance_GetConfigurationData 40 * nssCKFWInstance_GetInitArgs 41 * nssCKFWInstance_DestroySessionHandle 42 * nssCKFWInstance_FindSessionHandle 43 * 44 * -- private accessors -- 45 * nssCKFWInstance_CreateSessionHandle 46 * nssCKFWInstance_ResolveSessionHandle 47 * nssCKFWInstance_CreateObjectHandle 48 * nssCKFWInstance_ResolveObjectHandle 49 * nssCKFWInstance_DestroyObjectHandle 50 * 51 * -- module fronts -- 52 * nssCKFWInstance_GetNSlots 53 * nssCKFWInstance_GetCryptokiVersion 54 * nssCKFWInstance_GetManufacturerID 55 * nssCKFWInstance_GetFlags 56 * nssCKFWInstance_GetLibraryDescription 57 * nssCKFWInstance_GetLibraryVersion 58 * nssCKFWInstance_GetModuleHandlesSessionObjects 59 * nssCKFWInstance_GetSlots 60 * nssCKFWInstance_WaitForSlotEvent 61 * 62 * -- debugging versions only -- 63 * nssCKFWInstance_verifyPointer 64 */ 65 66 struct NSSCKFWInstanceStr { 67 NSSCKFWMutex *mutex; 68 NSSArena *arena; 69 NSSCKMDInstance *mdInstance; 70 CK_C_INITIALIZE_ARGS_PTR pInitArgs; 71 CK_C_INITIALIZE_ARGS initArgs; 72 CryptokiLockingState LockingState; 73 CK_BBOOL mayCreatePthreads; 74 NSSUTF8 *configurationData; 75 CK_ULONG nSlots; 76 NSSCKFWSlot **fwSlotList; 77 NSSCKMDSlot **mdSlotList; 78 CK_BBOOL moduleHandlesSessionObjects; 79 80 /* 81 * Everything above is set at creation time, and then not modified. 82 * The invariants the mutex protects are: 83 * 84 * 1) Each of the cached descriptions (versions, etc.) are in an 85 * internally consistant state. 86 * 87 * 2) The session handle hashes and count are consistant 88 * 89 * 3) The object handle hashes and count are consistant. 90 * 91 * I could use multiple locks, but let's wait to see if that's 92 * really necessary. 93 * 94 * Note that the calls accessing the cached descriptions will 95 * call the NSSCKMDInstance methods with the mutex locked. Those 96 * methods may then call the public NSSCKFWInstance routines. 97 * Those public routines only access the constant data above, so 98 * there's no problem. But be careful if you add to this object; 99 * mutexes are in general not reentrant, so don't create deadlock 100 * situations. 101 */ 102 103 CK_VERSION cryptokiVersion; 104 NSSUTF8 *manufacturerID; 105 NSSUTF8 *libraryDescription; 106 CK_VERSION libraryVersion; 107 108 CK_ULONG lastSessionHandle; 109 nssCKFWHash *sessionHandleHash; 110 111 CK_ULONG lastObjectHandle; 112 nssCKFWHash *objectHandleHash; 113 }; 114 115 #ifdef DEBUG 116 /* 117 * But first, the pointer-tracking stuff. 118 * 119 * NOTE: the pointer-tracking support in NSS/base currently relies 120 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 121 * locking, which is tied into the runtime. We need a pointer-tracker 122 * implementation that uses the locks supplied through C_Initialize. 123 * That support, however, can be filled in later. So for now, I'll 124 * just do this routines as no-ops. 125 */ 126 127 static CK_RV 128 instance_add_pointer( 129 const NSSCKFWInstance *fwInstance) 130 { 131 return CKR_OK; 132 } 133 134 static CK_RV 135 instance_remove_pointer( 136 const NSSCKFWInstance *fwInstance) 137 { 138 return CKR_OK; 139 } 140 141 NSS_IMPLEMENT CK_RV 142 nssCKFWInstance_verifyPointer( 143 const NSSCKFWInstance *fwInstance) 144 { 145 return CKR_OK; 146 } 147 148 #endif /* DEBUG */ 149 150 /* 151 * nssCKFWInstance_Create 152 * 153 */ 154 NSS_IMPLEMENT NSSCKFWInstance * 155 nssCKFWInstance_Create( 156 CK_C_INITIALIZE_ARGS_PTR pInitArgs, 157 CryptokiLockingState LockingState, 158 NSSCKMDInstance *mdInstance, 159 CK_RV *pError) 160 { 161 NSSCKFWInstance *fwInstance; 162 NSSArena *arena = (NSSArena *)NULL; 163 CK_ULONG i; 164 CK_BBOOL called_Initialize = CK_FALSE; 165 166 #ifdef NSSDEBUG 167 if ((CK_RV)NULL == pError) { 168 return (NSSCKFWInstance *)NULL; 169 } 170 171 if (!mdInstance) { 172 *pError = CKR_ARGUMENTS_BAD; 173 return (NSSCKFWInstance *)NULL; 174 } 175 #endif /* NSSDEBUG */ 176 177 arena = NSSArena_Create(); 178 if (!arena) { 179 *pError = CKR_HOST_MEMORY; 180 return (NSSCKFWInstance *)NULL; 181 } 182 183 fwInstance = nss_ZNEW(arena, NSSCKFWInstance); 184 if (!fwInstance) { 185 goto nomem; 186 } 187 188 fwInstance->arena = arena; 189 fwInstance->mdInstance = mdInstance; 190 191 fwInstance->LockingState = LockingState; 192 if ((CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs) { 193 fwInstance->initArgs = *pInitArgs; 194 fwInstance->pInitArgs = &fwInstance->initArgs; 195 if (pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) { 196 fwInstance->mayCreatePthreads = CK_FALSE; 197 } else { 198 fwInstance->mayCreatePthreads = CK_TRUE; 199 } 200 fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved); 201 } else { 202 fwInstance->mayCreatePthreads = CK_TRUE; 203 } 204 205 fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena, 206 pError); 207 if (!fwInstance->mutex) { 208 if (CKR_OK == *pError) { 209 *pError = CKR_GENERAL_ERROR; 210 } 211 goto loser; 212 } 213 214 if (mdInstance->Initialize) { 215 *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData); 216 if (CKR_OK != *pError) { 217 goto loser; 218 } 219 220 called_Initialize = CK_TRUE; 221 } 222 223 if (mdInstance->ModuleHandlesSessionObjects) { 224 fwInstance->moduleHandlesSessionObjects = 225 mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance); 226 } else { 227 fwInstance->moduleHandlesSessionObjects = CK_FALSE; 228 } 229 230 if (!mdInstance->GetNSlots) { 231 /* That routine is required */ 232 *pError = CKR_GENERAL_ERROR; 233 goto loser; 234 } 235 236 fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError); 237 if ((CK_ULONG)0 == fwInstance->nSlots) { 238 if (CKR_OK == *pError) { 239 /* Zero is not a legitimate answer */ 240 *pError = CKR_GENERAL_ERROR; 241 } 242 goto loser; 243 } 244 245 fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots); 246 if ((NSSCKFWSlot **)NULL == fwInstance->fwSlotList) { 247 goto nomem; 248 } 249 250 fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots); 251 if ((NSSCKMDSlot **)NULL == fwInstance->mdSlotList) { 252 goto nomem; 253 } 254 255 fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance, 256 fwInstance->arena, pError); 257 if (!fwInstance->sessionHandleHash) { 258 goto loser; 259 } 260 261 fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance, 262 fwInstance->arena, pError); 263 if (!fwInstance->objectHandleHash) { 264 goto loser; 265 } 266 267 if (!mdInstance->GetSlots) { 268 /* That routine is required */ 269 *pError = CKR_GENERAL_ERROR; 270 goto loser; 271 } 272 273 *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList); 274 if (CKR_OK != *pError) { 275 goto loser; 276 } 277 278 for (i = 0; i < fwInstance->nSlots; i++) { 279 NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i]; 280 281 if (!mdSlot) { 282 *pError = CKR_GENERAL_ERROR; 283 goto loser; 284 } 285 286 fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError); 287 if (CKR_OK != *pError) { 288 CK_ULONG j; 289 290 for (j = 0; j < i; j++) { 291 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]); 292 } 293 294 for (j = i; j < fwInstance->nSlots; j++) { 295 NSSCKMDSlot *mds = fwInstance->mdSlotList[j]; 296 if (mds->Destroy) { 297 mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance); 298 } 299 } 300 301 goto loser; 302 } 303 } 304 305 #ifdef DEBUG 306 *pError = instance_add_pointer(fwInstance); 307 if (CKR_OK != *pError) { 308 for (i = 0; i < fwInstance->nSlots; i++) { 309 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]); 310 } 311 312 goto loser; 313 } 314 #endif /* DEBUG */ 315 316 *pError = CKR_OK; 317 return fwInstance; 318 319 nomem: 320 *pError = CKR_HOST_MEMORY; 321 /*FALLTHROUGH*/ 322 loser: 323 324 if (CK_TRUE == called_Initialize) { 325 if (mdInstance->Finalize) { 326 mdInstance->Finalize(mdInstance, fwInstance); 327 } 328 } 329 330 if (fwInstance && fwInstance->mutex) { 331 nssCKFWMutex_Destroy(fwInstance->mutex); 332 } 333 334 if (arena) { 335 (void)NSSArena_Destroy(arena); 336 } 337 return (NSSCKFWInstance *)NULL; 338 } 339 340 /* 341 * nssCKFWInstance_Destroy 342 * 343 */ 344 NSS_IMPLEMENT CK_RV 345 nssCKFWInstance_Destroy( 346 NSSCKFWInstance *fwInstance) 347 { 348 #ifdef NSSDEBUG 349 CK_RV error = CKR_OK; 350 #endif /* NSSDEBUG */ 351 CK_ULONG i; 352 353 #ifdef NSSDEBUG 354 error = nssCKFWInstance_verifyPointer(fwInstance); 355 if (CKR_OK != error) { 356 return error; 357 } 358 #endif /* NSSDEBUG */ 359 360 nssCKFWMutex_Destroy(fwInstance->mutex); 361 362 for (i = 0; i < fwInstance->nSlots; i++) { 363 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]); 364 } 365 366 if (fwInstance->mdInstance->Finalize) { 367 fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance); 368 } 369 370 if (fwInstance->sessionHandleHash) { 371 nssCKFWHash_Destroy(fwInstance->sessionHandleHash); 372 } 373 374 if (fwInstance->objectHandleHash) { 375 nssCKFWHash_Destroy(fwInstance->objectHandleHash); 376 } 377 378 #ifdef DEBUG 379 (void)instance_remove_pointer(fwInstance); 380 #endif /* DEBUG */ 381 382 (void)NSSArena_Destroy(fwInstance->arena); 383 return CKR_OK; 384 } 385 386 /* 387 * nssCKFWInstance_GetMDInstance 388 * 389 */ 390 NSS_IMPLEMENT NSSCKMDInstance * 391 nssCKFWInstance_GetMDInstance( 392 NSSCKFWInstance *fwInstance) 393 { 394 #ifdef NSSDEBUG 395 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 396 return (NSSCKMDInstance *)NULL; 397 } 398 #endif /* NSSDEBUG */ 399 400 return fwInstance->mdInstance; 401 } 402 403 /* 404 * nssCKFWInstance_GetArena 405 * 406 */ 407 NSS_IMPLEMENT NSSArena * 408 nssCKFWInstance_GetArena( 409 NSSCKFWInstance *fwInstance, 410 CK_RV *pError) 411 { 412 #ifdef NSSDEBUG 413 if (!pError) { 414 return (NSSArena *)NULL; 415 } 416 417 *pError = nssCKFWInstance_verifyPointer(fwInstance); 418 if (CKR_OK != *pError) { 419 return (NSSArena *)NULL; 420 } 421 #endif /* NSSDEBUG */ 422 423 *pError = CKR_OK; 424 return fwInstance->arena; 425 } 426 427 /* 428 * nssCKFWInstance_MayCreatePthreads 429 * 430 */ 431 NSS_IMPLEMENT CK_BBOOL 432 nssCKFWInstance_MayCreatePthreads( 433 NSSCKFWInstance *fwInstance) 434 { 435 #ifdef NSSDEBUG 436 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 437 return CK_FALSE; 438 } 439 #endif /* NSSDEBUG */ 440 441 return fwInstance->mayCreatePthreads; 442 } 443 444 /* 445 * nssCKFWInstance_CreateMutex 446 * 447 */ 448 NSS_IMPLEMENT NSSCKFWMutex * 449 nssCKFWInstance_CreateMutex( 450 NSSCKFWInstance *fwInstance, 451 NSSArena *arena, 452 CK_RV *pError) 453 { 454 NSSCKFWMutex *mutex; 455 456 #ifdef NSSDEBUG 457 if (!pError) { 458 return (NSSCKFWMutex *)NULL; 459 } 460 461 *pError = nssCKFWInstance_verifyPointer(fwInstance); 462 if (CKR_OK != *pError) { 463 return (NSSCKFWMutex *)NULL; 464 } 465 #endif /* NSSDEBUG */ 466 467 mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState, 468 arena, pError); 469 if (!mutex) { 470 if (CKR_OK == *pError) { 471 *pError = CKR_GENERAL_ERROR; 472 } 473 474 return (NSSCKFWMutex *)NULL; 475 } 476 477 return mutex; 478 } 479 480 /* 481 * nssCKFWInstance_GetConfigurationData 482 * 483 */ 484 NSS_IMPLEMENT NSSUTF8 * 485 nssCKFWInstance_GetConfigurationData( 486 NSSCKFWInstance *fwInstance) 487 { 488 #ifdef NSSDEBUG 489 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 490 return (NSSUTF8 *)NULL; 491 } 492 #endif /* NSSDEBUG */ 493 494 return fwInstance->configurationData; 495 } 496 497 /* 498 * nssCKFWInstance_GetInitArgs 499 * 500 */ 501 CK_C_INITIALIZE_ARGS_PTR 502 nssCKFWInstance_GetInitArgs( 503 NSSCKFWInstance *fwInstance) 504 { 505 #ifdef NSSDEBUG 506 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 507 return (CK_C_INITIALIZE_ARGS_PTR)NULL; 508 } 509 #endif /* NSSDEBUG */ 510 511 return fwInstance->pInitArgs; 512 } 513 514 #if defined(_MSC_VER) 515 #pragma warning(push) 516 #pragma warning(disable : 4312) 517 #elif defined(__clang__) || defined(__GNUC__) 518 #pragma GCC diagnostic push 519 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast" 520 #endif 521 522 PR_STATIC_ASSERT(sizeof(CK_SESSION_HANDLE) <= sizeof(void *)); 523 524 static inline void * 525 CKSessionHandleToVoidPtr(CK_SESSION_HANDLE handle) 526 { 527 return (void *)(uintptr_t)handle; 528 } 529 530 #if defined(_MSC_VER) 531 #pragma warning(pop) 532 #elif defined(__clang__) || defined(__GNUC__) 533 #pragma GCC diagnostic pop 534 #endif 535 536 /* 537 * nssCKFWInstance_CreateSessionHandle 538 * 539 */ 540 NSS_IMPLEMENT CK_SESSION_HANDLE 541 nssCKFWInstance_CreateSessionHandle( 542 NSSCKFWInstance *fwInstance, 543 NSSCKFWSession *fwSession, 544 CK_RV *pError) 545 { 546 CK_SESSION_HANDLE hSession; 547 548 #ifdef NSSDEBUG 549 if (!pError) { 550 return (CK_SESSION_HANDLE)0; 551 } 552 553 *pError = nssCKFWInstance_verifyPointer(fwInstance); 554 if (CKR_OK != *pError) { 555 return (CK_SESSION_HANDLE)0; 556 } 557 #endif /* NSSDEBUG */ 558 559 *pError = nssCKFWMutex_Lock(fwInstance->mutex); 560 if (CKR_OK != *pError) { 561 return (CK_SESSION_HANDLE)0; 562 } 563 564 hSession = ++(fwInstance->lastSessionHandle); 565 566 /* Alan would say I should unlock for this call. */ 567 568 *pError = nssCKFWSession_SetHandle(fwSession, hSession); 569 if (CKR_OK != *pError) { 570 goto done; 571 } 572 573 *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash, 574 CKSessionHandleToVoidPtr(hSession), (const void *)fwSession); 575 if (CKR_OK != *pError) { 576 hSession = (CK_SESSION_HANDLE)0; 577 goto done; 578 } 579 580 done: 581 nssCKFWMutex_Unlock(fwInstance->mutex); 582 return hSession; 583 } 584 585 /* 586 * nssCKFWInstance_ResolveSessionHandle 587 * 588 */ 589 NSS_IMPLEMENT NSSCKFWSession * 590 nssCKFWInstance_ResolveSessionHandle( 591 NSSCKFWInstance *fwInstance, 592 CK_SESSION_HANDLE hSession) 593 { 594 NSSCKFWSession *fwSession; 595 596 #ifdef NSSDEBUG 597 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 598 return (NSSCKFWSession *)NULL; 599 } 600 #endif /* NSSDEBUG */ 601 602 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 603 return (NSSCKFWSession *)NULL; 604 } 605 606 fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup( 607 fwInstance->sessionHandleHash, CKSessionHandleToVoidPtr(hSession)); 608 609 /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */ 610 611 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 612 613 return fwSession; 614 } 615 616 /* 617 * nssCKFWInstance_DestroySessionHandle 618 * 619 */ 620 NSS_IMPLEMENT void 621 nssCKFWInstance_DestroySessionHandle( 622 NSSCKFWInstance *fwInstance, 623 CK_SESSION_HANDLE hSession) 624 { 625 NSSCKFWSession *fwSession; 626 627 #ifdef NSSDEBUG 628 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 629 return; 630 } 631 #endif /* NSSDEBUG */ 632 633 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 634 return; 635 } 636 637 fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup( 638 fwInstance->sessionHandleHash, CKSessionHandleToVoidPtr(hSession)); 639 if (fwSession) { 640 nssCKFWHash_Remove(fwInstance->sessionHandleHash, CKSessionHandleToVoidPtr(hSession)); 641 nssCKFWSession_SetHandle(fwSession, (CK_SESSION_HANDLE)0); 642 } 643 644 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 645 646 return; 647 } 648 649 /* 650 * nssCKFWInstance_FindSessionHandle 651 * 652 */ 653 NSS_IMPLEMENT CK_SESSION_HANDLE 654 nssCKFWInstance_FindSessionHandle( 655 NSSCKFWInstance *fwInstance, 656 NSSCKFWSession *fwSession) 657 { 658 #ifdef NSSDEBUG 659 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 660 return (CK_SESSION_HANDLE)0; 661 } 662 663 if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) { 664 return (CK_SESSION_HANDLE)0; 665 } 666 #endif /* NSSDEBUG */ 667 668 return nssCKFWSession_GetHandle(fwSession); 669 /* look it up and assert? */ 670 } 671 672 /* 673 * nssCKFWInstance_CreateObjectHandle 674 * 675 */ 676 NSS_IMPLEMENT CK_OBJECT_HANDLE 677 nssCKFWInstance_CreateObjectHandle( 678 NSSCKFWInstance *fwInstance, 679 NSSCKFWObject *fwObject, 680 CK_RV *pError) 681 { 682 CK_OBJECT_HANDLE hObject; 683 684 #ifdef NSSDEBUG 685 if (!pError) { 686 return (CK_OBJECT_HANDLE)0; 687 } 688 689 *pError = nssCKFWInstance_verifyPointer(fwInstance); 690 if (CKR_OK != *pError) { 691 return (CK_OBJECT_HANDLE)0; 692 } 693 #endif /* NSSDEBUG */ 694 695 *pError = nssCKFWMutex_Lock(fwInstance->mutex); 696 if (CKR_OK != *pError) { 697 return (CK_OBJECT_HANDLE)0; 698 } 699 700 hObject = ++(fwInstance->lastObjectHandle); 701 702 *pError = nssCKFWObject_SetHandle(fwObject, hObject); 703 if (CKR_OK != *pError) { 704 hObject = (CK_OBJECT_HANDLE)0; 705 goto done; 706 } 707 708 *pError = nssCKFWHash_Add(fwInstance->objectHandleHash, 709 CKSessionHandleToVoidPtr(hObject), (const void *)fwObject); 710 if (CKR_OK != *pError) { 711 hObject = (CK_OBJECT_HANDLE)0; 712 goto done; 713 } 714 715 done: 716 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 717 return hObject; 718 } 719 720 /* 721 * nssCKFWInstance_ResolveObjectHandle 722 * 723 */ 724 NSS_IMPLEMENT NSSCKFWObject * 725 nssCKFWInstance_ResolveObjectHandle( 726 NSSCKFWInstance *fwInstance, 727 CK_OBJECT_HANDLE hObject) 728 { 729 NSSCKFWObject *fwObject; 730 731 #ifdef NSSDEBUG 732 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 733 return (NSSCKFWObject *)NULL; 734 } 735 #endif /* NSSDEBUG */ 736 737 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 738 return (NSSCKFWObject *)NULL; 739 } 740 741 fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup( 742 fwInstance->objectHandleHash, CKSessionHandleToVoidPtr(hObject)); 743 744 /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */ 745 746 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 747 return fwObject; 748 } 749 750 /* 751 * nssCKFWInstance_ReassignObjectHandle 752 * 753 */ 754 NSS_IMPLEMENT CK_RV 755 nssCKFWInstance_ReassignObjectHandle( 756 NSSCKFWInstance *fwInstance, 757 CK_OBJECT_HANDLE hObject, 758 NSSCKFWObject *fwObject) 759 { 760 CK_RV error = CKR_OK; 761 NSSCKFWObject *oldObject; 762 763 #ifdef NSSDEBUG 764 error = nssCKFWInstance_verifyPointer(fwInstance); 765 if (CKR_OK != error) { 766 return error; 767 } 768 #endif /* NSSDEBUG */ 769 770 error = nssCKFWMutex_Lock(fwInstance->mutex); 771 if (CKR_OK != error) { 772 return error; 773 } 774 775 oldObject = (NSSCKFWObject *)nssCKFWHash_Lookup( 776 fwInstance->objectHandleHash, CKSessionHandleToVoidPtr(hObject)); 777 if (oldObject) { 778 /* Assert(hObject == nssCKFWObject_GetHandle(oldObject) */ 779 (void)nssCKFWObject_SetHandle(oldObject, (CK_SESSION_HANDLE)0); 780 nssCKFWHash_Remove(fwInstance->objectHandleHash, CKSessionHandleToVoidPtr(hObject)); 781 } 782 783 error = nssCKFWObject_SetHandle(fwObject, hObject); 784 if (CKR_OK != error) { 785 goto done; 786 } 787 error = nssCKFWHash_Add(fwInstance->objectHandleHash, 788 CKSessionHandleToVoidPtr(hObject), (const void *)fwObject); 789 790 done: 791 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 792 return error; 793 } 794 795 /* 796 * nssCKFWInstance_DestroyObjectHandle 797 * 798 */ 799 NSS_IMPLEMENT void 800 nssCKFWInstance_DestroyObjectHandle( 801 NSSCKFWInstance *fwInstance, 802 CK_OBJECT_HANDLE hObject) 803 { 804 NSSCKFWObject *fwObject; 805 806 #ifdef NSSDEBUG 807 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 808 return; 809 } 810 #endif /* NSSDEBUG */ 811 812 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 813 return; 814 } 815 816 fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup( 817 fwInstance->objectHandleHash, CKSessionHandleToVoidPtr(hObject)); 818 if (fwObject) { 819 /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */ 820 nssCKFWHash_Remove(fwInstance->objectHandleHash, CKSessionHandleToVoidPtr(hObject)); 821 (void)nssCKFWObject_SetHandle(fwObject, (CK_SESSION_HANDLE)0); 822 } 823 824 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 825 return; 826 } 827 828 /* 829 * nssCKFWInstance_FindObjectHandle 830 * 831 */ 832 NSS_IMPLEMENT CK_OBJECT_HANDLE 833 nssCKFWInstance_FindObjectHandle( 834 NSSCKFWInstance *fwInstance, 835 NSSCKFWObject *fwObject) 836 { 837 #ifdef NSSDEBUG 838 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 839 return (CK_OBJECT_HANDLE)0; 840 } 841 842 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) { 843 return (CK_OBJECT_HANDLE)0; 844 } 845 #endif /* NSSDEBUG */ 846 847 return nssCKFWObject_GetHandle(fwObject); 848 } 849 850 /* 851 * nssCKFWInstance_GetNSlots 852 * 853 */ 854 NSS_IMPLEMENT CK_ULONG 855 nssCKFWInstance_GetNSlots( 856 NSSCKFWInstance *fwInstance, 857 CK_RV *pError) 858 { 859 #ifdef NSSDEBUG 860 if (!pError) { 861 return (CK_ULONG)0; 862 } 863 864 *pError = nssCKFWInstance_verifyPointer(fwInstance); 865 if (CKR_OK != *pError) { 866 return (CK_ULONG)0; 867 } 868 #endif /* NSSDEBUG */ 869 870 *pError = CKR_OK; 871 return fwInstance->nSlots; 872 } 873 874 /* 875 * nssCKFWInstance_GetCryptokiVersion 876 * 877 */ 878 NSS_IMPLEMENT CK_VERSION 879 nssCKFWInstance_GetCryptokiVersion( 880 NSSCKFWInstance *fwInstance) 881 { 882 CK_VERSION rv; 883 884 #ifdef NSSDEBUG 885 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 886 rv.major = rv.minor = 0; 887 return rv; 888 } 889 #endif /* NSSDEBUG */ 890 891 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 892 rv.major = rv.minor = 0; 893 return rv; 894 } 895 896 if ((0 != fwInstance->cryptokiVersion.major) || 897 (0 != fwInstance->cryptokiVersion.minor)) { 898 rv = fwInstance->cryptokiVersion; 899 goto done; 900 } 901 902 if (fwInstance->mdInstance->GetCryptokiVersion) { 903 fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion( 904 fwInstance->mdInstance, fwInstance); 905 } else { 906 fwInstance->cryptokiVersion.major = 2; 907 fwInstance->cryptokiVersion.minor = 1; 908 } 909 910 rv = fwInstance->cryptokiVersion; 911 912 done: 913 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 914 return rv; 915 } 916 917 /* 918 * nssCKFWInstance_GetManufacturerID 919 * 920 */ 921 NSS_IMPLEMENT CK_RV 922 nssCKFWInstance_GetManufacturerID( 923 NSSCKFWInstance *fwInstance, 924 CK_CHAR manufacturerID[32]) 925 { 926 CK_RV error = CKR_OK; 927 928 #ifdef NSSDEBUG 929 if ((CK_CHAR_PTR)NULL == manufacturerID) { 930 return CKR_ARGUMENTS_BAD; 931 } 932 933 error = nssCKFWInstance_verifyPointer(fwInstance); 934 if (CKR_OK != error) { 935 return error; 936 } 937 #endif /* NSSDEBUG */ 938 939 error = nssCKFWMutex_Lock(fwInstance->mutex); 940 if (CKR_OK != error) { 941 return error; 942 } 943 944 if (!fwInstance->manufacturerID) { 945 if (fwInstance->mdInstance->GetManufacturerID) { 946 fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID( 947 fwInstance->mdInstance, fwInstance, &error); 948 if ((!fwInstance->manufacturerID) && (CKR_OK != error)) { 949 goto done; 950 } 951 } else { 952 fwInstance->manufacturerID = (NSSUTF8 *)""; 953 } 954 } 955 956 (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' '); 957 error = CKR_OK; 958 959 done: 960 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 961 return error; 962 } 963 964 /* 965 * nssCKFWInstance_GetFlags 966 * 967 */ 968 NSS_IMPLEMENT CK_ULONG 969 nssCKFWInstance_GetFlags( 970 NSSCKFWInstance *fwInstance) 971 { 972 #ifdef NSSDEBUG 973 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 974 return (CK_ULONG)0; 975 } 976 #endif /* NSSDEBUG */ 977 978 /* No "instance flags" are yet defined by Cryptoki. */ 979 return (CK_ULONG)0; 980 } 981 982 /* 983 * nssCKFWInstance_GetLibraryDescription 984 * 985 */ 986 NSS_IMPLEMENT CK_RV 987 nssCKFWInstance_GetLibraryDescription( 988 NSSCKFWInstance *fwInstance, 989 CK_CHAR libraryDescription[32]) 990 { 991 CK_RV error = CKR_OK; 992 993 #ifdef NSSDEBUG 994 if ((CK_CHAR_PTR)NULL == libraryDescription) { 995 return CKR_ARGUMENTS_BAD; 996 } 997 998 error = nssCKFWInstance_verifyPointer(fwInstance); 999 if (CKR_OK != error) { 1000 return error; 1001 } 1002 #endif /* NSSDEBUG */ 1003 1004 error = nssCKFWMutex_Lock(fwInstance->mutex); 1005 if (CKR_OK != error) { 1006 return error; 1007 } 1008 1009 if (!fwInstance->libraryDescription) { 1010 if (fwInstance->mdInstance->GetLibraryDescription) { 1011 fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription( 1012 fwInstance->mdInstance, fwInstance, &error); 1013 if ((!fwInstance->libraryDescription) && (CKR_OK != error)) { 1014 goto done; 1015 } 1016 } else { 1017 fwInstance->libraryDescription = (NSSUTF8 *)""; 1018 } 1019 } 1020 1021 (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' '); 1022 error = CKR_OK; 1023 1024 done: 1025 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 1026 return error; 1027 } 1028 1029 /* 1030 * nssCKFWInstance_GetLibraryVersion 1031 * 1032 */ 1033 NSS_IMPLEMENT CK_VERSION 1034 nssCKFWInstance_GetLibraryVersion( 1035 NSSCKFWInstance *fwInstance) 1036 { 1037 CK_VERSION rv; 1038 1039 #ifdef NSSDEBUG 1040 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1041 rv.major = rv.minor = 0; 1042 return rv; 1043 } 1044 #endif /* NSSDEBUG */ 1045 1046 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) { 1047 rv.major = rv.minor = 0; 1048 return rv; 1049 } 1050 1051 if ((0 != fwInstance->libraryVersion.major) || 1052 (0 != fwInstance->libraryVersion.minor)) { 1053 rv = fwInstance->libraryVersion; 1054 goto done; 1055 } 1056 1057 if (fwInstance->mdInstance->GetLibraryVersion) { 1058 fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion( 1059 fwInstance->mdInstance, fwInstance); 1060 } else { 1061 fwInstance->libraryVersion.major = 0; 1062 fwInstance->libraryVersion.minor = 3; 1063 } 1064 1065 rv = fwInstance->libraryVersion; 1066 done: 1067 (void)nssCKFWMutex_Unlock(fwInstance->mutex); 1068 return rv; 1069 } 1070 1071 /* 1072 * nssCKFWInstance_GetModuleHandlesSessionObjects 1073 * 1074 */ 1075 NSS_IMPLEMENT CK_BBOOL 1076 nssCKFWInstance_GetModuleHandlesSessionObjects( 1077 NSSCKFWInstance *fwInstance) 1078 { 1079 #ifdef NSSDEBUG 1080 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1081 return CK_FALSE; 1082 } 1083 #endif /* NSSDEBUG */ 1084 1085 return fwInstance->moduleHandlesSessionObjects; 1086 } 1087 1088 /* 1089 * nssCKFWInstance_GetSlots 1090 * 1091 */ 1092 NSS_IMPLEMENT NSSCKFWSlot ** 1093 nssCKFWInstance_GetSlots( 1094 NSSCKFWInstance *fwInstance, 1095 CK_RV *pError) 1096 { 1097 #ifdef NSSDEBUG 1098 if (!pError) { 1099 return (NSSCKFWSlot **)NULL; 1100 } 1101 1102 *pError = nssCKFWInstance_verifyPointer(fwInstance); 1103 if (CKR_OK != *pError) { 1104 return (NSSCKFWSlot **)NULL; 1105 } 1106 #endif /* NSSDEBUG */ 1107 1108 return fwInstance->fwSlotList; 1109 } 1110 1111 /* 1112 * nssCKFWInstance_WaitForSlotEvent 1113 * 1114 */ 1115 NSS_IMPLEMENT NSSCKFWSlot * 1116 nssCKFWInstance_WaitForSlotEvent( 1117 NSSCKFWInstance *fwInstance, 1118 CK_BBOOL block, 1119 CK_RV *pError) 1120 { 1121 NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL; 1122 NSSCKMDSlot *mdSlot; 1123 CK_ULONG i, n; 1124 1125 #ifdef NSSDEBUG 1126 if (!pError) { 1127 return (NSSCKFWSlot *)NULL; 1128 } 1129 1130 *pError = nssCKFWInstance_verifyPointer(fwInstance); 1131 if (CKR_OK != *pError) { 1132 return (NSSCKFWSlot *)NULL; 1133 } 1134 1135 switch (block) { 1136 case CK_TRUE: 1137 case CK_FALSE: 1138 break; 1139 default: 1140 *pError = CKR_ARGUMENTS_BAD; 1141 return (NSSCKFWSlot *)NULL; 1142 } 1143 #endif /* NSSDEBUG */ 1144 1145 if (!fwInstance->mdInstance->WaitForSlotEvent) { 1146 *pError = CKR_NO_EVENT; 1147 return (NSSCKFWSlot *)NULL; 1148 } 1149 1150 mdSlot = fwInstance->mdInstance->WaitForSlotEvent( 1151 fwInstance->mdInstance, 1152 fwInstance, 1153 block, 1154 pError); 1155 1156 if (!mdSlot) { 1157 return (NSSCKFWSlot *)NULL; 1158 } 1159 1160 n = nssCKFWInstance_GetNSlots(fwInstance, pError); 1161 if (((CK_ULONG)0 == n) && (CKR_OK != *pError)) { 1162 return (NSSCKFWSlot *)NULL; 1163 } 1164 1165 for (i = 0; i < n; i++) { 1166 if (fwInstance->mdSlotList[i] == mdSlot) { 1167 fwSlot = fwInstance->fwSlotList[i]; 1168 break; 1169 } 1170 } 1171 1172 if (!fwSlot) { 1173 /* Internal error */ 1174 *pError = CKR_GENERAL_ERROR; 1175 return (NSSCKFWSlot *)NULL; 1176 } 1177 1178 return fwSlot; 1179 } 1180 1181 /* 1182 * NSSCKFWInstance_GetMDInstance 1183 * 1184 */ 1185 NSS_IMPLEMENT NSSCKMDInstance * 1186 NSSCKFWInstance_GetMDInstance( 1187 NSSCKFWInstance *fwInstance) 1188 { 1189 #ifdef DEBUG 1190 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1191 return (NSSCKMDInstance *)NULL; 1192 } 1193 #endif /* DEBUG */ 1194 1195 return nssCKFWInstance_GetMDInstance(fwInstance); 1196 } 1197 1198 /* 1199 * NSSCKFWInstance_GetArena 1200 * 1201 */ 1202 NSS_IMPLEMENT NSSArena * 1203 NSSCKFWInstance_GetArena( 1204 NSSCKFWInstance *fwInstance, 1205 CK_RV *pError) 1206 { 1207 #ifdef DEBUG 1208 if (!pError) { 1209 return (NSSArena *)NULL; 1210 } 1211 1212 *pError = nssCKFWInstance_verifyPointer(fwInstance); 1213 if (CKR_OK != *pError) { 1214 return (NSSArena *)NULL; 1215 } 1216 #endif /* DEBUG */ 1217 1218 return nssCKFWInstance_GetArena(fwInstance, pError); 1219 } 1220 1221 /* 1222 * NSSCKFWInstance_MayCreatePthreads 1223 * 1224 */ 1225 NSS_IMPLEMENT CK_BBOOL 1226 NSSCKFWInstance_MayCreatePthreads( 1227 NSSCKFWInstance *fwInstance) 1228 { 1229 #ifdef DEBUG 1230 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1231 return CK_FALSE; 1232 } 1233 #endif /* DEBUG */ 1234 1235 return nssCKFWInstance_MayCreatePthreads(fwInstance); 1236 } 1237 1238 /* 1239 * NSSCKFWInstance_CreateMutex 1240 * 1241 */ 1242 NSS_IMPLEMENT NSSCKFWMutex * 1243 NSSCKFWInstance_CreateMutex( 1244 NSSCKFWInstance *fwInstance, 1245 NSSArena *arena, 1246 CK_RV *pError) 1247 { 1248 #ifdef DEBUG 1249 if (!pError) { 1250 return (NSSCKFWMutex *)NULL; 1251 } 1252 1253 *pError = nssCKFWInstance_verifyPointer(fwInstance); 1254 if (CKR_OK != *pError) { 1255 return (NSSCKFWMutex *)NULL; 1256 } 1257 #endif /* DEBUG */ 1258 1259 return nssCKFWInstance_CreateMutex(fwInstance, arena, pError); 1260 } 1261 1262 /* 1263 * NSSCKFWInstance_GetConfigurationData 1264 * 1265 */ 1266 NSS_IMPLEMENT NSSUTF8 * 1267 NSSCKFWInstance_GetConfigurationData( 1268 NSSCKFWInstance *fwInstance) 1269 { 1270 #ifdef DEBUG 1271 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1272 return (NSSUTF8 *)NULL; 1273 } 1274 #endif /* DEBUG */ 1275 1276 return nssCKFWInstance_GetConfigurationData(fwInstance); 1277 } 1278 1279 /* 1280 * NSSCKFWInstance_GetInitArgs 1281 * 1282 */ 1283 NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR 1284 NSSCKFWInstance_GetInitArgs( 1285 NSSCKFWInstance *fwInstance) 1286 { 1287 #ifdef DEBUG 1288 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) { 1289 return (CK_C_INITIALIZE_ARGS_PTR)NULL; 1290 } 1291 #endif /* DEBUG */ 1292 1293 return nssCKFWInstance_GetInitArgs(fwInstance); 1294 } 1295 1296 /* 1297 * nssCKFWInstance_DestroySessionHandle 1298 * 1299 */ 1300 NSS_IMPLEMENT void 1301 NSSCKFWInstance_DestroySessionHandle( 1302 NSSCKFWInstance *fwInstance, 1303 CK_SESSION_HANDLE hSession) 1304 { 1305 nssCKFWInstance_DestroySessionHandle(fwInstance, hSession); 1306 } 1307 1308 /* 1309 * nssCKFWInstance_FindSessionHandle 1310 * 1311 */ 1312 NSS_IMPLEMENT CK_SESSION_HANDLE 1313 NSSCKFWInstance_FindSessionHandle( 1314 NSSCKFWInstance *fwInstance, 1315 NSSCKFWSession *fwSession) 1316 { 1317 return nssCKFWInstance_FindSessionHandle(fwInstance, fwSession); 1318 }