token.c (42635B)
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 * token.c 7 * 8 * This file implements the NSSCKFWToken type and methods. 9 */ 10 11 #ifndef CK_T 12 #include "ck.h" 13 #endif /* CK_T */ 14 15 /* 16 * NSSCKFWToken 17 * 18 * -- create/destroy -- 19 * nssCKFWToken_Create 20 * nssCKFWToken_Destroy 21 * 22 * -- public accessors -- 23 * NSSCKFWToken_GetMDToken 24 * NSSCKFWToken_GetFWSlot 25 * NSSCKFWToken_GetMDSlot 26 * NSSCKFWToken_GetSessionState 27 * 28 * -- implement public accessors -- 29 * nssCKFWToken_GetMDToken 30 * nssCKFWToken_GetFWSlot 31 * nssCKFWToken_GetMDSlot 32 * nssCKFWToken_GetSessionState 33 * nssCKFWToken_SetSessionState 34 * 35 * -- private accessors -- 36 * nssCKFWToken_SetSessionState 37 * nssCKFWToken_RemoveSession 38 * nssCKFWToken_CloseAllSessions 39 * nssCKFWToken_GetSessionCount 40 * nssCKFWToken_GetRwSessionCount 41 * nssCKFWToken_GetRoSessionCount 42 * nssCKFWToken_GetSessionObjectHash 43 * nssCKFWToken_GetMDObjectHash 44 * nssCKFWToken_GetObjectHandleHash 45 * 46 * -- module fronts -- 47 * nssCKFWToken_InitToken 48 * nssCKFWToken_GetLabel 49 * nssCKFWToken_GetManufacturerID 50 * nssCKFWToken_GetModel 51 * nssCKFWToken_GetSerialNumber 52 * nssCKFWToken_GetHasRNG 53 * nssCKFWToken_GetIsWriteProtected 54 * nssCKFWToken_GetLoginRequired 55 * nssCKFWToken_GetUserPinInitialized 56 * nssCKFWToken_GetRestoreKeyNotNeeded 57 * nssCKFWToken_GetHasClockOnToken 58 * nssCKFWToken_GetHasProtectedAuthenticationPath 59 * nssCKFWToken_GetSupportsDualCryptoOperations 60 * nssCKFWToken_GetMaxSessionCount 61 * nssCKFWToken_GetMaxRwSessionCount 62 * nssCKFWToken_GetMaxPinLen 63 * nssCKFWToken_GetMinPinLen 64 * nssCKFWToken_GetTotalPublicMemory 65 * nssCKFWToken_GetFreePublicMemory 66 * nssCKFWToken_GetTotalPrivateMemory 67 * nssCKFWToken_GetFreePrivateMemory 68 * nssCKFWToken_GetHardwareVersion 69 * nssCKFWToken_GetFirmwareVersion 70 * nssCKFWToken_GetUTCTime 71 * nssCKFWToken_OpenSession 72 * nssCKFWToken_GetMechanismCount 73 * nssCKFWToken_GetMechanismTypes 74 * nssCKFWToken_GetMechanism 75 */ 76 77 struct NSSCKFWTokenStr { 78 NSSCKFWMutex *mutex; 79 NSSArena *arena; 80 NSSCKMDToken *mdToken; 81 NSSCKFWSlot *fwSlot; 82 NSSCKMDSlot *mdSlot; 83 NSSCKFWInstance *fwInstance; 84 NSSCKMDInstance *mdInstance; 85 86 /* 87 * Everything above is set at creation time, and then not modified. 88 * The invariants the mutex protects are: 89 * 90 * 1) Each of the cached descriptions (versions, etc.) are in an 91 * internally consistant state. 92 * 93 * 2) The session counts and hashes are consistant. 94 * 95 * 3) The object hashes are consistant. 96 * 97 * Note that the calls accessing the cached descriptions will call 98 * the NSSCKMDToken methods with the mutex locked. Those methods 99 * may then call the public NSSCKFWToken routines. Those public 100 * routines only access the constant data above and the atomic 101 * CK_STATE session state variable below, so there's no problem. 102 * But be careful if you add to this object; mutexes are in 103 * general not reentrant, so don't create deadlock situations. 104 */ 105 106 NSSUTF8 *label; 107 NSSUTF8 *manufacturerID; 108 NSSUTF8 *model; 109 NSSUTF8 *serialNumber; 110 CK_VERSION hardwareVersion; 111 CK_VERSION firmwareVersion; 112 113 CK_ULONG sessionCount; 114 CK_ULONG rwSessionCount; 115 nssCKFWHash *sessions; 116 nssCKFWHash *sessionObjectHash; 117 nssCKFWHash *mdObjectHash; 118 nssCKFWHash *mdMechanismHash; 119 120 CK_STATE state; 121 }; 122 123 #ifdef DEBUG 124 /* 125 * But first, the pointer-tracking stuff. 126 * 127 * NOTE: the pointer-tracking support in NSS/base currently relies 128 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 129 * locking, which is tied into the runtime. We need a pointer-tracker 130 * implementation that uses the locks supplied through C_Initialize. 131 * That support, however, can be filled in later. So for now, I'll 132 * just do this routines as no-ops. 133 */ 134 135 static CK_RV 136 token_add_pointer( 137 const NSSCKFWToken *fwToken) 138 { 139 return CKR_OK; 140 } 141 142 static CK_RV 143 token_remove_pointer( 144 const NSSCKFWToken *fwToken) 145 { 146 return CKR_OK; 147 } 148 149 NSS_IMPLEMENT CK_RV 150 nssCKFWToken_verifyPointer( 151 const NSSCKFWToken *fwToken) 152 { 153 return CKR_OK; 154 } 155 156 #endif /* DEBUG */ 157 158 /* 159 * nssCKFWToken_Create 160 * 161 */ 162 NSS_IMPLEMENT NSSCKFWToken * 163 nssCKFWToken_Create( 164 NSSCKFWSlot *fwSlot, 165 NSSCKMDToken *mdToken, 166 CK_RV *pError) 167 { 168 NSSArena *arena = (NSSArena *)NULL; 169 NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; 170 CK_BBOOL called_setup = CK_FALSE; 171 172 /* 173 * We have already verified the arguments in nssCKFWSlot_GetToken. 174 */ 175 176 arena = NSSArena_Create(); 177 if (!arena) { 178 *pError = CKR_HOST_MEMORY; 179 goto loser; 180 } 181 182 fwToken = nss_ZNEW(arena, NSSCKFWToken); 183 if (!fwToken) { 184 *pError = CKR_HOST_MEMORY; 185 goto loser; 186 } 187 188 fwToken->arena = arena; 189 fwToken->mdToken = mdToken; 190 fwToken->fwSlot = fwSlot; 191 fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot); 192 fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot); 193 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ 194 fwToken->sessionCount = 0; 195 fwToken->rwSessionCount = 0; 196 197 fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError); 198 if (!fwToken->mutex) { 199 if (CKR_OK == *pError) { 200 *pError = CKR_GENERAL_ERROR; 201 } 202 goto loser; 203 } 204 205 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError); 206 if (!fwToken->sessions) { 207 if (CKR_OK == *pError) { 208 *pError = CKR_GENERAL_ERROR; 209 } 210 goto loser; 211 } 212 213 if (CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects( 214 fwToken->fwInstance)) { 215 fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 216 arena, pError); 217 if (!fwToken->sessionObjectHash) { 218 if (CKR_OK == *pError) { 219 *pError = CKR_GENERAL_ERROR; 220 } 221 goto loser; 222 } 223 } 224 225 fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 226 arena, pError); 227 if (!fwToken->mdObjectHash) { 228 if (CKR_OK == *pError) { 229 *pError = CKR_GENERAL_ERROR; 230 } 231 goto loser; 232 } 233 234 fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance, 235 arena, pError); 236 if (!fwToken->mdMechanismHash) { 237 if (CKR_OK == *pError) { 238 *pError = CKR_GENERAL_ERROR; 239 } 240 goto loser; 241 } 242 243 /* More here */ 244 245 if (mdToken->Setup) { 246 *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); 247 if (CKR_OK != *pError) { 248 goto loser; 249 } 250 } 251 252 called_setup = CK_TRUE; 253 254 #ifdef DEBUG 255 *pError = token_add_pointer(fwToken); 256 if (CKR_OK != *pError) { 257 goto loser; 258 } 259 #endif /* DEBUG */ 260 261 *pError = CKR_OK; 262 return fwToken; 263 264 loser: 265 266 if (CK_TRUE == called_setup) { 267 if (mdToken->Invalidate) { 268 mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); 269 } 270 } 271 272 if (arena) { 273 (void)NSSArena_Destroy(arena); 274 } 275 276 return (NSSCKFWToken *)NULL; 277 } 278 279 static void 280 nss_ckfwtoken_session_iterator( 281 const void *key, 282 void *value, 283 void *closure) 284 { 285 /* 286 * Remember that the fwToken->mutex is locked 287 */ 288 NSSCKFWSession *fwSession = (NSSCKFWSession *)value; 289 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); 290 return; 291 } 292 293 static void 294 nss_ckfwtoken_object_iterator( 295 const void *key, 296 void *value, 297 void *closure) 298 { 299 /* 300 * Remember that the fwToken->mutex is locked 301 */ 302 NSSCKFWObject *fwObject = (NSSCKFWObject *)value; 303 (void)nssCKFWObject_Finalize(fwObject, CK_FALSE); 304 return; 305 } 306 307 /* 308 * nssCKFWToken_Destroy 309 * 310 */ 311 NSS_IMPLEMENT CK_RV 312 nssCKFWToken_Destroy( 313 NSSCKFWToken *fwToken) 314 { 315 CK_RV error = CKR_OK; 316 317 #ifdef NSSDEBUG 318 error = nssCKFWToken_verifyPointer(fwToken); 319 if (CKR_OK != error) { 320 return error; 321 } 322 #endif /* NSSDEBUG */ 323 324 (void)nssCKFWMutex_Destroy(fwToken->mutex); 325 326 if (fwToken->mdToken->Invalidate) { 327 fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken, 328 fwToken->mdInstance, fwToken->fwInstance); 329 } 330 /* we can destroy the list without locking now because no one else is 331 * referencing us (or _Destroy was invalidly called!) 332 */ 333 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, 334 (void *)NULL); 335 nssCKFWHash_Destroy(fwToken->sessions); 336 337 /* session objects go away when their sessions are removed */ 338 if (fwToken->sessionObjectHash) { 339 nssCKFWHash_Destroy(fwToken->sessionObjectHash); 340 } 341 342 /* free up the token objects */ 343 if (fwToken->mdObjectHash) { 344 nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator, 345 (void *)NULL); 346 nssCKFWHash_Destroy(fwToken->mdObjectHash); 347 } 348 if (fwToken->mdMechanismHash) { 349 nssCKFWHash_Destroy(fwToken->mdMechanismHash); 350 } 351 352 nssCKFWSlot_ClearToken(fwToken->fwSlot); 353 354 #ifdef DEBUG 355 error = token_remove_pointer(fwToken); 356 #endif /* DEBUG */ 357 358 (void)NSSArena_Destroy(fwToken->arena); 359 return error; 360 } 361 362 /* 363 * nssCKFWToken_GetMDToken 364 * 365 */ 366 NSS_IMPLEMENT NSSCKMDToken * 367 nssCKFWToken_GetMDToken( 368 NSSCKFWToken *fwToken) 369 { 370 #ifdef NSSDEBUG 371 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 372 return (NSSCKMDToken *)NULL; 373 } 374 #endif /* NSSDEBUG */ 375 376 return fwToken->mdToken; 377 } 378 379 /* 380 * nssCKFWToken_GetArena 381 * 382 */ 383 NSS_IMPLEMENT NSSArena * 384 nssCKFWToken_GetArena( 385 NSSCKFWToken *fwToken, 386 CK_RV *pError) 387 { 388 #ifdef NSSDEBUG 389 if (!pError) { 390 return (NSSArena *)NULL; 391 } 392 393 *pError = nssCKFWToken_verifyPointer(fwToken); 394 if (CKR_OK != *pError) { 395 return (NSSArena *)NULL; 396 } 397 #endif /* NSSDEBUG */ 398 399 return fwToken->arena; 400 } 401 402 /* 403 * nssCKFWToken_GetFWSlot 404 * 405 */ 406 NSS_IMPLEMENT NSSCKFWSlot * 407 nssCKFWToken_GetFWSlot( 408 NSSCKFWToken *fwToken) 409 { 410 #ifdef NSSDEBUG 411 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 412 return (NSSCKFWSlot *)NULL; 413 } 414 #endif /* NSSDEBUG */ 415 416 return fwToken->fwSlot; 417 } 418 419 /* 420 * nssCKFWToken_GetMDSlot 421 * 422 */ 423 NSS_IMPLEMENT NSSCKMDSlot * 424 nssCKFWToken_GetMDSlot( 425 NSSCKFWToken *fwToken) 426 { 427 #ifdef NSSDEBUG 428 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 429 return (NSSCKMDSlot *)NULL; 430 } 431 #endif /* NSSDEBUG */ 432 433 return fwToken->mdSlot; 434 } 435 436 /* 437 * nssCKFWToken_GetSessionState 438 * 439 */ 440 NSS_IMPLEMENT CK_STATE 441 nssCKFWToken_GetSessionState( 442 NSSCKFWToken *fwToken) 443 { 444 #ifdef NSSDEBUG 445 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 446 return CKS_RO_PUBLIC_SESSION; /* whatever */ 447 } 448 #endif /* NSSDEBUG */ 449 450 /* 451 * BTW, do not lock the token in this method. 452 */ 453 454 /* 455 * Theoretically, there is no state if there aren't any 456 * sessions open. But then we'd need to worry about 457 * reporting an error, etc. What the heck-- let's just 458 * revert to CKR_RO_PUBLIC_SESSION as the "default." 459 */ 460 461 return fwToken->state; 462 } 463 464 /* 465 * nssCKFWToken_InitToken 466 * 467 */ 468 NSS_IMPLEMENT CK_RV 469 nssCKFWToken_InitToken( 470 NSSCKFWToken *fwToken, 471 NSSItem *pin, 472 NSSUTF8 *label) 473 { 474 CK_RV error; 475 476 #ifdef NSSDEBUG 477 error = nssCKFWToken_verifyPointer(fwToken); 478 if (CKR_OK != error) { 479 return CKR_ARGUMENTS_BAD; 480 } 481 #endif /* NSSDEBUG */ 482 483 error = nssCKFWMutex_Lock(fwToken->mutex); 484 if (CKR_OK != error) { 485 return error; 486 } 487 488 if (fwToken->sessionCount > 0) { 489 error = CKR_SESSION_EXISTS; 490 goto done; 491 } 492 493 if (!fwToken->mdToken->InitToken) { 494 error = CKR_DEVICE_ERROR; 495 goto done; 496 } 497 498 if (!pin) { 499 if (nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken)) { 500 ; /* okay */ 501 } else { 502 error = CKR_PIN_INCORRECT; 503 goto done; 504 } 505 } 506 507 if (!label) { 508 label = (NSSUTF8 *)""; 509 } 510 511 error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken, 512 fwToken->mdInstance, fwToken->fwInstance, pin, label); 513 514 done: 515 (void)nssCKFWMutex_Unlock(fwToken->mutex); 516 return error; 517 } 518 519 /* 520 * nssCKFWToken_GetLabel 521 * 522 */ 523 NSS_IMPLEMENT CK_RV 524 nssCKFWToken_GetLabel( 525 NSSCKFWToken *fwToken, 526 CK_CHAR label[32]) 527 { 528 CK_RV error = CKR_OK; 529 530 #ifdef NSSDEBUG 531 if ((CK_CHAR_PTR)NULL == label) { 532 return CKR_ARGUMENTS_BAD; 533 } 534 535 error = nssCKFWToken_verifyPointer(fwToken); 536 if (CKR_OK != error) { 537 return error; 538 } 539 #endif /* NSSDEBUG */ 540 541 error = nssCKFWMutex_Lock(fwToken->mutex); 542 if (CKR_OK != error) { 543 return error; 544 } 545 546 if (!fwToken->label) { 547 if (fwToken->mdToken->GetLabel) { 548 fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken, 549 fwToken->mdInstance, fwToken->fwInstance, &error); 550 if ((!fwToken->label) && (CKR_OK != error)) { 551 goto done; 552 } 553 } else { 554 fwToken->label = (NSSUTF8 *)""; 555 } 556 } 557 558 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' '); 559 error = CKR_OK; 560 561 done: 562 (void)nssCKFWMutex_Unlock(fwToken->mutex); 563 return error; 564 } 565 566 /* 567 * nssCKFWToken_GetManufacturerID 568 * 569 */ 570 NSS_IMPLEMENT CK_RV 571 nssCKFWToken_GetManufacturerID( 572 NSSCKFWToken *fwToken, 573 CK_CHAR manufacturerID[32]) 574 { 575 CK_RV error = CKR_OK; 576 577 #ifdef NSSDEBUG 578 if ((CK_CHAR_PTR)NULL == manufacturerID) { 579 return CKR_ARGUMENTS_BAD; 580 } 581 582 error = nssCKFWToken_verifyPointer(fwToken); 583 if (CKR_OK != error) { 584 return error; 585 } 586 #endif /* NSSDEBUG */ 587 588 error = nssCKFWMutex_Lock(fwToken->mutex); 589 if (CKR_OK != error) { 590 return error; 591 } 592 593 if (!fwToken->manufacturerID) { 594 if (fwToken->mdToken->GetManufacturerID) { 595 fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken, 596 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); 597 if ((!fwToken->manufacturerID) && (CKR_OK != error)) { 598 goto done; 599 } 600 } else { 601 fwToken->manufacturerID = (NSSUTF8 *)""; 602 } 603 } 604 605 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' '); 606 error = CKR_OK; 607 608 done: 609 (void)nssCKFWMutex_Unlock(fwToken->mutex); 610 return error; 611 } 612 613 /* 614 * nssCKFWToken_GetModel 615 * 616 */ 617 NSS_IMPLEMENT CK_RV 618 nssCKFWToken_GetModel( 619 NSSCKFWToken *fwToken, 620 CK_CHAR model[16]) 621 { 622 CK_RV error = CKR_OK; 623 624 #ifdef NSSDEBUG 625 if ((CK_CHAR_PTR)NULL == model) { 626 return CKR_ARGUMENTS_BAD; 627 } 628 629 error = nssCKFWToken_verifyPointer(fwToken); 630 if (CKR_OK != error) { 631 return error; 632 } 633 #endif /* NSSDEBUG */ 634 635 error = nssCKFWMutex_Lock(fwToken->mutex); 636 if (CKR_OK != error) { 637 return error; 638 } 639 640 if (!fwToken->model) { 641 if (fwToken->mdToken->GetModel) { 642 fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken, 643 fwToken->mdInstance, fwToken->fwInstance, &error); 644 if ((!fwToken->model) && (CKR_OK != error)) { 645 goto done; 646 } 647 } else { 648 fwToken->model = (NSSUTF8 *)""; 649 } 650 } 651 652 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' '); 653 error = CKR_OK; 654 655 done: 656 (void)nssCKFWMutex_Unlock(fwToken->mutex); 657 return error; 658 } 659 660 /* 661 * nssCKFWToken_GetSerialNumber 662 * 663 */ 664 NSS_IMPLEMENT CK_RV 665 nssCKFWToken_GetSerialNumber( 666 NSSCKFWToken *fwToken, 667 CK_CHAR serialNumber[16]) 668 { 669 CK_RV error = CKR_OK; 670 671 #ifdef NSSDEBUG 672 if ((CK_CHAR_PTR)NULL == serialNumber) { 673 return CKR_ARGUMENTS_BAD; 674 } 675 676 error = nssCKFWToken_verifyPointer(fwToken); 677 if (CKR_OK != error) { 678 return error; 679 } 680 #endif /* NSSDEBUG */ 681 682 error = nssCKFWMutex_Lock(fwToken->mutex); 683 if (CKR_OK != error) { 684 return error; 685 } 686 687 if (!fwToken->serialNumber) { 688 if (fwToken->mdToken->GetSerialNumber) { 689 fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken, 690 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); 691 if ((!fwToken->serialNumber) && (CKR_OK != error)) { 692 goto done; 693 } 694 } else { 695 fwToken->serialNumber = (NSSUTF8 *)""; 696 } 697 } 698 699 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' '); 700 error = CKR_OK; 701 702 done: 703 (void)nssCKFWMutex_Unlock(fwToken->mutex); 704 return error; 705 } 706 707 /* 708 * nssCKFWToken_GetHasRNG 709 * 710 */ 711 NSS_IMPLEMENT CK_BBOOL 712 nssCKFWToken_GetHasRNG( 713 NSSCKFWToken *fwToken) 714 { 715 #ifdef NSSDEBUG 716 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 717 return CK_FALSE; 718 } 719 #endif /* NSSDEBUG */ 720 721 if (!fwToken->mdToken->GetHasRNG) { 722 return CK_FALSE; 723 } 724 725 return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, 726 fwToken->mdInstance, fwToken->fwInstance); 727 } 728 729 /* 730 * nssCKFWToken_GetIsWriteProtected 731 * 732 */ 733 NSS_IMPLEMENT CK_BBOOL 734 nssCKFWToken_GetIsWriteProtected( 735 NSSCKFWToken *fwToken) 736 { 737 #ifdef NSSDEBUG 738 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 739 return CK_FALSE; 740 } 741 #endif /* NSSDEBUG */ 742 743 if (!fwToken->mdToken->GetIsWriteProtected) { 744 return CK_FALSE; 745 } 746 747 return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, 748 fwToken->mdInstance, fwToken->fwInstance); 749 } 750 751 /* 752 * nssCKFWToken_GetLoginRequired 753 * 754 */ 755 NSS_IMPLEMENT CK_BBOOL 756 nssCKFWToken_GetLoginRequired( 757 NSSCKFWToken *fwToken) 758 { 759 #ifdef NSSDEBUG 760 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 761 return CK_FALSE; 762 } 763 #endif /* NSSDEBUG */ 764 765 if (!fwToken->mdToken->GetLoginRequired) { 766 return CK_FALSE; 767 } 768 769 return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, 770 fwToken->mdInstance, fwToken->fwInstance); 771 } 772 773 /* 774 * nssCKFWToken_GetUserPinInitialized 775 * 776 */ 777 NSS_IMPLEMENT CK_BBOOL 778 nssCKFWToken_GetUserPinInitialized( 779 NSSCKFWToken *fwToken) 780 { 781 #ifdef NSSDEBUG 782 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 783 return CK_FALSE; 784 } 785 #endif /* NSSDEBUG */ 786 787 if (!fwToken->mdToken->GetUserPinInitialized) { 788 return CK_FALSE; 789 } 790 791 return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, 792 fwToken->mdInstance, fwToken->fwInstance); 793 } 794 795 /* 796 * nssCKFWToken_GetRestoreKeyNotNeeded 797 * 798 */ 799 NSS_IMPLEMENT CK_BBOOL 800 nssCKFWToken_GetRestoreKeyNotNeeded( 801 NSSCKFWToken *fwToken) 802 { 803 #ifdef NSSDEBUG 804 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 805 return CK_FALSE; 806 } 807 #endif /* NSSDEBUG */ 808 809 if (!fwToken->mdToken->GetRestoreKeyNotNeeded) { 810 return CK_FALSE; 811 } 812 813 return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, 814 fwToken->mdInstance, fwToken->fwInstance); 815 } 816 817 /* 818 * nssCKFWToken_GetHasClockOnToken 819 * 820 */ 821 NSS_IMPLEMENT CK_BBOOL 822 nssCKFWToken_GetHasClockOnToken( 823 NSSCKFWToken *fwToken) 824 { 825 #ifdef NSSDEBUG 826 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 827 return CK_FALSE; 828 } 829 #endif /* NSSDEBUG */ 830 831 if (!fwToken->mdToken->GetHasClockOnToken) { 832 return CK_FALSE; 833 } 834 835 return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, 836 fwToken->mdInstance, fwToken->fwInstance); 837 } 838 839 /* 840 * nssCKFWToken_GetHasProtectedAuthenticationPath 841 * 842 */ 843 NSS_IMPLEMENT CK_BBOOL 844 nssCKFWToken_GetHasProtectedAuthenticationPath( 845 NSSCKFWToken *fwToken) 846 { 847 #ifdef NSSDEBUG 848 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 849 return CK_FALSE; 850 } 851 #endif /* NSSDEBUG */ 852 853 if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) { 854 return CK_FALSE; 855 } 856 857 return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, 858 fwToken, fwToken->mdInstance, fwToken->fwInstance); 859 } 860 861 /* 862 * nssCKFWToken_GetSupportsDualCryptoOperations 863 * 864 */ 865 NSS_IMPLEMENT CK_BBOOL 866 nssCKFWToken_GetSupportsDualCryptoOperations( 867 NSSCKFWToken *fwToken) 868 { 869 #ifdef NSSDEBUG 870 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 871 return CK_FALSE; 872 } 873 #endif /* NSSDEBUG */ 874 875 if (!fwToken->mdToken->GetSupportsDualCryptoOperations) { 876 return CK_FALSE; 877 } 878 879 return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, 880 fwToken, fwToken->mdInstance, fwToken->fwInstance); 881 } 882 883 /* 884 * nssCKFWToken_GetMaxSessionCount 885 * 886 */ 887 NSS_IMPLEMENT CK_ULONG 888 nssCKFWToken_GetMaxSessionCount( 889 NSSCKFWToken *fwToken) 890 { 891 #ifdef NSSDEBUG 892 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 893 return CK_UNAVAILABLE_INFORMATION; 894 } 895 #endif /* NSSDEBUG */ 896 897 if (!fwToken->mdToken->GetMaxSessionCount) { 898 return CK_UNAVAILABLE_INFORMATION; 899 } 900 901 return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, 902 fwToken->mdInstance, fwToken->fwInstance); 903 } 904 905 /* 906 * nssCKFWToken_GetMaxRwSessionCount 907 * 908 */ 909 NSS_IMPLEMENT CK_ULONG 910 nssCKFWToken_GetMaxRwSessionCount( 911 NSSCKFWToken *fwToken) 912 { 913 #ifdef NSSDEBUG 914 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 915 return CK_UNAVAILABLE_INFORMATION; 916 } 917 #endif /* NSSDEBUG */ 918 919 if (!fwToken->mdToken->GetMaxRwSessionCount) { 920 return CK_UNAVAILABLE_INFORMATION; 921 } 922 923 return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, 924 fwToken->mdInstance, fwToken->fwInstance); 925 } 926 927 /* 928 * nssCKFWToken_GetMaxPinLen 929 * 930 */ 931 NSS_IMPLEMENT CK_ULONG 932 nssCKFWToken_GetMaxPinLen( 933 NSSCKFWToken *fwToken) 934 { 935 #ifdef NSSDEBUG 936 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 937 return CK_UNAVAILABLE_INFORMATION; 938 } 939 #endif /* NSSDEBUG */ 940 941 if (!fwToken->mdToken->GetMaxPinLen) { 942 return CK_UNAVAILABLE_INFORMATION; 943 } 944 945 return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, 946 fwToken->mdInstance, fwToken->fwInstance); 947 } 948 949 /* 950 * nssCKFWToken_GetMinPinLen 951 * 952 */ 953 NSS_IMPLEMENT CK_ULONG 954 nssCKFWToken_GetMinPinLen( 955 NSSCKFWToken *fwToken) 956 { 957 #ifdef NSSDEBUG 958 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 959 return CK_UNAVAILABLE_INFORMATION; 960 } 961 #endif /* NSSDEBUG */ 962 963 if (!fwToken->mdToken->GetMinPinLen) { 964 return CK_UNAVAILABLE_INFORMATION; 965 } 966 967 return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, 968 fwToken->mdInstance, fwToken->fwInstance); 969 } 970 971 /* 972 * nssCKFWToken_GetTotalPublicMemory 973 * 974 */ 975 NSS_IMPLEMENT CK_ULONG 976 nssCKFWToken_GetTotalPublicMemory( 977 NSSCKFWToken *fwToken) 978 { 979 #ifdef NSSDEBUG 980 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 981 return CK_UNAVAILABLE_INFORMATION; 982 } 983 #endif /* NSSDEBUG */ 984 985 if (!fwToken->mdToken->GetTotalPublicMemory) { 986 return CK_UNAVAILABLE_INFORMATION; 987 } 988 989 return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, 990 fwToken->mdInstance, fwToken->fwInstance); 991 } 992 993 /* 994 * nssCKFWToken_GetFreePublicMemory 995 * 996 */ 997 NSS_IMPLEMENT CK_ULONG 998 nssCKFWToken_GetFreePublicMemory( 999 NSSCKFWToken *fwToken) 1000 { 1001 #ifdef NSSDEBUG 1002 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1003 return CK_UNAVAILABLE_INFORMATION; 1004 } 1005 #endif /* NSSDEBUG */ 1006 1007 if (!fwToken->mdToken->GetFreePublicMemory) { 1008 return CK_UNAVAILABLE_INFORMATION; 1009 } 1010 1011 return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, 1012 fwToken->mdInstance, fwToken->fwInstance); 1013 } 1014 1015 /* 1016 * nssCKFWToken_GetTotalPrivateMemory 1017 * 1018 */ 1019 NSS_IMPLEMENT CK_ULONG 1020 nssCKFWToken_GetTotalPrivateMemory( 1021 NSSCKFWToken *fwToken) 1022 { 1023 #ifdef NSSDEBUG 1024 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1025 return CK_UNAVAILABLE_INFORMATION; 1026 } 1027 #endif /* NSSDEBUG */ 1028 1029 if (!fwToken->mdToken->GetTotalPrivateMemory) { 1030 return CK_UNAVAILABLE_INFORMATION; 1031 } 1032 1033 return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, 1034 fwToken->mdInstance, fwToken->fwInstance); 1035 } 1036 1037 /* 1038 * nssCKFWToken_GetFreePrivateMemory 1039 * 1040 */ 1041 NSS_IMPLEMENT CK_ULONG 1042 nssCKFWToken_GetFreePrivateMemory( 1043 NSSCKFWToken *fwToken) 1044 { 1045 #ifdef NSSDEBUG 1046 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1047 return CK_UNAVAILABLE_INFORMATION; 1048 } 1049 #endif /* NSSDEBUG */ 1050 1051 if (!fwToken->mdToken->GetFreePrivateMemory) { 1052 return CK_UNAVAILABLE_INFORMATION; 1053 } 1054 1055 return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, 1056 fwToken->mdInstance, fwToken->fwInstance); 1057 } 1058 1059 /* 1060 * nssCKFWToken_GetHardwareVersion 1061 * 1062 */ 1063 NSS_IMPLEMENT CK_VERSION 1064 nssCKFWToken_GetHardwareVersion( 1065 NSSCKFWToken *fwToken) 1066 { 1067 CK_VERSION rv; 1068 1069 #ifdef NSSDEBUG 1070 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1071 rv.major = rv.minor = 0; 1072 return rv; 1073 } 1074 #endif /* NSSDEBUG */ 1075 1076 if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { 1077 rv.major = rv.minor = 0; 1078 return rv; 1079 } 1080 1081 if ((0 != fwToken->hardwareVersion.major) || 1082 (0 != fwToken->hardwareVersion.minor)) { 1083 rv = fwToken->hardwareVersion; 1084 goto done; 1085 } 1086 1087 if (fwToken->mdToken->GetHardwareVersion) { 1088 fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion( 1089 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); 1090 } else { 1091 fwToken->hardwareVersion.major = 0; 1092 fwToken->hardwareVersion.minor = 1; 1093 } 1094 1095 rv = fwToken->hardwareVersion; 1096 1097 done: 1098 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1099 return rv; 1100 } 1101 1102 /* 1103 * nssCKFWToken_GetFirmwareVersion 1104 * 1105 */ 1106 NSS_IMPLEMENT CK_VERSION 1107 nssCKFWToken_GetFirmwareVersion( 1108 NSSCKFWToken *fwToken) 1109 { 1110 CK_VERSION rv; 1111 1112 #ifdef NSSDEBUG 1113 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1114 rv.major = rv.minor = 0; 1115 return rv; 1116 } 1117 #endif /* NSSDEBUG */ 1118 1119 if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { 1120 rv.major = rv.minor = 0; 1121 return rv; 1122 } 1123 1124 if ((0 != fwToken->firmwareVersion.major) || 1125 (0 != fwToken->firmwareVersion.minor)) { 1126 rv = fwToken->firmwareVersion; 1127 goto done; 1128 } 1129 1130 if (fwToken->mdToken->GetFirmwareVersion) { 1131 fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion( 1132 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); 1133 } else { 1134 fwToken->firmwareVersion.major = 0; 1135 fwToken->firmwareVersion.minor = 1; 1136 } 1137 1138 rv = fwToken->firmwareVersion; 1139 1140 done: 1141 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1142 return rv; 1143 } 1144 1145 /* 1146 * nssCKFWToken_GetUTCTime 1147 * 1148 */ 1149 NSS_IMPLEMENT CK_RV 1150 nssCKFWToken_GetUTCTime( 1151 NSSCKFWToken *fwToken, 1152 CK_CHAR utcTime[16]) 1153 { 1154 CK_RV error = CKR_OK; 1155 1156 #ifdef NSSDEBUG 1157 error = nssCKFWToken_verifyPointer(fwToken); 1158 if (CKR_OK != error) { 1159 return error; 1160 } 1161 1162 if ((CK_CHAR_PTR)NULL == utcTime) { 1163 return CKR_ARGUMENTS_BAD; 1164 } 1165 #endif /* DEBUG */ 1166 1167 if (CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken)) { 1168 /* return CKR_DEVICE_ERROR; */ 1169 (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' '); 1170 return CKR_OK; 1171 } 1172 1173 if (!fwToken->mdToken->GetUTCTime) { 1174 /* It said it had one! */ 1175 return CKR_GENERAL_ERROR; 1176 } 1177 1178 error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, 1179 fwToken->mdInstance, fwToken->fwInstance, utcTime); 1180 if (CKR_OK != error) { 1181 return error; 1182 } 1183 1184 /* Sanity-check the data */ 1185 { 1186 /* Format is YYYYMMDDhhmmss00 */ 1187 int i; 1188 int Y, M, D, h, m, s; 1189 static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 1190 1191 for (i = 0; i < 16; i++) { 1192 if ((utcTime[i] < '0') || (utcTime[i] > '9')) { 1193 goto badtime; 1194 } 1195 } 1196 1197 Y = ((utcTime[0] - '0') * 1000) + ((utcTime[1] - '0') * 100) + 1198 ((utcTime[2] - '0') * 10) + (utcTime[3] - '0'); 1199 M = ((utcTime[4] - '0') * 10) + (utcTime[5] - '0'); 1200 D = ((utcTime[6] - '0') * 10) + (utcTime[7] - '0'); 1201 h = ((utcTime[8] - '0') * 10) + (utcTime[9] - '0'); 1202 m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0'); 1203 s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0'); 1204 1205 if ((Y < 1990) || (Y > 3000)) 1206 goto badtime; /* Y3K problem. heh heh heh */ 1207 if ((M < 1) || (M > 12)) 1208 goto badtime; 1209 if ((D < 1) || (D > 31)) 1210 goto badtime; 1211 1212 if (D > dims[M - 1]) 1213 goto badtime; /* per-month check */ 1214 if ((2 == M) && (((Y % 4) || !(Y % 100)) && (Y % 400)) && 1215 (D > 28)) 1216 goto badtime; /* leap years */ 1217 1218 if ((h < 0) || (h > 23)) 1219 goto badtime; 1220 if ((m < 0) || (m > 60)) 1221 goto badtime; 1222 if ((s < 0) || (s > 61)) 1223 goto badtime; 1224 1225 /* 60m and 60 or 61s is only allowed for leap seconds. */ 1226 if ((60 == m) || (s >= 60)) { 1227 if ((23 != h) || (60 != m) || (s < 60)) 1228 goto badtime; 1229 /* leap seconds can only happen on June 30 or Dec 31.. I think */ 1230 /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */ 1231 } 1232 } 1233 1234 return CKR_OK; 1235 1236 badtime: 1237 return CKR_GENERAL_ERROR; 1238 } 1239 1240 /* 1241 * nssCKFWToken_OpenSession 1242 * 1243 */ 1244 NSS_IMPLEMENT NSSCKFWSession * 1245 nssCKFWToken_OpenSession( 1246 NSSCKFWToken *fwToken, 1247 CK_BBOOL rw, 1248 CK_VOID_PTR pApplication, 1249 CK_NOTIFY Notify, 1250 CK_RV *pError) 1251 { 1252 NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL; 1253 NSSCKMDSession *mdSession; 1254 1255 #ifdef NSSDEBUG 1256 if (!pError) { 1257 return (NSSCKFWSession *)NULL; 1258 } 1259 1260 *pError = nssCKFWToken_verifyPointer(fwToken); 1261 if (CKR_OK != *pError) { 1262 return (NSSCKFWSession *)NULL; 1263 } 1264 1265 switch (rw) { 1266 case CK_TRUE: 1267 case CK_FALSE: 1268 break; 1269 default: 1270 *pError = CKR_ARGUMENTS_BAD; 1271 return (NSSCKFWSession *)NULL; 1272 } 1273 #endif /* NSSDEBUG */ 1274 1275 *pError = nssCKFWMutex_Lock(fwToken->mutex); 1276 if (CKR_OK != *pError) { 1277 return (NSSCKFWSession *)NULL; 1278 } 1279 1280 if (CK_TRUE == rw) { 1281 /* Read-write session desired */ 1282 if (CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken)) { 1283 *pError = CKR_TOKEN_WRITE_PROTECTED; 1284 goto done; 1285 } 1286 } else { 1287 /* Read-only session desired */ 1288 if (CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken)) { 1289 *pError = CKR_SESSION_READ_WRITE_SO_EXISTS; 1290 goto done; 1291 } 1292 } 1293 1294 /* We could compare sesion counts to any limits we know of, I guess.. */ 1295 1296 if (!fwToken->mdToken->OpenSession) { 1297 /* 1298 * I'm not sure that the Module actually needs to implement 1299 * mdSessions -- the Framework can keep track of everything 1300 * needed, really. But I'll sort out that detail later.. 1301 */ 1302 *pError = CKR_GENERAL_ERROR; 1303 goto done; 1304 } 1305 1306 fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError); 1307 if (!fwSession) { 1308 if (CKR_OK == *pError) { 1309 *pError = CKR_GENERAL_ERROR; 1310 } 1311 goto done; 1312 } 1313 1314 mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken, 1315 fwToken->mdInstance, fwToken->fwInstance, fwSession, 1316 rw, pError); 1317 if (!mdSession) { 1318 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); 1319 if (CKR_OK == *pError) { 1320 *pError = CKR_GENERAL_ERROR; 1321 } 1322 goto done; 1323 } 1324 1325 *pError = nssCKFWSession_SetMDSession(fwSession, mdSession); 1326 if (CKR_OK != *pError) { 1327 if (mdSession->Close) { 1328 mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken, 1329 fwToken->mdInstance, fwToken->fwInstance); 1330 } 1331 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); 1332 goto done; 1333 } 1334 1335 *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession); 1336 if (CKR_OK != *pError) { 1337 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); 1338 fwSession = (NSSCKFWSession *)NULL; 1339 goto done; 1340 } 1341 1342 done: 1343 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1344 return fwSession; 1345 } 1346 1347 /* 1348 * nssCKFWToken_GetMechanismCount 1349 * 1350 */ 1351 NSS_IMPLEMENT CK_ULONG 1352 nssCKFWToken_GetMechanismCount( 1353 NSSCKFWToken *fwToken) 1354 { 1355 #ifdef NSSDEBUG 1356 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1357 return 0; 1358 } 1359 #endif /* NSSDEBUG */ 1360 1361 if (!fwToken->mdToken->GetMechanismCount) { 1362 return 0; 1363 } 1364 1365 return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken, 1366 fwToken->mdInstance, fwToken->fwInstance); 1367 } 1368 1369 /* 1370 * nssCKFWToken_GetMechanismTypes 1371 * 1372 */ 1373 NSS_IMPLEMENT CK_RV 1374 nssCKFWToken_GetMechanismTypes( 1375 NSSCKFWToken *fwToken, 1376 CK_MECHANISM_TYPE types[]) 1377 { 1378 #ifdef NSSDEBUG 1379 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1380 return CKR_ARGUMENTS_BAD; 1381 } 1382 1383 if (!types) { 1384 return CKR_ARGUMENTS_BAD; 1385 } 1386 #endif /* NSSDEBUG */ 1387 1388 if (!fwToken->mdToken->GetMechanismTypes) { 1389 /* 1390 * This should only be called with a sufficiently-large 1391 * "types" array, which can only be done if GetMechanismCount 1392 * is implemented. If that's implemented (and returns nonzero), 1393 * then this should be too. So return an error. 1394 */ 1395 return CKR_GENERAL_ERROR; 1396 } 1397 1398 return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken, 1399 fwToken->mdInstance, fwToken->fwInstance, types); 1400 } 1401 1402 /* 1403 * nssCKFWToken_GetMechanism 1404 * 1405 */ 1406 NSS_IMPLEMENT NSSCKFWMechanism * 1407 nssCKFWToken_GetMechanism( 1408 NSSCKFWToken *fwToken, 1409 CK_MECHANISM_TYPE which, 1410 CK_RV *pError) 1411 { 1412 NSSCKMDMechanism *mdMechanism; 1413 if (!fwToken->mdMechanismHash) { 1414 *pError = CKR_GENERAL_ERROR; 1415 return (NSSCKFWMechanism *)NULL; 1416 } 1417 1418 if (!fwToken->mdToken->GetMechanism) { 1419 /* 1420 * If we don't implement any GetMechanism function, then we must 1421 * not support any. 1422 */ 1423 *pError = CKR_MECHANISM_INVALID; 1424 return (NSSCKFWMechanism *)NULL; 1425 } 1426 1427 /* lookup in hash table */ 1428 mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken, 1429 fwToken->mdInstance, fwToken->fwInstance, which, pError); 1430 if (!mdMechanism) { 1431 return (NSSCKFWMechanism *)NULL; 1432 } 1433 /* store in hash table */ 1434 return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken, 1435 fwToken->mdInstance, fwToken->fwInstance); 1436 } 1437 1438 NSS_IMPLEMENT CK_RV 1439 nssCKFWToken_SetSessionState( 1440 NSSCKFWToken *fwToken, 1441 CK_STATE newState) 1442 { 1443 CK_RV error = CKR_OK; 1444 1445 #ifdef NSSDEBUG 1446 error = nssCKFWToken_verifyPointer(fwToken); 1447 if (CKR_OK != error) { 1448 return error; 1449 } 1450 1451 switch (newState) { 1452 case CKS_RO_PUBLIC_SESSION: 1453 case CKS_RO_USER_FUNCTIONS: 1454 case CKS_RW_PUBLIC_SESSION: 1455 case CKS_RW_USER_FUNCTIONS: 1456 case CKS_RW_SO_FUNCTIONS: 1457 break; 1458 default: 1459 return CKR_ARGUMENTS_BAD; 1460 } 1461 #endif /* NSSDEBUG */ 1462 1463 error = nssCKFWMutex_Lock(fwToken->mutex); 1464 if (CKR_OK != error) { 1465 return error; 1466 } 1467 1468 fwToken->state = newState; 1469 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1470 return CKR_OK; 1471 } 1472 1473 /* 1474 * nssCKFWToken_RemoveSession 1475 * 1476 */ 1477 NSS_IMPLEMENT CK_RV 1478 nssCKFWToken_RemoveSession( 1479 NSSCKFWToken *fwToken, 1480 NSSCKFWSession *fwSession) 1481 { 1482 CK_RV error = CKR_OK; 1483 1484 #ifdef NSSDEBUG 1485 error = nssCKFWToken_verifyPointer(fwToken); 1486 if (CKR_OK != error) { 1487 return error; 1488 } 1489 1490 error = nssCKFWSession_verifyPointer(fwSession); 1491 if (CKR_OK != error) { 1492 return error; 1493 } 1494 #endif /* NSSDEBUG */ 1495 1496 error = nssCKFWMutex_Lock(fwToken->mutex); 1497 if (CKR_OK != error) { 1498 return error; 1499 } 1500 1501 if (CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession)) { 1502 error = CKR_SESSION_HANDLE_INVALID; 1503 goto done; 1504 } 1505 1506 nssCKFWHash_Remove(fwToken->sessions, fwSession); 1507 fwToken->sessionCount--; 1508 1509 if (nssCKFWSession_IsRWSession(fwSession)) { 1510 fwToken->rwSessionCount--; 1511 } 1512 1513 if (0 == fwToken->sessionCount) { 1514 fwToken->rwSessionCount = 0; /* sanity */ 1515 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ 1516 } 1517 1518 error = CKR_OK; 1519 1520 done: 1521 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1522 return error; 1523 } 1524 1525 /* 1526 * nssCKFWToken_CloseAllSessions 1527 * 1528 */ 1529 NSS_IMPLEMENT CK_RV 1530 nssCKFWToken_CloseAllSessions( 1531 NSSCKFWToken *fwToken) 1532 { 1533 CK_RV error = CKR_OK; 1534 1535 #ifdef NSSDEBUG 1536 error = nssCKFWToken_verifyPointer(fwToken); 1537 if (CKR_OK != error) { 1538 return error; 1539 } 1540 #endif /* NSSDEBUG */ 1541 1542 error = nssCKFWMutex_Lock(fwToken->mutex); 1543 if (CKR_OK != error) { 1544 return error; 1545 } 1546 1547 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL); 1548 1549 nssCKFWHash_Destroy(fwToken->sessions); 1550 1551 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error); 1552 if (!fwToken->sessions) { 1553 if (CKR_OK == error) { 1554 error = CKR_GENERAL_ERROR; 1555 } 1556 goto done; 1557 } 1558 1559 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ 1560 fwToken->sessionCount = 0; 1561 fwToken->rwSessionCount = 0; 1562 1563 error = CKR_OK; 1564 1565 done: 1566 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1567 return error; 1568 } 1569 1570 /* 1571 * nssCKFWToken_GetSessionCount 1572 * 1573 */ 1574 NSS_IMPLEMENT CK_ULONG 1575 nssCKFWToken_GetSessionCount( 1576 NSSCKFWToken *fwToken) 1577 { 1578 CK_ULONG rv; 1579 1580 #ifdef NSSDEBUG 1581 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1582 return (CK_ULONG)0; 1583 } 1584 #endif /* NSSDEBUG */ 1585 1586 if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { 1587 return (CK_ULONG)0; 1588 } 1589 1590 rv = fwToken->sessionCount; 1591 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1592 return rv; 1593 } 1594 1595 /* 1596 * nssCKFWToken_GetRwSessionCount 1597 * 1598 */ 1599 NSS_IMPLEMENT CK_ULONG 1600 nssCKFWToken_GetRwSessionCount( 1601 NSSCKFWToken *fwToken) 1602 { 1603 CK_ULONG rv; 1604 1605 #ifdef NSSDEBUG 1606 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1607 return (CK_ULONG)0; 1608 } 1609 #endif /* NSSDEBUG */ 1610 1611 if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { 1612 return (CK_ULONG)0; 1613 } 1614 1615 rv = fwToken->rwSessionCount; 1616 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1617 return rv; 1618 } 1619 1620 /* 1621 * nssCKFWToken_GetRoSessionCount 1622 * 1623 */ 1624 NSS_IMPLEMENT CK_ULONG 1625 nssCKFWToken_GetRoSessionCount( 1626 NSSCKFWToken *fwToken) 1627 { 1628 CK_ULONG rv; 1629 1630 #ifdef NSSDEBUG 1631 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1632 return (CK_ULONG)0; 1633 } 1634 #endif /* NSSDEBUG */ 1635 1636 if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { 1637 return (CK_ULONG)0; 1638 } 1639 1640 rv = fwToken->sessionCount - fwToken->rwSessionCount; 1641 (void)nssCKFWMutex_Unlock(fwToken->mutex); 1642 return rv; 1643 } 1644 1645 /* 1646 * nssCKFWToken_GetSessionObjectHash 1647 * 1648 */ 1649 NSS_IMPLEMENT nssCKFWHash * 1650 nssCKFWToken_GetSessionObjectHash( 1651 NSSCKFWToken *fwToken) 1652 { 1653 #ifdef NSSDEBUG 1654 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1655 return (nssCKFWHash *)NULL; 1656 } 1657 #endif /* NSSDEBUG */ 1658 1659 return fwToken->sessionObjectHash; 1660 } 1661 1662 /* 1663 * nssCKFWToken_GetMDObjectHash 1664 * 1665 */ 1666 NSS_IMPLEMENT nssCKFWHash * 1667 nssCKFWToken_GetMDObjectHash( 1668 NSSCKFWToken *fwToken) 1669 { 1670 #ifdef NSSDEBUG 1671 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1672 return (nssCKFWHash *)NULL; 1673 } 1674 #endif /* NSSDEBUG */ 1675 1676 return fwToken->mdObjectHash; 1677 } 1678 1679 /* 1680 * nssCKFWToken_GetObjectHandleHash 1681 * 1682 */ 1683 NSS_IMPLEMENT nssCKFWHash * 1684 nssCKFWToken_GetObjectHandleHash( 1685 NSSCKFWToken *fwToken) 1686 { 1687 #ifdef NSSDEBUG 1688 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1689 return (nssCKFWHash *)NULL; 1690 } 1691 #endif /* NSSDEBUG */ 1692 1693 return fwToken->mdObjectHash; 1694 } 1695 1696 /* 1697 * NSSCKFWToken_GetMDToken 1698 * 1699 */ 1700 1701 NSS_IMPLEMENT NSSCKMDToken * 1702 NSSCKFWToken_GetMDToken( 1703 NSSCKFWToken *fwToken) 1704 { 1705 #ifdef DEBUG 1706 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1707 return (NSSCKMDToken *)NULL; 1708 } 1709 #endif /* DEBUG */ 1710 1711 return nssCKFWToken_GetMDToken(fwToken); 1712 } 1713 1714 /* 1715 * NSSCKFWToken_GetArena 1716 * 1717 */ 1718 1719 NSS_IMPLEMENT NSSArena * 1720 NSSCKFWToken_GetArena( 1721 NSSCKFWToken *fwToken, 1722 CK_RV *pError) 1723 { 1724 #ifdef DEBUG 1725 if (!pError) { 1726 return (NSSArena *)NULL; 1727 } 1728 1729 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1730 *pError = CKR_ARGUMENTS_BAD; 1731 return (NSSArena *)NULL; 1732 } 1733 #endif /* DEBUG */ 1734 1735 return nssCKFWToken_GetArena(fwToken, pError); 1736 } 1737 1738 /* 1739 * NSSCKFWToken_GetFWSlot 1740 * 1741 */ 1742 1743 NSS_IMPLEMENT NSSCKFWSlot * 1744 NSSCKFWToken_GetFWSlot( 1745 NSSCKFWToken *fwToken) 1746 { 1747 #ifdef DEBUG 1748 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1749 return (NSSCKFWSlot *)NULL; 1750 } 1751 #endif /* DEBUG */ 1752 1753 return nssCKFWToken_GetFWSlot(fwToken); 1754 } 1755 1756 /* 1757 * NSSCKFWToken_GetMDSlot 1758 * 1759 */ 1760 1761 NSS_IMPLEMENT NSSCKMDSlot * 1762 NSSCKFWToken_GetMDSlot( 1763 NSSCKFWToken *fwToken) 1764 { 1765 #ifdef DEBUG 1766 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1767 return (NSSCKMDSlot *)NULL; 1768 } 1769 #endif /* DEBUG */ 1770 1771 return nssCKFWToken_GetMDSlot(fwToken); 1772 } 1773 1774 /* 1775 * NSSCKFWToken_GetSessionState 1776 * 1777 */ 1778 1779 NSS_IMPLEMENT CK_STATE 1780 NSSCKFWSession_GetSessionState( 1781 NSSCKFWToken *fwToken) 1782 { 1783 #ifdef DEBUG 1784 if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { 1785 return CKS_RO_PUBLIC_SESSION; 1786 } 1787 #endif /* DEBUG */ 1788 1789 return nssCKFWToken_GetSessionState(fwToken); 1790 }