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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5