slot.c (15308B)
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 * slot.c 7 * 8 * This file implements the NSSCKFWSlot type and methods. 9 */ 10 11 #ifndef CK_T 12 #include "ck.h" 13 #endif /* CK_T */ 14 15 /* 16 * NSSCKFWSlot 17 * 18 * -- create/destroy -- 19 * nssCKFWSlot_Create 20 * nssCKFWSlot_Destroy 21 * 22 * -- public accessors -- 23 * NSSCKFWSlot_GetMDSlot 24 * NSSCKFWSlot_GetFWInstance 25 * NSSCKFWSlot_GetMDInstance 26 * NSSCKFWSlot_GetSlotID 27 * 28 * -- implement public accessors -- 29 * nssCKFWSlot_GetMDSlot 30 * nssCKFWSlot_GetFWInstance 31 * nssCKFWSlot_GetMDInstance 32 * nssCKFWSlot_GetSlotID 33 * 34 * -- private accessors -- 35 * nssCKFWSlot_ClearToken 36 * 37 * -- module fronts -- 38 * nssCKFWSlot_GetSlotDescription 39 * nssCKFWSlot_GetManufacturerID 40 * nssCKFWSlot_GetTokenPresent 41 * nssCKFWSlot_GetRemovableDevice 42 * nssCKFWSlot_GetHardwareSlot 43 * nssCKFWSlot_GetHardwareVersion 44 * nssCKFWSlot_GetFirmwareVersion 45 * nssCKFWSlot_InitToken 46 * nssCKFWSlot_GetToken 47 */ 48 49 struct NSSCKFWSlotStr { 50 NSSCKFWMutex *mutex; 51 NSSCKMDSlot *mdSlot; 52 NSSCKFWInstance *fwInstance; 53 NSSCKMDInstance *mdInstance; 54 CK_SLOT_ID slotID; 55 56 /* 57 * Everything above is set at creation time, and then not modified. 58 * The invariants the mutex protects are: 59 * 60 * 1) Each of the cached descriptions (versions, etc.) are in an 61 * internally consistant state. 62 * 63 * 2) The fwToken points to the token currently in the slot, and 64 * it is in a consistant state. 65 * 66 * Note that the calls accessing the cached descriptions will 67 * call the NSSCKMDSlot methods with the mutex locked. Those 68 * methods may then call the public NSSCKFWSlot routines. Those 69 * public routines only access the constant data above, so there's 70 * no problem. But be careful if you add to this object; mutexes 71 * are in general not reentrant, so don't create deadlock situations. 72 */ 73 74 NSSUTF8 *slotDescription; 75 NSSUTF8 *manufacturerID; 76 CK_VERSION hardwareVersion; 77 CK_VERSION firmwareVersion; 78 NSSCKFWToken *fwToken; 79 }; 80 81 #ifdef DEBUG 82 /* 83 * But first, the pointer-tracking stuff. 84 * 85 * NOTE: the pointer-tracking support in NSS/base currently relies 86 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 87 * locking, which is tied into the runtime. We need a pointer-tracker 88 * implementation that uses the locks supplied through C_Initialize. 89 * That support, however, can be filled in later. So for now, I'll 90 * just do this routines as no-ops. 91 */ 92 93 static CK_RV 94 slot_add_pointer( 95 const NSSCKFWSlot *fwSlot) 96 { 97 return CKR_OK; 98 } 99 100 static CK_RV 101 slot_remove_pointer( 102 const NSSCKFWSlot *fwSlot) 103 { 104 return CKR_OK; 105 } 106 107 NSS_IMPLEMENT CK_RV 108 nssCKFWSlot_verifyPointer( 109 const NSSCKFWSlot *fwSlot) 110 { 111 return CKR_OK; 112 } 113 114 #endif /* DEBUG */ 115 116 /* 117 * nssCKFWSlot_Create 118 * 119 */ 120 NSS_IMPLEMENT NSSCKFWSlot * 121 nssCKFWSlot_Create( 122 NSSCKFWInstance *fwInstance, 123 NSSCKMDSlot *mdSlot, 124 CK_SLOT_ID slotID, 125 CK_RV *pError) 126 { 127 NSSCKFWSlot *fwSlot; 128 NSSCKMDInstance *mdInstance; 129 NSSArena *arena; 130 131 #ifdef NSSDEBUG 132 if (!pError) { 133 return (NSSCKFWSlot *)NULL; 134 } 135 136 *pError = nssCKFWInstance_verifyPointer(fwInstance); 137 if (CKR_OK != *pError) { 138 return (NSSCKFWSlot *)NULL; 139 } 140 #endif /* NSSDEBUG */ 141 142 mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); 143 if (!mdInstance) { 144 *pError = CKR_GENERAL_ERROR; 145 return (NSSCKFWSlot *)NULL; 146 } 147 148 arena = nssCKFWInstance_GetArena(fwInstance, pError); 149 if (!arena) { 150 if (CKR_OK == *pError) { 151 *pError = CKR_GENERAL_ERROR; 152 } 153 } 154 155 fwSlot = nss_ZNEW(arena, NSSCKFWSlot); 156 if (!fwSlot) { 157 *pError = CKR_HOST_MEMORY; 158 return (NSSCKFWSlot *)NULL; 159 } 160 161 fwSlot->mdSlot = mdSlot; 162 fwSlot->fwInstance = fwInstance; 163 fwSlot->mdInstance = mdInstance; 164 fwSlot->slotID = slotID; 165 166 fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError); 167 if (!fwSlot->mutex) { 168 if (CKR_OK == *pError) { 169 *pError = CKR_GENERAL_ERROR; 170 } 171 (void)nss_ZFreeIf(fwSlot); 172 return (NSSCKFWSlot *)NULL; 173 } 174 175 if (mdSlot->Initialize) { 176 *pError = CKR_OK; 177 *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance); 178 if (CKR_OK != *pError) { 179 (void)nssCKFWMutex_Destroy(fwSlot->mutex); 180 (void)nss_ZFreeIf(fwSlot); 181 return (NSSCKFWSlot *)NULL; 182 } 183 } 184 185 #ifdef DEBUG 186 *pError = slot_add_pointer(fwSlot); 187 if (CKR_OK != *pError) { 188 if (mdSlot->Destroy) { 189 mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance); 190 } 191 192 (void)nssCKFWMutex_Destroy(fwSlot->mutex); 193 (void)nss_ZFreeIf(fwSlot); 194 return (NSSCKFWSlot *)NULL; 195 } 196 #endif /* DEBUG */ 197 198 return fwSlot; 199 } 200 201 /* 202 * nssCKFWSlot_Destroy 203 * 204 */ 205 NSS_IMPLEMENT CK_RV 206 nssCKFWSlot_Destroy( 207 NSSCKFWSlot *fwSlot) 208 { 209 CK_RV error = CKR_OK; 210 211 #ifdef NSSDEBUG 212 error = nssCKFWSlot_verifyPointer(fwSlot); 213 if (CKR_OK != error) { 214 return error; 215 } 216 #endif /* NSSDEBUG */ 217 if (fwSlot->fwToken) { 218 nssCKFWToken_Destroy(fwSlot->fwToken); 219 } 220 221 (void)nssCKFWMutex_Destroy(fwSlot->mutex); 222 223 if (fwSlot->mdSlot->Destroy) { 224 fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot, 225 fwSlot->mdInstance, fwSlot->fwInstance); 226 } 227 228 #ifdef DEBUG 229 error = slot_remove_pointer(fwSlot); 230 #endif /* DEBUG */ 231 (void)nss_ZFreeIf(fwSlot); 232 return error; 233 } 234 235 /* 236 * nssCKFWSlot_GetMDSlot 237 * 238 */ 239 NSS_IMPLEMENT NSSCKMDSlot * 240 nssCKFWSlot_GetMDSlot( 241 NSSCKFWSlot *fwSlot) 242 { 243 #ifdef NSSDEBUG 244 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 245 return (NSSCKMDSlot *)NULL; 246 } 247 #endif /* NSSDEBUG */ 248 249 return fwSlot->mdSlot; 250 } 251 252 /* 253 * nssCKFWSlot_GetFWInstance 254 * 255 */ 256 257 NSS_IMPLEMENT NSSCKFWInstance * 258 nssCKFWSlot_GetFWInstance( 259 NSSCKFWSlot *fwSlot) 260 { 261 #ifdef NSSDEBUG 262 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 263 return (NSSCKFWInstance *)NULL; 264 } 265 #endif /* NSSDEBUG */ 266 267 return fwSlot->fwInstance; 268 } 269 270 /* 271 * nssCKFWSlot_GetMDInstance 272 * 273 */ 274 275 NSS_IMPLEMENT NSSCKMDInstance * 276 nssCKFWSlot_GetMDInstance( 277 NSSCKFWSlot *fwSlot) 278 { 279 #ifdef NSSDEBUG 280 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 281 return (NSSCKMDInstance *)NULL; 282 } 283 #endif /* NSSDEBUG */ 284 285 return fwSlot->mdInstance; 286 } 287 288 /* 289 * nssCKFWSlot_GetSlotID 290 * 291 */ 292 NSS_IMPLEMENT CK_SLOT_ID 293 nssCKFWSlot_GetSlotID( 294 NSSCKFWSlot *fwSlot) 295 { 296 #ifdef NSSDEBUG 297 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 298 return (CK_SLOT_ID)0; 299 } 300 #endif /* NSSDEBUG */ 301 302 return fwSlot->slotID; 303 } 304 305 /* 306 * nssCKFWSlot_GetSlotDescription 307 * 308 */ 309 NSS_IMPLEMENT CK_RV 310 nssCKFWSlot_GetSlotDescription( 311 NSSCKFWSlot *fwSlot, 312 CK_CHAR slotDescription[64]) 313 { 314 CK_RV error = CKR_OK; 315 316 #ifdef NSSDEBUG 317 if ((CK_CHAR_PTR)NULL == slotDescription) { 318 return CKR_ARGUMENTS_BAD; 319 } 320 321 error = nssCKFWSlot_verifyPointer(fwSlot); 322 if (CKR_OK != error) { 323 return error; 324 } 325 #endif /* NSSDEBUG */ 326 327 error = nssCKFWMutex_Lock(fwSlot->mutex); 328 if (CKR_OK != error) { 329 return error; 330 } 331 332 if (!fwSlot->slotDescription) { 333 if (fwSlot->mdSlot->GetSlotDescription) { 334 fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription( 335 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, 336 fwSlot->fwInstance, &error); 337 if ((!fwSlot->slotDescription) && (CKR_OK != error)) { 338 goto done; 339 } 340 } else { 341 fwSlot->slotDescription = (NSSUTF8 *)""; 342 } 343 } 344 345 (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' '); 346 error = CKR_OK; 347 348 done: 349 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 350 return error; 351 } 352 353 /* 354 * nssCKFWSlot_GetManufacturerID 355 * 356 */ 357 NSS_IMPLEMENT CK_RV 358 nssCKFWSlot_GetManufacturerID( 359 NSSCKFWSlot *fwSlot, 360 CK_CHAR manufacturerID[32]) 361 { 362 CK_RV error = CKR_OK; 363 364 #ifdef NSSDEBUG 365 if ((CK_CHAR_PTR)NULL == manufacturerID) { 366 return CKR_ARGUMENTS_BAD; 367 } 368 369 error = nssCKFWSlot_verifyPointer(fwSlot); 370 if (CKR_OK != error) { 371 return error; 372 } 373 #endif /* NSSDEBUG */ 374 375 error = nssCKFWMutex_Lock(fwSlot->mutex); 376 if (CKR_OK != error) { 377 return error; 378 } 379 380 if (!fwSlot->manufacturerID) { 381 if (fwSlot->mdSlot->GetManufacturerID) { 382 fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID( 383 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, 384 fwSlot->fwInstance, &error); 385 if ((!fwSlot->manufacturerID) && (CKR_OK != error)) { 386 goto done; 387 } 388 } else { 389 fwSlot->manufacturerID = (NSSUTF8 *)""; 390 } 391 } 392 393 (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' '); 394 error = CKR_OK; 395 396 done: 397 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 398 return error; 399 } 400 401 /* 402 * nssCKFWSlot_GetTokenPresent 403 * 404 */ 405 NSS_IMPLEMENT CK_BBOOL 406 nssCKFWSlot_GetTokenPresent( 407 NSSCKFWSlot *fwSlot) 408 { 409 #ifdef NSSDEBUG 410 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 411 return CK_FALSE; 412 } 413 #endif /* NSSDEBUG */ 414 415 if (!fwSlot->mdSlot->GetTokenPresent) { 416 return CK_TRUE; 417 } 418 419 return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot, 420 fwSlot->mdInstance, fwSlot->fwInstance); 421 } 422 423 /* 424 * nssCKFWSlot_GetRemovableDevice 425 * 426 */ 427 NSS_IMPLEMENT CK_BBOOL 428 nssCKFWSlot_GetRemovableDevice( 429 NSSCKFWSlot *fwSlot) 430 { 431 #ifdef NSSDEBUG 432 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 433 return CK_FALSE; 434 } 435 #endif /* NSSDEBUG */ 436 437 if (!fwSlot->mdSlot->GetRemovableDevice) { 438 return CK_FALSE; 439 } 440 441 return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot, 442 fwSlot->mdInstance, fwSlot->fwInstance); 443 } 444 445 /* 446 * nssCKFWSlot_GetHardwareSlot 447 * 448 */ 449 NSS_IMPLEMENT CK_BBOOL 450 nssCKFWSlot_GetHardwareSlot( 451 NSSCKFWSlot *fwSlot) 452 { 453 #ifdef NSSDEBUG 454 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 455 return CK_FALSE; 456 } 457 #endif /* NSSDEBUG */ 458 459 if (!fwSlot->mdSlot->GetHardwareSlot) { 460 return CK_FALSE; 461 } 462 463 return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot, 464 fwSlot->mdInstance, fwSlot->fwInstance); 465 } 466 467 /* 468 * nssCKFWSlot_GetHardwareVersion 469 * 470 */ 471 NSS_IMPLEMENT CK_VERSION 472 nssCKFWSlot_GetHardwareVersion( 473 NSSCKFWSlot *fwSlot) 474 { 475 CK_VERSION rv; 476 477 #ifdef NSSDEBUG 478 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 479 rv.major = rv.minor = 0; 480 return rv; 481 } 482 #endif /* NSSDEBUG */ 483 484 if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) { 485 rv.major = rv.minor = 0; 486 return rv; 487 } 488 489 if ((0 != fwSlot->hardwareVersion.major) || 490 (0 != fwSlot->hardwareVersion.minor)) { 491 rv = fwSlot->hardwareVersion; 492 goto done; 493 } 494 495 if (fwSlot->mdSlot->GetHardwareVersion) { 496 fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion( 497 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance); 498 } else { 499 fwSlot->hardwareVersion.major = 0; 500 fwSlot->hardwareVersion.minor = 1; 501 } 502 503 rv = fwSlot->hardwareVersion; 504 done: 505 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 506 return rv; 507 } 508 509 /* 510 * nssCKFWSlot_GetFirmwareVersion 511 * 512 */ 513 NSS_IMPLEMENT CK_VERSION 514 nssCKFWSlot_GetFirmwareVersion( 515 NSSCKFWSlot *fwSlot) 516 { 517 CK_VERSION rv; 518 519 #ifdef NSSDEBUG 520 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 521 rv.major = rv.minor = 0; 522 return rv; 523 } 524 #endif /* NSSDEBUG */ 525 526 if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) { 527 rv.major = rv.minor = 0; 528 return rv; 529 } 530 531 if ((0 != fwSlot->firmwareVersion.major) || 532 (0 != fwSlot->firmwareVersion.minor)) { 533 rv = fwSlot->firmwareVersion; 534 goto done; 535 } 536 537 if (fwSlot->mdSlot->GetFirmwareVersion) { 538 fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion( 539 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance); 540 } else { 541 fwSlot->firmwareVersion.major = 0; 542 fwSlot->firmwareVersion.minor = 1; 543 } 544 545 rv = fwSlot->firmwareVersion; 546 done: 547 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 548 return rv; 549 } 550 551 /* 552 * nssCKFWSlot_GetToken 553 * 554 */ 555 NSS_IMPLEMENT NSSCKFWToken * 556 nssCKFWSlot_GetToken( 557 NSSCKFWSlot *fwSlot, 558 CK_RV *pError) 559 { 560 NSSCKMDToken *mdToken; 561 NSSCKFWToken *fwToken; 562 563 #ifdef NSSDEBUG 564 if (!pError) { 565 return (NSSCKFWToken *)NULL; 566 } 567 568 *pError = nssCKFWSlot_verifyPointer(fwSlot); 569 if (CKR_OK != *pError) { 570 return (NSSCKFWToken *)NULL; 571 } 572 #endif /* NSSDEBUG */ 573 574 *pError = nssCKFWMutex_Lock(fwSlot->mutex); 575 if (CKR_OK != *pError) { 576 return (NSSCKFWToken *)NULL; 577 } 578 579 if (!fwSlot->fwToken) { 580 if (!fwSlot->mdSlot->GetToken) { 581 *pError = CKR_GENERAL_ERROR; 582 fwToken = (NSSCKFWToken *)NULL; 583 goto done; 584 } 585 586 mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot, 587 fwSlot->mdInstance, fwSlot->fwInstance, pError); 588 if (!mdToken) { 589 if (CKR_OK == *pError) { 590 *pError = CKR_GENERAL_ERROR; 591 } 592 return (NSSCKFWToken *)NULL; 593 } 594 595 fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError); 596 fwSlot->fwToken = fwToken; 597 } else { 598 fwToken = fwSlot->fwToken; 599 } 600 601 done: 602 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 603 return fwToken; 604 } 605 606 /* 607 * nssCKFWSlot_ClearToken 608 * 609 */ 610 NSS_IMPLEMENT void 611 nssCKFWSlot_ClearToken( 612 NSSCKFWSlot *fwSlot) 613 { 614 #ifdef NSSDEBUG 615 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 616 return; 617 } 618 #endif /* NSSDEBUG */ 619 620 if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) { 621 /* Now what? */ 622 return; 623 } 624 625 fwSlot->fwToken = (NSSCKFWToken *)NULL; 626 (void)nssCKFWMutex_Unlock(fwSlot->mutex); 627 return; 628 } 629 630 /* 631 * NSSCKFWSlot_GetMDSlot 632 * 633 */ 634 635 NSS_IMPLEMENT NSSCKMDSlot * 636 NSSCKFWSlot_GetMDSlot( 637 NSSCKFWSlot *fwSlot) 638 { 639 #ifdef DEBUG 640 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 641 return (NSSCKMDSlot *)NULL; 642 } 643 #endif /* DEBUG */ 644 645 return nssCKFWSlot_GetMDSlot(fwSlot); 646 } 647 648 /* 649 * NSSCKFWSlot_GetFWInstance 650 * 651 */ 652 653 NSS_IMPLEMENT NSSCKFWInstance * 654 NSSCKFWSlot_GetFWInstance( 655 NSSCKFWSlot *fwSlot) 656 { 657 #ifdef DEBUG 658 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 659 return (NSSCKFWInstance *)NULL; 660 } 661 #endif /* DEBUG */ 662 663 return nssCKFWSlot_GetFWInstance(fwSlot); 664 } 665 666 /* 667 * NSSCKFWSlot_GetMDInstance 668 * 669 */ 670 671 NSS_IMPLEMENT NSSCKMDInstance * 672 NSSCKFWSlot_GetMDInstance( 673 NSSCKFWSlot *fwSlot) 674 { 675 #ifdef DEBUG 676 if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) { 677 return (NSSCKMDInstance *)NULL; 678 } 679 #endif /* DEBUG */ 680 681 return nssCKFWSlot_GetMDInstance(fwSlot); 682 } 683 684 /* 685 * NSSCKFWSlot_GetSlotID 686 * 687 */ 688 689 NSS_IMPLEMENT CK_SLOT_ID 690 NSSCKFWSlot_GetSlotID( 691 NSSCKFWSlot *fwSlot) 692 { 693 return nssCKFWSlot_GetSlotID(fwSlot); 694 }