[Openpgpmdrv-commits] r10 - in trunk: OpenPGPminidriver OpenPGPminidriverTest
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Mar 15 19:23:21 CET 2010
Author: vletoux
Date: 2010-03-15 19:23:17 +0100 (Mon, 15 Mar 2010)
New Revision: 10
Modified:
trunk/OpenPGPminidriver/CardAndContainerProperties.c
trunk/OpenPGPminidriver/CardCryptographicOperations.c
trunk/OpenPGPminidriver/Context.h
trunk/OpenPGPminidriver/ContextManagement.c
trunk/OpenPGPminidriver/CryptoOperations.c
trunk/OpenPGPminidriver/CryptoOperations.h
trunk/OpenPGPminidriver/PinOperations.c
trunk/OpenPGPminidriver/PublicDataOperations.c
trunk/OpenPGPminidriverTest/CryptoOperations.cpp
trunk/OpenPGPminidriverTest/Dialog.h
trunk/OpenPGPminidriverTest/Dialog.rc
trunk/OpenPGPminidriverTest/PINOperations.cpp
trunk/OpenPGPminidriverTest/global.h
trunk/OpenPGPminidriverTest/main.cpp
Log:
first beta version
Modified: trunk/OpenPGPminidriver/CardAndContainerProperties.c
===================================================================
--- trunk/OpenPGPminidriver/CardAndContainerProperties.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/CardAndContainerProperties.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -629,6 +629,7 @@
)
{
DWORD dwReturn = 0;
+ POPENPGP_CONTEXT pContext = NULL;
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter wszProperty = %s", wszProperty);
__try
{
@@ -644,6 +645,12 @@
dwReturn = SCARD_E_INVALID_PARAMETER;
__leave;
}
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
if (wcscmp(wszProperty,CP_CARD_FREE_SPACE) == 0
|| wcscmp(wszProperty,CP_CARD_CAPABILITIES) == 0
|| wcscmp(wszProperty,CP_CARD_KEYSIZES) == 0
@@ -707,7 +714,21 @@
dwReturn = SCARD_E_INVALID_PARAMETER;
__leave;
}
- dwReturn = SCARD_W_SECURITY_VIOLATION;
+ if ( cbDataLen != sizeof(BOOL) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbDataLen == %d", cbDataLen);
+ dwReturn = SCARD_E_INVALID_PARAMETER ;
+ __leave;
+ }
+ if (pContext->fDoesTheAdminHasBeenAuthenticatedAtLeastOnce)
+ {
+ pContext->fIsReadOnly = *((PBOOL) pbData);
+ dwReturn = 0;
+ }
+ else
+ {
+ dwReturn = SCARD_W_SECURITY_VIOLATION;
+ }
}
else if (wcscmp(wszProperty,CP_PARENT_WINDOW) == 0)
{
@@ -729,7 +750,7 @@
dwReturn = SCARD_E_INVALID_PARAMETER ;
__leave;
}
- if ( *pbData != 0)
+ if ( *((HWND*)pbData) != 0)
{
if (IsWindow( *((HWND*)pbData)) == 0)
{
Modified: trunk/OpenPGPminidriver/CardCryptographicOperations.c
===================================================================
--- trunk/OpenPGPminidriver/CardCryptographicOperations.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/CardCryptographicOperations.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -136,14 +136,8 @@
dwReturn = SCARD_E_INVALID_PARAMETER;
__leave;
}
- if (pInfo->dwKeySpec == AT_KEYEXCHANGE)
+ if (pInfo->dwKeySpec != AT_SIGNATURE && pInfo->dwKeySpec != AT_KEYEXCHANGE)
{
- Trace(WINEVENT_LEVEL_ERROR, L"AT_KEYEXCHANGE %d", pInfo->dwKeySpec);
- dwReturn = SCARD_E_NO_KEY_CONTAINER ;
- __leave;
- }
- if (pInfo->dwKeySpec != AT_SIGNATURE)
- {
Trace(WINEVENT_LEVEL_ERROR, L"AT_SIGNATURE %d", pInfo->dwKeySpec);
dwReturn = SCARD_E_INVALID_PARAMETER ;
__leave;
@@ -156,6 +150,7 @@
switch(pInfo->bContainerIndex)
{
case ContainerAuthentication:
+ case ContainerConfidentiality:
dwReturn = OCardAuthenticate(pCardData, pInfo);
break;
case ContainerSignature:
Modified: trunk/OpenPGPminidriver/Context.h
===================================================================
--- trunk/OpenPGPminidriver/Context.h 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/Context.h 2010-03-15 18:23:17 UTC (rev 10)
@@ -65,8 +65,11 @@
BOOL fHasKey[KEYMAX];
BOOL fIsReadOnly;
BYTE bFingerPrint[60];
- PBYTE pbKeyCache[KEYMAX];
- DWORD dwKeyCacheSize[KEYMAX];
+ PBYTE pbModulusInLittleEndian[KEYMAX];
+ WORD dwModulusSizeInBytes[KEYMAX];
+ DWORD dwExponent[KEYMAX];
+ LARGE_INTEGER LastCacheCheck[KEYMAX];
+ BOOL fDoesTheAdminHasBeenAuthenticatedAtLeastOnce;
} OPENPGP_CONTEXT, *POPENPGP_CONTEXT ;
DWORD CreateContext(__in PCARD_DATA pCardData, __in DWORD dwFlags);
Modified: trunk/OpenPGPminidriver/ContextManagement.c
===================================================================
--- trunk/OpenPGPminidriver/ContextManagement.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/ContextManagement.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -197,13 +197,22 @@
DWORD CleanContext(__in PCARD_DATA pCardData)
{
- DWORD dwReturn = 0;
+ DWORD dwReturn = 0, dwI;
__try
{
if (pCardData)
{
if ( pCardData->pvVendorSpecific)
{
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ for(dwI = 0; dwI < KeyMax; dwI++)
+ {
+ if (pContext->pbModulusInLittleEndian[dwI] != NULL)
+ {
+ pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwI]);
+ pContext->pbModulusInLittleEndian[dwI] = NULL;
+ }
+ }
pCardData->pfnCspFree( pCardData->pvVendorSpecific);
pCardData->pvVendorSpecific = NULL;
}
@@ -362,11 +371,11 @@
}
}
}
- dwReturn = CCIDgetFeatures(pCardData);
+ /*dwReturn = CCIDgetFeatures(pCardData);
if (dwReturn)
{
__leave;
- }
+ }*/
dwReturn = 0;
}
__finally
Modified: trunk/OpenPGPminidriver/CryptoOperations.c
===================================================================
--- trunk/OpenPGPminidriver/CryptoOperations.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/CryptoOperations.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -29,15 +29,15 @@
OPENPGP_KEY_INFO Keys[] =
{
{0xB6, 0xCE, 0xC7, CALG_RSA_SIGN}, // signature
- {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN}, // authentication
- {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX} // confidentiality
+ {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX}, // confidentiality
+ {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN} // authentication
};
OPENPGP_CONTAINER_INFO Containers[] =
{
{ROLE_SIGNATURE, AT_SIGNATURE},
- {ROLE_AUTHENTICATION, AT_SIGNATURE},
- {ROLE_CONFIDENTIALITY, AT_KEYEXCHANGE}
+ {ROLE_CONFIDENTIALITY, AT_KEYEXCHANGE},
+ {ROLE_AUTHENTICATION, AT_SIGNATURE}
};
typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
{
@@ -57,6 +57,7 @@
BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
+#define OPENPGP_NO_OID 0xFFFFFFFF
OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
{
{CALG_SHA1,20,
@@ -103,10 +104,10 @@
szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
break;
case KeyAuthentication:
- szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
break;
case KeyConfidentiality:
- szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
break;
default:
dwReturn = SCARD_E_NO_KEY_CONTAINER;
@@ -159,10 +160,10 @@
szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
break;
case KeyAuthentication:
- szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
break;
case KeyConfidentiality:
- szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
break;
default:
dwReturn = SCARD_E_NO_KEY_CONTAINER;
@@ -185,7 +186,7 @@
__finally
{
}
- Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
return dwReturn;
}
@@ -370,56 +371,63 @@
__finally
{
}
- Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d", dwReturn, dwKey);
return dwReturn;
}
-DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
+DWORD CreateGenerationDateTime(__in PCARD_DATA pCardData,
__out PDWORD pdwSecondsSince1970)
{
- DWORD dwReturn = 0;
LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;
SYSTEMTIME WindowsSystemTime;
FILETIME WindowsFileTime;
+ UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
+ GetSystemTime(&WindowsSystemTime);
+ SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
+ /* It is not recommended that you add and subtract values from the FILETIME
+ structure to obtain relative times. Instead, you should copy the low- and high-order
+ parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic
+ on the QuadPart member, and copy the LowPart and HighPart members into the
+ FILETIME structure.
+
+ Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
+ or __int64* value because it can cause alignment faults on 64-bit Windows.
+ */
+ WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
+ WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
+ *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
+ return 0;
+}
+
+
+DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
+ __out DWORD dwSecondsSince1970)
+{
+ DWORD dwReturn = 0;
+
BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
DWORD dwCommandSize = ARRAYSIZE(pbCommand);
__try
{
- UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
- GetSystemTime(&WindowsSystemTime);
- SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
- /* It is not recommended that you add and subtract values from the FILETIME
- structure to obtain relative times. Instead, you should copy the low- and high-order
- parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic
- on the QuadPart member, and copy the LowPart and HighPart members into the
- FILETIME structure.
-
- Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
- or __int64* value because it can cause alignment faults on 64-bit Windows.
- */
- WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
- WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
- *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
+
pbCommand[3] = Keys[dwKey].bDateTimeTag;
- pbCommand[5] = (BYTE) (*pdwSecondsSince1970 / 0x1000000);
- pbCommand[6] = (BYTE) ((*pdwSecondsSince1970 % 0x1000000) / 0x10000);
- pbCommand[7] = (BYTE) ((*pdwSecondsSince1970 % 0x10000) / 0x100);
- pbCommand[8] = (BYTE) ((*pdwSecondsSince1970 % 0x100) / 0x1);
+ pbCommand[5] = (BYTE) (dwSecondsSince1970 / 0x1000000);
+ pbCommand[6] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
+ pbCommand[7] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
+ pbCommand[8] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
}
__finally
{
}
- Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
return dwReturn;
}
-DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
+DWORD CreateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
__in DWORD dwSecondsSince1970,
- __in PBYTE pbModulus, __in DWORD dwModulusSizeInBit,
- __in BOOL fIsModulusInBigEndian,
- __in DWORD dwExponent)
+ __inout BYTE pbFingerPrint[20])
{
// modulus in input are in big endian
// rfc4880 12.2
@@ -429,12 +437,15 @@
DWORD dwOffset = 0;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
- BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
- DWORD dwCommandSize = ARRAYSIZE(pbCommand);
- DWORD dwHashLen = 0x14;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ DWORD dwHashLen = 0x14, dwModulusSizeInBytes, dwModulusSizeInBit, dwExponent;
+ DWORD dwI;
__try
{
- dwBufferSize = dwModulusSizeInBit / 8 + sizeof(DWORD) + 10 + 3;
+ dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
+ dwModulusSizeInBit = dwModulusSizeInBytes * 8;
+ dwExponent = pContext->dwExponent[dwKey];
+ dwBufferSize = dwModulusSizeInBytes + sizeof(DWORD) + 10 + 3;
pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
if (!pbBuffer)
{
@@ -442,6 +453,7 @@
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
__leave;
}
+
pbBuffer[dwOffset++] = 0x99;
// -3 because of the header size
pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
@@ -459,18 +471,11 @@
// size of modulus
pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
- if (fIsModulusInBigEndian)
+ // little endian => big endian
+ for(dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
{
- memcpy(pbBuffer + dwOffset, pbModulus, dwModulusSizeInBit / 8);
+ pbBuffer[dwOffset + dwI] = pContext->pbModulusInLittleEndian[dwKey][dwModulusSizeInBytes - 1 - dwI];
}
- else
- {
- DWORD dwI;
- for(dwI = 0; dwI < dwModulusSizeInBit / 8; dwI++)
- {
- pbBuffer[dwOffset + dwI] = pbModulus[dwModulusSizeInBit / 8 - 1 - dwI];
- }
- }
// size of exponent
pbBuffer[dwOffset++] = 0;
pbBuffer[dwOffset++] = sizeof(DWORD);
@@ -499,13 +504,12 @@
Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
__leave;
}
- if(!CryptGetHashParam(hHash, HP_HASHVAL, pbCommand + 5, &dwHashLen, 0)) {
+ if(!CryptGetHashParam(hHash, HP_HASHVAL, pbFingerPrint, &dwHashLen, 0)) {
dwReturn = GetLastError();
Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
__leave;
}
- pbCommand[3] = Keys[dwKey].bSignatureTag;
- dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
+
}
__finally
@@ -518,16 +522,32 @@
CryptReleaseContext(hProv,0);
}
- Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
return dwReturn;
}
-DWORD OCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
+DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
+ __inout BYTE pbFingerPrint[20])
{
- DWORD dwReturn;
+ BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
+ DWORD dwCommandSize = ARRAYSIZE(pbCommand), dwReturn;
+ __try
+ {
+ pbCommand[3] = Keys[dwKey].bSignatureTag;
+ memcpy(pbCommand + 5, pbFingerPrint, 20);
+ dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
+ return dwReturn;
+}
+DWORD OCardUpdateCachedPublicKey(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
+{
PBYTE pbData = NULL;
- DWORD dwResponseSize = 0;
+ DWORD dwResponseSize = 0, dwReturn;
BYTE pbCmd[] = {0x00,
0x47,
0x81,
@@ -541,12 +561,12 @@
0x00
};
DWORD dwCmdSize;
- POPENPGP_CONTEXT pContext;
+ DWORD dwTotalTlvSize, dwOffset;
+ DWORD dwModulusSizeInBytes;
PBYTE pbModulus;
- DWORD dwModulusSize, dwI;
+ DWORD dwI;
PBYTE pbExponent;
- PRSAPUBLICKEYBLOB pbBlob = NULL;
- DWORD dwTotalTlvSize, dwOffset;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
@@ -556,7 +576,11 @@
Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
__leave;
}
- pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ if (pContext->pbModulusInLittleEndian[dwKey] != NULL)
+ {
+ pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
+ pContext->pbModulusInLittleEndian[dwKey] = NULL;
+ }
pbCmd[7] = Keys[dwKey].bKeyTag;
dwCmdSize = 9;
if (pContext->fExtentedLeLcFields)
@@ -576,7 +600,7 @@
}
dwOffset = 2;
dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
- if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSize))
+ if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSizeInBytes))
{
dwReturn = SCARD_E_UNEXPECTED;
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
@@ -588,8 +612,167 @@
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
__leave;
}
- Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);
- *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
+ Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
+
+ pContext->dwExponent[dwKey] = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
+ pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
+ if (!pContext->pbModulusInLittleEndian[dwKey])
+ {
+ dwReturn = SCARD_E_NO_MEMORY;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY");
+ __leave;
+ }
+ // convert big endian into little endian
+ for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
+ {
+ pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
+ }
+ pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
+ dwReturn = 0;
+ }
+ __finally
+ {
+ if (pbData)
+ pCardData->pfnCspFree(pbData);
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+DWORD OCardUpdateCachedPublicKeyIfNeeded(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
+{
+ PBYTE pbFingerPrint = NULL;
+ DWORD dwFingerPrintSize, dwReturn;
+ BOOL fHasToUpdateTheCache;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ LARGE_INTEGER Now;
+ SYSTEMTIME WindowsSystemTime;
+ FILETIME WindowsFileTime;
+ __try
+ {
+ GetSystemTime(&WindowsSystemTime);
+ SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
+ Now.HighPart = WindowsFileTime.dwHighDateTime;
+ Now.LowPart = WindowsFileTime.dwLowDateTime;
+ // last read less than 0,2 s
+ if ((Now.QuadPart - pContext->LastCacheCheck[dwKey].QuadPart) < 2000000)
+ {
+ Trace(WINEVENT_LEVEL_INFO, L"Cache up to date");
+ pContext->LastCacheCheck[dwKey] = Now;
+ dwReturn = 0;
+ __leave;
+ }
+ Trace(WINEVENT_LEVEL_INFO, L"Updating cache");
+ // try to use the cache
+ dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if (dwFingerPrintSize != 60)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ // determine if we have to retrieve the modulus from the card
+ if (memcmp(pbFingerPrint + dwKey * 20, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0)
+ {
+ // no public key => why want to read it ?
+ Trace(WINEVENT_LEVEL_ERROR, L"pbFingerPrint null for key %d", dwKey);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ if (pContext->pbModulusInLittleEndian[dwKey])
+ {
+ pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
+ pContext->pbModulusInLittleEndian[dwKey] = NULL;
+ }
+ pContext->fHasKey[dwKey] = FALSE;
+ __leave;
+ }
+ if (memcmp(pbFingerPrint + dwKey * 20, pContext->bFingerPrint + dwKey * 20, 20) == 0)
+ {
+ if (pContext->pbModulusInLittleEndian[dwKey])
+ {
+ fHasToUpdateTheCache = FALSE;
+ }
+ else
+ {
+ fHasToUpdateTheCache = TRUE;
+ }
+ }
+ else
+ {
+ fHasToUpdateTheCache = TRUE;
+ }
+ if (fHasToUpdateTheCache)
+ {
+ dwReturn = OCardUpdateCachedPublicKey(pCardData, dwKey);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ pContext->LastCacheCheck[dwKey] = Now;
+ }
+ __finally
+ {
+ if (pbFingerPrint)
+ pCardData->pfnCspFree(pbFingerPrint);
+ }
+ return dwReturn;
+}
+
+DWORD OCardGetKeyLengthInBytes(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey, __out PDWORD pdwLengthInBytes)
+{
+ DWORD dwReturn;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
+ if (dwKey >= KeyMax)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
+ __leave;
+ }
+ dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ *pdwLengthInBytes = pContext->dwModulusSizeInBytes[dwKey];
+ Trace(WINEVENT_LEVEL_VERBOSE, L"modulus size in bits= %d",*pdwLengthInBytes*8);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+DWORD OCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
+{
+ DWORD dwReturn;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ PRSAPUBLICKEYBLOB pbBlob = NULL;
+ DWORD dwModulusSizeInBytes;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
+ if (dwKey >= KeyMax)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
+ __leave;
+ }
+ dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
+ Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
+ *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSizeInBytes - sizeof(DWORD);
*pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
if (!*pbPublicKey)
{
@@ -604,21 +787,13 @@
pbBlob->blobheader.reserved = 0;
pbBlob->blobheader.aiKeyAlg = Keys[dwKey].aiKeyAlg;
pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
- pbBlob->rsapubkey.bitlen = dwModulusSize*8;
- pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
- // convert big endian into little endian
- //memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
- for (dwI = 0; dwI < dwModulusSize; dwI++)
- {
- pbBlob->modulus[dwI] = pbModulus[dwModulusSize - 1 - dwI];
- }
-
+ pbBlob->rsapubkey.bitlen = dwModulusSizeInBytes*8;
+ pbBlob->rsapubkey.pubexp = pContext->dwExponent[dwKey];
+ memcpy(pbBlob->modulus, pContext->pbModulusInLittleEndian[dwKey], dwModulusSizeInBytes);
dwReturn = 0;
}
__finally
{
- if (pbData)
- pCardData->pfnCspFree(pbData);
}
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
return dwReturn;
@@ -630,10 +805,10 @@
PBYTE pbData = NULL;
DWORD dwResponseSize = 0, dwCmdSize;
OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
- POPENPGP_CONTEXT pContext;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
DWORD dwSecondsSince1970;
PBYTE pbModulus, pbExponent;
- DWORD dwModulusSize, dwExponent;
+ DWORD dwModulusSizeInBytes, dwExponent, dwI;
BYTE pbCmd[] = {0x00,
0x47,
0x80,
@@ -647,6 +822,7 @@
0x00
};
DWORD dwTotalTlvSize, dwOffset;
+ BYTE pbFingerPrint[20];
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
@@ -657,19 +833,16 @@
__leave;
}
// key len
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
- if (dwReturn)
- {
- __leave;
- }
- Attributes.wModulusLengthInBit = (WORD) dwBitLen;
+ Attributes.wModulusLengthInBit = (unsigned short)dwBitLen * 8;
+ Attributes.wExponentLengthInBit = 4 * 8;
+ Attributes.bAlgoId = 1;
+ Attributes.bFormat = 0;
dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
if (dwReturn)
{
__leave;
}
- pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
pbCmd[7] = Keys[dwKey].bKeyTag;
dwCmdSize = 9;
if (pContext->fExtentedLeLcFields)
@@ -689,7 +862,7 @@
}
dwOffset = 2;
dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
- if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSize))
+ if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSizeInBytes))
{
dwReturn = SCARD_E_UNEXPECTED;
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
@@ -698,26 +871,62 @@
if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
{
dwReturn = SCARD_E_UNEXPECTED;
- Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x82");
__leave;
}
dwExponent = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
- dwReturn = UpdateGenerationDateTime(pCardData, dwKey, &dwSecondsSince1970);
+ // save in the cache
+ pContext->fHasKey[dwKey] = TRUE;
+ pContext->dwExponent[dwKey] = dwExponent;
+ pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
+ if (pContext->pbModulusInLittleEndian[dwKey])
+ {
+ pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
+ }
+ pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
+ if (!pContext->pbModulusInLittleEndian[dwKey])
+ {
+ dwReturn = SCARD_E_NO_MEMORY;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
+ __leave;
+ }
+ for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
+ {
+ pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
+ }
+ dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
if (dwReturn)
{
__leave;
}
- dwReturn = UpdateFingerPrint(pCardData, dwKey, dwSecondsSince1970,
- pbModulus,
- dwModulusSize * 8,
- TRUE,
- dwExponent
- );
+ dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
if (dwReturn)
{
__leave;
}
- pContext->fHasKey[dwKey] = TRUE;
+ // avoid two key having the same fingerprint if generated too fast
+ while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
+ || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
+ || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
+ {
+ dwSecondsSince1970++;
+ dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
}
__finally
{
@@ -744,6 +953,7 @@
BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
DWORD dwSecondsSince1970;
POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ BYTE pbFingerPrint[20];
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);
@@ -768,12 +978,10 @@
__leave;
}
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
- if (dwReturn)
- {
- __leave;
- }
Attributes.wModulusLengthInBit = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
+ Attributes.wExponentLengthInBit = 4 * 8;
+ Attributes.bAlgoId = 1;
+ Attributes.bFormat = 0;
dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
if (dwReturn)
{
@@ -818,22 +1026,55 @@
{
__leave;
}
- dwReturn = UpdateGenerationDateTime(pCardData, dwKey, &dwSecondsSince1970);
+ // save in the cache
+ pContext->fHasKey[dwKey] = TRUE;
+ pContext->dwExponent[dwKey] = pbPublicKeyBlob->rsapubkey.pubexp;
+ pContext->dwModulusSizeInBytes[dwKey] = (WORD) pbPublicKeyBlob->rsapubkey.bitlen / 8;
+ if (pContext->pbModulusInLittleEndian[dwKey])
+ {
+ pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
+ }
+ pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(pContext->dwModulusSizeInBytes[dwKey]);
+ if (!pContext->pbModulusInLittleEndian[dwKey])
+ {
+ dwReturn = SCARD_E_NO_MEMORY;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
+ __leave;
+ }
+ memcpy(pContext->pbModulusInLittleEndian[dwKey],&(pbPublicKeyBlob->modulus),pContext->dwModulusSizeInBytes[dwKey]);
+ dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
if (dwReturn)
{
__leave;
}
- dwReturn = UpdateFingerPrint(pCardData, dwKey, dwSecondsSince1970,
- pbPublicKeyBlob->modulus,
- pbPublicKeyBlob->rsapubkey.bitlen,
- FALSE,
- pbPublicKeyBlob->rsapubkey.pubexp
- );
+ dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
if (dwReturn)
{
__leave;
}
- pContext->fHasKey[dwKey] = TRUE;
+ // avoid two key having the same fingerprint if generated too fast
+ while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
+ || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
+ || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
+ {
+ dwSecondsSince1970++;
+ dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
}
__finally
{
@@ -848,11 +1089,11 @@
pCardData->pfnCspFree(pbTlv);
}
}
- Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
return dwReturn;
}
-DWORD OCardCheckSigningInfo(__in PCARD_SIGNING_INFO pInfo, __out PDWORD pdwIndex)
+DWORD OCardCheckSigningInfo(__in PCARD_SIGNING_INFO pInfo, __in BOOL fAllowNoOid, __out PDWORD pdwIndex)
{
DWORD dwReturn, dwI;
__try
@@ -868,6 +1109,21 @@
if ( pInfo->dwPaddingType == CARD_PADDING_PKCS1)
{
BCRYPT_PKCS1_PADDING_INFO* padding = (BCRYPT_PKCS1_PADDING_INFO*) pInfo->pPaddingInfo;
+ if (padding->pszAlgId == NULL)
+ {
+ if (fAllowNoOid)
+ {
+ *pdwIndex = OPENPGP_NO_OID;
+ dwReturn = 0;
+ __leave;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ }
for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
{
if (wcscmp(SignatureAlgorithm[dwI].szAlgId,padding->pszAlgId) == 0)
@@ -940,8 +1196,7 @@
DWORD dwReturn;
PBYTE pbData = NULL;
DWORD dwCmdSize = 0, dwIndex, dwI;
- POPENPGP_CONTEXT pContext;
- OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
BYTE pbCmd[6 + 256 + 256] = {0x00,
0x2A,
0x9E,
@@ -952,33 +1207,25 @@
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
- dwReturn = OCardCheckSigningInfo(pInfo, &dwIndex);
- if (dwReturn)
- {
- __leave;
- }
if (pInfo->bContainerIndex != ContainerSignature)
{
dwReturn = SCARD_E_NO_KEY_CONTAINER;
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
__leave;
}
+ dwReturn = OCardCheckSigningInfo(pInfo, FALSE, &dwIndex);
+ if (dwReturn)
+ {
+ __leave;
+ }
if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
{
// optimisation :
// return the buffer size only
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeySignature, &Attributes);
- if (dwReturn)
- {
- __leave;
- }
- pInfo->cbSignedData = Attributes.wModulusLengthInBit/8;
- dwReturn = 0;
+ dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
__leave;
}
- pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
-
dwCmdSize = 5;
if (pContext->fExtentedLeLcFields)
{
@@ -1033,15 +1280,56 @@
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
return dwReturn;
}
-
+DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData)
+{
+ DWORD dwReturn;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ __try
+ {
+ // see if the confidentiality key is the same than the authentication key
+ // if yes, confidentiality key can sign
+ // else ... we don't follow ms guidelines which requiers every container
+ // to be able to sign data
+ dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerAuthentication);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerConfidentiality);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if (pContext->dwModulusSizeInBytes[ContainerAuthentication]
+ != pContext->dwModulusSizeInBytes[ContainerConfidentiality])
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
+ __leave;
+ }
+ if (memcmp(pContext->pbModulusInLittleEndian[ContainerAuthentication],
+ pContext->pbModulusInLittleEndian[ContainerConfidentiality],
+ pContext->dwModulusSizeInBytes[ContainerConfidentiality]) != 0)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
+ __leave;
+ }
+ // if we are here, then the confidentiality key can sign using the authentication key
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
DWORD OCardAuthenticate(PCARD_DATA pCardData,
PCARD_SIGNING_INFO pInfo)
{
DWORD dwReturn;
PBYTE pbData = NULL;
DWORD dwCmdSize = 0, dwIndex, dwI;
- POPENPGP_CONTEXT pContext;
- OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
BYTE pbCmd[6 + 256 + 256] = {0x00,
0x88,
0x00,
@@ -1052,48 +1340,51 @@
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
- dwReturn = OCardCheckSigningInfo(pInfo, &dwIndex);
- if (dwReturn)
+
+ if (pInfo->bContainerIndex != ContainerAuthentication && pInfo->bContainerIndex != ContainerConfidentiality)
{
- __leave;
- }
- if (pInfo->bContainerIndex != ContainerAuthentication)
- {
dwReturn = SCARD_E_NO_KEY_CONTAINER;
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
__leave;
}
- if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
+ if (pInfo->bContainerIndex == ContainerConfidentiality)
{
- // optimisation :
- // return the buffer size only
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyAuthentication, &Attributes);
+ dwReturn = OCardIsConfidentialityKeyTheSameThanAuthentication(pCardData);
if (dwReturn)
{
__leave;
}
- pInfo->cbSignedData = Attributes.wModulusLengthInBit/8;
- dwReturn = 0;
+ }
+ dwReturn = OCardCheckSigningInfo(pInfo, TRUE, &dwIndex);
+ if (dwReturn)
+ {
__leave;
}
+ if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
+ {
+ // optimisation :
+ // return the buffer size only
+ dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
+ __leave;
+ }
- pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
-
dwCmdSize = 5;
if (pContext->fExtentedLeLcFields)
{
dwCmdSize++;
}
- pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
- memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
- dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
- /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
+ if (dwIndex == OPENPGP_NO_OID)
{
- pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
- }*/
+ pbCmd[dwCmdSize++] = (BYTE) (pInfo->cbData);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
+ memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
+ dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
+ }
memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
dwCmdSize += pInfo->cbData;
-
if (pContext->fExtentedLeLcFields)
{
@@ -1146,7 +1437,7 @@
0x86,
0x00,
};
- POPENPGP_CONTEXT pContext;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
DWORD dwI;
OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
__try
@@ -1176,7 +1467,6 @@
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d", pInfo->cbData);
__leave;
}
- pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
dwCmdSize = 5;
if (pContext->fExtentedLeLcFields)
{
@@ -1250,7 +1540,7 @@
{
DWORD dwReturn = 0;
POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
- OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
+ DWORD dwSizeInBits;
__try
{
PCONTAINER_MAP_RECORD pContainer = NULL;
@@ -1266,12 +1556,12 @@
pContainer = (PCONTAINER_MAP_RECORD) *ppbResponse;
memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * ContainerMax);
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyAuthentication, &Attributes);
+ dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyAuthentication, &dwSizeInBits);
if (dwReturn)
{
__leave;
}
- pContainer[ContainerAuthentication].wSigKeySizeBits = Attributes.wModulusLengthInBit;
+ pContainer[ContainerAuthentication].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
swprintf_s(pContainer[ContainerAuthentication].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],
@@ -1284,12 +1574,12 @@
fIsDefaultContainerSet = TRUE;
}
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyConfidentiality, &Attributes);
+ dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyConfidentiality, &dwSizeInBits);
if (dwReturn)
{
__leave;
}
- pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = Attributes.wModulusLengthInBit;
+ pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = (WORD)dwSizeInBits * 8;
swprintf_s(pContainer[ContainerConfidentiality].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],
@@ -1306,12 +1596,12 @@
}
}
- dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeySignature, &Attributes);
+ dwReturn = OCardGetKeyLengthInBytes(pCardData, KeySignature, &dwSizeInBits);
if (dwReturn)
{
__leave;
}
- pContainer[ContainerSignature].wSigKeySizeBits = Attributes.wModulusLengthInBit;
+ pContainer[ContainerSignature].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
swprintf_s(pContainer[ContainerSignature].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],
Modified: trunk/OpenPGPminidriver/CryptoOperations.h
===================================================================
--- trunk/OpenPGPminidriver/CryptoOperations.h 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/CryptoOperations.h 2010-03-15 18:23:17 UTC (rev 10)
@@ -18,16 +18,16 @@
typedef enum _OPENPGP_CONTAINER
{
ContainerSignature,
+ ContainerConfidentiality,
ContainerAuthentication,
- ContainerConfidentiality,
ContainerMax
} OPENPGP_CONTAINER;
typedef enum _OPENPGP_KEY
{
KeySignature,
+ KeyConfidentiality,
KeyAuthentication,
- KeyConfidentiality,
KeyMax
} OPENPGP_KEY;
@@ -83,4 +83,9 @@
PCARD_RSA_DECRYPT_INFO pInfo);
DWORD OCardReadContainerMapFile(__in PCARD_DATA pCardData,
- __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize);
\ No newline at end of file
+ __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize);
+
+DWORD OCardGetKeyLengthInBytes(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
+ __out PDWORD pdwLengthInBytes);
+
+DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData);
\ No newline at end of file
Modified: trunk/OpenPGPminidriver/PinOperations.c
===================================================================
--- trunk/OpenPGPminidriver/PinOperations.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/PinOperations.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -133,6 +133,7 @@
__in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin)
{
DWORD dwReturn;
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
// 256 because the size of the PIN must fit in a Byte
BYTE pbCmd[256 + 5] = {0x00,
0x20,
@@ -171,7 +172,10 @@
__leave;
}
Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication successfull");
-
+ if (PinId == ROLE_ADMIN)
+ {
+ pContext->fDoesTheAdminHasBeenAuthenticatedAtLeastOnce = TRUE;
+ }
}
__finally
{
Modified: trunk/OpenPGPminidriver/PublicDataOperations.c
===================================================================
--- trunk/OpenPGPminidriver/PublicDataOperations.c 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriver/PublicDataOperations.c 2010-03-15 18:23:17 UTC (rev 10)
@@ -34,6 +34,7 @@
#define OPENPGP_FILE_OPTIONAL 1
#define OPENPGP_FILE_WRITE_ONLY 2
#define OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING 4
+#define OPENPGP_FILE_CONF_IS_AUTH 8
typedef struct _OPENPGP_FILE
{
@@ -70,7 +71,8 @@
{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},
+ {szBASE_CSP_DIR, "ksc1", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING | OPENPGP_FILE_CONF_IS_AUTH},
+ {szBASE_CSP_DIR, "ksc2", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING},
};
@@ -237,7 +239,7 @@
__in_opt PSTR szDirectory,
__in PBYTE* pbResponse, __in PDWORD pdwResponseSize)
{
- DWORD dwReturn = 0, dwReadFileReturn;
+ DWORD dwReturn = 0, dwTempReturn;
DWORD dwI, dwSize;
BOOL fDirectoryFound = FALSE;
BOOL fAddToOuput;
@@ -296,8 +298,8 @@
DWORD dwSize;
fAddToOuput = FALSE;
// check if the file exists and be read
- dwReadFileReturn = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
- if (!dwReadFileReturn)
+ dwTempReturn = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
+ if (!dwTempReturn)
{
pCardData->pfnCspFree(pbData);
if (dwSize > 0)
@@ -306,6 +308,14 @@
}
}
}
+ if (fAddToOuput && (Files[dwI].dwFlag & OPENPGP_FILE_CONF_IS_AUTH))
+ {
+ dwTempReturn = OCardIsConfidentialityKeyTheSameThanAuthentication(pCardData);
+ if (dwReturn)
+ {
+ fAddToOuput = FALSE;
+ }
+ }
if (fAddToOuput)
{
dwSize = (DWORD) strlen( Files[dwI].szFile) + 1;
Modified: trunk/OpenPGPminidriverTest/CryptoOperations.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/CryptoOperations.cpp 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/CryptoOperations.cpp 2010-03-15 18:23:17 UTC (rev 10)
@@ -37,11 +37,11 @@
dwKeySpec = AT_SIGNATURE;
PinId = ROLE_USER;
break;
- case 1: //Authentication,
+ case 2: //Authentication,
dwKeySpec = AT_SIGNATURE;
PinId = 3;
break;
- case 2: // Confidentiality,
+ case 1: // Confidentiality,
dwKeySpec = AT_KEYEXCHANGE;
PinId = 4;
break;
@@ -97,11 +97,11 @@
dwKeySpec = AT_SIGNATURE;
PinId = ROLE_USER;
break;
- case 1: //Authentication,
+ case 2: //Authentication,
dwKeySpec = AT_SIGNATURE;
PinId = 3;
break;
- case 2: // Confidentiality,
+ case 1: // Confidentiality,
dwKeySpec = AT_KEYEXCHANGE;
PinId = 4;
break;
@@ -251,11 +251,11 @@
dwKeySpec = AT_SIGNATURE;
PinId = ROLE_USER;
break;
- case 1: //Authentication,
+ case 2: //Authentication,
dwKeySpec = AT_SIGNATURE;
PinId = 3;
break;
- case 2: // Confidentiality,
+ case 1: // Confidentiality,
dwKeySpec = AT_KEYEXCHANGE;
PinId = 4;
break;
@@ -315,4 +315,21 @@
CryptReleaseContext(hProv,0);
}
return dwReturn;
+}
+DWORD SetReadOnly(BOOL fSet)
+{
+ DWORD dwReturn;
+ __try
+ {
+ if (!pCardData)
+ {
+ dwReturn = SCARD_E_COMM_DATA_LOST;
+ __leave;
+ }
+ dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0);
+ }
+ __finally
+ {
+ }
+ return dwReturn;
}
\ No newline at end of file
Modified: trunk/OpenPGPminidriverTest/Dialog.h
===================================================================
--- trunk/OpenPGPminidriverTest/Dialog.h 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/Dialog.h 2010-03-15 18:23:17 UTC (rev 10)
@@ -8,18 +8,20 @@
#define IDD_PIN 1200
#define IDC_PINUSER 1201
#define IDC_PINADMIN 1202
+#define IDC_PUK 1208
#define IDC_CHECKPIN 1203
#define IDC_TXTPIN 1204
#define IDC_TXTPIN2 1205
#define IDC_CHANGEPIN 1206
#define IDC_UNBLOCKPIN 1207
-#define IDC_PUK 1208
#define IDC_BTN1 1209
#define IDD_CRYPTO 1300
#define IDC_SAMEKEY 1301
#define IDC_IMPORTKEY 1302
#define IDC_NEWKEY 1303
#define IDC_CONTAINERINDEX 1304
+#define IDC_SETREADONLY 1305
+#define IDC_UNSETREADONLY 1306
#define IDD_FILE 1400
#define IDC_LISTFILES 1401
#define IDC_STC2 1402
Modified: trunk/OpenPGPminidriverTest/Dialog.rc
===================================================================
--- trunk/OpenPGPminidriverTest/Dialog.rc 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/Dialog.rc 2010-03-15 18:23:17 UTC (rev 10)
@@ -36,15 +36,17 @@
CONTROL "Set Puk",IDC_BTN1,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,267,66,54,21
END
-IDD_CRYPTO DIALOGEX 10,10,400,300
+IDD_CRYPTO DIALOGEX 0,0,400,300
CAPTION "IDD_MAIN"
FONT 8,"MS Sans Serif",0,0,0
STYLE NOT WS_VISIBLE|WS_CHILDWINDOW
BEGIN
- CONTROL "Set same key",IDC_SAMEKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,123,39,72,21
+ CONTROL "Set same key for all containers",IDC_SAMEKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,150,18,105,36
CONTROL "Import key",IDC_IMPORTKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,42,63,72,21
CONTROL "Generate new key",IDC_NEWKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,42,39,72,21
CONTROL "",IDC_CONTAINERINDEX,"ComboBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWNLIST,39,18,90,15
+ CONTROL "Set readonly",IDC_SETREADONLY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,174,117,57,24
+ CONTROL "Unset readonly",IDC_UNSETREADONLY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,174,147,57,24
END
IDD_FILE DIALOGEX 10,10,400,300
Modified: trunk/OpenPGPminidriverTest/PINOperations.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/PINOperations.cpp 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/PINOperations.cpp 2010-03-15 18:23:17 UTC (rev 10)
@@ -36,7 +36,7 @@
pCardData,
wszUserId,
(PBYTE) szPin,
- cbPin - 1,
+ cbPin,
pcAttemptsRemaining);
}
__finally
Modified: trunk/OpenPGPminidriverTest/global.h
===================================================================
--- trunk/OpenPGPminidriverTest/global.h 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/global.h 2010-03-15 18:23:17 UTC (rev 10)
@@ -30,4 +30,5 @@
DWORD GenerateNewKey(DWORD dwIndex);
DWORD ImportKey(DWORD dwIndex);
DWORD SetTheSameKeyForAllContainers();
+DWORD SetReadOnly(BOOL fSet);
#define OPENPGP_TEST_CONTAINER TEXT("Test_OPENPGPG")
\ No newline at end of file
Modified: trunk/OpenPGPminidriverTest/main.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/main.cpp 2010-03-15 09:47:30 UTC (rev 9)
+++ trunk/OpenPGPminidriverTest/main.cpp 2010-03-15 18:23:17 UTC (rev 10)
@@ -315,8 +315,8 @@
{
case WM_INITDIALOG:
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Signature"));
+ SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Confidentiality"));
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Authentication"));
- SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Confidentiality"));
SendDlgItemMessage(hWnd,IDC_CONTAINERINDEX, CB_SETCURSEL, 0, 0);
break;
case WM_COMMAND:
@@ -337,6 +337,14 @@
dwReturn = SetTheSameKeyForAllContainers();
MessageBoxWin32(dwReturn);
break;
+ case IDC_SETREADONLY:
+ dwReturn = SetReadOnly(TRUE);
+ MessageBoxWin32(dwReturn);
+ break;
+ case IDC_UNSETREADONLY:
+ dwReturn = SetReadOnly(FALSE);
+ MessageBoxWin32(dwReturn);
+ break;
}
break;
}
More information about the Openpgpmdrv-commits
mailing list