diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2023-06-29 00:06:20 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2023-06-29 00:06:20 +0200 |
commit | 034b64f4153550cbe5849bcbfc27e187377cc512 (patch) | |
tree | d831496163c3891031765010bf1934406b0c4a3c /src/Common/SCardLoader.cpp | |
parent | 502ab9112a7624dbd7c1c90c2e12ed45512b8b3c (diff) | |
download | VeraCrypt-034b64f4153550cbe5849bcbfc27e187377cc512.tar.gz VeraCrypt-034b64f4153550cbe5849bcbfc27e187377cc512.zip |
EMV keyfile support: Overall code improvements and bug fixes
Diffstat (limited to 'src/Common/SCardLoader.cpp')
-rw-r--r-- | src/Common/SCardLoader.cpp | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/src/Common/SCardLoader.cpp b/src/Common/SCardLoader.cpp new file mode 100644 index 00000000..ff3c9100 --- /dev/null +++ b/src/Common/SCardLoader.cpp @@ -0,0 +1,402 @@ +#include "SCardLoader.h" +#include "PCSCException.h" + +#ifndef TC_WINDOWS +#include <dlfcn.h> +#define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_LOCAL) +#define FreeLibrary(x) dlclose(x) +#define GetProcAddress(x, y) dlsym(x, y) +typedef void* HMODULE; +#ifdef TC_MACOSX +#if !defined(USE_SCARD_CONTROL_112) +#define SCardControlName "SCardControl132" +#else +#define SCardControlName "SCardControl" +#endif +#else +#define SCardControlName "SCardControl" +#endif +#define SCardConnectName "SCardConnect" +#define SCardStatusName "SCardStatus" +#define SCardGetStatusChangeName "SCardGetStatusChange" +#define SCardListReaderGroupsName "SCardListReaderGroups" +#define SCardListReadersName "SCardListReaders" +#else +#define SCardControlName "SCardControl" +#define SCardConnectName "SCardConnectW" +#define SCardStatusName "SCardStatusW" +#define SCardGetStatusChangeName "SCardGetStatusChangeW" +#define SCardListReaderGroupsName "SCardListReaderGroupsW" +#define SCardListReadersName "SCardListReadersW" +#endif + +using namespace std; + +namespace VeraCrypt +{ + HMODULE SCardLoader::hScardModule = NULL; + SCARDCONTEXT SCardLoader::hScardContext = 0; + SCardEstablishContextPtr SCardLoader::scardEstablishContext = NULL; + SCardReleaseContextPtr SCardLoader::scardReleaseContext = NULL; + SCardIsValidContextPtr SCardLoader::scardIsValidContext = NULL; +#ifndef TC_MACOSX + SCardFreeMemoryPtr SCardLoader::scardFreeMemory = NULL; +#endif + SCardConnectPtr SCardLoader::scardConnect = NULL; + SCardReconnectPtr SCardLoader::scardReconnect = NULL; + SCardDisconnectPtr SCardLoader::scardDisconnect = NULL; + SCardBeginTransactionPtr SCardLoader::scardBeginTransaction = NULL; + SCardEndTransactionPtr SCardLoader::scardEndTransaction = NULL; + SCardStatusPtr SCardLoader::scardStatus = NULL; + SCardGetStatusChangePtr SCardLoader::scardGetStatusChange = NULL; + SCardControlPtr SCardLoader::scardControl = NULL; + SCardTransmitPtr SCardLoader::scardTransmit = NULL; + SCardListReaderGroupsPtr SCardLoader::scardListReaderGroups = NULL; + SCardListReadersPtr SCardLoader::scardListReaders = NULL; + SCardCancelPtr SCardLoader::scardCancel = NULL; + SCardGetAttribPtr SCardLoader::scardGetAttrib = NULL; + SCardSetAttribPtr SCardLoader::scardSetAttrib = NULL; + SCARD_IO_REQUEST* SCardLoader::scardT0Pci = NULL; + SCARD_IO_REQUEST* SCardLoader::scardT1Pci = NULL; + SCARD_IO_REQUEST* SCardLoader::scardRawPci = NULL; + bool SCardLoader::bInitialized = false; + +#ifdef TC_WINDOWS + wstring SCardLoader::GetSCardPath() +#else + string SCardLoader::GetSCardPath() +#endif + { +#ifdef TC_WINDOWS + wchar_t winscardPath[TC_MAX_PATH]; + if (GetSystemDirectory(winscardPath, TC_MAX_PATH)) + { + StringCbCat(winscardPath, sizeof(winscardPath), L"\\Winscard.dll"); + } + else + StringCbCopy(winscardPath, sizeof(winscardPath), L"C:\\Windows\\System32\\Winscard.dll"); + return winscardPath; +#elif TC_MACOSX + return "/System/Library/Frameworks/PCSC.framework/PCSC"; +#else + string pcscPath = ""; + FILE* pipe = +#ifdef TC_LINUX + popen("ldconfig -p", "r"); +#else + popen("ldconfig -r", "r"); // FreeBSD +#endif + if (pipe) + { + char buffer[128]; + while (!feof(pipe)) + { + if (fgets(buffer, 128, pipe) != NULL) + { + string line(buffer); + if (line.find("libpcsclite.so") != string::npos) + { + size_t pos = line.find("=>"); + if (pos != string::npos) + { + pcscPath = line.substr(pos + 3); + pos = pcscPath.find_first_of(" \t\r\n"); + if (pos != string::npos) + pcscPath = pcscPath.substr(0, pos); + break; + } + } + } + } + pclose(pipe); + } + + if (pcscPath == "") + { + pcscPath = "libpcsclite.so"; + } + + return pcscPath; +#endif + } + + void SCardLoader::Initialize() + { + if (bInitialized) + return; + + hScardModule = LoadLibrary(GetSCardPath().c_str()); + if (hScardModule) + { + scardEstablishContext = (SCardEstablishContextPtr)GetProcAddress(hScardModule, "SCardEstablishContext"); + scardReleaseContext = (SCardReleaseContextPtr)GetProcAddress(hScardModule, "SCardReleaseContext"); + scardIsValidContext = (SCardIsValidContextPtr)GetProcAddress(hScardModule, "SCardIsValidContext"); +#ifndef TC_MACOSX + scardFreeMemory = (SCardFreeMemoryPtr)GetProcAddress(hScardModule, "SCardFreeMemory"); +#endif + scardConnect = (SCardConnectPtr)GetProcAddress(hScardModule, SCardConnectName); + scardReconnect = (SCardReconnectPtr)GetProcAddress(hScardModule, "SCardReconnect"); + scardDisconnect = (SCardDisconnectPtr)GetProcAddress(hScardModule, "SCardDisconnect"); + scardBeginTransaction = (SCardBeginTransactionPtr)GetProcAddress(hScardModule, "SCardBeginTransaction"); + scardEndTransaction = (SCardEndTransactionPtr)GetProcAddress(hScardModule, "SCardEndTransaction"); + scardStatus = (SCardStatusPtr)GetProcAddress(hScardModule, SCardStatusName); + scardGetStatusChange = (SCardGetStatusChangePtr)GetProcAddress(hScardModule, SCardGetStatusChangeName); + scardControl = (SCardControlPtr)GetProcAddress(hScardModule, SCardControlName); + scardTransmit = (SCardTransmitPtr)GetProcAddress(hScardModule, "SCardTransmit"); + scardListReaderGroups = (SCardListReaderGroupsPtr)GetProcAddress(hScardModule, SCardListReaderGroupsName); + scardListReaders = (SCardListReadersPtr)GetProcAddress(hScardModule, SCardListReadersName); + scardCancel = (SCardCancelPtr)GetProcAddress(hScardModule, "SCardCancel"); + scardGetAttrib = (SCardGetAttribPtr)GetProcAddress(hScardModule, "SCardGetAttrib"); + scardSetAttrib = (SCardSetAttribPtr)GetProcAddress(hScardModule, "SCardSetAttrib"); + scardT0Pci = (SCARD_IO_REQUEST*)GetProcAddress(hScardModule, "g_rgSCardT0Pci"); + scardT1Pci = (SCARD_IO_REQUEST*)GetProcAddress(hScardModule, "g_rgSCardT1Pci"); + scardRawPci = (SCARD_IO_REQUEST*)GetProcAddress(hScardModule, "g_rgSCardRawPci"); + if ( +#ifndef TC_MACOSX + scardFreeMemory && +#endif + scardEstablishContext && scardReleaseContext && scardIsValidContext && scardConnect && scardReconnect && scardDisconnect && + scardBeginTransaction && scardEndTransaction && scardStatus && scardGetStatusChange && scardControl && scardTransmit && + scardListReaderGroups && scardListReaders && scardCancel && scardGetAttrib && scardSetAttrib && scardT0Pci && scardT1Pci && scardRawPci) + { + if (SCARD_S_SUCCESS == scardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hScardContext)) + { + bInitialized = true; + } + } + } + + if (!bInitialized) + { + Finalize(); + } + } + + void SCardLoader::Finalize() + { + if (hScardContext) + { + scardReleaseContext(hScardContext); + hScardContext = 0; + } + + if (hScardModule) + { + FreeLibrary(hScardModule); + hScardModule = NULL; + } + + scardEstablishContext = NULL; + scardReleaseContext = NULL; + scardIsValidContext = NULL; +#ifndef TC_MACOSX + scardFreeMemory = NULL; +#endif + scardConnect = NULL; + scardReconnect = NULL; + scardDisconnect = NULL; + scardBeginTransaction = NULL; + scardEndTransaction = NULL; + scardStatus = NULL; + scardGetStatusChange = NULL; + scardControl = NULL; + scardTransmit = NULL; + scardListReaderGroups = NULL; + scardListReaders = NULL; + scardCancel = NULL; + scardGetAttrib = NULL; + scardSetAttrib = NULL; + scardT0Pci = NULL; + scardT1Pci = NULL; + scardRawPci = NULL; + + bInitialized = false; + } + + SCARDCONTEXT SCardLoader::GetSCardContext() + { + return hScardContext; + } + + LONG SCardLoader::SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext); + } + + LONG SCardLoader::SCardReleaseContext(SCARDCONTEXT hContext) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardReleaseContext(hContext); + } + + LONG SCardLoader::SCardIsValidContext(SCARDCONTEXT hContext) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardIsValidContext(hContext); + } + +#ifndef TC_MACOSX + LONG SCardLoader::SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardFreeMemory(hContext, pvMem); + } +#endif + + LONG SCardLoader::SCardConnect(SCARDCONTEXT hContext, LPCTSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardConnect(hContext, szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); + } + + LONG SCardLoader::SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardReconnect(hCard, dwShareMode, dwPreferredProtocols, dwInitialization, pdwActiveProtocol); + } + + LONG SCardLoader::SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardDisconnect(hCard, dwDisposition); + } + + LONG SCardLoader::SCardBeginTransaction(SCARDHANDLE hCard) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardBeginTransaction(hCard); + } + + LONG SCardLoader::SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardEndTransaction(hCard, dwDisposition); + } + + LONG SCardLoader::SCardStatus(SCARDHANDLE hCard, LPTSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, BYTE* pbAtr, LPDWORD pcbAtrLen) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardStatus(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); + } + + LONG SCardLoader::SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardGetStatusChange(hContext, dwTimeout, rgReaderStates, cReaders); + } + + LONG SCardLoader::SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned); + } + + LONG SCardLoader::SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, const BYTE* pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, BYTE* pbRecvBuffer, LPDWORD pcbRecvLength) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, pioRecvPci, pbRecvBuffer, pcbRecvLength); + } + + LONG SCardLoader::SCardListReaderGroups(SCARDCONTEXT hContext, LPTSTR mszGroups, LPDWORD pcchGroups) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardListReaderGroups(hContext, mszGroups, pcchGroups); + } + + LONG SCardLoader::SCardListReaders(SCARDCONTEXT hContext, LPCTSTR mszGroups, LPTSTR mszReaders, LPDWORD pcchReaders) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardListReaders(hContext, mszGroups, mszReaders, pcchReaders); + } + + LONG SCardLoader::SCardCancel(SCARDCONTEXT hContext) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardCancel(hContext); + } + + LONG SCardLoader::SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, BYTE* pbAttr, LPDWORD pcbAttrLen) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen); + } + + LONG SCardLoader::SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, const BYTE* pbAttr, DWORD cbAttrLen) + { + Initialize(); + + if (!bInitialized) + throw ScardLibraryInitializationFailed(); + + return scardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen); + } +}
\ No newline at end of file |