/[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 101 - (hide annotations) (download)
Wed Jun 5 18:31:04 2002 UTC (10 years, 11 months ago) by corcoran
File MIME type: text/plain
File size: 51431 byte(s)
some changes
1 corcoran 11 /******************************************************************
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 corcoran 79 #ifndef WIN32
19 corcoran 11 #include "config.h"
20 corcoran 79 #else
21     #include "../win32/win32_config.h"
22     #endif
23    
24 corcoran 11 #include "musclecard.h"
25     #include "tokenfactory.h"
26     #include "debuglog.h"
27    
28     #ifdef USE_THREAD_SAFETY
29 corcoran 79 #ifndef WIN32
30 corcoran 11 #include "wintypes.h"
31 corcoran 79 #endif
32 corcoran 11 #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 rousseau 24 static SCARDCONTEXT localHContext = 0;
45 corcoran 58 static ULONG blockingContext = MSC_BLOCKSTATUS_RESUME;
46 corcoran 100 static PCSCLITE_THREAD_T callbackThread;
47 corcoran 99
48 rousseau 24 /*
49     * internal function
50     */
51     MSC_RV pcscToMSC(MSCLong32);
52 corcoran 11 MSC_RV MSCReEstablishConnection(MSCLPTokenConnection);
53    
54 rousseau 24 void mscLockThread()
55     {
56 corcoran 11 #ifdef USE_THREAD_SAFETY
57 rousseau 24 SYS_MutexLock(&mcardMutex);
58     #endif
59 corcoran 11 }
60    
61 rousseau 24 void mscUnLockThread()
62     {
63 corcoran 11 #ifdef USE_THREAD_SAFETY
64 rousseau 24 SYS_MutexUnLock(&mcardMutex);
65 corcoran 11 #endif
66     }
67    
68     /**************** MSC Connection Functions **************************/
69    
70 rousseau 24 MSC_RV MSCListTokens(MSCULong32 listScope, MSCLPTokenInfo tokenArray,
71 corcoran 51 MSCPULong32 arrayLength)
72 rousseau 24 {
73 corcoran 11
74 rousseau 24 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 corcoran 11
83 rousseau 24 readerLength = 0;
84     tokensFound = 0;
85     readerList = 0;
86     strLoc = 0;
87     i = 0;
88 corcoran 11
89 rousseau 24 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 corcoran 11
97 rousseau 24 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 corcoran 11
111 rousseau 24 /*
112     * Get the reader list size
113     */
114     rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
115 corcoran 11
116 rousseau 24 if (pcscToMSC(rv) != MSC_SUCCESS)
117     {
118     return pcscToMSC(rv);
119     }
120 corcoran 11
121 rousseau 24 readerList = (char *) malloc(sizeof(char) * readerLength);
122 corcoran 11
123 rousseau 24 if (readerList == 0)
124     {
125     return MSC_INTERNAL_ERROR;
126     }
127 corcoran 11
128 rousseau 24 rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
129 corcoran 11
130 rousseau 24 /*
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 corcoran 11
138 corcoran 51 rv = SCardGetStatusChange(localHContext, INFINITE,
139     &rgReaderStates,
140     1);
141 corcoran 11
142 rousseau 24 if (pcscToMSC(rv) != MSC_SUCCESS)
143     {
144     if (readerList)
145     free(readerList);
146     return pcscToMSC(rv);
147     }
148 corcoran 11
149 rousseau 24 /*
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 corcoran 11
156 rousseau 24 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 corcoran 11
165 rousseau 24 /*
166     * Success for this function
167     */
168     if ((rv == 0) || (listScope == MSC_LIST_SLOTS) ||
169     (listScope == MSC_LIST_ALL))
170     {
171 corcoran 11
172 rousseau 24 /*
173     * We found something interesting to the application
174     */
175     tokensFound += 1;
176 corcoran 11
177 rousseau 24 if ((tokensFound <= *arrayLength) && (tokenArray != 0))
178     {
179     currentToken = &tokenArray[tokensFound - 1];
180 corcoran 59 currentToken->addParams = 0;
181     currentToken->addParamsSize = 0;
182 corcoran 11
183 rousseau 24 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 corcoran 11
200 rousseau 24 strncpy(currentToken->slotName,
201     rgReaderStates.szReader, MAX_READERNAME);
202 corcoran 11
203 rousseau 24 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 corcoran 11
214 rousseau 24 currentToken->tokenState = rgReaderStates.dwEventState;
215 corcoran 11
216 rousseau 24 }
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 corcoran 11
228 rousseau 24 if (readerList)
229     free(readerList);
230 corcoran 11
231 rousseau 24 /*
232     * Application provides null requesting length
233     */
234     if (tokenArray == 0)
235     {
236     *arrayLength = tokensFound;
237     return MSC_SUCCESS;
238     }
239 corcoran 11
240 rousseau 24 /*
241     * Provided length is too small
242     */
243     if (*arrayLength < tokensFound)
244     {
245     *arrayLength = tokensFound;
246     return MSC_INSUFFICIENT_BUFFER;
247     }
248 corcoran 11
249 rousseau 24 *arrayLength = tokensFound;
250     return MSC_SUCCESS;
251 corcoran 11 }
252    
253 rousseau 24 MSC_RV MSCEstablishConnection(MSCLPTokenInfo tokenStruct,
254 corcoran 51 MSCULong32 sharingMode,
255     MSCPUChar8 applicationName,
256     MSCULong32 nameSize,
257     MSCLPTokenConnection pConnection)
258 rousseau 24 {
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 corcoran 11
273 rousseau 24 tokenSize = 0;
274     tokenList = 0;
275     tokenSize = 0;
276     selectedIFD = -1;
277 corcoran 79 tokenIdLength = sizeof(tokenId);
278 rousseau 24 slotState = 0;
279     slotProtocol = 0;
280     slotNameSize = sizeof(slotName);
281     vIdFunction = 0;
282     vInitFunction = 0;
283 corcoran 11
284 rousseau 24 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 corcoran 11
291 rousseau 24 pConnection->tokenLibHandle = 0;
292     pConnection->hContext = 0;
293     pConnection->tokenInfo.tokenIdLength = 0;
294     pConnection->shareMode = 0;
295 corcoran 11
296 rousseau 24 /*
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 corcoran 11
311 rousseau 24 /*
312     * Set up the initial connection to the resource manager
313     */
314 corcoran 11
315 rousseau 24 mscLockThread();
316     if (localHContext == 0)
317     {
318     rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
319     &localHContext);
320 corcoran 11 #ifdef MSC_DEBUG
321 rousseau 24 DebugLogC("SCardEstablishContext returns %s\n",
322     pcsc_stringify_error(rv));
323 corcoran 11 #endif
324 rousseau 24 if (pcscToMSC(rv) != MSC_SUCCESS)
325     {
326     localHContext = 0;
327     mscUnLockThread();
328     return pcscToMSC(rv);
329     }
330 corcoran 11
331 rousseau 24 pConnection->hContext = localHContext;
332     } else
333     {
334     pConnection->hContext = localHContext;
335     }
336     mscUnLockThread();
337    
338     rv = SCardConnect(pConnection->hContext, tokenStruct->slotName,
339 corcoran 101 sharingMode, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
340 rousseau 24 &pConnection->hCard, &dwActiveProtocol);
341    
342 corcoran 11 #ifdef MSC_DEBUG
343 rousseau 24 DebugLogC("SCardConnect returns %s\n", pcsc_stringify_error(rv));
344 corcoran 11 #endif
345    
346 rousseau 24 if (pcscToMSC(rv) != MSC_SUCCESS)
347     {
348     return pcscToMSC(rv);
349     }
350 corcoran 11
351 rousseau 24 /*
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 corcoran 11
367 rousseau 24 /*
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 corcoran 11 #ifdef MSC_DEBUG
376 rousseau 24 DebugLogC("SCardStatus returns %s\n", pcsc_stringify_error(rv));
377 corcoran 11 #endif
378    
379 rousseau 24 if (pcscToMSC(rv) != MSC_SUCCESS)
380     {
381     SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
382     pConnection->hCard = 0;
383     return pcscToMSC(rv);
384     }
385 corcoran 11
386 rousseau 24 if ((sharingMode == MSC_SHARE_DIRECT) && (slotState & SCARD_ABSENT))
387     {
388 corcoran 11
389 rousseau 24 /*
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 corcoran 11
397 rousseau 24 if ((tokenIdLength != tokenStruct->tokenIdLength) ||
398     (strcmp(slotName, tokenStruct->slotName) != 0) ||
399     (memcmp(tokenId, tokenStruct->tokenId, tokenIdLength) != 0))
400     {
401 corcoran 99 DebugLogA("Internal inconsistent values, ID, slotName\n");
402 rousseau 24 SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
403     pConnection->hCard = 0;
404     return MSC_INCONSISTENT_STATUS;
405     }
406 corcoran 11
407 rousseau 24 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 corcoran 11 #ifdef MSC_DEBUG
420 rousseau 24 DebugLogC("TPLoadToken returns %s\n", pcsc_stringify_error(rv));
421 corcoran 11 #endif
422    
423 rousseau 24 if (rv != SCARD_S_SUCCESS)
424     {
425     SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
426     pConnection->hCard = 0;
427     return pcscToMSC(rv);
428     }
429 corcoran 11
430 rousseau 24 /*
431     * Select the AID or initialization routine for the card
432     */
433     vInitFunction = pConnection->libPointers.pvfInitializePlugin;
434     vIdFunction = pConnection->libPointers.pvfIdentifyToken;
435 corcoran 11
436 rousseau 24 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 corcoran 11
445 rousseau 24 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 corcoran 11
454 rousseau 24 libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
455     vInitFunction;
456 corcoran 11
457 rousseau 24 libPL_MSCIdentifyToken = (MSCLong32(*)(MSCLPTokenConnection))
458     vIdFunction;
459 corcoran 11
460 rousseau 24 rv = (*libPL_MSCInitializePlugin) (pConnection);
461 corcoran 11
462 rousseau 24 if (rv != MSC_SUCCESS)
463     {
464 corcoran 99 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 rousseau 24 }
472    
473 corcoran 99 if (sharingMode != MSC_SHARE_DIRECT)
474 rousseau 24 {
475    
476 corcoran 99 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 corcoran 11 #ifdef MSC_DEBUG
492 rousseau 24 DebugLogC("MSCIdentifyToken returns %s\n", msc_error(rv));
493 corcoran 11 #endif
494    
495 rousseau 24 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 corcoran 11 }
514    
515 rousseau 24 pConnection->shareMode = sharingMode;
516     return MSC_SUCCESS;
517 corcoran 11 }
518    
519 rousseau 24 MSC_RV MSCReleaseConnection(MSCLPTokenConnection pConnection,
520 corcoran 51 MSCULong32 endAction)
521 rousseau 24 {
522 corcoran 11
523 rousseau 24 MSCLong32 rv = SCARD_S_SUCCESS;
524     MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
525     MSCPVoid32 vFunction;
526 corcoran 11
527 rousseau 24 vFunction = 0;
528 corcoran 11
529 rousseau 24 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 corcoran 11
537 rousseau 24 /*
538     * Select finalization routine for the token plugin
539     */
540     vFunction = pConnection->libPointers.pvfFinalizePlugin;
541 corcoran 11
542 rousseau 24 if (vFunction == 0)
543     {
544     DebugLogC("Error: Card service failure: %s\n",
545     "FinalizePlugin function missing");
546     return MSC_INTERNAL_ERROR;
547     }
548 corcoran 11
549 rousseau 24 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 corcoran 11 }
585    
586 rousseau 24 MSC_RV MSCWaitForTokenEvent(MSCLPTokenInfo tokenArray,
587 corcoran 59 MSCULong32 arraySize,
588     MSCULong32 timeoutValue)
589 rousseau 24 {
590 corcoran 11
591 rousseau 24 MSCLong32 rv, rt;
592     LPSCARD_READERSTATE_A rgReaderStates;
593     MSCTokenInfo tokenInfo;
594     int i;
595 corcoran 11
596 rousseau 24 rgReaderStates = 0;
597 corcoran 11
598 rousseau 24 /*
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 corcoran 11
604 rousseau 24 if (arraySize == 0)
605     {
606     return MSC_SUCCESS;
607     } else if (arraySize > MSC_MAXSIZE_TOKENARRAY)
608     {
609     return MSC_INSUFFICIENT_BUFFER;
610     }
611 corcoran 11
612 rousseau 24 /*
613     * Set up the initial connection to the resource manager
614     */
615 corcoran 11
616 rousseau 24 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 corcoran 11
630 rousseau 24 rgReaderStates = (LPSCARD_READERSTATE_A)
631     malloc(sizeof(SCARD_READERSTATE_A) * arraySize);
632 corcoran 11
633 rousseau 24 if (rgReaderStates == 0)
634     {
635     return MSC_INTERNAL_ERROR;
636     }
637 corcoran 11
638 rousseau 24 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 corcoran 11
649 rousseau 24 rgReaderStates[i].szReader = tokenArray[i].slotName;
650     rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
651     rgReaderStates[i].dwEventState = 0;
652     }
653 corcoran 11
654 rousseau 24 rv = SCardGetStatusChange(localHContext, timeoutValue,
655     rgReaderStates, arraySize);
656 corcoran 11
657 rousseau 24 if (rv != SCARD_S_SUCCESS)
658     {
659     free(rgReaderStates);
660     return pcscToMSC(rv);
661     }
662 corcoran 11
663 rousseau 24 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 corcoran 11
679 rousseau 24 rv = SCardGetStatusChange(localHContext, timeoutValue,
680     rgReaderStates, arraySize);
681 corcoran 11
682 rousseau 24 for (i = 0; i < arraySize; i++)
683     {
684     tokenArray[i].tokenState = rgReaderStates[i].dwEventState;
685 corcoran 11
686 rousseau 24 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 corcoran 11 }
723    
724 rousseau 24 free(rgReaderStates);
725     return pcscToMSC(rv);
726 corcoran 11 }
727    
728 rousseau 24 MSC_RV MSCCancelEventWait(void)
729     {
730 corcoran 11
731 rousseau 24 MSCLong32 rv;
732 corcoran 11
733 rousseau 24 rv = SCardCancel(localHContext);
734 corcoran 11
735 rousseau 24 return pcscToMSC(rv);
736 corcoran 11 }
737    
738     /************************ Start of Callbacks ****************************/
739     #ifdef USE_THREAD_SAFETY
740 rousseau 24 void *_MSCEventThread(void *arg)
741     {
742    
743     MSCLong32 rv;
744     MSCLPEventWaitInfo evlist;
745     MSCLong32 curToken;
746    
747     if (arg == NULL)
748     {
749 corcoran 100 SYS_ThreadExit(NULL);
750 rousseau 24 }
751    
752     evlist = (MSCLPEventWaitInfo) arg;
753 corcoran 58 blockingContext = MSC_BLOCKSTATUS_BLOCKING;
754 rousseau 24
755     while (1)
756     {
757 corcoran 58 rv = MSCWaitForTokenEvent(evlist->tokenArray,
758     evlist->arraySize,
759     MSC_NO_TIMEOUT);
760 rousseau 24
761     if (rv == MSC_SUCCESS)
762     {
763 corcoran 58 (evlist->callBack) (evlist->tokenArray,
764     evlist->arraySize,
765     evlist->appData);
766     } else {
767     break;
768    
769     }
770    
771     if (blockingContext == MSC_BLOCKSTATUS_CANCELLING)
772 rousseau 24 {
773 corcoran 58 break;
774     }
775     }
776 rousseau 24
777 corcoran 58 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 rousseau 24
786 corcoran 58 free(evlist);
787     blockingContext = MSC_BLOCKSTATUS_RESUME;
788 corcoran 100 SYS_ThreadExit(&rv);
789 corcoran 58
790 corcoran 11 }
791    
792 rousseau 24 MSC_RV MSCCallbackForTokenEvent(MSCLPTokenInfo tokenArray,
793 corcoran 59 MSCULong32 arraySize,
794     MSCCallBack callBack,
795     MSCPVoid32 appData)
796 rousseau 24 {
797     MSCLPEventWaitInfo evlist;
798     MSCULong32 curToken;
799    
800 corcoran 100
801     if (blockingContext == MSC_BLOCKSTATUS_BLOCKING)
802     {
803     return MSC_OPERATION_NOT_ALLOWED;
804     }
805    
806 rousseau 24 /*
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 corcoran 100 if (SYS_ThreadCreate(&callbackThread, NULL, _MSCEventThread,
849     (void *) evlist))
850 rousseau 24 {
851     return MSC_INTERNAL_ERROR;
852     }
853    
854     return MSC_SUCCESS;
855 corcoran 11 }
856    
857 rousseau 24 MSC_RV MSCCallbackCancelEvent()
858     {
859 corcoran 11
860 corcoran 58 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 corcoran 59
868 corcoran 100 SYS_ThreadJoin(&callbackThread, 0);
869 corcoran 99
870 corcoran 58 }
871    
872     return MSC_SUCCESS;
873 corcoran 11 }
874    
875     #endif
876     /************************** End of Callbacks *****************************/
877    
878 rousseau 24 MSC_RV MSCBeginTransaction(MSCLPTokenConnection pConnection)
879     {
880 corcoran 11
881 rousseau 24 MSCLong32 rv;
882     MSCLong32 ret;
883 corcoran 11
884 rousseau 24 if (localHContext == 0)
885     return MSC_INTERNAL_ERROR;
886 corcoran 11
887 rousseau 24 while (1)
888     {
889     rv = SCardBeginTransaction(pConnection->hCard);
890     ret = pcscToMSC(rv);
891 corcoran 11
892 rousseau 24 if (ret == MSC_SUCCESS)
893     break;
894     if (ret == MSC_TOKEN_RESET)
895     {
896 corcoran 26 pConnection->tokenInfo.tokenType |=
897     MSC_TOKEN_TYPE_RESET;
898 rousseau 24 ret = MSCReEstablishConnection(pConnection);
899     if (ret != MSC_SUCCESS)
900     break;
901     continue;
902     } else if (ret == MSC_TOKEN_REMOVED)
903     {
904 corcoran 80 pConnection->tokenInfo.tokenType =
905     MSC_TOKEN_TYPE_REMOVED;
906 rousseau 24 return ret;
907     }
908     }
909    
910     return ret;
911 corcoran 11 }
912    
913 rousseau 24 MSC_RV MSCEndTransaction(MSCLPTokenConnection pConnection,
914     MSCULong32 endAction)
915     {
916 corcoran 11
917 rousseau 24 MSCLong32 rv;
918     MSCLong32 ret;
919 corcoran 11
920 rousseau 24 if (localHContext == 0)
921     return MSC_INTERNAL_ERROR;
922 corcoran 11
923 rousseau 24 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 corcoran 26 pConnection->tokenInfo.tokenType |=
933     MSC_TOKEN_TYPE_RESET;
934 rousseau 24 ret = MSCReEstablishConnection(pConnection);
935     if (ret != MSC_SUCCESS)
936     break;
937     continue;
938     } else if (ret == MSC_TOKEN_REMOVED)
939     {
940 corcoran 80 pConnection->tokenInfo.tokenType =
941     MSC_TOKEN_TYPE_REMOVED;
942 rousseau 24 return ret;
943     }
944     }
945    
946     return ret;
947 corcoran 11 }
948    
949 rousseau 24 MSC_RV MSCWriteFramework(MSCLPTokenConnection pConnection,
950     MSCLPInitTokenParams pInitParams)
951     {
952 corcoran 11
953 rousseau 24 MSCLong32 rv;
954     MSCPVoid32 vFunction;
955     MSCLong32(*libMSCWriteFramework) (MSCLPTokenConnection,
956     MSCLPInitTokenParams);
957 corcoran 11
958 rousseau 24 if (pConnection == NULL)
959     return MSC_INVALID_PARAMETER;
960     if (localHContext == 0)
961     return MSC_INTERNAL_ERROR;
962 corcoran 11
963 rousseau 24 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 corcoran 11 }
978    
979 rousseau 24 /*
980     * Real MSC functions
981     */
982 corcoran 11
983 rousseau 24 MSC_RV MSCGetStatus(MSCLPTokenConnection pConnection,
984     MSCLPStatusInfo pStatusInfo)
985     {
986     MSCLong32 rv;
987     MSCPVoid32 vFunction;
988     MSCLong32(*libMSCGetStatus) (MSCLPTokenConnection, MSCLPStatusInfo);
989 corcoran 11
990 rousseau 24 if (pConnection == NULL)
991     return MSC_INVALID_PARAMETER;
992     if (localHContext == 0)
993     return MSC_INTERNAL_ERROR;
994 corcoran 11
995 rousseau 24 vFunction = pConnection->libPointers.pvfGetStatus;
996 corcoran 11
997 rousseau 24 if (vFunction != 0)
998     {
999     libMSCGetStatus = (MSCLong32(*)(MSCLPTokenConnection,
1000     MSCLPStatusInfo)) vFunction;
1001     rv = (*libMSCGetStatus) (pConnection, pStatusInfo);
1002 corcoran 11
1003 rousseau 24 } else
1004     {
1005     return MSC_UNSUPPORTED_FEATURE;
1006     }
1007    
1008     return rv;
1009 corcoran 11 }
1010    
1011 rousseau 24 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 corcoran 11
1019 rousseau 24 if (pConnection == NULL)
1020     return MSC_INVALID_PARAMETER;
1021     if (localHContext == 0)
1022     return MSC_INTERNAL_ERROR;
1023 corcoran 11
1024 rousseau 24 vFunction = pConnection->libPointers.pvfGetCapabilities;
1025 corcoran 11
1026 rousseau 24 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 corcoran 11 }
1040    
1041 rousseau 24 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 corcoran 11
1050 rousseau 24 if (pConnection == NULL)
1051     return MSC_INVALID_PARAMETER;
1052     if (localHContext == 0)
1053     return MSC_INTERNAL_ERROR;
1054 corcoran 11
1055 rousseau 24 vFunction = pConnection->libPointers.pvfExtendedFeature;
1056 corcoran 11
1057 rousseau 24 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 corcoran 11 }
1072    
1073 rousseau 24 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 corcoran 11
1081 rousseau 24 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 corcoran 51 MSCUChar8, MSCUChar8,
1092     MSCLPGenKeyParams))
1093     vFunction;
1094 rousseau 24 rv = (*libMSCGenerateKeys) (pConnection, prvKeyNum, pubKeyNum,
1095 corcoran 51 pParams);
1096 rousseau 24
1097     } else
1098     {
1099     return MSC_UNSUPPORTED_FEATURE;
1100     }
1101    
1102     return rv;
1103 corcoran 11 }
1104    
1105 rousseau 24 MSC_RV MSCImportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
1106 corcoran 66 MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,MSCULong32 keyBlobSize,
1107 corcoran 48 MSCLPKeyPolicy keyPolicy, MSCPVoid32 pAddParams,
1108     MSCUChar8 addParamsSize)
1109 rousseau 24 {
1110     MSCLong32 rv;
1111     MSCPVoid32 vFunction;
1112 corcoran 48 MSCLong32(*libMSCImportKey) (MSCLPTokenConnection, MSCUChar8,
1113 corcoran 66 MSCLPKeyACL, MSCPUChar8,
1114 corcoran 48 MSCULong32, MSCLPKeyPolicy, MSCPVoid32,
1115     MSCUChar8);
1116 corcoran 11
1117 rousseau 24 if (pConnection == NULL)
1118     return MSC_INVALID_PARAMETER;
1119     if (localHContext == 0)
1120     return MSC_INTERNAL_ERROR;
1121 corcoran 11
1122 rousseau 24 vFunction = pConnection->libPointers.pvfImportKey;
1123    
1124     if (vFunction != 0)
1125     {
1126 corcoran 48 libMSCImportKey = (MSCLong32(*)(MSCLPTokenConnection,
1127 corcoran 66 MSCUChar8,
1128 corcoran 48 MSCLPKeyACL, MSCPUChar8,
1129     MSCULong32, MSCLPKeyPolicy,
1130     MSCPVoid32, MSCUChar8))
1131     vFunction;
1132 rousseau 24
1133 corcoran 66 rv = (*libMSCImportKey) (pConnection, keyNum,
1134 corcoran 48 pKeyACL, pKeyBlob, keyBlobSize,
1135     keyPolicy, pAddParams, addParamsSize);
1136    
1137 rousseau 24 } else
1138     {
1139     return MSC_UNSUPPORTED_FEATURE;
1140     }
1141    
1142     return rv;
1143 corcoran 11 }
1144    
1145 rousseau 24 MSC_RV MSCExportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
1146 corcoran 48 MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
1147     MSCPVoid32 pAddParams, MSCUChar8 addParamsSize)
1148 rousseau 24 {
1149     MSCLong32 rv;
1150     MSCPVoid32 vFunction;
1151     MSCLong32(*libMSCExportKey) (MSCLPTokenConnection, MSCUChar8,
1152     MSCPUChar8, MSCPULong32, MSCPVoid32, MSCUChar8);
1153 corcoran 11
1154 rousseau 24 if (pConnection == NULL)
1155     return MSC_INVALID_PARAMETER;
1156     if (localHContext == 0)
1157     return MSC_INTERNAL_ERROR;
1158 corcoran 11
1159 rousseau 24 vFunction = pConnection->libPointers.pvfExportKey;
1160 corcoran 11
1161 rousseau 24 if (vFunction != 0)
1162     {
1163 corcoran 51 libMSCExportKey = (MSCLong32(*)(MSCLPTokenConnection,
1164     MSCUChar8, MSCPUChar8,
1165     MSCPULong32, MSCPVoid32,
1166     MSCUChar8)) vFunction;
1167    
1168 rousseau 24 rv = (*libMSCExportKey) (pConnection, keyNum, pKeyBlob,
1169     keyBlobSize, pAddParams, addParamsSize);
1170 corcoran 11
1171 rousseau 24 } else
1172     {
1173     return MSC_UNSUPPORTED_FEATURE;
1174     }
1175    
1176     return rv;
1177 corcoran 11 }
1178    
1179 rousseau 24 MSC_RV MSCComputeCrypt(MSCLPTokenConnection pConnection,
1180 corcoran 51 MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
1181     MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
1182     MSCPULong32 outputDataSize)
1183 rousseau 24 {
1184     MSCLong32 rv;
1185     MSCPVoid32 vFunction;
1186     MSCLong32(*libMSCComputeCrypt) (MSCLPTokenConnection, MSCLPCryptInit,
1187 corcoran 51 MSCPUChar8, MSCULong32, MSCPUChar8,
1188     MSCPULong32);
1189 corcoran 11
1190 rousseau 24 if (pConnection == NULL)
1191     return MSC_INVALID_PARAMETER;
1192     if (localHContext == 0)
1193     return MSC_INTERNAL_ERROR;
1194 corcoran 11
1195 rousseau 24 vFunction = pConnection->libPointers.pvfComputeCrypt;
1196    
1197     if (vFunction != 0)
1198     {
1199     libMSCComputeCrypt =
1200 corcoran 51 (MSCLong32(*)(MSCLPTokenConnection, MSCLPCryptInit,
1201     MSCPUChar8, MSCULong32, MSCPUChar8,
1202     MSCPULong32)) vFunction;
1203 rousseau 24 rv = (*libMSCComputeCrypt) (pConnection, cryptInit, pInputData,
1204 corcoran 51 inputDataSize, pOutputData,
1205     outputDataSize);
1206 rousseau 24
1207     } else
1208     {
1209     return MSC_UNSUPPORTED_FEATURE;
1210     }
1211    
1212     return rv;
1213 corcoran 11 }
1214    
1215 rousseau 24 MSC_RV MSCExtAuthenticate(MSCLPTokenConnection pConnection,
1216 corcoran 51 MSCUChar8 keyNum, MSCUChar8 cipherMode,
1217     MSCUChar8 cipherDirection,
1218     MSCPUChar8 pData, MSCULong32 dataSize)
1219 rousseau 24 {
1220     MSCLong32 rv;
1221     MSCPVoid32 vFunction;
1222     MSCLong32(*libMSCExtAuthenticate) (MSCLPTokenConnection, MSCUChar8,
1223 corcoran 51 MSCUChar8, MSCUChar8, MSCPUChar8,
1224     MSCULong32);
1225 corcoran 11
1226 rousseau 24 if (pConnection == NULL)
1227     return MSC_INVALID_PARAMETER;
1228     if (localHContext == 0)
1229     return MSC_INTERNAL_ERROR;
1230 corcoran 11
1231 rousseau 24 vFunction = pConnection->libPointers.pvfExtAuthenticate;
1232 corcoran 11
1233 rousseau 24 if (vFunction != 0)
1234     {
1235     libMSCExtAuthenticate =
1236 corcoran 51 (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
1237     MSCUChar8, MSCUChar8, MSCPUChar8,
1238     MSCULong32)) vFunction;
1239 rousseau 24 rv = (*libMSCExtAuthenticate) (pConnection, keyNum, cipherMode,
1240     cipherDirection, pData, dataSize);
1241     } else
1242     {
1243     return MSC_UNSUPPORTED_FEATURE;
1244     }
1245    
1246     return rv;
1247 corcoran 11 }
1248    
1249 rousseau 24 MSC_RV MSCListKeys(MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
1250 corcoran 51 MSCLPKeyInfo pKeyInfo)
1251 rousseau 24 {
1252     MSCLong32 rv;
1253     MSCPVoid32 vFunction;
1254     MSCLong32(*libMSCListKeys) (MSCLPTokenConnection, MSCUChar8,
1255     MSCLPKeyInfo);
1256 corcoran 11
1257 rousseau 24 if (pConnection == NULL)
1258     return MSC_INVALID_PARAMETER;
1259     if (localHContext == 0)
1260     return MSC_INTERNAL_ERROR;
1261 corcoran 11
1262 rousseau 24 vFunction = pConnection->libPointers.pvfListKeys;
1263 corcoran 11
1264 rousseau 24 if (vFunction != 0)
1265     {
1266     libMSCListKeys = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
1267 corcoran 51 MSCLPKeyInfo)) vFunction;
1268 rousseau 24 rv = (*libMSCListKeys) (pConnection, seqOption, pKeyInfo);
1269 corcoran 11
1270 rousseau 24 } else
1271     {
1272     return MSC_UNSUPPORTED_FEATURE;
1273     }
1274    
1275     return rv;
1276 corcoran 11 }
1277    
1278 rousseau 24 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 corcoran 11
1288 rousseau 24 if (pConnection == NULL)
1289     return MSC_INVALID_PARAMETER;
1290     if (localHContext == 0)
1291     return MSC_INTERNAL_ERROR;
1292 corcoran 11
1293 rousseau 24 vFunction = pConnection->libPointers.pvfCreatePIN;
1294 corcoran 11
1295 rousseau 24 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 corcoran 11
1303 rousseau 24 } else
1304     {
1305     return MSC_UNSUPPORTED_FEATURE;
1306     }
1307    
1308     return rv;
1309 corcoran 11 }
1310    
1311 rousseau 24 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 corcoran 11
1319 rousseau 24 if (pConnection == NULL)
1320     return MSC_INVALID_PARAMETER;
1321     if (localHContext == 0)
1322     return MSC_INTERNAL_ERROR;
1323 corcoran 11
1324 rousseau 24 vFunction = pConnection->libPointers.pvfVerifyPIN;
1325 corcoran 11
1326 rousseau 24 if (vFunction != 0)
1327     {
1328     libMSCVerifyPIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
1329     MSCPUChar8, MSCULong32)) vFunction;
1330     rv = (*libMSCVerifyPIN) (pConnection, pinNum, pPinCode,
1331     pinCodeSize);
1332 corcoran 11
1333 rousseau 24 } else
1334     {
1335     return MSC_UNSUPPORTED_FEATURE;
1336     }
1337    
1338     return rv;
1339 corcoran 11 }
1340    
1341 rousseau 24 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 corcoran 11
1350 rousseau 24 if (pConnection == NULL)
1351     return MSC_INVALID_PARAMETER;
1352     if (localHContext == 0)
1353     return MSC_INTERNAL_ERROR;
1354 corcoran 11
1355 rousseau 24 vFunction = pConnection->libPointers.pvfChangePIN;
1356 corcoran 11
1357 rousseau 24 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 corcoran 11
1364 rousseau 24 } else
1365     {
1366     return MSC_UNSUPPORTED_FEATURE;
1367     }
1368    
1369     return rv;
1370 corcoran 11 }
1371    
1372 rousseau 24 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 corcoran 11
1380 rousseau 24 if (pConnection == NULL)
1381     return MSC_INVALID_PARAMETER;
1382     if (localHContext == 0)
1383     return MSC_INTERNAL_ERROR;
1384 corcoran 11
1385 rousseau 24 vFunction = pConnection->libPointers.pvfUnblockPIN;
1386 corcoran 11
1387 rousseau 24 if (vFunction != 0)
1388     {
1389     libMSCUnblockPIN = (MSCLong32(*)(MSCLPTokenConnection,
1390     MSCUChar8, MSCPUChar8, MSCULong32)) vFunction;
1391     rv = (*libMSCUnblockPIN) (pConnection, pinNum, pUnblockCode,
1392     unblockCodeSize);
1393 corcoran 11
1394 rousseau 24 } else
1395     {
1396     return MSC_UNSUPPORTED_FEATURE;
1397     }
1398    
1399     return rv;
1400 corcoran 11 }
1401    
1402 rousseau 24 MSC_RV MSCListPINs(MSCLPTokenConnection pConnection,
1403     MSCPUShort16 pPinBitMask)
1404     {
1405     MSCLong32 rv;
1406     MSCPVoid32 vFunction;
1407     MSCLong32(*libMSCListPINs) (MSCLPTokenConnection, MSCPUShort16);
1408 corcoran 11
1409 rousseau 24 if (pConnection == NULL)
1410     return MSC_INVALID_PARAMETER;
1411     if (localHContext == 0)
1412     return MSC_INTERNAL_ERROR;
1413 corcoran 11
1414 rousseau 24 vFunction = pConnection->libPointers.pvfListPINs;
1415 corcoran 11
1416 rousseau 24 if (vFunction != 0)
1417     {
1418     libMSCListPINs = (MSCLong32(*)(MSCLPTokenConnection,
1419     MSCPUShort16)) vFunction;
1420     rv = (*libMSCListPINs) (pConnection, pPinBitMask);
1421 corcoran 11
1422 rousseau 24 } else
1423     {
1424     return MSC_UNSUPPORTED_FEATURE;
1425     }
1426    
1427     return rv;
1428 corcoran 11 }
1429    
1430 rousseau 24 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 corcoran 11
1438 rousseau 24 if (pConnection == NULL)
1439     return MSC_INVALID_PARAMETER;
1440     if (localHContext == 0)
1441     return MSC_INTERNAL_ERROR;
1442 corcoran 11
1443 rousseau 24 vFunction = pConnection->libPointers.pvfCreateObject;
1444 corcoran 11
1445 rousseau 24 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 corcoran 11
1456 rousseau 24 return rv;
1457 corcoran 11 }
1458    
1459 rousseau 24 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 corcoran 11
1467 rousseau 24 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 corcoran 11 }
1487    
1488 corcoran 49 MSC_RV MSCWriteObject(MSCLPTokenConnection pConnection,
1489     MSCString objectID, MSCULong32 offSet,
1490     MSCPUChar8 pInputData, MSCULong32 dataSize,
1491     LPRWEventCallback rwCallback, MSCPVoid32 addParams)
1492 rousseau 24 {
1493 corcoran 49 MSC_RV rv = MSC_UNSPECIFIED_ERROR;
1494     MSCULong32 objectSize;
1495     int totalSteps, stepInterval;
1496     MSC_RV(*callBackFunction) (void *, int);
1497 rousseau 24 MSCPVoid32 vFunction;
1498     MSCLong32(*libMSCWriteObject) (MSCLPTokenConnection, MSCString,
1499     MSCULong32, MSCPUChar8, MSCUChar8);
1500 corcoran 49 int i;
1501 corcoran 11
1502 rousseau 24 if (pConnection == NULL)
1503     return MSC_INVALID_PARAMETER;
1504     if (localHContext == 0)
1505     return MSC_INTERNAL_ERROR;
1506 corcoran 11
1507 corcoran 49 vFunction = pConnection->libPointers.pvfWriteObject;
1508     callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
1509     objectSize = dataSize;
1510 corcoran 11
1511 corcoran 49 if (vFunction == 0)
1512 rousseau 24 {
1513 corcoran 49 return MSC_UNSUPPORTED_FEATURE;
1514     }
1515 corcoran 11
1516 corcoran 49 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 rousseau 24 {
1530 corcoran 49 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 rousseau 24 }
1548    
1549 corcoran 49 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 rousseau 24 return rv;
1569 corcoran 11 }
1570    
1571 corcoran 49 MSC_RV MSCReadObject(MSCLPTokenConnection pConnection,
1572     MSCString objectID, MSCULong32 offSet,
1573     MSCPUChar8 pOutputData, MSCULong32 dataSize,
1574     LPRWEventCallback rwCallback,
1575     MSCPVoid32 addParams)
1576 rousseau 24 {
1577 corcoran 49
1578     MSC_RV rv = MSC_UNSPECIFIED_ERROR;
1579     MSCULong32 objectSize;
1580     int totalSteps, stepInterval;
1581     MSC_RV(*callBackFunction) (void *, int);
1582 rousseau 24 MSCPVoid32 vFunction;
1583     MSCLong32(*libMSCReadObject) (MSCLPTokenConnection, MSCString,
1584     MSCULong32, MSCPUChar8, MSCUChar8);
1585 corcoran 49 int i;
1586 corcoran 11
1587 rousseau 24 if (pConnection == NULL)
1588     return MSC_INVALID_PARAMETER;
1589     if (localHContext == 0)
1590     return MSC_INTERNAL_ERROR;
1591 corcoran 11
1592 corcoran 49 vFunction = pConnection->libPointers.pvfReadObject;
1593     callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
1594     objectSize = dataSize;
1595 corcoran 11
1596 corcoran 49 if (vFunction == 0)
1597 rousseau 24 {
1598 corcoran 49 return MSC_UNSUPPORTED_FEATURE;
1599     }
1600 corcoran 11
1601 corcoran 49 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 rousseau 24 {
1616 corcoran 49 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 rousseau 24 }
1635    
1636 corcoran 49 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 rousseau 24 return rv;
1655 corcoran 11 }
1656    
1657 rousseau 24 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 corcoran 11
1665 rousseau 24 if (pConnection == NULL)
1666     return MSC_INVALID_PARAMETER;
1667     if (localHContext == 0)
1668     return MSC_INTERNAL_ERROR;
1669 corcoran 11
1670 rousseau 24 vFunction = pConnection->libPointers.pvfListObjects;
1671 corcoran 11
1672 rousseau 24 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 corcoran 11 }
1685    
1686 rousseau 24 MSC_RV MSCLogoutAll(MSCLPTokenConnection pConnection)
1687     {
1688 corcoran 11
1689 rousseau 24 MSCLong32 rv;
1690     MSCPVoid32 vFunction;
1691     MSCLong32(*libMSCLogoutAll) (MSCLPTokenConnection);
1692 corcoran 11
1693 rousseau 24 if (pConnection == NULL)
1694     return MSC_INVALID_PARAMETER;
1695     if (localHContext == 0)
1696     return MSC_INTERNAL_ERROR;
1697 corcoran 11
1698 rousseau 24 vFunction = pConnection->libPointers.pvfLogoutAll;
1699 corcoran 11
1700 rousseau 24 if (vFunction != 0)
1701     {
1702     libMSCLogoutAll = (MSCLong32(*)(MSCLPTokenConnection)) vFunction;
1703     rv = (*libMSCLogoutAll) (pConnection);
1704 corcoran 11
1705 rousseau 24 } else
1706     {
1707     return MSC_UNSUPPORTED_FEATURE;
1708     }
1709    
1710     return rv;
1711 corcoran 11 }
1712    
1713 rousseau 24 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 corcoran 11
1722 rousseau 24 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 corcoran 11 }
1744    
1745 rousseau 24 MSC_RV MSCGetKeyAttributes(MSCLPTokenConnection pConnection,
1746 corcoran 49 MSCUChar8 keyNumber, MSCLPKeyInfo pKeyInfo)
1747 rousseau 24 {
1748 corcoran 11
1749 rousseau 24 MSC_RV rv;
1750     MSCKeyInfo keyInfo;
1751 corcoran 11
1752 rousseau 24 if (pConnection == NULL)
1753     return MSC_INVALID_PARAMETER;
1754     if (localHContext == 0)
1755     return MSC_INTERNAL_ERROR;
1756 corcoran 11
1757 rousseau 24 rv = MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyInfo);
1758 corcoran 11
1759 rousseau 24 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
1760     {
1761     return rv;
1762     }
1763 corcoran 11
1764 rousseau 24 if (rv == MSC_SEQUENCE_END)
1765     {
1766     return MSC_INVALID_PARAMETER;
1767     }
1768 corcoran 11
1769 rousseau 24 if (keyNumber == keyInfo.keyNum)
1770     {
1771     pKeyInfo->keyNum = keyInfo.keyNum;
1772     pKeyInfo->keyType = keyInfo.keyType;
1773     pKeyInfo->keySize = keyInfo.keySize;
1774 corcoran 11
1775 rousseau 24 pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode;
1776     pKeyInfo->keyPolicy.cipherDirection =
1777     keyInfo.keyPolicy.cipherDirection;
1778 corcoran 11
1779 corcoran 49 pKeyInfo->keyACL.readPermission =
1780     keyInfo.keyACL.readPermission;
1781     pKeyInfo->keyACL.writePermission =
1782     keyInfo.keyACL.writePermission;
1783     pKeyInfo->keyACL.usePermission =
1784     keyInfo.keyACL.usePermission;
1785 corcoran 11
1786 rousseau 24 return MSC_SUCCESS;
1787     }
1788 corcoran 11
1789 rousseau 24 do
1790     {
1791     rv = MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyInfo);
1792     if (keyNumber == keyInfo.keyNum)
1793     break;
1794     }
1795     while (rv == MSC_SUCCESS);
1796 corcoran 11
1797 rousseau 24 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 corcoran 11 }
1821    
1822 rousseau 24 MSC_RV MSCGetObjectAttributes(MSCLPTokenConnection pConnection,
1823     MSCString objectID, MSCLPObjectInfo pObjectInfo)
1824     {
1825 corcoran 11
1826 rousseau 24 MSC_RV rv;
1827     MSCObjectInfo objInfo;
1828 corcoran 11
1829 rousseau 24 if (pConnection == NULL)
1830     return MSC_INVALID_PARAMETER;
1831     if (localHContext == 0)
1832     return MSC_INTERNAL_ERROR;
1833 corcoran 11
1834 rousseau 24 rv = MSCListObjects(pConnection, MSC_SEQUENCE_RESET, &objInfo);
1835 corcoran 11
1836 rousseau 24 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
1837     {
1838     return rv;
1839     }
1840 corcoran 11
1841 rousseau 24 if (rv == MSC_SEQUENCE_END)
1842     {
1843     return MSC_OBJECT_NOT_FOUND;
1844     }
1845 corcoran 11
1846 rousseau 24 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 corcoran 11
1859 rousseau 24 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 corcoran 11
1867 rousseau 24 if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
1868     {
1869     return rv;
1870     }
1871 corcoran 11
1872 rousseau 24 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 corcoran 11 }
1888    
1889 rousseau 24 MSC_RV MSCReadAllocateObject(MSCLPTokenConnection pConnection,
1890 corcoran 49 MSCString objectID, MSCPUChar8 * pOutputData,
1891     MSCPULong32 dataSize,
1892     LPRWEventCallback rwCallback,
1893     MSCPVoid32 addParams)
1894 rousseau 24 {
1895     MSC_RV rv;
1896     MSCObjectInfo objInfo;
1897     MSCULong32 objectSize;
1898 corcoran 11
1899 rousseau 24 if (pConnection == NULL)
1900     return MSC_INVALID_PARAMETER;
1901     if (localHContext == 0)
1902     return MSC_INTERNAL_ERROR;
1903 corcoran 11
1904 rousseau 24 if (pOutputData == 0)
1905     {
1906     return MSC_INVALID_PARAMETER;
1907     }
1908 corcoran 11
1909 rousseau 24 rv = MSCGetObjectAttributes(pConnection, objectID, &objInfo);
1910 corcoran 11
1911 rousseau 24 if (rv != MSC_SUCCESS)
1912     {
1913     *dataSize = 0;
1914     *pOutputData = 0;
1915     return rv;
1916     }
1917 corcoran 11
1918 rousseau 24 objectSize = objInfo.objectSize;
1919     *dataSize = objectSize;
1920     *pOutputData = (MSCPUChar8) malloc(sizeof(MSCUChar8) * objectSize);
1921 corcoran 11
1922 corcoran 49 return MSCReadObject(pConnection, objectID, 0, *pOutputData,
1923     objectSize, rwCallback, addParams);
1924 rousseau 24
1925 corcoran 11 }
1926    
1927    
1928 rousseau 24 MSC_RV pcscToMSC(MSCLong32 pcscCode)
1929     {
1930 corcoran 11
1931 rousseau 24 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 corcoran 11
1964 rousseau 24 default:
1965     return MSC_INTERNAL_ERROR;
1966     }
1967     }
1968 corcoran 11
1969 rousseau 24 char *msc_error(MSC_RV errorCode)
1970     {
1971 corcoran 11
1972 rousseau 24 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 corcoran 11 }
2068    
2069 rousseau 24 MSC_RV MSCReEstablishConnection(MSCLPTokenConnection pConnection)
2070     {
2071 corcoran 11
2072 rousseau 24 MSC_RV rv;
2073 corcoran 26 MSCPVoid32 vInitFunction, vFinFunction, vIdFunction;
2074 rousseau 24 MSCULong32 dwActiveProtocol;
2075     MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection);
2076     MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
2077 corcoran 26 MSCLong32 (*libPL_MSCIdentifyToken)(MSCLPTokenConnection);
2078 corcoran 11
2079 rousseau 24 vInitFunction = 0;
2080 corcoran 26 vFinFunction = 0;
2081     vIdFunction = 0;
2082 corcoran 11
2083 rousseau 24 /*
2084     * Select the AID or initialization routine for the card
2085     */
2086     vInitFunction = pConnection->libPointers.pvfInitializePlugin;
2087 corcoran 26 vFinFunction = pConnection->libPointers.pvfFinalizePlugin;
2088     vIdFunction = pConnection->libPointers.pvfIdentifyToken;
2089 corcoran 11
2090 rousseau 24 if (vInitFunction == 0)
2091     {
2092     DebugLogC("Error: Card service failure: %s\n",
2093     "InitializePlugin function missing");
2094     return MSC_INTERNAL_ERROR;
2095     }
2096 corcoran 11
2097 rousseau 24 if (vFinFunction == 0)
2098     {
2099     DebugLogC("Error: Card service failure: %s\n",
2100     "FinalizePlugin function missing");
2101     return MSC_INTERNAL_ERROR;
2102     }
2103 corcoran 11
2104 corcoran 26 if ( vIdFunction == 0 )
2105     {
2106     DebugLogC("Error: Card service failure: %s\n",
2107     "IdentifyToken function missing");
2108     return MSC_INTERNAL_ERROR;
2109     }
2110    
2111 rousseau 24 libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
2112     vInitFunction;
2113 corcoran 11
2114 rousseau 24 libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection))
2115     vFinFunction;
2116 corcoran 11
2117 corcoran 26 libPL_MSCIdentifyToken = (MSCLong32 (*)(MSCLPTokenConnection))
2118     vIdFunction;
2119    
2120 rousseau 24 rv = SCardReconnect(pConnection->hCard, pConnection->shareMode,
2121     SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
2122     SCARD_LEAVE_CARD, &dwActiveProtocol);
2123 corcoran 11
2124 rousseau 24 if (rv != SCARD_S_SUCCESS)
2125     return pcscToMSC(rv);
2126 corcoran 11
2127 rousseau 24 /*
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 corcoran 26 /*
2138     * Use the default AID given by the Info.plist
2139     */
2140     rv = (*libPL_MSCIdentifyToken)(pConnection);
2141    
2142 rousseau 24 if (rv != MSC_SUCCESS)
2143     return rv;
2144    
2145     return MSC_SUCCESS;
2146 corcoran 11 }
2147    
2148 rousseau 24 MSCUChar8 MSCIsTokenReset(MSCLPTokenConnection pConnection)
2149     {
2150 corcoran 80 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 rousseau 24 if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_RESET)
2166     {
2167     return 1;
2168     } else
2169     {
2170     return 0;
2171     }
2172 corcoran 11 }
2173    
2174 rousseau 24 MSCUChar8 MSCClearReset(MSCLPTokenConnection pConnection)
2175     {
2176     pConnection->tokenInfo.tokenType &= ~MSC_TOKEN_TYPE_RESET;
2177     return 1;
2178 corcoran 11 }
2179    
2180 rousseau 24 MSCUChar8 MSCIsTokenMoved(MSCLPTokenConnection pConnection)
2181     {
2182 corcoran 80 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 rousseau 24 if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_REMOVED)
2206     {
2207     return 1;
2208     } else
2209     {
2210     return 0;
2211     }
2212 corcoran 11 }
2213    
2214 rousseau 24 MSCUChar8 MSCIsTokenChanged(MSCLPTokenConnection pConnection)
2215     {
2216 corcoran 80 if (MSCIsTokenMoved(pConnection))
2217 rousseau 24 {
2218     return 1;
2219 corcoran 80 } else if (MSCIsTokenReset(pConnection))
2220 rousseau 24 {
2221 corcoran 80 return 1;
2222     } else {
2223     return 0;
2224 rousseau 24 }
2225 corcoran 11 }
2226    
2227 rousseau 24 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 corcoran 11 }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5