/[pcsclite]/trunk/PCSC/libmusclecard/src/musclecard.c
ViewVC logotype

Contents of /trunk/PCSC/libmusclecard/src/musclecard.c

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5