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 : musclecard.c 22 Package: MuscleCard Framework 23 Author : David Corcoran 24 Date : 09/26/01 25 License: Copyright (C) 2001-2002 David Corcoran 26 <corcoran@linuxnet.com> 27 Purpose: This loads MuscleCard plug-ins and provides 28 functions for applications. 29 30 You may not remove this header from this file without 31 prior permission from the author. 32 33********************************************************************/ 34 35#ifndef WIN32 36#include "config.h" 37#else 38#include "../win32/win32_config.h" 39#endif 40 41#include "musclecard.h" 42#include "tokenfactory.h" 43#include "debuglog.h" 44 45#ifdef USE_THREAD_SAFETY 46#ifndef WIN32 47#include "wintypes.h" 48#endif 49#include "thread_generic.h" 50#include "sys_generic.h" 51#endif 52 53#ifdef USE_THREAD_SAFETY 54static PCSCLITE_MUTEX mcardMutex = PTHREAD_MUTEX_INITIALIZER; 55#endif 56 57#include <string.h> 58#include <stdlib.h> 59#include <stdio.h> 60 61static SCARDCONTEXT localHContext = 0; 62 63#ifdef USE_THREAD_SAFETY 64static PCSCLITE_THREAD_T callbackThread; 65#endif 66 67/* 68 * internal function 69 */ 70MSC_RV pcscToMSC(MSCLong32); 71MSC_RV MSCReEstablishConnection(MSCLPTokenConnection); 72 73void mscLockThread() 74{ 75#ifdef USE_THREAD_SAFETY 76 SYS_MutexLock(&mcardMutex); 77#endif 78} 79 80void mscUnLockThread() 81{ 82#ifdef USE_THREAD_SAFETY 83 SYS_MutexUnLock(&mcardMutex); 84#endif 85} 86 87/**************** MSC Connection Functions **************************/ 88 89MSC_RV MSCListTokens(MSCULong32 listScope, MSCLPTokenInfo tokenArray, 90 MSCPULong32 arrayLength) 91{ 92 93 MSCLong32 rv; 94 SCARD_READERSTATE_A rgReaderStates; 95 MSCTokenInfo tokenInfo; 96 MSCLPTokenInfo currentToken; 97 MSCULong32 tokensFound; 98 MSCULong32 readerLength; 99 char *readerList; 100 int i, strLoc; 101 102 readerLength = 0; 103 tokensFound = 0; 104 readerList = 0; 105 strLoc = 0; 106 i = 0; 107 108 if (arrayLength == 0) 109 return MSC_INVALID_PARAMETER; 110 if (listScope != MSC_LIST_KNOWN && 111 listScope != MSC_LIST_ALL && listScope != MSC_LIST_SLOTS) 112 { 113 return MSC_INVALID_PARAMETER; 114 } 115 116 mscLockThread(); 117 if (localHContext == 0) 118 { 119 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, 120 &localHContext); 121 if (pcscToMSC(rv) != MSC_SUCCESS) 122 { 123 localHContext = 0; 124 mscUnLockThread(); 125 return pcscToMSC(rv); 126 } 127 } 128 mscUnLockThread(); 129 130 /* 131 * Get the reader list size 132 */ 133 rv = SCardListReaders(localHContext, 0, readerList, &readerLength); 134 135 if (pcscToMSC(rv) != MSC_SUCCESS) 136 { 137 return pcscToMSC(rv); 138 } 139 140 readerList = (char *) malloc(sizeof(char) * readerLength); 141 142 if (readerList == 0) 143 { 144 return MSC_INTERNAL_ERROR; 145 } 146 147 rv = SCardListReaders(localHContext, 0, readerList, &readerLength); 148 149 /* 150 * Now that we have the readers, lets check their status 151 */ 152 for (i = 0; i < readerLength - 1; i++) 153 { 154 rgReaderStates.szReader = &readerList[i]; 155 rgReaderStates.dwCurrentState = SCARD_STATE_UNAWARE; 156 157 rv = SCardGetStatusChange(localHContext, INFINITE, 158 &rgReaderStates, 159 1); 160 161 if (pcscToMSC(rv) != MSC_SUCCESS) 162 { 163 if (readerList) 164 free(readerList); 165 return pcscToMSC(rv); 166 } 167 168 /* 169 * We only care about slots with a token unless stated 170 */ 171 if ((rgReaderStates.dwEventState & SCARD_STATE_PRESENT) || 172 (listScope == MSC_LIST_SLOTS)) 173 { 174 175 if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT) 176 { 177 /* 178 * We only care about supported tokens 179 */ 180 rv = TPSearchBundlesForAtr(rgReaderStates.rgbAtr, 181 rgReaderStates.cbAtr, &tokenInfo); 182 } 183 184 /* 185 * Success for this function 186 */ 187 if ((rv == 0) || (listScope == MSC_LIST_SLOTS) || 188 (listScope == MSC_LIST_ALL)) 189 { 190 191 /* 192 * We found something interesting to the application 193 */ 194 tokensFound += 1; 195 196 if ((tokensFound <= *arrayLength) && (tokenArray != 0)) 197 { 198 currentToken = &tokenArray[tokensFound - 1]; 199 currentToken->addParams = 0; 200 currentToken->addParamsSize = 0; 201 currentToken->tokenType = 0; /* Vinnie 1693 */ 202 203 if (rgReaderStates.dwEventState & SCARD_STATE_EMPTY) 204 { 205 currentToken->tokenType |= MSC_TOKEN_TYPE_REMOVED; 206 strncpy(currentToken->tokenName, 207 MSC_TOKEN_EMPTY_STR, MSC_MAXSIZE_TOKENAME); 208 } else if (rv == 0) 209 { 210 currentToken->tokenType |= MSC_TOKEN_TYPE_KNOWN; 211 strncpy(currentToken->tokenName, 212 tokenInfo.tokenName, MSC_MAXSIZE_TOKENAME); 213 } else 214 { 215 currentToken->tokenType |= MSC_TOKEN_TYPE_UNKNOWN; 216 strncpy(currentToken->tokenName, 217 MSC_TOKEN_UNKNOWN_STR, MSC_MAXSIZE_TOKENAME); 218 } 219 220 strncpy(currentToken->slotName, 221 rgReaderStates.szReader, MAX_READERNAME); 222 223 if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT) 224 { 225 memcpy(currentToken->tokenId, 226 rgReaderStates.rgbAtr, rgReaderStates.cbAtr); 227 currentToken->tokenIdLength = rgReaderStates.cbAtr; 228 } 229 else 230 { 231 memset(currentToken->tokenId, 0x00, MAX_ATR_SIZE); 232 currentToken->tokenIdLength = 0x00; 233 } 234 235 if (rv == 0) 236 { 237 memcpy(currentToken->tokenApp, 238 tokenInfo.tokenApp, tokenInfo.tokenAppLen); 239 currentToken->tokenAppLen = tokenInfo.tokenAppLen; 240 241 strncpy(currentToken->svProvider, 242 tokenInfo.svProvider, MSC_MAXSIZE_SVCPROV); 243 } else 244 { 245 memset(currentToken->tokenApp, 0x00, MSC_MAXSIZE_AID); 246 currentToken->tokenAppLen = 0x00; 247 memset(currentToken->svProvider, 0x00, MSC_MAXSIZE_SVCPROV); 248 } 249 250 currentToken->tokenState = rgReaderStates.dwEventState; 251 252 } 253 } 254 /* 255 * End of TPSearch success 256 */ 257 } 258 /* 259 * End of if token present 260 */ 261 while (readerList[++i] != 0) ; 262 } /* End of for .. readers */ 263 264 if (readerList) 265 free(readerList); 266 267 /* 268 * Application provides null requesting length 269 */ 270 if (tokenArray == 0) 271 { 272 *arrayLength = tokensFound; 273 return MSC_SUCCESS; 274 } 275 276 /* 277 * Provided length is too small 278 */ 279 if (*arrayLength < tokensFound) 280 { 281 *arrayLength = tokensFound; 282 return MSC_INSUFFICIENT_BUFFER; 283 } 284 285 *arrayLength = tokensFound; 286 return MSC_SUCCESS; 287} 288 289MSC_RV MSCEstablishConnection(MSCLPTokenInfo tokenStruct, 290 MSCULong32 sharingMode, 291 MSCPUChar8 applicationName, 292 MSCULong32 nameSize, 293 MSCLPTokenConnection pConnection) 294{ 295 MSCLong32 rv; 296 MSCULong32 tokenSize; 297 MSCLPTokenInfo tokenList; 298 MSCPVoid32 vInitFunction; 299 MSCPVoid32 vIdFunction; 300 MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection); 301 MSCLong32(*libPL_MSCIdentifyToken) (MSCLPTokenConnection); 302 MSCULong32 dwActiveProtocol; 303 int selectedIFD; 304 char slotName[MAX_READERNAME]; 305 MSCULong32 slotNameSize, slotState, slotProtocol; 306 MSCUChar8 tokenId[MAX_ATR_SIZE]; 307 MSCULong32 tokenIdLength; 308 309 tokenSize = 0; 310 tokenList = 0; 311 tokenSize = 0; 312 selectedIFD = -1; 313 tokenIdLength = sizeof(tokenId); 314 slotState = 0; 315 slotProtocol = 0; 316 slotNameSize = sizeof(slotName); 317 vIdFunction = 0; 318 vInitFunction = 0; 319 320 if (pConnection == NULL) 321 return MSC_INVALID_PARAMETER; 322 if (tokenStruct == NULL) 323 return MSC_INVALID_PARAMETER; 324 if (nameSize > MSC_MAXSIZE_AID) 325 return MSC_INVALID_PARAMETER; 326 327 pConnection->tokenLibHandle = 0; 328 pConnection->hContext = 0; 329 pConnection->tokenInfo.tokenIdLength = 0; 330 pConnection->shareMode = 0; 331 332 /* 333 * Check the token name strings 334 */ 335 if (sharingMode != MSC_SHARE_DIRECT) 336 { 337 if (strcmp(tokenStruct->tokenName, MSC_TOKEN_EMPTY_STR) == 0) 338 { 339 return MSC_TOKEN_REMOVED; 340 } else if (strcmp(tokenStruct->tokenName, 341 MSC_TOKEN_UNKNOWN_STR) == 0) 342 { 343 return MSC_UNRECOGNIZED_TOKEN; 344 } 345 } 346 347 /* 348 * Set up the initial connection to the resource manager 349 */ 350 351 mscLockThread(); 352 if (localHContext == 0) 353 { 354 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, 355 &localHContext); 356#ifdef MSC_DEBUG 357 DebugLogB("SCardEstablishContext returns %s\n", 358 pcsc_stringify_error(rv)); 359#endif 360 if (pcscToMSC(rv) != MSC_SUCCESS) 361 { 362 localHContext = 0; 363 mscUnLockThread(); 364 return pcscToMSC(rv); 365 } 366 367 pConnection->hContext = localHContext; 368 } else 369 { 370 pConnection->hContext = localHContext; 371 } 372 mscUnLockThread(); 373 374#ifdef WIN32 375 rv = SCardConnect(pConnection->hContext, tokenStruct->slotName, 376 SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 377 &pConnection->hCard, &dwActiveProtocol); 378#else 379 rv = SCardConnect(pConnection->hContext, tokenStruct->slotName, 380 sharingMode, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 381 &pConnection->hCard, &dwActiveProtocol); 382#endif 383 384#ifdef MSC_DEBUG 385 DebugLogB("SCardConnect returns %s\n", pcsc_stringify_error(rv)); 386#endif 387 388 if (pcscToMSC(rv) != MSC_SUCCESS) 389 { 390 return pcscToMSC(rv); 391 } 392 393 /* 394 * Set the sendPCI value based on the ActiveProtocol 395 */ 396 switch (dwActiveProtocol) 397 { 398 case SCARD_PROTOCOL_T0: 399 pConnection->ioType = SCARD_PCI_T0; 400 break; 401 case SCARD_PROTOCOL_T1: 402 pConnection->ioType = SCARD_PCI_T1; 403 break; 404 default: 405 pConnection->ioType = SCARD_PCI_RAW; 406 break; 407 } 408 409 /* 410 * Call SCardStatus, make sure the card information matches if it does 411 * not return an error. If it does, copy it 412 */ 413 414 rv = SCardStatus(pConnection->hCard, slotName, 415 &slotNameSize, &slotState, &slotProtocol, tokenId, &tokenIdLength); 416 417#ifdef MSC_DEBUG 418 DebugLogB("SCardStatus returns %s\n", pcsc_stringify_error(rv)); 419#endif 420 421 if (pcscToMSC(rv) != MSC_SUCCESS) 422 { 423 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 424 pConnection->hCard = 0; 425 return pcscToMSC(rv); 426 } 427 428 if ((sharingMode == MSC_SHARE_DIRECT) && (slotState & SCARD_ABSENT)) 429 { 430 431 /* 432 * They asked for direct mode and no card is inserted so we are 433 * done with this 434 */ 435 pConnection->shareMode = sharingMode; 436 return MSC_SUCCESS; 437 } 438 439 if ((tokenIdLength != tokenStruct->tokenIdLength) || 440 (strcmp(slotName, tokenStruct->slotName) != 0) || 441 (memcmp(tokenId, tokenStruct->tokenId, tokenIdLength) != 0)) 442 { 443 DebugLogA("Internal inconsistent values, ID, slotName\n"); 444 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 445 pConnection->hCard = 0; 446 return MSC_INCONSISTENT_STATUS; 447 } 448 449 memcpy(pConnection->tokenInfo.tokenId, tokenId, tokenIdLength); 450 pConnection->tokenInfo.tokenIdLength = tokenIdLength; 451 strncpy(pConnection->tokenInfo.slotName, tokenStruct->slotName, 452 MAX_READERNAME); 453 strncpy(pConnection->tokenInfo.tokenName, tokenStruct->tokenName, 454 MSC_MAXSIZE_TOKENAME); 455 456 /* 457 * Load the library for the token 458 */ 459 rv = TPLoadToken(pConnection); 460 461#ifdef MSC_DEBUG 462 DebugLogB("TPLoadToken returns %s\n", pcsc_stringify_error(rv)); 463#endif 464 465 if (rv != SCARD_S_SUCCESS) 466 { 467 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 468 pConnection->hCard = 0; 469 return pcscToMSC(rv); 470 } 471 472 /* 473 * Select the AID or initialization routine for the card 474 */ 475 vInitFunction = pConnection->libPointers.pvfInitializePlugin; 476 vIdFunction = pConnection->libPointers.pvfIdentifyToken; 477 478 if (vInitFunction == 0) 479 { 480 DebugLogB("Error: Card service failure: %s\n", 481 "InitializePlugin function missing"); 482 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 483 pConnection->hCard = 0; 484 return MSC_UNSUPPORTED_FEATURE; 485 } 486 487 if (vIdFunction == 0) 488 { 489 DebugLogB("Error: Card service failure: %s\n", 490 "IdentifyToken function missing"); 491 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 492 pConnection->hCard = 0; 493 return MSC_UNSUPPORTED_FEATURE; 494 } 495 496 libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection)) 497 vInitFunction; 498 499 libPL_MSCIdentifyToken = (MSCLong32(*)(MSCLPTokenConnection)) 500 vIdFunction; 501 502 rv = (*libPL_MSCInitializePlugin) (pConnection); 503 504 if (rv != MSC_SUCCESS) 505 { 506 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 507 if (pConnection->tokenLibHandle != 0) 508 { 509 TPUnloadToken(pConnection); 510 pConnection->tokenLibHandle = 0; 511 } 512 pConnection->hCard = 0; 513 } 514 515 if (sharingMode != MSC_SHARE_DIRECT) 516 { 517 518 if ((applicationName == 0) || (nameSize == 0)) 519 { 520 /* 521 * Use the default AID given by the Info.plist 522 */ 523 524 rv = (*libPL_MSCIdentifyToken) (pConnection); 525 } else 526 { 527 pConnection->tokenInfo.tokenAppLen = nameSize; 528 memcpy(pConnection->tokenInfo.tokenApp, 529 applicationName, nameSize); 530 rv = (*libPL_MSCIdentifyToken) (pConnection); 531 } 532 533#ifdef MSC_DEBUG 534 DebugLogB("MSCIdentifyToken returns %s\n", msc_error(rv)); 535#endif 536 537 if (rv != MSC_SUCCESS) 538 { 539 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD); 540 if (pConnection->tokenLibHandle != 0) 541 { 542 TPUnloadToken(pConnection); 543 pConnection->tokenLibHandle = 0; 544 } 545 pConnection->hCard = 0; 546 547 if (rv == MSC_SHARING_VIOLATION) 548 { 549 return rv; 550 } else 551 { 552 return MSC_UNRECOGNIZED_TOKEN; 553 } 554 } 555 } 556 557 pConnection->shareMode = sharingMode; 558 return MSC_SUCCESS; 559} 560 561MSC_RV MSCReleaseConnection(MSCLPTokenConnection pConnection, 562 MSCULong32 endAction) 563{ 564 565 MSCLong32 rv = SCARD_S_SUCCESS; 566 MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection); 567 MSCPVoid32 vFunction; 568 569 vFunction = 0; 570 571 if (pConnection == NULL) 572 return MSC_INVALID_PARAMETER; 573 if (pConnection->tokenLibHandle == 0 || 574 pConnection->hContext == 0 || pConnection->hCard == 0) 575 { 576 return MSC_INVALID_HANDLE; 577 } 578 579 /* 580 * Select finalization routine for the token plugin 581 */ 582 vFunction = pConnection->libPointers.pvfFinalizePlugin; 583 584 if (vFunction == 0) 585 { 586 DebugLogB("Error: Card service failure: %s\n", 587 "FinalizePlugin function missing"); 588 return MSC_INTERNAL_ERROR; 589 } 590 591 libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection)) 592 vFunction; 593 594 /* 595 * Stop and clean up the plugin 596 */ 597 rv = (*libPL_MSCFinalizePlugin) (pConnection); 598 599 /* 600 * Disconnect from the token 601 */ 602 if (pConnection->hCard != 0) 603 { 604 rv = SCardDisconnect(pConnection->hCard, endAction); 605 if (pcscToMSC(rv) != MSC_SUCCESS) 606 { 607 return pcscToMSC(rv); 608 } 609 } 610 611 /* 612 * Unload the token driver 613 */ 614 if (pConnection->tokenLibHandle != 0) 615 { 616 rv = TPUnloadToken(pConnection); 617 pConnection->tokenLibHandle = 0; 618 } 619 620 pConnection->tokenLibHandle = 0; 621 pConnection->hCard = 0; 622 pConnection->hContext = 0; 623 pConnection->shareMode = 0; 624 625 return MSC_SUCCESS; 626} 627 628MSC_RV MSCWaitForTokenEvent(MSCLPTokenInfo tokenArray, 629 MSCULong32 arraySize, 630 MSCULong32 timeoutValue) 631{ 632 633 MSCLong32 rv, rt; 634 LPSCARD_READERSTATE_A rgReaderStates; 635 MSCTokenInfo tokenInfo; 636 int i; 637 638 rgReaderStates = 0; 639 640 /* 641 * Allocate array of SCARD_READERSTATE_A structures, set UNAWARE on 642 * all of the structures to get the current status and then send them 643 * to GetStatusChange for blocking event 644 */ 645 646 if (arraySize == 0) 647 { 648 return MSC_SUCCESS; 649 } else if (arraySize > MSC_MAXSIZE_TOKENARRAY) 650 { 651 return MSC_INSUFFICIENT_BUFFER; 652 } 653 654 /* 655 * Set up the initial connection to the resource manager 656 */ 657 658 mscLockThread(); 659 if (localHContext == 0) 660 { 661 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, 662 &localHContext); 663 if (pcscToMSC(rv) != MSC_SUCCESS) 664 { 665 localHContext = 0; 666 mscUnLockThread(); 667 return pcscToMSC(rv); 668 } 669 } 670 mscUnLockThread(); 671 672 rgReaderStates = (LPSCARD_READERSTATE_A) 673 malloc(sizeof(SCARD_READERSTATE_A) * arraySize); 674 675 if (rgReaderStates == 0) 676 { 677 return MSC_INTERNAL_ERROR; 678 } 679 680 for (i = 0; i < arraySize; i++) 681 { 682 /* 683 * Make sure they don't pass an empty structure 684 */ 685 if (strlen(tokenArray[i].slotName) == 0) 686 { 687 free(rgReaderStates); 688 return MSC_INVALID_PARAMETER; 689 } 690 691 rgReaderStates[i].szReader = tokenArray[i].slotName; 692 rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE; 693 rgReaderStates[i].dwEventState = 0; 694 } 695 696 rv = SCardGetStatusChange(localHContext, timeoutValue, 697 rgReaderStates, arraySize); 698 699 if (rv != SCARD_S_SUCCESS) 700 { 701 free(rgReaderStates); 702 return pcscToMSC(rv); 703 } 704 705 for (i = 0; i < arraySize; i++) 706 { 707 if (tokenArray[i].tokenState == 0) 708 { 709 rgReaderStates[i].dwCurrentState = 710 rgReaderStates[i].dwEventState; 711 } else if (tokenArray[i].tokenState == MSC_STATE_UNAWARE) 712 { 713 rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE; 714 } else 715 { 716 rgReaderStates[i].dwCurrentState = tokenArray[i].tokenState; 717 } 718 rgReaderStates[i].dwEventState = 0; 719 } 720 721 rv = SCardGetStatusChange(localHContext, timeoutValue, 722 rgReaderStates, arraySize); 723 724 for (i = 0; i < arraySize; i++) 725 { 726 tokenArray[i].tokenState = rgReaderStates[i].dwEventState; 727 728 if (tokenArray[i].tokenState & MSC_STATE_CHANGED) 729 { 730 /* 731 * If it is removed, we need to update the names/etc 732 */ 733 if (tokenArray[i].tokenState & MSC_STATE_EMPTY) 734 { 735 memset(tokenArray[i].tokenId, 0x00, MAX_ATR_SIZE); 736 tokenArray[i].tokenIdLength = 0; 737 tokenArray[i].tokenType = MSC_TOKEN_TYPE_REMOVED; 738 strncpy(tokenArray[i].tokenName, MSC_TOKEN_EMPTY_STR, 739 MSC_MAXSIZE_TOKENAME); 740 } else if (tokenArray[i].tokenState & MSC_STATE_PRESENT) 741 { 742 memcpy(tokenArray[i].tokenId, rgReaderStates[i].rgbAtr, 743 rgReaderStates[i].cbAtr); 744 tokenArray[i].tokenIdLength = rgReaderStates[i].cbAtr; 745 746 rt = TPSearchBundlesForAtr(rgReaderStates[i].rgbAtr, 747 rgReaderStates[i].cbAtr, &tokenInfo); 748 /* 749 * Successfully found 750 */ 751 if (rt == 0) 752 { 753 tokenArray[i].tokenType = MSC_TOKEN_TYPE_KNOWN; 754 strncpy(tokenArray[i].tokenName, tokenInfo.tokenName, 755 MSC_MAXSIZE_TOKENAME); 756 } else 757 { 758 tokenArray[i].tokenType = MSC_TOKEN_TYPE_UNKNOWN; 759 strncpy(tokenArray[i].tokenName, MSC_TOKEN_UNKNOWN_STR, 760 MSC_MAXSIZE_TOKENAME); 761 } 762 } 763 } 764 } 765 766 free(rgReaderStates); 767 return pcscToMSC(rv); 768} 769 770MSC_RV MSCCancelEventWait(void) 771{ 772 773 MSCLong32 rv; 774 775 rv = SCardCancel(localHContext); 776 777 return pcscToMSC(rv); 778} 779 780/************************ Start of Callbacks ****************************/ 781#ifdef USE_THREAD_SAFETY 782void *_MSCEventThread(void *arg) 783{ 784 785 MSCLong32 rv; 786 MSCLPEventWaitInfo evlist; 787 MSCLong32 curToken; 788 789 if (arg == NULL) 790 { 791 SYS_ThreadExit(NULL); 792 } 793 794 evlist = (MSCLPEventWaitInfo) arg; 795 blockingContext = MSC_BLOCKSTATUS_BLOCKING; 796 797 while (1) 798 { 799 rv = MSCWaitForTokenEvent(evlist->tokenArray, 800 evlist->arraySize, 801 MSC_NO_TIMEOUT); 802 803 if (rv == MSC_SUCCESS) 804 { 805 (evlist->callBack) (evlist->tokenArray, 806 evlist->arraySize, 807 evlist->appData); 808 } else { 809 break; 810 811 } 812 813 if (blockingContext == MSC_BLOCKSTATUS_CANCELLING) 814 { 815 break; 816 } 817 } 818 819 for (curToken = 0; curToken < evlist->arraySize; curToken++) 820 { 821 if (evlist->tokenArray[curToken].addParams) 822 { 823 free(evlist->tokenArray[curToken].addParams); 824 } 825 } 826 827 828 free(evlist); 829 blockingContext = MSC_BLOCKSTATUS_RESUME; 830 SYS_ThreadExit(&rv); 831 832 return NULL; 833} 834 835MSC_RV MSCCallbackForTokenEvent(MSCLPTokenInfo tokenArray, 836 MSCULong32 arraySize, 837 MSCCallBack callBack, 838 MSCPVoid32 appData) 839{ 840 MSCLPEventWaitInfo evlist; 841 MSCULong32 curToken; 842 843 /* 844 * Create the event wait list 845 */ 846 evlist = (MSCLPEventWaitInfo) malloc(sizeof(MSCEventWaitInfo)); 847 848 if (evlist == NULL) 849 { 850 return MSC_INTERNAL_ERROR; 851 } 852 853 evlist->arraySize = arraySize; 854 evlist->tokenArray = malloc(sizeof(MSCTokenInfo) * arraySize); 855 evlist->appData = appData; 856 evlist->callBack = callBack; 857 858 if (evlist->tokenArray == NULL) 859 { 860 free(evlist); 861 return MSC_INTERNAL_ERROR; 862 } 863 864 mscLockThread(); 865 memcpy(evlist->tokenArray, tokenArray, 866 sizeof(MSCTokenInfo) * arraySize); 867 868 /* 869 * Copy the "extra" data 870 */ 871 for (curToken = 0; curToken < arraySize; curToken++) 872 { 873 if (tokenArray[curToken].addParams != NULL) 874 { 875 evlist->tokenArray[curToken].addParams = 876 malloc(evlist->tokenArray[curToken].addParamsSize); 877 memcpy((void *) (evlist->tokenArray[curToken].addParams), 878 &tokenArray[curToken], 879 evlist->tokenArray[curToken].addParamsSize); 880 881 } 882 } 883 mscUnLockThread(); 884 885 if (SYS_ThreadCreate(&callbackThread, THREAD_ATTR_DEFAULT, _MSCEventThread, 886 (void *) evlist) == 0) 887 { 888 return MSC_INTERNAL_ERROR; 889 } 890 891 return MSC_SUCCESS; 892} 893 894MSC_RV MSCCallbackCancelEvent() 895{ 896 897 LONG rv; 898 899 /* Release the thread and stop the GetStatusChange */ 900 if (blockingContext == MSC_BLOCKSTATUS_BLOCKING) 901 { 902 blockingContext = MSC_BLOCKSTATUS_CANCELLING; 903 rv = MSCCancelEventWait(); 904 905 SYS_ThreadJoin(&callbackThread, 0); 906 907 } 908 909 return MSC_SUCCESS; 910} 911 912#endif 913/************************** End of Callbacks *****************************/ 914 915MSC_RV MSCBeginTransaction(MSCLPTokenConnection pConnection) 916{ 917 918 MSCLong32 rv; 919 MSCLong32 ret; 920 921 if (localHContext == 0) 922 return MSC_INTERNAL_ERROR; 923 924 while (1) 925 { 926 rv = SCardBeginTransaction(pConnection->hCard); 927 ret = pcscToMSC(rv); 928 929 if (ret == MSC_SUCCESS) 930 break; 931 if (ret == MSC_TOKEN_RESET) 932 { 933 pConnection->tokenInfo.tokenType |= 934 MSC_TOKEN_TYPE_RESET; 935 ret = MSCReEstablishConnection(pConnection); 936 if (ret != MSC_SUCCESS) 937 break; 938 continue; 939 } else if (ret == MSC_TOKEN_REMOVED) 940 { 941 pConnection->tokenInfo.tokenType = 942 MSC_TOKEN_TYPE_REMOVED; 943 return ret; 944 } 945 } 946 947 return ret; 948} 949 950MSC_RV MSCEndTransaction(MSCLPTokenConnection pConnection, 951 MSCULong32 endAction) 952{ 953 954 MSCLong32 rv; 955 MSCLong32 ret; 956 957 if (localHContext == 0) 958 return MSC_INTERNAL_ERROR; 959 960 while (1) 961 { 962 rv = SCardEndTransaction(pConnection->hCard, endAction); 963 ret = pcscToMSC(rv); 964 965 if (ret == MSC_SUCCESS) 966 break; 967 if (ret == MSC_TOKEN_RESET) 968 { 969 pConnection->tokenInfo.tokenType |= 970 MSC_TOKEN_TYPE_RESET; 971 ret = MSCReEstablishConnection(pConnection); 972 if (ret != MSC_SUCCESS) 973 break; 974 continue; 975 } else if (ret == MSC_TOKEN_REMOVED) 976 { 977 pConnection->tokenInfo.tokenType = 978 MSC_TOKEN_TYPE_REMOVED; 979 return ret; 980 } 981 } 982 983 return ret; 984} 985 986MSC_RV MSCWriteFramework(MSCLPTokenConnection pConnection, 987 MSCLPInitTokenParams pInitParams) 988{ 989 990 MSCLong32 rv; 991 MSCPVoid32 vFunction; 992 MSCLong32(*libMSCWriteFramework) (MSCLPTokenConnection, 993 MSCLPInitTokenParams); 994 995 if (pConnection == NULL) 996 return MSC_INVALID_PARAMETER; 997 if (localHContext == 0) 998 return MSC_INTERNAL_ERROR; 999 1000 vFunction = pConnection->libPointers.pvfWriteFramework; 1001 1002 if (vFunction != 0) 1003 { 1004 libMSCWriteFramework = (MSCLong32(*)(MSCLPTokenConnection, 1005 MSCLPInitTokenParams)) vFunction; 1006 rv = (*libMSCWriteFramework) (pConnection, pInitParams); 1007 1008 } else 1009 { 1010 return MSC_UNSUPPORTED_FEATURE; 1011 } 1012 1013 return rv; 1014} 1015 1016/* 1017 * Real MSC functions 1018 */ 1019 1020MSC_RV MSCGetStatus(MSCLPTokenConnection pConnection, 1021 MSCLPStatusInfo pStatusInfo) 1022{ 1023 MSCLong32 rv; 1024 MSCPVoid32 vFunction; 1025 MSCLong32(*libMSCGetStatus) (MSCLPTokenConnection, MSCLPStatusInfo); 1026 1027 if (pConnection == NULL) 1028 return MSC_INVALID_PARAMETER; 1029 if (localHContext == 0) 1030 return MSC_INTERNAL_ERROR; 1031 1032 vFunction = pConnection->libPointers.pvfGetStatus; 1033 1034 if (vFunction != 0) 1035 { 1036 libMSCGetStatus = (MSCLong32(*)(MSCLPTokenConnection, 1037 MSCLPStatusInfo)) vFunction; 1038 rv = (*libMSCGetStatus) (pConnection, pStatusInfo); 1039 1040 } else 1041 { 1042 return MSC_UNSUPPORTED_FEATURE; 1043 } 1044 1045 return rv; 1046} 1047 1048MSC_RV MSCGetCapabilities(MSCLPTokenConnection pConnection, MSCULong32 Tag, 1049 MSCPUChar8 Value, MSCPULong32 Length) 1050{ 1051 MSCLong32 rv; 1052 MSCPVoid32 vFunction; 1053 MSCLong32(*libMSCGetCapabilities) (MSCLPTokenConnection, MSCULong32, 1054 MSCPUChar8, MSCPULong32); 1055 1056 if (pConnection == NULL) 1057 return MSC_INVALID_PARAMETER; 1058 if (localHContext == 0) 1059 return MSC_INTERNAL_ERROR; 1060 1061 vFunction = pConnection->libPointers.pvfGetCapabilities; 1062 1063 if (vFunction != 0) 1064 { 1065 libMSCGetCapabilities = 1066 (MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8, 1067 MSCPULong32)) vFunction; 1068 rv = (*libMSCGetCapabilities) (pConnection, Tag, Value, Length); 1069 1070 } else 1071 { 1072 return MSC_UNSUPPORTED_FEATURE; 1073 } 1074 1075 return rv; 1076} 1077 1078MSC_RV MSCExtendedFeature(MSCLPTokenConnection pConnection, 1079 MSCULong32 extFeature, MSCPUChar8 outData, 1080 MSCULong32 outLength, MSCPUChar8 inData, MSCPULong32 inLength) 1081{ 1082 MSCLong32 rv; 1083 MSCPVoid32 vFunction; 1084 MSCLong32(*libMSCExtendedFeature) (MSCLPTokenConnection, MSCULong32, 1085 MSCPUChar8, MSCULong32, MSCPUChar8, MSCPULong32); 1086 1087 if (pConnection == NULL) 1088 return MSC_INVALID_PARAMETER; 1089 if (localHContext == 0) 1090 return MSC_INTERNAL_ERROR; 1091 1092 vFunction = pConnection->libPointers.pvfExtendedFeature; 1093 1094 if (vFunction != 0) 1095 { 1096 libMSCExtendedFeature = 1097 (MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8, 1098 MSCULong32, MSCPUChar8, MSCPULong32)) vFunction; 1099 rv = (*libMSCExtendedFeature) (pConnection, extFeature, outData, 1100 outLength, inData, inLength); 1101 1102 } else 1103 { 1104 return MSC_UNSUPPORTED_FEATURE; 1105 } 1106 1107 return rv; 1108} 1109 1110MSC_RV MSCGenerateKeys(MSCLPTokenConnection pConnection, 1111 MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum, MSCLPGenKeyParams pParams) 1112{ 1113 MSCLong32 rv; 1114 MSCPVoid32 vFunction; 1115 MSCLong32(*libMSCGenerateKeys) (MSCLPTokenConnection, MSCUChar8, 1116 MSCUChar8, MSCLPGenKeyParams); 1117 1118 if (pConnection == NULL) 1119 return MSC_INVALID_PARAMETER; 1120 if (localHContext == 0) 1121 return MSC_INTERNAL_ERROR; 1122 1123 vFunction = pConnection->libPointers.pvfGenerateKeys; 1124 1125 if (vFunction != 0) 1126 { 1127 libMSCGenerateKeys = (MSCLong32(*)(MSCLPTokenConnection, 1128 MSCUChar8, MSCUChar8, 1129 MSCLPGenKeyParams)) 1130 vFunction; 1131 rv = (*libMSCGenerateKeys) (pConnection, prvKeyNum, pubKeyNum, 1132 pParams); 1133 1134 } else 1135 { 1136 return MSC_UNSUPPORTED_FEATURE; 1137 } 1138 1139 return rv; 1140} 1141 1142MSC_RV MSCImportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum, 1143 MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,MSCULong32 keyBlobSize, 1144 MSCLPKeyPolicy keyPolicy, MSCPVoid32 pAddParams, 1145 MSCUChar8 addParamsSize) 1146{ 1147 MSCLong32 rv; 1148 MSCPVoid32 vFunction; 1149 MSCLong32(*libMSCImportKey) (MSCLPTokenConnection, MSCUChar8, 1150 MSCLPKeyACL, MSCPUChar8, 1151 MSCULong32, MSCLPKeyPolicy, MSCPVoid32, 1152 MSCUChar8); 1153 1154 if (pConnection == NULL) 1155 return MSC_INVALID_PARAMETER; 1156 if (localHContext == 0) 1157 return MSC_INTERNAL_ERROR; 1158 1159 vFunction = pConnection->libPointers.pvfImportKey; 1160 1161 if (vFunction != 0) 1162 { 1163 libMSCImportKey = (MSCLong32(*)(MSCLPTokenConnection, 1164 MSCUChar8, 1165 MSCLPKeyACL, MSCPUChar8, 1166 MSCULong32, MSCLPKeyPolicy, 1167 MSCPVoid32, MSCUChar8)) 1168 vFunction; 1169 1170 rv = (*libMSCImportKey) (pConnection, keyNum, 1171 pKeyACL, pKeyBlob, keyBlobSize, 1172 keyPolicy, pAddParams, addParamsSize); 1173 1174 } else 1175 { 1176 return MSC_UNSUPPORTED_FEATURE; 1177 } 1178 1179 return rv; 1180} 1181 1182MSC_RV MSCExportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum, 1183 MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize, 1184 MSCPVoid32 pAddParams, MSCUChar8 addParamsSize) 1185{ 1186 MSCLong32 rv; 1187 MSCPVoid32 vFunction; 1188 MSCLong32(*libMSCExportKey) (MSCLPTokenConnection, MSCUChar8, 1189 MSCPUChar8, MSCPULong32, MSCPVoid32, MSCUChar8); 1190 1191 if (pConnection == NULL) 1192 return MSC_INVALID_PARAMETER; 1193 if (localHContext == 0) 1194 return MSC_INTERNAL_ERROR; 1195 1196 vFunction = pConnection->libPointers.pvfExportKey; 1197 1198 if (vFunction != 0) 1199 { 1200 libMSCExportKey = (MSCLong32(*)(MSCLPTokenConnection, 1201 MSCUChar8, MSCPUChar8, 1202 MSCPULong32, MSCPVoid32, 1203 MSCUChar8)) vFunction; 1204 1205 rv = (*libMSCExportKey) (pConnection, keyNum, pKeyBlob, 1206 keyBlobSize, pAddParams, addParamsSize); 1207 1208 } else 1209 { 1210 return MSC_UNSUPPORTED_FEATURE; 1211 } 1212 1213 return rv; 1214} 1215 1216MSC_RV MSCComputeCrypt(MSCLPTokenConnection pConnection, 1217 MSCLPCryptInit cryptInit, MSCPUChar8 pInputData, 1218 MSCULong32 inputDataSize, MSCPUChar8 pOutputData, 1219 MSCPULong32 outputDataSize) 1220{ 1221 MSCLong32 rv; 1222 MSCPVoid32 vFunction; 1223 MSCLong32(*libMSCComputeCrypt) (MSCLPTokenConnection, MSCLPCryptInit, 1224 MSCPUChar8, MSCULong32, MSCPUChar8, 1225 MSCPULong32); 1226 1227 if (pConnection == NULL) 1228 return MSC_INVALID_PARAMETER; 1229 if (localHContext == 0) 1230 return MSC_INTERNAL_ERROR; 1231 1232 vFunction = pConnection->libPointers.pvfComputeCrypt; 1233 1234 if (vFunction != 0) 1235 { 1236 libMSCComputeCrypt = 1237 (MSCLong32(*)(MSCLPTokenConnection, MSCLPCryptInit, 1238 MSCPUChar8, MSCULong32, MSCPUChar8, 1239 MSCPULong32)) vFunction; 1240 rv = (*libMSCComputeCrypt) (pConnection, cryptInit, pInputData, 1241 inputDataSize, pOutputData, 1242 outputDataSize); 1243 1244 } else 1245 { 1246 return MSC_UNSUPPORTED_FEATURE; 1247 } 1248 1249 return rv; 1250} 1251 1252MSC_RV MSCExtAuthenticate(MSCLPTokenConnection pConnection, 1253 MSCUChar8 keyNum, MSCUChar8 cipherMode, 1254 MSCUChar8 cipherDirection, 1255 MSCPUChar8 pData, MSCULong32 dataSize) 1256{ 1257 MSCLong32 rv; 1258 MSCPVoid32 vFunction; 1259 MSCLong32(*libMSCExtAuthenticate) (MSCLPTokenConnection, MSCUChar8, 1260 MSCUChar8, MSCUChar8, MSCPUChar8, 1261 MSCULong32); 1262 1263 if (pConnection == NULL) 1264 return MSC_INVALID_PARAMETER; 1265 if (localHContext == 0) 1266 return MSC_INTERNAL_ERROR; 1267 1268 vFunction = pConnection->libPointers.pvfExtAuthenticate; 1269 1270 if (vFunction != 0) 1271 { 1272 libMSCExtAuthenticate = 1273 (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1274 MSCUChar8, MSCUChar8, MSCPUChar8, 1275 MSCULong32)) vFunction; 1276 rv = (*libMSCExtAuthenticate) (pConnection, keyNum, cipherMode, 1277 cipherDirection, pData, dataSize); 1278 } else 1279 { 1280 return MSC_UNSUPPORTED_FEATURE; 1281 } 1282 1283 return rv; 1284} 1285 1286MSC_RV MSCListKeys(MSCLPTokenConnection pConnection, MSCUChar8 seqOption, 1287 MSCLPKeyInfo pKeyInfo) 1288{ 1289 MSCLong32 rv; 1290 MSCPVoid32 vFunction; 1291 MSCLong32(*libMSCListKeys) (MSCLPTokenConnection, MSCUChar8, 1292 MSCLPKeyInfo); 1293 1294 if (pConnection == NULL) 1295 return MSC_INVALID_PARAMETER; 1296 if (localHContext == 0) 1297 return MSC_INTERNAL_ERROR; 1298 1299 vFunction = pConnection->libPointers.pvfListKeys; 1300 1301 if (vFunction != 0) 1302 { 1303 libMSCListKeys = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1304 MSCLPKeyInfo)) vFunction; 1305 rv = (*libMSCListKeys) (pConnection, seqOption, pKeyInfo); 1306 1307 } else 1308 { 1309 return MSC_UNSUPPORTED_FEATURE; 1310 } 1311 1312 return rv; 1313} 1314 1315MSC_RV MSCCreatePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum, 1316 MSCUChar8 pinAttempts, MSCPUChar8 pPinCode, 1317 MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode, 1318 MSCUChar8 unblockCodeSize) 1319{ 1320 MSCLong32 rv; 1321 MSCPVoid32 vFunction; 1322 MSCLong32(*libMSCCreatePIN) (MSCLPTokenConnection, MSCUChar8, 1323 MSCUChar8, MSCPUChar8, MSCULong32, MSCPUChar8, MSCUChar8); 1324 1325 if (pConnection == NULL) 1326 return MSC_INVALID_PARAMETER; 1327 if (localHContext == 0) 1328 return MSC_INTERNAL_ERROR; 1329 1330 vFunction = pConnection->libPointers.pvfCreatePIN; 1331 1332 if (vFunction != 0) 1333 { 1334 libMSCCreatePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1335 MSCUChar8, MSCPUChar8, 1336 MSCULong32, MSCPUChar8, MSCUChar8)) vFunction; 1337 rv = (*libMSCCreatePIN) (pConnection, pinNum, pinAttempts, 1338 pPinCode, pinCodeSize, pUnblockCode, unblockCodeSize); 1339 1340 } else 1341 { 1342 return MSC_UNSUPPORTED_FEATURE; 1343 } 1344 1345 return rv; 1346} 1347 1348MSC_RV MSCVerifyPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum, 1349 MSCPUChar8 pPinCode, MSCULong32 pinCodeSize) 1350{ 1351 MSCLong32 rv; 1352 MSCPVoid32 vFunction; 1353 MSCLong32(*libMSCVerifyPIN) (MSCLPTokenConnection, MSCUChar8, 1354 MSCPUChar8, MSCULong32); 1355 1356 if (pConnection == NULL) 1357 return MSC_INVALID_PARAMETER; 1358 if (localHContext == 0) 1359 return MSC_INTERNAL_ERROR; 1360 1361 vFunction = pConnection->libPointers.pvfVerifyPIN; 1362 1363 if (vFunction != 0) 1364 { 1365 libMSCVerifyPIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1366 MSCPUChar8, MSCULong32)) vFunction; 1367 rv = (*libMSCVerifyPIN) (pConnection, pinNum, pPinCode, 1368 pinCodeSize); 1369 1370 } else 1371 { 1372 return MSC_UNSUPPORTED_FEATURE; 1373 } 1374 1375 return rv; 1376} 1377 1378MSC_RV MSCChangePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum, 1379 MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize, 1380 MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize) 1381{ 1382 MSCLong32 rv; 1383 MSCPVoid32 vFunction; 1384 MSCLong32(*libMSCChangePIN) (MSCLPTokenConnection, MSCUChar8, 1385 MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8); 1386 1387 if (pConnection == NULL) 1388 return MSC_INVALID_PARAMETER; 1389 if (localHContext == 0) 1390 return MSC_INTERNAL_ERROR; 1391 1392 vFunction = pConnection->libPointers.pvfChangePIN; 1393 1394 if (vFunction != 0) 1395 { 1396 libMSCChangePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1397 MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8)) vFunction; 1398 rv = (*libMSCChangePIN) (pConnection, pinNum, pOldPinCode, 1399 oldPinCodeSize, pNewPinCode, newPinCodeSize); 1400 1401 } else 1402 { 1403 return MSC_UNSUPPORTED_FEATURE; 1404 } 1405 1406 return rv; 1407} 1408 1409MSC_RV MSCUnblockPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum, 1410 MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize) 1411{ 1412 MSCLong32 rv; 1413 MSCPVoid32 vFunction; 1414 MSCLong32(*libMSCUnblockPIN) (MSCLPTokenConnection, MSCUChar8, 1415 MSCPUChar8, MSCULong32); 1416 1417 if (pConnection == NULL) 1418 return MSC_INVALID_PARAMETER; 1419 if (localHContext == 0) 1420 return MSC_INTERNAL_ERROR; 1421 1422 vFunction = pConnection->libPointers.pvfUnblockPIN; 1423 1424 if (vFunction != 0) 1425 { 1426 libMSCUnblockPIN = (MSCLong32(*)(MSCLPTokenConnection, 1427 MSCUChar8, MSCPUChar8, MSCULong32)) vFunction; 1428 rv = (*libMSCUnblockPIN) (pConnection, pinNum, pUnblockCode, 1429 unblockCodeSize); 1430 1431 } else 1432 { 1433 return MSC_UNSUPPORTED_FEATURE; 1434 } 1435 1436 return rv; 1437} 1438 1439MSC_RV MSCListPINs(MSCLPTokenConnection pConnection, 1440 MSCPUShort16 pPinBitMask) 1441{ 1442 MSCLong32 rv; 1443 MSCPVoid32 vFunction; 1444 MSCLong32(*libMSCListPINs) (MSCLPTokenConnection, MSCPUShort16); 1445 1446 if (pConnection == NULL) 1447 return MSC_INVALID_PARAMETER; 1448 if (localHContext == 0) 1449 return MSC_INTERNAL_ERROR; 1450 1451 vFunction = pConnection->libPointers.pvfListPINs; 1452 1453 if (vFunction != 0) 1454 { 1455 libMSCListPINs = (MSCLong32(*)(MSCLPTokenConnection, 1456 MSCPUShort16)) vFunction; 1457 rv = (*libMSCListPINs) (pConnection, pPinBitMask); 1458 1459 } else 1460 { 1461 return MSC_UNSUPPORTED_FEATURE; 1462 } 1463 1464 return rv; 1465} 1466 1467MSC_RV MSCCreateObject(MSCLPTokenConnection pConnection, 1468 MSCString objectID, MSCULong32 objectSize, MSCLPObjectACL pObjectACL) 1469{ 1470 MSCLong32 rv; 1471 MSCPVoid32 vFunction; 1472 MSCLong32(*libMSCCreateObject) (MSCLPTokenConnection, MSCString, 1473 MSCULong32, MSCLPObjectACL); 1474 1475 if (pConnection == NULL) 1476 return MSC_INVALID_PARAMETER; 1477 if (localHContext == 0) 1478 return MSC_INTERNAL_ERROR; 1479 1480 vFunction = pConnection->libPointers.pvfCreateObject; 1481 1482 if (vFunction != 0) 1483 { 1484 libMSCCreateObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString, 1485 MSCULong32, MSCLPObjectACL)) vFunction; 1486 rv = (*libMSCCreateObject) (pConnection, objectID, objectSize, 1487 pObjectACL); 1488 } else 1489 { 1490 return MSC_UNSUPPORTED_FEATURE; 1491 } 1492 1493 return rv; 1494} 1495 1496MSC_RV MSCDeleteObject(MSCLPTokenConnection pConnection, 1497 MSCString objectID, MSCUChar8 zeroFlag) 1498{ 1499 MSCLong32 rv; 1500 MSCPVoid32 vFunction; 1501 MSCLong32(*libMSCDeleteObject) (MSCLPTokenConnection, MSCString, 1502 MSCUChar8); 1503 1504 if (pConnection == NULL) 1505 return MSC_INVALID_PARAMETER; 1506 if (localHContext == 0) 1507 return MSC_INTERNAL_ERROR; 1508 1509 vFunction = pConnection->libPointers.pvfDeleteObject; 1510 1511 if (vFunction != 0) 1512 { 1513 libMSCDeleteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString, 1514 MSCUChar8)) vFunction; 1515 rv = (*libMSCDeleteObject) (pConnection, objectID, zeroFlag); 1516 1517 } else 1518 { 1519 return MSC_UNSUPPORTED_FEATURE; 1520 } 1521 1522 return rv; 1523} 1524 1525MSC_RV MSCWriteObject(MSCLPTokenConnection pConnection, 1526 MSCString objectID, MSCULong32 offSet, 1527 MSCPUChar8 pInputData, MSCULong32 dataSize, 1528 LPRWEventCallback rwCallback, MSCPVoid32 addParams) 1529{ 1530 MSC_RV rv = MSC_UNSPECIFIED_ERROR; 1531 MSCULong32 objectSize; 1532 int totalSteps, stepInterval; 1533 MSC_RV(*callBackFunction) (void *, int); 1534 MSCPVoid32 vFunction; 1535 MSCLong32(*libMSCWriteObject) (MSCLPTokenConnection, MSCString, 1536 MSCULong32, MSCPUChar8, MSCUChar8); 1537 int i; 1538 1539 if (pConnection == NULL) 1540 return MSC_INVALID_PARAMETER; 1541 if (localHContext == 0) 1542 return MSC_INTERNAL_ERROR; 1543 1544 vFunction = pConnection->libPointers.pvfWriteObject; 1545 callBackFunction = (MSC_RV(*)(void *, int)) rwCallback; 1546 objectSize = dataSize; 1547 1548 if (vFunction == 0) 1549 { 1550 return MSC_UNSUPPORTED_FEATURE; 1551 } 1552 1553 libMSCWriteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString, 1554 MSCULong32, MSCPUChar8, MSCUChar8)) 1555 vFunction; 1556 1557 /* 1558 * Figure out the number of steps total and present this in a percent 1559 * step basis 1560 */ 1561 1562 totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1; 1563 stepInterval = MSC_PERCENT_STEPSIZE / totalSteps; 1564 1565 for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++) 1566 { 1567 rv = (*libMSCWriteObject) (pConnection, objectID, 1568 i * MSC_SIZEOF_KEYPACKET + offSet, 1569 &pInputData[i * MSC_SIZEOF_KEYPACKET], 1570 MSC_SIZEOF_KEYPACKET); 1571 if (rv != MSC_SUCCESS) 1572 { 1573 return rv; 1574 } 1575 1576 if (rwCallback) 1577 { 1578 if ((*callBackFunction) (addParams, 1579 stepInterval * i) == MSC_CANCELLED) 1580 { 1581 return MSC_CANCELLED; 1582 } 1583 } 1584 } 1585 1586 if (objectSize % MSC_SIZEOF_KEYPACKET) 1587 { 1588 1589 rv = (*libMSCWriteObject) (pConnection, objectID, 1590 i * MSC_SIZEOF_KEYPACKET + offSet, 1591 &pInputData[i * MSC_SIZEOF_KEYPACKET], 1592 objectSize % MSC_SIZEOF_KEYPACKET); 1593 1594 if (rv != MSC_SUCCESS) 1595 { 1596 return rv; 1597 } 1598 } 1599 1600 if (rwCallback) 1601 { 1602 (*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE); 1603 } 1604 1605 return rv; 1606} 1607 1608MSC_RV MSCReadObject(MSCLPTokenConnection pConnection, 1609 MSCString objectID, MSCULong32 offSet, 1610 MSCPUChar8 pOutputData, MSCULong32 dataSize, 1611 LPRWEventCallback rwCallback, 1612 MSCPVoid32 addParams) 1613{ 1614 1615 MSC_RV rv = MSC_UNSPECIFIED_ERROR; 1616 MSCULong32 objectSize; 1617 int totalSteps, stepInterval; 1618 MSC_RV(*callBackFunction) (void *, int); 1619 MSCPVoid32 vFunction; 1620 MSCLong32(*libMSCReadObject) (MSCLPTokenConnection, MSCString, 1621 MSCULong32, MSCPUChar8, MSCUChar8); 1622 int i; 1623 1624 if (pConnection == NULL) 1625 return MSC_INVALID_PARAMETER; 1626 if (localHContext == 0) 1627 return MSC_INTERNAL_ERROR; 1628 1629 vFunction = pConnection->libPointers.pvfReadObject; 1630 callBackFunction = (MSC_RV(*)(void *, int)) rwCallback; 1631 objectSize = dataSize; 1632 1633 if (vFunction == 0) 1634 { 1635 return MSC_UNSUPPORTED_FEATURE; 1636 } 1637 1638 libMSCReadObject = (MSCLong32(*)(MSCLPTokenConnection, 1639 MSCString, MSCULong32, 1640 MSCPUChar8, MSCUChar8)) 1641 vFunction; 1642 1643 /* 1644 * Figure out the number of steps total and present this in a percent 1645 * step basis 1646 */ 1647 1648 totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1; 1649 stepInterval = MSC_PERCENT_STEPSIZE / totalSteps; 1650 1651 for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++) 1652 { 1653 rv = (*libMSCReadObject) (pConnection, objectID, 1654 i * MSC_SIZEOF_KEYPACKET + offSet, 1655 &pOutputData[i * MSC_SIZEOF_KEYPACKET], 1656 MSC_SIZEOF_KEYPACKET); 1657 1658 if (rv != MSC_SUCCESS) 1659 { 1660 return rv; 1661 } 1662 1663 if (rwCallback) 1664 { 1665 if ((*callBackFunction) (addParams, 1666 stepInterval * i) == MSC_CANCELLED) 1667 { 1668 return MSC_CANCELLED; 1669 } 1670 } 1671 } 1672 1673 if (objectSize % MSC_SIZEOF_KEYPACKET) 1674 { 1675 rv = (*libMSCReadObject) (pConnection, objectID, 1676 i * MSC_SIZEOF_KEYPACKET + offSet, 1677 &pOutputData[i * MSC_SIZEOF_KEYPACKET], 1678 objectSize % MSC_SIZEOF_KEYPACKET); 1679 1680 if (rv != MSC_SUCCESS) 1681 { 1682 return rv; 1683 } 1684 } 1685 1686 if (rwCallback) 1687 { 1688 (*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE); 1689 } 1690 1691 return rv; 1692} 1693 1694MSC_RV MSCListObjects(MSCLPTokenConnection pConnection, 1695 MSCUChar8 seqOption, MSCLPObjectInfo pObjectInfo) 1696{ 1697 MSCLong32 rv; 1698 MSCPVoid32 vFunction; 1699 MSCLong32(*libMSCListObjects) (MSCLPTokenConnection, MSCUChar8, 1700 MSCLPObjectInfo); 1701 1702 if (pConnection == NULL) 1703 return MSC_INVALID_PARAMETER; 1704 if (localHContext == 0) 1705 return MSC_INTERNAL_ERROR; 1706 1707 vFunction = pConnection->libPointers.pvfListObjects; 1708 1709 if (vFunction != 0) 1710 { 1711 libMSCListObjects = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8, 1712 MSCLPObjectInfo)) vFunction; 1713 rv = (*libMSCListObjects) (pConnection, seqOption, pObjectInfo); 1714 1715 } else 1716 { 1717 return MSC_UNSUPPORTED_FEATURE; 1718 } 1719 1720 return rv; 1721} 1722 1723MSC_RV MSCLogoutAll(MSCLPTokenConnection pConnection) 1724{ 1725 1726 MSCLong32 rv; 1727 MSCPVoid32 vFunction; 1728 MSCLong32(*libMSCLogoutAll) (MSCLPTokenConnection); 1729 1730 if (pConnection == NULL) 1731 return MSC_INVALID_PARAMETER; 1732 if (localHContext == 0) 1733 return MSC_INTERNAL_ERROR; 1734 1735 vFunction = pConnection->libPointers.pvfLogoutAll; 1736 1737 if (vFunction != 0) 1738 { 1739 libMSCLogoutAll = (MSCLong32(*)(MSCLPTokenConnection)) vFunction; 1740 rv = (*libMSCLogoutAll) (pConnection); 1741 1742 } else 1743 { 1744 return MSC_UNSUPPORTED_FEATURE; 1745 } 1746 1747 return rv; 1748} 1749 1750MSC_RV MSCGetChallenge(MSCLPTokenConnection pConnection, MSCPUChar8 pSeed, 1751 MSCUShort16 seedSize, MSCPUChar8 pRandomData, 1752 MSCUShort16 randomDataSize) 1753{ 1754 MSCLong32 rv; 1755 MSCPVoid32 vFunction; 1756 MSCLong32(*libMSCGetChallenge) (MSCLPTokenConnection, MSCPUChar8, 1757 MSCUShort16, MSCPUChar8, MSCUShort16); 1758 1759 if (pConnection == NULL) 1760 return MSC_INVALID_PARAMETER; 1761 if (localHContext == 0) 1762 return MSC_INTERNAL_ERROR; 1763 1764 vFunction = pConnection->libPointers.pvfGetChallenge; 1765 1766 if (vFunction != 0) 1767 { 1768 libMSCGetChallenge = (MSCLong32(*)(MSCLPTokenConnection, 1769 MSCPUChar8, MSCUShort16, 1770 MSCPUChar8, MSCUShort16)) vFunction; 1771 rv = (*libMSCGetChallenge) (pConnection, pSeed, seedSize, 1772 pRandomData, randomDataSize); 1773 1774 } else 1775 { 1776 return MSC_UNSUPPORTED_FEATURE; 1777 } 1778 1779 return rv; 1780} 1781 1782MSC_RV MSCGetKeyAttributes(MSCLPTokenConnection pConnection, 1783 MSCUChar8 keyNumber, MSCLPKeyInfo pKeyInfo) 1784{ 1785 1786 MSC_RV rv; 1787 MSCKeyInfo keyInfo; 1788 1789 if (pConnection == NULL) 1790 return MSC_INVALID_PARAMETER; 1791 if (localHContext == 0) 1792 return MSC_INTERNAL_ERROR; 1793 1794 rv = MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyInfo); 1795 1796 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) 1797 { 1798 return rv; 1799 } 1800 1801 if (rv == MSC_SEQUENCE_END) 1802 { 1803 return MSC_INVALID_PARAMETER; 1804 } 1805 1806 if (keyNumber == keyInfo.keyNum) 1807 { 1808 pKeyInfo->keyNum = keyInfo.keyNum; 1809 pKeyInfo->keyType = keyInfo.keyType; 1810 pKeyInfo->keySize = keyInfo.keySize; 1811 1812 pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode; 1813 pKeyInfo->keyPolicy.cipherDirection = 1814 keyInfo.keyPolicy.cipherDirection; 1815 1816 pKeyInfo->keyACL.readPermission = 1817 keyInfo.keyACL.readPermission; 1818 pKeyInfo->keyACL.writePermission = 1819 keyInfo.keyACL.writePermission; 1820 pKeyInfo->keyACL.usePermission = 1821 keyInfo.keyACL.usePermission; 1822 1823 return MSC_SUCCESS; 1824 } 1825 1826 do 1827 { 1828 rv = MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyInfo); 1829 if (keyNumber == keyInfo.keyNum) 1830 break; 1831 } 1832 while (rv == MSC_SUCCESS); 1833 1834 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) 1835 { 1836 return rv; 1837 } 1838 1839 if (rv == MSC_SEQUENCE_END) 1840 { 1841 return MSC_INVALID_PARAMETER; 1842 } 1843 1844 pKeyInfo->keyNum = keyInfo.keyNum; 1845 pKeyInfo->keyType = keyInfo.keyType; 1846 pKeyInfo->keySize = keyInfo.keySize; 1847 1848 pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode; 1849 pKeyInfo->keyPolicy.cipherDirection = 1850 keyInfo.keyPolicy.cipherDirection; 1851 1852 pKeyInfo->keyACL.readPermission = keyInfo.keyACL.readPermission; 1853 pKeyInfo->keyACL.writePermission = keyInfo.keyACL.writePermission; 1854 pKeyInfo->keyACL.usePermission = keyInfo.keyACL.usePermission; 1855 1856 return MSC_SUCCESS; 1857} 1858 1859MSC_RV MSCGetObjectAttributes(MSCLPTokenConnection pConnection, 1860 MSCString objectID, MSCLPObjectInfo pObjectInfo) 1861{ 1862 1863 MSC_RV rv; 1864 MSCObjectInfo objInfo; 1865 1866 if (pConnection == NULL) 1867 return MSC_INVALID_PARAMETER; 1868 if (localHContext == 0) 1869 return MSC_INTERNAL_ERROR; 1870 1871 rv = MSCListObjects(pConnection, MSC_SEQUENCE_RESET, &objInfo); 1872 1873 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) 1874 { 1875 return rv; 1876 } 1877 1878 if (rv == MSC_SEQUENCE_END) 1879 { 1880 return MSC_OBJECT_NOT_FOUND; 1881 } 1882 1883 if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0) 1884 { 1885 pObjectInfo->objectSize = objInfo.objectSize; 1886 pObjectInfo->objectACL.readPermission = 1887 objInfo.objectACL.readPermission; 1888 pObjectInfo->objectACL.writePermission = 1889 objInfo.objectACL.writePermission; 1890 pObjectInfo->objectACL.deletePermission = 1891 objInfo.objectACL.deletePermission; 1892 strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID); 1893 return MSC_SUCCESS; 1894 } 1895 1896 do 1897 { 1898 rv = MSCListObjects(pConnection, MSC_SEQUENCE_NEXT, &objInfo); 1899 if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0) 1900 break; 1901 } 1902 while (rv == MSC_SUCCESS); 1903 1904 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) 1905 { 1906 return rv; 1907 } 1908 1909 if (rv == MSC_SEQUENCE_END) 1910 { 1911 return MSC_OBJECT_NOT_FOUND; 1912 } 1913 1914 pObjectInfo->objectSize = objInfo.objectSize; 1915 pObjectInfo->objectACL.readPermission = 1916 objInfo.objectACL.readPermission; 1917 pObjectInfo->objectACL.writePermission = 1918 objInfo.objectACL.writePermission; 1919 pObjectInfo->objectACL.deletePermission = 1920 objInfo.objectACL.deletePermission; 1921 strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID); 1922 1923 return MSC_SUCCESS; 1924} 1925 1926MSC_RV MSCReadAllocateObject(MSCLPTokenConnection pConnection, 1927 MSCString objectID, MSCPUChar8 * pOutputData, 1928 MSCPULong32 dataSize, 1929 LPRWEventCallback rwCallback, 1930 MSCPVoid32 addParams) 1931{ 1932 MSC_RV rv; 1933 MSCObjectInfo objInfo; 1934 MSCULong32 objectSize; 1935 MSCPUChar8 data = NULL; 1936 1937 if (pConnection == NULL) 1938 return MSC_INVALID_PARAMETER; 1939 if (localHContext == 0) 1940 return MSC_INTERNAL_ERROR; 1941 1942 if (pOutputData == 0) 1943 { 1944 return MSC_INVALID_PARAMETER; 1945 } 1946 1947 *dataSize = 0; 1948 *pOutputData = 0; 1949 1950 rv = MSCGetObjectAttributes(pConnection, objectID, &objInfo); 1951 if (rv == MSC_SUCCESS) 1952 { 1953 objectSize = objInfo.objectSize; 1954 data = (MSCPUChar8) malloc(sizeof(MSCUChar8) * objectSize); 1955 if(data) 1956 { 1957 rv = MSCReadObject(pConnection, objectID, 0, data, 1958 objectSize, rwCallback, addParams); 1959 1960 if (rv == MSC_SUCCESS) 1961 { 1962 *dataSize = objectSize; 1963 *pOutputData = data; 1964 } 1965 else 1966 { 1967 rv = MSC_INTERNAL_ERROR; 1968 free(data); 1969 } 1970 } 1971 } 1972 1973 return rv; 1974} 1975 1976 1977MSC_RV pcscToMSC(MSCLong32 pcscCode) 1978{ 1979 1980 switch (pcscCode) 1981 { 1982 case SCARD_S_SUCCESS: 1983 return MSC_SUCCESS; 1984 case SCARD_E_INVALID_HANDLE: 1985 return MSC_INVALID_HANDLE; 1986 case SCARD_E_SHARING_VIOLATION: 1987 return MSC_SHARING_VIOLATION; 1988 case SCARD_W_REMOVED_CARD: 1989 return MSC_TOKEN_REMOVED; 1990 case SCARD_E_NO_SMARTCARD: 1991 return MSC_TOKEN_REMOVED; 1992 case SCARD_W_RESET_CARD: 1993 return MSC_TOKEN_RESET; 1994 case SCARD_W_INSERTED_CARD: 1995 return MSC_TOKEN_INSERTED; 1996 case SCARD_E_NO_SERVICE: 1997 return MSC_SERVICE_UNRESPONSIVE; 1998 case SCARD_E_UNKNOWN_CARD: 1999 case SCARD_W_UNSUPPORTED_CARD: 2000 case SCARD_E_CARD_UNSUPPORTED: 2001 return MSC_UNRECOGNIZED_TOKEN; 2002 case SCARD_E_INVALID_PARAMETER: 2003 case SCARD_E_INVALID_VALUE: 2004 case SCARD_E_UNKNOWN_READER: 2005 case SCARD_E_PROTO_MISMATCH: 2006 case SCARD_E_READER_UNAVAILABLE: 2007 return MSC_INVALID_PARAMETER; 2008 case SCARD_E_CANCELLED: 2009 return MSC_CANCELLED; 2010 case SCARD_E_TIMEOUT: 2011 return MSC_TIMEOUT_OCCURRED; 2012 2013 default: 2014 return MSC_INTERNAL_ERROR; 2015 } 2016} 2017 2018char *msc_error(unsigned long int errorCode) //MSC_RV 2019{ 2020 2021 static char message[500]; 2022 2023 switch (errorCode) 2024 { 2025 case MSC_SUCCESS: 2026 strncpy(message, "Successful", sizeof(message)); 2027 break; 2028 case MSC_NO_MEMORY_LEFT: 2029 strncpy(message, "No more memory", sizeof(message)); 2030 break; 2031 case MSC_AUTH_FAILED: 2032 strncpy(message, "Authentication failed", sizeof(message)); 2033 break; 2034 case MSC_OPERATION_NOT_ALLOWED: 2035 strncpy(message, "Operation not allowed", sizeof(message)); 2036 break; 2037 case MSC_INCONSISTENT_STATUS: 2038 strncpy(message, "Inconsistent status", sizeof(message)); 2039 break; 2040 case MSC_UNSUPPORTED_FEATURE: 2041 strncpy(message, "Feature unsupported", sizeof(message)); 2042 break; 2043 case MSC_UNAUTHORIZED: 2044 strncpy(message, "Unauthorized usage", sizeof(message)); 2045 break; 2046 case MSC_OBJECT_NOT_FOUND: 2047 strncpy(message, "Object not found", sizeof(message)); 2048 break; 2049 case MSC_OBJECT_EXISTS: 2050 strncpy(message, "Object already exists", sizeof(message)); 2051 break; 2052 case MSC_INCORRECT_ALG: 2053 strncpy(message, "Incorrect algorithm", sizeof(message)); 2054 break; 2055 case MSC_SIGNATURE_INVALID: 2056 strncpy(message, "Invalid signature", sizeof(message)); 2057 break; 2058 case MSC_IDENTITY_BLOCKED: 2059 strncpy(message, "Identity is blocked", sizeof(message)); 2060 break; 2061 case MSC_UNSPECIFIED_ERROR: 2062 strncpy(message, "Unspecified error", sizeof(message)); 2063 break; 2064 case MSC_TRANSPORT_ERROR: 2065 strncpy(message, "Transport error", sizeof(message)); 2066 break; 2067 case MSC_INVALID_PARAMETER: 2068 strncpy(message, "Invalid parameter", sizeof(message)); 2069 break; 2070 case MSC_SEQUENCE_END: 2071 strncpy(message, "End of sequence", sizeof(message)); 2072 break; 2073 case MSC_INTERNAL_ERROR: 2074 strncpy(message, "Internal Error", sizeof(message)); 2075 break; 2076 case MSC_CANCELLED: 2077 strncpy(message, "Operation Cancelled", sizeof(message)); 2078 break; 2079 case MSC_INSUFFICIENT_BUFFER: 2080 strncpy(message, "Buffer is too small", sizeof(message)); 2081 break; 2082 case MSC_UNRECOGNIZED_TOKEN: 2083 strncpy(message, "Token is unsupported", sizeof(message)); 2084 break; 2085 case MSC_SERVICE_UNRESPONSIVE: 2086 strncpy(message, "Service is not running", sizeof(message)); 2087 break; 2088 case MSC_TIMEOUT_OCCURRED: 2089 strncpy(message, "Timeout has occurred", sizeof(message)); 2090 break; 2091 case MSC_TOKEN_REMOVED: 2092 strncpy(message, "Token was removed", sizeof(message)); 2093 break; 2094 case MSC_TOKEN_RESET: 2095 strncpy(message, "Token was reset", sizeof(message)); 2096 break; 2097 case MSC_TOKEN_INSERTED: 2098 strncpy(message, "Token was inserted", sizeof(message)); 2099 break; 2100 case MSC_TOKEN_UNRESPONSIVE: 2101 strncpy(message, "Token is unresponsive", sizeof(message)); 2102 break; 2103 case MSC_INVALID_HANDLE: 2104 strncpy(message, "Handle is invalid", sizeof(message)); 2105 break; 2106 case MSC_SHARING_VIOLATION: 2107 strncpy(message, "Sharing violation", sizeof(message)); 2108 break; 2109 2110 default: 2111 sprintf(message, "Unknown SW: %04lu", errorCode); 2112 break; 2113 } 2114 2115 return message; 2116} 2117 2118MSC_RV MSCReEstablishConnection(MSCLPTokenConnection pConnection) 2119{ 2120 2121 MSC_RV rv; 2122 MSCPVoid32 vInitFunction, vFinFunction, vIdFunction; 2123 MSCULong32 dwActiveProtocol; 2124 MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection); 2125 MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection); 2126 MSCLong32 (*libPL_MSCIdentifyToken)(MSCLPTokenConnection); 2127 2128 vInitFunction = 0; 2129 vFinFunction = 0; 2130 vIdFunction = 0; 2131 2132 /* 2133 * Select the AID or initialization routine for the card 2134 */ 2135 vInitFunction = pConnection->libPointers.pvfInitializePlugin; 2136 vFinFunction = pConnection->libPointers.pvfFinalizePlugin; 2137 vIdFunction = pConnection->libPointers.pvfIdentifyToken; 2138 2139 if (vInitFunction == 0) 2140 { 2141 DebugLogB("Error: Card service failure: %s\n", 2142 "InitializePlugin function missing"); 2143 return MSC_INTERNAL_ERROR; 2144 } 2145 2146 if (vFinFunction == 0) 2147 { 2148 DebugLogB("Error: Card service failure: %s\n", 2149 "FinalizePlugin function missing"); 2150 return MSC_INTERNAL_ERROR; 2151 } 2152 2153 if ( vIdFunction == 0 ) 2154 { 2155 DebugLogB("Error: Card service failure: %s\n", 2156 "IdentifyToken function missing"); 2157 return MSC_INTERNAL_ERROR; 2158 } 2159 2160 libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection)) 2161 vInitFunction; 2162 2163 libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection)) 2164 vFinFunction; 2165 2166 libPL_MSCIdentifyToken = (MSCLong32 (*)(MSCLPTokenConnection)) 2167 vIdFunction; 2168 2169 rv = SCardReconnect(pConnection->hCard, pConnection->shareMode, 2170 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 2171 SCARD_LEAVE_CARD, &dwActiveProtocol); 2172 2173 if (rv != SCARD_S_SUCCESS) 2174 return pcscToMSC(rv); 2175 2176 /* 2177 * Stop the plugin and start it up again 2178 */ 2179 rv = (*libPL_MSCFinalizePlugin) (pConnection); 2180 2181 /* 2182 * Use the default AID given by the Info.plist 2183 */ 2184 rv = (*libPL_MSCInitializePlugin) (pConnection); 2185 2186 /* 2187 * Use the default AID given by the Info.plist 2188 */ 2189 rv = (*libPL_MSCIdentifyToken)(pConnection); 2190 2191 if (rv != MSC_SUCCESS) 2192 return rv; 2193 2194 return MSC_SUCCESS; 2195} 2196 2197MSCUChar8 MSCIsTokenReset(MSCLPTokenConnection pConnection) 2198{ 2199 MSCULong32 rv; 2200 char slotName[MAX_READERNAME]; 2201 MSCULong32 slotNameSize, slotState, slotProtocol; 2202 MSCUChar8 tokenId[MAX_ATR_SIZE]; 2203 MSCULong32 tokenIdLength; 2204 2205 rv = SCardStatus(pConnection->hCard, slotName, 2206 &slotNameSize, &slotState, &slotProtocol, 2207 tokenId, &tokenIdLength); 2208 2209 if (rv == SCARD_W_RESET_CARD) 2210 { 2211 return 1; 2212 } 2213 2214 if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_RESET) 2215 { 2216 return 1; 2217 } else 2218 { 2219 return 0; 2220 } 2221} 2222 2223MSCUChar8 MSCClearReset(MSCLPTokenConnection pConnection) 2224{ 2225 pConnection->tokenInfo.tokenType &= ~MSC_TOKEN_TYPE_RESET; 2226 return 1; 2227} 2228 2229MSCUChar8 MSCIsTokenMoved(MSCLPTokenConnection pConnection) 2230{ 2231 MSCULong32 rv; 2232 char slotName[MAX_READERNAME]; 2233 MSCULong32 slotNameSize, slotState, slotProtocol; 2234 MSCUChar8 tokenId[MAX_ATR_SIZE]; 2235 MSCULong32 tokenIdLength; 2236 2237 2238 rv = SCardStatus(pConnection->hCard, slotName, 2239 &slotNameSize, &slotState, &slotProtocol, 2240 tokenId, &tokenIdLength); 2241 2242 if (rv == SCARD_W_REMOVED_CARD) 2243 { 2244 return 1; 2245 } else if (rv == SCARD_W_INSERTED_CARD) 2246 { 2247 return 1; 2248 } else if (slotState & SCARD_ABSENT) 2249 { 2250 return 1; 2251 } 2252 2253 2254 if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_REMOVED) 2255 { 2256 return 1; 2257 } else 2258 { 2259 return 0; 2260 } 2261} 2262 2263MSCUChar8 MSCIsTokenChanged(MSCLPTokenConnection pConnection) 2264{ 2265 if (MSCIsTokenMoved(pConnection)) 2266 { 2267 return 1; 2268 } else if (MSCIsTokenReset(pConnection)) 2269 { 2270 return 1; 2271 } else { 2272 return 0; 2273 } 2274} 2275 2276MSCUChar8 MSCIsTokenKnown(MSCLPTokenConnection pConnection) 2277{ 2278 if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_KNOWN) 2279 { 2280 return 1; 2281 } else 2282 { 2283 return 0; 2284 } 2285} 2286