--- trunk/OpenPGPminidriver/PublicDataOperations.c 2010/02/23 19:18:59 1 +++ trunk/OpenPGPminidriver/PublicDataOperations.c 2010/03/15 09:47:30 9 @@ -23,6 +23,7 @@ #include "SmartCard.h" #include "PublicDataOperations.h" #include "CryptoOperations.h" +#include "tlv.h" typedef enum _OPENPGP_FILE_TYPE { @@ -30,14 +31,19 @@ Virtual, } OPENPGP_FILE_TYPE; +#define OPENPGP_FILE_OPTIONAL 1 +#define OPENPGP_FILE_WRITE_ONLY 2 +#define OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING 4 + typedef struct _OPENPGP_FILE { PCHAR szDirectory; PCHAR szFile; OPENPGP_FILE_TYPE dwFileType; - BYTE bP1; - BYTE bP2; + DWORD dwTag; + DWORD dwTlv; CARD_FILE_ACCESS_CONDITION dwAccess; + DWORD dwFlag; } OPENPGP_FILE, *POPENPGP_FILE; @@ -45,30 +51,32 @@ OPENPGP_FILE Files[] = { - {szOpenPGPDir, szOpenPGPFingerprint, StoredOnSmartCard, 0x00, 0xC5, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPStatus, StoredOnSmartCard, 0x00, 0xC4, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPApplicationIdentifier, StoredOnSmartCard, 0x00, 0x4F, UnknownAc}, - {szOpenPGPDir, szOpenPGPLogin, StoredOnSmartCard, 0x00, 0x5E, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPName, StoredOnSmartCard, 0x00, 0x5B, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPLanguage, StoredOnSmartCard, 0x5F, 0x2D, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPSex, StoredOnSmartCard, 0x5F, 0x35, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPUrl, StoredOnSmartCard, 0x5F, 0x50, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPHistoricalBytes, StoredOnSmartCard, 0x5F, 0x52, UnknownAc}, - {szOpenPGPDir, szOpenPGPCertificate, StoredOnSmartCard, 0x7F, 0x21, EveryoneReadAdminWriteAc}, - {szOpenPGPDir, szOpenPGPExtendedCap, StoredOnSmartCard, 0x00, 0xC0, UnknownAc}, - {szOpenPGPDir, szOpenPGPAlgoAttributesSignature, StoredOnSmartCard, 0x00, 0xC1, UnknownAc}, - {szOpenPGPDir, szOpenPGPAlgoAttributesDecryption, StoredOnSmartCard, 0x00, 0xC2, UnknownAc}, - {szOpenPGPDir, szOpenPGPAlgoAttributesAuthentication, StoredOnSmartCard, 0x00, 0xC3, UnknownAc }, - {NULL, szCARD_IDENTIFIER_FILE, StoredOnSmartCard, 0x00, 0x4F, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPFingerprint, StoredOnSmartCard, 0x6E, 0xC5, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPStatus, StoredOnSmartCard, 0xC4, 0, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPApplicationIdentifier, StoredOnSmartCard, 0x4F, 0, UnknownAc}, + {szOpenPGPDir, szOpenPGPLogin, StoredOnSmartCard, 0x5E, 0, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPName, StoredOnSmartCard, 0x65, 0x5B, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPLanguage, StoredOnSmartCard, 0x65, 0x5F2D, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPSex, StoredOnSmartCard, 0x65, 0x5F35,EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPUrl, StoredOnSmartCard, 0x5F50, 0, EveryoneReadAdminWriteAc}, + {szOpenPGPDir, szOpenPGPHistoricalBytes, StoredOnSmartCard, 0x5F52, 0, UnknownAc}, + {szOpenPGPDir, szOpenPGPCertificate, StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING}, + {szOpenPGPDir, szOpenPGPExtendedCap, StoredOnSmartCard, 0x6E, 0xC0, UnknownAc}, + {szOpenPGPDir, szOpenPGPAlgoAttributesSignature, StoredOnSmartCard, 0x6E, 0xC1, UnknownAc}, + {szOpenPGPDir, szOpenPGPAlgoAttributesDecryption, StoredOnSmartCard, 0x6E, 0xC2,UnknownAc}, + {szOpenPGPDir, szOpenPGPAlgoAttributesAuthentication, StoredOnSmartCard, 0x6E, 0xC3, UnknownAc }, + {szOpenPGPDir, szOpenPGPPUK, StoredOnSmartCard, 0xD3, 0, UnknownAc, OPENPGP_FILE_WRITE_ONLY }, + {NULL, szCARD_IDENTIFIER_FILE, StoredOnSmartCard, 0x4F, 0, EveryoneReadAdminWriteAc}, {NULL, szCARD_APPLICATION_FILE, Virtual, 0, 0, EveryoneReadAdminWriteAc}, {NULL, szCACHE_FILE, Virtual, 0, 0, EveryoneReadUserWriteAc}, {szBASE_CSP_DIR, szCONTAINER_MAP_FILE, Virtual, 0, 0, EveryoneReadUserWriteAc}, + {szBASE_CSP_DIR, "ksc1", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING}, }; DWORD dwFileCount = ARRAYSIZE(Files); -DWORD SCardDirectoryList(__in PCARD_DATA pCardData, +DWORD OCardDirectoryList(__in PCARD_DATA pCardData, __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize) { // hardcoded @@ -82,10 +90,11 @@ return 0; } + // read file -DWORD SCardReadFile(__in PCARD_DATA pCardData, +DWORD OCardReadFile(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PSTR szFile, - __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize) + __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize) { DWORD dwI; DWORD dwReturn = 0; @@ -94,8 +103,10 @@ BYTE pbCmd[] = {0x00, 0xCA, 0x00, 0x00, 0x00}; DWORD dwCmdSize = ARRAYSIZE(pbCmd); POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; + PBYTE pbData = NULL; __try { + *pdwResponseSize = 0; for(dwI = 0; dwI < dwFileCount; dwI++) { BOOL fMatch = FALSE; @@ -105,12 +116,12 @@ } else { - if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; } if (fMatch) { fDirectoryFound = TRUE; - if (strcmp(szFile, Files[dwI].szFile) == 0) + if (_stricmp(szFile, Files[dwI].szFile) == 0) { fFileFound = TRUE; break; @@ -133,23 +144,53 @@ } if (Files[dwI].dwFileType == StoredOnSmartCard) { - pbCmd[2] = Files[dwI].bP1; - pbCmd[3] = Files[dwI].bP2; - dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, pbResponse, pdwResponseSize); + pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100); + pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100); + dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, pdwResponseSize); + if (dwReturn) + { + __leave; + } + if (Files[dwI].dwTlv) + { + PBYTE pbPointer; + //TraceDump(0,pbData,*pdwResponseSize); + if (find_tlv(pbData, Files[dwI].dwTlv, *pdwResponseSize, &pbPointer, pdwResponseSize)) + { + *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize); + if (!*ppbResponse ) + { + Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY"); + dwReturn = SCARD_E_NO_MEMORY; + } + memcpy(*ppbResponse, pbPointer, *pdwResponseSize); + } + else + { + dwReturn = SCARD_E_FILE_NOT_FOUND; + Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile); + } + } + else + { + *ppbResponse = pbData; + // do not free the data ! + pbData = NULL; + } } else { if (szDirectory == NULL) { - if (strcmp(szFile, szCARD_APPLICATION_FILE) == 0) + if (_stricmp(szFile, szCARD_APPLICATION_FILE) == 0) { - dwReturn = SCardDirectoryList(pCardData, pbResponse, pdwResponseSize); + dwReturn = OCardDirectoryList(pCardData, ppbResponse, pdwResponseSize); } - else if (strcmp(szFile, szCACHE_FILE) == 0) + else if (_stricmp(szFile, szCACHE_FILE) == 0) { *pdwResponseSize = sizeof(CARD_CACHE_FILE_FORMAT); - *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize); - memset(*pbResponse,0,*pdwResponseSize); + *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize); + memset(*ppbResponse,0,*pdwResponseSize); } else { @@ -157,45 +198,11 @@ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile); } } - else if (strcmp(szDirectory,szBASE_CSP_DIR) == 0) + else if (_stricmp(szDirectory,szBASE_CSP_DIR) == 0) { - if (strcmp(szFile, szCONTAINER_MAP_FILE) == 0) + if (_stricmp(szFile, szCONTAINER_MAP_FILE) == 0) { - PCONTAINER_MAP_RECORD pContainer = NULL; - *pdwResponseSize = sizeof(CONTAINER_MAP_RECORD) * MaxContainer; - *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize); - if (! *pbResponse ) - { - dwReturn = SCARD_E_NO_MEMORY; - Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY"); - __leave; - } - pContainer = (PCONTAINER_MAP_RECORD) *pbResponse; - memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * 3); - swprintf_s(pContainer[Signature].wszGuid,MAX_CONTAINER_NAME_LEN + 1, - L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Signature", - pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1], - pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1], - pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1], - pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]); - pContainer[Signature].bFlags = CONTAINER_MAP_VALID_CONTAINER; - pContainer[Signature].wSigKeySizeBits = 1024; - swprintf_s(pContainer[Authentication].wszGuid,MAX_CONTAINER_NAME_LEN + 1, - L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Authenticate", - pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1], - pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1], - pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1], - pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]); - pContainer[Authentication].bFlags = CONTAINER_MAP_VALID_CONTAINER | CONTAINER_MAP_DEFAULT_CONTAINER; - pContainer[Authentication].wSigKeySizeBits = 1024; - swprintf_s(pContainer[Confidentiality].wszGuid,MAX_CONTAINER_NAME_LEN + 1, - L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Confidential", - pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1], - pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1], - pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1], - pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]); - pContainer[Confidentiality].bFlags = CONTAINER_MAP_VALID_CONTAINER; - pContainer[Confidentiality].wKeyExchangeKeySizeBits = 1024; + dwReturn = OCardReadContainerMapFile(pCardData, ppbResponse, pdwResponseSize); } else { @@ -219,23 +226,28 @@ } __finally { + if( pbData) + pCardData->pfnCspFree(pbData); } - Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X",szDirectory, szFile, dwReturn); + Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X size = %d",szDirectory, szFile, dwReturn, *pdwResponseSize); return dwReturn; } -DWORD SCardEnumFile(__in PCARD_DATA pCardData, +DWORD OCardEnumFile(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PBYTE* pbResponse, __in PDWORD pdwResponseSize) { - DWORD dwReturn = 0, dwNotExists; + DWORD dwReturn = 0, dwReadFileReturn; DWORD dwI, dwSize; BOOL fDirectoryFound = FALSE; - + BOOL fAddToOuput; __try { *pbResponse = NULL; *pdwResponseSize = 0; + + // compute the max size of the buffer + dwSize = 0; for(dwI = 0; dwI < dwFileCount; dwI++) { BOOL fMatch = FALSE; @@ -245,40 +257,58 @@ } else { - if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + } + if (fMatch && !(Files[dwI].dwFileType & OPENPGP_FILE_WRITE_ONLY)) + { + dwSize += (DWORD) strlen( Files[dwI].szFile) + 1; + } + } + dwSize += 1; + *pbResponse = pCardData->pfnCspAlloc(dwSize); + if (!*pbResponse) + { + dwReturn = SCARD_E_NO_MEMORY; + __leave; + } + for(dwI = 0; dwI < dwFileCount; dwI++) + { + BOOL fMatch = FALSE; + if (szDirectory == NULL) + { + if (!Files[dwI].szDirectory) fMatch = TRUE; + } + else + { + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; } if (fMatch) { fDirectoryFound = TRUE; - dwNotExists = 0; - if (StoredOnSmartCard == Files[dwI].dwFileType) + fAddToOuput = TRUE; + if (Files[dwI].dwFlag & OPENPGP_FILE_WRITE_ONLY) + { + fAddToOuput = FALSE; + } + if (fAddToOuput && (Files[dwI].dwFlag & OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING)) { PBYTE pbData = NULL; DWORD dwSize; + fAddToOuput = FALSE; // check if the file exists and be read - dwNotExists = SCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize); - if (!dwNotExists) + dwReadFileReturn = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize); + if (!dwReadFileReturn) { pCardData->pfnCspFree(pbData); + if (dwSize > 0) + { + fAddToOuput = TRUE; + } } } - if (!dwNotExists) + if (fAddToOuput) { dwSize = (DWORD) strlen( Files[dwI].szFile) + 1; - // + 1 to add the final \0 - if (*pbResponse) - { - *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, *pdwResponseSize + dwSize + 1); - } - else - { - *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize + dwSize + 1); - } - if (!*pbResponse) - { - dwReturn = SCARD_E_NO_MEMORY; - __leave; - } memcpy(*pbResponse + *pdwResponseSize, Files[dwI].szFile, dwSize); *pdwResponseSize += dwSize; } @@ -301,7 +331,7 @@ } // read file -DWORD SCardGetFileInfo(__in PCARD_DATA pCardData, +DWORD OCardGetFileInfo(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PSTR szFile, __inout PCARD_FILE_INFO pCardFileInfo) { @@ -310,7 +340,7 @@ DWORD dwSize, dwI; __try { - dwReturn = SCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize); + dwReturn = OCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize); if (dwReturn) { __leave; @@ -320,10 +350,18 @@ pCardFileInfo->AccessCondition = InvalidAc; for(dwI = 0; dwI < dwFileCount; dwI++) { - if ((strcmp(szDirectory, Files[dwI].szDirectory) == 0) - || (!szDirectory && !Files[dwI].szDirectory) ) + BOOL fMatch = FALSE; + if (szDirectory == NULL) { - if (strcmp(szFile, Files[dwI].szFile) == 0) + if (!Files[dwI].szDirectory) fMatch = TRUE; + } + else + { + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + } + if (fMatch) + { + if (_stricmp(szFile, Files[dwI].szFile) == 0) { pCardFileInfo->AccessCondition = Files[dwI].dwAccess; break; @@ -339,7 +377,7 @@ return dwReturn; } -DWORD SCardWriteFile(__in PCARD_DATA pCardData, +DWORD OCardWriteFile(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PSTR szFile, __in PBYTE pbData, __in DWORD dwSize) { @@ -368,12 +406,12 @@ } else { - if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; } if (fMatch) { fDirectoryFound = TRUE; - if (strcmp(szFile, Files[dwI].szFile) == 0) + if (_stricmp(szFile, Files[dwI].szFile) == 0) { fFileFound = TRUE; break; @@ -396,21 +434,23 @@ } if (Files[dwI].dwFileType == StoredOnSmartCard) { - // fail because the PUT DO doesn't work => too much data - if (Files[dwI].bP1 != 0) + if (Files[dwI].dwTlv > 0) { - dwReturn = SCARD_E_WRITE_TOO_MANY ; - Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_WRITE_TOO_MANY %S",szFile); - __leave; + pbCmd[2] = (BYTE) (Files[dwI].dwTlv / 0x100); + pbCmd[3] = (BYTE) (Files[dwI].dwTlv % 0x100); + } + else + { + pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100); + pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100); } - pbCmd[3] = Files[dwI].bP2; pbCmd[4] = (BYTE) dwSize; if (dwSize) { memcpy(pbCmd + 5, pbData, dwSize); } dwCmdSize = dwSize + 5; - dwReturn = SCardSendCommand(pCardData, pbCmd, dwCmdSize); + dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize); if (dwReturn) { __leave; @@ -432,14 +472,14 @@ return dwReturn; } -DWORD SCardDeleteFile(__in PCARD_DATA pCardData, +DWORD OCardDeleteFile(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PSTR szFile) { - return SCardWriteFile(pCardData, szDirectory, szFile, NULL, 0); + return OCardWriteFile(pCardData, szDirectory, szFile, NULL, 0); } // just change the flag in Files -DWORD SCardCreateFile(__in PCARD_DATA pCardData, +DWORD OCardCreateFile(__in PCARD_DATA pCardData, __in_opt PSTR szDirectory, __in PSTR szFile) { DWORD dwI; @@ -457,12 +497,12 @@ } else { - if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; + if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE; } if (fMatch) { fDirectoryFound = TRUE; - if (strcmp(szFile, Files[dwI].szFile) == 0) + if (_stricmp(szFile, Files[dwI].szFile) == 0) { fFileFound = TRUE; break;