1/* 2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved. 3 * The contents of this file constitute Original Code as defined in and are 4 * subject to the Apple Public Source License Version 1.2 (the 'License'). 5 * You may not use this file except in compliance with the License. Please 6 * obtain a copy of the License at http://www.apple.com/publicsource and 7 * read it before using this file. 8 * 9 * This Original Code and all software distributed under the License are 10 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 11 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 12 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 13 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please 14 * see the License for the specific language governing rights and 15 * limitations under the License. 16 */ 17 18/****************************************************************** 19 20 MUSCLE SmartCard Development ( http://www.linuxnet.com ) 21 Title : tokenfactory.c 22 Package: pcsc lite 23 Author : David Corcoran 24 Date : 01/01/00 25 Purpose: This handles card abstraction attachment. 26 27 $Id: tokenfactory.c 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $ 28 29*******************************************************************/ 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <string.h> 34#include <sys/types.h> 35 36#ifndef WIN32 37#include <dirent.h> 38#include "config.h" 39#else 40#include "../win32/win32_config.h" 41#endif 42 43#include "debuglog.h" 44#include "dyn_generic.h" 45#include "tokenfactory.h" 46 47#define MSC_MANUMSC_KEY_NAME "spVendorName" 48#define MSC_PRODMSC_KEY_NAME "spProductName" 49#define MSC_ATRMSC_KEY_NAME "spAtrValue" 50#define MSC_LIBRMSC_KEY_NAME "CFBundleExecutable" 51#define MSC_DEFAULTAPP_NAME "spDefaultApplication" 52 53extern int LTPBundleFindValueWithKey(char *, char *, char *, int); 54 55int atrToString(MSCPUChar8 Atr, MSCULong32 Length, char *outAtr) 56{ 57 58 int i; 59 int j; 60 61 j = 0; 62 63 for (i = 0; i < Length; i++) 64 { 65 if ((Atr[i] / 16) > 9) 66 { 67 outAtr[j] = ((Atr[i] / 16) - 10) + 'A'; 68 } else 69 { 70 outAtr[j] = (Atr[i] / 16) + '0'; 71 } 72 73 j += 1; 74 75 if ((Atr[i] % 16) > 9) 76 { 77 outAtr[j] = ((Atr[i] % 16) - 10) + 'A'; 78 } else 79 { 80 outAtr[j] = (Atr[i] % 16) + '0'; 81 } 82 83 j += 1; 84 85 } 86 87 outAtr[j] = 0; /* Add the NULL */ 88 89 return 0; 90} 91 92int stringToBytes(char *inStr, MSCPUChar8 Buffer, MSCPULong32 Length) 93{ 94 95 int i; 96 int j; 97 int inLen; 98 99 j = 0; 100 inLen = 0; 101 102 inLen = strlen(inStr); 103 104 if (inLen > MSC_MAXSIZE_AID) 105 { 106 return -1; 107 } 108 109 for (i = 0; i < inLen; i += 2) 110 { 111 if (inStr[i] <= '9' && inStr[i] >= '0') 112 { 113 Buffer[j] = (inStr[i] - '0') * 16; 114 } else if (inStr[i] <= 'F' && inStr[i] >= 'A') 115 { 116 Buffer[j] = (inStr[i] - 'A' + 10) * 16; 117 } 118 119 if (inStr[i + 1] <= '9' && inStr[i + 1] >= '0') 120 { 121 Buffer[j] += inStr[i + 1] - '0'; 122 } else if (inStr[i + 1] <= 'F' && inStr[i + 1] >= 'A') 123 { 124 Buffer[j] += inStr[i + 1] - 'A' + 10; 125 } 126 127 j += 1; 128 } 129 130 *Length = j; 131 132 return 0; 133} 134 135MSCLong32 TPSearchBundlesForAtr(MSCPUChar8 Atr, MSCULong32 Length, 136 MSCLPTokenInfo tokenInfo) 137{ 138 139 MSCLong32 rv; 140 141#ifndef WIN32 142 DIR *hpDir = 0; 143 struct dirent *currFP = 0; 144#else 145 HANDLE hFind; 146 WIN32_FIND_DATA findData; 147 char findPath[200]; 148#endif 149 150 char atrString[100]; 151 char fullPath[200]; 152 char fullLibPath[250]; 153 char keyValue[200]; 154 int atrIndex; 155 156 rv = 0; 157 atrIndex = 0; 158 159 atrToString(Atr, Length, atrString); 160 161#ifndef WIN32 162 163 hpDir = opendir(MSC_SVC_DROPDIR); 164 165 if (hpDir == 0) 166#else 167 sprintf(findPath, "%s\\*.bundle", MSC_SVC_DROPDIR); 168 hFind = FindFirstFile(findPath, &findData); 169 170 if (hFind == INVALID_HANDLE_VALUE) 171#endif 172 { 173 DebugLogA("Cannot open PC/SC token drivers directory.\n"); 174 175 return -1; 176 } 177 178#ifndef WIN32 179 while ((currFP = readdir(hpDir)) != 0) 180 { 181 if (strstr(currFP->d_name, ".bundle") != 0) 182#else 183 do 184 { 185 if (strstr(findData.cFileName, ".bundle") != 0) 186#endif 187 { 188 189 /* 190 * The bundle exists - let's form a full path name and get the 191 * vendor and product ID's for this particular bundle 192 */ 193#ifndef WIN32 194 sprintf(fullPath, "%s%s%s", MSC_SVC_DROPDIR, currFP->d_name, 195 "/Contents/Info.plist"); 196#else 197 sprintf(fullPath, "%s%s%s", MSC_SVC_DROPDIR, findData.cFileName, 198 "\\Contents\\Info.plist"); 199#endif 200 201 atrIndex = 0; 202 203#ifdef MSC_DEBUG 204 DebugLogB("ATR comparison: FILE: %s\n", fullPath); 205 DebugLogB("ATR comparison: Target Match: %s\n", atrString); 206#endif 207 208 while (1) 209 { 210 rv = LTPBundleFindValueWithKey(fullPath, 211 MSC_ATRMSC_KEY_NAME, keyValue, atrIndex); 212 if (rv != 0) 213 { 214 break; /* No aliases found, break out of search 215 * aliases loop */ 216 } 217#ifdef MSC_DEBUG 218 DebugLogB("ATR comparison: Source: %s\n", keyValue); 219#endif 220 221 if (strcmp(keyValue, atrString) != 0) 222 { 223 /* 224 * Go back and see if there are any aliases 225 */ 226 atrIndex += 1; 227 continue; 228 } 229#ifdef MSC_DEBUG 230 DebugLogB("Match found at ATR alias %d\n", atrIndex); 231#endif 232 233 /* 234 * See if this bundle has a special name for this ATR 235 */ 236 rv = LTPBundleFindValueWithKey(fullPath, 237 MSC_PRODMSC_KEY_NAME, keyValue, atrIndex); 238 if (rv != 0) 239 { 240 rv = LTPBundleFindValueWithKey(fullPath, 241 MSC_PRODMSC_KEY_NAME, keyValue, 0); 242 if (rv != 0) 243 { 244 DebugLogA 245 ("Match found, failed due to no product name.\n"); 246#ifndef WIN32 247 closedir(hpDir); 248#endif 249 return -1; 250 } 251 } 252#ifdef MSC_DEBUG 253 DebugLogB("Product name: %s\n", keyValue); 254#endif 255 strcpy(tokenInfo->tokenName, keyValue); 256 257 /* 258 * See if this bundle has a special driver for this card 259 */ 260 rv = LTPBundleFindValueWithKey(fullPath, 261 MSC_LIBRMSC_KEY_NAME, keyValue, atrIndex); 262 if (rv != 0) 263 { 264 rv = LTPBundleFindValueWithKey(fullPath, 265 MSC_LIBRMSC_KEY_NAME, keyValue, 0); 266 if (rv != 0) 267 { 268 DebugLogA 269 ("Match found, failed due to no library path.\n"); 270#ifndef WIN32 271 closedir(hpDir); 272#endif 273 return -1; 274 } 275 } 276#ifdef WIN32 277 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 278 findData.cFileName, "\\Contents\\Win32\\", keyValue); 279#else 280#ifdef MSC_TARGET_LINUX 281 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 282 currFP->d_name, "/Contents/Linux/", keyValue); 283#else 284#ifdef MSC_TARGET_OSX 285 sprintf(fullLibPath, "%s%s", MSC_SVC_DROPDIR, 286 currFP->d_name); 287 288#else 289#ifdef MSC_TARGET_BSD 290 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 291 currFP->d_name, "/Contents/BSD/", keyValue); 292 293#else 294#ifdef MSC_TARGET_SOLARIS 295 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 296 currFP->d_name, "/Contents/Solaris/", keyValue); 297 298#else 299#ifdef MSC_TARGET_HPUX 300 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 301 currFP->d_name, "/Contents/HPUX/", keyValue); 302 303#else 304#ifdef MSC_TARGET_TRU64 305 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 306 currFP->d_name, "/Contents/Tru64/", keyValue); 307 308#else 309#ifdef MSC_TARGET_CYGWIN 310 sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR, 311 currFP->d_name, "/Contents/CygWin/", keyValue); 312#endif 313#endif 314#endif 315#endif 316#endif 317#endif 318#endif 319#endif 320 321 if (fullLibPath == NULL) 322 { 323 DebugLogA("No path to bundle library found !\n"); 324 return -1; 325 } 326 327 /* 328 * Copy the library path and return successfully 329 */ 330 strcpy(tokenInfo->svProvider, fullLibPath); 331 332 /* 333 * See if this bundle has a default AID 334 */ 335 rv = LTPBundleFindValueWithKey(fullPath, 336 MSC_DEFAULTAPP_NAME, keyValue, atrIndex); 337 if (rv != 0) 338 { 339 rv = LTPBundleFindValueWithKey(fullPath, 340 MSC_DEFAULTAPP_NAME, keyValue, 0); 341 } 342 343 if (rv == 0) 344 { 345#ifdef MSC_DEBUG 346 DebugLogB("Default AID name: %s\n", keyValue); 347#endif 348 rv = stringToBytes(keyValue, tokenInfo->tokenApp, 349 &tokenInfo->tokenAppLen); 350 if (rv != 0) 351 { 352 DebugLogA 353 ("Match found, failed due to malformed aid string.\n"); 354#ifndef WIN32 355 closedir(hpDir); 356#endif 357 return -1; 358 } 359 360 } else 361 { 362 DebugLogA("No AID specified in bundle\n"); 363 tokenInfo->tokenAppLen = 0; 364 } 365 366#ifndef WIN32 367 closedir(hpDir); 368#endif 369 return 0; 370 371 } /* do ... while */ 372 } /* if .bundle */ 373 } /* while readdir */ 374#ifdef WIN32 375 // This is part of a Do..While loop (see above) 376 while (FindNextFile(hFind, &findData) != 0); 377#endif 378 379#ifndef WIN32 380 closedir(hpDir); 381#endif 382 return -1; 383} 384 385const char *TPSvcDropdir(void) 386{ 387 const char *dropDir = getenv(MSC_SVC_DROPDIR_ENV); 388 if (dropDir) 389 return dropDir; 390 391 return MSC_SVC_DROPDIR_DEFAULT; 392} 393 394MSCLong32 TPLoadToken(MSCLPTokenConnection pConnection) 395{ 396 397 MSCLong32 rv; 398 399 pConnection->libPointers.pvfWriteFramework = 0; 400 pConnection->libPointers.pvfInitializePlugin = 0; 401 pConnection->libPointers.pvfFinalizePlugin = 0; 402 pConnection->libPointers.pvfGetStatus = 0; 403 pConnection->libPointers.pvfGetCapabilities = 0; 404 pConnection->libPointers.pvfExtendedFeature = 0; 405 pConnection->libPointers.pvfGenerateKeys = 0; 406 pConnection->libPointers.pvfImportKey = 0; 407 pConnection->libPointers.pvfExportKey = 0; 408 pConnection->libPointers.pvfComputeCrypt = 0; 409 pConnection->libPointers.pvfExtAuthenticate = 0; 410 pConnection->libPointers.pvfListKeys = 0; 411 pConnection->libPointers.pvfCreatePIN = 0; 412 pConnection->libPointers.pvfVerifyPIN = 0; 413 pConnection->libPointers.pvfChangePIN = 0; 414 pConnection->libPointers.pvfUnblockPIN = 0; 415 pConnection->libPointers.pvfListPINs = 0; 416 pConnection->libPointers.pvfCreateObject = 0; 417 pConnection->libPointers.pvfDeleteObject = 0; 418 pConnection->libPointers.pvfWriteObject = 0; 419 pConnection->libPointers.pvfReadObject = 0; 420 pConnection->libPointers.pvfListObjects = 0; 421 pConnection->libPointers.pvfLogoutAll = 0; 422 pConnection->libPointers.pvfGetChallenge = 0; 423 424 /* 425 * Find the Card's Library 426 */ 427 428 rv = TPSearchBundlesForAtr(pConnection->tokenInfo.tokenId, 429 pConnection->tokenInfo.tokenIdLength, &pConnection->tokenInfo); 430 431 if (rv != 0) 432 { 433 DebugLogA("Error: Matching Token ATR Not Found.\n"); 434 log_xxd(PCSC_LOG_INFO, "ATR : ", pConnection->tokenInfo.tokenId, 435 pConnection->tokenInfo.tokenIdLength); 436 437 return SCARD_E_CARD_UNSUPPORTED; 438 } 439 440 /* 441 * Load that library and store the handle in the SCARDCHANNEL 442 * structure 443 */ 444 445 rv = DYN_LoadLibrary(&pConnection->tokenLibHandle, 446 pConnection->tokenInfo.svProvider); 447 448 if (rv != SCARD_S_SUCCESS) 449 { 450 DebugLogA("Error: Could not load service library\n"); 451 DebugLogB("->> %s\n", pConnection->tokenInfo.svProvider); 452 return SCARD_E_INVALID_TARGET; 453 } else 454 { 455 DebugLogB("Loading service library %s\n", 456 pConnection->tokenInfo.svProvider); 457 } 458 459 rv = TPBindFunctions(pConnection); 460 461 return rv; 462} 463 464MSCLong32 TPUnloadToken(MSCLPTokenConnection pConnection) 465{ 466 467 MSCLong32 rv; 468 469 if (pConnection->tokenLibHandle == 0) 470 { 471 return SCARD_E_INVALID_VALUE; 472 } 473 474 rv = DYN_CloseLibrary(&pConnection->tokenLibHandle); 475 476 if (rv != SCARD_S_SUCCESS) 477 { 478 return rv; 479 } 480 481 pConnection->tokenLibHandle = 0; 482 return TPUnbindFunctions(pConnection); 483} 484 485MSCLong32 TPBindFunctions(MSCLPTokenConnection pConnection) 486{ 487 488 MSCLong32 rv; 489 490 if (pConnection->tokenLibHandle == 0) 491 { 492 return SCARD_E_INVALID_TARGET; 493 } 494 495 rv = DYN_GetAddress(pConnection->tokenLibHandle, 496 &pConnection->libPointers.pvfWriteFramework, 497 "PL_MSCWriteFramework"); 498 499 if (rv != SCARD_S_SUCCESS) 500 { 501 pConnection->libPointers.pvfWriteFramework = 0; 502 DebugLogA("TPBindFunctions: Missing functions"); 503 /* 504 * No big deal - this feature is just not supported 505 */ 506 } 507 508 rv = DYN_GetAddress(pConnection->tokenLibHandle, 509 &pConnection->libPointers.pvfIdentifyToken, "PL_MSCIdentifyToken"); 510 511 if (rv != SCARD_S_SUCCESS) 512 { 513 pConnection->libPointers.pvfIdentifyToken = 0; 514 DebugLogA("TPBindFunctions: Missing functions"); 515 return SCARD_F_INTERNAL_ERROR; 516 } 517 518 rv = DYN_GetAddress(pConnection->tokenLibHandle, 519 &pConnection->libPointers.pvfInitializePlugin, 520 "PL_MSCInitializePlugin"); 521 522 if (rv != SCARD_S_SUCCESS) 523 { 524 pConnection->libPointers.pvfInitializePlugin = 0; 525 DebugLogA("TPBindFunctions: Missing functions"); 526 return SCARD_F_INTERNAL_ERROR; 527 } 528 529 rv = DYN_GetAddress(pConnection->tokenLibHandle, 530 &pConnection->libPointers.pvfFinalizePlugin, 531 "PL_MSCFinalizePlugin"); 532 533 if (rv != SCARD_S_SUCCESS) 534 { 535 pConnection->libPointers.pvfFinalizePlugin = 0; 536 DebugLogA("TPBindFunctions: Missing functions"); 537 return SCARD_F_INTERNAL_ERROR; 538 } 539 540 rv = DYN_GetAddress(pConnection->tokenLibHandle, 541 &pConnection->libPointers.pvfGetStatus, "PL_MSCGetStatus"); 542 543 if (rv != SCARD_S_SUCCESS) 544 { 545 pConnection->libPointers.pvfGetStatus = 0; 546 DebugLogA("TPBindFunctions: Missing functions"); 547 return SCARD_F_INTERNAL_ERROR; 548 } 549 550 rv = DYN_GetAddress(pConnection->tokenLibHandle, 551 &pConnection->libPointers.pvfGetCapabilities, 552 "PL_MSCGetCapabilities"); 553 554 if (rv != SCARD_S_SUCCESS) 555 { 556 pConnection->libPointers.pvfGetCapabilities = 0; 557 DebugLogA("TPBindFunctions: Missing functions"); 558 return SCARD_F_INTERNAL_ERROR; 559 } 560 561 rv = DYN_GetAddress(pConnection->tokenLibHandle, 562 &pConnection->libPointers.pvfExtendedFeature, 563 "PL_MSCExtendedFeature"); 564 565 if (rv != SCARD_S_SUCCESS) 566 { 567 pConnection->libPointers.pvfExtendedFeature = 0; 568 DebugLogA("TPBindFunctions: Missing functions"); 569 /* 570 * No big deal - there are no extended features 571 */ 572 } 573 574 rv = DYN_GetAddress(pConnection->tokenLibHandle, 575 &pConnection->libPointers.pvfGenerateKeys, "PL_MSCGenerateKeys"); 576 577 if (rv != SCARD_S_SUCCESS) 578 { 579 pConnection->libPointers.pvfGenerateKeys = 0; 580 DebugLogA("TPBindFunctions: Missing functions"); 581 return SCARD_F_INTERNAL_ERROR; 582 } 583 584 rv = DYN_GetAddress(pConnection->tokenLibHandle, 585 &pConnection->libPointers.pvfImportKey, "PL_MSCImportKey"); 586 587 if (rv != SCARD_S_SUCCESS) 588 { 589 pConnection->libPointers.pvfImportKey = 0; 590 DebugLogA("TPBindFunctions: Missing functions"); 591 return SCARD_F_INTERNAL_ERROR; 592 } 593 594 rv = DYN_GetAddress(pConnection->tokenLibHandle, 595 &pConnection->libPointers.pvfExportKey, "PL_MSCExportKey"); 596 597 if (rv != SCARD_S_SUCCESS) 598 { 599 pConnection->libPointers.pvfExportKey = 0; 600 DebugLogA("TPBindFunctions: Missing functions"); 601 return SCARD_F_INTERNAL_ERROR; 602 } 603 604 rv = DYN_GetAddress(pConnection->tokenLibHandle, 605 &pConnection->libPointers.pvfComputeCrypt, "PL_MSCComputeCrypt"); 606 607 if (rv != SCARD_S_SUCCESS) 608 { 609 pConnection->libPointers.pvfComputeCrypt = 0; 610 DebugLogA("TPBindFunctions: Missing functions"); 611 return SCARD_F_INTERNAL_ERROR; 612 } 613 614 rv = DYN_GetAddress(pConnection->tokenLibHandle, 615 &pConnection->libPointers.pvfExtAuthenticate, 616 "PL_MSCExtAuthenticate"); 617 618 if (rv != SCARD_S_SUCCESS) 619 { 620 pConnection->libPointers.pvfExtAuthenticate = 0; 621 DebugLogA("TPBindFunctions: Missing functions"); 622 return SCARD_F_INTERNAL_ERROR; 623 } 624 625 rv = DYN_GetAddress(pConnection->tokenLibHandle, 626 &pConnection->libPointers.pvfListKeys, "PL_MSCListKeys"); 627 628 if (rv != SCARD_S_SUCCESS) 629 { 630 pConnection->libPointers.pvfListKeys = 0; 631 DebugLogA("TPBindFunctions: Missing functions"); 632 return SCARD_F_INTERNAL_ERROR; 633 } 634 635 rv = DYN_GetAddress(pConnection->tokenLibHandle, 636 &pConnection->libPointers.pvfCreatePIN, "PL_MSCCreatePIN"); 637 638 if (rv != SCARD_S_SUCCESS) 639 { 640 pConnection->libPointers.pvfCreatePIN = 0; 641 DebugLogA("TPBindFunctions: Missing functions"); 642 return SCARD_F_INTERNAL_ERROR; 643 } 644 645 rv = DYN_GetAddress(pConnection->tokenLibHandle, 646 &pConnection->libPointers.pvfVerifyPIN, "PL_MSCVerifyPIN"); 647 648 if (rv != SCARD_S_SUCCESS) 649 { 650 pConnection->libPointers.pvfVerifyPIN = 0; 651 DebugLogA("TPBindFunctions: Missing functions"); 652 return SCARD_F_INTERNAL_ERROR; 653 } 654 655 rv = DYN_GetAddress(pConnection->tokenLibHandle, 656 &pConnection->libPointers.pvfChangePIN, "PL_MSCChangePIN"); 657 658 if (rv != SCARD_S_SUCCESS) 659 { 660 pConnection->libPointers.pvfChangePIN = 0; 661 DebugLogA("TPBindFunctions: Missing functions"); 662 return SCARD_F_INTERNAL_ERROR; 663 } 664 665 rv = DYN_GetAddress(pConnection->tokenLibHandle, 666 &pConnection->libPointers.pvfUnblockPIN, "PL_MSCUnblockPIN"); 667 668 if (rv != SCARD_S_SUCCESS) 669 { 670 pConnection->libPointers.pvfUnblockPIN = 0; 671 DebugLogA("TPBindFunctions: Missing functions"); 672 return SCARD_F_INTERNAL_ERROR; 673 } 674 675 rv = DYN_GetAddress(pConnection->tokenLibHandle, 676 &pConnection->libPointers.pvfListPINs, "PL_MSCListPINs"); 677 678 if (rv != SCARD_S_SUCCESS) 679 { 680 pConnection->libPointers.pvfListPINs = 0; 681 DebugLogA("TPBindFunctions: Missing functions"); 682 return SCARD_F_INTERNAL_ERROR; 683 } 684 685 rv = DYN_GetAddress(pConnection->tokenLibHandle, 686 &pConnection->libPointers.pvfCreateObject, "PL_MSCCreateObject"); 687 688 if (rv != SCARD_S_SUCCESS) 689 { 690 pConnection->libPointers.pvfCreateObject = 0; 691 DebugLogA("TPBindFunctions: Missing functions"); 692 return SCARD_F_INTERNAL_ERROR; 693 } 694 695 rv = DYN_GetAddress(pConnection->tokenLibHandle, 696 &pConnection->libPointers.pvfDeleteObject, "PL_MSCDeleteObject"); 697 698 if (rv != SCARD_S_SUCCESS) 699 { 700 pConnection->libPointers.pvfDeleteObject = 0; 701 DebugLogA("TPBindFunctions: Missing functions"); 702 return SCARD_F_INTERNAL_ERROR; 703 } 704 705 rv = DYN_GetAddress(pConnection->tokenLibHandle, 706 &pConnection->libPointers.pvfWriteObject, "PL_MSCWriteObject"); 707 708 if (rv != SCARD_S_SUCCESS) 709 { 710 pConnection->libPointers.pvfWriteObject = 0; 711 DebugLogA("TPBindFunctions: Missing functions"); 712 return SCARD_F_INTERNAL_ERROR; 713 } 714 715 rv = DYN_GetAddress(pConnection->tokenLibHandle, 716 &pConnection->libPointers.pvfReadObject, "PL_MSCReadObject"); 717 718 if (rv != SCARD_S_SUCCESS) 719 { 720 pConnection->libPointers.pvfReadObject = 0; 721 DebugLogA("TPBindFunctions: Missing functions"); 722 return SCARD_F_INTERNAL_ERROR; 723 } 724 725 rv = DYN_GetAddress(pConnection->tokenLibHandle, 726 &pConnection->libPointers.pvfListObjects, "PL_MSCListObjects"); 727 728 if (rv != SCARD_S_SUCCESS) 729 { 730 pConnection->libPointers.pvfListObjects = 0; 731 DebugLogA("TPBindFunctions: Missing functions"); 732 return SCARD_F_INTERNAL_ERROR; 733 } 734 735 rv = DYN_GetAddress(pConnection->tokenLibHandle, 736 &pConnection->libPointers.pvfLogoutAll, "PL_MSCLogoutAll"); 737 738 if (rv != SCARD_S_SUCCESS) 739 { 740 pConnection->libPointers.pvfLogoutAll = 0; 741 DebugLogA("TPBindFunctions: Missing functions"); 742 return SCARD_F_INTERNAL_ERROR; 743 } 744 745 rv = DYN_GetAddress(pConnection->tokenLibHandle, 746 &pConnection->libPointers.pvfGetChallenge, "PL_MSCGetChallenge"); 747 748 if (rv != SCARD_S_SUCCESS) 749 { 750 pConnection->libPointers.pvfGetChallenge = 0; 751 DebugLogA("TPBindFunctions: Missing functions"); 752 return SCARD_F_INTERNAL_ERROR; 753 } 754 755 return SCARD_S_SUCCESS; 756} 757 758MSCLong32 TPUnbindFunctions(MSCLPTokenConnection pConnection) 759{ 760 761 pConnection->libPointers.pvfWriteFramework = 0; 762 pConnection->libPointers.pvfInitializePlugin = 0; 763 pConnection->libPointers.pvfFinalizePlugin = 0; 764 pConnection->libPointers.pvfGetStatus = 0; 765 pConnection->libPointers.pvfGetCapabilities = 0; 766 pConnection->libPointers.pvfExtendedFeature = 0; 767 pConnection->libPointers.pvfGenerateKeys = 0; 768 pConnection->libPointers.pvfImportKey = 0; 769 pConnection->libPointers.pvfExportKey = 0; 770 pConnection->libPointers.pvfComputeCrypt = 0; 771 pConnection->libPointers.pvfExtAuthenticate = 0; 772 pConnection->libPointers.pvfListKeys = 0; 773 pConnection->libPointers.pvfCreatePIN = 0; 774 pConnection->libPointers.pvfVerifyPIN = 0; 775 pConnection->libPointers.pvfChangePIN = 0; 776 pConnection->libPointers.pvfUnblockPIN = 0; 777 pConnection->libPointers.pvfListPINs = 0; 778 pConnection->libPointers.pvfCreateObject = 0; 779 pConnection->libPointers.pvfDeleteObject = 0; 780 pConnection->libPointers.pvfWriteObject = 0; 781 pConnection->libPointers.pvfReadObject = 0; 782 pConnection->libPointers.pvfListObjects = 0; 783 pConnection->libPointers.pvfLogoutAll = 0; 784 pConnection->libPointers.pvfGetChallenge = 0; 785 786 return SCARD_S_SUCCESS; 787} 788