sessobj.c (23738B)
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 * sessobj.c 7 * 8 * This file contains an NSSCKMDObject implementation for session 9 * objects. The framework uses this implementation to manage 10 * session objects when a Module doesn't wish to be bothered. 11 */ 12 13 #ifndef CK_T 14 #include "ck.h" 15 #endif /* CK_T */ 16 17 /* 18 * nssCKMDSessionObject 19 * 20 * -- create -- 21 * nssCKMDSessionObject_Create 22 * 23 * -- EPV calls -- 24 * nss_ckmdSessionObject_Finalize 25 * nss_ckmdSessionObject_IsTokenObject 26 * nss_ckmdSessionObject_GetAttributeCount 27 * nss_ckmdSessionObject_GetAttributeTypes 28 * nss_ckmdSessionObject_GetAttributeSize 29 * nss_ckmdSessionObject_GetAttribute 30 * nss_ckmdSessionObject_SetAttribute 31 * nss_ckmdSessionObject_GetObjectSize 32 */ 33 34 struct nssCKMDSessionObjectStr { 35 CK_ULONG n; 36 NSSArena *arena; 37 NSSItem *attributes; 38 CK_ATTRIBUTE_TYPE_PTR types; 39 nssCKFWHash *hash; 40 }; 41 typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject; 42 43 #ifdef DEBUG 44 /* 45 * But first, the pointer-tracking stuff. 46 * 47 * NOTE: the pointer-tracking support in NSS/base currently relies 48 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 49 * locking, which is tied into the runtime. We need a pointer-tracker 50 * implementation that uses the locks supplied through C_Initialize. 51 * That support, however, can be filled in later. So for now, I'll 52 * just do this routines as no-ops. 53 */ 54 55 static CK_RV 56 nss_ckmdSessionObject_add_pointer( 57 const NSSCKMDObject *mdObject) 58 { 59 return CKR_OK; 60 } 61 62 static CK_RV 63 nss_ckmdSessionObject_remove_pointer( 64 const NSSCKMDObject *mdObject) 65 { 66 return CKR_OK; 67 } 68 69 #ifdef NSS_DEBUG 70 static CK_RV 71 nss_ckmdSessionObject_verifyPointer( 72 const NSSCKMDObject *mdObject) 73 { 74 return CKR_OK; 75 } 76 #endif 77 78 #endif /* DEBUG */ 79 80 /* 81 * We must forward-declare these routines 82 */ 83 static void 84 nss_ckmdSessionObject_Finalize( 85 NSSCKMDObject *mdObject, 86 NSSCKFWObject *fwObject, 87 NSSCKMDSession *mdSession, 88 NSSCKFWSession *fwSession, 89 NSSCKMDToken *mdToken, 90 NSSCKFWToken *fwToken, 91 NSSCKMDInstance *mdInstance, 92 NSSCKFWInstance *fwInstance); 93 94 static CK_RV 95 nss_ckmdSessionObject_Destroy( 96 NSSCKMDObject *mdObject, 97 NSSCKFWObject *fwObject, 98 NSSCKMDSession *mdSession, 99 NSSCKFWSession *fwSession, 100 NSSCKMDToken *mdToken, 101 NSSCKFWToken *fwToken, 102 NSSCKMDInstance *mdInstance, 103 NSSCKFWInstance *fwInstance); 104 105 static CK_BBOOL 106 nss_ckmdSessionObject_IsTokenObject( 107 NSSCKMDObject *mdObject, 108 NSSCKFWObject *fwObject, 109 NSSCKMDSession *mdSession, 110 NSSCKFWSession *fwSession, 111 NSSCKMDToken *mdToken, 112 NSSCKFWToken *fwToken, 113 NSSCKMDInstance *mdInstance, 114 NSSCKFWInstance *fwInstance); 115 116 static CK_ULONG 117 nss_ckmdSessionObject_GetAttributeCount( 118 NSSCKMDObject *mdObject, 119 NSSCKFWObject *fwObject, 120 NSSCKMDSession *mdSession, 121 NSSCKFWSession *fwSession, 122 NSSCKMDToken *mdToken, 123 NSSCKFWToken *fwToken, 124 NSSCKMDInstance *mdInstance, 125 NSSCKFWInstance *fwInstance, 126 CK_RV *pError); 127 128 static CK_RV 129 nss_ckmdSessionObject_GetAttributeTypes( 130 NSSCKMDObject *mdObject, 131 NSSCKFWObject *fwObject, 132 NSSCKMDSession *mdSession, 133 NSSCKFWSession *fwSession, 134 NSSCKMDToken *mdToken, 135 NSSCKFWToken *fwToken, 136 NSSCKMDInstance *mdInstance, 137 NSSCKFWInstance *fwInstance, 138 CK_ATTRIBUTE_TYPE_PTR typeArray, 139 CK_ULONG ulCount); 140 141 static CK_ULONG 142 nss_ckmdSessionObject_GetAttributeSize( 143 NSSCKMDObject *mdObject, 144 NSSCKFWObject *fwObject, 145 NSSCKMDSession *mdSession, 146 NSSCKFWSession *fwSession, 147 NSSCKMDToken *mdToken, 148 NSSCKFWToken *fwToken, 149 NSSCKMDInstance *mdInstance, 150 NSSCKFWInstance *fwInstance, 151 CK_ATTRIBUTE_TYPE attribute, 152 CK_RV *pError); 153 154 static NSSCKFWItem 155 nss_ckmdSessionObject_GetAttribute( 156 NSSCKMDObject *mdObject, 157 NSSCKFWObject *fwObject, 158 NSSCKMDSession *mdSession, 159 NSSCKFWSession *fwSession, 160 NSSCKMDToken *mdToken, 161 NSSCKFWToken *fwToken, 162 NSSCKMDInstance *mdInstance, 163 NSSCKFWInstance *fwInstance, 164 CK_ATTRIBUTE_TYPE attribute, 165 CK_RV *pError); 166 167 static CK_RV 168 nss_ckmdSessionObject_SetAttribute( 169 NSSCKMDObject *mdObject, 170 NSSCKFWObject *fwObject, 171 NSSCKMDSession *mdSession, 172 NSSCKFWSession *fwSession, 173 NSSCKMDToken *mdToken, 174 NSSCKFWToken *fwToken, 175 NSSCKMDInstance *mdInstance, 176 NSSCKFWInstance *fwInstance, 177 CK_ATTRIBUTE_TYPE attribute, 178 NSSItem *value); 179 180 static CK_ULONG 181 nss_ckmdSessionObject_GetObjectSize( 182 NSSCKMDObject *mdObject, 183 NSSCKFWObject *fwObject, 184 NSSCKMDSession *mdSession, 185 NSSCKFWSession *fwSession, 186 NSSCKMDToken *mdToken, 187 NSSCKFWToken *fwToken, 188 NSSCKMDInstance *mdInstance, 189 NSSCKFWInstance *fwInstance, 190 CK_RV *pError); 191 192 /* 193 * nssCKMDSessionObject_Create 194 * 195 */ 196 NSS_IMPLEMENT NSSCKMDObject * 197 nssCKMDSessionObject_Create( 198 NSSCKFWToken *fwToken, 199 NSSArena *arena, 200 CK_ATTRIBUTE_PTR attributes, 201 CK_ULONG ulCount, 202 CK_RV *pError) 203 { 204 NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL; 205 nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL; 206 CK_ULONG i; 207 nssCKFWHash *hash; 208 209 *pError = CKR_OK; 210 211 mdso = nss_ZNEW(arena, nssCKMDSessionObject); 212 if (!mdso) { 213 goto loser; 214 } 215 216 mdso->arena = arena; 217 mdso->n = ulCount; 218 mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount); 219 if (!mdso->attributes) { 220 goto loser; 221 } 222 223 mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount); 224 if (!mdso->types) { 225 goto loser; 226 } 227 for (i = 0; i < ulCount; i++) { 228 mdso->types[i] = attributes[i].type; 229 mdso->attributes[i].size = attributes[i].ulValueLen; 230 mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen); 231 if (!mdso->attributes[i].data) { 232 goto loser; 233 } 234 (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue, 235 attributes[i].ulValueLen); 236 } 237 238 mdObject = nss_ZNEW(arena, NSSCKMDObject); 239 if (!mdObject) { 240 goto loser; 241 } 242 243 mdObject->etc = (void *)mdso; 244 mdObject->Finalize = nss_ckmdSessionObject_Finalize; 245 mdObject->Destroy = nss_ckmdSessionObject_Destroy; 246 mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject; 247 mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount; 248 mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes; 249 mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize; 250 mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute; 251 mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute; 252 mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize; 253 254 hash = nssCKFWToken_GetSessionObjectHash(fwToken); 255 if (!hash) { 256 *pError = CKR_GENERAL_ERROR; 257 goto loser; 258 } 259 260 mdso->hash = hash; 261 262 *pError = nssCKFWHash_Add(hash, mdObject, mdObject); 263 if (CKR_OK != *pError) { 264 goto loser; 265 } 266 267 #ifdef DEBUG 268 if ((*pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK) { 269 goto loser; 270 } 271 #endif /* DEBUG */ 272 273 return mdObject; 274 275 loser: 276 if (mdso) { 277 if (mdso->attributes) { 278 for (i = 0; i < ulCount; i++) { 279 nss_ZFreeIf(mdso->attributes[i].data); 280 } 281 nss_ZFreeIf(mdso->attributes); 282 } 283 nss_ZFreeIf(mdso->types); 284 nss_ZFreeIf(mdso); 285 } 286 287 nss_ZFreeIf(mdObject); 288 if (*pError == CKR_OK) { 289 *pError = CKR_HOST_MEMORY; 290 } 291 return (NSSCKMDObject *)NULL; 292 } 293 294 /* 295 * nss_ckmdSessionObject_Finalize 296 * 297 */ 298 static void 299 nss_ckmdSessionObject_Finalize( 300 NSSCKMDObject *mdObject, 301 NSSCKFWObject *fwObject, 302 NSSCKMDSession *mdSession, 303 NSSCKFWSession *fwSession, 304 NSSCKMDToken *mdToken, 305 NSSCKFWToken *fwToken, 306 NSSCKMDInstance *mdInstance, 307 NSSCKFWInstance *fwInstance) 308 { 309 /* This shouldn't ever be called */ 310 return; 311 } 312 313 /* 314 * nss_ckmdSessionObject_Destroy 315 * 316 */ 317 318 static CK_RV 319 nss_ckmdSessionObject_Destroy( 320 NSSCKMDObject *mdObject, 321 NSSCKFWObject *fwObject, 322 NSSCKMDSession *mdSession, 323 NSSCKFWSession *fwSession, 324 NSSCKMDToken *mdToken, 325 NSSCKFWToken *fwToken, 326 NSSCKMDInstance *mdInstance, 327 NSSCKFWInstance *fwInstance) 328 { 329 #ifdef NSSDEBUG 330 CK_RV error = CKR_OK; 331 #endif /* NSSDEBUG */ 332 nssCKMDSessionObject *mdso; 333 CK_ULONG i; 334 335 #ifdef NSSDEBUG 336 error = nss_ckmdSessionObject_verifyPointer(mdObject); 337 if (CKR_OK != error) { 338 return error; 339 } 340 #endif /* NSSDEBUG */ 341 342 mdso = (nssCKMDSessionObject *)mdObject->etc; 343 344 nssCKFWHash_Remove(mdso->hash, mdObject); 345 346 for (i = 0; i < mdso->n; i++) { 347 nss_ZFreeIf(mdso->attributes[i].data); 348 } 349 nss_ZFreeIf(mdso->attributes); 350 nss_ZFreeIf(mdso->types); 351 nss_ZFreeIf(mdso); 352 nss_ZFreeIf(mdObject); 353 354 #ifdef DEBUG 355 (void)nss_ckmdSessionObject_remove_pointer(mdObject); 356 #endif /* DEBUG */ 357 358 return CKR_OK; 359 } 360 361 /* 362 * nss_ckmdSessionObject_IsTokenObject 363 * 364 */ 365 366 static CK_BBOOL 367 nss_ckmdSessionObject_IsTokenObject( 368 NSSCKMDObject *mdObject, 369 NSSCKFWObject *fwObject, 370 NSSCKMDSession *mdSession, 371 NSSCKFWSession *fwSession, 372 NSSCKMDToken *mdToken, 373 NSSCKFWToken *fwToken, 374 NSSCKMDInstance *mdInstance, 375 NSSCKFWInstance *fwInstance) 376 { 377 #ifdef NSSDEBUG 378 if (CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject)) { 379 return CK_FALSE; 380 } 381 #endif /* NSSDEBUG */ 382 383 /* 384 * This implementation is only ever used for session objects. 385 */ 386 return CK_FALSE; 387 } 388 389 /* 390 * nss_ckmdSessionObject_GetAttributeCount 391 * 392 */ 393 static CK_ULONG 394 nss_ckmdSessionObject_GetAttributeCount( 395 NSSCKMDObject *mdObject, 396 NSSCKFWObject *fwObject, 397 NSSCKMDSession *mdSession, 398 NSSCKFWSession *fwSession, 399 NSSCKMDToken *mdToken, 400 NSSCKFWToken *fwToken, 401 NSSCKMDInstance *mdInstance, 402 NSSCKFWInstance *fwInstance, 403 CK_RV *pError) 404 { 405 nssCKMDSessionObject *obj; 406 407 #ifdef NSSDEBUG 408 if (!pError) { 409 return 0; 410 } 411 412 *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 413 if (CKR_OK != *pError) { 414 return 0; 415 } 416 417 /* We could even check all the other arguments, for sanity. */ 418 #endif /* NSSDEBUG */ 419 420 obj = (nssCKMDSessionObject *)mdObject->etc; 421 422 return obj->n; 423 } 424 425 /* 426 * nss_ckmdSessionObject_GetAttributeTypes 427 * 428 */ 429 static CK_RV 430 nss_ckmdSessionObject_GetAttributeTypes( 431 NSSCKMDObject *mdObject, 432 NSSCKFWObject *fwObject, 433 NSSCKMDSession *mdSession, 434 NSSCKFWSession *fwSession, 435 NSSCKMDToken *mdToken, 436 NSSCKFWToken *fwToken, 437 NSSCKMDInstance *mdInstance, 438 NSSCKFWInstance *fwInstance, 439 CK_ATTRIBUTE_TYPE_PTR typeArray, 440 CK_ULONG ulCount) 441 { 442 #ifdef NSSDEBUG 443 CK_RV error = CKR_OK; 444 #endif /* NSSDEBUG */ 445 nssCKMDSessionObject *obj; 446 447 #ifdef NSSDEBUG 448 error = nss_ckmdSessionObject_verifyPointer(mdObject); 449 if (CKR_OK != error) { 450 return error; 451 } 452 453 /* We could even check all the other arguments, for sanity. */ 454 #endif /* NSSDEBUG */ 455 456 obj = (nssCKMDSessionObject *)mdObject->etc; 457 458 if (ulCount < obj->n) { 459 return CKR_BUFFER_TOO_SMALL; 460 } 461 462 (void)nsslibc_memcpy(typeArray, obj->types, 463 sizeof(CK_ATTRIBUTE_TYPE) * 464 obj->n); 465 466 return CKR_OK; 467 } 468 469 /* 470 * nss_ckmdSessionObject_GetAttributeSize 471 * 472 */ 473 static CK_ULONG 474 nss_ckmdSessionObject_GetAttributeSize( 475 NSSCKMDObject *mdObject, 476 NSSCKFWObject *fwObject, 477 NSSCKMDSession *mdSession, 478 NSSCKFWSession *fwSession, 479 NSSCKMDToken *mdToken, 480 NSSCKFWToken *fwToken, 481 NSSCKMDInstance *mdInstance, 482 NSSCKFWInstance *fwInstance, 483 CK_ATTRIBUTE_TYPE attribute, 484 CK_RV *pError) 485 { 486 nssCKMDSessionObject *obj; 487 CK_ULONG i; 488 489 #ifdef NSSDEBUG 490 if (!pError) { 491 return 0; 492 } 493 494 *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 495 if (CKR_OK != *pError) { 496 return 0; 497 } 498 499 /* We could even check all the other arguments, for sanity. */ 500 #endif /* NSSDEBUG */ 501 502 obj = (nssCKMDSessionObject *)mdObject->etc; 503 504 for (i = 0; i < obj->n; i++) { 505 if (attribute == obj->types[i]) { 506 return (CK_ULONG)(obj->attributes[i].size); 507 } 508 } 509 510 *pError = CKR_ATTRIBUTE_TYPE_INVALID; 511 return 0; 512 } 513 514 /* 515 * nss_ckmdSessionObject_GetAttribute 516 * 517 */ 518 static NSSCKFWItem 519 nss_ckmdSessionObject_GetAttribute( 520 NSSCKMDObject *mdObject, 521 NSSCKFWObject *fwObject, 522 NSSCKMDSession *mdSession, 523 NSSCKFWSession *fwSession, 524 NSSCKMDToken *mdToken, 525 NSSCKFWToken *fwToken, 526 NSSCKMDInstance *mdInstance, 527 NSSCKFWInstance *fwInstance, 528 CK_ATTRIBUTE_TYPE attribute, 529 CK_RV *pError) 530 { 531 NSSCKFWItem item; 532 nssCKMDSessionObject *obj; 533 CK_ULONG i; 534 535 item.needsFreeing = PR_FALSE; 536 item.item = NULL; 537 #ifdef NSSDEBUG 538 if (!pError) { 539 return item; 540 } 541 542 *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 543 if (CKR_OK != *pError) { 544 return item; 545 } 546 547 /* We could even check all the other arguments, for sanity. */ 548 #endif /* NSSDEBUG */ 549 550 obj = (nssCKMDSessionObject *)mdObject->etc; 551 552 for (i = 0; i < obj->n; i++) { 553 if (attribute == obj->types[i]) { 554 item.item = &obj->attributes[i]; 555 return item; 556 } 557 } 558 559 *pError = CKR_ATTRIBUTE_TYPE_INVALID; 560 return item; 561 } 562 563 /* 564 * nss_ckmdSessionObject_SetAttribute 565 * 566 */ 567 568 /* 569 * Okay, so this implementation sucks. It doesn't support removing 570 * an attribute (if value == NULL), and could be more graceful about 571 * memory. It should allow "blank" slots in the arrays, with some 572 * invalid attribute type, and then it could support removal much 573 * more easily. Do this later. 574 */ 575 static CK_RV 576 nss_ckmdSessionObject_SetAttribute( 577 NSSCKMDObject *mdObject, 578 NSSCKFWObject *fwObject, 579 NSSCKMDSession *mdSession, 580 NSSCKFWSession *fwSession, 581 NSSCKMDToken *mdToken, 582 NSSCKFWToken *fwToken, 583 NSSCKMDInstance *mdInstance, 584 NSSCKFWInstance *fwInstance, 585 CK_ATTRIBUTE_TYPE attribute, 586 NSSItem *value) 587 { 588 nssCKMDSessionObject *obj; 589 CK_ULONG i; 590 NSSItem n; 591 NSSItem *ra; 592 CK_ATTRIBUTE_TYPE_PTR rt; 593 #ifdef NSSDEBUG 594 CK_RV error; 595 #endif /* NSSDEBUG */ 596 597 #ifdef NSSDEBUG 598 error = nss_ckmdSessionObject_verifyPointer(mdObject); 599 if (CKR_OK != error) { 600 return 0; 601 } 602 603 /* We could even check all the other arguments, for sanity. */ 604 #endif /* NSSDEBUG */ 605 606 obj = (nssCKMDSessionObject *)mdObject->etc; 607 608 n.size = value->size; 609 n.data = nss_ZAlloc(obj->arena, n.size); 610 if (!n.data) { 611 return CKR_HOST_MEMORY; 612 } 613 (void)nsslibc_memcpy(n.data, value->data, n.size); 614 615 for (i = 0; i < obj->n; i++) { 616 if (attribute == obj->types[i]) { 617 nss_ZFreeIf(obj->attributes[i].data); 618 obj->attributes[i] = n; 619 return CKR_OK; 620 } 621 } 622 623 /* 624 * It's new. 625 */ 626 627 ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1)); 628 if (!ra) { 629 nss_ZFreeIf(n.data); 630 return CKR_HOST_MEMORY; 631 } 632 obj->attributes = ra; 633 634 rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, 635 sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1)); 636 if (!rt) { 637 nss_ZFreeIf(n.data); 638 return CKR_HOST_MEMORY; 639 } 640 641 obj->types = rt; 642 obj->attributes[obj->n] = n; 643 obj->types[obj->n] = attribute; 644 obj->n++; 645 646 return CKR_OK; 647 } 648 649 /* 650 * nss_ckmdSessionObject_GetObjectSize 651 * 652 */ 653 static CK_ULONG 654 nss_ckmdSessionObject_GetObjectSize( 655 NSSCKMDObject *mdObject, 656 NSSCKFWObject *fwObject, 657 NSSCKMDSession *mdSession, 658 NSSCKFWSession *fwSession, 659 NSSCKMDToken *mdToken, 660 NSSCKFWToken *fwToken, 661 NSSCKMDInstance *mdInstance, 662 NSSCKFWInstance *fwInstance, 663 CK_RV *pError) 664 { 665 nssCKMDSessionObject *obj; 666 CK_ULONG i; 667 CK_ULONG rv = (CK_ULONG)0; 668 669 #ifdef NSSDEBUG 670 if (!pError) { 671 return 0; 672 } 673 674 *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 675 if (CKR_OK != *pError) { 676 return 0; 677 } 678 679 /* We could even check all the other arguments, for sanity. */ 680 #endif /* NSSDEBUG */ 681 682 obj = (nssCKMDSessionObject *)mdObject->etc; 683 684 for (i = 0; i < obj->n; i++) { 685 rv += obj->attributes[i].size; 686 } 687 688 rv += sizeof(NSSItem) * obj->n; 689 rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n; 690 rv += sizeof(nssCKMDSessionObject); 691 692 return rv; 693 } 694 695 /* 696 * nssCKMDFindSessionObjects 697 * 698 * -- create -- 699 * nssCKMDFindSessionObjects_Create 700 * 701 * -- EPV calls -- 702 * nss_ckmdFindSessionObjects_Final 703 * nss_ckmdFindSessionObjects_Next 704 */ 705 706 struct nodeStr { 707 struct nodeStr *next; 708 NSSCKMDObject *mdObject; 709 }; 710 711 struct nssCKMDFindSessionObjectsStr { 712 NSSArena *arena; 713 CK_RV error; 714 CK_ATTRIBUTE_PTR pTemplate; 715 CK_ULONG ulCount; 716 struct nodeStr *list; 717 nssCKFWHash *hash; 718 }; 719 typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects; 720 721 #ifdef DEBUG 722 /* 723 * But first, the pointer-tracking stuff. 724 * 725 * NOTE: the pointer-tracking support in NSS/base currently relies 726 * upon NSPR's CallOnce support. That, however, relies upon NSPR's 727 * locking, which is tied into the runtime. We need a pointer-tracker 728 * implementation that uses the locks supplied through C_Initialize. 729 * That support, however, can be filled in later. So for now, I'll 730 * just do this routines as no-ops. 731 */ 732 733 static CK_RV 734 nss_ckmdFindSessionObjects_add_pointer( 735 const NSSCKMDFindObjects *mdFindObjects) 736 { 737 return CKR_OK; 738 } 739 740 static CK_RV 741 nss_ckmdFindSessionObjects_remove_pointer( 742 const NSSCKMDFindObjects *mdFindObjects) 743 { 744 return CKR_OK; 745 } 746 747 #ifdef NSS_DEBUG 748 static CK_RV 749 nss_ckmdFindSessionObjects_verifyPointer( 750 const NSSCKMDFindObjects *mdFindObjects) 751 { 752 return CKR_OK; 753 } 754 #endif 755 756 #endif /* DEBUG */ 757 758 /* 759 * We must forward-declare these routines. 760 */ 761 static void 762 nss_ckmdFindSessionObjects_Final( 763 NSSCKMDFindObjects *mdFindObjects, 764 NSSCKFWFindObjects *fwFindObjects, 765 NSSCKMDSession *mdSession, 766 NSSCKFWSession *fwSession, 767 NSSCKMDToken *mdToken, 768 NSSCKFWToken *fwToken, 769 NSSCKMDInstance *mdInstance, 770 NSSCKFWInstance *fwInstance); 771 772 static NSSCKMDObject * 773 nss_ckmdFindSessionObjects_Next( 774 NSSCKMDFindObjects *mdFindObjects, 775 NSSCKFWFindObjects *fwFindObjects, 776 NSSCKMDSession *mdSession, 777 NSSCKFWSession *fwSession, 778 NSSCKMDToken *mdToken, 779 NSSCKFWToken *fwToken, 780 NSSCKMDInstance *mdInstance, 781 NSSCKFWInstance *fwInstance, 782 NSSArena *arena, 783 CK_RV *pError); 784 785 static CK_BBOOL 786 items_match( 787 NSSItem *a, 788 CK_VOID_PTR pValue, 789 CK_ULONG ulValueLen) 790 { 791 if (a->size != ulValueLen) { 792 return CK_FALSE; 793 } 794 795 if (PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL)) { 796 return CK_TRUE; 797 } else { 798 return CK_FALSE; 799 } 800 } 801 802 /* 803 * Our hashtable iterator 804 */ 805 static void 806 findfcn( 807 const void *key, 808 void *value, 809 void *closure) 810 { 811 NSSCKMDObject *mdObject = (NSSCKMDObject *)value; 812 nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc; 813 nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure; 814 CK_ULONG i, j; 815 struct nodeStr *node; 816 817 if (CKR_OK != mdfso->error) { 818 return; 819 } 820 821 for (i = 0; i < mdfso->ulCount; i++) { 822 CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i]; 823 824 for (j = 0; j < mdso->n; j++) { 825 if (mdso->types[j] == p->type) { 826 if (!items_match(&mdso->attributes[j], p->pValue, p->ulValueLen)) { 827 return; 828 } else { 829 break; 830 } 831 } 832 } 833 834 if (j == mdso->n) { 835 /* Attribute not found */ 836 return; 837 } 838 } 839 840 /* Matches */ 841 node = nss_ZNEW(mdfso->arena, struct nodeStr); 842 if ((struct nodeStr *)NULL == node) { 843 mdfso->error = CKR_HOST_MEMORY; 844 return; 845 } 846 847 node->mdObject = mdObject; 848 node->next = mdfso->list; 849 mdfso->list = node; 850 851 return; 852 } 853 854 /* 855 * nssCKMDFindSessionObjects_Create 856 * 857 */ 858 NSS_IMPLEMENT NSSCKMDFindObjects * 859 nssCKMDFindSessionObjects_Create( 860 NSSCKFWToken *fwToken, 861 CK_ATTRIBUTE_PTR pTemplate, 862 CK_ULONG ulCount, 863 CK_RV *pError) 864 { 865 NSSArena *arena; 866 nssCKMDFindSessionObjects *mdfso; 867 nssCKFWHash *hash; 868 NSSCKMDFindObjects *rv; 869 870 #ifdef NSSDEBUG 871 if (!pError) { 872 return (NSSCKMDFindObjects *)NULL; 873 } 874 875 *pError = nssCKFWToken_verifyPointer(fwToken); 876 if (CKR_OK != *pError) { 877 return (NSSCKMDFindObjects *)NULL; 878 } 879 880 if ((CK_ATTRIBUTE_PTR)NULL == pTemplate) { 881 *pError = CKR_ARGUMENTS_BAD; 882 return (NSSCKMDFindObjects *)NULL; 883 } 884 #endif /* NSSDEBUG */ 885 886 *pError = CKR_OK; 887 888 hash = nssCKFWToken_GetSessionObjectHash(fwToken); 889 if (!hash) { 890 *pError = CKR_GENERAL_ERROR; 891 return (NSSCKMDFindObjects *)NULL; 892 } 893 894 arena = NSSArena_Create(); 895 if (!arena) { 896 *pError = CKR_HOST_MEMORY; 897 return (NSSCKMDFindObjects *)NULL; 898 } 899 900 mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects); 901 if (!mdfso) { 902 goto loser; 903 } 904 905 rv = nss_ZNEW(arena, NSSCKMDFindObjects); 906 if (rv == NULL) { 907 goto loser; 908 } 909 910 mdfso->error = CKR_OK; 911 mdfso->pTemplate = pTemplate; 912 mdfso->ulCount = ulCount; 913 mdfso->hash = hash; 914 915 nssCKFWHash_Iterate(hash, findfcn, mdfso); 916 917 if (CKR_OK != mdfso->error) { 918 goto loser; 919 } 920 921 rv->etc = (void *)mdfso; 922 rv->Final = nss_ckmdFindSessionObjects_Final; 923 rv->Next = nss_ckmdFindSessionObjects_Next; 924 925 #ifdef DEBUG 926 if ((*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK) { 927 goto loser; 928 } 929 #endif /* DEBUG */ 930 mdfso->arena = arena; 931 932 return rv; 933 934 loser: 935 if (arena) { 936 NSSArena_Destroy(arena); 937 } 938 if (*pError == CKR_OK) { 939 *pError = CKR_HOST_MEMORY; 940 } 941 return NULL; 942 } 943 944 static void 945 nss_ckmdFindSessionObjects_Final( 946 NSSCKMDFindObjects *mdFindObjects, 947 NSSCKFWFindObjects *fwFindObjects, 948 NSSCKMDSession *mdSession, 949 NSSCKFWSession *fwSession, 950 NSSCKMDToken *mdToken, 951 NSSCKFWToken *fwToken, 952 NSSCKMDInstance *mdInstance, 953 NSSCKFWInstance *fwInstance) 954 { 955 nssCKMDFindSessionObjects *mdfso; 956 957 #ifdef NSSDEBUG 958 if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) { 959 return; 960 } 961 #endif /* NSSDEBUG */ 962 963 mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; 964 if (mdfso->arena) 965 NSSArena_Destroy(mdfso->arena); 966 967 #ifdef DEBUG 968 (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects); 969 #endif /* DEBUG */ 970 971 return; 972 } 973 974 static NSSCKMDObject * 975 nss_ckmdFindSessionObjects_Next( 976 NSSCKMDFindObjects *mdFindObjects, 977 NSSCKFWFindObjects *fwFindObjects, 978 NSSCKMDSession *mdSession, 979 NSSCKFWSession *fwSession, 980 NSSCKMDToken *mdToken, 981 NSSCKFWToken *fwToken, 982 NSSCKMDInstance *mdInstance, 983 NSSCKFWInstance *fwInstance, 984 NSSArena *arena, 985 CK_RV *pError) 986 { 987 nssCKMDFindSessionObjects *mdfso; 988 NSSCKMDObject *rv = (NSSCKMDObject *)NULL; 989 990 #ifdef NSSDEBUG 991 if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) { 992 return (NSSCKMDObject *)NULL; 993 } 994 #endif /* NSSDEBUG */ 995 996 mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; 997 998 while (!rv) { 999 if ((struct nodeStr *)NULL == mdfso->list) { 1000 *pError = CKR_OK; 1001 return (NSSCKMDObject *)NULL; 1002 } 1003 1004 if (nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject)) { 1005 rv = mdfso->list->mdObject; 1006 } 1007 1008 mdfso->list = mdfso->list->next; 1009 } 1010 1011 return rv; 1012 }