#ifndef WIN32
#include "config.h"
#else
#include "../win32/win32_config.h"
#endif
#include "musclecard.h"
#include "tokenfactory.h"
#include "debuglog.h"
#ifdef USE_THREAD_SAFETY
#ifndef WIN32
#include "wintypes.h"
#endif
#include "thread_generic.h"
#include "sys_generic.h"
#endif
#ifdef USE_THREAD_SAFETY
static PCSCLITE_MUTEX mcardMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static SCARDCONTEXT localHContext = 0;
#ifdef USE_THREAD_SAFETY
static PCSCLITE_THREAD_T callbackThread;
#endif
MSC_RV pcscToMSC(MSCLong32);
MSC_RV MSCReEstablishConnection(MSCLPTokenConnection);
void mscLockThread()
{
#ifdef USE_THREAD_SAFETY
SYS_MutexLock(&mcardMutex);
#endif
}
void mscUnLockThread()
{
#ifdef USE_THREAD_SAFETY
SYS_MutexUnLock(&mcardMutex);
#endif
}
MSC_RV MSCListTokens(MSCULong32 listScope, MSCLPTokenInfo tokenArray,
MSCPULong32 arrayLength)
{
MSCLong32 rv;
SCARD_READERSTATE_A rgReaderStates;
MSCTokenInfo tokenInfo;
MSCLPTokenInfo currentToken;
MSCULong32 tokensFound;
MSCULong32 readerLength;
char *readerList;
int i, strLoc;
readerLength = 0;
tokensFound = 0;
readerList = 0;
strLoc = 0;
i = 0;
if (arrayLength == 0)
return MSC_INVALID_PARAMETER;
if (listScope != MSC_LIST_KNOWN &&
listScope != MSC_LIST_ALL && listScope != MSC_LIST_SLOTS)
{
return MSC_INVALID_PARAMETER;
}
mscLockThread();
if (localHContext == 0)
{
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
&localHContext);
if (pcscToMSC(rv) != MSC_SUCCESS)
{
localHContext = 0;
mscUnLockThread();
return pcscToMSC(rv);
}
}
mscUnLockThread();
rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
if (pcscToMSC(rv) != MSC_SUCCESS)
{
return pcscToMSC(rv);
}
readerList = (char *) malloc(sizeof(char) * readerLength);
if (readerList == 0)
{
return MSC_INTERNAL_ERROR;
}
rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
for (i = 0; i < readerLength - 1; i++)
{
rgReaderStates.szReader = &readerList[i];
rgReaderStates.dwCurrentState = SCARD_STATE_UNAWARE;
rv = SCardGetStatusChange(localHContext, INFINITE,
&rgReaderStates,
1);
if (pcscToMSC(rv) != MSC_SUCCESS)
{
if (readerList)
free(readerList);
return pcscToMSC(rv);
}
if ((rgReaderStates.dwEventState & SCARD_STATE_PRESENT) ||
(listScope == MSC_LIST_SLOTS))
{
if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT)
{
rv = TPSearchBundlesForAtr(rgReaderStates.rgbAtr,
rgReaderStates.cbAtr, &tokenInfo);
}
if ((rv == 0) || (listScope == MSC_LIST_SLOTS) ||
(listScope == MSC_LIST_ALL))
{
tokensFound += 1;
if ((tokensFound <= *arrayLength) && (tokenArray != 0))
{
currentToken = &tokenArray[tokensFound - 1];
currentToken->addParams = 0;
currentToken->addParamsSize = 0;
currentToken->tokenType = 0;
if (rgReaderStates.dwEventState & SCARD_STATE_EMPTY)
{
currentToken->tokenType |= MSC_TOKEN_TYPE_REMOVED;
strncpy(currentToken->tokenName,
MSC_TOKEN_EMPTY_STR, MSC_MAXSIZE_TOKENAME);
} else if (rv == 0)
{
currentToken->tokenType |= MSC_TOKEN_TYPE_KNOWN;
strncpy(currentToken->tokenName,
tokenInfo.tokenName, MSC_MAXSIZE_TOKENAME);
} else
{
currentToken->tokenType |= MSC_TOKEN_TYPE_UNKNOWN;
strncpy(currentToken->tokenName,
MSC_TOKEN_UNKNOWN_STR, MSC_MAXSIZE_TOKENAME);
}
strncpy(currentToken->slotName,
rgReaderStates.szReader, MAX_READERNAME);
if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT)
{
memcpy(currentToken->tokenId,
rgReaderStates.rgbAtr, rgReaderStates.cbAtr);
currentToken->tokenIdLength = rgReaderStates.cbAtr;
}
else
{
memset(currentToken->tokenId, 0x00, MAX_ATR_SIZE);
currentToken->tokenIdLength = 0x00;
}
if (rv == 0)
{
memcpy(currentToken->tokenApp,
tokenInfo.tokenApp, tokenInfo.tokenAppLen);
currentToken->tokenAppLen = tokenInfo.tokenAppLen;
strncpy(currentToken->svProvider,
tokenInfo.svProvider, MSC_MAXSIZE_SVCPROV);
} else
{
memset(currentToken->tokenApp, 0x00, MSC_MAXSIZE_AID);
currentToken->tokenAppLen = 0x00;
memset(currentToken->svProvider, 0x00, MSC_MAXSIZE_SVCPROV);
}
currentToken->tokenState = rgReaderStates.dwEventState;
}
}
}
while (readerList[++i] != 0) ;
}
if (readerList)
free(readerList);
if (tokenArray == 0)
{
*arrayLength = tokensFound;
return MSC_SUCCESS;
}
if (*arrayLength < tokensFound)
{
*arrayLength = tokensFound;
return MSC_INSUFFICIENT_BUFFER;
}
*arrayLength = tokensFound;
return MSC_SUCCESS;
}
MSC_RV MSCEstablishConnection(MSCLPTokenInfo tokenStruct,
MSCULong32 sharingMode,
MSCPUChar8 applicationName,
MSCULong32 nameSize,
MSCLPTokenConnection pConnection)
{
MSCLong32 rv;
MSCULong32 tokenSize;
MSCLPTokenInfo tokenList;
MSCPVoid32 vInitFunction;
MSCPVoid32 vIdFunction;
MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection);
MSCLong32(*libPL_MSCIdentifyToken) (MSCLPTokenConnection);
MSCULong32 dwActiveProtocol;
int selectedIFD;
char slotName[MAX_READERNAME];
MSCULong32 slotNameSize, slotState, slotProtocol;
MSCUChar8 tokenId[MAX_ATR_SIZE];
MSCULong32 tokenIdLength;
tokenSize = 0;
tokenList = 0;
tokenSize = 0;
selectedIFD = -1;
tokenIdLength = sizeof(tokenId);
slotState = 0;
slotProtocol = 0;
slotNameSize = sizeof(slotName);
vIdFunction = 0;
vInitFunction = 0;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (tokenStruct == NULL)
return MSC_INVALID_PARAMETER;
if (nameSize > MSC_MAXSIZE_AID)
return MSC_INVALID_PARAMETER;
pConnection->tokenLibHandle = 0;
pConnection->hContext = 0;
pConnection->tokenInfo.tokenIdLength = 0;
pConnection->shareMode = 0;
if (sharingMode != MSC_SHARE_DIRECT)
{
if (strcmp(tokenStruct->tokenName, MSC_TOKEN_EMPTY_STR) == 0)
{
return MSC_TOKEN_REMOVED;
} else if (strcmp(tokenStruct->tokenName,
MSC_TOKEN_UNKNOWN_STR) == 0)
{
return MSC_UNRECOGNIZED_TOKEN;
}
}
mscLockThread();
if (localHContext == 0)
{
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
&localHContext);
#ifdef MSC_DEBUG
DebugLogB("SCardEstablishContext returns %s\n",
pcsc_stringify_error(rv));
#endif
if (pcscToMSC(rv) != MSC_SUCCESS)
{
localHContext = 0;
mscUnLockThread();
return pcscToMSC(rv);
}
pConnection->hContext = localHContext;
} else
{
pConnection->hContext = localHContext;
}
mscUnLockThread();
#ifdef WIN32
rv = SCardConnect(pConnection->hContext, tokenStruct->slotName,
SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&pConnection->hCard, &dwActiveProtocol);
#else
rv = SCardConnect(pConnection->hContext, tokenStruct->slotName,
sharingMode, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&pConnection->hCard, &dwActiveProtocol);
#endif
#ifdef MSC_DEBUG
DebugLogB("SCardConnect returns %s\n", pcsc_stringify_error(rv));
#endif
if (pcscToMSC(rv) != MSC_SUCCESS)
{
return pcscToMSC(rv);
}
switch (dwActiveProtocol)
{
case SCARD_PROTOCOL_T0:
pConnection->ioType = SCARD_PCI_T0;
break;
case SCARD_PROTOCOL_T1:
pConnection->ioType = SCARD_PCI_T1;
break;
default:
pConnection->ioType = SCARD_PCI_RAW;
break;
}
rv = SCardStatus(pConnection->hCard, slotName,
&slotNameSize, &slotState, &slotProtocol, tokenId, &tokenIdLength);
#ifdef MSC_DEBUG
DebugLogB("SCardStatus returns %s\n", pcsc_stringify_error(rv));
#endif
if (pcscToMSC(rv) != MSC_SUCCESS)
{
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
pConnection->hCard = 0;
return pcscToMSC(rv);
}
if ((sharingMode == MSC_SHARE_DIRECT) && (slotState & SCARD_ABSENT))
{
pConnection->shareMode = sharingMode;
return MSC_SUCCESS;
}
if ((tokenIdLength != tokenStruct->tokenIdLength) ||
(strcmp(slotName, tokenStruct->slotName) != 0) ||
(memcmp(tokenId, tokenStruct->tokenId, tokenIdLength) != 0))
{
DebugLogA("Internal inconsistent values, ID, slotName\n");
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
pConnection->hCard = 0;
return MSC_INCONSISTENT_STATUS;
}
memcpy(pConnection->tokenInfo.tokenId, tokenId, tokenIdLength);
pConnection->tokenInfo.tokenIdLength = tokenIdLength;
strncpy(pConnection->tokenInfo.slotName, tokenStruct->slotName,
MAX_READERNAME);
strncpy(pConnection->tokenInfo.tokenName, tokenStruct->tokenName,
MSC_MAXSIZE_TOKENAME);
rv = TPLoadToken(pConnection);
#ifdef MSC_DEBUG
DebugLogB("TPLoadToken returns %s\n", pcsc_stringify_error(rv));
#endif
if (rv != SCARD_S_SUCCESS)
{
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
pConnection->hCard = 0;
return pcscToMSC(rv);
}
vInitFunction = pConnection->libPointers.pvfInitializePlugin;
vIdFunction = pConnection->libPointers.pvfIdentifyToken;
if (vInitFunction == 0)
{
DebugLogB("Error: Card service failure: %s\n",
"InitializePlugin function missing");
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
pConnection->hCard = 0;
return MSC_UNSUPPORTED_FEATURE;
}
if (vIdFunction == 0)
{
DebugLogB("Error: Card service failure: %s\n",
"IdentifyToken function missing");
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
pConnection->hCard = 0;
return MSC_UNSUPPORTED_FEATURE;
}
libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
vInitFunction;
libPL_MSCIdentifyToken = (MSCLong32(*)(MSCLPTokenConnection))
vIdFunction;
rv = (*libPL_MSCInitializePlugin) (pConnection);
if (rv != MSC_SUCCESS)
{
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
if (pConnection->tokenLibHandle != 0)
{
TPUnloadToken(pConnection);
pConnection->tokenLibHandle = 0;
}
pConnection->hCard = 0;
}
if (sharingMode != MSC_SHARE_DIRECT)
{
if ((applicationName == 0) || (nameSize == 0))
{
rv = (*libPL_MSCIdentifyToken) (pConnection);
} else
{
pConnection->tokenInfo.tokenAppLen = nameSize;
memcpy(pConnection->tokenInfo.tokenApp,
applicationName, nameSize);
rv = (*libPL_MSCIdentifyToken) (pConnection);
}
#ifdef MSC_DEBUG
DebugLogB("MSCIdentifyToken returns %s\n", msc_error(rv));
#endif
if (rv != MSC_SUCCESS)
{
SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
if (pConnection->tokenLibHandle != 0)
{
TPUnloadToken(pConnection);
pConnection->tokenLibHandle = 0;
}
pConnection->hCard = 0;
if (rv == MSC_SHARING_VIOLATION)
{
return rv;
} else
{
return MSC_UNRECOGNIZED_TOKEN;
}
}
}
pConnection->shareMode = sharingMode;
return MSC_SUCCESS;
}
MSC_RV MSCReleaseConnection(MSCLPTokenConnection pConnection,
MSCULong32 endAction)
{
MSCLong32 rv = SCARD_S_SUCCESS;
MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
MSCPVoid32 vFunction;
vFunction = 0;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (pConnection->tokenLibHandle == 0 ||
pConnection->hContext == 0 || pConnection->hCard == 0)
{
return MSC_INVALID_HANDLE;
}
vFunction = pConnection->libPointers.pvfFinalizePlugin;
if (vFunction == 0)
{
DebugLogB("Error: Card service failure: %s\n",
"FinalizePlugin function missing");
return MSC_INTERNAL_ERROR;
}
libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection))
vFunction;
rv = (*libPL_MSCFinalizePlugin) (pConnection);
if (pConnection->hCard != 0)
{
rv = SCardDisconnect(pConnection->hCard, endAction);
if (pcscToMSC(rv) != MSC_SUCCESS)
{
return pcscToMSC(rv);
}
}
if (pConnection->tokenLibHandle != 0)
{
rv = TPUnloadToken(pConnection);
pConnection->tokenLibHandle = 0;
}
pConnection->tokenLibHandle = 0;
pConnection->hCard = 0;
pConnection->hContext = 0;
pConnection->shareMode = 0;
return MSC_SUCCESS;
}
MSC_RV MSCWaitForTokenEvent(MSCLPTokenInfo tokenArray,
MSCULong32 arraySize,
MSCULong32 timeoutValue)
{
MSCLong32 rv, rt;
LPSCARD_READERSTATE_A rgReaderStates;
MSCTokenInfo tokenInfo;
int i;
rgReaderStates = 0;
if (arraySize == 0)
{
return MSC_SUCCESS;
} else if (arraySize > MSC_MAXSIZE_TOKENARRAY)
{
return MSC_INSUFFICIENT_BUFFER;
}
mscLockThread();
if (localHContext == 0)
{
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
&localHContext);
if (pcscToMSC(rv) != MSC_SUCCESS)
{
localHContext = 0;
mscUnLockThread();
return pcscToMSC(rv);
}
}
mscUnLockThread();
rgReaderStates = (LPSCARD_READERSTATE_A)
malloc(sizeof(SCARD_READERSTATE_A) * arraySize);
if (rgReaderStates == 0)
{
return MSC_INTERNAL_ERROR;
}
for (i = 0; i < arraySize; i++)
{
if (strlen(tokenArray[i].slotName) == 0)
{
free(rgReaderStates);
return MSC_INVALID_PARAMETER;
}
rgReaderStates[i].szReader = tokenArray[i].slotName;
rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
rgReaderStates[i].dwEventState = 0;
}
rv = SCardGetStatusChange(localHContext, timeoutValue,
rgReaderStates, arraySize);
if (rv != SCARD_S_SUCCESS)
{
free(rgReaderStates);
return pcscToMSC(rv);
}
for (i = 0; i < arraySize; i++)
{
if (tokenArray[i].tokenState == 0)
{
rgReaderStates[i].dwCurrentState =
rgReaderStates[i].dwEventState;
} else if (tokenArray[i].tokenState == MSC_STATE_UNAWARE)
{
rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
} else
{
rgReaderStates[i].dwCurrentState = tokenArray[i].tokenState;
}
rgReaderStates[i].dwEventState = 0;
}
rv = SCardGetStatusChange(localHContext, timeoutValue,
rgReaderStates, arraySize);
for (i = 0; i < arraySize; i++)
{
tokenArray[i].tokenState = rgReaderStates[i].dwEventState;
if (tokenArray[i].tokenState & MSC_STATE_CHANGED)
{
if (tokenArray[i].tokenState & MSC_STATE_EMPTY)
{
memset(tokenArray[i].tokenId, 0x00, MAX_ATR_SIZE);
tokenArray[i].tokenIdLength = 0;
tokenArray[i].tokenType = MSC_TOKEN_TYPE_REMOVED;
strncpy(tokenArray[i].tokenName, MSC_TOKEN_EMPTY_STR,
MSC_MAXSIZE_TOKENAME);
} else if (tokenArray[i].tokenState & MSC_STATE_PRESENT)
{
memcpy(tokenArray[i].tokenId, rgReaderStates[i].rgbAtr,
rgReaderStates[i].cbAtr);
tokenArray[i].tokenIdLength = rgReaderStates[i].cbAtr;
rt = TPSearchBundlesForAtr(rgReaderStates[i].rgbAtr,
rgReaderStates[i].cbAtr, &tokenInfo);
if (rt == 0)
{
tokenArray[i].tokenType = MSC_TOKEN_TYPE_KNOWN;
strncpy(tokenArray[i].tokenName, tokenInfo.tokenName,
MSC_MAXSIZE_TOKENAME);
} else
{
tokenArray[i].tokenType = MSC_TOKEN_TYPE_UNKNOWN;
strncpy(tokenArray[i].tokenName, MSC_TOKEN_UNKNOWN_STR,
MSC_MAXSIZE_TOKENAME);
}
}
}
}
free(rgReaderStates);
return pcscToMSC(rv);
}
MSC_RV MSCCancelEventWait(void)
{
MSCLong32 rv;
rv = SCardCancel(localHContext);
return pcscToMSC(rv);
}
#ifdef USE_THREAD_SAFETY
void *_MSCEventThread(void *arg)
{
MSCLong32 rv;
MSCLPEventWaitInfo evlist;
MSCLong32 curToken;
if (arg == NULL)
{
SYS_ThreadExit(NULL);
}
evlist = (MSCLPEventWaitInfo) arg;
blockingContext = MSC_BLOCKSTATUS_BLOCKING;
while (1)
{
rv = MSCWaitForTokenEvent(evlist->tokenArray,
evlist->arraySize,
MSC_NO_TIMEOUT);
if (rv == MSC_SUCCESS)
{
(evlist->callBack) (evlist->tokenArray,
evlist->arraySize,
evlist->appData);
} else {
break;
}
if (blockingContext == MSC_BLOCKSTATUS_CANCELLING)
{
break;
}
}
for (curToken = 0; curToken < evlist->arraySize; curToken++)
{
if (evlist->tokenArray[curToken].addParams)
{
free(evlist->tokenArray[curToken].addParams);
}
}
free(evlist);
blockingContext = MSC_BLOCKSTATUS_RESUME;
SYS_ThreadExit(&rv);
return NULL;
}
MSC_RV MSCCallbackForTokenEvent(MSCLPTokenInfo tokenArray,
MSCULong32 arraySize,
MSCCallBack callBack,
MSCPVoid32 appData)
{
MSCLPEventWaitInfo evlist;
MSCULong32 curToken;
evlist = (MSCLPEventWaitInfo) malloc(sizeof(MSCEventWaitInfo));
if (evlist == NULL)
{
return MSC_INTERNAL_ERROR;
}
evlist->arraySize = arraySize;
evlist->tokenArray = malloc(sizeof(MSCTokenInfo) * arraySize);
evlist->appData = appData;
evlist->callBack = callBack;
if (evlist->tokenArray == NULL)
{
free(evlist);
return MSC_INTERNAL_ERROR;
}
mscLockThread();
memcpy(evlist->tokenArray, tokenArray,
sizeof(MSCTokenInfo) * arraySize);
for (curToken = 0; curToken < arraySize; curToken++)
{
if (tokenArray[curToken].addParams != NULL)
{
evlist->tokenArray[curToken].addParams =
malloc(evlist->tokenArray[curToken].addParamsSize);
memcpy((void *) (evlist->tokenArray[curToken].addParams),
&tokenArray[curToken],
evlist->tokenArray[curToken].addParamsSize);
}
}
mscUnLockThread();
if (SYS_ThreadCreate(&callbackThread, THREAD_ATTR_DEFAULT, _MSCEventThread,
(void *) evlist) == 0)
{
return MSC_INTERNAL_ERROR;
}
return MSC_SUCCESS;
}
MSC_RV MSCCallbackCancelEvent()
{
LONG rv;
if (blockingContext == MSC_BLOCKSTATUS_BLOCKING)
{
blockingContext = MSC_BLOCKSTATUS_CANCELLING;
rv = MSCCancelEventWait();
SYS_ThreadJoin(&callbackThread, 0);
}
return MSC_SUCCESS;
}
#endif
MSC_RV MSCBeginTransaction(MSCLPTokenConnection pConnection)
{
MSCLong32 rv;
MSCLong32 ret;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
while (1)
{
rv = SCardBeginTransaction(pConnection->hCard);
ret = pcscToMSC(rv);
if (ret == MSC_SUCCESS)
break;
if (ret == MSC_TOKEN_RESET)
{
pConnection->tokenInfo.tokenType |=
MSC_TOKEN_TYPE_RESET;
ret = MSCReEstablishConnection(pConnection);
if (ret != MSC_SUCCESS)
break;
continue;
} else if (ret == MSC_TOKEN_REMOVED)
{
pConnection->tokenInfo.tokenType =
MSC_TOKEN_TYPE_REMOVED;
return ret;
}
}
return ret;
}
MSC_RV MSCEndTransaction(MSCLPTokenConnection pConnection,
MSCULong32 endAction)
{
MSCLong32 rv;
MSCLong32 ret;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
while (1)
{
rv = SCardEndTransaction(pConnection->hCard, endAction);
ret = pcscToMSC(rv);
if (ret == MSC_SUCCESS)
break;
if (ret == MSC_TOKEN_RESET)
{
pConnection->tokenInfo.tokenType |=
MSC_TOKEN_TYPE_RESET;
ret = MSCReEstablishConnection(pConnection);
if (ret != MSC_SUCCESS)
break;
continue;
} else if (ret == MSC_TOKEN_REMOVED)
{
pConnection->tokenInfo.tokenType =
MSC_TOKEN_TYPE_REMOVED;
return ret;
}
}
return ret;
}
MSC_RV MSCWriteFramework(MSCLPTokenConnection pConnection,
MSCLPInitTokenParams pInitParams)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCWriteFramework) (MSCLPTokenConnection,
MSCLPInitTokenParams);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfWriteFramework;
if (vFunction != 0)
{
libMSCWriteFramework = (MSCLong32(*)(MSCLPTokenConnection,
MSCLPInitTokenParams)) vFunction;
rv = (*libMSCWriteFramework) (pConnection, pInitParams);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCGetStatus(MSCLPTokenConnection pConnection,
MSCLPStatusInfo pStatusInfo)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCGetStatus) (MSCLPTokenConnection, MSCLPStatusInfo);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfGetStatus;
if (vFunction != 0)
{
libMSCGetStatus = (MSCLong32(*)(MSCLPTokenConnection,
MSCLPStatusInfo)) vFunction;
rv = (*libMSCGetStatus) (pConnection, pStatusInfo);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCGetCapabilities(MSCLPTokenConnection pConnection, MSCULong32 Tag,
MSCPUChar8 Value, MSCPULong32 Length)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCGetCapabilities) (MSCLPTokenConnection, MSCULong32,
MSCPUChar8, MSCPULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfGetCapabilities;
if (vFunction != 0)
{
libMSCGetCapabilities =
(MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8,
MSCPULong32)) vFunction;
rv = (*libMSCGetCapabilities) (pConnection, Tag, Value, Length);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCExtendedFeature(MSCLPTokenConnection pConnection,
MSCULong32 extFeature, MSCPUChar8 outData,
MSCULong32 outLength, MSCPUChar8 inData, MSCPULong32 inLength)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCExtendedFeature) (MSCLPTokenConnection, MSCULong32,
MSCPUChar8, MSCULong32, MSCPUChar8, MSCPULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfExtendedFeature;
if (vFunction != 0)
{
libMSCExtendedFeature =
(MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8,
MSCULong32, MSCPUChar8, MSCPULong32)) vFunction;
rv = (*libMSCExtendedFeature) (pConnection, extFeature, outData,
outLength, inData, inLength);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCGenerateKeys(MSCLPTokenConnection pConnection,
MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum, MSCLPGenKeyParams pParams)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCGenerateKeys) (MSCLPTokenConnection, MSCUChar8,
MSCUChar8, MSCLPGenKeyParams);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfGenerateKeys;
if (vFunction != 0)
{
libMSCGenerateKeys = (MSCLong32(*)(MSCLPTokenConnection,
MSCUChar8, MSCUChar8,
MSCLPGenKeyParams))
vFunction;
rv = (*libMSCGenerateKeys) (pConnection, prvKeyNum, pubKeyNum,
pParams);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCImportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,MSCULong32 keyBlobSize,
MSCLPKeyPolicy keyPolicy, MSCPVoid32 pAddParams,
MSCUChar8 addParamsSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCImportKey) (MSCLPTokenConnection, MSCUChar8,
MSCLPKeyACL, MSCPUChar8,
MSCULong32, MSCLPKeyPolicy, MSCPVoid32,
MSCUChar8);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfImportKey;
if (vFunction != 0)
{
libMSCImportKey = (MSCLong32(*)(MSCLPTokenConnection,
MSCUChar8,
MSCLPKeyACL, MSCPUChar8,
MSCULong32, MSCLPKeyPolicy,
MSCPVoid32, MSCUChar8))
vFunction;
rv = (*libMSCImportKey) (pConnection, keyNum,
pKeyACL, pKeyBlob, keyBlobSize,
keyPolicy, pAddParams, addParamsSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCExportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
MSCPVoid32 pAddParams, MSCUChar8 addParamsSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCExportKey) (MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCPULong32, MSCPVoid32, MSCUChar8);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfExportKey;
if (vFunction != 0)
{
libMSCExportKey = (MSCLong32(*)(MSCLPTokenConnection,
MSCUChar8, MSCPUChar8,
MSCPULong32, MSCPVoid32,
MSCUChar8)) vFunction;
rv = (*libMSCExportKey) (pConnection, keyNum, pKeyBlob,
keyBlobSize, pAddParams, addParamsSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCComputeCrypt(MSCLPTokenConnection pConnection,
MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
MSCPULong32 outputDataSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCComputeCrypt) (MSCLPTokenConnection, MSCLPCryptInit,
MSCPUChar8, MSCULong32, MSCPUChar8,
MSCPULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfComputeCrypt;
if (vFunction != 0)
{
libMSCComputeCrypt =
(MSCLong32(*)(MSCLPTokenConnection, MSCLPCryptInit,
MSCPUChar8, MSCULong32, MSCPUChar8,
MSCPULong32)) vFunction;
rv = (*libMSCComputeCrypt) (pConnection, cryptInit, pInputData,
inputDataSize, pOutputData,
outputDataSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCExtAuthenticate(MSCLPTokenConnection pConnection,
MSCUChar8 keyNum, MSCUChar8 cipherMode,
MSCUChar8 cipherDirection,
MSCPUChar8 pData, MSCULong32 dataSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCExtAuthenticate) (MSCLPTokenConnection, MSCUChar8,
MSCUChar8, MSCUChar8, MSCPUChar8,
MSCULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfExtAuthenticate;
if (vFunction != 0)
{
libMSCExtAuthenticate =
(MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCUChar8, MSCUChar8, MSCPUChar8,
MSCULong32)) vFunction;
rv = (*libMSCExtAuthenticate) (pConnection, keyNum, cipherMode,
cipherDirection, pData, dataSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCListKeys(MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
MSCLPKeyInfo pKeyInfo)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCListKeys) (MSCLPTokenConnection, MSCUChar8,
MSCLPKeyInfo);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfListKeys;
if (vFunction != 0)
{
libMSCListKeys = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCLPKeyInfo)) vFunction;
rv = (*libMSCListKeys) (pConnection, seqOption, pKeyInfo);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCCreatePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
MSCUChar8 unblockCodeSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCCreatePIN) (MSCLPTokenConnection, MSCUChar8,
MSCUChar8, MSCPUChar8, MSCULong32, MSCPUChar8, MSCUChar8);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfCreatePIN;
if (vFunction != 0)
{
libMSCCreatePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCUChar8, MSCPUChar8,
MSCULong32, MSCPUChar8, MSCUChar8)) vFunction;
rv = (*libMSCCreatePIN) (pConnection, pinNum, pinAttempts,
pPinCode, pinCodeSize, pUnblockCode, unblockCodeSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCVerifyPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
MSCPUChar8 pPinCode, MSCULong32 pinCodeSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCVerifyPIN) (MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfVerifyPIN;
if (vFunction != 0)
{
libMSCVerifyPIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCULong32)) vFunction;
rv = (*libMSCVerifyPIN) (pConnection, pinNum, pPinCode,
pinCodeSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCChangePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCChangePIN) (MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfChangePIN;
if (vFunction != 0)
{
libMSCChangePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8)) vFunction;
rv = (*libMSCChangePIN) (pConnection, pinNum, pOldPinCode,
oldPinCodeSize, pNewPinCode, newPinCodeSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCUnblockPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCUnblockPIN) (MSCLPTokenConnection, MSCUChar8,
MSCPUChar8, MSCULong32);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfUnblockPIN;
if (vFunction != 0)
{
libMSCUnblockPIN = (MSCLong32(*)(MSCLPTokenConnection,
MSCUChar8, MSCPUChar8, MSCULong32)) vFunction;
rv = (*libMSCUnblockPIN) (pConnection, pinNum, pUnblockCode,
unblockCodeSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCListPINs(MSCLPTokenConnection pConnection,
MSCPUShort16 pPinBitMask)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCListPINs) (MSCLPTokenConnection, MSCPUShort16);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfListPINs;
if (vFunction != 0)
{
libMSCListPINs = (MSCLong32(*)(MSCLPTokenConnection,
MSCPUShort16)) vFunction;
rv = (*libMSCListPINs) (pConnection, pPinBitMask);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCCreateObject(MSCLPTokenConnection pConnection,
MSCString objectID, MSCULong32 objectSize, MSCLPObjectACL pObjectACL)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCCreateObject) (MSCLPTokenConnection, MSCString,
MSCULong32, MSCLPObjectACL);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfCreateObject;
if (vFunction != 0)
{
libMSCCreateObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
MSCULong32, MSCLPObjectACL)) vFunction;
rv = (*libMSCCreateObject) (pConnection, objectID, objectSize,
pObjectACL);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCDeleteObject(MSCLPTokenConnection pConnection,
MSCString objectID, MSCUChar8 zeroFlag)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCDeleteObject) (MSCLPTokenConnection, MSCString,
MSCUChar8);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfDeleteObject;
if (vFunction != 0)
{
libMSCDeleteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
MSCUChar8)) vFunction;
rv = (*libMSCDeleteObject) (pConnection, objectID, zeroFlag);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCWriteObject(MSCLPTokenConnection pConnection,
MSCString objectID, MSCULong32 offSet,
MSCPUChar8 pInputData, MSCULong32 dataSize,
LPRWEventCallback rwCallback, MSCPVoid32 addParams)
{
MSC_RV rv = MSC_UNSPECIFIED_ERROR;
MSCULong32 objectSize;
int totalSteps, stepInterval;
MSC_RV(*callBackFunction) (void *, int);
MSCPVoid32 vFunction;
MSCLong32(*libMSCWriteObject) (MSCLPTokenConnection, MSCString,
MSCULong32, MSCPUChar8, MSCUChar8);
int i;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfWriteObject;
callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
objectSize = dataSize;
if (vFunction == 0)
{
return MSC_UNSUPPORTED_FEATURE;
}
libMSCWriteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
MSCULong32, MSCPUChar8, MSCUChar8))
vFunction;
totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1;
stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++)
{
rv = (*libMSCWriteObject) (pConnection, objectID,
i * MSC_SIZEOF_KEYPACKET + offSet,
&pInputData[i * MSC_SIZEOF_KEYPACKET],
MSC_SIZEOF_KEYPACKET);
if (rv != MSC_SUCCESS)
{
return rv;
}
if (rwCallback)
{
if ((*callBackFunction) (addParams,
stepInterval * i) == MSC_CANCELLED)
{
return MSC_CANCELLED;
}
}
}
if (objectSize % MSC_SIZEOF_KEYPACKET)
{
rv = (*libMSCWriteObject) (pConnection, objectID,
i * MSC_SIZEOF_KEYPACKET + offSet,
&pInputData[i * MSC_SIZEOF_KEYPACKET],
objectSize % MSC_SIZEOF_KEYPACKET);
if (rv != MSC_SUCCESS)
{
return rv;
}
}
if (rwCallback)
{
(*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE);
}
return rv;
}
MSC_RV MSCReadObject(MSCLPTokenConnection pConnection,
MSCString objectID, MSCULong32 offSet,
MSCPUChar8 pOutputData, MSCULong32 dataSize,
LPRWEventCallback rwCallback,
MSCPVoid32 addParams)
{
MSC_RV rv = MSC_UNSPECIFIED_ERROR;
MSCULong32 objectSize;
int totalSteps, stepInterval;
MSC_RV(*callBackFunction) (void *, int);
MSCPVoid32 vFunction;
MSCLong32(*libMSCReadObject) (MSCLPTokenConnection, MSCString,
MSCULong32, MSCPUChar8, MSCUChar8);
int i;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfReadObject;
callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
objectSize = dataSize;
if (vFunction == 0)
{
return MSC_UNSUPPORTED_FEATURE;
}
libMSCReadObject = (MSCLong32(*)(MSCLPTokenConnection,
MSCString, MSCULong32,
MSCPUChar8, MSCUChar8))
vFunction;
totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1;
stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++)
{
rv = (*libMSCReadObject) (pConnection, objectID,
i * MSC_SIZEOF_KEYPACKET + offSet,
&pOutputData[i * MSC_SIZEOF_KEYPACKET],
MSC_SIZEOF_KEYPACKET);
if (rv != MSC_SUCCESS)
{
return rv;
}
if (rwCallback)
{
if ((*callBackFunction) (addParams,
stepInterval * i) == MSC_CANCELLED)
{
return MSC_CANCELLED;
}
}
}
if (objectSize % MSC_SIZEOF_KEYPACKET)
{
rv = (*libMSCReadObject) (pConnection, objectID,
i * MSC_SIZEOF_KEYPACKET + offSet,
&pOutputData[i * MSC_SIZEOF_KEYPACKET],
objectSize % MSC_SIZEOF_KEYPACKET);
if (rv != MSC_SUCCESS)
{
return rv;
}
}
if (rwCallback)
{
(*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE);
}
return rv;
}
MSC_RV MSCListObjects(MSCLPTokenConnection pConnection,
MSCUChar8 seqOption, MSCLPObjectInfo pObjectInfo)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCListObjects) (MSCLPTokenConnection, MSCUChar8,
MSCLPObjectInfo);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfListObjects;
if (vFunction != 0)
{
libMSCListObjects = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
MSCLPObjectInfo)) vFunction;
rv = (*libMSCListObjects) (pConnection, seqOption, pObjectInfo);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCLogoutAll(MSCLPTokenConnection pConnection)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCLogoutAll) (MSCLPTokenConnection);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfLogoutAll;
if (vFunction != 0)
{
libMSCLogoutAll = (MSCLong32(*)(MSCLPTokenConnection)) vFunction;
rv = (*libMSCLogoutAll) (pConnection);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCGetChallenge(MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
MSCUShort16 seedSize, MSCPUChar8 pRandomData,
MSCUShort16 randomDataSize)
{
MSCLong32 rv;
MSCPVoid32 vFunction;
MSCLong32(*libMSCGetChallenge) (MSCLPTokenConnection, MSCPUChar8,
MSCUShort16, MSCPUChar8, MSCUShort16);
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
vFunction = pConnection->libPointers.pvfGetChallenge;
if (vFunction != 0)
{
libMSCGetChallenge = (MSCLong32(*)(MSCLPTokenConnection,
MSCPUChar8, MSCUShort16,
MSCPUChar8, MSCUShort16)) vFunction;
rv = (*libMSCGetChallenge) (pConnection, pSeed, seedSize,
pRandomData, randomDataSize);
} else
{
return MSC_UNSUPPORTED_FEATURE;
}
return rv;
}
MSC_RV MSCGetKeyAttributes(MSCLPTokenConnection pConnection,
MSCUChar8 keyNumber, MSCLPKeyInfo pKeyInfo)
{
MSC_RV rv;
MSCKeyInfo keyInfo;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
rv = MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyInfo);
if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
{
return rv;
}
if (rv == MSC_SEQUENCE_END)
{
return MSC_INVALID_PARAMETER;
}
if (keyNumber == keyInfo.keyNum)
{
pKeyInfo->keyNum = keyInfo.keyNum;
pKeyInfo->keyType = keyInfo.keyType;
pKeyInfo->keySize = keyInfo.keySize;
pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode;
pKeyInfo->keyPolicy.cipherDirection =
keyInfo.keyPolicy.cipherDirection;
pKeyInfo->keyACL.readPermission =
keyInfo.keyACL.readPermission;
pKeyInfo->keyACL.writePermission =
keyInfo.keyACL.writePermission;
pKeyInfo->keyACL.usePermission =
keyInfo.keyACL.usePermission;
return MSC_SUCCESS;
}
do
{
rv = MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyInfo);
if (keyNumber == keyInfo.keyNum)
break;
}
while (rv == MSC_SUCCESS);
if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
{
return rv;
}
if (rv == MSC_SEQUENCE_END)
{
return MSC_INVALID_PARAMETER;
}
pKeyInfo->keyNum = keyInfo.keyNum;
pKeyInfo->keyType = keyInfo.keyType;
pKeyInfo->keySize = keyInfo.keySize;
pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode;
pKeyInfo->keyPolicy.cipherDirection =
keyInfo.keyPolicy.cipherDirection;
pKeyInfo->keyACL.readPermission = keyInfo.keyACL.readPermission;
pKeyInfo->keyACL.writePermission = keyInfo.keyACL.writePermission;
pKeyInfo->keyACL.usePermission = keyInfo.keyACL.usePermission;
return MSC_SUCCESS;
}
MSC_RV MSCGetObjectAttributes(MSCLPTokenConnection pConnection,
MSCString objectID, MSCLPObjectInfo pObjectInfo)
{
MSC_RV rv;
MSCObjectInfo objInfo;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
rv = MSCListObjects(pConnection, MSC_SEQUENCE_RESET, &objInfo);
if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
{
return rv;
}
if (rv == MSC_SEQUENCE_END)
{
return MSC_OBJECT_NOT_FOUND;
}
if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0)
{
pObjectInfo->objectSize = objInfo.objectSize;
pObjectInfo->objectACL.readPermission =
objInfo.objectACL.readPermission;
pObjectInfo->objectACL.writePermission =
objInfo.objectACL.writePermission;
pObjectInfo->objectACL.deletePermission =
objInfo.objectACL.deletePermission;
strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
return MSC_SUCCESS;
}
do
{
rv = MSCListObjects(pConnection, MSC_SEQUENCE_NEXT, &objInfo);
if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0)
break;
}
while (rv == MSC_SUCCESS);
if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
{
return rv;
}
if (rv == MSC_SEQUENCE_END)
{
return MSC_OBJECT_NOT_FOUND;
}
pObjectInfo->objectSize = objInfo.objectSize;
pObjectInfo->objectACL.readPermission =
objInfo.objectACL.readPermission;
pObjectInfo->objectACL.writePermission =
objInfo.objectACL.writePermission;
pObjectInfo->objectACL.deletePermission =
objInfo.objectACL.deletePermission;
strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
return MSC_SUCCESS;
}
MSC_RV MSCReadAllocateObject(MSCLPTokenConnection pConnection,
MSCString objectID, MSCPUChar8 * pOutputData,
MSCPULong32 dataSize,
LPRWEventCallback rwCallback,
MSCPVoid32 addParams)
{
MSC_RV rv;
MSCObjectInfo objInfo;
MSCULong32 objectSize;
MSCPUChar8 data = NULL;
if (pConnection == NULL)
return MSC_INVALID_PARAMETER;
if (localHContext == 0)
return MSC_INTERNAL_ERROR;
if (pOutputData == 0)
{
return MSC_INVALID_PARAMETER;
}
*dataSize = 0;
*pOutputData = 0;
rv = MSCGetObjectAttributes(pConnection, objectID, &objInfo);
if (rv == MSC_SUCCESS)
{
objectSize = objInfo.objectSize;
data = (MSCPUChar8) malloc(sizeof(MSCUChar8) * objectSize);
if(data)
{
rv = MSCReadObject(pConnection, objectID, 0, data,
objectSize, rwCallback, addParams);
if (rv == MSC_SUCCESS)
{
*dataSize = objectSize;
*pOutputData = data;
}
else
{
rv = MSC_INTERNAL_ERROR;
free(data);
}
}
}
return rv;
}
MSC_RV pcscToMSC(MSCLong32 pcscCode)
{
switch (pcscCode)
{
case SCARD_S_SUCCESS:
return MSC_SUCCESS;
case SCARD_E_INVALID_HANDLE:
return MSC_INVALID_HANDLE;
case SCARD_E_SHARING_VIOLATION:
return MSC_SHARING_VIOLATION;
case SCARD_W_REMOVED_CARD:
return MSC_TOKEN_REMOVED;
case SCARD_E_NO_SMARTCARD:
return MSC_TOKEN_REMOVED;
case SCARD_W_RESET_CARD:
return MSC_TOKEN_RESET;
case SCARD_W_INSERTED_CARD:
return MSC_TOKEN_INSERTED;
case SCARD_E_NO_SERVICE:
return MSC_SERVICE_UNRESPONSIVE;
case SCARD_E_UNKNOWN_CARD:
case SCARD_W_UNSUPPORTED_CARD:
case SCARD_E_CARD_UNSUPPORTED:
return MSC_UNRECOGNIZED_TOKEN;
case SCARD_E_INVALID_PARAMETER:
case SCARD_E_INVALID_VALUE:
case SCARD_E_UNKNOWN_READER:
case SCARD_E_PROTO_MISMATCH:
case SCARD_E_READER_UNAVAILABLE:
return MSC_INVALID_PARAMETER;
case SCARD_E_CANCELLED:
return MSC_CANCELLED;
case SCARD_E_TIMEOUT:
return MSC_TIMEOUT_OCCURRED;
default:
return MSC_INTERNAL_ERROR;
}
}
char *msc_error(unsigned long int errorCode) {
static char message[500];
switch (errorCode)
{
case MSC_SUCCESS:
strncpy(message, "Successful", sizeof(message));
break;
case MSC_NO_MEMORY_LEFT:
strncpy(message, "No more memory", sizeof(message));
break;
case MSC_AUTH_FAILED:
strncpy(message, "Authentication failed", sizeof(message));
break;
case MSC_OPERATION_NOT_ALLOWED:
strncpy(message, "Operation not allowed", sizeof(message));
break;
case MSC_INCONSISTENT_STATUS:
strncpy(message, "Inconsistent status", sizeof(message));
break;
case MSC_UNSUPPORTED_FEATURE:
strncpy(message, "Feature unsupported", sizeof(message));
break;
case MSC_UNAUTHORIZED:
strncpy(message, "Unauthorized usage", sizeof(message));
break;
case MSC_OBJECT_NOT_FOUND:
strncpy(message, "Object not found", sizeof(message));
break;
case MSC_OBJECT_EXISTS:
strncpy(message, "Object already exists", sizeof(message));
break;
case MSC_INCORRECT_ALG:
strncpy(message, "Incorrect algorithm", sizeof(message));
break;
case MSC_SIGNATURE_INVALID:
strncpy(message, "Invalid signature", sizeof(message));
break;
case MSC_IDENTITY_BLOCKED:
strncpy(message, "Identity is blocked", sizeof(message));
break;
case MSC_UNSPECIFIED_ERROR:
strncpy(message, "Unspecified error", sizeof(message));
break;
case MSC_TRANSPORT_ERROR:
strncpy(message, "Transport error", sizeof(message));
break;
case MSC_INVALID_PARAMETER:
strncpy(message, "Invalid parameter", sizeof(message));
break;
case MSC_SEQUENCE_END:
strncpy(message, "End of sequence", sizeof(message));
break;
case MSC_INTERNAL_ERROR:
strncpy(message, "Internal Error", sizeof(message));
break;
case MSC_CANCELLED:
strncpy(message, "Operation Cancelled", sizeof(message));
break;
case MSC_INSUFFICIENT_BUFFER:
strncpy(message, "Buffer is too small", sizeof(message));
break;
case MSC_UNRECOGNIZED_TOKEN:
strncpy(message, "Token is unsupported", sizeof(message));
break;
case MSC_SERVICE_UNRESPONSIVE:
strncpy(message, "Service is not running", sizeof(message));
break;
case MSC_TIMEOUT_OCCURRED:
strncpy(message, "Timeout has occurred", sizeof(message));
break;
case MSC_TOKEN_REMOVED:
strncpy(message, "Token was removed", sizeof(message));
break;
case MSC_TOKEN_RESET:
strncpy(message, "Token was reset", sizeof(message));
break;
case MSC_TOKEN_INSERTED:
strncpy(message, "Token was inserted", sizeof(message));
break;
case MSC_TOKEN_UNRESPONSIVE:
strncpy(message, "Token is unresponsive", sizeof(message));
break;
case MSC_INVALID_HANDLE:
strncpy(message, "Handle is invalid", sizeof(message));
break;
case MSC_SHARING_VIOLATION:
strncpy(message, "Sharing violation", sizeof(message));
break;
default:
sprintf(message, "Unknown SW: %04lu", errorCode);
break;
}
return message;
}
MSC_RV MSCReEstablishConnection(MSCLPTokenConnection pConnection)
{
MSC_RV rv;
MSCPVoid32 vInitFunction, vFinFunction, vIdFunction;
MSCULong32 dwActiveProtocol;
MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection);
MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
MSCLong32 (*libPL_MSCIdentifyToken)(MSCLPTokenConnection);
vInitFunction = 0;
vFinFunction = 0;
vIdFunction = 0;
vInitFunction = pConnection->libPointers.pvfInitializePlugin;
vFinFunction = pConnection->libPointers.pvfFinalizePlugin;
vIdFunction = pConnection->libPointers.pvfIdentifyToken;
if (vInitFunction == 0)
{
DebugLogB("Error: Card service failure: %s\n",
"InitializePlugin function missing");
return MSC_INTERNAL_ERROR;
}
if (vFinFunction == 0)
{
DebugLogB("Error: Card service failure: %s\n",
"FinalizePlugin function missing");
return MSC_INTERNAL_ERROR;
}
if ( vIdFunction == 0 )
{
DebugLogB("Error: Card service failure: %s\n",
"IdentifyToken function missing");
return MSC_INTERNAL_ERROR;
}
libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
vInitFunction;
libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection))
vFinFunction;
libPL_MSCIdentifyToken = (MSCLong32 (*)(MSCLPTokenConnection))
vIdFunction;
rv = SCardReconnect(pConnection->hCard, pConnection->shareMode,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
SCARD_LEAVE_CARD, &dwActiveProtocol);
if (rv != SCARD_S_SUCCESS)
return pcscToMSC(rv);
rv = (*libPL_MSCFinalizePlugin) (pConnection);
rv = (*libPL_MSCInitializePlugin) (pConnection);
rv = (*libPL_MSCIdentifyToken)(pConnection);
if (rv != MSC_SUCCESS)
return rv;
return MSC_SUCCESS;
}
MSCUChar8 MSCIsTokenReset(MSCLPTokenConnection pConnection)
{
MSCULong32 rv;
char slotName[MAX_READERNAME];
MSCULong32 slotNameSize, slotState, slotProtocol;
MSCUChar8 tokenId[MAX_ATR_SIZE];
MSCULong32 tokenIdLength;
rv = SCardStatus(pConnection->hCard, slotName,
&slotNameSize, &slotState, &slotProtocol,
tokenId, &tokenIdLength);
if (rv == SCARD_W_RESET_CARD)
{
return 1;
}
if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_RESET)
{
return 1;
} else
{
return 0;
}
}
MSCUChar8 MSCClearReset(MSCLPTokenConnection pConnection)
{
pConnection->tokenInfo.tokenType &= ~MSC_TOKEN_TYPE_RESET;
return 1;
}
MSCUChar8 MSCIsTokenMoved(MSCLPTokenConnection pConnection)
{
MSCULong32 rv;
char slotName[MAX_READERNAME];
MSCULong32 slotNameSize, slotState, slotProtocol;
MSCUChar8 tokenId[MAX_ATR_SIZE];
MSCULong32 tokenIdLength;
rv = SCardStatus(pConnection->hCard, slotName,
&slotNameSize, &slotState, &slotProtocol,
tokenId, &tokenIdLength);
if (rv == SCARD_W_REMOVED_CARD)
{
return 1;
} else if (rv == SCARD_W_INSERTED_CARD)
{
return 1;
} else if (slotState & SCARD_ABSENT)
{
return 1;
}
if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_REMOVED)
{
return 1;
} else
{
return 0;
}
}
MSCUChar8 MSCIsTokenChanged(MSCLPTokenConnection pConnection)
{
if (MSCIsTokenMoved(pConnection))
{
return 1;
} else if (MSCIsTokenReset(pConnection))
{
return 1;
} else {
return 0;
}
}
MSCUChar8 MSCIsTokenKnown(MSCLPTokenConnection pConnection)
{
if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_KNOWN)
{
return 1;
} else
{
return 0;
}
}