[Openpgpmdrv-commits] r1 - / trunk trunk/OpenPGPminidriver trunk/OpenPGPminidriverTest
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Tue Feb 23 20:19:08 CET 2010
Author: vletoux
Date: 2010-02-23 20:18:59 +0100 (Tue, 23 Feb 2010)
New Revision: 1
Added:
trunk/
trunk/OpenPGPminidriver.sln
trunk/OpenPGPminidriver/
trunk/OpenPGPminidriver/CardAndContainerProperties.c
trunk/OpenPGPminidriver/CardCryptographicOperations.c
trunk/OpenPGPminidriver/CardInitializationAndDeconstruct.c
trunk/OpenPGPminidriver/CardKeyContainer.c
trunk/OpenPGPminidriver/CardPinOperation.c
trunk/OpenPGPminidriver/CardPublicDataOperation.c
trunk/OpenPGPminidriver/CardSecureKeyInjection.c
trunk/OpenPGPminidriver/Context.h
trunk/OpenPGPminidriver/ContextManagement.c
trunk/OpenPGPminidriver/CryptoOperations.c
trunk/OpenPGPminidriver/CryptoOperations.h
trunk/OpenPGPminidriver/DllMain.c
trunk/OpenPGPminidriver/OpenPGPminidriver.def
trunk/OpenPGPminidriver/OpenPGPminidriver.vcproj
trunk/OpenPGPminidriver/PinOperations.c
trunk/OpenPGPminidriver/PinOperations.h
trunk/OpenPGPminidriver/PublicDataOperations.c
trunk/OpenPGPminidriver/PublicDataOperations.h
trunk/OpenPGPminidriver/README.txt
trunk/OpenPGPminidriver/SmartCard.c
trunk/OpenPGPminidriver/SmartCard.h
trunk/OpenPGPminidriver/SmartCardOperations.c
trunk/OpenPGPminidriver/Tracing.c
trunk/OpenPGPminidriver/Tracing.h
trunk/OpenPGPminidriver/driver.inf
trunk/OpenPGPminidriver/version.rc
trunk/OpenPGPminidriverTest/
trunk/OpenPGPminidriverTest/BaseCSP.cpp
trunk/OpenPGPminidriverTest/CryptoOperations.cpp
trunk/OpenPGPminidriverTest/Dialog.h
trunk/OpenPGPminidriverTest/Dialog.rc
trunk/OpenPGPminidriverTest/InitializationAndDeconstruct.cpp
trunk/OpenPGPminidriverTest/OpenPGPminidriverTest.vcproj
trunk/OpenPGPminidriverTest/PINOperations.cpp
trunk/OpenPGPminidriverTest/PublicDataOperations.cpp
trunk/OpenPGPminidriverTest/RegisterCardForTestIfTheDriverIsNotInstalled.reg
trunk/OpenPGPminidriverTest/global.h
trunk/OpenPGPminidriverTest/main.cpp
Log:
Added: trunk/OpenPGPminidriver/CardAndContainerProperties.c
===================================================================
--- trunk/OpenPGPminidriver/CardAndContainerProperties.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardAndContainerProperties.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,582 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "CryptoOperations.h"
+#include "PinOperations.h"
+
+// 4.4 Card capabilities
+
+/** This function queries the card and card-specific minidriver combination
+for the functionality that is provided at this level, such as certificate or
+file compression.*/
+
+DWORD WINAPI CardQueryCapabilities(
+ __in PCARD_DATA pCardData,
+ __inout PCARD_CAPABILITIES pCardCapabilities
+)
+{
+ DWORD dwReturn = 0, dwVersion;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pCardCapabilities == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardCapabilities == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwVersion = (pCardCapabilities->dwVersion == 0) ? 1 : pCardCapabilities->dwVersion;
+ if ( dwVersion != CARD_CAPABILITIES_CURRENT_VERSION )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwVersion %d", dwVersion);
+ dwReturn = ERROR_REVISION_MISMATCH;
+ __leave;
+ }
+ pCardCapabilities->fCertificateCompression = TRUE;
+ pCardCapabilities->fKeyGen = TRUE;
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+// 4.5 Card and container properties
+
+/** The CardGetContainerProperty function is modeled after the query
+functions of CAPI for keys. It takes a LPWSTR that indicates which parameter
+is being requested. Then it returns data written into the pbData parameter.*/
+
+DWORD WINAPI CardGetContainerProperty(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in LPCWSTR wszProperty,
+ __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData,
+ __in DWORD cbData,
+ __out PDWORD pdwDataLen,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex = %d wszProperty = %s", bContainerIndex, wszProperty);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pdwDataLen == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pdwDataLen == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wszProperty == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (bContainerIndex >= MaxContainer)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d", bContainerIndex);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER ;
+ __leave;
+ }
+ if (wcscmp(wszProperty,CCP_CONTAINER_INFO) == 0)
+ {
+ if (cbData < sizeof(CONTAINER_INFO))
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *pdwDataLen = cbData;
+ dwReturn = CardGetContainerInfo(pCardData, bContainerIndex, dwFlags, (PCONTAINER_INFO) pbData);
+ }
+ else if (wcscmp(wszProperty,CCP_PIN_IDENTIFIER) == 0)
+ {
+ if (cbData < sizeof(PIN_ID))
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *pdwDataLen = cbData;
+ if(bContainerIndex < MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", bContainerIndex);
+ __leave;
+ }
+ (*(PDWORD)pbData) = Containers[bContainerIndex].PinId;
+ dwReturn = 0;
+ }
+ /*else if (wcscmp(wszProperty,CCP_ASSOCIATED_ECDH_KEY) == 0)
+ {
+ }*/
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** This function sets the properties on containers. Only two container
+properties are supported:
+ CCP_PIN_IDENTIFIER
+ CCP_ASSOCIATED_ECDH_KEY
+*/
+
+DWORD WINAPI CardSetContainerProperty(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in LPCWSTR wszProperty,
+ __in_bcount(cbDataLen) PBYTE pbData,
+ __in DWORD cbDataLen,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex = %d wszProperty = %s", bContainerIndex, wszProperty);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wszProperty == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (wcscmp(wszProperty,CCP_PIN_IDENTIFIER) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ else if (wcscmp(wszProperty,CCP_ASSOCIATED_ECDH_KEY) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardGetProperty function is modeled after the query functions of
+CAPI for keys. It takes a LPWSTR that indicates which parameter is being
+requested. The function returns data in the pbData parameter.*/
+
+DWORD WINAPI CardGetProperty(
+ __in PCARD_DATA pCardData,
+ __in LPCWSTR wszProperty,
+ __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData,
+ __in DWORD cbData,
+ __out PDWORD pdwDataLen,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ PBYTE pbTempData = NULL;
+ DWORD dwTempSize = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter wszProperty = %s", wszProperty);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wszProperty == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pdwDataLen == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pdwDataLen == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (wcscmp(wszProperty,CP_CARD_FREE_SPACE) == 0)
+ {
+ *pdwDataLen = sizeof(CARD_FREE_SPACE_INFO);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ dwReturn = CardQueryFreeSpace(pCardData, dwFlags, (PCARD_FREE_SPACE_INFO) pbData);
+ }
+ else if (wcscmp(wszProperty,CP_CARD_CAPABILITIES) == 0)
+ {
+ *pdwDataLen = sizeof(CARD_CAPABILITIES);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ dwReturn = CardQueryCapabilities(pCardData, (PCARD_CAPABILITIES) pbData);
+ }
+ else if (wcscmp(wszProperty,CP_CARD_KEYSIZES) == 0)
+ {
+ *pdwDataLen = sizeof(CARD_KEY_SIZES);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ dwReturn = CardQueryKeySizes(pCardData, dwFlags, 0, (PCARD_KEY_SIZES) pbData);
+ }
+ else if (wcscmp(wszProperty,CP_CARD_READ_ONLY) == 0)
+ {
+ *pdwDataLen = sizeof(BOOL);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *((PBOOL)pbData) = TRUE;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_CACHE_MODE) == 0)
+ {
+ *pdwDataLen = sizeof(DWORD);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *((PDWORD)pbData) = CP_CACHE_MODE_NO_CACHE;
+ }
+ else if (wcscmp(wszProperty,CP_SUPPORTS_WIN_X509_ENROLLMENT) == 0)
+ {
+ *pdwDataLen = sizeof(BOOL);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *((PBOOL)pbData) = FALSE;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_GUID) == 0)
+ {
+ dwReturn = CardReadFile(pCardData, NULL, szCARD_IDENTIFIER_FILE, 0, &pbTempData, &dwTempSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ *pdwDataLen = dwTempSize;
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ memcpy(pbData, pbTempData, dwTempSize);
+ }
+ else if (wcscmp(wszProperty,CP_CARD_SERIAL_NO) == 0)
+ {
+ *pdwDataLen = sizeof(OPENPGP_AID);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ memcpy(pbData, &(((POPENPGP_CONTEXT)pCardData->pvVendorSpecific)->Aid), sizeof(OPENPGP_AID));
+ dwReturn = 0;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_PIN_INFO) == 0)
+ {
+ PPIN_INFO pPinInfo;
+ *pdwDataLen = sizeof(PIN_INFO);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ pPinInfo = (PPIN_INFO) pbData;
+ dwReturn = GetPinInfo(dwFlags, pPinInfo);
+ }
+ else if (wcscmp(wszProperty,CP_CARD_LIST_PINS) == 0)
+ {
+ PPIN_SET pPinSet;
+ *pdwDataLen = sizeof(PIN_SET);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ pPinSet = (PPIN_SET) pbData;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_AUTHENTICATED_STATE) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_PIN_STRENGTH_VERIFY) == 0)
+ {
+ PPIN_SET pPinSet;
+ *pdwDataLen = sizeof(PIN_SET);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ pPinSet = (PPIN_SET) pbData;
+ *pPinSet = CARD_PIN_STRENGTH_PLAINTEXT;
+ }
+ else if (wcscmp(wszProperty,CP_KEY_IMPORT_SUPPORT) == 0)
+ {
+ *pdwDataLen = sizeof(DWORD);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *((PDWORD)pbData) = CARD_KEY_IMPORT_RSA_KEYEST;
+ }
+ else if (wcscmp(wszProperty,CP_ENUM_ALGORITHMS ) == 0)
+ {
+ if (dwFlags == CARD_CIPHER_OPERATION)
+ {
+ *pdwDataLen = sizeof(OPENPGP_SUPPORTED_CYPHER_ALGORITHM);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ memcpy(pbData,OPENPGP_SUPPORTED_CYPHER_ALGORITHM,*pdwDataLen);
+ }
+ else if (dwFlags == CARD_ASYMMETRIC_OPERATION )
+ {
+ *pdwDataLen = sizeof(OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ memcpy(pbData,OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM,*pdwDataLen);
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ }
+ }
+ else if (wcscmp(wszProperty,CP_PADDING_SCHEMES ) == 0)
+ {
+ if (dwFlags == CARD_CIPHER_OPERATION)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ }
+ else if (dwFlags == CARD_ASYMMETRIC_OPERATION )
+ {
+ *pdwDataLen = sizeof(DWORD);
+ if (cbData < *pdwDataLen)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData);
+ dwReturn = ERROR_INSUFFICIENT_BUFFER;
+ __leave;
+ }
+ *((PDWORD)pbData) = CARD_PADDING_PKCS1;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ }
+
+ }
+ else if (wcscmp(wszProperty,CP_CHAINING_MODES ) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ if (pbTempData)
+ {
+ pCardData->pfnCspFree(pbTempData);
+ }
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** This function can be used to set properties on the card.*/
+
+DWORD WINAPI CardSetProperty(
+ __in PCARD_DATA pCardData,
+ __in LPCWSTR wszProperty,
+ __in_bcount(cbDataLen) PBYTE pbData,
+ __in DWORD cbDataLen,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter wszProperty = %s", wszProperty);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wszProperty == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (wcscmp(wszProperty,CP_CARD_FREE_SPACE) == 0
+ || wcscmp(wszProperty,CP_CARD_CAPABILITIES) == 0
+ || wcscmp(wszProperty,CP_CARD_KEYSIZES) == 0
+ || wcscmp(wszProperty,CP_CARD_LIST_PINS) == 0
+ || wcscmp(wszProperty,CP_CARD_AUTHENTICATED_STATE) == 0
+ || wcscmp(wszProperty,CP_KEY_IMPORT_SUPPORT) == 0
+ || wcscmp(wszProperty,CP_ENUM_ALGORITHMS) == 0
+ || wcscmp(wszProperty,CP_PADDING_SCHEMES) == 0
+ || wcscmp(wszProperty,CP_CHAINING_MODES) == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s SCARD_E_UNSUPPORTED_FEATURE", wszProperty);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ __leave;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_READ_ONLY) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_CACHE_MODE) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_SUPPORTS_WIN_X509_ENROLLMENT) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_GUID) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_SERIAL_NO) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_PIN_INFO) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else if (wcscmp(wszProperty,CP_CARD_PIN_STRENGTH_VERIFY) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE ;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
Added: trunk/OpenPGPminidriver/CardCryptographicOperations.c
===================================================================
--- trunk/OpenPGPminidriver/CardCryptographicOperations.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardCryptographicOperations.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,264 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "CryptoOperations.h"
+
+// 4.7 Cryptographic operations
+
+/** This function performs an RSA decryption operation on the passed buffer
+by using the private key that a container index refers to. Note that for
+ECC-only smart cards, this entry point is not defined and is set to NULL
+in the returned CARD_DATA structure from CardAcquireContext. This operation
+is restricted to a single buffer of a size equal to the key modulus.*/
+
+DWORD WINAPI CardRSADecrypt(
+ __in PCARD_DATA pCardData,
+ __inout PCARD_RSA_DECRYPT_INFO pInfo
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ if ( pInfo == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pInfo == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pInfo->pbData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pInfo->pbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pInfo->dwVersion < CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION
+ && pCardData->dwVersion == CARD_DATA_CURRENT_VERSION)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"ERROR_REVISION_MISMATCH");
+ dwReturn = ERROR_REVISION_MISMATCH;
+ __leave;
+ }
+ if (pInfo->dwKeySpec != AT_KEYEXCHANGE)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"AT_KEYEXCHANGE %d", pInfo->dwKeySpec);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER ;
+ __leave;
+ }
+ if (pInfo->bContainerIndex != Confidentiality)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"Confidentiality %d", pInfo->bContainerIndex);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER ;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardDecrypt(pCardData, pInfo);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+
+/** The CardSignData function signs a block of unpadded data. This entry either performs
+padding on the card or pads the data by using the PFN_CSP_PAD_DATA callback. All card
+minidrivers must support this entry point.*/
+
+DWORD WINAPI CardSignData(
+ __in PCARD_DATA pCardData,
+ __in PCARD_SIGNING_INFO pInfo
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ if ( pInfo == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pInfo == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pInfo->pbData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pInfo->pbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardSign(pCardData, pInfo);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** This function returns the public key sizes that are supported by the card in use.*/
+DWORD WINAPI CardQueryKeySizes(
+ __in PCARD_DATA pCardData,
+ __in DWORD dwKeySpec,
+ __in DWORD dwFlags,
+ __inout PCARD_KEY_SIZES pKeySizes
+)
+{
+ DWORD dwReturn = 0, dwVersion;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ if ( dwFlags != 0 )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags != 0 : %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pKeySizes == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pKeySizes == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwVersion = (pKeySizes->dwVersion == 0) ? 1 : pKeySizes->dwVersion;
+ if ( dwVersion != CARD_KEY_SIZES_CURRENT_VERSION )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwVersion == %d", pKeySizes->dwVersion);
+ dwReturn = ERROR_REVISION_MISMATCH;
+ __leave;
+ }
+
+ switch(dwKeySpec)
+ {
+ case AT_ECDHE_P256 :
+ case AT_ECDHE_P384 :
+ case AT_ECDHE_P521 :
+ case AT_ECDSA_P256 :
+ case AT_ECDSA_P384 :
+ case AT_ECDSA_P521 :
+ Trace(WINEVENT_LEVEL_ERROR, L"dwKeySpec == %d", dwKeySpec);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ break;
+ case AT_KEYEXCHANGE:
+ case AT_SIGNATURE :
+ break;
+ default:
+ Trace(WINEVENT_LEVEL_ERROR, L"dwKeySpec == %d", dwKeySpec);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ break;
+ }
+
+ pKeySizes->dwMinimumBitlen = 1024;
+ pKeySizes->dwDefaultBitlen = 2048;
+ pKeySizes->dwMaximumBitlen = 2048;
+ pKeySizes->dwIncrementalBitlen = 0;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+
+/** The CardConstructDHAgreement function performs a secret agreement calculation
+for Diffie Hellman (DH) key exchange by using a private key that is present on the
+card. For RSA-only card minidrivers, this entry point is not defined and is set to
+NULL in the CARD_DATA structure that is returned from CardAcquireContext.
+The CARD_DH_AGREEMENT structure changes to allow for return of a handle to
+the agreed secret. This raises a point about how to index the DH agreement
+on the card in an opaque manner. Maintaining a map file is unnecessary because
+Ncrypt makes no provision for persistent DH agreements and there is no way to
+retrieve one after a provider is closed. DH agreements are addressable on card
+through an opaque BYTE that the card minidriver maintains. This BYTE should be
+associated with a handle to a card-side agreement.*/
+
+DWORD WINAPI CardConstructDHAgreement(
+ __in PCARD_DATA pCardData,
+ __inout PCARD_DH_AGREEMENT_INFO pSecretInfo
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The key derivation structure represents the majority of the required changes
+for FIPS 140-2 compliance for smart cards. It holds the requested key derivation
+function (KDF) and the associated input. The KDFs are defined in the CNG Reference
+documentation on MSDN. For RSA-only card minidrivers, this entry point is not defined
+and is set to NULL in the CARD_DATA structure that is returned from CardAcquireContext.*/
+
+DWORD WINAPI CardDeriveKey(
+ __in PCARD_DATA pCardData,
+ __inout PCARD_DERIVE_KEY pAgreementInfo
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardDestroyDHAgreement function removes an agreed secret from the card.
+For RSA-only card minidrivers, this entry point is not defined and is set to
+NULL in the CARD_DATA structure that was returned from CardAcquireContext.*/
+
+DWORD WINAPI CardDestroyDHAgreement(
+ __in PCARD_DATA pCardData,
+ __in BYTE bSecretAgreementIndex,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/CardInitializationAndDeconstruct.c
===================================================================
--- trunk/OpenPGPminidriver/CardInitializationAndDeconstruct.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardInitializationAndDeconstruct.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,176 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+
+// 4.1 Initialization and Deconstruct
+
+
+
+/** The CardAcquireContext function, defined by a smart card module,
+initializes communication between the smart card module and either the
+Microsoft Base Smart Card Cryptographic Service Provider (CSP) or smart
+card key storage provider (KSP).
+*/
+DWORD WINAPI CardAcquireContext(
+ __in PCARD_DATA pCardData,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ if ( dwFlags != 0 )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags != 0");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CreateContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE))
+ {
+ if (pCardData->hSCardCtx == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hSCardCtx == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pCardData->hScard == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hScard == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ // select the application on the card
+ dwReturn = SelectOpenPGPApplication(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+
+ /* CardInitializationAndDeconstruct.c */
+ pCardData->pfnCardDeleteContext = CardDeleteContext;
+
+ /* CardPinOperation.c */
+ pCardData->pfnCardAuthenticatePin = CardAuthenticatePin;
+ pCardData->pfnCardGetChallenge = CardGetChallenge;
+ pCardData->pfnCardAuthenticateChallenge = CardAuthenticateChallenge;
+ // CardDeauthenticate not implemented
+ pCardData->pfnCardDeauthenticate = CardDeauthenticate;
+ pCardData->pfnCardAuthenticateEx = CardAuthenticateEx;
+ pCardData->pfnCardGetChallengeEx = CardGetChallengeEx;
+ pCardData->pfnCardDeauthenticateEx = CardDeauthenticateEx;
+ pCardData->pfnCardChangeAuthenticatorEx = CardChangeAuthenticatorEx;
+ pCardData->pfnCardUnblockPin = CardUnblockPin;
+ pCardData->pfnCardChangeAuthenticator = CardChangeAuthenticator;
+
+ /* CardPublicDataOperation.c */
+ pCardData->pfnCardCreateDirectory = CardCreateDirectory;
+ pCardData->pfnCardDeleteDirectory = CardDeleteDirectory;
+ pCardData->pfnCardReadFile = CardReadFile;
+ pCardData->pfnCardCreateFile = CardCreateFile;
+ pCardData->pfnCardGetFileInfo = CardGetFileInfo;
+ pCardData->pfnCardWriteFile = CardWriteFile;
+ pCardData->pfnCardDeleteFile = CardDeleteFile;
+ pCardData->pfnCardEnumFiles = CardEnumFiles;
+ pCardData->pfnCardQueryFreeSpace = CardQueryFreeSpace;
+
+ /* CardCapabilities.c */
+ pCardData->pfnCardQueryCapabilities = CardQueryCapabilities;
+
+ /* CardAndContainerProperties.c */
+ pCardData->pfnCardGetContainerProperty = CardGetContainerProperty;
+ pCardData->pfnCardSetContainerProperty = CardSetContainerProperty;
+ pCardData->pfnCardGetProperty = CardGetProperty;
+ pCardData->pfnCardSetProperty = CardSetProperty;
+
+ /* CardKeyContainer.c */
+ pCardData->pfnCardCreateContainer = CardCreateContainer;
+ pCardData->pfnCardCreateContainerEx = CardCreateContainerEx;
+ pCardData->pfnCardDeleteContainer = CardDeleteContainer;
+ pCardData->pfnCardGetContainerInfo = CardGetContainerInfo;
+
+ /* CardCryptographicOperations.c */
+ pCardData->pfnCardRSADecrypt = CardRSADecrypt;
+ pCardData->pfnCardSignData = CardSignData;
+
+ // should be null for RSA only card
+ pCardData->pfnCardConstructDHAgreement = NULL; //CardConstructDHAgreement;
+ pCardData->pfnCardDeriveKey = NULL; //CardDeriveKey;
+ pCardData->pfnCardDestroyDHAgreement = NULL; //CardDestroyDHAgreement;
+
+ pCardData->pfnCardSignData = CardSignData;
+ pCardData->pfnCardQueryKeySizes = CardQueryKeySizes;
+
+ /* Not found :
+ The pfnCardDeriveKey, pfnCardDestroyDHAgreement, and pfnCspGetDHAgreement
+ members of the CARD_DATA structure are described in later sections.
+ Starting with Version 5 of this specification, the necessary modifications
+ to the pfnCardConstructDHAgreement function are handled through versioning
+ the structure that is associated with that function.
+ => what's the prototype for this function ?
+ */
+
+ pCardData->pfnCspGetDHAgreement = NULL;
+ }
+ __finally
+ {
+ if (dwReturn)
+ {
+ CleanContext(pCardData);
+ }
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardDeleteContext function reverses the effect of CardAcquireContext
+and severs the communication between the Base CSP/KSP and the card minidriver.
+This function also performs any needed deallocations and cleanup.
+*/
+
+DWORD WINAPI CardDeleteContext(
+ __inout PCARD_DATA pCardData
+ )
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ CleanContext(pCardData);
+ return 0;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/CardKeyContainer.c
===================================================================
--- trunk/OpenPGPminidriver/CardKeyContainer.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardKeyContainer.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,239 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "CryptoOperations.h"
+
+// 4.6 Key Container
+
+/** The CardCreateContainer function creates a new key container that is
+identified by the container index that the bContainerIndex argument specifies.
+For applications in which the card does not support on-card key generation or
+if it is desired to archive the keys, the key material can be supplied with
+the call by specifying in flags that the card is to import the supplied key material.*/
+
+DWORD WINAPI CardCreateContainer(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwFlags,
+ __in DWORD dwKeySpec,
+ __in DWORD dwKeySize,
+ __in PBYTE pbKeyData
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (bContainerIndex >= MaxContainer)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ __leave;
+ }
+ if (Containers[bContainerIndex].dwKeySpec != dwKeySpec)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwKeySpec == %d",dwKeySpec);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ dwReturn = CardCreateContainerEx(pCardData,
+ bContainerIndex,
+ dwFlags,
+ dwKeySpec,
+ dwKeySize,
+ pbKeyData,
+ Containers[bContainerIndex].PinId);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardCreateContainerEx function creates a new key container that the
+container index identifies and the bContainerIndex parameter specifies. The function
+associates the key container with the PIN that the PinId parameter specified.
+This function is useful if the card-edge does not allow for changing the key attributes
+after the key container is created. This function replaces the need to call
+CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer
+is called.
+The caller of this function can provide the key material that the card imports.
+This is useful in those situations in which the card either does not support internal
+key generation or the caller requests that the key be archived in the card.*/
+
+DWORD WINAPI CardCreateContainerEx(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwFlags,
+ __in DWORD dwKeySpec,
+ __in DWORD dwKeySize,
+ __in PBYTE pbKeyData,
+ __in PIN_ID PinId
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (bContainerIndex >= MaxContainer)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ __leave;
+ }
+ if (Containers[bContainerIndex].dwKeySpec != dwKeySpec)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwKeySpec == %d",dwKeySpec);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ if (Containers[bContainerIndex].PinId != PinId)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"PinId == %d",PinId);
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if ((dwFlags & CARD_CREATE_CONTAINER_KEY_GEN) == CARD_CREATE_CONTAINER_KEY_GEN )
+ {
+ dwReturn = SCardCreateKey(pCardData, bContainerIndex, dwKeySize);
+ }
+ else if ((dwFlags & CARD_CREATE_CONTAINER_KEY_IMPORT ) == CARD_CREATE_CONTAINER_KEY_IMPORT )
+ {
+ if (pbKeyData == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbKeyData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = SCardImportKey(pCardData, bContainerIndex, pbKeyData, dwKeySize);
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d",dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardDeleteContainer function deletes the key container specified by its index value.
+This is done by deleting all key material (public and private) that is associated with
+that index value.*/
+
+DWORD WINAPI CardDeleteContainer(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwReserved
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardGetContainerInfo function queries the specified key container for more
+information about which keys are present, such as its key specification (such as AT_ECDSA_P384).*/
+
+DWORD WINAPI CardGetContainerInfo(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in DWORD dwFlags,
+ __inout PCONTAINER_INFO pContainerInfo
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pContainerInfo == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pContainerInfo == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( dwFlags )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (bContainerIndex >= MaxContainer)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex);
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ pContainerInfo->pbSigPublicKey = NULL;
+ pContainerInfo->pbKeyExPublicKey = NULL;
+ pContainerInfo->cbSigPublicKey = 0;
+ pContainerInfo->cbKeyExPublicKey = 0;
+ switch(bContainerIndex)
+ {
+ case Signature:
+ case Authentication:
+ dwReturn = SCardReadPublicKey(pCardData, bContainerIndex,
+ &(pContainerInfo->pbSigPublicKey),&(pContainerInfo->cbSigPublicKey));
+ break;
+ case Confidentiality:
+ dwReturn = SCardReadPublicKey(pCardData, bContainerIndex,
+ &(pContainerInfo->pbKeyExPublicKey),&(pContainerInfo->cbKeyExPublicKey));
+ break;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
Added: trunk/OpenPGPminidriver/CardPinOperation.c
===================================================================
--- trunk/OpenPGPminidriver/CardPinOperation.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardPinOperation.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,607 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+#include "PinOperations.h"
+
+
+// 4.2 Card PIN Operations
+
+/** The CardAuthenticatePin function submits a PIN value as a string
+to the card to establish the users identity and to satisfy access
+conditions for an operation to be undertaken on the users behalf.
+Submission of a PIN to the card may involve some processing by the card
+minidriver to render the PIN information to a card-specific form. */
+
+DWORD WINAPI CardAuthenticatePin(
+ __in PCARD_DATA pCardData,
+ __in LPWSTR pwszUserId,
+ __in_bcount(cbPin) PBYTE pbPin,
+ __in DWORD cbPin,
+ __out_opt PDWORD pcAttemptsRemaining
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter authenticate %s", pwszUserId);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pwszUserId == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbPin == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbPin == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wcscmp(pwszUserId, wszCARD_USER_USER) == 0 )
+ {
+ dwReturn = CheckPinLength(pCardData, ROLE_USER, cbPin);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = VerifyPIN(pCardData, ROLE_USER, pbPin, cbPin);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData, ROLE_USER, pcAttemptsRemaining);
+ }
+ }
+ else if ( wcscmp(pwszUserId, wszCARD_USER_ADMIN) == 0)
+ {
+ dwReturn = CheckPinLength(pCardData, ROLE_ADMIN, cbPin);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = VerifyPIN(pCardData, ROLE_ADMIN, pbPin, cbPin);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData, ROLE_ADMIN, pcAttemptsRemaining);
+ }
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId unknown : %s", pwszUserId);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** A card principal can be authenticated by using either a PIN
+or a challenge/response protocol in which the card generates a block
+of challenge data by using its administrative key. The authenticating
+caller must compute the response to the challenge by using shared
+knowledge of that key and submit the response back to the card.
+If the response is correct, the principal is authenticated to the card. */
+
+DWORD WINAPI CardGetChallenge(
+ __in PCARD_DATA pCardData,
+ __deref_out_bcount(*pcbChallengeData) PBYTE *ppbChallengeData,
+ __out PDWORD pcbChallengeData
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardAuthenticateChallenge function performs authentication of
+a card principal by using a challenge/response protocol. The caller of
+this function must have previously called CardGetChallenge to retrieve
+the challenge data from the card and computed the correct response data
+to submit with this call. */
+
+DWORD WINAPI CardAuthenticateChallenge(
+ __in PCARD_DATA pCardData,
+ __in_bcount(cbResponseData) PBYTE pbResponseData,
+ __in DWORD cbResponseData,
+ __out_opt PDWORD pcAttemptsRemaining
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardDeauthenticate function is an optional export that should be
+provided if it is possible within the card minidriver to efficiently reverse
+the effect of authenticating a user or administrator without resetting
+the card. If this function is not implemented, the card minidriver should
+put NULL in the CARD_DATA structure pointer for this function.
+The Base CSP/KSP tests this pointer for NULL value before calling it. If it
+is found NULL, the Base CSP/KSP deauthenticates a user by resetting the
+card. Because a card reset is a time-consuming operation, the card minidriver
+should implement this function if it can be done.
+*/
+
+DWORD WINAPI CardDeauthenticate(
+ __in PCARD_DATA pCardData,
+ __in LPWSTR pwszUserId,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pwszUserId == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( dwFlags != 0 )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags != 0 : %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = Deauthenticate(pCardData);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardAuthenticateEx function handles PIN authentication operations to the card.
+This function replaces the CardAuthenticate function of earlier versions of these
+specifications and adds support for the following PIN types:
+ External PINs, which are PINs that are accessed from a device that is connected to the computer.
+ Challenge/response PINs.
+ Secure PIN channels.
+ Session PINs.
+*/
+DWORD WINAPI CardAuthenticateEx(
+ __in PCARD_DATA pCardData,
+ __in PIN_ID PinId,
+ __in DWORD dwFlags,
+ __in_bcount(cbPinData) PBYTE pbPinData,
+ __in DWORD cbPinData,
+ __deref_opt_out_bcount(*pcbSessionPin) PBYTE *ppbSessionPin,
+ __out_opt PDWORD pcbSessionPin,
+ __out_opt PDWORD pcAttemptsRemaining
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter authenticate %d", PinId);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbPinData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbPinData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ((dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN)
+ || (dwFlags & CARD_AUTHENTICATE_SESSION_PIN))
+ {
+ if ( ( ppbSessionPin == NULL ) ||
+ ( pcbSessionPin == NULL ) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"ppbSessionPin == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SESSION_PIN SCARD_E_UNSUPPORTED_FEATURE");
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ }
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckPinLength(pCardData, PinId, cbPinData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = VerifyPIN(pCardData, PinId, pbPinData, cbPinData);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData, PinId, pcAttemptsRemaining);
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** Besides authentication by using a PIN, a card principal can be authenticated
+by using a challenge/response protocol in which the card generates a block of challenge data.
+The authenticating caller must compute the response to the challenge by using
+shared knowledge of a key and submit the response back to the card by calling
+CardGetChallengeEx. If the response is correct, the principal is authenticated to the card.
+*/
+
+DWORD WINAPI CardGetChallengeEx(
+ __in PCARD_DATA pCardData,
+ __in PIN_ID PinId,
+ __deref_out_bcount(*pcbChallengeData) PBYTE *ppbChallengeData,
+ __out PDWORD pcbChallengeData,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardDeauthenticateEx function must always be provided. If it is not
+possible within the card minidriver to efficiently reverse the effect of an
+authentication operation without resetting the card, the call must return
+SCARD_E_UNSUPPORTED_FEATURE. In this situation, the Base CSP/KSP performs
+deauthentication by resetting the card. Because a card reset is a time-consuming
+operation, the card minidriver must implement this function if it can be done.*/
+
+DWORD WINAPI CardDeauthenticateEx(
+ __in PCARD_DATA pCardData,
+ __in PIN_SET PinId,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( dwFlags != 0 )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags != 0 : %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = Deauthenticate(pCardData);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardUnblockPin function is used to unblock a card that has become
+blocked by too many incorrect PIN entry attempts. The unblock function is
+atomic in that authentication and unblocking the card must occur as a single
+operation. Therefore, authentication information and the new user PIN must
+be presented when the call is made.*/
+
+DWORD WINAPI CardUnblockPin(
+ __in PCARD_DATA pCardData,
+ __in LPWSTR pwszUserId,
+ __in_bcount(cbAuthenticationData) PBYTE pbAuthenticationData,
+ __in DWORD cbAuthenticationData,
+ __in_bcount(cbNewPinData) PBYTE pbNewPinData,
+ __in DWORD cbNewPinData,
+ __in DWORD cRetryCount,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pwszUserId == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbAuthenticationData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbAuthenticationData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbNewPinData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbNewPinData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (!(dwFlags & CARD_AUTHENTICATE_PIN_PIN))
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags = 0x%08X", dwFlags);
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( !dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wcscmp(pwszUserId, wszCARD_USER_USER) == 0 )
+ {
+ dwReturn = ResetUserPIN(pCardData, ROLE_PUK,
+ pbAuthenticationData, cbAuthenticationData,
+ pbNewPinData, cbNewPinData);
+ }
+ else if ( wcscmp(pwszUserId, wszCARD_USER_ADMIN) == 0)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"wszCARD_USER_ADMIN");
+ __leave;
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId unknown : %s", pwszUserId);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** This function changes the authenticator for the affected card principal.
+It can be used to change a users PIN or to change the challenge/response key.
+The two usages are distinguished by use of a flag value.*/
+
+DWORD WINAPI CardChangeAuthenticator(
+ __in PCARD_DATA pCardData,
+ __in LPWSTR pwszUserId,
+ __in_bcount(cbCurrentAuthenticator)
+ PBYTE pbCurrentAuthenticator,
+ __in DWORD cbCurrentAuthenticator,
+ __in_bcount(cbNewAuthenticator) PBYTE pbNewAuthenticator,
+ __in DWORD cbNewAuthenticator,
+ __in DWORD cRetryCount,
+ __in DWORD dwFlags,
+ __out_opt PDWORD pcAttemptsRemaining
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pwszUserId == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbCurrentAuthenticator == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbCurrentAuthenticator == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbNewAuthenticator == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbNewAuthenticator == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (!(dwFlags & CARD_AUTHENTICATE_PIN_PIN))
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags = 0x%08X", dwFlags);
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( !dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( wcscmp(pwszUserId, wszCARD_USER_USER) == 0 )
+ {
+ dwReturn = ChangePIN(pCardData, ROLE_USER,
+ pbCurrentAuthenticator, cbCurrentAuthenticator,
+ pbNewAuthenticator, cbNewAuthenticator);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData, ROLE_USER, pcAttemptsRemaining);
+ }
+ }
+ else if ( wcscmp(pwszUserId, wszCARD_USER_ADMIN) == 0)
+ {
+ dwReturn = ChangePIN(pCardData, ROLE_ADMIN,
+ pbCurrentAuthenticator, cbCurrentAuthenticator,
+ pbNewAuthenticator, cbNewAuthenticator);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData,ROLE_ADMIN, pcAttemptsRemaining);
+ }
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pwszUserId unknown : %s", pwszUserId);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+
+/** This function changes the authenticator for the affected card principal.
+It can be used to change a PIN or unblock a PIN. The usages are distinguished
+by use of a flag value.*/
+
+DWORD WINAPI CardChangeAuthenticatorEx(
+ __in PCARD_DATA pCardData,
+ __in DWORD dwFlags,
+ __in PIN_ID dwAuthenticatingPinId,
+ __in_bcount(cbAuthenticatingPinData)
+ PBYTE pbAuthenticatingPinData,
+ __in DWORD cbAuthenticatingPinData,
+ __in PIN_ID dwTargetPinId,
+ __in_bcount(cbTargetData) PBYTE pbTargetData,
+ __in DWORD cbTargetData,
+ __in DWORD cRetryCount,
+ __out_opt PDWORD pcAttemptsRemaining
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbAuthenticatingPinData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbAuthenticatingPinData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbTargetData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbTargetData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (!(dwFlags & CARD_AUTHENTICATE_PIN_PIN))
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags = 0x%08X", dwFlags);
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if ( !dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"GetContext dwReturn == 0x%08X", dwReturn);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( dwAuthenticatingPinId == dwTargetPinId)
+ {
+ dwReturn = ChangePIN(pCardData, dwAuthenticatingPinId,
+ pbAuthenticatingPinData, cbAuthenticatingPinData,
+ pbTargetData, cbTargetData);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData, dwAuthenticatingPinId, pcAttemptsRemaining);
+ }
+ }
+ else if ( dwAuthenticatingPinId == ROLE_ADMIN && dwTargetPinId == ROLE_USER)
+ {
+ dwReturn = ResetUserPIN(pCardData, ROLE_ADMIN,
+ pbAuthenticatingPinData, cbAuthenticatingPinData,
+ pbTargetData, cbTargetData);
+ if (pcAttemptsRemaining)
+ {
+ GetRemainingPin(pCardData,dwTargetPinId, pcAttemptsRemaining);
+ }
+ }
+ else
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"unknown role match: %d %d", dwAuthenticatingPinId, dwTargetPinId);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
Added: trunk/OpenPGPminidriver/CardPublicDataOperation.c
===================================================================
--- trunk/OpenPGPminidriver/CardPublicDataOperation.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardPublicDataOperation.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,421 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "PublicDataOperations.h"
+
+// 4.3 Public Data Operations
+
+/** This function creates a subdirectory from the root in the file system of
+the card and applies the provided access condition. Directories are generally
+created for segregating the files that belong to a single application on the card.
+As an example, the files that belong to the Microsoft cryptographic application
+are in the mscp directory.*/
+
+DWORD WINAPI CardCreateDirectory(
+ __in PCARD_DATA pCardData,
+ __in LPSTR pszDirectoryName,
+ __in CARD_DIRECTORY_ACCESS_CONDITION AccessCondition
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** This function deletes a directory from the card. This operation fails if it violates
+permissions on the directory or if the directory is not empty. */
+DWORD WINAPI CardDeleteDirectory(
+ __in CARD_DATA *pCardData,
+ __in LPSTR pszDirectoryName
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardReadFile function reads the entire file at the specified location into the
+user-supplied buffer.*/
+DWORD WINAPI CardReadFile(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __in LPSTR pszFileName,
+ __in DWORD dwFlags,
+ __deref_out_bcount_opt(*pcbData) PBYTE *ppbData,
+ __out PDWORD pcbData
+)
+{
+ DWORD dwReturn = 0;
+ PSTR szFiles = NULL;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter %S\\%S",pszDirectoryName,pszFileName);
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pszFileName == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pszFileName == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (ppbData == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"ppbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pcbData == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pcbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags != 0)
+ {
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags = 0x%08X", dwFlags);
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardReadFile(pCardData, pszDirectoryName, pszFileName, ppbData, pcbData);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardCreateFile function creates a file on the card with a specified name and
+access permission. This function cannot be used to create directories. If the directory
+that is named by pszDirectoryName does not exist, the function fails with SCARD_E_DIR_NOT_FOUND.*/
+DWORD WINAPI CardCreateFile(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __in LPSTR pszFileName,
+ __in DWORD cbInitialCreationSize,
+ __in CARD_FILE_ACCESS_CONDITION AccessCondition
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pszFileName == NULL || pszFileName[0] == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pszFileName == NULL or empty");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardCreateFile(pCardData, pszDirectoryName, pszFileName);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** This function retrieves information about a file, specifically its size and ACL information.*/
+
+DWORD WINAPI CardGetFileInfo(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __in LPSTR pszFileName,
+ __inout PCARD_FILE_INFO pCardFileInfo
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pszFileName == NULL || pszFileName[0] == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pszFileName == NULL or empty");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pCardFileInfo == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardFileInfo == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardGetFileInfo(pCardData, pszDirectoryName, pszFileName, pCardFileInfo);
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardWriteFile function writes the entire contents of a data buffer to a file.
+The file contents are replaced, starting at the beginning of the file. The file must
+exist, or CardWriteFile fails.*/
+
+DWORD WINAPI CardWriteFile(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __in LPSTR pszFileName,
+ __in DWORD dwFlags,
+ __in_bcount(cbData) PBYTE pbData,
+ __in DWORD cbData
+)
+{
+ DWORD dwReturn = 0;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pszFileName == NULL || pszFileName[0] == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pszFileName == NULL or empty");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pbData == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pbData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( cbData == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"cbData == 0");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardWriteFile(pCardData, pszDirectoryName, pszFileName, pbData, cbData);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardDeleteFile function deletes the specified file. If the file does not exist,
+the returned Status value should indicate that the file did not exist.*/
+
+DWORD WINAPI CardDeleteFile(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __in LPSTR pszFileName,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+
+ PBYTE pbData = NULL;
+ DWORD dwSize = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pszFileName == NULL || pszFileName[0] == 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pszFileName == NULL or empty");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == 0");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ // try to read the file to see if it exists and return the right error code
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardDeleteFile(pCardData, pszDirectoryName, pszFileName);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardEnumFiles function returns name information about available files in a
+directory as a multistring list.*/
+
+DWORD WINAPI CardEnumFiles(
+ __in PCARD_DATA pCardData,
+ __in_opt LPSTR pszDirectoryName,
+ __deref_out_ecount(*pdwcbFileName) LPSTR *pmszFileNames,
+ __out LPDWORD pdwcbFileName,
+ __in DWORD dwFlags
+)
+{
+ DWORD dwReturn = 0;
+ PSTR szFiles = NULL;
+
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pmszFileNames == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pmszFileNames == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pmszFileNames == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pmszFileNames == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags != 0)
+ {
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags = 0x%08X", dwFlags);
+ __leave;
+ }
+ if (pszDirectoryName != NULL)
+ {
+ DWORD dwLen = (DWORD) strlen(pszDirectoryName);
+ if (dwLen > 8 || dwLen == 0)
+ {
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ Trace(WINEVENT_LEVEL_ERROR, L"Invalid directory %S", pszDirectoryName);
+ __leave;
+ }
+ }
+ dwReturn = CheckContext(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = SCardEnumFile(pCardData, pszDirectoryName, pmszFileNames, pdwcbFileName);
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+/** The CardQueryFreeSpace function determines the amount of available card storage space.*/
+DWORD WINAPI CardQueryFreeSpace(
+ __in PCARD_DATA pCardData,
+ __in DWORD dwFlags,
+ __inout PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo
+)
+{
+ DWORD dwReturn = 0;
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if ( pCardFreeSpaceInfo == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardFreeSpaceInfo == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (dwFlags)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == 0");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ pCardFreeSpaceInfo->dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION;
+ pCardFreeSpaceInfo->dwMaxKeyContainers = 3;
+ pCardFreeSpaceInfo->dwKeyContainersAvailable = CARD_DATA_VALUE_UNKNOWN;
+ pCardFreeSpaceInfo->dwBytesAvailable = CARD_DATA_VALUE_UNKNOWN;
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
Added: trunk/OpenPGPminidriver/CardSecureKeyInjection.c
===================================================================
--- trunk/OpenPGPminidriver/CardSecureKeyInjection.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CardSecureKeyInjection.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,163 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+
+// 4.8 Secure key injection
+
+
+/** The CardImportSessionKey function imports a temporary session key to the card.
+The session key is encrypted with a key exchange key, and the function returns a
+handle of the imported session key to the caller.*/
+
+DWORD WINAPI CardImportSessionKey(
+ __in PCARD_DATA pCardData,
+ __in BYTE bContainerIndex,
+ __in VOID *pPaddingInfo,
+ __in LPCWSTR pwszBlobType,
+ __in LPCWSTR pwszAlgId,
+ __out CARD_KEY_HANDLE *phKey,
+ __in_bcount(cbInput) PBYTE pbInput,
+ __in DWORD cbInput,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The MDImportSessionKey function imports a temporary session key to the card minidriver
+and returns a key handle to the caller.*/
+
+DWORD WINAPI MDImportSessionKey(
+ __in PCARD_DATA pCardData,
+ __in LPCWSTR pwszBlobType,
+ __in LPCWSTR pwszAlgId,
+ __out PCARD_KEY_HANDLE phKey,
+ __in_bcount(cbInput) PBYTE pbInput,
+ __in DWORD cbInput
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The MDEncryptData function uses a key handle to encrypt data with a symmetric key.
+The data is encrypted in a format that the smart card supports.*/
+
+DWORD WINAPI MDEncryptData(
+ __in PCARD_DATA pCardData,
+ __in CARD_KEY_HANDLE hKey,
+ __in LPCWSTR pwszSecureFunction,
+ __in_bcount(cbInput) PBYTE pbInput,
+ __in DWORD cbInput,
+ __in DWORD dwFlags,
+ __deref_out_ecount(*pcEncryptedData)
+ PCARD_ENCRYPTED_DATA *ppEncryptedData,
+ __out PDWORD pcEncryptedData
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+
+/** The CardGetSharedKeyHandle function returns a session key handle to the caller.
+Note: The manner in which this session key has been established is outside the
+scope of this specification. For example, the session key could be established
+by either a permanent shared key or a key derivation algorithm that has occurred
+before the call to CardGetSharedKeyHandle.*/
+
+DWORD WINAPI CardGetSharedKeyHandle(
+ __in PCARD_DATA pCardData,
+ __in_bcount(cbInput) PBYTE pbInput,
+ __in DWORD cbInput,
+ __deref_opt_out_bcount(*pcbOutput)
+ PBYTE *ppbOutput,
+ __out_opt PDWORD pcbOutput,
+ __out PCARD_KEY_HANDLE phKey
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** The CardDestroyKey function releases a temporary key on the card. The card
+should delete all of the key material that is associated with that key handle.*/
+
+DWORD WINAPI CardDestroyKey(
+ __in PCARD_DATA pCardData,
+ __in CARD_KEY_HANDLE hKey
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** This function can be used to get properties for a cryptographic algorithm.*/
+DWORD WINAPI CardGetAlgorithmProperty (
+ __in PCARD_DATA pCardData,
+ __in LPCWSTR pwszAlgId,
+ __in LPCWSTR pwszProperty,
+ __out_bcount_part_opt(cbData, *pdwDataLen)
+ PBYTE pbData,
+ __in DWORD cbData,
+ __out PDWORD pdwDataLen,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** This function is used to set the properties of a key.*/
+DWORD WINAPI CardSetKeyProperty(
+ __in PCARD_DATA pCardData,
+ __in CARD_KEY_HANDLE hKey,
+ __in LPCWSTR pwszProperty,
+ __in_bcount(cbInput) PBYTE pbInput,
+ __in DWORD cbInput,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+/** CardProcessEncryptedData processes a set of encrypted data BLOBs by
+sending them to the card where the data BLOBs are decrypted.*/
+
+DWORD WINAPI CardProcessEncryptedData(
+ __in PCARD_DATA pCardData,
+ __in CARD_KEY_HANDLE hKey,
+ __in LPCWSTR pwszSecureFunction,
+ __in_ecount(cEncryptedData)
+ PCARD_ENCRYPTED_DATA pEncryptedData,
+ __in DWORD cEncryptedData,
+ __out_bcount_part_opt(cbOutput, *pdwOutputLen)
+ PBYTE pbOutput,
+ __in DWORD cbOutput,
+ __out_opt PDWORD pdwOutputLen,
+ __in DWORD dwFlags
+)
+{
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
Added: trunk/OpenPGPminidriver/Context.h
===================================================================
--- trunk/OpenPGPminidriver/Context.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/Context.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,67 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+typedef struct _OPENPGP_AID
+{
+ BYTE AidRid[5];
+ BYTE AidApplication[1];
+ BYTE AidVersion[2];
+ BYTE AidManufacturer[2];
+ BYTE AidSerialNumber[4];
+ BYTE AidRFU[2];
+} OPENPGP_AID;
+
+#define FEATURE_VERIFY_PIN_START 0x01
+#define FEATURE_VERIFY_PIN_FINISH 0x02
+#define FEATURE_MODIFY_PIN_START 0x03
+#define FEATURE_MODIFY_PIN_FINISH 0x04
+#define FEATURE_GET_KEY_PRESSED 0x05
+#define FEATURE_VERIFY_PIN_DIRECT 0x06
+#define FEATURE_MODIFY_PIN_DIRECT 0x07
+#define FEATURE_MCT_READERDIRECT 0x08
+#define FEATURE_MCT_UNIVERSAL 0x09
+#define FEATURE_IFD_PIN_PROPERTIES 0x0A
+#define FEATURE_ABORT 0x0B
+
+typedef struct _FEATURES
+{
+ DWORD VERIFY_PIN_START;
+ DWORD VERIFY_PIN_FINISH;
+ DWORD VERIFY_PIN_DIRECT;
+ DWORD MODIFY_PIN_START;
+ DWORD MODIFY_PIN_FINISH;
+ DWORD MODIFY_PIN_DIRECT;
+ DWORD ABORT;
+ DWORD GET_KEY_PRESSED;
+} FEATURES, *PFEATURES;
+
+typedef struct _OPENPGP_CONTEXT
+{
+ OPENPGP_AID Aid;
+ FEATURES SmartCardReaderFeatures;
+ BOOL fSupportCommandChaining;
+ BOOL fExtentedLeLcFields;
+ DWORD dwMaxLength;
+ BOOL fHasSignature;
+ BOOL fHasDecryption;
+ BOOL fHasAuthentication;
+} OPENPGP_CONTEXT, *POPENPGP_CONTEXT ;
+
+DWORD CreateContext(__in PCARD_DATA pCardData);
+DWORD CheckContext(__in PCARD_DATA pCardData);
+DWORD CleanContext(__in PCARD_DATA pCardData);
\ No newline at end of file
Added: trunk/OpenPGPminidriver/ContextManagement.c
===================================================================
--- trunk/OpenPGPminidriver/ContextManagement.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/ContextManagement.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,291 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "Smartcard.h"
+#include "PublicDataOperations.h"
+
+SCARD_ATRMASK SupportedATR [] =
+{
+ { // v2
+ 21,
+ //3B DA 18 FF 81 B1 FE 75 1F 03 00 31 C5 73 C0 01 40 00 90 00 0C
+ {0x3B,0xDA,0x18,0xFF,0x81,0xB1,0xFE,0x75,0x1F,0x03,
+ 0x00,0x31,0xC5,0x73,0xC0,0x01,0x40,0x00,0x90,0x00,0x0C},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
+ },
+ { // v1
+ 20,
+ //3B FA 13 00 FF 81 31 80 45 00 31 C1 73 C0 01 00 00 90 00 B1
+ {0x3B,0xFA,0x13,0x00,0xFF,0x81,0x31,0x80,0x45,0x00,
+ 0x31,0xC1,0x73,0xC0,0x01,0x00,0x00,0x90,0x00,0xB1},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
+ }
+};
+DWORD dwSupportedATRCount = ARRAYSIZE(SupportedATR);
+
+BOOL find_compacttlv(__in PBYTE pbData, __in DWORD dwTotalSize, __in BYTE bCode, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize)
+{
+ DWORD dwOffset = 0;
+ DWORD dwSize;
+ while (dwOffset < dwTotalSize)
+ {
+ if (bCode * 0x10 == (pbData[dwOffset] & 0xF0) )
+ {
+ dwSize = (pbData[dwOffset] & 0x0F);
+ if (pdwSize)
+ {
+ *pdwSize = dwSize;
+ }
+ dwOffset++;
+ // size sequence
+
+ *pbDataOut = pbData + dwOffset;
+ return TRUE;
+ }
+ else
+ {
+
+ dwSize = (pbData[dwOffset] & 0x0F);
+ dwOffset += dwSize + 1;
+ }
+ }
+ return FALSE;
+}
+
+
+DWORD CreateContext(__in PCARD_DATA pCardData)
+{
+ DWORD dwReturn;
+ PBYTE pbCapabilities = NULL, pbCardCapabilities;
+ PBYTE pbExtendedCapabilities = NULL;
+ PBYTE pbApplicationIdentifier = NULL;
+ DWORD dwCapabilitiesSize,
+ dwCardCapabilitiesSize,
+ dwApplicationIdentifierSize;
+ BYTE bCategoryIndicator, bStatusIndicator;
+ __try
+ {
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ if (pContext)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pContext != NULL");
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ // not found => initialize context
+ pContext = pCardData->pfnCspAlloc(sizeof(OPENPGP_CONTEXT));
+ if (!pContext)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
+ dwReturn = SCARD_E_NO_MEMORY;
+ __leave;
+ }
+ memset(pContext, 0, sizeof(OPENPGP_CONTEXT));
+ pCardData->pvVendorSpecific = pContext;
+
+ dwReturn = SelectOpenPGPApplication(pCardData);
+ if (dwReturn)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"No SelectOpenPGPApplication");
+ __leave;
+ }
+ dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if (dwApplicationIdentifierSize != sizeof(OPENPGP_AID))
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwApplicationIdentifierSize = %02X", dwApplicationIdentifierSize);
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ memcpy(&(pContext->Aid),pbApplicationIdentifier,sizeof(OPENPGP_AID));
+ dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ bCategoryIndicator = pbCapabilities[0];
+ if (bCategoryIndicator != 0)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bCategoryIndicator = %02X", bCategoryIndicator);
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ bStatusIndicator = pbCapabilities[dwCapabilitiesSize -3];
+ if (bStatusIndicator != 0 && bStatusIndicator != 03 && bStatusIndicator != 05)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"bStatusIndicator = %02X", bStatusIndicator);
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ if (!find_compacttlv(pbCapabilities + 1, dwCapabilitiesSize - 1, 7, &pbCardCapabilities, &dwCardCapabilitiesSize))
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"tlv not found");
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ if (dwCardCapabilitiesSize != 3)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"dwCardCapabilitiesSize = %02X", dwCardCapabilitiesSize);
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ //dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
+ if (dwReturn)
+ {
+ //__leave;
+ }
+ pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
+ pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
+ pContext->dwMaxLength = 0x0800;// pbCapabilities[8] * 256 + pbCapabilities[9];
+ dwReturn = CCIDgetFeatures(pCardData);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = 0;
+ }
+ __finally
+ {
+ if (pbApplicationIdentifier)
+ pCardData->pfnCspFree(pbApplicationIdentifier);
+ if (pbCapabilities)
+ pCardData->pfnCspFree(pbCapabilities);
+ if (pbExtendedCapabilities)
+ pCardData->pfnCspFree(pbExtendedCapabilities);
+ }
+ return dwReturn;
+}
+
+
+DWORD CheckContext(__in PCARD_DATA pCardData)
+{
+ DWORD dwReturn;
+ DWORD dwI, dwJ;
+ BOOL fFound = FALSE;
+ BOOL fRightATRLenFound = FALSE;
+ __try
+ {
+ if ( pCardData == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pCardData->pbAtr == NULL)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pbAtr == NULL");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ if (pCardData->dwVersion < CARD_DATA_VERSION_SIX)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData->dwVersion(%d) < CARD_DATA_VERSION_SIX", pCardData->dwVersion);
+ dwReturn = ERROR_REVISION_MISMATCH;
+ __leave;
+ }
+ pCardData->dwVersion = min(pCardData->dwVersion, CARD_DATA_VERSION_SIX);
+ for (dwI = 0; dwI < dwSupportedATRCount; dwI++)
+ {
+ if (SupportedATR[dwI].cbAtr == pCardData->cbAtr)
+ {
+ BYTE pbAtr[36];
+ fRightATRLenFound = TRUE;
+ memcpy(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr);
+ for( dwJ = 0; dwJ < SupportedATR[dwI].cbAtr; dwJ++)
+ {
+ pbAtr[dwJ] &= SupportedATR[dwI].rgbMask[dwJ];
+ }
+ if (memcmp(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr) == 0)
+ {
+ fFound = TRUE;
+ //Trace(WINEVENT_LEVEL_VERBOSE, L"card match ATR %d", dwI);
+ break;
+ }
+
+ }
+ }
+ if (!fRightATRLenFound)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR len %d",pCardData->cbAtr);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (!fFound)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR");
+ dwReturn = SCARD_E_UNKNOWN_CARD;
+ __leave;
+ }
+
+ if ( pCardData->pwszCardName == NULL )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pwszCardName");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ /* Memory management functions */
+ if ( ( pCardData->pfnCspAlloc == NULL ) ||
+ ( pCardData->pfnCspReAlloc == NULL ) ||
+ ( pCardData->pfnCspFree == NULL ) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"Memory functions null");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (!pCardData->pvVendorSpecific)
+ {
+ // not found =>
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD CleanContext(__in PCARD_DATA pCardData)
+{
+ DWORD dwReturn = 0;
+ __try
+ {
+ if (pCardData)
+ {
+ if ( pCardData->pvVendorSpecific)
+ {
+ pCardData->pfnCspFree( pCardData->pvVendorSpecific);
+ pCardData->pvVendorSpecific = NULL;
+ }
+ }
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/CryptoOperations.c
===================================================================
--- trunk/OpenPGPminidriver/CryptoOperations.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CryptoOperations.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,779 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+#include "CryptoOperations.h"
+#include "PinOperations.h"
+#include "PublicDataOperations.h"
+
+OPENPGP_CONTAINER_INFO Containers[] =
+{
+ {0xB6, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE},
+ {0xA4, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION},
+ {0xB8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY}
+
+};
+
+typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
+{
+ ALG_ID aiHashAlg;
+ DWORD dwHashSize;
+ PBYTE pbEncodedOid;
+ DWORD dwEncodedOidSize;
+} OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM, *POPENPGP_SUPPORTED_SIGNATURE_ALGORITHM;
+
+BYTE dwSHA1EncodedOid[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
+BYTE dwSHA256EncodedOid[] = {0x30, 0x31, 0x30, 0x0D,0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+ 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
+BYTE dwSHA384EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+ 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
+BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+ 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
+
+OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
+{
+ {CALG_SHA1,20,
+ dwSHA1EncodedOid,
+ ARRAYSIZE(dwSHA1EncodedOid)},
+ {CALG_SHA-256,32,
+ dwSHA256EncodedOid,
+ ARRAYSIZE(dwSHA256EncodedOid)},
+ {CALG_SHA-384,48,
+ dwSHA384EncodedOid,
+ ARRAYSIZE(dwSHA384EncodedOid)},
+ {CALG_SHA-512,64,
+ dwSHA512EncodedOid,
+ ARRAYSIZE(dwSHA512EncodedOid)},
+};
+
+DWORD dwSignatureAlgorithmCount = ARRAYSIZE(SignatureAlgorithm);
+
+#pragma pack(push,1)
+typedef struct _OPENPGP_ALGORITHM_ATTRIBUTE
+{
+ BYTE bAlgoId;
+ unsigned short wModulusLength;
+ unsigned short wExponentLength;
+ BYTE bFormat;
+} OPENPGP_ALGORITHM_ATTRIBUTE, *POPENPGP_ALGORITHM_ATTRIBUTE;
+#pragma pack(pop)
+
+typedef struct _RSAPUBLICKEYBLOB
+{
+ BLOBHEADER blobheader;
+ RSAPUBKEY rsapubkey;
+ BYTE modulus[sizeof(DWORD)];
+} RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB;
+
+DWORD getTlvSize(__in PBYTE pbPointer, __in PDWORD pdwOffset)
+{
+ DWORD dwSize;
+ switch(*pbPointer)
+ {
+ case 0x81:
+ *pdwOffset+=2;
+ dwSize = pbPointer[1];
+ break;
+ case 0x82:
+ *pdwOffset+=3;
+ dwSize = pbPointer[1] * 0x100 + pbPointer[2];
+ break;
+ default:
+ dwSize = *pbPointer;
+ *pdwOffset+=1;
+ break;
+ }
+ return dwSize;
+}
+
+BOOL find_tlv(__in PBYTE pbData, __in BYTE bCode, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize)
+{
+ DWORD dwOffset = 2;
+ DWORD dwSize;
+ DWORD dwTotalSize = getTlvSize(pbData + 2,&dwOffset) + 2;
+ while (dwOffset < dwTotalSize)
+ {
+ if (bCode == pbData[dwOffset])
+ {
+ dwOffset++;
+ // size sequence
+ dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
+ if (pdwSize)
+ {
+ *pdwSize = dwSize;
+ }
+ *pbDataOut = pbData + dwOffset;
+ return TRUE;
+ }
+ else
+ {
+ dwOffset++;
+ dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
+ dwOffset += dwSize;
+ }
+ }
+ return FALSE;
+}
+
+
+DWORD GetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
+ __in OPENPGP_CONTAINER dwContainer,
+ __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
+{
+ DWORD dwReturn;
+ PSTR szAlgorithmAttributes = NULL;
+ PBYTE pbData = NULL;
+ DWORD dwResponseSize;
+ WORD wTemp;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
+ switch(dwContainer)
+ {
+ case Signature:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
+ break;
+ case Authentication:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
+ break;
+ case Confidentiality:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
+ break;
+ default:
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
+ __leave;
+ }
+ dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, &pbData, &dwResponseSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if (dwResponseSize != sizeof(OPENPGP_ALGORITHM_ATTRIBUTE))
+ {
+ dwReturn = SCARD_E_UNEXPECTED;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED");
+ __leave;
+ }
+ memcpy(pAttributes, pbData, dwResponseSize);
+ // big endian, little endian ...
+ wTemp = pAttributes->wExponentLength;
+ pAttributes->wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
+ wTemp = pAttributes->wModulusLength;
+ pAttributes->wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
+
+ dwReturn = 0;
+ }
+ __finally
+ {
+ if (pbData)
+ pCardData->pfnCspFree(pbData);
+ }
+ return dwReturn;
+}
+
+DWORD SetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
+ __in OPENPGP_CONTAINER dwContainer,
+ __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
+{
+ DWORD dwReturn;
+ PSTR szAlgorithmAttributes = NULL;
+ OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
+ WORD wTemp;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
+ switch(dwContainer)
+ {
+ case Signature:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
+ break;
+ case Authentication:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
+ break;
+ case Confidentiality:
+ szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
+ break;
+ default:
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
+ __leave;
+ }
+ memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
+ wTemp = TempAttributes.wExponentLength;
+ TempAttributes.wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
+ wTemp = TempAttributes.wModulusLength;
+ TempAttributes.wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
+
+ dwReturn = SCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
+ if (dwReturn)
+ {
+ __leave;
+ }
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
+ __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
+{
+ DWORD dwReturn;
+ __try
+ {
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
+{
+ DWORD dwReturn;
+ PBYTE pbData = NULL;
+ DWORD dwResponseSize = 0;
+ BYTE pbCmd[] = {0x00,
+ 0x47,
+ 0x81,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ DWORD dwCmdSize;
+ POPENPGP_CONTEXT pContext;
+ PBYTE pbModulus;
+ DWORD dwModulusSize;
+ PBYTE pbExponent;
+ PRSAPUBLICKEYBLOB pbBlob = NULL;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
+ if (dwContainer >= MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
+ __leave;
+ }
+ pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ pbCmd[7] = Containers[dwContainer].Tag;
+ dwCmdSize = 9;
+ if (pContext->fExtentedLeLcFields)
+ {
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = 0xFF;
+ }
+
+ dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ //TraceDump(WINEVENT_LEVEL_INFO, pbData,dwSize);
+ if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
+ {
+ dwReturn = SCARD_E_UNEXPECTED;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
+ __leave;
+ }
+ if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
+ {
+ dwReturn = SCARD_E_UNEXPECTED;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
+ __leave;
+ }
+ *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
+ *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
+ if (!*pbPublicKey)
+ {
+ dwReturn = SCARD_E_NO_MEMORY;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY %d", dwContainer);
+ __leave;
+ }
+ pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
+ memset(pbBlob,0,*pdwPublicKeySize);
+ pbBlob->blobheader.bType = PUBLICKEYBLOB;
+ pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
+ pbBlob->blobheader.reserved = 0;
+ pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].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];
+ memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
+ //TraceDump(WINEVENT_LEVEL_INFO, (PBYTE) pbBlob,*pdwPublicKeySize);
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
+{
+ DWORD dwReturn;
+ PBYTE pbData = NULL;
+ DWORD dwResponseSize = 0, dwCmdSize;
+ OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
+ POPENPGP_CONTEXT pContext;
+ BYTE pbCmd[] = {0x00,
+ 0x47,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
+ if (dwContainer >= MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
+ __leave;
+ }
+ // key len
+ dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
+ if (dwReturn == SCARD_E_FILE_NOT_FOUND)
+ {
+ Attributes.bAlgoId = 0x01;
+ Attributes.bFormat = 0;
+ Attributes.wExponentLength = 0x20;
+ }
+ else if (dwReturn)
+ {
+ __leave;
+ }
+ Attributes.wModulusLength = (WORD) dwBitLen;
+ dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
+ if (dwReturn)
+ {
+ __leave;
+ }
+
+ pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ pbCmd[7] = Containers[dwContainer].Tag;
+ dwCmdSize = 9;
+ if (pContext->fExtentedLeLcFields)
+ {
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = 0xFF;
+ }
+
+ dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ __finally
+ {
+ if (pbData)
+ pCardData->pfnCspFree(pbData);
+ }
+ return dwReturn;
+}
+
+DWORD SCardImportKey(PCARD_DATA pCardData,
+ OPENPGP_CONTAINER dwContainer,
+ PBYTE pBlob,
+ DWORD dwKeySize)
+{
+ DWORD dwReturn;
+ PSTR szAlgorithmAttributes = NULL;
+ PBYTE pbData = NULL;
+ DWORD dwResponseSize;
+ OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
+ PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
+ // check blob
+ if (pbPublicKeyBlob->blobheader.aiKeyAlg != Containers[dwContainer].aiKeyAlg)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pbPublicKeyBlob->blobheader.bType != PUBLICKEYBLOB)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+
+ dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
+ if (dwReturn == SCARD_E_FILE_NOT_FOUND)
+ {
+ Attributes.bAlgoId = 0x01;
+ Attributes.bFormat = 0;
+ Attributes.wExponentLength = 0x20;
+ }
+ else if (dwReturn)
+ {
+ __leave;
+ }
+ Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
+ dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ __finally
+ {
+ if (dwReturn)
+ {
+
+ }
+ }
+ return dwReturn;
+}
+
+DWORD SCardSign(PCARD_DATA pCardData,
+ PCARD_SIGNING_INFO pInfo)
+{
+ DWORD dwReturn;
+ PBYTE pbData = NULL;
+ DWORD dwCmdSize = 0, dwI;
+ POPENPGP_CONTEXT pContext;
+ BYTE pbCmd[6 + 256 + 256] = {0x00,
+ 0x2A,
+ 0x9E,
+ 0x9A,
+ 0x00,
+ 0x00,
+ };
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
+ if (pInfo->bContainerIndex >= MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ if (pInfo->bContainerIndex != Signature)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
+ __leave;
+ }
+ else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
+ __leave;
+ }
+ for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
+ {
+ if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
+ {
+ // found
+ break;
+ }
+ }
+ if (dwI >= dwSignatureAlgorithmCount)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
+ __leave;
+ }
+ if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
+ __leave;
+ }
+ pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+
+ dwCmdSize = 5;
+ if (pContext->fExtentedLeLcFields)
+ {
+ dwCmdSize++;
+ }
+ pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
+ memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
+ dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
+ for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
+ {
+ pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
+ }
+ //memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
+ dwCmdSize += pInfo->cbData;
+
+
+ if (pContext->fExtentedLeLcFields)
+ {
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = 0;
+ }
+ dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
+ if (dwReturn == SCARD_W_WRONG_CHV)
+ {
+ dwReturn = SCARD_W_SECURITY_VIOLATION;
+ __leave;
+ }
+ if (dwReturn)
+ {
+ __leave;
+ }
+ // revert the BYTES
+ for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
+ {
+ BYTE bTemp = pInfo->pbSignedData[dwI];
+ pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
+ pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
+ }
+ TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData);
+ }
+ __finally
+ {
+ if (dwReturn)
+ {
+ if (pInfo->pbSignedData)
+ pCardData->pfnCspFree(pInfo->pbSignedData);
+ }
+ }
+ return dwReturn;
+}
+
+DWORD SCardDecrypt(PCARD_DATA pCardData,
+ PCARD_RSA_DECRYPT_INFO pInfo)
+{
+ DWORD dwReturn;
+ PBYTE pbData = NULL;
+ DWORD dwCmdSize = 0, dwResponseSize;
+ BYTE pbCmd[6 + 256 + 256] = {0x00,
+ 0x2A,
+ 0x80,
+ 0x86,
+ 0x00,
+ };
+ POPENPGP_CONTEXT pContext;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
+ if (pInfo->bContainerIndex >= MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ if (pInfo->bContainerIndex != Confidentiality)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ dwCmdSize = 5;
+ if (pContext->fExtentedLeLcFields)
+ {
+ pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
+ pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
+ }
+ pbCmd[dwCmdSize++] = 0;
+ memcpy(pbCmd + dwCmdSize, pInfo->pbData, pInfo->cbData);
+ dwCmdSize += pInfo->cbData;
+ if (pContext->fExtentedLeLcFields)
+ {
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
+ pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
+ }
+ else
+ {
+ pbCmd[dwCmdSize++] = 0;
+ }
+ dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ if ( pInfo->cbData < dwResponseSize)
+ {
+ dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
+ __leave;
+ }
+ pInfo->cbData = dwResponseSize;
+ memcpy( pInfo->pbData, pbData, dwResponseSize);
+ }
+ __finally
+ {
+ if (pbData)
+ pCardData->pfnCspFree(pbData);
+ }
+ return dwReturn;
+}
+
+DWORD SCardAuthenticate(PCARD_DATA pCardData,
+ PCARD_SIGNING_INFO pInfo)
+{
+ DWORD dwReturn;
+ PBYTE pbData = NULL;
+ DWORD dwSize = 0, dwI;
+ BYTE pbCmd[6 + 256 + 256] = {0x00,
+ 0x88,
+ 0x00,
+ 0x00,
+ 0x00,
+ };
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
+ if (pInfo->bContainerIndex >= MaxContainer)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ if (pInfo->bContainerIndex != Authentication)
+ {
+ dwReturn = SCARD_E_NO_KEY_CONTAINER;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
+ __leave;
+ }
+ if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
+ __leave;
+ }
+ else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
+ {
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
+ __leave;
+ }
+ for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
+ {
+ if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
+ {
+ // found
+ break;
+ }
+ }
+ if (dwI >= dwSignatureAlgorithmCount)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
+ __leave;
+ }
+ if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
+ __leave;
+ }
+ memcpy(pbCmd +5, SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
+ memcpy(pbCmd +5 + SignatureAlgorithm[dwI].dwEncodedOidSize, pInfo->pbData,pInfo->cbData);
+
+ dwReturn = SCardGetData(pCardData, pbCmd, ARRAYSIZE(pbCmd), &(pInfo->pbSignedData), &(pInfo->cbSignedData));
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
+{
+ DWORD dwReturn=0;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
+ switch(dwPinIndex)
+ {
+ case ROLE_SIGNATURE:
+ pPinInfo->PinType = AlphaNumericPinType;
+ pPinInfo->PinPurpose = DigitalSignaturePin;
+ pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
+ pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
+ pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
+ break;
+ case ROLE_AUTHENTICATION:
+ pPinInfo->PinType = AlphaNumericPinType;
+ pPinInfo->PinPurpose = AuthenticationPin;
+ pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
+ pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
+ pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
+ break;
+ case ROLE_CONFIDENTIALITY:
+ pPinInfo->PinType = AlphaNumericPinType;
+ pPinInfo->PinPurpose = EncryptionPin;
+ pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
+ pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
+ pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
+ break;
+ default:
+ Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
+ dwReturn = SCARD_E_INVALID_PARAMETER ;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/CryptoOperations.h
===================================================================
--- trunk/OpenPGPminidriver/CryptoOperations.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/CryptoOperations.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,59 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+typedef enum _OPENPGP_CONTAINER
+{
+ Signature,
+ Authentication,
+ Confidentiality,
+ MaxContainer
+} OPENPGP_CONTAINER;
+
+typedef struct _OPENPGP_CONTAINER_INFO
+{
+ BYTE Tag;
+ ALG_ID aiKeyAlg;
+ DWORD dwKeySpec;
+ PIN_ID PinId;
+} OPENPGP_CONTAINER_INFO, *POPENPGP_CONTAINER_INFO;
+
+extern OPENPGP_CONTAINER_INFO Containers[];
+
+#define OPENPGP_SUPPORTED_CYPHER_ALGORITHM L"\0"
+#define OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM L"RSA\0"
+
+DWORD SCardReadPublicKey(PCARD_DATA pCardData,
+ OPENPGP_CONTAINER dwContainer,
+ PBYTE *pbPublicKey, PDWORD pdwPublicKeySize);
+
+DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen);
+
+DWORD SCardImportKey(PCARD_DATA pCardData,
+ OPENPGP_CONTAINER dwContainer,
+ PBYTE pBlob,
+ DWORD dwKeySize);
+
+DWORD SCardSign(PCARD_DATA pCardData,
+ PCARD_SIGNING_INFO pInfo);
+
+DWORD SCardDecrypt(PCARD_DATA pCardData,
+ PCARD_RSA_DECRYPT_INFO pInfo);
+
+DWORD SCardAuthenticate(PCARD_DATA pCardData,
+ PCARD_SIGNING_INFO pInfo);
+
+DWORD GetPinInfo(DWORD __in bContainerIndex, __inout PPIN_INFO pPinInfo);
\ No newline at end of file
Added: trunk/OpenPGPminidriver/DllMain.c
===================================================================
--- trunk/OpenPGPminidriver/DllMain.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/DllMain.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,40 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+
+
+/** This function provides handling for load/unload and attach/detach notifications
+to allow the DLL to manage its state and allocated resources. For more information,
+see DllMain Callback Function on MSDN®.
+
+return TRUE on DLL_PROCESS_ATTACH if initialization of the DLL was successful;
+otherwise, FALSE. Value ignored at other times by caller. */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,
+ DWORD dwReason,
+ LPVOID lpReserved)
+{
+ // Perform actions based on the reason for calling.
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/OpenPGPminidriver.def
===================================================================
--- trunk/OpenPGPminidriver/OpenPGPminidriver.def 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/OpenPGPminidriver.def 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,6 @@
+LIBRARY
+
+EXPORTS
+CardAcquireContext
+EnableLogging
+DisableLogging
\ No newline at end of file
Added: trunk/OpenPGPminidriver/OpenPGPminidriver.vcproj
===================================================================
--- trunk/OpenPGPminidriver/OpenPGPminidriver.vcproj 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/OpenPGPminidriver.vcproj 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="OpenPGPminidriver"
+ ProjectGUID="{775DAB1D-5A49-4A57-B259-AD3DC833A75F}"
+ RootNamespace="OpenPGPminidriver"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\openpgpmdrv32.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile="OpenPGPminidriver.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\openpgpmdrv64.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile="OpenPGPminidriver.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\openpgpmdrv32.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile="OpenPGPminidriver.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\openpgpmdrv64.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile="OpenPGPminidriver.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="3) Microsoft Interface"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\CardAndContainerProperties.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardCryptographicOperations.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardInitializationAndDeconstruct.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardKeyContainer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardPinOperation.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardPublicDataOperation.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CardSecureKeyInjection.c"
+ >
+ </File>
+ <File
+ RelativePath=".\DllMain.c"
+ >
+ </File>
+ <File
+ RelativePath=".\Tracing.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Context.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CryptoOperations.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PinOperations.h"
+ >
+ </File>
+ <File
+ RelativePath=".\PublicDataOperations.h"
+ >
+ </File>
+ <File
+ RelativePath=".\SmartCard.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Tracing.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="1) Low level"
+ >
+ <File
+ RelativePath=".\SmartCard.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resources Files"
+ >
+ <File
+ RelativePath=".\driver.inf"
+ >
+ </File>
+ <File
+ RelativePath=".\OpenPGPminidriver.def"
+ >
+ </File>
+ <File
+ RelativePath=".\version.rc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="2) Application"
+ >
+ <File
+ RelativePath=".\ContextManagement.c"
+ >
+ </File>
+ <File
+ RelativePath=".\CryptoOperations.c"
+ >
+ </File>
+ <File
+ RelativePath=".\PinOperations.c"
+ >
+ </File>
+ <File
+ RelativePath=".\PublicDataOperations.c"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\README.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: trunk/OpenPGPminidriver/PinOperations.c
===================================================================
--- trunk/OpenPGPminidriver/PinOperations.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/PinOperations.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,321 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+#include "PublicDataOperations.h"
+#include "PinOperations.h"
+
+
+DWORD CheckPinLength(__in PCARD_DATA pCardData, __in PIN_ID PinId, __in DWORD cbPin)
+{
+ DWORD dwReturn;
+ PBYTE pbResponse = NULL;
+ DWORD dwMinPinSize = 0, dwMaxPinSize;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
+ // check min Pin length
+ // (hard coded in specication)
+ switch(PinId)
+ {
+ case ROLE_SIGNATURE:
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ dwMinPinSize = 6;
+ case ROLE_PUK:
+ break;
+ case ROLE_ADMIN:
+ dwMinPinSize = 8;
+ break;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (cbPin < dwMinPinSize)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d minPinSize = %d",PinId, cbPin, dwMinPinSize);
+ dwReturn = SCARD_W_WRONG_CHV;
+ __leave;
+ }
+ // check in status DO
+ dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, NULL);
+ switch(PinId)
+ {
+ case ROLE_SIGNATURE:
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ dwMaxPinSize = pbResponse[1];
+ break;
+ case ROLE_PUK:
+ dwMaxPinSize = pbResponse[2];
+ break;
+ case ROLE_ADMIN:
+ dwMaxPinSize = pbResponse[3];
+ break;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ if (cbPin > dwMaxPinSize)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d dwMaxPinSize = %d", PinId, cbPin, dwMaxPinSize);
+ dwReturn = SCARD_W_WRONG_CHV;
+ __leave;
+ }
+ dwReturn = 0;
+ }
+ __finally
+ {
+ if (pbResponse)
+ pCardData->pfnCspFree(pbResponse);
+ }
+ return dwReturn;
+}
+
+DWORD GetRemainingPin(__in PCARD_DATA pCardData, __in PIN_ID PinId, __out PDWORD pdwCounter)
+{
+ DWORD dwReturn;
+ PBYTE pbResponse = NULL;
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
+ dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, NULL);
+ switch(PinId)
+ {
+ case ROLE_SIGNATURE:
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ *pdwCounter = pbResponse[4];
+ break;
+ case ROLE_PUK:
+ *pdwCounter = pbResponse[5];
+ break;
+ case ROLE_ADMIN:
+ *pdwCounter = pbResponse[6];
+ break;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ }
+ __finally
+ {
+ if (pbResponse)
+ pCardData->pfnCspFree(pbResponse);
+ }
+ return dwReturn;
+}
+
+DWORD VerifyPIN(__in PCARD_DATA pCardData,__in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin)
+{
+ DWORD dwReturn;
+ // 256 because the size of the PIN must fit in a Byte
+ BYTE pbCmd[256 + 5] = {0x00,
+ 0x20,
+ 0x00,
+ 0x82,
+ 0x00
+ };
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
+ switch(PinId)
+ {
+ case ROLE_SIGNATURE:
+ pbCmd[3] = 0x81;
+ break;
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ pbCmd[3] = 0x82;
+ break;
+ case ROLE_ADMIN:
+ pbCmd[3] = 0x83;
+ break;
+ case ROLE_PUK:
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ pbCmd[4] = (BYTE) cbPin;
+ memcpy(pbCmd + 5, pbPin, cbPin);
+ dwReturn = SCardSendCommand(pCardData, pbCmd, 5 + cbPin);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ switch(PinId)
+ {
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ dwReturn = VerifyPIN(pCardData, ROLE_SIGNATURE, pbPin, cbPin);
+ break;
+ }
+
+ }
+ __finally
+ {
+ SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
+ }
+
+ return dwReturn;
+}
+
+DWORD ChangePIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbOldPin, __in DWORD cbOldPin,
+ __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
+ )
+{
+ DWORD dwReturn;
+ // 256 because the size of the PIN must fit in a Byte
+ BYTE pbCmd[256 + 256 + 6] = {0x00,
+ 0x24,
+ 0x00,
+ 0x81,
+ 0x00
+ };
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
+ dwReturn = CheckPinLength(pCardData, PinId, cbOldPin);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ switch(PinId)
+ {
+ case ROLE_SIGNATURE:
+ case ROLE_AUTHENTICATION:
+ case ROLE_CONFIDENTIALITY:
+ pbCmd[3] = 0x81;
+ break;
+ case ROLE_ADMIN:
+ pbCmd[3] = 0x83;
+ break;
+ case ROLE_PUK:
+ dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
+ __leave;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ pbCmd[4] = (BYTE) (cbOldPin + cbNewPin);
+ memcpy(pbCmd + 5, pbOldPin, cbOldPin);
+ memcpy(pbCmd + 5 + cbOldPin, pbNewPin, cbNewPin);
+ dwReturn = SCardSendCommand(pCardData, pbCmd, 5 + cbOldPin + cbNewPin);
+ }
+ __finally
+ {
+ SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
+ }
+ return dwReturn;
+}
+
+/** only the user PIN can be reseted => target is implicit*/
+DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator,
+ __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
+ )
+{
+ DWORD dwReturn;
+ BYTE pbCmd[256 + 5] = {0x00,
+ 0x2C,
+ 0x02,
+ 0x81,
+ 0x00
+ };
+ DWORD dwCmdSize;
+
+ __try
+ {
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
+ switch(PinId)
+ {
+ case ROLE_ADMIN:
+ // authenticate the admin
+ dwReturn = VerifyPIN(pCardData, PinId, pbAuthenticator, cbAuthenticator);
+ if (!dwReturn)
+ {
+ return dwReturn;
+ }
+ pbCmd[4] = (BYTE) cbAuthenticator;
+ memcpy(pbCmd + 5, pbNewPin, cbNewPin);
+ dwCmdSize = 5 + cbNewPin;
+ break;
+ case ROLE_PUK:
+ dwReturn = CheckPinLength(pCardData, PinId, cbAuthenticator);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ pbCmd[2] = 0x00;
+ pbCmd[4] = (BYTE) (cbAuthenticator + cbNewPin);
+ memcpy(pbCmd + 5, pbAuthenticator, cbAuthenticator);
+ memcpy(pbCmd + 5 + cbAuthenticator, pbNewPin, cbNewPin);
+ dwCmdSize = 5 + cbNewPin + cbAuthenticator;
+ break;
+ default:
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ __leave;
+ }
+ dwReturn = SCardSendCommand(pCardData, pbCmd, dwCmdSize);
+ }
+ __finally
+ {
+ SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
+ }
+ return dwReturn;
+}
+
+DWORD Deauthenticate(__in PCARD_DATA pCardData)
+{
+ DWORD dwAP;
+ DWORD dwReturn;
+ __try
+ {
+ // reset the card
+ Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
+ dwReturn = SCardReconnect(pCardData->hScard,
+ SCARD_SHARE_SHARED,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD,
+ &dwAP );
+ if (dwReturn)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCardControl 0x%08X", dwReturn);
+ __leave;
+ }
+ // regain the ownership of a transaction
+ dwReturn = SCardBeginTransaction(pCardData->hScard);
+ if (dwReturn)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCardBeginTransaction 0x%08X", dwReturn);
+ __leave;
+ }
+ dwReturn = SelectOpenPGPApplication(pCardData);
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/PinOperations.h
===================================================================
--- trunk/OpenPGPminidriver/PinOperations.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/PinOperations.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,37 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#define ROLE_SIGNATURE ROLE_USER
+#define ROLE_AUTHENTICATION 3
+#define ROLE_CONFIDENTIALITY 4
+#define ROLE_PUK 5
+
+DWORD CheckPinLength(__in PCARD_DATA pCardData, __in PIN_ID PinId, __in DWORD cbPin);
+DWORD GetRemainingPin(__in PCARD_DATA pCardData, __in PIN_ID PinId, __out PDWORD pdwCounter);
+DWORD VerifyPIN(__in PCARD_DATA pCardData,__in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin)
+;
+DWORD ChangePIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbOldPin, __in DWORD cbOldPin,
+ __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
+ );
+DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
+ __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator,
+ __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
+ );
+DWORD Deauthenticate(__in PCARD_DATA pCardData);
\ No newline at end of file
Added: trunk/OpenPGPminidriver/PublicDataOperations.c
===================================================================
--- trunk/OpenPGPminidriver/PublicDataOperations.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/PublicDataOperations.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,491 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <stdio.h>
+#include <cardmod.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+#include "PublicDataOperations.h"
+#include "CryptoOperations.h"
+
+typedef enum _OPENPGP_FILE_TYPE
+{
+ StoredOnSmartCard,
+ Virtual,
+} OPENPGP_FILE_TYPE;
+
+typedef struct _OPENPGP_FILE
+{
+ PCHAR szDirectory;
+ PCHAR szFile;
+ OPENPGP_FILE_TYPE dwFileType;
+ BYTE bP1;
+ BYTE bP2;
+ CARD_FILE_ACCESS_CONDITION dwAccess;
+} OPENPGP_FILE, *POPENPGP_FILE;
+
+
+#define szCARD_APPLICATION_FILE "cardapps"
+
+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},
+ {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},
+
+};
+
+DWORD dwFileCount = ARRAYSIZE(Files);
+
+DWORD SCardDirectoryList(__in PCARD_DATA pCardData,
+ __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
+{
+ // hardcoded
+ *pdwResponseSize = 16;
+ *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
+ if (!*pbResponse)
+ {
+ return SCARD_E_NO_MEMORY;
+ }
+ memcpy(*pbResponse, "openpgp\0mscp\0\0\0\0", *pdwResponseSize);
+ return 0;
+}
+
+// read file
+DWORD SCardReadFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile,
+ __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
+{
+ DWORD dwI;
+ DWORD dwReturn = 0;
+ BOOL fDirectoryFound = FALSE;
+ BOOL fFileFound = FALSE;
+ BYTE pbCmd[] = {0x00, 0xCA, 0x00, 0x00, 0x00};
+ DWORD dwCmdSize = ARRAYSIZE(pbCmd);
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+ __try
+ {
+ for(dwI = 0; dwI < dwFileCount; dwI++)
+ {
+ BOOL fMatch = FALSE;
+ if (szDirectory == NULL)
+ {
+ if (!Files[dwI].szDirectory) fMatch = TRUE;
+ }
+ else
+ {
+ if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
+ }
+ if (fMatch)
+ {
+ fDirectoryFound = TRUE;
+ if (strcmp(szFile, Files[dwI].szFile) == 0)
+ {
+ fFileFound = TRUE;
+ break;
+ }
+ }
+ }
+ if (!fFileFound)
+ {
+ if (fDirectoryFound)
+ {
+ dwReturn = SCARD_E_FILE_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
+ }
+ else
+ {
+ dwReturn = SCARD_E_DIR_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
+ }
+ __leave;
+ }
+ if (Files[dwI].dwFileType == StoredOnSmartCard)
+ {
+ pbCmd[2] = Files[dwI].bP1;
+ pbCmd[3] = Files[dwI].bP2;
+ dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, pbResponse, pdwResponseSize);
+ }
+ else
+ {
+ if (szDirectory == NULL)
+ {
+ if (strcmp(szFile, szCARD_APPLICATION_FILE) == 0)
+ {
+ dwReturn = SCardDirectoryList(pCardData, pbResponse, pdwResponseSize);
+ }
+ else if (strcmp(szFile, szCACHE_FILE) == 0)
+ {
+ *pdwResponseSize = sizeof(CARD_CACHE_FILE_FORMAT);
+ *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
+ memset(*pbResponse,0,*pdwResponseSize);
+ }
+ else
+ {
+ dwReturn = SCARD_E_FILE_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
+ }
+ }
+ else if (strcmp(szDirectory,szBASE_CSP_DIR) == 0)
+ {
+ if (strcmp(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;
+ }
+ else
+ {
+ dwReturn = SCARD_E_FILE_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
+ }
+ }
+ else
+ {
+ dwReturn = SCARD_E_DIR_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
+ }
+ }
+ if (dwReturn)
+ {
+ __leave;
+ }
+ // add to the cache
+ dwReturn = 0;
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X",szDirectory, szFile, dwReturn);
+ return dwReturn;
+}
+
+DWORD SCardEnumFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory,
+ __in PBYTE* pbResponse, __in PDWORD pdwResponseSize)
+{
+ DWORD dwReturn = 0, dwNotExists;
+ DWORD dwI, dwSize;
+ BOOL fDirectoryFound = FALSE;
+
+ __try
+ {
+ *pbResponse = NULL;
+ *pdwResponseSize = 0;
+ for(dwI = 0; dwI < dwFileCount; dwI++)
+ {
+ BOOL fMatch = FALSE;
+ if (szDirectory == NULL)
+ {
+ if (!Files[dwI].szDirectory) fMatch = TRUE;
+ }
+ else
+ {
+ if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
+ }
+ if (fMatch)
+ {
+ fDirectoryFound = TRUE;
+ dwNotExists = 0;
+ if (StoredOnSmartCard == Files[dwI].dwFileType)
+ {
+ PBYTE pbData = NULL;
+ DWORD dwSize;
+ // check if the file exists and be read
+ dwNotExists = SCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
+ if (!dwNotExists)
+ {
+ pCardData->pfnCspFree(pbData);
+ }
+ }
+ if (!dwNotExists)
+ {
+ 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;
+ }
+ }
+ }
+ if (!fDirectoryFound)
+ {
+ dwReturn = SCARD_E_DIR_NOT_FOUND;
+ __leave;
+ }
+ (*pbResponse)[*pdwResponseSize] = '\0';
+ *pdwResponseSize += 1;
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+// read file
+DWORD SCardGetFileInfo(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile,
+ __inout PCARD_FILE_INFO pCardFileInfo)
+{
+ DWORD dwReturn = 0;
+ PBYTE pbData = NULL;
+ DWORD dwSize, dwI;
+ __try
+ {
+ dwReturn = SCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ pCardData->pfnCspFree(pbData);
+ pCardFileInfo->cbFileSize = dwSize;
+ pCardFileInfo->AccessCondition = InvalidAc;
+ for(dwI = 0; dwI < dwFileCount; dwI++)
+ {
+ if ((strcmp(szDirectory, Files[dwI].szDirectory) == 0)
+ || (!szDirectory && !Files[dwI].szDirectory) )
+ {
+ if (strcmp(szFile, Files[dwI].szFile) == 0)
+ {
+ pCardFileInfo->AccessCondition = Files[dwI].dwAccess;
+ break;
+ }
+ }
+ }
+ dwReturn = 0;
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+DWORD SCardWriteFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile,
+ __in PBYTE pbData, __in DWORD dwSize)
+{
+ DWORD dwI;
+ DWORD dwReturn = 0;
+ BOOL fDirectoryFound = FALSE;
+ BOOL fFileFound = FALSE;
+ BYTE pbCmd[5 + 256] = {0x00, 0xDA, 0x00, 0x00, 0x00};
+ DWORD dwCmdSize = 0;
+ __try
+ {
+ if (dwSize > 255)
+ {
+ dwReturn = SCARD_E_INVALID_PARAMETER;
+ Trace(WINEVENT_LEVEL_ERROR, L"dwSize %d",dwSize);
+ __leave;
+ }
+
+
+ for(dwI = 0; dwI < dwFileCount; dwI++)
+ {
+ BOOL fMatch = FALSE;
+ if (szDirectory == NULL)
+ {
+ if (!Files[dwI].szDirectory) fMatch = TRUE;
+ }
+ else
+ {
+ if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
+ }
+ if (fMatch)
+ {
+ fDirectoryFound = TRUE;
+ if (strcmp(szFile, Files[dwI].szFile) == 0)
+ {
+ fFileFound = TRUE;
+ break;
+ }
+ }
+ }
+ if (!fFileFound)
+ {
+ if (fDirectoryFound)
+ {
+ dwReturn = SCARD_E_FILE_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
+ }
+ else
+ {
+ dwReturn = SCARD_E_DIR_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
+ }
+ __leave;
+ }
+ if (Files[dwI].dwFileType == StoredOnSmartCard)
+ {
+ // fail because the PUT DO doesn't work => too much data
+ if (Files[dwI].bP1 != 0)
+ {
+ dwReturn = SCARD_E_WRITE_TOO_MANY ;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_WRITE_TOO_MANY %S",szFile);
+ __leave;
+ }
+ pbCmd[3] = Files[dwI].bP2;
+ pbCmd[4] = (BYTE) dwSize;
+ if (dwSize)
+ {
+ memcpy(pbCmd + 5, pbData, dwSize);
+ }
+ dwCmdSize = dwSize + 5;
+ dwReturn = SCardSendCommand(pCardData, pbCmd, dwCmdSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ }
+ else
+ {
+ dwReturn = SCARD_W_SECURITY_VIOLATION;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION %S",szFile);
+ __leave;
+ }
+
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
+
+DWORD SCardDeleteFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile)
+{
+ return SCardWriteFile(pCardData, szDirectory, szFile, NULL, 0);
+}
+
+// just change the flag in Files
+DWORD SCardCreateFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile)
+{
+ DWORD dwI;
+ DWORD dwReturn = 0;
+ BOOL fDirectoryFound = FALSE;
+ BOOL fFileFound = FALSE;
+ __try
+ {
+ for(dwI = 0; dwI < dwFileCount; dwI++)
+ {
+ BOOL fMatch = FALSE;
+ if (szDirectory == NULL)
+ {
+ if (!Files[dwI].szDirectory) fMatch = TRUE;
+ }
+ else
+ {
+ if (Files[dwI].szDirectory && strcmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
+ }
+ if (fMatch)
+ {
+ fDirectoryFound = TRUE;
+ if (strcmp(szFile, Files[dwI].szFile) == 0)
+ {
+ fFileFound = TRUE;
+ break;
+ }
+ }
+ }
+ if (!fDirectoryFound)
+ {
+ dwReturn = SCARD_E_DIR_NOT_FOUND;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szFile);
+ __leave;
+ }
+ if (!fFileFound)
+ {
+ dwReturn = SCARD_W_SECURITY_VIOLATION;
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION %S",szFile);
+ __leave;
+ }
+
+ }
+ __finally
+ {
+ }
+ Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
+ return dwReturn;
+}
Added: trunk/OpenPGPminidriver/PublicDataOperations.h
===================================================================
--- trunk/OpenPGPminidriver/PublicDataOperations.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/PublicDataOperations.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,56 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+// max len = 8 bytes
+#define szOpenPGPDir "openpgp"
+#define szOpenPGPFingerprint "fingerpr"
+#define szOpenPGPStatus "status"
+#define szOpenPGPApplicationIdentifier "aid"
+#define szOpenPGPLogin "logindat"
+#define szOpenPGPName "name"
+#define szOpenPGPLanguage "language"
+#define szOpenPGPSex "sex"
+#define szOpenPGPUrl "url"
+#define szOpenPGPHistoricalBytes "histo"
+#define szOpenPGPCertificate "certific"
+#define szOpenPGPExtendedCap "extcapab"
+#define szOpenPGPAlgoAttributesSignature "algsign"
+#define szOpenPGPAlgoAttributesDecryption "algcryp"
+#define szOpenPGPAlgoAttributesAuthentication "algauth"
+
+
+DWORD SCardReadFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR file,
+ __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize);
+
+DWORD SCardEnumFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory,
+ __in PBYTE* pbResponse, __in PDWORD pdwResponseSize);
+
+DWORD SCardGetFileInfo(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile,
+ __inout PCARD_FILE_INFO pCardFileInfo);
+
+DWORD SCardWriteFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile,
+ __in PBYTE pbData, __in DWORD dwSize);
+
+DWORD SCardDeleteFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile);
+
+DWORD SCardCreateFile(__in PCARD_DATA pCardData,
+ __in_opt PSTR szDirectory, __in PSTR szFile);
\ No newline at end of file
Added: trunk/OpenPGPminidriver/README.txt
===================================================================
--- trunk/OpenPGPminidriver/README.txt 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/README.txt 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,21 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+Testing
+http://msdn.microsoft.com/en-us/library/dd327365.aspx
+
+cmck.exe is included in the "Windows Driver Kit (WDK)"
\ No newline at end of file
Added: trunk/OpenPGPminidriver/SmartCard.c
===================================================================
--- trunk/OpenPGPminidriver/SmartCard.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/SmartCard.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,272 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <cardmod.h>
+#include <stdio.h>
+#include "Tracing.h"
+#include "Context.h"
+#include "SmartCard.h"
+
+#pragma comment(lib,"Winscard")
+
+
+DWORD SCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize)
+{
+ DWORD dwReturn = 0;
+
+ SCARD_IO_REQUEST ioSendPci = {1, sizeof(SCARD_IO_REQUEST)};
+ SCARD_IO_REQUEST ioRecvPci = {1, sizeof(SCARD_IO_REQUEST)};
+ BYTE recvbuf[256];
+ DWORD recvlen = sizeof(recvbuf);
+ BYTE SW1, SW2;
+ __try
+ {
+
+ dwReturn = SCardTransmit(pCardData->hScard,
+ SCARD_PCI_T1,
+ pbCmd,
+ dwCmdSize,
+ NULL,
+ recvbuf,
+ &recvlen);
+ if ( dwReturn != SCARD_S_SUCCESS )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
+ __leave;
+ }
+ SW1 = recvbuf[recvlen-2];
+ SW2 = recvbuf[recvlen-1];
+ if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
+ {
+
+ }
+ else if ( (SW1 == 0x69) && (SW2 == 0x82) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
+ dwReturn = SCARD_W_WRONG_CHV;
+ __leave;
+ }
+ else if ( (SW1 == 0x69) && (SW2 == 0x83) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
+ dwReturn = SCARD_W_CHV_BLOCKED;
+ __leave;
+ }
+ else
+ {
+ TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
+ Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
+ dwReturn = SCARD_F_UNKNOWN_ERROR;
+ __leave;
+ }
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData)
+{
+ BYTE pbCmd[] = {0x00,
+ 0xA4,
+ 0x04,
+ 0x00,
+ 0x06,
+ 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
+ 0x00
+ };
+
+ return SCardSendCommand(pCardData, pbCmd, sizeof(pbCmd));
+}
+
+
+DWORD SCardGetData(__in PCARD_DATA pCardData,
+ __in PBYTE pbCmd, __in DWORD dwCmdSize,
+ __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
+{
+
+ DWORD dwReturn;
+ BYTE pbGetResponse[] = {0x00,
+ 0xC0,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ DWORD dwGetResponseSize = ARRAYSIZE(pbGetResponse);
+ BYTE recvbuf[0x800];
+ DWORD recvlen = sizeof(recvbuf);
+ BYTE SW1, SW2;
+ DWORD dwDataSize = 0;
+ __try
+ {
+
+ *pbResponse = NULL;
+ dwReturn = SCardTransmit(pCardData->hScard,
+ SCARD_PCI_T1,
+ pbCmd,
+ dwCmdSize,
+ NULL,
+ recvbuf,
+ &recvlen);
+
+ do
+ {
+ if ( dwReturn != SCARD_S_SUCCESS )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
+ __leave;
+ }
+ SW1 = recvbuf[recvlen-2];
+ SW2 = recvbuf[recvlen-1];
+ if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
+ {
+ dwDataSize = recvlen-2;
+ *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
+ memcpy(*pbResponse, recvbuf, dwDataSize);
+ }
+ else if (SW1 == 0x61)
+ {
+ dwDataSize += SW2;
+ if (*pbResponse)
+ {
+ *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize);
+ }
+ else
+ {
+ *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
+ }
+ dwGetResponseSize = ARRAYSIZE(pbGetResponse);
+ dwReturn = SCardTransmit(pCardData->hScard,
+ SCARD_PCI_T1,
+ pbGetResponse,
+ dwGetResponseSize,
+ NULL,
+ recvbuf,
+ &recvlen);
+ }
+ else if ( (SW1 == 0x69) && (SW2 == 0x82) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
+ dwReturn = SCARD_W_WRONG_CHV;
+ __leave;
+ }
+ else if ( (SW1 == 0x69) && (SW2 == 0x83) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
+ dwReturn = SCARD_W_CHV_BLOCKED;
+ __leave;
+ }
+ else if ( (SW1 == 0x6A) && (SW2 == 0x88) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND");
+ dwReturn = SCARD_E_FILE_NOT_FOUND;
+ __leave;
+ }
+ else if ( (SW1 == 0x69) && (SW2 == 0x85) )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION");
+ dwReturn = SCARD_W_SECURITY_VIOLATION;
+ __leave;
+ }
+ else
+ {
+ TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
+ Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
+ dwReturn = SCARD_F_UNKNOWN_ERROR;
+ __leave;
+ }
+
+ } while (SW1 == 0x61);
+ if (pdwResponseSize)
+ {
+ *pdwResponseSize = dwDataSize;
+ }
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength)
+{
+ DWORD idx = 0;
+ int count;
+ while (idx < featuresLength) {
+ BYTE tag = features[idx];
+ idx++;
+ idx++;
+ if (featureTag == tag) {
+ DWORD feature = 0;
+ for (count = 0; count < 3; count++) {
+ feature |= features[idx] & 0xff;
+ idx++;
+ feature <<= 8;
+ }
+ feature |= features[idx] & 0xff;
+ return feature;
+ }
+ idx += 4;
+ }
+ return 0;
+}
+
+DWORD CCIDgetFeatures(__in PCARD_DATA pCardData)
+{
+ BYTE pbRecvBuffer[200];
+ DWORD dwRecvLength, dwReturn;
+ __try
+ {
+ POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
+
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0;
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0;
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0;
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0;
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0;
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0;
+ pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0;
+ pContext->SmartCardReaderFeatures.ABORT = 0;
+
+ dwReturn = SCardControl(pCardData->hScard,
+ SCARD_CTL_CODE(3400),
+ NULL,
+ 0,
+ pbRecvBuffer,
+ sizeof(pbRecvBuffer),
+ &dwRecvLength);
+ if ( dwReturn )
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn);
+ __leave;
+ }
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength);
+ pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength);
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriver/SmartCard.h
===================================================================
--- trunk/OpenPGPminidriver/SmartCard.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/SmartCard.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,25 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+DWORD SCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize);
+DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData);
+
+DWORD SCardGetData(__in PCARD_DATA pCardData,
+ __in PBYTE pbCmd, __in DWORD dwCmdSize,
+ __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize);
+
+DWORD CCIDgetFeatures(__in PCARD_DATA pCardData) ;
\ No newline at end of file
Added: trunk/OpenPGPminidriver/SmartCardOperations.c
===================================================================
--- trunk/OpenPGPminidriver/SmartCardOperations.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/SmartCardOperations.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,3 @@
+
+#include "SmartCardOperations.h"
+
Added: trunk/OpenPGPminidriver/Tracing.c
===================================================================
--- trunk/OpenPGPminidriver/Tracing.c 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/Tracing.c 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,290 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <Evntprov.h>
+#include <initguid.h>
+#include <Wmistr.h>
+#include <Evntrace.h>
+#include <cardmod.h>
+#include "Tracing.h"
+
+#define MessageBoxWin32(status) MessageBoxWin32Ex (status, __FILE__,__LINE__);
+
+// to enable tracing in kernel debugger, issue the following command in windbg : ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
+// OR
+// Open up the registry and go to this path,
+// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter
+// and add the following value "DEFAULT" : REG_DWORD : 0xFFFFFFFF and then reboot
+
+// {081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}
+DEFINE_GUID(TracingGuid,
+0x81cce5f, 0x5f9c, 0x4b43, 0x9a, 0x15, 0x1d, 0xcf, 0x5d, 0x2d, 0x45, 0xf5);
+
+REGHANDLE hPub = 0;
+
+void TracingRegister() {
+ EventRegister(&TracingGuid,NULL,NULL,&hPub);
+}
+
+void TracingUnRegister() {
+ EventUnregister(hPub);
+}
+
+
+void TraceEx(LPCSTR szFile, DWORD dwLine, LPCSTR szFunction, UCHAR dwLevel, PCWSTR szFormat,...) {
+#ifndef _DEBUG
+ UNREFERENCED_PARAMETER(dwLine);
+ UNREFERENCED_PARAMETER(szFile);
+#endif
+ WCHAR Buffer[256];
+ WCHAR Buffer2[356];
+ int ret;
+ va_list ap;
+
+ if (!hPub) TracingRegister();
+
+ va_start (ap, szFormat);
+ ret = _vsnwprintf_s (Buffer, 256, 256, szFormat, ap);
+ va_end (ap);
+ if (ret <= 0) return;
+ if (ret > 256) ret = 255;
+ Buffer[255] = L'\0';
+#ifdef _DEBUG
+ swprintf_s(Buffer2,356,L"%S(%d) : %S - %s\r\n",szFile,dwLine,szFunction,Buffer);
+ OutputDebugString(Buffer2);
+#endif
+ swprintf_s(Buffer2,356,L"%S(%d) : %s",szFunction,dwLine,Buffer);
+ EventWriteString(hPub,dwLevel,0,Buffer2);
+
+}
+
+void TraceDumpEx(LPCSTR szFile, DWORD dwLine, LPCSTR szFunction, UCHAR dwLevel,
+ __in PBYTE pbCmd, __in DWORD dwCmdSize)
+{
+ WCHAR szData[10 * 3 + 1];
+ DWORD dwI;
+ PWSTR szPointer = szData;
+ for(dwI = 0; dwI < dwCmdSize; dwI++)
+ {
+ if (dwI%10 == 0 && dwI != 0)
+ {
+ TraceEx(szFile,dwLine,szFunction,dwLevel,L"DUMP : %s",szData);
+ szPointer = szData;
+ }
+ swprintf_s(szPointer + 3 * (dwI%10),4,L"%02X ",pbCmd[dwI]);
+
+ }
+ TraceEx(szFile,dwLine,szFunction,dwLevel,L"DUMP : %s",szData);
+}
+
+/**
+ * Display a messagebox giving an error code
+ */
+void MessageBoxWin32Ex(DWORD status, LPCSTR szFile, DWORD dwLine) {
+ LPVOID Error;
+ TCHAR szTitle[1024];
+#ifdef UNICODE
+ _stprintf_s(szTitle,ARRAYSIZE(szTitle),TEXT("%S(%d)"),szFile, dwLine);
+#else
+ _stprintf_s(szTitle,ARRAYSIZE(szTitle),TEXT("%s(%d)"),szFile, dwLine);
+#endif
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,status,0,(LPTSTR)&Error,0,NULL);
+ MessageBox(NULL,(LPCTSTR)Error,szTitle ,MB_ICONASTERISK);
+ LocalFree(Error);
+}
+
+BOOL StartLogging()
+{
+ BOOL fReturn = FALSE;
+ TRACEHANDLE SessionHandle;
+ struct _Prop
+ {
+ EVENT_TRACE_PROPERTIES TraceProperties;
+ TCHAR LogFileName[1024];
+ TCHAR LoggerName[1024];
+ } Properties;
+ ULONG err;
+ __try
+ {
+ memset(&Properties, 0, sizeof(Properties));
+ Properties.TraceProperties.Wnode.BufferSize = sizeof(Properties);
+ Properties.TraceProperties.Wnode.Guid = TracingGuid;
+ Properties.TraceProperties.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
+ Properties.TraceProperties.Wnode.ClientContext = 1;
+ Properties.TraceProperties.LogFileMode = 4864;
+ Properties.TraceProperties.LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
+ Properties.TraceProperties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + 1024;
+ Properties.TraceProperties.MaximumFileSize = 8;
+ _tcscpy_s(Properties.LogFileName,1024,TEXT("c:\\Windows\\system32\\LogFiles\\WMI\\OpenPGPmdrv.etl"));
+ DeleteFile(Properties.LogFileName);
+ err = StartTrace(&SessionHandle, TEXT("OpenPGPmdrv"), &(Properties.TraceProperties));
+ if (err != ERROR_SUCCESS)
+ {
+ MessageBoxWin32(err);
+ __leave;
+ }
+ err = EnableTraceEx(&TracingGuid,NULL,SessionHandle,TRUE,WINEVENT_LEVEL_VERBOSE,0,0,0,NULL);
+ if (err != ERROR_SUCCESS)
+ {
+ MessageBoxWin32(err);
+ __leave;
+ }
+ fReturn = TRUE;
+ }
+ __finally
+ {
+ }
+ return fReturn;
+}
+
+void StopLogging()
+{
+ LONG err;
+ struct _Prop
+ {
+ EVENT_TRACE_PROPERTIES TraceProperties;
+ TCHAR LogFileName[1024];
+ TCHAR LoggerName[1024];
+ } Properties;
+ memset(&Properties, 0, sizeof(Properties));
+ Properties.TraceProperties.Wnode.BufferSize = sizeof(Properties);
+ Properties.TraceProperties.Wnode.Guid = TracingGuid;
+ Properties.TraceProperties.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
+ Properties.TraceProperties.LogFileMode = 4864;
+ Properties.TraceProperties.LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
+ Properties.TraceProperties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + 1024 * sizeof(TCHAR);
+ Properties.TraceProperties.MaximumFileSize = 8;
+ err = ControlTrace((TRACEHANDLE)NULL, TEXT("OpenPGPmdrv"), &(Properties.TraceProperties),EVENT_TRACE_CONTROL_STOP);
+ if (err != ERROR_SUCCESS && err != 0x00001069)
+ {
+ MessageBoxWin32(err);
+ }
+}
+
+void EnableLogging()
+{
+ DWORD64 qdwValue;
+ DWORD dwValue;
+ LONG err;
+
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("Guid"), REG_SZ, TEXT("{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),sizeof(TEXT("{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}")));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("FileName"), REG_SZ, TEXT("c:\\windows\\system32\\LogFiles\\WMI\\OpenPGPmdrv.etl"),sizeof(TEXT("c:\\windows\\system32\\LogFiles\\WMI\\OpenPGPmdrv.etl")));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 8;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("FileMax"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 1;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("Start"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 8;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("BufferSize"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("FlushTimer"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("MaximumBuffers"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("MinimumBuffers"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 1;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("ClockType"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 64;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("MaxFileSize"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 4864;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("LogFileMode"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 5;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("FileCounter"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"),
+ TEXT("Status"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+
+ dwValue = 1;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("Enabled"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 5;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("EnableLevel"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("EnableProperty"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ dwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("Status"), REG_DWORD,&dwValue,sizeof(DWORD));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ qdwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("MatchAllKeyword"), REG_QWORD,&qdwValue,sizeof(DWORD64));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ qdwValue = 0;
+ err = RegSetKeyValue( HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv\\{081CCE5F-5F9C-4b43-9A15-1DCF5D2D45F5}"),
+ TEXT("MatchAnyKeyword"), REG_QWORD,&qdwValue,sizeof(DWORD64));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ StartLogging();
+}
+
+void DisableLogging()
+{
+
+ LONG err = RegDeleteTree(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\WMI\\Autologger\\OpenPGPmdrv"));
+ if (err != ERROR_SUCCESS) {MessageBoxWin32(err); return;}
+ StopLogging();
+}
Added: trunk/OpenPGPminidriver/Tracing.h
===================================================================
--- trunk/OpenPGPminidriver/Tracing.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/Tracing.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,38 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#pragma once
+
+#define WINEVENT_LEVEL_CRITICAL 1
+#define WINEVENT_LEVEL_ERROR 2
+#define WINEVENT_LEVEL_WARNING 3
+#define WINEVENT_LEVEL_INFO 4
+#define WINEVENT_LEVEL_VERBOSE 5
+
+void TracingRegister();
+void TracingUnRegister();
+
+#define Trace(dwLevel, ...) \
+ TraceEx(__FILE__,__LINE__,__FUNCTION__, dwLevel, __VA_ARGS__);
+
+void TraceEx(PCSTR szFile, DWORD dwLine, PCSTR szFunction, UCHAR dwLevel, PCWSTR szFormat,...);
+
+void TraceDumpEx(LPCSTR szFile, DWORD dwLine, LPCSTR szFunction, UCHAR dwLevel,
+ __in PBYTE pbCmd, __in DWORD dwCmdSize);
+
+#define TraceDump(dwLevel, pbCmd,dwCmdSize) \
+ TraceDumpEx(__FILE__,__LINE__,__FUNCTION__, dwLevel, pbCmd,dwCmdSize);
\ No newline at end of file
Added: trunk/OpenPGPminidriver/driver.inf
===================================================================
--- trunk/OpenPGPminidriver/driver.inf 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/driver.inf 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,142 @@
+;
+;OpenPGP Smartcard Minidriver for an x86 and x64 based package.
+;
+
+[Version]
+Signature="$Windows NT$"
+Class=SmartCard
+ClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391}
+Provider=%OPENPGP%
+CatalogFile=delta.cat
+DriverVer=02/23/2010,0.0.0.1
+
+[Manufacturer]
+%OPENPGP%=OpenPGP,NTamd64,NTamd64.6.1,NTx86,NTx86.6.1
+
+[OpenPGP.NTamd64]
+%OpenPGPCardDeviceName%=OpenPGP64_Install,SCFILTER\CID_0031c573c00140009000
+
+[OpenPGP.NTx86]
+%OpenPGPCardDeviceName%=OpenPGP32_Install,SCFILTER\CID_0031c573c00140009000
+
+[OpenPGP.NTamd64.6.1]
+%OpenPGPCardDeviceName%=OpenPGP64_61_Install,SCFILTER\CID_0031c573c00140009000
+
+[OpenPGP.NTx86.6.1]
+%OpenPGPCardDeviceName%=OpenPGP32_61_Install,SCFILTER\CID_0031c573c00140009000
+
+[SourceDisksFiles]
+openpgpmdrv64.dll=1
+openpgpmdrv32.dll=1
+
+[SourceDisksNames]
+1 = %MediaDescription%
+
+[OpenPGP64_Install.NT]
+CopyFiles=amd64_CopyFiles
+CopyFiles=wow64_CopyFiles
+AddReg=AddRegWOW64
+AddReg=AddReg64
+
+[OpenPGP64_61_Install.NT]
+CopyFiles=amd64_CopyFiles
+CopyFiles=wow64_CopyFiles
+AddReg=AddRegWOW64
+AddReg=AddReg64
+Include=umpass.inf
+Needs=UmPass
+
+[OpenPGP32_Install.NT]
+CopyFiles=x86_CopyFiles
+AddReg=AddReg32
+
+[OpenPGP32_61_Install.NT]
+CopyFiles=x86_CopyFiles
+AddReg=AddReg32
+Include=umpass.inf
+Needs=UmPass
+
+[OpenPGP64_61_Install.NT.Services]
+Include=umpass.inf
+Needs=UmPass.Services
+
+[OpenPGP32_61_Install.NT.Services]
+Include=umpass.inf
+Needs=UmPass.Services
+
+
+[OpenPGP64_61_Install.NT.HW]
+Include=umpass.inf
+Needs=UmPass.HW
+
+[OpenPGP64_61_Install.NT.CoInstallers]
+Include=umpass.inf
+Needs=UmPass.CoInstallers
+
+
+[OpenPGP64_61_Install.NT.Interfaces]
+Include=umpass.inf
+Needs=UmPass.Interfaces
+
+
+[OpenPGP32_61_Install.NT.HW]
+Include=umpass.inf
+Needs=UmPass.HW
+
+[OpenPGP32_61_Install.NT.CoInstallers]
+Include=umpass.inf
+Needs=UmPass.CoInstallers
+
+
+[OpenPGP32_61_Install.NT.Interfaces]
+Include=umpass.inf
+Needs=UmPass.Interfaces
+
+
+[amd64_CopyFiles]
+%SmartCardCardModule64%
+
+[x86_CopyFiles]
+%SmartCardCardModule32%
+
+[wow64_CopyFiles]
+%SmartCardCardModule32%
+
+[AddRegWOW64]
+HKLM, %SmartCardNameWOW64%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C
+HKLM, %SmartCardNameWOW64%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
+HKLM, %SmartCardNameWOW64%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider"
+HKLM, %SmartCardNameWOW64%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider"
+HKLM, %SmartCardNameWOW64%,"80000001",0x00000000,%SmartCardCardModule32%
+
+[AddReg32]
+HKLM, %SmartCardName%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C
+HKLM, %SmartCardName%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
+HKLM, %SmartCardName%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider"
+HKLM, %SmartCardName%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider"
+HKLM, %SmartCardName%,"80000001",0x00000000,%SmartCardCardModule32%
+
+[AddReg64]
+HKLM, %SmartCardName%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C
+HKLM, %SmartCardName%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
+HKLM, %SmartCardName%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider"
+HKLM, %SmartCardName%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider"
+HKLM, %SmartCardName%,"80000001",0x00000000,%SmartCardCardModule64%
+
+
+[DestinationDirs]
+amd64_CopyFiles=10,system32
+x86_CopyFiles=10,system32
+wow64_CopyFiles=10,syswow64
+
+
+; =================== Generic ==================================
+
+[Strings]
+OPENPGP ="OpenPGP"
+MediaDescription="OpenPGP Smart Card Minidriver Installation Disk"
+OpenPGPCardDeviceName="OpenPGP Minidriver for Smart Card"
+SmartCardName="SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\OpenPGP"
+SmartCardNameWOW64="SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\OpenPGP"
+SmartCardCardModule32="openpgpmdrv32.dll"
+SmartCardCardModule64="openpgpmdrv64.dll"
Added: trunk/OpenPGPminidriver/version.rc
===================================================================
--- trunk/OpenPGPminidriver/version.rc 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver/version.rc 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,25 @@
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION 0,3,0,2
+PRODUCTVERSION 0,3,0,2
+FILEOS 0x00000004
+FILETYPE 0x00000002
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "OpenPGP smart card mini driver\0"
+ VALUE "FileVersion", "0.0.0.1\0"
+ VALUE "InternalName", "openpgpmdrv.dll\0"
+ VALUE "OriginalFilename", "openpgpmdrv.dll\0"
+ VALUE "ProductName", "OpenPGP smart card mini driver\0"
+ VALUE "ProductVersion", "0.0.0.1\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 0x04B0
+ END
+END
+
Added: trunk/OpenPGPminidriver.sln
===================================================================
--- trunk/OpenPGPminidriver.sln 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriver.sln 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,39 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenPGPminidriver", "OpenPGPminidriver\OpenPGPminidriver.vcproj", "{775DAB1D-5A49-4A57-B259-AD3DC833A75F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenPGPminidriverTest", "OpenPGPminidriverTest\OpenPGPminidriverTest.vcproj", "{4E413ED7-0D68-47A9-AB93-39319815E730}"
+ ProjectSection(ProjectDependencies) = postProject
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F} = {775DAB1D-5A49-4A57-B259-AD3DC833A75F}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|Win32.Build.0 = Debug|Win32
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x64.ActiveCfg = Debug|x64
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x64.Build.0 = Debug|x64
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|Win32.ActiveCfg = Release|Win32
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|Win32.Build.0 = Release|Win32
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x64.ActiveCfg = Release|x64
+ {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x64.Build.0 = Release|x64
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|Win32.Build.0 = Debug|Win32
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x64.ActiveCfg = Debug|x64
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x64.Build.0 = Debug|x64
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|Win32.ActiveCfg = Release|Win32
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|Win32.Build.0 = Release|Win32
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x64.ActiveCfg = Release|x64
+ {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Added: trunk/OpenPGPminidriverTest/BaseCSP.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/BaseCSP.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/BaseCSP.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,482 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <Cryptuiapi.h>
+#include <commctrl.h>
+#include "dialog.h"
+#pragma comment(lib,"Cryptui")
+#pragma comment(lib,"Crypt32")
+
+extern HWND hMainWnd;
+
+BOOL SchGetProviderNameFromCardName(__in LPCTSTR szCardName, __out LPTSTR szProviderName, __out PDWORD pdwProviderNameLen)
+{
+ // get provider name
+ SCARDCONTEXT hSCardContext;
+ LONG lCardStatus;
+ lCardStatus = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSCardContext);
+ if (SCARD_S_SUCCESS != lCardStatus)
+ {
+ return FALSE;
+ }
+
+ lCardStatus = SCardGetCardTypeProviderName(hSCardContext,
+ szCardName,
+ SCARD_PROVIDER_CSP,
+ szProviderName,
+ pdwProviderNameLen);
+ if (SCARD_S_SUCCESS != lCardStatus)
+ {
+ SCardReleaseContext(hSCardContext);
+ return FALSE;
+ }
+ SCardReleaseContext(hSCardContext);
+ return TRUE;
+}
+
+DWORD ListContainer()
+{
+ HCRYPTPROV HMainCryptProv = NULL;
+ BOOL bStatus = FALSE;
+ LPTSTR szMainContainerName = NULL;
+ CHAR szContainerName[1024];
+ DWORD dwContainerNameLen = sizeof(szContainerName);
+ DWORD dwErr = 0;
+ DWORD dwFlags = CRYPT_FIRST;
+ DWORD dwContextArrayLen = 0;
+ HCRYPTPROV hProv = NULL;
+ HCRYPTKEY hKey = NULL;
+ LPBYTE pbCert = NULL;
+ DWORD dwCertLen = 0;
+ PCCERT_CONTEXT pCertContext = NULL;
+ DWORD pKeySpecs[2] = { AT_KEYEXCHANGE,AT_SIGNATURE};
+ PCCERT_CONTEXT pSelectedContext = NULL;
+ HCERTSTORE hStore = NULL;
+ TCHAR szCardName[256];
+ TCHAR szReaderName[256];
+ TCHAR szOutProviderName[256];
+ DWORD dwOutProviderLength = ARRAYSIZE(szOutProviderName);
+ OPENCARDNAME_EX dlgStruct;
+ DWORD dwReturn;
+ SCARDCONTEXT hSCardContext = NULL;
+ SCARDHANDLE hSCardHandle = NULL;
+ __try
+ {
+
+ SendMessage(GetDlgItem(hMainWnd, IDC_LSTCONTAINER),LB_RESETCONTENT,0,0);
+ dwReturn = SCardEstablishContext(SCARD_SCOPE_USER,
+ NULL,
+ NULL,
+ &hSCardContext );
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ // Initialize the structure.
+ memset(&dlgStruct, 0, sizeof(dlgStruct));
+ dlgStruct.dwStructSize = sizeof(dlgStruct);
+ dlgStruct.hSCardContext = hSCardContext;
+ dlgStruct.dwFlags = SC_DLG_MINIMAL_UI;
+ dlgStruct.lpstrRdr = szReaderName;
+ dlgStruct.nMaxRdr = ARRAYSIZE(szReaderName);
+ dlgStruct.lpstrCard = szCardName;
+ dlgStruct.nMaxCard = ARRAYSIZE(szCardName);
+ dlgStruct.lpstrTitle = L"Select Card";
+ dlgStruct.dwShareMode = 0;
+ // Display the select card dialog box.
+ dwReturn = SCardUIDlgSelectCard(&dlgStruct);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ dwReturn = SCardUIDlgSelectCard(&dlgStruct);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ if (!SchGetProviderNameFromCardName(szCardName, szOutProviderName, &dwOutProviderLength))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ size_t ulNameLen = _tcslen(szReaderName);
+ szMainContainerName = (LPWSTR) LocalAlloc(0,(DWORD)(ulNameLen + 6) * sizeof(WCHAR));
+ if (!szMainContainerName)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ swprintf_s(szMainContainerName,(ulNameLen + 6), L"\\\\.\\%s\\", szReaderName);
+
+ bStatus = CryptAcquireContext(&HMainCryptProv,
+ szMainContainerName,
+ szOutProviderName,
+ PROV_RSA_FULL,
+ CRYPT_SILENT);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ if (dwReturn == NTE_BAD_KEYSET)
+ {
+ bStatus = CryptAcquireContext(&HMainCryptProv,NULL, szOutProviderName, PROV_RSA_FULL, CRYPT_SILENT);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ }
+ else
+ {
+ __leave;
+ }
+
+ }
+
+
+
+ /* Enumerate all the containers */
+ while (CryptGetProvParam(HMainCryptProv,
+ PP_ENUMCONTAINERS,
+ (LPBYTE) szContainerName,
+ &dwContainerNameLen,
+ dwFlags) &&
+ (dwContextArrayLen < 128)
+ )
+ {
+
+ // convert the container name to unicode
+ int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0);
+ LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0,wLen * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen);
+
+ // Acquire a context on the current container
+ if (CryptAcquireContext(&hProv,
+ szWideContainerName,
+ szOutProviderName,
+ PROV_RSA_FULL,
+ 0))
+ {
+ // Loop over all the key specs
+ for (int i = 0; i < 2; i++)
+ {
+ if (CryptGetUserKey(hProv,
+ pKeySpecs[i],
+ &hKey) )
+ {
+ TCHAR szText[256];
+ _stprintf_s(szText, ARRAYSIZE(szText), TEXT("%s %d"),szWideContainerName,pKeySpecs[i]);
+ SendDlgItemMessage(hMainWnd,IDC_LSTCONTAINER,LB_ADDSTRING,0,(LPARAM)szText);
+ CryptDestroyKey(hKey);
+ hKey = NULL;
+ }
+ }
+ CryptReleaseContext(hProv, 0);
+ hProv = NULL;
+ }
+ LocalFree(szWideContainerName);
+
+ // prepare parameters for the next loop
+ dwContainerNameLen = sizeof(szContainerName);
+ dwFlags = 0;
+ }
+ }
+ __finally
+ {
+ if (hKey)
+ CryptDestroyKey(hKey);
+ if (hProv)
+ CryptReleaseContext(hProv, 0);
+ if (szMainContainerName)
+ LocalFree(szMainContainerName);
+ if (HMainCryptProv)
+ CryptReleaseContext(HMainCryptProv, 0);
+ }
+ return dwReturn;
+}
+
+
+DWORD ViewCertificate(PTSTR szContainer, DWORD dwKeySpec)
+{
+ BOOL bStatus;
+ DWORD dwReturn = 0;
+ HCRYPTPROV hProv = NULL;
+ HCRYPTKEY hKey = NULL;
+ DWORD dwCertLen = 0;
+ PBYTE pbCert = NULL;
+ PCCERT_CONTEXT pCertContext = NULL;
+ CRYPTUI_VIEWCERTIFICATE_STRUCT certViewInfo;
+ BOOL fPropertiesChanged = FALSE;
+ __try
+ {
+ bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, CRYPT_SILENT);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGetKeyParam(hKey,
+ KP_CERTIFICATE,
+ NULL,
+ &dwCertLen,
+ 0);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ pbCert = (LPBYTE) LocalAlloc(0,dwCertLen);
+ if (!pbCert)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGetKeyParam(hKey,
+ KP_CERTIFICATE,
+ pbCert,
+ &dwCertLen,
+ 0);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ pCertContext = CertCreateCertificateContext(
+ X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
+ pbCert,
+ dwCertLen);
+ if (!pCertContext)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ certViewInfo.dwSize = sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
+ certViewInfo.hwndParent = hMainWnd;
+ certViewInfo.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_DISABLE_EXPORT | CRYPTUI_DISABLE_HTMLLINK;
+ certViewInfo.szTitle = TEXT("Info");
+ certViewInfo.pCertContext = pCertContext;
+ certViewInfo.cPurposes = 0;
+ certViewInfo.rgszPurposes = 0;
+ certViewInfo.pCryptProviderData = NULL;
+ certViewInfo.hWVTStateData = NULL;
+ certViewInfo.fpCryptProviderDataTrustedUsage = FALSE;
+ certViewInfo.idxSigner = 0;
+ certViewInfo.idxCert = 0;
+ certViewInfo.fCounterSigner = FALSE;
+ certViewInfo.idxCounterSigner = 0;
+ certViewInfo.cStores = 0;
+ certViewInfo.rghStores = NULL;
+ certViewInfo.cPropSheetPages = 0;
+ certViewInfo.rgPropSheetPages = NULL;
+ certViewInfo.nStartPage = 0;
+
+ dwReturn = CryptUIDlgViewCertificate(&certViewInfo,&fPropertiesChanged);
+
+ }
+ __finally
+ {
+ if (pCertContext)
+ CertFreeCertificateContext(pCertContext);
+ if (pbCert)
+ LocalFree(pbCert);
+ if (hKey)
+ CryptDestroyKey(hKey);
+ if (hProv)
+ CryptReleaseContext(hProv, 0);
+ }
+ return dwReturn;
+}
+
+DWORD Sign(PTSTR szContainer, DWORD dwKeySpec)
+{
+ BOOL bStatus;
+ DWORD dwReturn = 0;
+ HCRYPTPROV hProv = NULL;
+ HCRYPTKEY hKey = NULL;
+ HCRYPTHASH hHash = NULL;
+ PBYTE pbSignature = NULL;
+ DWORD dwSignatureSize = 0;
+ BYTE pbChallenge[20];
+ TCHAR szDescription[] = TEXT("Test");
+ __try
+ {
+ bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (!CryptCreateHash(hProv,CALG_SHA,NULL,0,&hHash))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (!CryptSetHashParam(hHash, HP_HASHVAL, pbChallenge, 0))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, NULL, &dwSignatureSize))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ pbSignature = (PBYTE) LocalAlloc(0,dwSignatureSize);
+ if (!pbSignature)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, pbSignature, &dwSignatureSize))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (!CryptVerifySignature(hHash, pbSignature, dwSignatureSize, hKey, szDescription, 0))
+ {
+ dwReturn = GetLastError();
+ }
+ }
+ __finally
+ {
+ if (pbSignature)
+ LocalFree(pbSignature);
+ if (hHash)
+ CryptDestroyHash(hHash);
+ if (hKey)
+ CryptDestroyKey(hKey);
+ if (hProv)
+ CryptReleaseContext(hProv, 0);
+ }
+ return dwReturn;
+}
+
+DWORD Decrypt(PTSTR szContainer, DWORD dwKeySpec)
+{
+ BOOL bStatus;
+ DWORD dwReturn = 0;
+ HCRYPTPROV hProv = NULL;
+ HCRYPTKEY hKey = NULL;
+ HCRYPTHASH hHash = NULL;
+ PBYTE pbCrypt = NULL;
+ DWORD dwCryptSize = 0, dwBufferSize;
+ BYTE pbChallenge[]=
+ {0x09,0x59,0x1B,0x38,0x56,0xBD,0x71,0xA2,0x38,0x70,0x4E,0xDC,0x47,0xB3,0x0B,0x19,0xB3,
+ 0x33,0x65,0x79,0xF7,0x46,0x4C,0xBF,0x24,0x77,
+ 0x7E,0x06,0x1D,0xA6,0x97,0x46,0x08,0x0C,0x95};
+ BYTE pbDecrypt[] =
+ {0x5D,0x29,0xB8,0xC2,0x27,0x26,0xAC,0x36,0x29,0x40,0xEF,0x38,0x65,0xD0,0x37,0x85,0x11,0x91
+,0x18,0x98,0x6A,0xDF,0xA4,0x5A,0xC2,0x66,0x4F,0x1E,0xF6,0xC5,0xE5,0xEE,0x85,0xC2,0x0A,0xA6,0xFF,0x69,0x6D,0xF1,0xF5,0xEA,0x83,0x49
+,0xB6,0x8E,0xE2,0xE8,0x2C,0x0B,0x38,0x9B,0x70,0x60,0xF8,0x1F,0xE1,0xCC,0xE5,0xA4,0xD9,0xF6,0x39,0x8D,0x94,0x6A,0x36,0xF0,0xA5,0x8B
+,0xF3,0x7F,0xC1,0xC8,0x53,0x42,0x70,0x33,0x6E,0x28,0xFC,0x5E,0xAC,0x7B,0xBC,0xB5,0x0D,0x93,0xD6,0xCC,0xF3,0x05,0x47,0xD8,0xAB,0x5E
+,0x43,0x8B,0x17,0x27,0x38,0x70,0xC9,0x0D,0xFC,0xF6,0x8F,0xEA,0x63,0xBB,0xF4,0x58,0xB1,0x8B,0x8D,0xC7,0x89,0x43,0x7A,0x69,0xEC,0x1E
+,0x9F,0x13,0xFC,0xC2,0x73,0xEA,0x04,0x0C,0x4E,0x1B,0x1B,0x55,0x51,0x14,0x20,0x90,0x60,0x30,0x73,0x11,0xE8,0x6F,0xF0,0x45,0xC0,0x49
+,0x1A,0x0B,0x9F,0x7C,0x30,0x5E,0xF9,0x69,0x2F,0x98,0x2C,0x53,0x06,0x02,0x93,0xAE,0xC8,0x12,0xEE,0x81,0xD4,0x9C,0xE6,0x16,0xB2,0x7D
+,0xF3,0x3E,0x9D,0xB5,0xDC,0x39,0x39,0x43,0xA1,0x37,0x81,0x06,0xC8,0x8D,0x40,0xB0,0x62,0x8F,0xE1,0x6C,0xB3,0xDE,0x08,0xC2,0x06,0xD5
+,0x8A,0x57,0xB5,0x3A,0x24,0x7A,0x75,0x97,0xDD,0x06,0x3B,0x16,0x4D,0xEE,0xC7,0x5E,0x88,0x49,0xF0,0x02,0x3C,0x99,0x93,0xE2,0x98,0xC5
+,0x8A,0x65,0x2F,0x85,0x99,0x25,0xC3,0x91,0x62,0x9E,0x39,0xB7,0xAB,0xB6,0x51,0x0C,0x74,0x98,0x5C,0x58,0x70,0x44,0xDE,0x79,0xF0,0xC5
+,0x04,0xAF,0x59,0xA5};
+ __try
+ {
+ bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ //bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ dwCryptSize = 0;
+ dwBufferSize = ARRAYSIZE(pbChallenge);
+ if (!CryptEncrypt(hKey,NULL, TRUE, 0, NULL, &dwBufferSize,0))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ pbCrypt = (PBYTE) LocalAlloc(0,dwBufferSize);
+ if (!pbCrypt)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ memcpy(pbCrypt, pbChallenge, ARRAYSIZE(pbChallenge));
+ dwCryptSize = ARRAYSIZE(pbChallenge);
+ if (!CryptEncrypt(hKey,NULL, FALSE, 0, pbCrypt, &dwCryptSize,dwBufferSize))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ //if (!CryptDecrypt(hKey, NULL, FALSE, 0, pbCrypt, &dwCryptSize))
+ dwCryptSize = ARRAYSIZE(pbDecrypt);
+ if (!CryptDecrypt(hKey, NULL, FALSE, 0, pbDecrypt, &dwCryptSize))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ if (dwCryptSize != ARRAYSIZE(pbChallenge))
+ {
+ dwReturn = NTE_BAD_DATA;
+ __leave;
+ }
+ if (memcmp(pbChallenge, pbCrypt, dwCryptSize) != 0)
+ {
+ dwReturn = NTE_BAD_DATA;
+ __leave;
+ }
+ }
+ __finally
+ {
+ if (pbCrypt)
+ LocalFree(pbCrypt);
+ if (hKey)
+ CryptDestroyKey(hKey);
+ if (hProv)
+ CryptReleaseContext(hProv, 0);
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/CryptoOperations.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/CryptoOperations.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/CryptoOperations.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,126 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <cardmod.h>
+#include "global.h"
+
+DWORD GenerateNewKey(DWORD dwIndex)
+{
+ DWORD dwReturn, dwKeySpec;
+ PIN_ID PinId;
+ __try
+ {
+ if (!pCardData)
+ {
+ dwReturn = SCARD_E_COMM_DATA_LOST;
+ __leave;
+ }
+ switch(dwIndex)
+ {
+ case 0: //Signature,
+ dwKeySpec = AT_SIGNATURE;
+ PinId = ROLE_USER;
+ break;
+ case 1: //Authentication,
+ dwKeySpec = AT_SIGNATURE;
+ PinId = 3;
+ break;
+ case 2: // Confidentiality,
+ dwKeySpec = AT_KEYEXCHANGE;
+ PinId = 4;
+ break;
+ default:
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) dwIndex,
+ CARD_CREATE_CONTAINER_KEY_GEN,
+ dwKeySpec, 1024, NULL, PinId);
+ }
+ __finally
+ {
+ }
+ return dwReturn;
+}
+
+DWORD ImportKey(DWORD dwIndex)
+{
+ DWORD dwReturn, dwKeySpec;
+ PIN_ID PinId;
+ HCRYPTPROV hProv = NULL;
+ HCRYPTKEY hKey = NULL;
+ TCHAR szContainerName[] = TEXT("Test_OPENPGPG");
+ BYTE pbData[4096];
+ DWORD dwDataSize = ARRAYSIZE(pbData);
+ BOOL bStatus;
+ __try
+ {
+ if (!pCardData)
+ {
+ dwReturn = SCARD_E_COMM_DATA_LOST;
+ __leave;
+ }
+ switch(dwIndex)
+ {
+ case 0: //Signature,
+ dwKeySpec = AT_SIGNATURE;
+ PinId = ROLE_USER;
+ break;
+ case 1: //Authentication,
+ dwKeySpec = AT_SIGNATURE;
+ PinId = 3;
+ break;
+ case 2: // Confidentiality,
+ dwKeySpec = AT_KEYEXCHANGE;
+ PinId = 4;
+ break;
+ default:
+ dwReturn = SCARD_E_UNEXPECTED;
+ __leave;
+ }
+ bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ bStatus = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataSize);
+ if (!bStatus)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) dwIndex,
+ CARD_CREATE_CONTAINER_KEY_IMPORT,
+ dwKeySpec, 1024, pbData, PinId);
+ }
+ __finally
+ {
+ if (hKey)
+ CryptDestroyKey(hKey);
+ CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/Dialog.h
===================================================================
--- trunk/OpenPGPminidriverTest/Dialog.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/Dialog.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,36 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define IDD_DLG 1000
+#define IDC_CONNECT 1001
+#define IDC_CurrentDll 1002
+#define IDC_SystemDll 1003
+#define IDC_DISCONNECT 1004
+#define IDC_TXTPIN 1005
+#define IDC_PIN 1006
+#define IDC_FILES 1007
+#define IDC_LISTFILES 1008
+#define IDC_PINADMIN 1009
+#define IDC_PINUSER 1010
+#define IDC_LSTCONTAINER 1011
+#define IDC_CONTAINER 1012
+#define IDC_STC1 1013
+#define IDC_SIGN 1014
+#define IDC_DECRYPT 1015
+#define IDC_CONTAINERINDEX 1016
+#define IDC_NEWKEY 1017
+#define IDC_IMPORTKEY 1018
Added: trunk/OpenPGPminidriverTest/Dialog.rc
===================================================================
--- trunk/OpenPGPminidriverTest/Dialog.rc 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/Dialog.rc 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,28 @@
+#include <Windows.h>
+#include "Dialog.h"
+
+IDD_DLG DIALOGEX -4,-16,475,385
+CAPTION "IDD_DLG"
+FONT 8,"MS Sans Serif",0,0,0
+STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW
+BEGIN
+ CONTROL "Connect",IDC_CONNECT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,9,39,54,21
+ CONTROL "Normal",IDC_CurrentDll,"Button",WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP|BS_AUTORADIOBUTTON,12,21,96,12
+ CONTROL "System Driver",IDC_SystemDll,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,12,6,96,12
+ CONTROL "Disconnect",IDC_DISCONNECT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,69,39,57,21
+ CONTROL "",IDC_TXTPIN,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP,12,90,93,21,WS_EX_CLIENTEDGE
+ CONTROL "Check PIN",IDC_PIN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,123,90,45,21
+ CONTROL "",IDC_FILES,"ListBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,186,9,153,108,WS_EX_CLIENTEDGE
+ CONTROL "List Files",IDC_LISTFILES,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,345,22,48,21
+ CONTROL "Admin",IDC_PINADMIN,"Button",WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP|BS_AUTORADIOBUTTON,57,75,36,12
+ CONTROL "User",IDC_PINUSER,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,12,75,33,13
+ CONTROL "",IDC_LSTCONTAINER,"ListBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,15,237,396,93,WS_EX_CLIENTEDGE
+ CONTROL "List container",IDC_CONTAINER,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,351,213,57,21
+ CONTROL "Double clic = show certificate",IDC_STC1,"Static",WS_CHILD|WS_VISIBLE,15,225,282,9
+ CONTROL "Sign",IDC_SIGN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,15,336,57,21
+ CONTROL "Decrypt",IDC_DECRYPT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,87,336,57,21
+ CONTROL "",IDC_CONTAINERINDEX,"ComboBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWNLIST,15,126,90,15
+ CONTROL "Generate new key",IDC_NEWKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,129,123,72,21
+ CONTROL "Import key",IDC_IMPORTKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,129,147,72,21
+END
+
Added: trunk/OpenPGPminidriverTest/InitializationAndDeconstruct.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/InitializationAndDeconstruct.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/InitializationAndDeconstruct.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,256 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <cardmod.h>
+
+#pragma comment(lib,"Scarddlg")
+#pragma comment(lib,"Winscard")
+
+HMODULE hModule = NULL;
+CARD_DATA CardData;
+PCARD_DATA pCardData = NULL;
+SCARD_ATRMASK atr;
+TCHAR szCard[256];
+
+extern "C" {
+
+ //
+ // Heap helpers
+ //
+
+ LPVOID WINAPI _Alloc(__in SIZE_T cBytes)
+ {
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes);
+ }
+
+ LPVOID WINAPI _ReAlloc(
+ __in LPVOID pvMem,
+ __in SIZE_T cBytes)
+ {
+ return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pvMem, cBytes);
+ }
+
+ void WINAPI _Free(
+ __in LPVOID pvMem)
+ {
+ HeapFree(GetProcessHeap(), 0, pvMem);
+ }
+
+ //
+ // Dummy data caching stubs to satisfy the card module callback requirements
+ //
+
+ DWORD WINAPI _CacheAddFileStub(
+ IN PVOID pvCacheContext,
+ IN LPWSTR wszTag,
+ IN DWORD dwFlags,
+ IN PBYTE pbData,
+ IN DWORD cbData)
+ {
+ UNREFERENCED_PARAMETER(pvCacheContext);
+ UNREFERENCED_PARAMETER(wszTag);
+ UNREFERENCED_PARAMETER(dwFlags);
+ UNREFERENCED_PARAMETER(pbData);
+ UNREFERENCED_PARAMETER(cbData);
+ return ERROR_SUCCESS;
+ }
+
+ DWORD WINAPI _CacheLookupFileStub(
+ IN PVOID pvCacheContext,
+ IN LPWSTR wszTag,
+ IN DWORD dwFlags,
+ IN PBYTE *ppbData,
+ IN PDWORD pcbData)
+ {
+ UNREFERENCED_PARAMETER(pvCacheContext);
+ UNREFERENCED_PARAMETER(wszTag);
+ UNREFERENCED_PARAMETER(dwFlags);
+ UNREFERENCED_PARAMETER(ppbData);
+ UNREFERENCED_PARAMETER(pcbData);
+ return ERROR_NOT_FOUND;
+ }
+
+ DWORD WINAPI _CacheDeleteFileStub(
+ IN PVOID pvCacheContext,
+ IN LPWSTR wszTag,
+ IN DWORD dwFlags)
+ {
+ UNREFERENCED_PARAMETER(pvCacheContext);
+ UNREFERENCED_PARAMETER(wszTag);
+ UNREFERENCED_PARAMETER(dwFlags);
+ return ERROR_SUCCESS;
+ }
+}
+
+DWORD Connect(BOOL fSystemDll)
+{
+ DWORD dwReturn = 0;
+ SCARDCONTEXT hSCardContext = NULL;
+ SCARDHANDLE hSCardHandle = NULL;
+ TCHAR szCardModule[256];
+ TCHAR szReader[256];
+ DWORD dwCardModuleSize = ARRAYSIZE(szCardModule);
+ DWORD dwReaderSize = ARRAYSIZE(szReader);
+ OPENCARDNAME_EX dlgStruct;
+ PFN_CARD_ACQUIRE_CONTEXT pfnCardAcquireContext;
+
+ __try
+ {
+ // find a smart card
+ /////////////////////
+
+ dwReturn = SCardEstablishContext(SCARD_SCOPE_USER,
+ NULL,
+ NULL,
+ &hSCardContext );
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+
+ // Initialize the structure.
+ memset(&dlgStruct, 0, sizeof(dlgStruct));
+ dlgStruct.dwStructSize = sizeof(dlgStruct);
+ dlgStruct.hSCardContext = hSCardContext;
+ dlgStruct.dwFlags = SC_DLG_MINIMAL_UI;
+ dlgStruct.lpstrRdr = szReader;
+ dlgStruct.nMaxRdr = dwReaderSize;
+ dlgStruct.lpstrCard = szCard;
+ dlgStruct.nMaxCard = ARRAYSIZE(szCard);
+ dlgStruct.lpstrTitle = L"Select Card";
+ dlgStruct.dwShareMode = 0;
+ // Display the select card dialog box.
+ dwReturn = SCardUIDlgSelectCard(&dlgStruct);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+
+ // find the dll path / name
+ ////////////////////////////
+ if (fSystemDll)
+ {
+
+ dwReturn = SCardGetCardTypeProviderName(
+ hSCardContext,
+ szCard,
+ SCARD_PROVIDER_CARD_MODULE,
+ (PTSTR) &szCardModule,
+ &dwCardModuleSize);
+ if (0 == dwCardModuleSize)
+ {
+ dwReturn = (DWORD) SCARD_E_UNKNOWN_CARD;
+ __leave;
+ }
+ }
+ else
+ {
+#ifdef WIN64
+ _tcscpy_s(szCardModule, dwCardModuleSize, TEXT("openpgpmdrv64.dll"));
+#else
+ _tcscpy_s(szCardModule, dwCardModuleSize, TEXT("openpgpmdrv32.dll"));
+#endif
+ }
+ // connect to the smart card
+ ////////////////////////////
+ DWORD dwProtocol, dwState;
+ dwReturn = SCardConnect(hSCardContext,szReader,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T1|SCARD_PROTOCOL_T0, &hSCardHandle, &dwProtocol);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ atr.cbAtr = 32;
+ dwReturn = SCardStatus(hSCardHandle, szReader, &dwReaderSize, &dwState, &dwProtocol, atr.rgbAtr,&atr.cbAtr);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ // load
+ ////////
+ if (NULL == (hModule = LoadLibrary(szCardModule)))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ if (NULL == (pfnCardAcquireContext =
+ (PFN_CARD_ACQUIRE_CONTEXT) GetProcAddress(
+ hModule, "CardAcquireContext")))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+ // initialize context
+ //////////////////////
+ pCardData = &CardData;
+ pCardData->dwVersion = CARD_DATA_CURRENT_VERSION;
+ pCardData->pfnCspAlloc = _Alloc;
+ pCardData->pfnCspFree = _Free;
+ pCardData->pfnCspReAlloc = _ReAlloc;
+ pCardData->pfnCspCacheAddFile = _CacheAddFileStub;
+ pCardData->pfnCspCacheLookupFile = _CacheLookupFileStub;
+ pCardData->pfnCspCacheDeleteFile = _CacheDeleteFileStub;
+ pCardData->hScard = hSCardHandle;
+ pCardData->hSCardCtx = hSCardContext;
+ pCardData->cbAtr = atr.cbAtr;
+ pCardData->pbAtr = atr.rgbAtr;
+ pCardData->pwszCardName = szCard;
+ dwReturn = SCardBeginTransaction(hSCardHandle);
+ if ( SCARD_S_SUCCESS != dwReturn )
+ {
+ __leave;
+ }
+ dwReturn = pfnCardAcquireContext(pCardData, 0);
+ }
+ __finally
+ {
+ if (dwReturn != 0)
+ {
+ if (hSCardHandle)
+ {
+ SCardEndTransaction(hSCardHandle,SCARD_LEAVE_CARD);
+ SCardDisconnect(hSCardHandle,0);
+ }
+ if (hSCardContext)
+ SCardReleaseContext(hSCardContext);
+ }
+ }
+ return dwReturn;
+}
+
+DWORD Disconnect()
+{
+ DWORD dwReturn = 0;
+ if (pCardData)
+ {
+ if (pCardData->hScard)
+ {
+ SCardEndTransaction(pCardData->hScard,SCARD_LEAVE_CARD);
+ SCardDisconnect(pCardData->hScard,0);
+ }
+ if (pCardData->hSCardCtx)
+ SCardReleaseContext(pCardData->hSCardCtx);
+ pCardData = NULL;
+ }
+ else
+ {
+ dwReturn = SCARD_E_COMM_DATA_LOST;
+ }
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/OpenPGPminidriverTest.vcproj
===================================================================
--- trunk/OpenPGPminidriverTest/OpenPGPminidriverTest.vcproj 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/OpenPGPminidriverTest.vcproj 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="OpenPGPminidriverTest"
+ ProjectGUID="{4E413ED7-0D68-47A9-AB93-39319815E730}"
+ RootNamespace="OpenPGPminidriverTest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)32.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)64.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)32.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)64.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\BaseCSP.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CryptoOperations.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\InitializationAndDeconstruct.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\PINOperations.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\PublicDataOperations.cpp"
+ >
+ </File>
+ <Filter
+ Name="UI"
+ >
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Dialog.h"
+ >
+ </File>
+ <File
+ RelativePath=".\global.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resources Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\Dialog.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\RegisterCardForTestIfTheDriverIsNotInstalled.reg"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: trunk/OpenPGPminidriverTest/PINOperations.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/PINOperations.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/PINOperations.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,75 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <cardmod.h>
+#include "global.h"
+
+DWORD Authenticate(PWSTR wszPin, PWSTR wszUserId, PDWORD pcAttemptsRemaining)
+{
+ LPSTR szPin = NULL;
+ DWORD cbPin = 0;
+ DWORD dwReturn;
+ __try
+ {
+ if (!pCardData)
+ {
+ dwReturn = SCARD_E_COMM_DATA_LOST;
+ __leave;
+ }
+ //
+ // Convert the PIN to ANSI
+ //
+ if (0 == (cbPin = WideCharToMultiByte(CP_ACP,0,wszPin,-1,NULL,0,NULL,NULL)))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ szPin = (LPSTR) LocalAlloc(0,cbPin);
+ if (szPin == NULL)
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ if (0 == (cbPin = WideCharToMultiByte(CP_ACP,0,wszPin,-1,szPin,cbPin,NULL,NULL)))
+ {
+ dwReturn = GetLastError();
+ __leave;
+ }
+
+ //
+ // Call the card module
+ //
+
+ dwReturn = pCardData->pfnCardAuthenticatePin(
+ pCardData,
+ wszUserId,
+ (PBYTE) szPin,
+ cbPin - 1,
+ pcAttemptsRemaining);
+ }
+ __finally
+ {
+ if (NULL != szPin)
+ LocalFree(szPin);
+ }
+
+ return dwReturn;
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/PublicDataOperations.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/PublicDataOperations.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/PublicDataOperations.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,83 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <cardmod.h>
+#include "global.h"
+#include "dialog.h"
+
+extern HWND hMainWnd;
+
+DWORD ListFiles(PSTR szDirectory)
+{
+ DWORD dwReturn = 0, dwSize;
+ LPSTR pszFiles = NULL;
+
+ dwSize = 0;
+ dwReturn = pCardData->pfnCardEnumFiles(pCardData, szDirectory, &pszFiles, &dwSize, 0);
+ if (!dwReturn)
+ {
+ LPSTR szCurrentFile = pszFiles;
+ while (szCurrentFile[0] != 0)
+ {
+ CHAR szText[256];
+ if (szDirectory)
+ {
+ sprintf_s(szText, ARRAYSIZE(szText),"%s\\%s",szDirectory, szCurrentFile);
+ }
+ else
+ {
+ sprintf_s(szText, ARRAYSIZE(szText),"%s",szCurrentFile);
+ }
+ SendDlgItemMessageA(hMainWnd,IDC_FILES,LB_ADDSTRING,0,(LPARAM)szText);
+ if (strcmp(szCurrentFile,"cardapps") == 0)
+ {
+ PBYTE pbData = NULL;
+ dwSize = 0;
+ dwReturn = pCardData->pfnCardReadFile(pCardData, szDirectory, szCurrentFile, 0, &pbData, &dwSize);
+ if (dwReturn == 0)
+ {
+ CHAR szDirectory[9];
+ for (DWORD dwI = 0; dwI < dwSize; dwI+=8)
+ {
+ memcpy(szDirectory, pbData + dwI, 8);
+ szDirectory[8] = 0;
+ ListFiles(szDirectory);
+ }
+
+ pCardData->pfnCspFree(pbData);
+ }
+ }
+
+ szCurrentFile = szCurrentFile + strlen(szCurrentFile)+1;
+ }
+ pCardData->pfnCspFree(pszFiles);
+ }
+ return dwReturn;
+}
+
+DWORD ListFiles()
+{
+ if (!pCardData)
+ {
+ return SCARD_E_COMM_DATA_LOST;
+ }
+ SendMessage(GetDlgItem(hMainWnd, IDC_FILES),LB_RESETCONTENT,0,0);
+ return ListFiles(NULL);
+}
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/RegisterCardForTestIfTheDriverIsNotInstalled.reg
===================================================================
--- trunk/OpenPGPminidriverTest/RegisterCardForTestIfTheDriverIsNotInstalled.reg 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/RegisterCardForTestIfTheDriverIsNotInstalled.reg 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,15 @@
+Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\OpenPGP]
+"ATR"= hex:3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C
+"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
+"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
+"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
+"80000001"="openpgpmdrv.dll"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\OpenPGP]
+"ATR"= hex:3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C
+"ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff
+"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
+"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"
+"80000001"="openpgpmdrv.dll"
Added: trunk/OpenPGPminidriverTest/global.h
===================================================================
--- trunk/OpenPGPminidriverTest/global.h 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/global.h 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,28 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+extern PCARD_DATA pCardData;
+DWORD Connect(BOOL fSystemDll);
+DWORD Disconnect();
+DWORD Authenticate(PWSTR wszPin, PWSTR wszUserId, PDWORD pcAttemptsRemaining);
+DWORD ListFiles();
+DWORD ListContainer();
+DWORD ViewCertificate(PTSTR szContainer, DWORD dwKeySpec);
+DWORD Sign(PTSTR szContainer, DWORD dwKeySpec);
+DWORD Decrypt(PTSTR szContainer, DWORD dwKeySpec);
+DWORD GenerateNewKey(DWORD dwIndex);
+DWORD ImportKey(DWORD dwIndex);
\ No newline at end of file
Added: trunk/OpenPGPminidriverTest/main.cpp
===================================================================
--- trunk/OpenPGPminidriverTest/main.cpp 2010-02-23 12:51:40 UTC (rev 0)
+++ trunk/OpenPGPminidriverTest/main.cpp 2010-02-23 19:18:59 UTC (rev 1)
@@ -0,0 +1,194 @@
+/* OpenPGP Smart Card Mini Driver
+ Copyright (C) 2009 Vincent Le Toux
+
+ This library is Free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <windows.h>
+#include <tchar.h>
+#include <cardmod.h>
+#include <commctrl.h>
+#include "dialog.h"
+#include "global.h"
+
+#ifdef UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_IA64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+// Variables globales :
+HINSTANCE hInst; // instance actuelle
+HWND hMainWnd;
+
+INT_PTR CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
+{
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+ hInst = hInstance;
+
+ DialogBox (hInst, MAKEINTRESOURCE (IDD_DLG), 0, WndProc);
+ return 0;
+
+}
+
+void MessageBoxWin32(DWORD status) {
+ LPVOID Error;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,status,0,(LPTSTR)&Error,0,NULL);
+ MessageBox(NULL,(LPCTSTR)Error,NULL,MB_ICONASTERISK);
+ LocalFree(Error);
+}
+
+BOOL GetContainerName(PWSTR szContainer, PDWORD pdwKeySpec)
+{
+ DWORD iItem = SendMessage(GetDlgItem(hMainWnd, IDC_LSTCONTAINER),LB_GETCURSEL,0,0);
+ if (iItem == LB_ERR) return FALSE;
+ SendMessage( GetDlgItem(hMainWnd,IDC_LSTCONTAINER), LB_GETTEXT,iItem,(LPARAM)szContainer);
+ *pdwKeySpec = _tstoi(szContainer + _tcslen(szContainer) - 1);
+ szContainer[ _tcslen(szContainer) - 2] = 0;
+ return TRUE;
+}
+
+INT_PTR CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+ DWORD dwReturn;
+ TCHAR szPin[256];
+ TCHAR szContainer[256];
+ DWORD dwKeySpec;
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ hMainWnd = hWnd;
+ CheckDlgButton(hWnd,IDC_CurrentDll,BST_CHECKED);
+ CheckDlgButton(hWnd,IDC_PINUSER,BST_CHECKED);
+ SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Signature"));
+ SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Authentication"));
+ SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX,CB_ADDSTRING,0,(LPARAM)TEXT("Confidentiality"));
+ SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX, CB_SETCURSEL, 0, 0);
+ break;
+
+ case WM_CLOSE:
+ EndDialog(hWnd, IDOK);
+ return TRUE;
+ case WM_COMMAND:
+ wmId = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+
+ switch (wmId)
+ {
+ case IDC_CONNECT:
+ if (IsDlgButtonChecked(hWnd,IDC_SystemDll))
+ {
+ dwReturn = Connect(TRUE);
+ }
+ else
+ {
+ dwReturn = Connect(FALSE);
+ }
+ if (dwReturn)
+ {
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_DISCONNECT:
+ dwReturn = Disconnect();
+ if (dwReturn)
+ {
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_PIN:
+ GetDlgItemText(hWnd,IDC_TXTPIN,szPin,ARRAYSIZE(szPin));
+ DWORD dwRemaining;
+ if (IsDlgButtonChecked(hWnd,IDC_PINADMIN))
+ {
+ dwReturn = Authenticate(szPin, wszCARD_USER_ADMIN, &dwRemaining);
+ }
+ else
+ {
+ dwReturn = Authenticate(szPin, wszCARD_USER_USER, &dwRemaining);
+ }
+ MessageBoxWin32(dwReturn);
+ break;
+ case IDC_LISTFILES:
+ dwReturn = ListFiles();
+ if (dwReturn)
+ {
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_NEWKEY:
+ dwReturn = GenerateNewKey(SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX, CB_GETCURSEL, 0, 0));
+ MessageBoxWin32(dwReturn);
+ break;
+ case IDC_IMPORTKEY:
+ dwReturn = ImportKey(SendDlgItemMessage(hMainWnd,IDC_CONTAINERINDEX, CB_GETCURSEL, 0, 0));
+ MessageBoxWin32(dwReturn);
+ break;
+ ////////// base CSP
+ case IDC_CONTAINER:
+ dwReturn = ListContainer();
+ if (dwReturn)
+ {
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_SIGN:
+ if (GetContainerName(szContainer, &dwKeySpec))
+ {
+ dwReturn = Sign(szContainer, dwKeySpec);
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_DECRYPT:
+ if (GetContainerName(szContainer, &dwKeySpec))
+ {
+ dwReturn = Decrypt(szContainer, dwKeySpec);
+ MessageBoxWin32(dwReturn);
+ }
+ break;
+ case IDC_LSTCONTAINER:
+ switch(wmEvent)
+ {
+ case LBN_DBLCLK:
+ if (GetContainerName(szContainer, &dwKeySpec))
+ {
+ dwReturn = ViewCertificate(szContainer, dwKeySpec);
+ if (dwReturn)
+ {
+ MessageBoxWin32(dwReturn);
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
More information about the Openpgpmdrv-commits
mailing list