├── OpenPGPminidriver ├── SmartCardOperations.c ├── DllMain.c ├── resource.h ├── version.rc ├── OpenPGPminidriver.def ├── CardPinOperation.c ├── CardPublicDataOperation.c ├── CardAndContainerProperties.c ├── CardCryptographicOperations.c ├── tlv.h ├── README.txt ├── SmartCard.h ├── Tracing.h ├── PinOperations.h ├── tlv.c ├── PublicDataOperations.h ├── Context.h ├── CryptoOperations.h ├── OpenPGPminidriver.vcxproj.filters ├── CardInitializationAndDeconstruct.c ├── CardSecureKeyInjection.c ├── openpgpmdrv.inf ├── CardKeyContainer.c ├── OpenPGPminidriver.vcproj ├── SmartCard.c └── OpenPGPminidriver.vcxproj ├── OpenPGPSetup ├── dlgbmp.bmp ├── bannrbmp.bmp ├── Resources │ ├── dlgbmp.bmp │ ├── bannrbmp.bmp │ ├── mysmartlogon.ico │ └── gnu-lgpl.rtf ├── openpgpmdrv-include.wxi ├── Product.wxs ├── OpenPGPSetup.wixproj └── gnu-lgpl.rtf ├── OpenPGPminidriverTest ├── main.cpp ├── RegisterCardForTestIfTheDriverIsNotInstalled.reg ├── Dialog.h ├── global.h ├── OpenPGPminidriverTest.vcxproj.filters ├── Dialog.rc ├── PublicDataOperations.cpp ├── PINOperations.cpp ├── Enrollment.cpp ├── InitializationAndDeconstruct.cpp ├── OpenPGPminidriverTest.vcproj ├── CryptoOperations.cpp ├── Personnalize.cpp └── OpenPGPminidriverTest.vcxproj ├── makemsi ├── openpgpmdrv-include.wxs ├── makemsi.cmd ├── openpgpmdrv32release.wxs ├── openpgpmdrv64release.wxs └── Resources │ └── gnu-lgpl.rtf ├── README.md ├── OpenPGPminidriver.sln └── .gitignore /OpenPGPminidriver/SmartCardOperations.c: -------------------------------------------------------------------------------- 1 | 2 | #include "SmartCardOperations.h" 3 | 4 | -------------------------------------------------------------------------------- /OpenPGPSetup/dlgbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPSetup/dlgbmp.bmp -------------------------------------------------------------------------------- /OpenPGPSetup/bannrbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPSetup/bannrbmp.bmp -------------------------------------------------------------------------------- /OpenPGPminidriver/DllMain.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/DllMain.c -------------------------------------------------------------------------------- /OpenPGPminidriver/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/resource.h -------------------------------------------------------------------------------- /OpenPGPminidriver/version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/version.rc -------------------------------------------------------------------------------- /OpenPGPminidriverTest/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriverTest/main.cpp -------------------------------------------------------------------------------- /OpenPGPSetup/Resources/dlgbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPSetup/Resources/dlgbmp.bmp -------------------------------------------------------------------------------- /OpenPGPminidriver/OpenPGPminidriver.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | 3 | EXPORTS 4 | CardAcquireContext 5 | EnableLogging 6 | DisableLogging -------------------------------------------------------------------------------- /OpenPGPSetup/Resources/bannrbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPSetup/Resources/bannrbmp.bmp -------------------------------------------------------------------------------- /OpenPGPminidriver/CardPinOperation.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/CardPinOperation.c -------------------------------------------------------------------------------- /makemsi/openpgpmdrv-include.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /OpenPGPSetup/Resources/mysmartlogon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPSetup/Resources/mysmartlogon.ico -------------------------------------------------------------------------------- /OpenPGPminidriver/CardPublicDataOperation.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/CardPublicDataOperation.c -------------------------------------------------------------------------------- /OpenPGPminidriver/CardAndContainerProperties.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/CardAndContainerProperties.c -------------------------------------------------------------------------------- /OpenPGPminidriver/CardCryptographicOperations.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vletoux/openpgpmdrv/HEAD/OpenPGPminidriver/CardCryptographicOperations.c -------------------------------------------------------------------------------- /OpenPGPminidriver/tlv.h: -------------------------------------------------------------------------------- 1 | DWORD getTlvSize(__in PBYTE pbPointer, __in PDWORD pdwOffset); 2 | BOOL find_tlv(__in PBYTE pbData, __in DWORD dwTlv, __in DWORD dwTotalSize, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize); 3 | -------------------------------------------------------------------------------- /OpenPGPSetup/openpgpmdrv-include.wxi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /OpenPGPminidriver/README.txt: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | Testing 19 | http://msdn.microsoft.com/en-us/library/dd327365.aspx 20 | 21 | cmck.exe is included in the "Windows Driver Kit (WDK)" -------------------------------------------------------------------------------- /OpenPGPminidriverTest/RegisterCardForTestIfTheDriverIsNotInstalled.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\OpenPGP] 4 | "ATR"= hex:3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C 5 | "ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff 6 | "Crypto Provider"="Microsoft Base Smart Card Crypto Provider" 7 | "Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" 8 | "80000001"="openpgpmdrv.dll" 9 | 10 | [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\OpenPGP] 11 | "ATR"= hex:3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,C5,73,C0,01,40,00,90,00,0C 12 | "ATRMask"=hex:ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff 13 | "Crypto Provider"="Microsoft Base Smart Card Crypto Provider" 14 | "Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" 15 | "80000001"="openpgpmdrv.dll" 16 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/Dialog.h: -------------------------------------------------------------------------------- 1 | #define IDD_MAIN 1000 2 | #define IDC_TAB1 1001 3 | #define IDD_CONNECT 1100 4 | #define IDC_SystemDll 1101 5 | #define IDC_CurrentDll 1102 6 | #define IDC_CONNECT 1103 7 | #define IDC_DISCONNECT 1104 8 | #define IDD_PIN 1200 9 | #define IDC_PINUSER 1201 10 | #define IDC_PINADMIN 1202 11 | #define IDC_PUK 1208 12 | #define IDC_SM 1212 13 | #define IDC_CHECKPIN 1203 14 | #define IDC_TXTPIN 1204 15 | #define IDC_TXTPIN2 1205 16 | #define IDC_CHANGEPIN 1206 17 | #define IDC_UNBLOCKPIN 1207 18 | #define IDC_SETPUK 1209 19 | #define IDC_PERSONNALIZE 1210 20 | #define IDC_SETSM 1211 21 | #define IDD_CRYPTO 1300 22 | #define IDC_SAMEKEY 1301 23 | #define IDC_IMPORTKEY 1302 24 | #define IDC_NEWKEY 1303 25 | #define IDC_CONTAINERINDEX 1304 26 | #define IDC_SETREADONLY 1305 27 | #define IDC_UNSETREADONLY 1306 28 | #define IDD_FILE 1400 29 | #define IDC_LISTFILES 1401 30 | #define IDC_STC2 1402 31 | #define IDC_CONTENT 1403 32 | #define IDC_FILES 1404 33 | #define IDD_CRYPTOAPI 1500 34 | #define IDC_DECRYPT 1501 35 | #define IDC_SIGN 1502 36 | #define IDC_STC1 1503 37 | #define IDC_CONTAINER 1504 38 | #define IDC_LSTCONTAINER 1505 39 | #define IDD_ENROLL 1600 40 | #define IDC_ENROLL 1601 41 | -------------------------------------------------------------------------------- /OpenPGPminidriver/SmartCard.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | DWORD OCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize); 19 | DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData); 20 | 21 | DWORD OCardGetData(__in PCARD_DATA pCardData, 22 | __in PBYTE pbCmd, __in DWORD dwCmdSize, 23 | __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize); 24 | 25 | DWORD CCIDgetFeatures(__in PCARD_DATA pCardData) ; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenPGP minidriver 2 | 3 | A minidriver for the OpenPGP card. 4 | 5 | These project should be considered in addition to the [OpenPGP CSP project](https://github.com/vletoux/OpenPGP-CSP). 6 | 7 | It has been designed to provide support for the OpenPGP card. 8 | 9 | ## Getting Started 10 | 11 | Open the solution in Visual Studio and build the project. 12 | The version used for the development is Visual Studio 2012 13 | 14 | ### Prerequisites 15 | 16 | The current release is signed by a SHA2 certificate (kernel mode signing). 17 | That means that the [Microsoft Security Advisory 3033929](https://docs.microsoft.com/en-us/security-updates/securityadvisories/2015/3033929) MUST be installed. 18 | 19 | ## Running the tests 20 | 21 | Run certutil -scinfo (beware of the 32 or 64 bits version when doing test - c:\windows\syswow64\certutil.exe is the 32 bits one) 22 | and double check that the Card name is filled. 23 | 24 | ### Certutil test with the "Open PGP Card v2" 25 | 26 | 27 | 28 | ``` 29 | 0: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0 30 | --- Lecteur�: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0 31 | --- Statut�: SCARD_STATE_PRESENT | SCARD_STATE_UNPOWERED 32 | --- Statut�: Carte disponible pour utilisation. 33 | --- Carte�: OpenPGP 34 | --- ATR�: 35 | 3b da 18 ff 81 b1 fe 75 1f 03 00 31 c5 73 c0 01 ;......u...1.s.. 36 | 40 00 90 00 0c @.... 37 | ``` 38 | 39 | ## Authors 40 | 41 | * **Vincent LE TOUX** - *Initial commit* 42 | 43 | ## License 44 | 45 | This project is licensed under the LGPL License 46 | 47 | -------------------------------------------------------------------------------- /OpenPGPminidriver/Tracing.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #pragma once 19 | 20 | #define WINEVENT_LEVEL_CRITICAL 1 21 | #define WINEVENT_LEVEL_ERROR 2 22 | #define WINEVENT_LEVEL_WARNING 3 23 | #define WINEVENT_LEVEL_INFO 4 24 | #define WINEVENT_LEVEL_VERBOSE 5 25 | 26 | void TracingRegister(); 27 | void TracingUnRegister(); 28 | extern BOOL fRunOnVistaAndLater; 29 | 30 | #define Trace(dwLevel, ...) \ 31 | TraceEx(__FILE__,__LINE__,__FUNCTION__, dwLevel, __VA_ARGS__); 32 | 33 | void TraceEx(PCSTR szFile, DWORD dwLine, PCSTR szFunction, UCHAR dwLevel, PCWSTR szFormat,...); 34 | 35 | void TraceDumpEx(LPCSTR szFile, DWORD dwLine, LPCSTR szFunction, UCHAR dwLevel, 36 | __in PBYTE pbCmd, __in DWORD dwCmdSize); 37 | 38 | #define TraceDump(dwLevel, pbCmd,dwCmdSize) \ 39 | TraceDumpEx(__FILE__,__LINE__,__FUNCTION__, dwLevel, pbCmd,dwCmdSize); -------------------------------------------------------------------------------- /OpenPGPminidriverTest/global.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | extern PCARD_DATA pCardData; 19 | DWORD Connect(BOOL fSystemDll); 20 | DWORD Disconnect(); 21 | DWORD Authenticate(PSTR wszPin, PWSTR wszUserId, PDWORD pcAttemptsRemaining); 22 | DWORD ResetPin(PSTR wszPin, PSTR wszPin2, BOOL fIsPUK, PDWORD pcAttemptsRemaining); 23 | DWORD ChangePin(PSTR szPin, PSTR szPin2, PWSTR wszUserId, PDWORD pcAttemptsRemaining); 24 | DWORD SetPuk(PSTR szPin, PSTR szPin2, PDWORD pcAttemptsRemaining); 25 | DWORD SetSM(PSTR szPin, PSTR szPin2, PDWORD pcAttemptsRemaining); 26 | DWORD ListFiles(HWND hWnd); 27 | DWORD ViewFile(HWND hWnd); 28 | DWORD ListContainer(HWND hWnd); 29 | DWORD ViewCertificate(HWND hWnd, PTSTR szContainer, DWORD dwKeySpec); 30 | DWORD Sign(PTSTR szContainer, DWORD dwKeySpec); 31 | DWORD Decrypt(PTSTR szContainer, DWORD dwKeySpec); 32 | DWORD GenerateNewKey(DWORD dwIndex); 33 | DWORD ImportKey(DWORD dwIndex); 34 | DWORD SetTheSameKeyForAllContainers(); 35 | DWORD SetReadOnly(BOOL fSet); 36 | void ViewCertificate(HWND hWnd, PCCERT_CONTEXT pCertContext); 37 | DWORD Personnalize(); 38 | HRESULT Enroll(); 39 | #define OPENPGP_TEST_CONTAINER TEXT("Test_OPENPGPG") -------------------------------------------------------------------------------- /OpenPGPminidriver/PinOperations.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | 19 | #define ROLE_SIGNATURE ROLE_USER 20 | #define ROLE_AUTHENTICATION 3 21 | #define ROLE_PUK 4 22 | 23 | DWORD CheckPinLength(__in PCARD_DATA pCardData, __in PIN_ID PinId, __in DWORD cbPin); 24 | DWORD GetRemainingPin(__in PCARD_DATA pCardData, __in PIN_ID PinId, __out PDWORD pdwCounter); 25 | DWORD VerifyPIN(__in PCARD_DATA pCardData,__in PIN_ID PinId, 26 | __in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin) 27 | ; 28 | DWORD ChangePIN(__in PCARD_DATA pCardData, __in PIN_ID PinId, 29 | __in_bcount(cbPin) PBYTE pbOldPin, __in DWORD cbOldPin, 30 | __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin 31 | ); 32 | DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId, 33 | __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator, 34 | __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin 35 | ); 36 | DWORD SetPUK(__in PCARD_DATA pCardData, 37 | __in_bcount(cbPin) PBYTE pbAdminPin, __in DWORD cbAdminPin, 38 | __in_bcount(cbPin) PBYTE pbPuk, __in DWORD cbPuk 39 | ); 40 | DWORD Deauthenticate(__in PCARD_DATA pCardData); 41 | DWORD GetPinInfo(DWORD __in bContainerIndex, __inout PPIN_INFO pPinInfo); 42 | -------------------------------------------------------------------------------- /OpenPGPminidriver/tlv.c: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | 20 | 21 | 22 | DWORD getTlvSize(__in PBYTE pbPointer, __in PDWORD pdwOffset) 23 | { 24 | DWORD dwSize; 25 | switch(*pbPointer) 26 | { 27 | case 0x81: 28 | *pdwOffset+=2; 29 | dwSize = pbPointer[1]; 30 | break; 31 | case 0x82: 32 | *pdwOffset+=3; 33 | dwSize = pbPointer[1] * 0x100 + pbPointer[2]; 34 | break; 35 | default: 36 | dwSize = *pbPointer; 37 | *pdwOffset+=1; 38 | break; 39 | } 40 | return dwSize; 41 | } 42 | 43 | /** used to parse tlv data returned when reading the public certificate */ 44 | BOOL find_tlv(__in PBYTE pbData, __in DWORD dwTlvSearched, __in DWORD dwTotalSize, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize) 45 | { 46 | DWORD dwOffset = 0, dwTlv ; 47 | DWORD dwSize; 48 | BOOL bFound = FALSE; 49 | while (dwOffset < dwTotalSize) 50 | { 51 | // check the tlv 52 | // if it begins with 0x5F => tlv of 2 bytes. 53 | // else 1 byte 54 | dwTlv = 0; 55 | if (pbData[dwOffset] == 0x5F) 56 | { 57 | dwTlv = pbData[dwOffset] * 0x100; 58 | dwOffset++; 59 | } 60 | dwTlv += pbData[dwOffset]; 61 | dwOffset++; 62 | 63 | 64 | if (dwTlv == dwTlvSearched) 65 | { 66 | // size sequence 67 | dwSize = getTlvSize(pbData + dwOffset,&dwOffset); 68 | if (pdwSize) 69 | { 70 | *pdwSize = dwSize; 71 | } 72 | *pbDataOut = pbData + dwOffset; 73 | return TRUE; 74 | } 75 | else 76 | { 77 | dwSize = getTlvSize(pbData + dwOffset,&dwOffset); 78 | if (dwTlv != 0x73) 79 | { 80 | dwOffset += dwSize; 81 | } 82 | } 83 | } 84 | return FALSE; 85 | } 86 | -------------------------------------------------------------------------------- /makemsi/makemsi.cmd: -------------------------------------------------------------------------------- 1 | ::@echo off 2 | set VERSION=1.0.0.0 3 | 4 | set WIX_PATH="C:\Program Files (x86)\Windows Installer XML v3\bin" 5 | :: Inf2cat and signtool are installed by Windows Driver Kit: 6 | set INF2CAT_PATH=C:\WinDDK\7600.16385.0\bin\selfsign 7 | set SIGNTOOL_PATH=C:\WinDDK\7600.16385.0\bin\x86 8 | 9 | :: Certificate name and store 10 | ::set CERTIFICATENAME=Fedict eID(test) 11 | ::set CERTIFICATESTORE=PrivateCertStore 12 | :: To create a test certificate: 13 | :: %SIGNTOOL_PATH%\MakeCert.exe -r -pe -ss %CERTIFICATESTORE% -n "CN=%CERTIFICATENAME%" fedicteidtest.cer 14 | 15 | :: Path to images 16 | set IMG_PATH=..\img 17 | 18 | set BUILDPATH=%~dp0 19 | 20 | cd %BUILDPATH% 21 | 22 | md %BUILDPATH%\Release 23 | md %BUILDPATH%\Build 24 | 25 | :: copy inf files 26 | copy %BUILDPATH%\..\OpenPGPminidriver\openpgpmdrv.inf %BUILDPATH%\Release 27 | 28 | :: copy dll files 29 | copy %BUILDPATH%\..\Release\openpgpmdrv32.dll %BUILDPATH%\Release 30 | copy %BUILDPATH%\..\Release\openpgpmdrv64.dll %BUILDPATH%\Release 31 | 32 | :: copy icon 33 | ::copy %IMG_PATH%\beid.ico %BUILDPATH%\Release\ 34 | 35 | :: Create catalog 36 | %INF2CAT_PATH%\inf2cat.exe /driver:%BUILDPATH%\Release\ /os:Vista_X86,Vista_X64,7_X86,7_X64,Server2008R2_X64,Server2008_X64,Server2008_X86,Server2003_X64,Server2003_X86,XP_X64,XP_X86 37 | 38 | :: Sign the catalog 39 | ::%SIGNTOOL_PATH%\SignTool.exe sign /v /s %CERTIFICATESTORE% /n "%CERTIFICATENAME%" /t http://timestamp.verisign.com/scripts/timestamp.dll %BUILDPATH%\Debug\openpgpmdrv.cat 40 | ::%SIGNTOOL_PATH%\SignTool.exe sign /v /s %CERTIFICATESTORE% /n "%CERTIFICATENAME%" /t http://timestamp.verisign.com/scripts/timestamp.dll %BUILDPATH%\Release\openpgpmdrv.cat 41 | 42 | :: Create MSI 64 bit Release 43 | %WIX_PATH%\candle -dVersion=%VERSION% -ext %WIX_PATH%\WixDifxAppExtension.dll openpgpmdrv64release.wxs 44 | %WIX_PATH%\light -ext %WIX_PATH%\WixDifxAppExtension.dll -ext WixUIExtension openpgpmdrv64release.wixobj %WIX_PATH%\difxapp_x64.wixlib -o Build\OpenPGPmdrv-%VERSION%-x64.msi 45 | 46 | :: Create MSI 32 bit Release 47 | %WIX_PATH%\candle -dVersion=%VERSION% -ext %WIX_PATH%\WixDifxAppExtension.dll openpgpmdrv32release.wxs 48 | %WIX_PATH%\light -ext %WIX_PATH%\WixDifxAppExtension.dll -ext WixUIExtension openpgpmdrv32release.wixobj %WIX_PATH%\difxapp_x86.wixlib -o Build\OpenPGPmdrv-%VERSION%-x86.msi 49 | 50 | :: Cleanup 51 | del openpgpmdrv32release.wixobj 52 | del Build\OpenPGPmdrv-%VERSION%-x86.wixpdb 53 | 54 | del openpgpmdrv64release.wixobj 55 | del Build\OpenPGPmdrv-%VERSION%-x64.wixpdb 56 | 57 | pause -------------------------------------------------------------------------------- /OpenPGPminidriver/PublicDataOperations.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | // max len = 8 bytes 19 | #define szOpenPGPDir "openpgp" 20 | #define szOpenPGPFingerprint "fingerpr" 21 | #define szOpenPGPStatus "status" 22 | #define szOpenPGPStatusPW1 "statusP1" 23 | #define szOpenPGPApplicationIdentifier "aid" 24 | #define szOpenPGPLogin "logindat" 25 | #define szOpenPGPName "name" 26 | #define szOpenPGPLanguage "language" 27 | #define szOpenPGPSex "sex" 28 | #define szOpenPGPUrl "url" 29 | #define szOpenPGPHistoricalBytes "histo" 30 | #define szOpenPGPCertificate "certific" 31 | #define szOpenPGPExtendedCap "extcapab" 32 | #define szOpenPGPAlgoAttributesSignature "algsign" 33 | #define szOpenPGPAlgoAttributesDecryption "algcryp" 34 | #define szOpenPGPAlgoAttributesAuthentication "algauth" 35 | #define szOpenPGPPUK "puk" 36 | #define szOpenPGPSecureMessaging "sm" 37 | #define szOpenPGPSecureMessagingCryptographicCheksum "smmac" 38 | #define szOpenPGPSecureMessagingCryptogram "smenc" 39 | 40 | 41 | DWORD OCardReadFile(__in PCARD_DATA pCardData, 42 | __in_opt PSTR szDirectory, __in PSTR file, 43 | __in PBYTE* pbResponse, __in PDWORD pdwResponseSize); 44 | 45 | DWORD OCardEnumFile(__in PCARD_DATA pCardData, 46 | __in_opt PSTR szDirectory, 47 | __in PBYTE* pbResponse, __in PDWORD pdwResponseSize); 48 | 49 | DWORD OCardGetFileInfo(__in PCARD_DATA pCardData, 50 | __in_opt PSTR szDirectory, __in PSTR szFile, 51 | __inout PCARD_FILE_INFO pCardFileInfo); 52 | 53 | DWORD OCardWriteFile(__in PCARD_DATA pCardData, 54 | __in_opt PSTR szDirectory, __in PSTR szFile, 55 | __in PBYTE pbData, __in DWORD dwSize); 56 | 57 | DWORD OCardDeleteFile(__in PCARD_DATA pCardData, 58 | __in_opt PSTR szDirectory, __in PSTR szFile); 59 | 60 | DWORD OCardCreateFile(__in PCARD_DATA pCardData, 61 | __in_opt PSTR szDirectory, __in PSTR szFile); -------------------------------------------------------------------------------- /OpenPGPminidriverTest/OpenPGPminidriverTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {83c4341a-449c-4c0a-9fc1-d30c12d925c7} 10 | 11 | 12 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 13 | h;hpp;hxx;hm;inl;inc;xsd 14 | 15 | 16 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 17 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files\UI 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | 58 | 59 | Resources Files 60 | 61 | 62 | 63 | 64 | Resources Files 65 | 66 | 67 | -------------------------------------------------------------------------------- /OpenPGPminidriver/Context.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | 19 | typedef struct _OPENPGP_AID 20 | { 21 | BYTE AidRid[5]; 22 | BYTE AidApplication[1]; 23 | BYTE AidVersion[2]; 24 | BYTE AidManufacturer[2]; 25 | BYTE AidSerialNumber[4]; 26 | BYTE AidRFU[2]; 27 | } OPENPGP_AID; 28 | 29 | #define FEATURE_VERIFY_PIN_START 0x01 30 | #define FEATURE_VERIFY_PIN_FINISH 0x02 31 | #define FEATURE_MODIFY_PIN_START 0x03 32 | #define FEATURE_MODIFY_PIN_FINISH 0x04 33 | #define FEATURE_GET_KEY_PRESSED 0x05 34 | #define FEATURE_VERIFY_PIN_DIRECT 0x06 35 | #define FEATURE_MODIFY_PIN_DIRECT 0x07 36 | #define FEATURE_MCT_READERDIRECT 0x08 37 | #define FEATURE_MCT_UNIVERSAL 0x09 38 | #define FEATURE_IFD_PIN_PROPERTIES 0x0A 39 | #define FEATURE_ABORT 0x0B 40 | 41 | typedef struct _FEATURES 42 | { 43 | DWORD VERIFY_PIN_START; 44 | DWORD VERIFY_PIN_FINISH; 45 | DWORD VERIFY_PIN_DIRECT; 46 | DWORD MODIFY_PIN_START; 47 | DWORD MODIFY_PIN_FINISH; 48 | DWORD MODIFY_PIN_DIRECT; 49 | DWORD ABORT; 50 | DWORD GET_KEY_PRESSED; 51 | } FEATURES, *PFEATURES; 52 | 53 | #define KEYMAX 3 54 | typedef struct _OPENPGP_CONTEXT 55 | { 56 | OPENPGP_AID Aid; 57 | FEATURES SmartCardReaderFeatures; 58 | BOOL fSupportCommandChaining; 59 | BOOL fExtentedLeLcFields; 60 | DWORD dwMaxChallengeLength; 61 | DWORD dwMaxCertificateLength; 62 | DWORD dwMaxCommandDataLength; 63 | DWORD dwMaxResponseLength; 64 | BOOL fHasKey[KEYMAX]; 65 | BOOL fIsReadOnly; 66 | BYTE bFingerPrint[60]; 67 | PBYTE pbModulusInLittleEndian[KEYMAX]; 68 | WORD dwModulusSizeInBytes[KEYMAX]; 69 | DWORD dwExponent[KEYMAX]; 70 | LARGE_INTEGER LastCacheCheck[KEYMAX]; 71 | BOOL fDoesTheAdminHasBeenAuthenticatedAtLeastOnce; 72 | ALG_ID aiSecureMessagingAlg; 73 | } OPENPGP_CONTEXT, *POPENPGP_CONTEXT ; 74 | 75 | DWORD CreateContext(__in PCARD_DATA pCardData, __in DWORD dwFlags); 76 | DWORD CheckContext(__in PCARD_DATA pCardData); 77 | DWORD CleanContext(__in PCARD_DATA pCardData); -------------------------------------------------------------------------------- /makemsi/openpgpmdrv32release.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | SELFFOUND 25 | NEWERFOUND 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /OpenPGPminidriver/CryptoOperations.h: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | typedef enum _OPENPGP_CONTAINER 19 | { 20 | ContainerSignature, 21 | ContainerConfidentiality, 22 | ContainerAuthentication, 23 | ContainerMax 24 | } OPENPGP_CONTAINER; 25 | 26 | typedef enum _OPENPGP_KEY 27 | { 28 | KeySignature, 29 | KeyConfidentiality, 30 | KeyAuthentication, 31 | KeyMax 32 | } OPENPGP_KEY; 33 | 34 | typedef struct _OPENPGP_KEY_INFO 35 | { 36 | BYTE bKeyTag; 37 | BYTE bDateTimeTag; 38 | BYTE bSignatureTag; 39 | ALG_ID aiKeyAlg; 40 | } OPENPGP_KEY_INFO, *POPENPGP_KEY_INFO; 41 | 42 | extern OPENPGP_KEY_INFO Keys[]; 43 | 44 | typedef struct _OPENPGP_CONTAINER_INFO 45 | { 46 | PIN_ID PinId; 47 | DWORD dwKeySpec; 48 | } OPENPGP_CONTAINER_INFO, *POPENPGP_CONTAINER_INFO; 49 | 50 | extern OPENPGP_CONTAINER_INFO Containers[]; 51 | 52 | #define OPENPGP_SUPPORTED_CYPHER_ALGORITHM L"\0" 53 | #define OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM L"RSA\0" 54 | 55 | #pragma pack(push,1) 56 | typedef struct _OPENPGP_ALGORITHM_ATTRIBUTE 57 | { 58 | BYTE bAlgoId; 59 | unsigned short wModulusLengthInBit; 60 | unsigned short wExponentLengthInBit; 61 | BYTE bFormat; 62 | } OPENPGP_ALGORITHM_ATTRIBUTE, *POPENPGP_ALGORITHM_ATTRIBUTE; 63 | #pragma pack(pop) 64 | 65 | DWORD OCardReadPublicKey(PCARD_DATA pCardData, 66 | OPENPGP_KEY dwKey, 67 | PBYTE *pbPublicKey, PDWORD pdwPublicKeySize); 68 | 69 | DWORD OCardCreateKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, DWORD dwBitLen); 70 | 71 | DWORD OCardImportKey(PCARD_DATA pCardData, 72 | OPENPGP_KEY dwKey, 73 | PBYTE pBlob, 74 | DWORD dwKeySize); 75 | 76 | DWORD OCardSign(PCARD_DATA pCardData, 77 | PCARD_SIGNING_INFO pInfo); 78 | 79 | DWORD OCardAuthenticate(PCARD_DATA pCardData, 80 | PCARD_SIGNING_INFO pInfo); 81 | 82 | DWORD OCardDecrypt(PCARD_DATA pCardData, 83 | PCARD_RSA_DECRYPT_INFO pInfo); 84 | 85 | DWORD OCardReadContainerMapFile(__in PCARD_DATA pCardData, 86 | __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize); 87 | 88 | DWORD OCardGetKeyLengthInBytes(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey, 89 | __out PDWORD pdwLengthInBytes); 90 | 91 | DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData); -------------------------------------------------------------------------------- /OpenPGPminidriver.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenPGPminidriver", "OpenPGPminidriver\OpenPGPminidriver.vcxproj", "{775DAB1D-5A49-4A57-B259-AD3DC833A75F}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenPGPminidriverTest", "OpenPGPminidriverTest\OpenPGPminidriverTest.vcxproj", "{4E413ED7-0D68-47A9-AB93-39319815E730}" 7 | EndProject 8 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "OpenPGPSetup", "OpenPGPSetup\OpenPGPSetup.wixproj", "{24A3ABBC-4BD3-49F9-8883-61D26AAE1A92}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F} = {775DAB1D-5A49-4A57-B259-AD3DC833A75F} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x64.ActiveCfg = Debug|x64 22 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x64.Build.0 = Debug|x64 23 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x86.ActiveCfg = Debug|Win32 24 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x86.Build.0 = Debug|Win32 25 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Debug|x86.Deploy.0 = Debug|Win32 26 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x64.ActiveCfg = Release|x64 27 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x64.Build.0 = Release|x64 28 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x86.ActiveCfg = Release|Win32 29 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x86.Build.0 = Release|Win32 30 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F}.Release|x86.Deploy.0 = Release|Win32 31 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x64.ActiveCfg = Debug|x64 32 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x64.Build.0 = Debug|x64 33 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x86.ActiveCfg = Debug|Win32 34 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x86.Build.0 = Debug|Win32 35 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Debug|x86.Deploy.0 = Debug|Win32 36 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x64.ActiveCfg = Release|x64 37 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x64.Build.0 = Release|x64 38 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x86.ActiveCfg = Release|Win32 39 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x86.Build.0 = Release|Win32 40 | {4E413ED7-0D68-47A9-AB93-39319815E730}.Release|x86.Deploy.0 = Release|Win32 41 | {24A3ABBC-4BD3-49F9-8883-61D26AAE1A92}.Debug|x64.ActiveCfg = Debug|x64 42 | {24A3ABBC-4BD3-49F9-8883-61D26AAE1A92}.Debug|x86.ActiveCfg = Debug|x86 43 | {24A3ABBC-4BD3-49F9-8883-61D26AAE1A92}.Release|x64.ActiveCfg = Release|x64 44 | {24A3ABBC-4BD3-49F9-8883-61D26AAE1A92}.Release|x86.ActiveCfg = Release|x86 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /makemsi/openpgpmdrv64release.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | SELFFOUND 25 | NEWERFOUND 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /OpenPGPminidriver/OpenPGPminidriver.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {837fc4be-d865-4ba0-8c08-07e4a80f552a} 14 | 15 | 16 | {607493fb-0026-4e10-b7b5-4a7cc3b077fd} 17 | 18 | 19 | {f1f42f9d-603d-444c-a1b6-a4ea7bc2a114} 20 | 21 | 22 | 23 | 24 | 3%29 Microsoft Interface 25 | 26 | 27 | 3%29 Microsoft Interface 28 | 29 | 30 | 3%29 Microsoft Interface 31 | 32 | 33 | 3%29 Microsoft Interface 34 | 35 | 36 | 3%29 Microsoft Interface 37 | 38 | 39 | 3%29 Microsoft Interface 40 | 41 | 42 | 3%29 Microsoft Interface 43 | 44 | 45 | 3%29 Microsoft Interface 46 | 47 | 48 | 1%29 Low level 49 | 50 | 51 | 1%29 Low level 52 | 53 | 54 | 2%29 Application 55 | 56 | 57 | 2%29 Application 58 | 59 | 60 | 2%29 Application 61 | 62 | 63 | 2%29 Application 64 | 65 | 66 | 2%29 Application 67 | 68 | 69 | 70 | 71 | Header Files 72 | 73 | 74 | Header Files 75 | 76 | 77 | Header Files 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | Header Files 90 | 91 | 92 | Header Files 93 | 94 | 95 | Header Files 96 | 97 | 98 | 99 | 100 | Resources Files 101 | 102 | 103 | Resources Files 104 | 105 | 106 | 107 | 108 | 109 | Resources Files 110 | 111 | 112 | -------------------------------------------------------------------------------- /OpenPGPSetup/Product.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Privileged 21 | 22 | 23 | 24 | 25 | VersionNT64 26 | 27 | 28 | 29 | Not VersionNT64 30 | 31 | 32 | 33 | 34 | 37 | 40 | 42 | 43 | 44 | 45 | 46 | SELFFOUND 47 | NEWERFOUND 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/Dialog.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Dialog.h" 3 | 4 | IDD_MAIN DIALOGEX -4,-16,475,385 5 | CAPTION "IDD_MAIN" 6 | FONT 8,"MS Sans Serif",0,0,0 7 | STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW 8 | BEGIN 9 | CONTROL "",IDC_TAB1,"SysTabControl32",WS_CHILD|WS_VISIBLE|WS_TABSTOP|TCS_FOCUSNEVER,0,3,474,381 10 | END 11 | 12 | IDD_CONNECT DIALOGEX 10,10,400,300 13 | CAPTION "IDD_MAIN" 14 | FONT 8,"MS Sans Serif",0,0,0 15 | STYLE WS_CHILDWINDOW|WS_VISIBLE 16 | BEGIN 17 | CONTROL "System Driver",IDC_SystemDll,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,12,6,96,12 18 | CONTROL "Normal",IDC_CurrentDll,"Button",WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP|BS_AUTORADIOBUTTON,12,21,96,12 19 | CONTROL "Connect",IDC_CONNECT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,9,39,54,21 20 | CONTROL "Disconnect",IDC_DISCONNECT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,69,39,57,21 21 | END 22 | 23 | IDD_PIN DIALOGEX 0,0,400,300 24 | CAPTION "IDD_MAIN" 25 | FONT 8,"MS Sans Serif",0,0,0 26 | STYLE NOT WS_VISIBLE|WS_CHILDWINDOW 27 | BEGIN 28 | CONTROL "User",IDC_PINUSER,"Button",WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP|BS_AUTORADIOBUTTON,6,15,33,13 29 | CONTROL "Admin",IDC_PINADMIN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,51,15,36,12 30 | CONTROL "Puk",IDC_PUK,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,93,15,36,12 31 | CONTROL "Secure Messaging",IDC_SM,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTORADIOBUTTON,138,15,87,12 32 | CONTROL "Check PIN",IDC_CHECKPIN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,162,36,54,21 33 | CONTROL "",IDC_TXTPIN,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP,9,36,138,21,WS_EX_CLIENTEDGE 34 | CONTROL "",IDC_TXTPIN2,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP,9,63,381,21,WS_EX_CLIENTEDGE 35 | CONTROL "Change Pin",IDC_CHANGEPIN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,165,87,54,21 36 | CONTROL "Unblock Pin",IDC_UNBLOCKPIN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,223,87,54,22 37 | CONTROL "Set Puk",IDC_SETPUK,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,282,87,54,21 38 | CONTROL "Personnalize after the admin pin to succeed ms test for the driver",IDC_PERSONNALIZE,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,12,228,345,27 39 | CONTROL "Set SM",IDC_SETSM,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,339,87,51,21 40 | END 41 | 42 | IDD_CRYPTO DIALOGEX 0,0,400,300 43 | CAPTION "IDD_MAIN" 44 | FONT 8,"MS Sans Serif",0,0,0 45 | STYLE NOT WS_VISIBLE|WS_CHILDWINDOW 46 | BEGIN 47 | CONTROL "Set same key for all containers",IDC_SAMEKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,150,18,105,36 48 | CONTROL "Import key",IDC_IMPORTKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,42,63,72,21 49 | CONTROL "Generate new key",IDC_NEWKEY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,42,39,72,21 50 | CONTROL "",IDC_CONTAINERINDEX,"ComboBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWNLIST,39,18,90,15 51 | CONTROL "Set readonly",IDC_SETREADONLY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,174,117,57,24 52 | CONTROL "Unset readonly",IDC_UNSETREADONLY,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,174,147,57,24 53 | END 54 | 55 | IDD_FILE DIALOGEX 10,10,400,300 56 | CAPTION "IDD_MAIN" 57 | FONT 8,"MS Sans Serif",0,0,0 58 | STYLE NOT WS_VISIBLE|WS_CHILDWINDOW 59 | BEGIN 60 | CONTROL "List Files",IDC_LISTFILES,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,177,18,48,21 61 | CONTROL "File content :",IDC_STC2,"Static",WS_CHILD|WS_VISIBLE,15,132,118,9 62 | CONTROL "",IDC_CONTENT,"Edit",WS_CHILD|WS_VISIBLE|WS_DISABLED|WS_TABSTOP|ES_MULTILINE,15,144,154,64,WS_EX_CLIENTEDGE 63 | CONTROL "",IDC_FILES,"ListBox",WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,15,21,153,108,WS_EX_CLIENTEDGE 64 | END 65 | 66 | IDD_CRYPTOAPI DIALOGEX 0,0,400,300 67 | CAPTION "IDD_MAIN" 68 | FONT 8,"MS Sans Serif",0,0,0 69 | STYLE NOT WS_VISIBLE|WS_CHILDWINDOW 70 | BEGIN 71 | CONTROL "Decrypt",IDC_DECRYPT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,78,132,57,21 72 | CONTROL "Sign",IDC_SIGN,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,6,132,57,21 73 | CONTROL "Double clic = show certificate",IDC_STC1,"Static",WS_CHILD|WS_VISIBLE,6,21,282,9 74 | CONTROL "List container",IDC_CONTAINER,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,321,9,57,21 75 | CONTROL "",IDC_LSTCONTAINER,"ListBox",WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_HASSTRINGS|LBS_NOTIFY,6,33,378,93,WS_EX_CLIENTEDGE 76 | END 77 | 78 | IDD_ENROLL DIALOGEX 0,0,400,300 79 | CAPTION "IDD_DLG" 80 | FONT 8,"MS Sans Serif",0,0,0 81 | STYLE NOT WS_VISIBLE|WS_CHILDWINDOW 82 | BEGIN 83 | CONTROL "Enroll new certificate",IDC_ENROLL,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,48,27,111,24 84 | END 85 | 86 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/PublicDataOperations.cpp: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include "cardmod.h" 22 | #include "global.h" 23 | #include "dialog.h" 24 | 25 | 26 | DWORD ListFiles(HWND hWnd, PSTR szDirectory) 27 | { 28 | DWORD dwReturn = 0, dwSize; 29 | LPSTR pszFiles = NULL; 30 | 31 | dwSize = 0; 32 | dwReturn = pCardData->pfnCardEnumFiles(pCardData, szDirectory, &pszFiles, &dwSize, 0); 33 | if (!dwReturn) 34 | { 35 | LPSTR szCurrentFile = pszFiles; 36 | while (szCurrentFile[0] != 0) 37 | { 38 | CHAR szText[256]; 39 | if (szDirectory) 40 | { 41 | sprintf_s(szText, ARRAYSIZE(szText),"%s\\%s",szDirectory, szCurrentFile); 42 | } 43 | else 44 | { 45 | sprintf_s(szText, ARRAYSIZE(szText),"%s",szCurrentFile); 46 | } 47 | SendDlgItemMessageA(hWnd,IDC_FILES,LB_ADDSTRING,0,(LPARAM)szText); 48 | if (_stricmp(szCurrentFile,"cardapps") == 0) 49 | { 50 | PBYTE pbData = NULL; 51 | dwSize = 0; 52 | dwReturn = pCardData->pfnCardReadFile(pCardData, szDirectory, szCurrentFile, 0, &pbData, &dwSize); 53 | if (dwReturn == 0) 54 | { 55 | CHAR szDirectory[9]; 56 | for (DWORD dwI = 0; dwI < dwSize; dwI+=8) 57 | { 58 | memcpy(szDirectory, pbData + dwI, 8); 59 | szDirectory[8] = 0; 60 | ListFiles(hWnd, szDirectory); 61 | } 62 | 63 | pCardData->pfnCspFree(pbData); 64 | } 65 | } 66 | 67 | szCurrentFile = szCurrentFile + strlen(szCurrentFile)+1; 68 | } 69 | pCardData->pfnCspFree(pszFiles); 70 | } 71 | return dwReturn; 72 | } 73 | 74 | DWORD ListFiles(HWND hWnd) 75 | { 76 | if (!pCardData) 77 | { 78 | return SCARD_E_COMM_DATA_LOST; 79 | } 80 | SendMessage(GetDlgItem(hWnd, IDC_FILES),LB_RESETCONTENT,0,0); 81 | return ListFiles(hWnd, NULL); 82 | } 83 | 84 | DWORD ViewFile(HWND hWnd) 85 | { 86 | CHAR szFileName[256]; 87 | PSTR szFile, szDirectory; 88 | DWORD dwReturn; 89 | PBYTE pbData = NULL; 90 | DWORD dwSize; 91 | TCHAR szData[10]; 92 | __try 93 | { 94 | // clear text 95 | SendMessage( GetDlgItem(hWnd, IDC_CONTENT), WM_SETTEXT,0,(LPARAM) ""); 96 | 97 | DWORD iItem = (DWORD)SendMessage(GetDlgItem(hWnd, IDC_FILES),LB_GETCURSEL,0,0); 98 | if (iItem == LB_ERR) 99 | { 100 | dwReturn = SCARD_E_COMM_DATA_LOST; 101 | __leave; 102 | } 103 | if (!pCardData) 104 | { 105 | dwReturn = SCARD_E_COMM_DATA_LOST; 106 | __leave; 107 | } 108 | SendMessageA( GetDlgItem(hWnd,IDC_FILES), LB_GETTEXT,iItem,(LPARAM)szFileName); 109 | 110 | szFile = strchr(szFileName,'\\'); 111 | if (szFile) 112 | { 113 | *szFile = 0; 114 | szFile++; 115 | szDirectory = szFileName; 116 | } 117 | else 118 | { 119 | szDirectory = NULL; 120 | szFile = szFileName; 121 | } 122 | dwReturn = pCardData->pfnCardReadFile(pCardData,szDirectory,szFile, 0, &pbData, &dwSize); 123 | if (dwReturn) 124 | { 125 | __leave; 126 | } 127 | if (strcmp(szDirectory, "openpgp") == 0 && strcmp(szFile, "certific") == 0 ) 128 | { 129 | PCCERT_CONTEXT pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING , pbData, dwSize); 130 | if (!pCertContext) 131 | { 132 | dwReturn = GetLastError(); 133 | __leave; 134 | } 135 | ViewCertificate(hWnd, pCertContext); 136 | CertFreeCertificateContext(pCertContext); 137 | } 138 | else 139 | { 140 | for(DWORD dwI = 0; dwI < dwSize; dwI++) 141 | { 142 | _stprintf_s(szData,ARRAYSIZE(szData),TEXT("%02X "),pbData[dwI]); 143 | SendMessage( // returns LRESULT in lResult 144 | GetDlgItem(hWnd, IDC_CONTENT), // (HWND) handle to destination control 145 | EM_REPLACESEL, // (UINT) message ID 146 | FALSE, // = () wParam; 147 | (LPARAM)szData // = (LPARAM)(LPCTSTR) lParam; 148 | ); 149 | 150 | } 151 | } 152 | } 153 | __finally 154 | { 155 | if (pbData) 156 | pCardData->pfnCspFree(pbData); 157 | } 158 | return dwReturn; 159 | } 160 | -------------------------------------------------------------------------------- /OpenPGPSetup/OpenPGPSetup.wixproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 3.7 7 | 24a3abbc-4bd3-49f9-8883-61d26aae1a92 8 | 2.0 9 | OpenPGPSetup 10 | Package 11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets 12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets 13 | 14 | 15 | $(SolutionDir)$(Platform)\$(Configuration)\ 16 | obj\$(Configuration)\ 17 | Debug 18 | "C:\Program Files (x86)\WiX Toolset v3.11\bin\difxapp_x86.wixlib" 19 | True 20 | 21 | 22 | $(SolutionDir)$(Platform)\$(Configuration)\ 23 | obj\$(Configuration)\ 24 | "C:\Program Files (x86)\WiX Toolset v3.11\bin\difxapp_x86.wixlib" 25 | True 26 | 27 | 28 | Debug 29 | $(SolutionDir)$(Platform)\$(Configuration)\ 30 | obj\$(Platform)\$(Configuration)\ 31 | "C:\Program Files (x86)\WiX Toolset v3.11\bin\difxapp_x64.wixlib" 32 | True 33 | 34 | 35 | $(SolutionDir)$(Platform)\$(Configuration)\ 36 | obj\$(Platform)\$(Configuration)\ 37 | "C:\Program Files (x86)\WiX Toolset v3.11\bin\difxapp_x64.wixlib" 38 | True 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | $(WixExtDir)\WixUIExtension.dll 52 | WixUIExtension 53 | 54 | 55 | $(WixExtDir)\WixDifxAppExtension.dll 56 | WixDifxAppExtension 57 | 58 | 59 | 60 | 61 | copy $(OutDir)..\..\OpenPGPminidriver\%2a.inf $(OutDir) 62 | IF /I "$(PlatformName)" == "x86" copy "$(OutDir)..\..\x64\$(ConfigurationName)\openpgpmdrv64.dll" "$(OutDir)" 63 | IF /I "$(PlatformName)" == "x64" copy "$(OutDir)..\..\x86\$(ConfigurationName)\openpgpmdrv32.dll" "$(OutDir)" 64 | 65 | IF /I "$(ConfigurationName)" == "Release" "C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe" sign /d OpenPGPmdrv /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Ping Castle SAS" "$(TargetDir)openpgpmdrv64.dll" "$(TargetDir)openpgpmdrv32.dll" 66 | 67 | "C:\Program Files (x86)\Windows Kits\8.0\bin\x86\inf2cat.exe" /driver:$(OutDir) /os:Vista_X86,Vista_X64,7_X86,7_X64,Server2008R2_X64,Server2008_X64,Server2008_X86,Server2003_X64,Server2003_X86,XP_X64,XP_X86 68 | 69 | IF /I "$(ConfigurationName)" == "Release" "C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe" sign /d OpenPGPmdrv /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Ping Castle SAS" "$(TargetDir)openpgpmdrv64.cat" "$(TargetDir)openpgpmdrv32.cat" 70 | 71 | 72 | IF /I "$(ConfigurationName)" == "Release" "C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe" sign /d OpenPGPmdrv /tr http://timestamp.digicert.com /td sha256 /fd sha256 /n "Ping Castle SAS" "$(TargetDir)OpenPGPSetup.msi" 73 | move "$(TargetDir)OpenPGPSetup.msi" "$(TargetDir)OpenPGPSetup-$(PlatformName)-$(ConfigurationName).msi" 74 | 75 | 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | 3 | ## Ignore Visual Studio temporary files, build results, and 4 | ## files generated by popular Visual Studio add-ons. 5 | ## 6 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | bld/ 25 | [Bb]in/ 26 | [Oo]bj/ 27 | [Ll]og/ 28 | 29 | # Visual Studio 2015 cache/options directory 30 | .vs/ 31 | # Uncomment if you have tasks that create the project's static files in wwwroot 32 | #wwwroot/ 33 | 34 | # MSTest test Results 35 | [Tt]est[Rr]esult*/ 36 | [Bb]uild[Ll]og.* 37 | 38 | # NUNIT 39 | *.VisualState.xml 40 | TestResult.xml 41 | 42 | # Build Results of an ATL Project 43 | [Dd]ebugPS/ 44 | [Rr]eleasePS/ 45 | dlldata.c 46 | 47 | # .NET Core 48 | project.lock.json 49 | project.fragment.lock.json 50 | artifacts/ 51 | **/Properties/launchSettings.json 52 | 53 | *_i.c 54 | *_p.c 55 | *_i.h 56 | *.ilk 57 | *.meta 58 | *.obj 59 | *.pch 60 | *.pdb 61 | *.pgc 62 | *.pgd 63 | *.rsp 64 | *.sbr 65 | *.tlb 66 | *.tli 67 | *.tlh 68 | *.tmp 69 | *.tmp_proj 70 | *.log 71 | *.vspscc 72 | *.vssscc 73 | .builds 74 | *.pidb 75 | *.svclog 76 | *.scc 77 | 78 | # Chutzpah Test files 79 | _Chutzpah* 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opendb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | *.VC.db 90 | *.VC.VC.opendb 91 | 92 | # Visual Studio profiler 93 | *.psess 94 | *.vsp 95 | *.vspx 96 | *.sap 97 | 98 | # TFS 2012 Local Workspace 99 | $tf/ 100 | 101 | # Guidance Automation Toolkit 102 | *.gpState 103 | 104 | # ReSharper is a .NET coding add-in 105 | _ReSharper*/ 106 | *.[Rr]e[Ss]harper 107 | *.DotSettings.user 108 | 109 | # JustCode is a .NET coding add-in 110 | .JustCode 111 | 112 | # TeamCity is a build add-in 113 | _TeamCity* 114 | 115 | # DotCover is a Code Coverage Tool 116 | *.dotCover 117 | 118 | # Visual Studio code coverage results 119 | *.coverage 120 | *.coveragexml 121 | 122 | # NCrunch 123 | _NCrunch_* 124 | .*crunch*.local.xml 125 | nCrunchTemp_* 126 | 127 | # MightyMoose 128 | *.mm.* 129 | AutoTest.Net/ 130 | 131 | # Web workbench (sass) 132 | .sass-cache/ 133 | 134 | # Installshield output folder 135 | [Ee]xpress/ 136 | 137 | # DocProject is a documentation generator add-in 138 | DocProject/buildhelp/ 139 | DocProject/Help/*.HxT 140 | DocProject/Help/*.HxC 141 | DocProject/Help/*.hhc 142 | DocProject/Help/*.hhk 143 | DocProject/Help/*.hhp 144 | DocProject/Help/Html2 145 | DocProject/Help/html 146 | 147 | # Click-Once directory 148 | publish/ 149 | 150 | # Publish Web Output 151 | *.[Pp]ublish.xml 152 | *.azurePubxml 153 | # TODO: Comment the next line if you want to checkin your web deploy settings 154 | # but database connection strings (with potential passwords) will be unencrypted 155 | *.pubxml 156 | *.publishproj 157 | 158 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 159 | # checkin your Azure Web App publish settings, but sensitive information contained 160 | # in these scripts will be unencrypted 161 | PublishScripts/ 162 | 163 | # NuGet Packages 164 | *.nupkg 165 | # The packages folder can be ignored because of Package Restore 166 | **/packages/* 167 | # except build/, which is used as an MSBuild target. 168 | !**/packages/build/ 169 | # Uncomment if necessary however generally it will be regenerated when needed 170 | #!**/packages/repositories.config 171 | # NuGet v3's project.json files produces more ignorable files 172 | *.nuget.props 173 | *.nuget.targets 174 | 175 | # Microsoft Azure Build Output 176 | csx/ 177 | *.build.csdef 178 | 179 | # Microsoft Azure Emulator 180 | ecf/ 181 | rcf/ 182 | 183 | # Windows Store app package directories and files 184 | AppPackages/ 185 | BundleArtifacts/ 186 | Package.StoreAssociation.xml 187 | _pkginfo.txt 188 | 189 | # Visual Studio cache files 190 | # files ending in .cache can be ignored 191 | *.[Cc]ache 192 | # but keep track of directories ending in .cache 193 | !*.[Cc]ache/ 194 | 195 | # Others 196 | ClientBin/ 197 | ~$* 198 | *~ 199 | *.dbmdl 200 | *.dbproj.schemaview 201 | *.jfm 202 | *.pfx 203 | *.publishsettings 204 | orleans.codegen.cs 205 | 206 | # Since there are multiple workflows, uncomment next line to ignore bower_components 207 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 208 | #bower_components/ 209 | 210 | # RIA/Silverlight projects 211 | Generated_Code/ 212 | 213 | # Backup & report files from converting an old project file 214 | # to a newer Visual Studio version. Backup files are not needed, 215 | # because we have git ;-) 216 | _UpgradeReport_Files/ 217 | Backup*/ 218 | UpgradeLog*.XML 219 | UpgradeLog*.htm 220 | 221 | # SQL Server files 222 | *.mdf 223 | *.ldf 224 | 225 | # Business Intelligence projects 226 | *.rdl.data 227 | *.bim.layout 228 | *.bim_*.settings 229 | 230 | # Microsoft Fakes 231 | FakesAssemblies/ 232 | 233 | # GhostDoc plugin setting file 234 | *.GhostDoc.xml 235 | 236 | # Node.js Tools for Visual Studio 237 | .ntvs_analysis.dat 238 | node_modules/ 239 | 240 | # Typescript v1 declaration files 241 | typings/ 242 | 243 | # Visual Studio 6 build log 244 | *.plg 245 | 246 | # Visual Studio 6 workspace options file 247 | *.opt 248 | 249 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 250 | *.vbw 251 | 252 | # Visual Studio LightSwitch build output 253 | **/*.HTMLClient/GeneratedArtifacts 254 | **/*.DesktopClient/GeneratedArtifacts 255 | **/*.DesktopClient/ModelManifest.xml 256 | **/*.Server/GeneratedArtifacts 257 | **/*.Server/ModelManifest.xml 258 | _Pvt_Extensions 259 | 260 | # Paket dependency manager 261 | .paket/paket.exe 262 | paket-files/ 263 | 264 | # FAKE - F# Make 265 | .fake/ 266 | 267 | # JetBrains Rider 268 | .idea/ 269 | *.sln.iml 270 | 271 | # CodeRush 272 | .cr/ 273 | 274 | # Python Tools for Visual Studio (PTVS) 275 | __pycache__/ 276 | *.pyc 277 | 278 | # Cake - Uncomment if you are using it 279 | # tools/** 280 | # !tools/packages.config 281 | *.dll 282 | -------------------------------------------------------------------------------- /OpenPGPminidriver/CardInitializationAndDeconstruct.c: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include "cardmod.h" 20 | #include "Tracing.h" 21 | #include "Context.h" 22 | #include "SmartCard.h" 23 | 24 | // 4.1 Initialization and Deconstruct 25 | 26 | 27 | 28 | /** The CardAcquireContext function, defined by a smart card module, 29 | initializes communication between the smart card module and either the 30 | Microsoft Base Smart Card Cryptographic Service Provider (CSP) or smart 31 | card key storage provider (KSP). 32 | */ 33 | DWORD WINAPI CardAcquireContext( 34 | __in PCARD_DATA pCardData, 35 | __in DWORD dwFlags 36 | ) 37 | { 38 | DWORD dwReturn = 0; 39 | __try 40 | { 41 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 42 | if ( pCardData == NULL ) 43 | { 44 | Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); 45 | dwReturn = SCARD_E_INVALID_PARAMETER; 46 | __leave; 47 | } 48 | 49 | if ( dwFlags != 0 ) 50 | { 51 | Trace(WINEVENT_LEVEL_ERROR, L"dwFlags != 0"); 52 | dwReturn = SCARD_E_INVALID_PARAMETER; 53 | __leave; 54 | } 55 | dwReturn = CreateContext(pCardData, dwFlags); 56 | if (dwReturn) 57 | { 58 | __leave; 59 | } 60 | 61 | pCardData->pfnCardDeleteContext = CardDeleteContext; 62 | pCardData->pfnCardAuthenticatePin = CardAuthenticatePin; 63 | pCardData->pfnCardGetChallenge = CardGetChallenge; 64 | pCardData->pfnCardAuthenticateChallenge = CardAuthenticateChallenge; 65 | pCardData->pfnCardDeauthenticate = NULL; //CardDeauthenticate; 66 | pCardData->pfnCardUnblockPin = CardUnblockPin; 67 | pCardData->pfnCardChangeAuthenticator = CardChangeAuthenticator; 68 | pCardData->pfnCardCreateDirectory = CardCreateDirectory; 69 | pCardData->pfnCardDeleteDirectory = CardDeleteDirectory; 70 | pCardData->pfnCardReadFile = CardReadFile; 71 | pCardData->pfnCardCreateFile = CardCreateFile; 72 | pCardData->pfnCardGetFileInfo = CardGetFileInfo; 73 | pCardData->pfnCardWriteFile = CardWriteFile; 74 | pCardData->pfnCardDeleteFile = CardDeleteFile; 75 | pCardData->pfnCardEnumFiles = CardEnumFiles; 76 | pCardData->pfnCardQueryFreeSpace = CardQueryFreeSpace; 77 | pCardData->pfnCardQueryCapabilities = CardQueryCapabilities; 78 | pCardData->pfnCardCreateContainer = CardCreateContainer; 79 | pCardData->pfnCardDeleteContainer = CardDeleteContainer; 80 | pCardData->pfnCardGetContainerInfo = CardGetContainerInfo; 81 | pCardData->pfnCardRSADecrypt = CardRSADecrypt; 82 | pCardData->pfnCardSignData = CardSignData; 83 | pCardData->pfnCardSignData = CardSignData; 84 | pCardData->pfnCardQueryKeySizes = CardQueryKeySizes; 85 | 86 | // should be null for RSA only card 87 | pCardData->pfnCardConstructDHAgreement = NULL; //CardConstructDHAgreement; 88 | 89 | if (pCardData->dwVersion >= CARD_DATA_VERSION_FIVE) 90 | { 91 | pCardData->pfnCardDeriveKey = NULL; //CardDeriveKey; 92 | pCardData->pfnCardDestroyDHAgreement = NULL; //CardDestroyDHAgreement; 93 | } 94 | if (pCardData->dwVersion >= CARD_DATA_VERSION_SIX) 95 | { 96 | pCardData->pfnCardGetChallengeEx = CardGetChallengeEx; 97 | pCardData->pfnCardAuthenticateEx = CardAuthenticateEx; 98 | pCardData->pfnCardChangeAuthenticatorEx = CardChangeAuthenticatorEx; 99 | pCardData->pfnCardDeauthenticateEx = CardDeauthenticateEx; 100 | pCardData->pfnCardGetContainerProperty = CardGetContainerProperty; 101 | pCardData->pfnCardSetContainerProperty = CardSetContainerProperty; 102 | pCardData->pfnCardGetProperty = CardGetProperty; 103 | pCardData->pfnCardSetProperty = CardSetProperty; 104 | } 105 | if (pCardData->dwVersion >= CARD_DATA_VERSION_SEVEN) 106 | { 107 | pCardData->pfnMDImportSessionKey = MDImportSessionKey; 108 | pCardData->pfnMDEncryptData = MDEncryptData; 109 | pCardData->pfnCardImportSessionKey = CardImportSessionKey; 110 | pCardData->pfnCardGetSharedKeyHandle = CardGetSharedKeyHandle; 111 | pCardData->pfnCardGetAlgorithmProperty = CardGetAlgorithmProperty; 112 | pCardData->pfnCardGetKeyProperty = CardGetKeyProperty; 113 | pCardData->pfnCardSetKeyProperty = CardSetKeyProperty; 114 | pCardData->pfnCardProcessEncryptedData = CardProcessEncryptedData; 115 | pCardData->pfnCardDestroyKey = CardDestroyKey; 116 | pCardData->pfnCardCreateContainerEx = CardCreateContainerEx; 117 | } 118 | } 119 | __finally 120 | { 121 | if (dwReturn) 122 | { 123 | CleanContext(pCardData); 124 | } 125 | } 126 | Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); 127 | return dwReturn; 128 | } 129 | 130 | /** The CardDeleteContext function reverses the effect of CardAcquireContext 131 | and severs the communication between the Base CSP/KSP and the card minidriver. 132 | This function also performs any needed deallocations and cleanup. 133 | */ 134 | 135 | DWORD WINAPI CardDeleteContext( 136 | __inout PCARD_DATA pCardData 137 | ) 138 | { 139 | DWORD dwReturn; 140 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 141 | dwReturn = CleanContext(pCardData); 142 | Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); 143 | return dwReturn; 144 | } -------------------------------------------------------------------------------- /OpenPGPminidriver/CardSecureKeyInjection.c: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include "cardmod.h" 20 | #include "Tracing.h" 21 | 22 | // 4.8 Secure key injection 23 | 24 | 25 | /** The CardImportSessionKey function imports a temporary session key to the card. 26 | The session key is encrypted with a key exchange key, and the function returns a 27 | handle of the imported session key to the caller.*/ 28 | 29 | DWORD WINAPI CardImportSessionKey( 30 | __in PCARD_DATA pCardData, 31 | __in BYTE bContainerIndex, 32 | __in VOID *pPaddingInfo, 33 | __in LPCWSTR pwszBlobType, 34 | __in LPCWSTR pwszAlgId, 35 | __out CARD_KEY_HANDLE *phKey, 36 | __in_bcount(cbInput) PBYTE pbInput, 37 | __in DWORD cbInput, 38 | __in DWORD dwFlags 39 | ) 40 | { 41 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 42 | return SCARD_E_UNSUPPORTED_FEATURE; 43 | } 44 | 45 | /** The MDImportSessionKey function imports a temporary session key to the card minidriver 46 | and returns a key handle to the caller.*/ 47 | 48 | DWORD WINAPI MDImportSessionKey( 49 | __in PCARD_DATA pCardData, 50 | __in LPCWSTR pwszBlobType, 51 | __in LPCWSTR pwszAlgId, 52 | __out PCARD_KEY_HANDLE phKey, 53 | __in_bcount(cbInput) PBYTE pbInput, 54 | __in DWORD cbInput 55 | ) 56 | { 57 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 58 | return SCARD_E_UNSUPPORTED_FEATURE; 59 | } 60 | 61 | /** The MDEncryptData function uses a key handle to encrypt data with a symmetric key. 62 | The data is encrypted in a format that the smart card supports.*/ 63 | 64 | DWORD WINAPI MDEncryptData( 65 | __in PCARD_DATA pCardData, 66 | __in CARD_KEY_HANDLE hKey, 67 | __in LPCWSTR pwszSecureFunction, 68 | __in_bcount(cbInput) PBYTE pbInput, 69 | __in DWORD cbInput, 70 | __in DWORD dwFlags, 71 | __deref_out_ecount(*pcEncryptedData) 72 | PCARD_ENCRYPTED_DATA *ppEncryptedData, 73 | __out PDWORD pcEncryptedData 74 | ) 75 | { 76 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 77 | return SCARD_E_UNSUPPORTED_FEATURE; 78 | } 79 | 80 | 81 | /** The CardGetSharedKeyHandle function returns a session key handle to the caller. 82 | Note: The manner in which this session key has been established is outside the 83 | scope of this specification. For example, the session key could be established 84 | by either a permanent shared key or a key derivation algorithm that has occurred 85 | before the call to CardGetSharedKeyHandle.*/ 86 | 87 | DWORD WINAPI CardGetSharedKeyHandle( 88 | __in PCARD_DATA pCardData, 89 | __in_bcount(cbInput) PBYTE pbInput, 90 | __in DWORD cbInput, 91 | __deref_opt_out_bcount(*pcbOutput) 92 | PBYTE *ppbOutput, 93 | __out_opt PDWORD pcbOutput, 94 | __out PCARD_KEY_HANDLE phKey 95 | ) 96 | { 97 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 98 | return SCARD_E_UNSUPPORTED_FEATURE; 99 | } 100 | 101 | /** The CardDestroyKey function releases a temporary key on the card. The card 102 | should delete all of the key material that is associated with that key handle.*/ 103 | 104 | DWORD WINAPI CardDestroyKey( 105 | __in PCARD_DATA pCardData, 106 | __in CARD_KEY_HANDLE hKey 107 | ) 108 | { 109 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 110 | return SCARD_E_UNSUPPORTED_FEATURE; 111 | } 112 | 113 | /** This function can be used to get properties for a cryptographic algorithm.*/ 114 | DWORD WINAPI CardGetAlgorithmProperty ( 115 | __in PCARD_DATA pCardData, 116 | __in LPCWSTR pwszAlgId, 117 | __in LPCWSTR pwszProperty, 118 | __out_bcount_part_opt(cbData, *pdwDataLen) 119 | PBYTE pbData, 120 | __in DWORD cbData, 121 | __out PDWORD pdwDataLen, 122 | __in DWORD dwFlags 123 | ) 124 | { 125 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 126 | return SCARD_E_UNSUPPORTED_FEATURE; 127 | } 128 | 129 | /** This function is used to get the properties of a key.*/ 130 | DWORD WINAPI CardGetKeyProperty( 131 | __in PCARD_DATA pCardData, 132 | __in CARD_KEY_HANDLE hKey, 133 | __in LPCWSTR pwszProperty, 134 | __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData, 135 | __in DWORD cbData, 136 | __out PDWORD pdwDataLen, 137 | __in DWORD dwFlags 138 | ) 139 | { 140 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 141 | return SCARD_E_UNSUPPORTED_FEATURE; 142 | } 143 | 144 | /** This function is used to set the properties of a key.*/ 145 | DWORD WINAPI CardSetKeyProperty( 146 | __in PCARD_DATA pCardData, 147 | __in CARD_KEY_HANDLE hKey, 148 | __in LPCWSTR pwszProperty, 149 | __in_bcount(cbInput) PBYTE pbInput, 150 | __in DWORD cbInput, 151 | __in DWORD dwFlags 152 | ) 153 | { 154 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 155 | return SCARD_E_UNSUPPORTED_FEATURE; 156 | } 157 | 158 | /** CardProcessEncryptedData processes a set of encrypted data BLOBs by 159 | sending them to the card where the data BLOBs are decrypted.*/ 160 | 161 | DWORD WINAPI CardProcessEncryptedData( 162 | __in PCARD_DATA pCardData, 163 | __in CARD_KEY_HANDLE hKey, 164 | __in LPCWSTR pwszSecureFunction, 165 | __in_ecount(cEncryptedData) 166 | PCARD_ENCRYPTED_DATA pEncryptedData, 167 | __in DWORD cEncryptedData, 168 | __out_bcount_part_opt(cbOutput, *pdwOutputLen) 169 | PBYTE pbOutput, 170 | __in DWORD cbOutput, 171 | __out_opt PDWORD pdwOutputLen, 172 | __in DWORD dwFlags 173 | ) 174 | { 175 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 176 | return SCARD_E_UNSUPPORTED_FEATURE; 177 | } 178 | 179 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/PINOperations.cpp: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include "cardmod.h" 21 | #include "global.h" 22 | 23 | DWORD Authenticate(PSTR szPin, PWSTR wszUserId, PDWORD pcAttemptsRemaining) 24 | { 25 | DWORD cbPin = (DWORD) strlen(szPin); 26 | DWORD dwReturn; 27 | __try 28 | { 29 | if (!pCardData) 30 | { 31 | dwReturn = SCARD_E_COMM_DATA_LOST; 32 | __leave; 33 | } 34 | 35 | dwReturn = pCardData->pfnCardAuthenticatePin( 36 | pCardData, 37 | wszUserId, 38 | (PBYTE) szPin, 39 | cbPin, 40 | pcAttemptsRemaining); 41 | } 42 | __finally 43 | { 44 | } 45 | 46 | return dwReturn; 47 | } 48 | 49 | DWORD ChangePin(PSTR szPin, PSTR szPin2, PWSTR wszUserId, PDWORD pcAttemptsRemaining) 50 | { 51 | DWORD cbPin = (DWORD) strlen(szPin); 52 | DWORD cbPin2 = (DWORD) strlen(szPin2); 53 | DWORD dwReturn; 54 | __try 55 | { 56 | if (!pCardData) 57 | { 58 | dwReturn = SCARD_E_COMM_DATA_LOST; 59 | __leave; 60 | } 61 | 62 | dwReturn = pCardData->pfnCardChangeAuthenticator( 63 | pCardData, 64 | wszUserId, 65 | (PBYTE) szPin, 66 | cbPin, 67 | (PBYTE) szPin2, 68 | cbPin2, 69 | 0,CARD_AUTHENTICATE_PIN_PIN, 70 | pcAttemptsRemaining); 71 | } 72 | __finally 73 | { 74 | } 75 | 76 | return dwReturn; 77 | } 78 | 79 | DWORD SetPuk(PSTR szPin, PSTR szPin2, PDWORD pcAttemptsRemaining) 80 | { 81 | DWORD cbPin = (DWORD) strlen(szPin); 82 | DWORD cbPin2 = (DWORD) strlen(szPin2); 83 | DWORD dwReturn; 84 | __try 85 | { 86 | if (!pCardData) 87 | { 88 | dwReturn = SCARD_E_COMM_DATA_LOST; 89 | __leave; 90 | } 91 | 92 | dwReturn = pCardData->pfnCardChangeAuthenticatorEx( 93 | pCardData, 94 | PIN_CHANGE_FLAG_CHANGEPIN, ROLE_ADMIN, 95 | (PBYTE) szPin, 96 | cbPin, 97 | 4, 98 | (PBYTE) szPin2, 99 | cbPin2, 100 | 0, 101 | pcAttemptsRemaining); 102 | } 103 | __finally 104 | { 105 | } 106 | 107 | return dwReturn; 108 | } 109 | 110 | BYTE CharToByte(BYTE b) 111 | { 112 | if (b >= 0x30 && b <= 0x39) 113 | { 114 | return b - 0x30; 115 | } 116 | if (b >= 0x41 && b <= 0x46) 117 | { 118 | return b - 0x37; 119 | } 120 | if (b >= 0x61 && b <= 0x66) 121 | { 122 | return b - 0x57; 123 | } 124 | return 0xFF; 125 | } 126 | 127 | DWORD SetSM(PSTR szPin, PSTR szPin2, PDWORD pcAttemptsRemaining) 128 | { 129 | DWORD cbPin = (DWORD) strlen(szPin); 130 | DWORD cbPin2 = (DWORD) strlen(szPin2); 131 | DWORD dwReturn; 132 | BYTE bBuffer[24]; 133 | BYTE bTagBuffer[2 + 2 + 24 + 2 +24]; 134 | DWORD dwBufferSize, dwI; 135 | BOOL fSet = FALSE; 136 | __try 137 | { 138 | if (!pCardData) 139 | { 140 | dwReturn = SCARD_E_COMM_DATA_LOST; 141 | __leave; 142 | } 143 | if (cbPin2 % 2 || cbPin2 / 2 > ARRAYSIZE(bBuffer)) 144 | { 145 | dwReturn = SCARD_E_INVALID_PARAMETER; 146 | __leave; 147 | } 148 | dwBufferSize = cbPin2 / 2; 149 | if (dwBufferSize != 24 && dwBufferSize != 16) 150 | { 151 | dwReturn = SCARD_E_INVALID_PARAMETER; 152 | __leave; 153 | } 154 | for(dwI = 0; dwI < cbPin2 / 2; dwI++) 155 | { 156 | BYTE b1, b2; 157 | b1 = szPin2[dwI * 2]; 158 | b2 = szPin2[dwI * 2 + 1]; 159 | b1 = CharToByte(b1); 160 | b2 = CharToByte(b2); 161 | if (b1 == 0xFF || b2 == 0xFF) 162 | { 163 | dwReturn = SCARD_E_INVALID_PARAMETER; 164 | __leave; 165 | } 166 | bBuffer[dwI] = (BYTE)(b1) * 16 + (b2); 167 | } 168 | bTagBuffer[0] = 0x4d; 169 | bTagBuffer[1] = (BYTE) dwBufferSize * 2 + 2 * 2; 170 | bTagBuffer[2] = 0xD1; 171 | bTagBuffer[3] = (BYTE) dwBufferSize; 172 | memcpy(bTagBuffer + 4, bBuffer, dwBufferSize); 173 | bTagBuffer[2 + 2 + dwBufferSize] = 0xD2; 174 | bTagBuffer[3 + 2 + dwBufferSize] = (BYTE) dwBufferSize; 175 | memcpy(bTagBuffer + 4 + 2 + dwBufferSize, bBuffer, dwBufferSize); 176 | dwReturn = pCardData->pfnCardAuthenticateEx( 177 | pCardData, 178 | ROLE_ADMIN,0, 179 | (PBYTE) szPin, 180 | cbPin, NULL,NULL, 181 | pcAttemptsRemaining); 182 | if (dwReturn) 183 | { 184 | __leave; 185 | } 186 | dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0); 187 | if (dwReturn) __leave; 188 | //dwReturn = pCardData->pfnCardWriteFile(pCardData, "openpgp", "smenc", 0, bBuffer, dwBufferSize); 189 | dwReturn = pCardData->pfnCardWriteFile(pCardData, "openpgp", "sm", 0, bTagBuffer, 6 + 2*dwBufferSize); 190 | if (dwReturn) __leave; 191 | 192 | } 193 | __finally 194 | { 195 | } 196 | 197 | return dwReturn; 198 | } 199 | 200 | DWORD ResetPin(PSTR szPin, PSTR szPin2, BOOL fIsPUK, PDWORD pcAttemptsRemaining) 201 | { 202 | DWORD cbPin = (DWORD) strlen(szPin); 203 | DWORD cbPin2 = (DWORD) strlen(szPin2); 204 | DWORD dwReturn; 205 | __try 206 | { 207 | if (!pCardData) 208 | { 209 | dwReturn = SCARD_E_COMM_DATA_LOST; 210 | __leave; 211 | } 212 | if (fIsPUK) 213 | { 214 | dwReturn = pCardData->pfnCardChangeAuthenticatorEx( 215 | pCardData, 216 | PIN_CHANGE_FLAG_UNBLOCK, 5, 217 | (PBYTE) szPin,cbPin, 218 | ROLE_USER, (PBYTE)szPin2, cbPin2, 0, 219 | pcAttemptsRemaining); 220 | } 221 | else 222 | { 223 | dwReturn = pCardData->pfnCardChangeAuthenticatorEx( 224 | pCardData, 225 | PIN_CHANGE_FLAG_UNBLOCK, ROLE_ADMIN, 226 | (PBYTE) szPin,cbPin, 227 | ROLE_USER, (PBYTE)szPin2, cbPin2, 0, 228 | pcAttemptsRemaining); 229 | } 230 | } 231 | __finally 232 | { 233 | } 234 | 235 | return dwReturn; 236 | } -------------------------------------------------------------------------------- /OpenPGPminidriverTest/Enrollment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "cardmod.h" 6 | #include 7 | #include 8 | 9 | BOOL SchGetProviderNameFromCardName(__in LPCTSTR szCardName, __out LPTSTR szProviderName, __out PDWORD pdwProviderNameLen); 10 | 11 | BSTR GetAuthenticationContainer() 12 | { 13 | BSTR szSignatureContainer = NULL; 14 | HCRYPTPROV HMainCryptProv = NULL; 15 | BOOL bStatus = FALSE; 16 | LPTSTR szMainContainerName = NULL; 17 | CHAR szContainerName[1024]; 18 | DWORD dwContainerNameLen = sizeof(szContainerName); 19 | DWORD dwErr = 0; 20 | DWORD dwFlags = CRYPT_FIRST; 21 | DWORD dwContextArrayLen = 0; 22 | HCRYPTPROV hProv = NULL; 23 | HCRYPTKEY hKey = NULL; 24 | LPBYTE pbCert = NULL; 25 | DWORD dwCertLen = 0; 26 | PCCERT_CONTEXT pCertContext = NULL; 27 | PCCERT_CONTEXT pSelectedContext = NULL; 28 | HCERTSTORE hStore = NULL; 29 | TCHAR szCardName[256]; 30 | TCHAR szReaderName[256]; 31 | TCHAR szOutProviderName[256]; 32 | DWORD dwOutProviderLength = ARRAYSIZE(szOutProviderName); 33 | OPENCARDNAME_EX dlgStruct; 34 | DWORD dwReturn; 35 | SCARDCONTEXT hSCardContext = NULL; 36 | SCARDHANDLE hSCardHandle = NULL; 37 | LPWSTR szWideContainerName = NULL; 38 | __try 39 | { 40 | dwReturn = SCardEstablishContext(SCARD_SCOPE_USER, 41 | NULL, 42 | NULL, 43 | &hSCardContext ); 44 | if ( SCARD_S_SUCCESS != dwReturn ) 45 | { 46 | __leave; 47 | } 48 | // Initialize the structure. 49 | memset(&dlgStruct, 0, sizeof(dlgStruct)); 50 | dlgStruct.dwStructSize = sizeof(dlgStruct); 51 | dlgStruct.hSCardContext = hSCardContext; 52 | dlgStruct.dwFlags = SC_DLG_MINIMAL_UI; 53 | dlgStruct.lpstrRdr = szReaderName; 54 | dlgStruct.nMaxRdr = ARRAYSIZE(szReaderName); 55 | dlgStruct.lpstrCard = szCardName; 56 | dlgStruct.nMaxCard = ARRAYSIZE(szCardName); 57 | dlgStruct.lpstrTitle = L"Select Card"; 58 | dlgStruct.dwShareMode = 0; 59 | // Display the select card dialog box. 60 | dwReturn = SCardUIDlgSelectCard(&dlgStruct); 61 | if ( SCARD_S_SUCCESS != dwReturn ) 62 | { 63 | __leave; 64 | } 65 | dwReturn = SCardUIDlgSelectCard(&dlgStruct); 66 | if ( SCARD_S_SUCCESS != dwReturn ) 67 | { 68 | __leave; 69 | } 70 | if (!SchGetProviderNameFromCardName(szCardName, szOutProviderName, &dwOutProviderLength)) 71 | { 72 | dwReturn = GetLastError(); 73 | __leave; 74 | } 75 | 76 | size_t ulNameLen = _tcslen(szReaderName); 77 | szMainContainerName = (LPWSTR) LocalAlloc(0,(DWORD)(ulNameLen + 6) * sizeof(WCHAR)); 78 | if (!szMainContainerName) 79 | { 80 | dwReturn = GetLastError(); 81 | __leave; 82 | } 83 | swprintf_s(szMainContainerName,(ulNameLen + 6), L"\\\\.\\%s\\", szReaderName); 84 | 85 | bStatus = CryptAcquireContext(&HMainCryptProv, 86 | szMainContainerName, 87 | szOutProviderName, 88 | PROV_RSA_FULL, 89 | CRYPT_SILENT); 90 | if (!bStatus) 91 | { 92 | dwReturn = GetLastError(); 93 | if (dwReturn == NTE_BAD_KEYSET) 94 | { 95 | bStatus = CryptAcquireContext(&HMainCryptProv,NULL, szOutProviderName, PROV_RSA_FULL, CRYPT_SILENT); 96 | if (!bStatus) 97 | { 98 | dwReturn = GetLastError(); 99 | __leave; 100 | } 101 | } 102 | else 103 | { 104 | __leave; 105 | } 106 | 107 | } 108 | 109 | 110 | 111 | /* Enumerate all the containers */ 112 | while (CryptGetProvParam(HMainCryptProv, 113 | PP_ENUMCONTAINERS, 114 | (LPBYTE) szContainerName, 115 | &dwContainerNameLen, 116 | dwFlags) && 117 | (dwContextArrayLen < 128) 118 | ) 119 | { 120 | 121 | // convert the container name to unicode 122 | int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0); 123 | szWideContainerName = (LPWSTR) LocalAlloc(0,wLen * sizeof(WCHAR)); 124 | MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen); 125 | 126 | // Acquire a context on the current container 127 | if (CryptAcquireContext(&hProv, 128 | szWideContainerName, 129 | szOutProviderName, 130 | PROV_RSA_FULL, 131 | 0)) 132 | { 133 | // Loop over all the key specs 134 | if (CryptGetUserKey(hProv, 135 | AT_SIGNATURE, 136 | &hKey) ) 137 | { 138 | if (wcsncmp(szWideContainerName,L"OPENPGP_",8) == 0 139 | && wcsstr(szWideContainerName, L"_Authenticate") != NULL) 140 | { 141 | szSignatureContainer = SysAllocString(szWideContainerName); 142 | } 143 | CryptDestroyKey(hKey); 144 | hKey = NULL; 145 | } 146 | CryptReleaseContext(hProv, 0); 147 | hProv = NULL; 148 | } 149 | LocalFree(szWideContainerName); 150 | szWideContainerName = NULL; 151 | // prepare parameters for the next loop 152 | dwContainerNameLen = sizeof(szContainerName); 153 | dwFlags = 0; 154 | } 155 | } 156 | __finally 157 | { 158 | if (szWideContainerName) 159 | LocalFree(szWideContainerName); 160 | if (hKey) 161 | CryptDestroyKey(hKey); 162 | if (hProv) 163 | CryptReleaseContext(hProv, 0); 164 | if (szMainContainerName) 165 | LocalFree(szMainContainerName); 166 | if (HMainCryptProv) 167 | CryptReleaseContext(HMainCryptProv, 0); 168 | } 169 | return szSignatureContainer; 170 | } 171 | 172 | 173 | HRESULT Enroll() 174 | { 175 | BSTR bstrDN = NULL; 176 | BSTR bstrReq = NULL; 177 | BSTR bstrOID = NULL; 178 | ICEnroll4 * pEnroll = NULL; 179 | HRESULT hr; 180 | 181 | __try 182 | { 183 | // initialize COM 184 | hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); 185 | if (FAILED(hr)) 186 | { 187 | __leave; 188 | } 189 | 190 | hr = CoCreateInstance( __uuidof(CEnroll2), 191 | NULL, 192 | CLSCTX_INPROC_SERVER, 193 | __uuidof(IEnroll4), 194 | (void **)&pEnroll); 195 | if (FAILED(hr)) 196 | { 197 | __leave; 198 | } 199 | pEnroll->put_ContainerName(GetAuthenticationContainer()); 200 | pEnroll->put_KeySpec(AT_SIGNATURE); 201 | pEnroll->put_UseExistingKeySet(TRUE); 202 | pEnroll->put_WriteCertToCSP(FALSE); 203 | // generate the DN for the cert request 204 | bstrDN = SysAllocString( TEXT("CN=Your Name") // common name 205 | TEXT(",OU=Your Unit") // org unit 206 | TEXT(",O=Your Org") // organization 207 | TEXT(",L=Your City") // locality 208 | TEXT(",S=Your State") // state 209 | TEXT(",C=Your Country") ); // country/region 210 | if (NULL == bstrDN) 211 | { 212 | hr = GetLastError(); 213 | __leave; 214 | } 215 | 216 | // generate the OID, for example, "1.3.6.1.4.1.311.2.1.21". 217 | bstrOID = SysAllocString(TEXT("1.3.6.1.5.5.7.3.2,1.3.6.1.4.1.311.20.2.2")); 218 | if (NULL == bstrOID) 219 | { 220 | __leave; 221 | } 222 | 223 | // create the PKCS10 224 | hr = pEnroll->createPKCS10( bstrDN, bstrOID, &bstrReq ); 225 | if (FAILED(hr)) 226 | { 227 | __leave; 228 | } 229 | // do something with the PKCS10 (bstrReq); 230 | 231 | } 232 | __finally 233 | { 234 | 235 | //clean up resources, etc. 236 | if ( bstrDN ) 237 | SysFreeString( bstrDN ); 238 | if ( bstrOID ) 239 | SysFreeString( bstrOID ); 240 | if ( bstrReq ) 241 | SysFreeString( bstrReq ); 242 | if ( pEnroll ) 243 | pEnroll->Release(); 244 | 245 | CoUninitialize(); 246 | } 247 | return hr; 248 | } -------------------------------------------------------------------------------- /OpenPGPminidriver/openpgpmdrv.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ;OpenPGP Smartcard Minidriver for an x86 and x64 based package. 3 | ; 4 | 5 | [Version] 6 | Signature="$Windows NT$" 7 | Class=SmartCard 8 | ClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391} 9 | Provider=%OPENPGP% 10 | CatalogFile.ntx86=openpgpmdrv32.cat 11 | CatalogFile.ntamd64=openpgpmdrv64.cat 12 | DriverVer=07/12/2014,1.0.0.0 13 | 14 | [Manufacturer] 15 | %OPENPGP%=OpenPGP,NTamd64,NTamd64.6.1,NTx86,NTx86.6.1 16 | 17 | [OpenPGP.NTamd64] 18 | %OpenPGPCardDeviceName%=OpenPGP64_Install,SCFILTER\CID_0031c573c00140009000 19 | %OpenPGPCardDeviceName%=OpenPGP64_Install,SCFILTER\CID_0031f573c00160009000 20 | 21 | [OpenPGP.NTx86] 22 | %OpenPGPCardDeviceName%=OpenPGP32_Install,SCFILTER\CID_0031c573c00140009000 23 | %OpenPGPCardDeviceName%=OpenPGP32_Install,SCFILTER\CID_0031f573c00160009000 24 | 25 | [OpenPGP.NTamd64.6.1] 26 | %OpenPGPCardDeviceName%=OpenPGP64_61_Install,SCFILTER\CID_0031c573c00140009000 27 | %OpenPGPCardDeviceName%=OpenPGP64_61_Install,SCFILTER\CID_0031f573c00160009000 28 | 29 | [OpenPGP.NTx86.6.1] 30 | %OpenPGPCardDeviceName%=OpenPGP32_61_Install,SCFILTER\CID_0031c573c00140009000 31 | %OpenPGPCardDeviceName%=OpenPGP32_61_Install,SCFILTER\CID_0031f573c00160009000 32 | 33 | [SourceDisksFiles] 34 | openpgpmdrv64.dll=1 35 | openpgpmdrv32.dll=1 36 | 37 | [SourceDisksNames] 38 | 1 = %MediaDescription% 39 | 40 | [DefaultInstall.NTamd64] 41 | CopyFiles=amd64_CopyFiles 42 | CopyFiles=wow64_CopyFiles 43 | AddReg=AddRegWOW64 44 | AddReg=AddReg64 45 | 46 | [DefaultInstall.NTamd64.6.1] 47 | CopyFiles=amd64_CopyFiles 48 | CopyFiles=wow64_CopyFiles 49 | AddReg=AddRegWOW64 50 | AddReg=AddReg64 51 | Include=umpass.inf 52 | Needs=UmPass 53 | 54 | [OpenPGP64_Install.NT] 55 | CopyFiles=amd64_CopyFiles 56 | CopyFiles=wow64_CopyFiles 57 | AddReg=AddRegWOW64 58 | AddReg=AddReg64 59 | 60 | [OpenPGP64_61_Install.NT] 61 | CopyFiles=amd64_CopyFiles 62 | CopyFiles=wow64_CopyFiles 63 | AddReg=AddRegWOW64 64 | AddReg=AddReg64 65 | Include=umpass.inf 66 | Needs=UmPass 67 | 68 | [DefaultInstall.NTx86] 69 | CopyFiles=x86_CopyFiles 70 | AddReg=AddReg32 71 | 72 | [DefaultInstall.NTx86.6.1] 73 | CopyFiles=x86_CopyFiles 74 | AddReg=AddReg32 75 | Include=umpass.inf 76 | Needs=UmPass 77 | 78 | [OpenPGP32_Install.NT] 79 | CopyFiles=x86_CopyFiles 80 | AddReg=AddReg32 81 | 82 | [OpenPGP32_61_Install.NT] 83 | CopyFiles=x86_CopyFiles 84 | AddReg=AddReg32 85 | Include=umpass.inf 86 | Needs=UmPass 87 | 88 | [OpenPGP64_61_Install.NT.Services] 89 | Include=umpass.inf 90 | Needs=UmPass.Services 91 | 92 | [OpenPGP32_61_Install.NT.Services] 93 | Include=umpass.inf 94 | Needs=UmPass.Services 95 | 96 | 97 | [OpenPGP64_61_Install.NT.HW] 98 | Include=umpass.inf 99 | Needs=UmPass.HW 100 | 101 | [OpenPGP64_61_Install.NT.CoInstallers] 102 | Include=umpass.inf 103 | Needs=UmPass.CoInstallers 104 | 105 | 106 | [OpenPGP64_61_Install.NT.Interfaces] 107 | Include=umpass.inf 108 | Needs=UmPass.Interfaces 109 | 110 | 111 | [OpenPGP32_61_Install.NT.HW] 112 | Include=umpass.inf 113 | Needs=UmPass.HW 114 | 115 | [OpenPGP32_61_Install.NT.CoInstallers] 116 | Include=umpass.inf 117 | Needs=UmPass.CoInstallers 118 | 119 | 120 | [OpenPGP32_61_Install.NT.Interfaces] 121 | Include=umpass.inf 122 | Needs=UmPass.Interfaces 123 | 124 | 125 | [amd64_CopyFiles] 126 | %SmartCardCardModule64% 127 | 128 | [x86_CopyFiles] 129 | %SmartCardCardModule32% 130 | 131 | [wow64_CopyFiles] 132 | %SmartCardCardModule32% 133 | 134 | [AddRegWOW64] 135 | 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 136 | 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 137 | HKLM, %SmartCardNameWOW64%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 138 | HKLM, %SmartCardNameWOW64%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 139 | HKLM, %SmartCardNameWOW64%,"80000001",0x00000000,%SmartCardCardModule32% 140 | 141 | HKLM, %SmartCardV3NameWOW64%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,F5,73,C0,01,60,00,90,00,1C 142 | HKLM, %SmartCardV3NameWOW64%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff 143 | HKLM, %SmartCardV3NameWOW64%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 144 | HKLM, %SmartCardV3NameWOW64%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 145 | HKLM, %SmartCardV3NameWOW64%,"80000001",0x00000000,%SmartCardCardModule32% 146 | 147 | [AddReg32] 148 | 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 149 | 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 150 | HKLM, %SmartCardName%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 151 | HKLM, %SmartCardName%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 152 | HKLM, %SmartCardName%,"80000001",0x00000000,%SmartCardCardModule32% 153 | 154 | HKLM, %SmartCardV3Name%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,F5,73,C0,01,60,00,90,00,1C 155 | HKLM, %SmartCardV3Name%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff 156 | HKLM, %SmartCardV3Name%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 157 | HKLM, %SmartCardV3Name%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 158 | HKLM, %SmartCardV3Name%,"80000001",0x00000000,%SmartCardCardModule32% 159 | 160 | [AddReg64] 161 | 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 162 | 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 163 | HKLM, %SmartCardName%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 164 | HKLM, %SmartCardName%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 165 | HKLM, %SmartCardName%,"80000001",0x00000000,%SmartCardCardModule64% 166 | 167 | HKLM, %SmartCardV3Name%,"ATR",0x00000001,3B,DA,18,FF,81,B1,FE,75,1F,03,00,31,F5,73,C0,01,60,00,90,00,1C 168 | HKLM, %SmartCardV3Name%,"ATRMask",0x00000001,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff 169 | HKLM, %SmartCardV3Name%,"Crypto Provider",0x00000000,"Microsoft Base Smart Card Crypto Provider" 170 | HKLM, %SmartCardV3Name%,"Smart Card Key Storage Provider",0x00000000,"Microsoft Smart Card Key Storage Provider" 171 | HKLM, %SmartCardV3Name%,"80000001",0x00000000,%SmartCardCardModule64% 172 | 173 | 174 | [DestinationDirs] 175 | amd64_CopyFiles=10,system32 176 | x86_CopyFiles=10,system32 177 | wow64_CopyFiles=10,syswow64 178 | 179 | 180 | ; =================== Generic ================================== 181 | 182 | [Strings] 183 | OPENPGP ="OpenPGP" 184 | MediaDescription="OpenPGP Smart Card Minidriver Installation Disk" 185 | OpenPGPCardDeviceName="OpenPGP Minidriver for Smart Card" 186 | SmartCardName="SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\OpenPGP" 187 | SmartCardNameWOW64="SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\OpenPGP" 188 | SmartCardV3Name="SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\OpenPGP v3" 189 | SmartCardV3NameWOW64="SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards\OpenPGP v3" 190 | SmartCardCardModule32="openpgpmdrv32.dll" 191 | SmartCardCardModule64="openpgpmdrv64.dll" 192 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/InitializationAndDeconstruct.cpp: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include "cardmod.h" 21 | 22 | #pragma comment(lib,"Scarddlg") 23 | #pragma comment(lib,"Winscard") 24 | 25 | HMODULE hModule = NULL; 26 | CARD_DATA CardData; 27 | PCARD_DATA pCardData = NULL; 28 | SCARD_ATRMASK atr; 29 | TCHAR szCard[256]; 30 | 31 | extern "C" { 32 | 33 | // 34 | // Heap helpers 35 | // 36 | 37 | LPVOID WINAPI _Alloc(__in SIZE_T cBytes) 38 | { 39 | return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes); 40 | } 41 | 42 | LPVOID WINAPI _ReAlloc( 43 | __in LPVOID pvMem, 44 | __in SIZE_T cBytes) 45 | { 46 | return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pvMem, cBytes); 47 | } 48 | 49 | void WINAPI _Free( 50 | __in LPVOID pvMem) 51 | { 52 | HeapFree(GetProcessHeap(), 0, pvMem); 53 | } 54 | 55 | // 56 | // Dummy data caching stubs to satisfy the card module callback requirements 57 | // 58 | 59 | DWORD WINAPI _CacheAddFileStub( 60 | IN PVOID pvCacheContext, 61 | IN LPWSTR wszTag, 62 | IN DWORD dwFlags, 63 | IN PBYTE pbData, 64 | IN DWORD cbData) 65 | { 66 | UNREFERENCED_PARAMETER(pvCacheContext); 67 | UNREFERENCED_PARAMETER(wszTag); 68 | UNREFERENCED_PARAMETER(dwFlags); 69 | UNREFERENCED_PARAMETER(pbData); 70 | UNREFERENCED_PARAMETER(cbData); 71 | return ERROR_SUCCESS; 72 | } 73 | 74 | DWORD WINAPI _CacheLookupFileStub( 75 | IN PVOID pvCacheContext, 76 | IN LPWSTR wszTag, 77 | IN DWORD dwFlags, 78 | IN PBYTE *ppbData, 79 | IN PDWORD pcbData) 80 | { 81 | UNREFERENCED_PARAMETER(pvCacheContext); 82 | UNREFERENCED_PARAMETER(wszTag); 83 | UNREFERENCED_PARAMETER(dwFlags); 84 | UNREFERENCED_PARAMETER(ppbData); 85 | UNREFERENCED_PARAMETER(pcbData); 86 | return ERROR_NOT_FOUND; 87 | } 88 | 89 | DWORD WINAPI _CacheDeleteFileStub( 90 | IN PVOID pvCacheContext, 91 | IN LPWSTR wszTag, 92 | IN DWORD dwFlags) 93 | { 94 | UNREFERENCED_PARAMETER(pvCacheContext); 95 | UNREFERENCED_PARAMETER(wszTag); 96 | UNREFERENCED_PARAMETER(dwFlags); 97 | return ERROR_SUCCESS; 98 | } 99 | } 100 | 101 | DWORD Connect(BOOL fSystemDll) 102 | { 103 | DWORD dwReturn = 0; 104 | SCARDCONTEXT hSCardContext = NULL; 105 | SCARDHANDLE hSCardHandle = NULL; 106 | TCHAR szCardModule[256]; 107 | TCHAR szReader[256]; 108 | DWORD dwCardModuleSize = ARRAYSIZE(szCardModule); 109 | DWORD dwReaderSize = ARRAYSIZE(szReader); 110 | OPENCARDNAME_EX dlgStruct; 111 | PFN_CARD_ACQUIRE_CONTEXT pfnCardAcquireContext; 112 | 113 | __try 114 | { 115 | // find a smart card 116 | ///////////////////// 117 | 118 | dwReturn = SCardEstablishContext(SCARD_SCOPE_USER, 119 | NULL, 120 | NULL, 121 | &hSCardContext ); 122 | if ( SCARD_S_SUCCESS != dwReturn ) 123 | { 124 | __leave; 125 | } 126 | 127 | // Initialize the structure. 128 | memset(&dlgStruct, 0, sizeof(dlgStruct)); 129 | dlgStruct.dwStructSize = sizeof(dlgStruct); 130 | dlgStruct.hSCardContext = hSCardContext; 131 | dlgStruct.dwFlags = SC_DLG_MINIMAL_UI; 132 | dlgStruct.lpstrRdr = szReader; 133 | dlgStruct.nMaxRdr = dwReaderSize; 134 | dlgStruct.lpstrCard = szCard; 135 | dlgStruct.nMaxCard = ARRAYSIZE(szCard); 136 | dlgStruct.lpstrTitle = L"Select Card"; 137 | dlgStruct.dwShareMode = 0; 138 | // Display the select card dialog box. 139 | dwReturn = SCardUIDlgSelectCard(&dlgStruct); 140 | if ( SCARD_S_SUCCESS != dwReturn ) 141 | { 142 | __leave; 143 | } 144 | 145 | // find the dll path / name 146 | //////////////////////////// 147 | if (fSystemDll) 148 | { 149 | 150 | dwReturn = SCardGetCardTypeProviderName( 151 | hSCardContext, 152 | szCard, 153 | SCARD_PROVIDER_CARD_MODULE, 154 | (PTSTR) &szCardModule, 155 | &dwCardModuleSize); 156 | if (0 == dwCardModuleSize) 157 | { 158 | dwReturn = (DWORD) SCARD_E_UNKNOWN_CARD; 159 | __leave; 160 | } 161 | } 162 | else 163 | { 164 | #ifdef _M_X64 165 | _tcscpy_s(szCardModule, dwCardModuleSize, TEXT("openpgpmdrv64.dll")); 166 | #else 167 | _tcscpy_s(szCardModule, dwCardModuleSize, TEXT("openpgpmdrv32.dll")); 168 | #endif 169 | } 170 | // connect to the smart card 171 | //////////////////////////// 172 | DWORD dwProtocol, dwState; 173 | dwReturn = SCardConnect(hSCardContext,szReader,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T1|SCARD_PROTOCOL_T0, &hSCardHandle, &dwProtocol); 174 | if ( SCARD_S_SUCCESS != dwReturn ) 175 | { 176 | __leave; 177 | } 178 | atr.cbAtr = 32; 179 | dwReturn = SCardStatus(hSCardHandle, szReader, &dwReaderSize, &dwState, &dwProtocol, atr.rgbAtr,&atr.cbAtr); 180 | if ( SCARD_S_SUCCESS != dwReturn ) 181 | { 182 | __leave; 183 | } 184 | // load 185 | //////// 186 | if (NULL == (hModule = LoadLibrary(szCardModule))) 187 | { 188 | dwReturn = GetLastError(); 189 | __leave; 190 | } 191 | 192 | if (NULL == (pfnCardAcquireContext = 193 | (PFN_CARD_ACQUIRE_CONTEXT) GetProcAddress( 194 | hModule, "CardAcquireContext"))) 195 | { 196 | dwReturn = GetLastError(); 197 | __leave; 198 | } 199 | // initialize context 200 | ////////////////////// 201 | pCardData = &CardData; 202 | pCardData->dwVersion = CARD_DATA_CURRENT_VERSION; 203 | pCardData->pfnCspAlloc = _Alloc; 204 | pCardData->pfnCspFree = _Free; 205 | pCardData->pfnCspReAlloc = _ReAlloc; 206 | pCardData->pfnCspCacheAddFile = _CacheAddFileStub; 207 | pCardData->pfnCspCacheLookupFile = _CacheLookupFileStub; 208 | pCardData->pfnCspCacheDeleteFile = _CacheDeleteFileStub; 209 | pCardData->hScard = hSCardHandle; 210 | pCardData->hSCardCtx = hSCardContext; 211 | pCardData->cbAtr = atr.cbAtr; 212 | pCardData->pbAtr = atr.rgbAtr; 213 | pCardData->pwszCardName = szCard; 214 | //dwReturn = SCardBeginTransaction(hSCardHandle); 215 | if ( SCARD_S_SUCCESS != dwReturn ) 216 | { 217 | __leave; 218 | } 219 | dwReturn = pfnCardAcquireContext(pCardData, 0); 220 | } 221 | __finally 222 | { 223 | if (dwReturn != 0) 224 | { 225 | if (hSCardHandle) 226 | { 227 | SCardEndTransaction(hSCardHandle,SCARD_LEAVE_CARD); 228 | SCardDisconnect(hSCardHandle,0); 229 | } 230 | if (hSCardContext) 231 | SCardReleaseContext(hSCardContext); 232 | } 233 | } 234 | return dwReturn; 235 | } 236 | 237 | DWORD Disconnect() 238 | { 239 | DWORD dwReturn = 0; 240 | if (pCardData) 241 | { 242 | if (pCardData->hScard) 243 | { 244 | SCardEndTransaction(pCardData->hScard,SCARD_LEAVE_CARD); 245 | SCardDisconnect(pCardData->hScard,0); 246 | } 247 | if (pCardData->hSCardCtx) 248 | SCardReleaseContext(pCardData->hSCardCtx); 249 | pCardData = NULL; 250 | } 251 | else 252 | { 253 | dwReturn = SCARD_E_COMM_DATA_LOST; 254 | } 255 | return dwReturn; 256 | } -------------------------------------------------------------------------------- /OpenPGPSetup/gnu-lgpl.rtf: -------------------------------------------------------------------------------- 1 | {\rtf\ansi{ GNU Lesser General Public License - GNU Project - Free Software Foundation (FSF) GNU LESSER GENERAL PUBLIC LICENSE \par 2 | \par 3 | Version 3, 29 June 2007 \par 4 | \par 5 | Copyright 2007 Free Software Foundation, Inc. \par 6 | \par 7 | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. \par 8 | \par 9 | This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. \par 10 | \par 11 | As used herein, this License refers to version 3 of the GNU Lesser General Public License, and the GNU GPL refers to version 3 of the GNU General Public License. \par 12 | \par 13 | The Library refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. \par 14 | \par 15 | An Application is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. \par 16 | \par 17 | A Combined Work is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the Linked Version. \par 18 | \par 19 | The Minimal Corresponding Source for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. \par 20 | \par 21 | The Corresponding Application Code for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. \par 22 | \par 23 | You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. \par 24 | \par 25 | If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: *a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or\par 26 | *b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.\par 27 | 3. Object Code Incorporating Material from Library Header Files. \par 28 | \par 29 | The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: *a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.\par 30 | *b) Accompany the object code with a copy of the GNU GPL and this license document.\par 31 | 4. Combined Works. \par 32 | \par 33 | You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: *a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.\par 34 | *b) Accompany the Combined Work with a copy of the GNU GPL and this license document.\par 35 | *c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.\par 36 | *d) Do one of the following: *0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.\par 37 | *1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.\par 38 | \par 39 | *e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)\par 40 | 5. Combined Libraries. \par 41 | \par 42 | You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: *a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.\par 43 | *b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.\par 44 | 6. Revised Versions of the GNU Lesser General Public License. \par 45 | \par 46 | The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. \par 47 | \par 48 | Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License or any later version applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. \par 49 | \par 50 | If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. }} -------------------------------------------------------------------------------- /makemsi/Resources/gnu-lgpl.rtf: -------------------------------------------------------------------------------- 1 | {\rtf\ansi{ GNU Lesser General Public License - GNU Project - Free Software Foundation (FSF) GNU LESSER GENERAL PUBLIC LICENSE \par 2 | \par 3 | Version 3, 29 June 2007 \par 4 | \par 5 | Copyright 2007 Free Software Foundation, Inc. \par 6 | \par 7 | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. \par 8 | \par 9 | This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. \par 10 | \par 11 | As used herein, this License refers to version 3 of the GNU Lesser General Public License, and the GNU GPL refers to version 3 of the GNU General Public License. \par 12 | \par 13 | The Library refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. \par 14 | \par 15 | An Application is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. \par 16 | \par 17 | A Combined Work is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the Linked Version. \par 18 | \par 19 | The Minimal Corresponding Source for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. \par 20 | \par 21 | The Corresponding Application Code for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. \par 22 | \par 23 | You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. \par 24 | \par 25 | If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: *a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or\par 26 | *b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.\par 27 | 3. Object Code Incorporating Material from Library Header Files. \par 28 | \par 29 | The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: *a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.\par 30 | *b) Accompany the object code with a copy of the GNU GPL and this license document.\par 31 | 4. Combined Works. \par 32 | \par 33 | You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: *a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.\par 34 | *b) Accompany the Combined Work with a copy of the GNU GPL and this license document.\par 35 | *c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.\par 36 | *d) Do one of the following: *0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.\par 37 | *1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.\par 38 | \par 39 | *e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)\par 40 | 5. Combined Libraries. \par 41 | \par 42 | You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: *a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.\par 43 | *b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.\par 44 | 6. Revised Versions of the GNU Lesser General Public License. \par 45 | \par 46 | The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. \par 47 | \par 48 | Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License or any later version applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. \par 49 | \par 50 | If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. }} -------------------------------------------------------------------------------- /OpenPGPSetup/Resources/gnu-lgpl.rtf: -------------------------------------------------------------------------------- 1 | {\rtf\ansi{ GNU Lesser General Public License - GNU Project - Free Software Foundation (FSF) GNU LESSER GENERAL PUBLIC LICENSE \par 2 | \par 3 | Version 3, 29 June 2007 \par 4 | \par 5 | Copyright 2007 Free Software Foundation, Inc. \par 6 | \par 7 | Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. \par 8 | \par 9 | This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. \par 10 | \par 11 | As used herein, this License refers to version 3 of the GNU Lesser General Public License, and the GNU GPL refers to version 3 of the GNU General Public License. \par 12 | \par 13 | The Library refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. \par 14 | \par 15 | An Application is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. \par 16 | \par 17 | A Combined Work is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the Linked Version. \par 18 | \par 19 | The Minimal Corresponding Source for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. \par 20 | \par 21 | The Corresponding Application Code for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. \par 22 | \par 23 | You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. \par 24 | \par 25 | If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: *a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or\par 26 | *b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.\par 27 | 3. Object Code Incorporating Material from Library Header Files. \par 28 | \par 29 | The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: *a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.\par 30 | *b) Accompany the object code with a copy of the GNU GPL and this license document.\par 31 | 4. Combined Works. \par 32 | \par 33 | You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: *a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.\par 34 | *b) Accompany the Combined Work with a copy of the GNU GPL and this license document.\par 35 | *c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.\par 36 | *d) Do one of the following: *0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.\par 37 | *1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.\par 38 | \par 39 | *e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)\par 40 | 5. Combined Libraries. \par 41 | \par 42 | You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: *a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.\par 43 | *b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.\par 44 | 6. Revised Versions of the GNU Lesser General Public License. \par 45 | \par 46 | The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. \par 47 | \par 48 | Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License or any later version applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. \par 49 | \par 50 | If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. }} -------------------------------------------------------------------------------- /OpenPGPminidriver/CardKeyContainer.c: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include "cardmod.h" 20 | #include "Tracing.h" 21 | #include "Context.h" 22 | #include "CryptoOperations.h" 23 | 24 | // 4.6 Key Container 25 | 26 | /** The CardCreateContainer function creates a new key container that is 27 | identified by the container index that the bContainerIndex argument specifies. 28 | For applications in which the card does not support on-card key generation or 29 | if it is desired to archive the keys, the key material can be supplied with 30 | the call by specifying in flags that the card is to import the supplied key material.*/ 31 | 32 | DWORD WINAPI CardCreateContainer( 33 | __in PCARD_DATA pCardData, 34 | __in BYTE bContainerIndex, 35 | __in DWORD dwFlags, 36 | __in DWORD dwKeySpec, 37 | __in DWORD dwKeySize, 38 | __in PBYTE pbKeyData 39 | ) 40 | { 41 | DWORD dwReturn = 0; 42 | POPENPGP_CONTEXT pContext = NULL; 43 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex); 44 | __try 45 | { 46 | if ( pCardData == NULL ) 47 | { 48 | Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); 49 | dwReturn = SCARD_E_INVALID_PARAMETER; 50 | __leave; 51 | } 52 | if (bContainerIndex >= ContainerMax) 53 | { 54 | Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex); 55 | dwReturn = SCARD_E_NO_KEY_CONTAINER; 56 | __leave; 57 | } 58 | // controls are done in CardCreateContainerEx 59 | dwReturn = CardCreateContainerEx(pCardData, 60 | bContainerIndex, 61 | dwFlags, 62 | dwKeySpec, 63 | dwKeySize, 64 | pbKeyData, 65 | Containers[bContainerIndex].PinId); 66 | } 67 | __finally 68 | { 69 | } 70 | Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); 71 | return dwReturn; 72 | } 73 | 74 | /** The CardCreateContainerEx function creates a new key container that the 75 | container index identifies and the bContainerIndex parameter specifies. The function 76 | associates the key container with the PIN that the PinId parameter specified. 77 | This function is useful if the card-edge does not allow for changing the key attributes 78 | after the key container is created. This function replaces the need to call 79 | CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer 80 | is called. 81 | The caller of this function can provide the key material that the card imports. 82 | This is useful in those situations in which the card either does not support internal 83 | key generation or the caller requests that the key be archived in the card.*/ 84 | 85 | DWORD WINAPI CardCreateContainerEx( 86 | __in PCARD_DATA pCardData, 87 | __in BYTE bContainerIndex, 88 | __in DWORD dwFlags, 89 | __in DWORD dwKeySpec, 90 | __in DWORD dwKeySize, 91 | __in PBYTE pbKeyData, 92 | __in PIN_ID PinId 93 | ) 94 | { 95 | DWORD dwReturn = 0; 96 | POPENPGP_CONTEXT pContext = NULL; 97 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex); 98 | __try 99 | { 100 | if ( pCardData == NULL ) 101 | { 102 | Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); 103 | dwReturn = SCARD_E_INVALID_PARAMETER; 104 | __leave; 105 | } 106 | if (bContainerIndex >= ContainerMax) 107 | { 108 | Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex); 109 | dwReturn = SCARD_E_NO_KEY_CONTAINER; 110 | __leave; 111 | } 112 | if (Containers[bContainerIndex].dwKeySpec != dwKeySpec) 113 | { 114 | Trace(WINEVENT_LEVEL_ERROR, L"dwKeySpec == %d",dwKeySpec); 115 | dwReturn = SCARD_E_UNSUPPORTED_FEATURE; 116 | __leave; 117 | } 118 | if (Containers[bContainerIndex].PinId != PinId) 119 | { 120 | Trace(WINEVENT_LEVEL_ERROR, L"PinId == %d",PinId); 121 | dwReturn = SCARD_E_UNSUPPORTED_FEATURE; 122 | __leave; 123 | } 124 | dwReturn = CheckContext(pCardData); 125 | if (dwReturn) 126 | { 127 | __leave; 128 | } 129 | pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; 130 | if (pContext->fIsReadOnly) 131 | { 132 | dwReturn = SCARD_E_UNSUPPORTED_FEATURE; 133 | Trace(WINEVENT_LEVEL_ERROR, L"Readonly card"); 134 | __leave; 135 | } 136 | if (dwFlags == CARD_CREATE_CONTAINER_KEY_GEN) 137 | { 138 | dwReturn = OCardCreateKey(pCardData, bContainerIndex, dwKeySize); 139 | } 140 | else if (dwFlags == CARD_CREATE_CONTAINER_KEY_IMPORT) 141 | { 142 | if (pbKeyData == NULL) 143 | { 144 | Trace(WINEVENT_LEVEL_ERROR, L"pbKeyData == NULL"); 145 | dwReturn = SCARD_E_INVALID_PARAMETER; 146 | __leave; 147 | } 148 | dwReturn = OCardImportKey(pCardData, bContainerIndex, pbKeyData, dwKeySize); 149 | } 150 | else 151 | { 152 | Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d",dwFlags); 153 | dwReturn = SCARD_E_INVALID_PARAMETER; 154 | __leave; 155 | } 156 | } 157 | __finally 158 | { 159 | } 160 | Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); 161 | return dwReturn; 162 | } 163 | 164 | /** The CardDeleteContainer function deletes the key container specified by its index value. 165 | This is done by deleting all key material (public and private) that is associated with 166 | that index value.*/ 167 | 168 | DWORD WINAPI CardDeleteContainer( 169 | __in PCARD_DATA pCardData, 170 | __in BYTE bContainerIndex, 171 | __in DWORD dwReserved 172 | ) 173 | { 174 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 175 | return SCARD_E_UNSUPPORTED_FEATURE; 176 | } 177 | 178 | /** The CardGetContainerInfo function queries the specified key container for more 179 | information about which keys are present, such as its key specification (such as AT_ECDSA_P384).*/ 180 | 181 | DWORD WINAPI CardGetContainerInfo( 182 | __in PCARD_DATA pCardData, 183 | __in BYTE bContainerIndex, 184 | __in DWORD dwFlags, 185 | __inout PCONTAINER_INFO pContainerInfo 186 | ) 187 | { 188 | DWORD dwReturn = 0, dwVersion; 189 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex=%d",bContainerIndex); 190 | __try 191 | { 192 | if ( pCardData == NULL ) 193 | { 194 | Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); 195 | dwReturn = SCARD_E_INVALID_PARAMETER; 196 | __leave; 197 | } 198 | if ( pContainerInfo == NULL ) 199 | { 200 | Trace(WINEVENT_LEVEL_ERROR, L"pContainerInfo == NULL"); 201 | dwReturn = SCARD_E_INVALID_PARAMETER; 202 | __leave; 203 | } 204 | dwVersion = (pContainerInfo->dwVersion == 0) ? 1 : pContainerInfo->dwVersion; 205 | if ( dwVersion != CONTAINER_INFO_CURRENT_VERSION ) 206 | { 207 | Trace(WINEVENT_LEVEL_ERROR, L"dwVersion == %d", pContainerInfo->dwVersion); 208 | dwReturn = ERROR_REVISION_MISMATCH; 209 | __leave; 210 | } 211 | if ( dwFlags ) 212 | { 213 | Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); 214 | dwReturn = SCARD_E_INVALID_PARAMETER; 215 | __leave; 216 | } 217 | if (bContainerIndex >= ContainerMax) 218 | { 219 | Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d",bContainerIndex); 220 | dwReturn = SCARD_E_NO_KEY_CONTAINER; 221 | __leave; 222 | } 223 | dwReturn = CheckContext(pCardData); 224 | if (dwReturn) 225 | { 226 | __leave; 227 | } 228 | pContainerInfo->pbSigPublicKey = NULL; 229 | pContainerInfo->pbKeyExPublicKey = NULL; 230 | pContainerInfo->cbSigPublicKey = 0; 231 | pContainerInfo->cbKeyExPublicKey = 0; 232 | switch(bContainerIndex) 233 | { 234 | case ContainerSignature: 235 | case ContainerAuthentication: 236 | dwReturn = OCardReadPublicKey(pCardData, bContainerIndex, 237 | &(pContainerInfo->pbSigPublicKey),&(pContainerInfo->cbSigPublicKey)); 238 | break; 239 | case ContainerConfidentiality: 240 | dwReturn = OCardReadPublicKey(pCardData, bContainerIndex, 241 | &(pContainerInfo->pbKeyExPublicKey),&(pContainerInfo->cbKeyExPublicKey)); 242 | break; 243 | } 244 | } 245 | __finally 246 | { 247 | } 248 | Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); 249 | return dwReturn; 250 | } 251 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/OpenPGPminidriverTest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 18 | 19 | 20 | 21 | 22 | 29 | 32 | 35 | 38 | 41 | 44 | 55 | 58 | 61 | 64 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 94 | 101 | 104 | 107 | 110 | 113 | 117 | 128 | 131 | 134 | 137 | 145 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 167 | 175 | 178 | 181 | 184 | 187 | 190 | 201 | 204 | 207 | 210 | 220 | 223 | 226 | 229 | 232 | 235 | 238 | 241 | 242 | 250 | 253 | 256 | 259 | 262 | 266 | 277 | 280 | 283 | 286 | 296 | 299 | 302 | 305 | 308 | 311 | 314 | 317 | 318 | 319 | 320 | 321 | 322 | 327 | 330 | 331 | 334 | 335 | 338 | 339 | 342 | 343 | 346 | 347 | 350 | 351 | 354 | 355 | 358 | 361 | 362 | 363 | 364 | 369 | 372 | 373 | 376 | 377 | 378 | 383 | 386 | 387 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/CryptoOperations.cpp: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include "cardmod.h" 21 | #include "global.h" 22 | 23 | DWORD GenerateNewKey(DWORD dwIndex) 24 | { 25 | DWORD dwReturn, dwKeySpec; 26 | PIN_ID PinId; 27 | __try 28 | { 29 | if (!pCardData) 30 | { 31 | dwReturn = SCARD_E_COMM_DATA_LOST; 32 | __leave; 33 | } 34 | switch(dwIndex) 35 | { 36 | case 0: //Signature, 37 | dwKeySpec = AT_SIGNATURE; 38 | PinId = ROLE_USER; 39 | break; 40 | case 2: //Authentication, 41 | dwKeySpec = AT_SIGNATURE; 42 | PinId = 3; 43 | break; 44 | case 1: // Confidentiality, 45 | dwKeySpec = AT_KEYEXCHANGE; 46 | PinId = 4; 47 | break; 48 | default: 49 | dwReturn = SCARD_E_UNEXPECTED; 50 | __leave; 51 | } 52 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) dwIndex, 53 | CARD_CREATE_CONTAINER_KEY_GEN, 54 | dwKeySpec, 1024, NULL, PinId); 55 | } 56 | __finally 57 | { 58 | } 59 | return dwReturn; 60 | } 61 | 62 | #pragma pack(push,1) 63 | typedef struct _RSAPUBLICKEYBLOB 64 | { 65 | BLOBHEADER blobheader; 66 | RSAPUBKEY rsapubkey; 67 | BYTE modulus[sizeof(DWORD)]; 68 | } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB; 69 | #pragma pack(pop) 70 | 71 | DWORD ImportKey(DWORD dwIndex) 72 | { 73 | DWORD dwReturn, dwKeySpec; 74 | PIN_ID PinId; 75 | HCRYPTPROV hProv = NULL; 76 | HCRYPTKEY hKey = NULL; 77 | TCHAR szContainerName[] = OPENPGP_TEST_CONTAINER; 78 | BYTE pbData[4096]; 79 | BYTE pbDataControl[4096]; 80 | BYTE pbBlobRef[4096]; 81 | DWORD dwDataSize = ARRAYSIZE(pbData); 82 | DWORD dwBlobRefSize = ARRAYSIZE(pbBlobRef); 83 | BOOL bStatus; 84 | CONTAINER_INFO ContainerInfo; 85 | PRSAPUBLICKEYBLOB pBlob, pBlobRef; 86 | DWORD dwAglLen, dwSize; 87 | __try 88 | { 89 | if (!pCardData) 90 | { 91 | dwReturn = SCARD_E_COMM_DATA_LOST; 92 | __leave; 93 | } 94 | switch(dwIndex) 95 | { 96 | case 0: //Signature, 97 | dwKeySpec = AT_SIGNATURE; 98 | PinId = ROLE_USER; 99 | break; 100 | case 2: //Authentication, 101 | dwKeySpec = AT_SIGNATURE; 102 | PinId = 3; 103 | break; 104 | case 1: // Confidentiality, 105 | dwKeySpec = AT_KEYEXCHANGE; 106 | PinId = 4; 107 | break; 108 | default: 109 | dwReturn = SCARD_E_UNEXPECTED; 110 | __leave; 111 | } 112 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); 113 | if (!bStatus) 114 | { 115 | dwReturn = GetLastError(); 116 | if (dwReturn == NTE_BAD_KEYSET) 117 | { 118 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); 119 | } 120 | if (!bStatus) 121 | { 122 | dwReturn = GetLastError(); 123 | __leave; 124 | } 125 | } 126 | bStatus = CryptGenKey(hProv, dwKeySpec, CRYPT_EXPORTABLE, &hKey); 127 | if (!bStatus) 128 | { 129 | dwReturn = GetLastError(); 130 | __leave; 131 | } 132 | bStatus = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataSize); 133 | if (!bStatus) 134 | { 135 | dwReturn = GetLastError(); 136 | __leave; 137 | } 138 | memcpy(pbDataControl, pbData, ARRAYSIZE(pbData)); 139 | dwSize = sizeof(DWORD); 140 | bStatus = CryptGetKeyParam(hKey, KP_KEYLEN, (PBYTE) &dwAglLen,&dwSize , 0); 141 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) dwIndex, 142 | CARD_CREATE_CONTAINER_KEY_IMPORT, 143 | dwKeySpec, dwAglLen, pbData, PinId); 144 | if (dwReturn) 145 | { 146 | __leave; 147 | } 148 | // check if the buffer has been altered 149 | if (memcmp(pbDataControl,pbData, ARRAYSIZE(pbData)) != 0) 150 | { 151 | dwReturn = SCARD_E_UNEXPECTED; 152 | __leave; 153 | } 154 | 155 | memset(&ContainerInfo,0,sizeof(CONTAINER_INFO)); 156 | ContainerInfo.dwVersion = 0; 157 | dwReturn = pCardData->pfnCardGetContainerInfo(pCardData, (BYTE) dwIndex, 0, &ContainerInfo); 158 | if (dwReturn) 159 | { 160 | __leave; 161 | } 162 | bStatus = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbBlobRef, &dwBlobRefSize); 163 | if (!bStatus) 164 | { 165 | dwReturn = GetLastError(); 166 | __leave; 167 | } 168 | pBlobRef = (PRSAPUBLICKEYBLOB) pbBlobRef; 169 | pBlob = (PRSAPUBLICKEYBLOB) (dwKeySpec==AT_SIGNATURE ? ContainerInfo.pbSigPublicKey : ContainerInfo.pbKeyExPublicKey); 170 | //if (memcmp(pBlobRef, pBlob, ContainerInfo.cbSigPublicKey) != 0) 171 | for (DWORD dwI = 0; dwI < pBlobRef->rsapubkey.bitlen / 8; dwI++) 172 | { 173 | if ( pBlobRef->modulus[dwI] != pBlob->modulus[dwI]) 174 | { 175 | dwReturn = SCARD_E_UNEXPECTED; 176 | __leave; 177 | } 178 | } 179 | dwReturn = 0; 180 | 181 | } 182 | __finally 183 | { 184 | if (hKey) 185 | CryptDestroyKey(hKey); 186 | //CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); 187 | if (hProv) 188 | CryptReleaseContext(hProv,0); 189 | } 190 | return dwReturn; 191 | } 192 | 193 | DWORD SetTheSameKeyForAllContainers() 194 | { 195 | DWORD dwReturn, dwKeySpec; 196 | PIN_ID PinId; 197 | HCRYPTPROV hProv = NULL; 198 | HCRYPTKEY hKey = NULL; 199 | TCHAR szContainerName[] = OPENPGP_TEST_CONTAINER; 200 | BYTE pbData[4096]; 201 | BYTE pbDataControl[4096]; 202 | BYTE pbBlobRef[4096]; 203 | DWORD dwDataSize = ARRAYSIZE(pbData); 204 | DWORD dwBlobRefSize = ARRAYSIZE(pbBlobRef); 205 | BOOL bStatus; 206 | CONTAINER_INFO ContainerInfo; 207 | PRSAPUBLICKEYBLOB pBlob, pBlobRef; 208 | DWORD dwAglLen, dwSize, dwIndex; 209 | __try 210 | { 211 | if (!pCardData) 212 | { 213 | dwReturn = SCARD_E_COMM_DATA_LOST; 214 | __leave; 215 | } 216 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); 217 | if (!bStatus) 218 | { 219 | dwReturn = GetLastError(); 220 | if (dwReturn == NTE_BAD_KEYSET) 221 | { 222 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); 223 | } 224 | if (!bStatus) 225 | { 226 | dwReturn = GetLastError(); 227 | __leave; 228 | } 229 | } 230 | bStatus = CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey); 231 | if (!bStatus) 232 | { 233 | dwReturn = GetLastError(); 234 | __leave; 235 | } 236 | bStatus = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataSize); 237 | if (!bStatus) 238 | { 239 | dwReturn = GetLastError(); 240 | __leave; 241 | } 242 | memcpy(pbDataControl, pbData, ARRAYSIZE(pbData)); 243 | dwSize = sizeof(DWORD); 244 | bStatus = CryptGetKeyParam(hKey, KP_KEYLEN, (PBYTE) &dwAglLen,&dwSize , 0); 245 | 246 | for(dwIndex = 0; dwIndex < 3; dwIndex++) 247 | { 248 | switch(dwIndex) 249 | { 250 | case 0: //Signature, 251 | dwKeySpec = AT_SIGNATURE; 252 | PinId = ROLE_USER; 253 | break; 254 | case 2: //Authentication, 255 | dwKeySpec = AT_SIGNATURE; 256 | PinId = 3; 257 | break; 258 | case 1: // Confidentiality, 259 | dwKeySpec = AT_KEYEXCHANGE; 260 | PinId = 4; 261 | break; 262 | default: 263 | dwReturn = SCARD_E_UNEXPECTED; 264 | __leave; 265 | } 266 | 267 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) dwIndex, 268 | CARD_CREATE_CONTAINER_KEY_IMPORT, 269 | dwKeySpec, dwAglLen, pbData, PinId); 270 | if (dwReturn) 271 | { 272 | __leave; 273 | } 274 | // check if the buffer has been altered 275 | if (memcmp(pbDataControl,pbData, ARRAYSIZE(pbData)) != 0) 276 | { 277 | dwReturn = SCARD_E_UNEXPECTED; 278 | __leave; 279 | } 280 | 281 | memset(&ContainerInfo,0,sizeof(CONTAINER_INFO)); 282 | ContainerInfo.dwVersion = 0; 283 | dwReturn = pCardData->pfnCardGetContainerInfo(pCardData, (BYTE) dwIndex, 0, &ContainerInfo); 284 | if (dwReturn) 285 | { 286 | __leave; 287 | } 288 | bStatus = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbBlobRef, &dwBlobRefSize); 289 | if (!bStatus) 290 | { 291 | dwReturn = GetLastError(); 292 | __leave; 293 | } 294 | pBlobRef = (PRSAPUBLICKEYBLOB) pbBlobRef; 295 | pBlob = (PRSAPUBLICKEYBLOB) (dwKeySpec==AT_SIGNATURE ? ContainerInfo.pbSigPublicKey : ContainerInfo.pbKeyExPublicKey); 296 | //if (memcmp(pBlobRef, pBlob, ContainerInfo.cbSigPublicKey) != 0) 297 | for (DWORD dwI = 0; dwI < pBlobRef->rsapubkey.bitlen / 8; dwI++) 298 | { 299 | if ( pBlobRef->modulus[dwI] != pBlob->modulus[dwI]) 300 | { 301 | dwReturn = SCARD_E_UNEXPECTED; 302 | __leave; 303 | } 304 | } 305 | } 306 | dwReturn = 0; 307 | 308 | } 309 | __finally 310 | { 311 | if (hKey) 312 | CryptDestroyKey(hKey); 313 | //CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); 314 | if (hProv) 315 | CryptReleaseContext(hProv,0); 316 | } 317 | return dwReturn; 318 | } 319 | DWORD SetReadOnly(BOOL fSet) 320 | { 321 | DWORD dwReturn; 322 | __try 323 | { 324 | if (!pCardData) 325 | { 326 | dwReturn = SCARD_E_COMM_DATA_LOST; 327 | __leave; 328 | } 329 | dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0); 330 | } 331 | __finally 332 | { 333 | } 334 | return dwReturn; 335 | } -------------------------------------------------------------------------------- /OpenPGPminidriver/OpenPGPminidriver.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 18 | 19 | 20 | 21 | 22 | 29 | 32 | 35 | 38 | 41 | 44 | 55 | 58 | 61 | 64 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 96 | 103 | 106 | 109 | 112 | 115 | 119 | 130 | 133 | 136 | 139 | 149 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 171 | 179 | 182 | 185 | 188 | 191 | 194 | 205 | 208 | 211 | 214 | 226 | 229 | 232 | 235 | 238 | 241 | 244 | 247 | 248 | 256 | 259 | 262 | 265 | 268 | 272 | 283 | 286 | 289 | 292 | 304 | 307 | 310 | 313 | 316 | 319 | 322 | 325 | 326 | 327 | 328 | 329 | 330 | 335 | 338 | 339 | 342 | 343 | 346 | 347 | 350 | 351 | 354 | 355 | 358 | 359 | 362 | 363 | 366 | 367 | 368 | 373 | 376 | 377 | 380 | 381 | 384 | 385 | 388 | 389 | 392 | 393 | 396 | 397 | 400 | 401 | 402 | 405 | 408 | 409 | 412 | 413 | 414 | 417 | 420 | 421 | 424 | 425 | 428 | 429 | 430 | 433 | 436 | 437 | 440 | 441 | 444 | 445 | 448 | 449 | 452 | 453 | 454 | 457 | 458 | 459 | 460 | 461 | 462 | -------------------------------------------------------------------------------- /OpenPGPminidriverTest/Personnalize.cpp: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include "cardmod.h" 21 | #include "global.h" 22 | 23 | 24 | 25 | LPBYTE AllocateAndEncodeObject(LPVOID pvStruct, LPCSTR lpszStructType, LPDWORD pdwSize ) 26 | { 27 | // Get Key Usage blob size 28 | LPBYTE pbEncodedObject = NULL; 29 | BOOL bResult = TRUE; 30 | DWORD dwError; 31 | __try 32 | { 33 | *pdwSize = 0; 34 | bResult = CryptEncodeObject(X509_ASN_ENCODING, 35 | lpszStructType, 36 | pvStruct, 37 | NULL, pdwSize); 38 | if (!bResult) 39 | { 40 | dwError = GetLastError(); 41 | __leave; 42 | } 43 | 44 | // Allocate Memory for Key Usage Blob 45 | pbEncodedObject = (LPBYTE)LocalAlloc(0,*pdwSize); 46 | if (!pbEncodedObject) 47 | { 48 | bResult = FALSE; 49 | dwError = GetLastError(); 50 | __leave; 51 | } 52 | 53 | // Get Key Usage Extension blob 54 | bResult = CryptEncodeObject(X509_ASN_ENCODING, 55 | lpszStructType, 56 | pvStruct, 57 | pbEncodedObject, pdwSize); 58 | if (!bResult) 59 | { 60 | dwError = GetLastError(); 61 | __leave; 62 | } 63 | } 64 | __finally 65 | { 66 | if (pbEncodedObject && !bResult) 67 | { 68 | LocalFree(pbEncodedObject); 69 | } 70 | } 71 | return pbEncodedObject; 72 | } 73 | 74 | DWORD Personnalize() 75 | { 76 | DWORD dwReturn; 77 | BOOL fSet; 78 | HCRYPTPROV hProv = NULL; 79 | HCRYPTKEY hKey = NULL; 80 | TCHAR szContainerName[] = OPENPGP_TEST_CONTAINER; 81 | BYTE pbData[4096]; 82 | DWORD dwDataSize = ARRAYSIZE(pbData); 83 | BOOL bStatus; 84 | BYTE One = 1; 85 | CERT_NAME_BLOB SubjectIssuerBlob = {0}; 86 | CERT_INFO CertInfo = {0}; 87 | CertInfo.rgExtension = 0; 88 | CRYPT_BIT_BLOB KeyUsage; 89 | BYTE ByteData; 90 | LPBYTE pbKeyUsage = NULL; 91 | DWORD dwSize; 92 | CERT_BASIC_CONSTRAINTS2_INFO BasicConstraints; 93 | LPBYTE pbBasicConstraints = NULL; 94 | CERT_ENHKEY_USAGE CertEnhKeyUsage = { 0, NULL }; 95 | LPBYTE pbEnhKeyUsage = NULL; 96 | CERT_EXTENSIONS CertExtensions = {0} ; 97 | PCCERT_CONTEXT pNewCertificateContext = NULL; 98 | SYSTEMTIME StartTime; 99 | SYSTEMTIME EndTime; 100 | HCERTSTORE hCertStore = NULL; 101 | BYTE pbCertificateBlob[4096]; 102 | CERT_BLOB dbStore = {ARRAYSIZE(pbCertificateBlob),pbCertificateBlob}; 103 | __try 104 | { 105 | if (!pCardData) 106 | { 107 | dwReturn = SCARD_E_COMM_DATA_LOST; 108 | __leave; 109 | } 110 | fSet = FALSE; 111 | dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0); 112 | if (dwReturn) __leave; 113 | dwReturn = pCardData->pfnCardWriteFile(pCardData, "openpgp", "statusP1", 0, &One, 1); 114 | if (dwReturn) __leave; 115 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 0, 116 | CARD_CREATE_CONTAINER_KEY_GEN, 117 | AT_SIGNATURE, 1024, NULL, 1); 118 | if (dwReturn) __leave; 119 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); 120 | if (!bStatus) 121 | { 122 | dwReturn = GetLastError(); 123 | if (dwReturn == NTE_BAD_KEYSET) 124 | { 125 | bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); 126 | } 127 | if (!bStatus) 128 | { 129 | dwReturn = GetLastError(); 130 | __leave; 131 | } 132 | } 133 | // WARNING : AT_SIGNATURE is used implicitely when creating a new certificate 134 | // if you use AT_KEYEXCHANGE, the public key of the container 135 | // won't match the public key of the certificate 136 | bStatus = CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey); 137 | if (!bStatus) 138 | { 139 | dwReturn = GetLastError(); 140 | __leave; 141 | } 142 | bStatus = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataSize); 143 | if (!bStatus) 144 | { 145 | dwReturn = GetLastError(); 146 | __leave; 147 | } 148 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 1, 149 | CARD_CREATE_CONTAINER_KEY_IMPORT, 150 | AT_KEYEXCHANGE, 1024, pbData, 3); 151 | if (dwReturn) 152 | { 153 | __leave; 154 | } 155 | dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 2, 156 | CARD_CREATE_CONTAINER_KEY_IMPORT, 157 | AT_SIGNATURE, 1024, pbData, 3); 158 | if (dwReturn) 159 | { 160 | __leave; 161 | } 162 | // create the cert data 163 | if (!CertStrToName(X509_ASN_ENCODING,TEXT("CN=test"),CERT_X500_NAME_STR,NULL,NULL,&SubjectIssuerBlob.cbData,NULL)) 164 | { 165 | dwReturn = GetLastError(); 166 | __leave; 167 | } 168 | SubjectIssuerBlob.pbData = (PBYTE) LocalAlloc(0,SubjectIssuerBlob.cbData); 169 | if (!SubjectIssuerBlob.pbData) 170 | { 171 | dwReturn = GetLastError(); 172 | __leave; 173 | } 174 | if (!CertStrToName(X509_ASN_ENCODING,TEXT("CN=test"),CERT_X500_NAME_STR,NULL,(PBYTE)SubjectIssuerBlob.pbData,&SubjectIssuerBlob.cbData,NULL)) 175 | { 176 | dwReturn = GetLastError(); 177 | __leave; 178 | } 179 | // max 10 extensions => we don't count them 180 | CertInfo.rgExtension = (PCERT_EXTENSION) LocalAlloc(0,sizeof(CERT_EXTENSION) * 10); 181 | CertInfo.cExtension = 0; 182 | if (!CertInfo.rgExtension) __leave; 183 | 184 | 185 | // Set Key Usage according to Public Key Type 186 | ZeroMemory(&KeyUsage, sizeof(KeyUsage)); 187 | KeyUsage.cbData = 1; 188 | KeyUsage.pbData = &ByteData; 189 | ByteData = CERT_DIGITAL_SIGNATURE_KEY_USAGE | 190 | CERT_DATA_ENCIPHERMENT_KEY_USAGE| 191 | CERT_KEY_ENCIPHERMENT_KEY_USAGE | 192 | CERT_KEY_AGREEMENT_KEY_USAGE; 193 | pbKeyUsage = AllocateAndEncodeObject(&KeyUsage,X509_KEY_USAGE,&dwSize); 194 | if (!pbKeyUsage) __leave; 195 | 196 | CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_KEY_USAGE; 197 | CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE; 198 | CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize; 199 | CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbKeyUsage; 200 | // Increase extension count 201 | CertInfo.cExtension++; 202 | ////////////////////////////////////////////////// 203 | 204 | // Zero Basic Constraints structure 205 | ZeroMemory(&BasicConstraints, sizeof(BasicConstraints)); 206 | 207 | BasicConstraints.fCA = TRUE; 208 | BasicConstraints.fPathLenConstraint = TRUE; 209 | BasicConstraints.dwPathLenConstraint = 1; 210 | pbBasicConstraints = AllocateAndEncodeObject(&BasicConstraints,X509_BASIC_CONSTRAINTS2,&dwSize); 211 | if (!pbBasicConstraints) __leave; 212 | 213 | // Set Basic Constraints extension 214 | CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_BASIC_CONSTRAINTS2; 215 | CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE; 216 | CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize; 217 | CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbBasicConstraints; 218 | // Increase extension count 219 | CertInfo.cExtension++; 220 | ////////////////////////////////////////////////// 221 | CertEnhKeyUsage.cUsageIdentifier+=4; 222 | 223 | CertEnhKeyUsage.rgpszUsageIdentifier = (LPSTR*) LocalAlloc(0,sizeof(LPSTR)*CertEnhKeyUsage.cUsageIdentifier); 224 | if (!CertEnhKeyUsage.rgpszUsageIdentifier) __leave; 225 | CertEnhKeyUsage.cUsageIdentifier = 0; 226 | CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_PKIX_KP_CLIENT_AUTH; 227 | CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_PKIX_KP_SERVER_AUTH; 228 | CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_KP_SMARTCARD_LOGON; 229 | CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_KP_EFS; 230 | pbEnhKeyUsage = AllocateAndEncodeObject(&CertEnhKeyUsage,X509_ENHANCED_KEY_USAGE,&dwSize); 231 | if (!pbEnhKeyUsage) __leave; 232 | 233 | // Set Basic Constraints extension 234 | CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_ENHANCED_KEY_USAGE; 235 | CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE; 236 | CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize; 237 | CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbEnhKeyUsage; 238 | // Increase extension count 239 | CertInfo.cExtension++; 240 | 241 | ////////////////////////////////////////////////// 242 | 243 | CertExtensions.cExtension = CertInfo.cExtension; 244 | CertExtensions.rgExtension = CertInfo.rgExtension; 245 | 246 | GetSystemTime(&StartTime); 247 | GetSystemTime(&EndTime); 248 | EndTime.wYear += 10; 249 | pNewCertificateContext = CertCreateSelfSignCertificate(hProv,&SubjectIssuerBlob, 250 | 0,NULL,NULL,&StartTime,&EndTime,&CertExtensions); 251 | if (!pNewCertificateContext) 252 | { 253 | dwReturn = GetLastError(); 254 | __leave; 255 | } 256 | /*hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY,0,(HCRYPTPROV)NULL,0,NULL); 257 | if (!hCertStore) 258 | { 259 | dwReturn = GetLastError(); 260 | __leave; 261 | } 262 | if( !CertAddCertificateContextToStore(hCertStore, // Store handle 263 | pNewCertificateContext, // Pointer to a certificate 264 | CERT_STORE_ADD_REPLACE_EXISTING, NULL) ) 265 | { 266 | dwReturn = GetLastError(); 267 | __leave; 268 | } 269 | if (!CertSaveStore( hCertStore, 270 | PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 271 | CERT_STORE_SAVE_AS_PKCS7, 272 | CERT_STORE_SAVE_TO_MEMORY, 273 | &dbStore, 274 | 0)) 275 | { 276 | dwReturn = GetLastError(); 277 | __leave; 278 | } 279 | dwReturn = pCardData->pfnCardWriteFile(pCardData, szBASE_CSP_DIR, "kxc01", 0, 280 | dbStore.pbData, 281 | dbStore.cbData); 282 | if (dwReturn) 283 | { 284 | __leave; 285 | }*/ 286 | dwReturn = pCardData->pfnCardWriteFile(pCardData, szBASE_CSP_DIR, "kxc01", 0, 287 | pNewCertificateContext->pbCertEncoded, 288 | pNewCertificateContext->cbCertEncoded); 289 | if (dwReturn) 290 | { 291 | __leave; 292 | } 293 | ViewCertificate(NULL, pNewCertificateContext); 294 | fSet = TRUE; 295 | dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0); 296 | if (dwReturn) __leave; 297 | 298 | } 299 | __finally 300 | { 301 | if (hKey) 302 | CryptDestroyKey(hKey); 303 | //CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); 304 | if (hProv) 305 | CryptReleaseContext(hProv,0); 306 | } 307 | return dwReturn; 308 | } -------------------------------------------------------------------------------- /OpenPGPminidriver/SmartCard.c: -------------------------------------------------------------------------------- 1 | /* OpenPGP Smart Card Mini Driver 2 | Copyright (C) 2009 Vincent Le Toux 3 | 4 | This library is Free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License version 2.1 as published by the Free Software Foundation. 7 | 8 | This library is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | Lesser General Public License for more details. 12 | 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | */ 17 | 18 | #include 19 | #include "cardmod.h" 20 | #include 21 | #include "Tracing.h" 22 | #include "Context.h" 23 | #include "SmartCard.h" 24 | 25 | #pragma comment(lib,"Winscard") 26 | 27 | DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData); 28 | 29 | /** called to re-select the Openpgp application when a SCARD_W_RESET occured */ 30 | DWORD OCardReconnect(__in PCARD_DATA pCardData) 31 | { 32 | DWORD dwAP; 33 | DWORD dwReturn; 34 | __try 35 | { 36 | // reset the card 37 | Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); 38 | dwReturn = SCardReconnect(pCardData->hScard, 39 | SCARD_SHARE_SHARED, 40 | SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, 41 | SCARD_LEAVE_CARD, 42 | &dwAP ); 43 | if (dwReturn) 44 | { 45 | Trace(WINEVENT_LEVEL_ERROR, L"SCardReconnect 0x%08X", dwReturn); 46 | __leave; 47 | } 48 | 49 | dwReturn = SelectOpenPGPApplication(pCardData); 50 | } 51 | __finally 52 | { 53 | } 54 | return dwReturn; 55 | } 56 | 57 | /** send a command to the smart card with no response expected */ 58 | DWORD OCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize) 59 | { 60 | DWORD dwReturn = 0; 61 | 62 | SCARD_IO_REQUEST ioSendPci = {1, sizeof(SCARD_IO_REQUEST)}; 63 | SCARD_IO_REQUEST ioRecvPci = {1, sizeof(SCARD_IO_REQUEST)}; 64 | BYTE recvbuf[256]; 65 | DWORD recvlen = sizeof(recvbuf); 66 | BYTE SW1, SW2; 67 | __try 68 | { 69 | 70 | dwReturn = SCardTransmit(pCardData->hScard, 71 | SCARD_PCI_T1, 72 | pbCmd, 73 | dwCmdSize, 74 | NULL, 75 | recvbuf, 76 | &recvlen); 77 | if ( dwReturn != SCARD_S_SUCCESS ) 78 | { 79 | if (dwReturn == SCARD_W_RESET_CARD) 80 | { 81 | dwReturn = OCardReconnect(pCardData); 82 | if (dwReturn) 83 | { 84 | __leave; 85 | } 86 | dwReturn = OCardSendCommand(pCardData,pbCmd, dwCmdSize); 87 | __leave; 88 | } 89 | Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn); 90 | __leave; 91 | } 92 | SW1 = recvbuf[recvlen-2]; 93 | SW2 = recvbuf[recvlen-1]; 94 | if ( (SW1 == 0x6A) && (SW2 == 0x88) ) 95 | { 96 | Trace(WINEVENT_LEVEL_ERROR, L"card reset"); 97 | recvlen = sizeof(recvbuf); 98 | dwReturn = SelectOpenPGPApplication(pCardData); 99 | if (dwReturn) 100 | { 101 | __leave; 102 | } 103 | dwReturn = SCardTransmit(pCardData->hScard, 104 | SCARD_PCI_T1, 105 | pbCmd, 106 | dwCmdSize, 107 | NULL, 108 | recvbuf, 109 | &recvlen); 110 | SW1 = recvbuf[recvlen-2]; 111 | SW2 = recvbuf[recvlen-1]; 112 | } 113 | if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) ) 114 | { 115 | 116 | } 117 | else if ( (SW1 == 0x69) && (SW2 == 0x82) ) 118 | { 119 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV"); 120 | dwReturn = SCARD_W_WRONG_CHV; 121 | __leave; 122 | } 123 | else if ( (SW1 == 0x69) && (SW2 == 0x83) ) 124 | { 125 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED"); 126 | dwReturn = SCARD_W_CHV_BLOCKED; 127 | __leave; 128 | } 129 | else if ( (SW1 == 0x69) && (SW2 == 0x85) ) 130 | { 131 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION"); 132 | dwReturn = SCARD_W_SECURITY_VIOLATION; 133 | __leave; 134 | } 135 | else 136 | { 137 | TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize); 138 | Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2); 139 | dwReturn = SCARD_F_UNKNOWN_ERROR; 140 | __leave; 141 | } 142 | } 143 | __finally 144 | { 145 | } 146 | return dwReturn; 147 | } 148 | 149 | /** send the select open pgp application apdu */ 150 | DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData) 151 | { 152 | BYTE pbCmd[] = {0x00, 153 | 0xA4, 154 | 0x04, 155 | 0x00, 156 | 0x06, 157 | 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, 158 | 0x00 159 | }; 160 | 161 | return OCardSendCommand(pCardData, pbCmd, sizeof(pbCmd)); 162 | } 163 | 164 | /** send a command to the smart card with response expected */ 165 | DWORD OCardGetData(__in PCARD_DATA pCardData, 166 | __in PBYTE pbCmd, __in DWORD dwCmdSize, 167 | __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize) 168 | { 169 | 170 | DWORD dwReturn; 171 | BYTE pbGetResponse[] = {0x00, 172 | 0xC0, 173 | 0x00, 174 | 0x00, 175 | 0x00 176 | }; 177 | DWORD dwGetResponseSize = ARRAYSIZE(pbGetResponse); 178 | BYTE recvbuf[0x800]; 179 | DWORD recvlen = sizeof(recvbuf); 180 | BYTE SW1, SW2; 181 | DWORD dwDataSize = 0; 182 | __try 183 | { 184 | 185 | *pbResponse = NULL; 186 | dwReturn = SCardTransmit(pCardData->hScard, 187 | SCARD_PCI_T1, 188 | pbCmd, 189 | dwCmdSize, 190 | NULL, 191 | recvbuf, 192 | &recvlen); 193 | 194 | do 195 | { 196 | if ( dwReturn != SCARD_S_SUCCESS ) 197 | { 198 | if (dwReturn == SCARD_W_RESET_CARD) 199 | { 200 | dwReturn = OCardReconnect(pCardData); 201 | if (dwReturn) 202 | { 203 | __leave; 204 | } 205 | dwReturn = OCardGetData(pCardData,pbCmd, dwCmdSize,pbResponse, pdwResponseSize); 206 | __leave; 207 | } 208 | Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn); 209 | __leave; 210 | } 211 | SW1 = recvbuf[recvlen-2]; 212 | SW2 = recvbuf[recvlen-1]; 213 | if ( (SW1 == 0x6A) && (SW2 == 0x88) ) 214 | { 215 | Trace(WINEVENT_LEVEL_ERROR, L"card reset"); 216 | recvlen = sizeof(recvbuf); 217 | dwReturn = SelectOpenPGPApplication(pCardData); 218 | if (dwReturn) 219 | { 220 | __leave; 221 | } 222 | dwReturn = SCardTransmit(pCardData->hScard, 223 | SCARD_PCI_T1, 224 | pbCmd, 225 | dwCmdSize, 226 | NULL, 227 | recvbuf, 228 | &recvlen); 229 | SW1 = recvbuf[recvlen-2]; 230 | SW2 = recvbuf[recvlen-1]; 231 | } 232 | if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) ) 233 | { 234 | dwDataSize = recvlen-2; 235 | *pbResponse = pCardData->pfnCspAlloc(dwDataSize); 236 | if (! *pbResponse) 237 | { 238 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY"); 239 | dwReturn = SCARD_E_NO_MEMORY; 240 | __leave; 241 | } 242 | memcpy(*pbResponse, recvbuf, dwDataSize); 243 | } 244 | else if (SW1 == 0x61) 245 | { 246 | dwDataSize += SW2; 247 | if (*pbResponse) 248 | { 249 | *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize); 250 | } 251 | else 252 | { 253 | *pbResponse = pCardData->pfnCspAlloc(dwDataSize); 254 | } 255 | dwGetResponseSize = ARRAYSIZE(pbGetResponse); 256 | dwReturn = SCardTransmit(pCardData->hScard, 257 | SCARD_PCI_T1, 258 | pbGetResponse, 259 | dwGetResponseSize, 260 | NULL, 261 | recvbuf, 262 | &recvlen); 263 | } 264 | else if ( (SW1 == 0x69) && (SW2 == 0x82) ) 265 | { 266 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV"); 267 | dwReturn = SCARD_W_WRONG_CHV; 268 | __leave; 269 | } 270 | else if ( (SW1 == 0x69) && (SW2 == 0x83) ) 271 | { 272 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED"); 273 | dwReturn = SCARD_W_CHV_BLOCKED; 274 | __leave; 275 | } 276 | else if ( (SW1 == 0x69) && (SW2 == 0x85) ) 277 | { 278 | Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION"); 279 | dwReturn = SCARD_W_SECURITY_VIOLATION; 280 | __leave; 281 | } 282 | else 283 | { 284 | TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize); 285 | Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2); 286 | dwReturn = SCARD_F_UNKNOWN_ERROR; 287 | __leave; 288 | } 289 | 290 | } while (SW1 == 0x61); 291 | if (pdwResponseSize) 292 | { 293 | *pdwResponseSize = dwDataSize; 294 | } 295 | } 296 | __finally 297 | { 298 | } 299 | return dwReturn; 300 | } 301 | 302 | DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength) 303 | { 304 | DWORD idx = 0; 305 | int count; 306 | while (idx < featuresLength) { 307 | BYTE tag = features[idx]; 308 | idx++; 309 | idx++; 310 | if (featureTag == tag) { 311 | DWORD feature = 0; 312 | for (count = 0; count < 3; count++) { 313 | feature |= features[idx] & 0xff; 314 | idx++; 315 | feature <<= 8; 316 | } 317 | feature |= features[idx] & 0xff; 318 | return feature; 319 | } 320 | idx += 4; 321 | } 322 | return 0; 323 | } 324 | 325 | DWORD CCIDgetFeatures(__in PCARD_DATA pCardData) 326 | { 327 | BYTE pbRecvBuffer[200]; 328 | DWORD dwRecvLength, dwReturn; 329 | __try 330 | { 331 | POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; 332 | 333 | pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0; 334 | pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0; 335 | pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0; 336 | pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0; 337 | pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0; 338 | pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0; 339 | pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0; 340 | pContext->SmartCardReaderFeatures.ABORT = 0; 341 | 342 | dwReturn = SCardControl(pCardData->hScard, 343 | SCARD_CTL_CODE(3400), 344 | NULL, 345 | 0, 346 | pbRecvBuffer, 347 | sizeof(pbRecvBuffer), 348 | &dwRecvLength); 349 | if ( dwReturn ) 350 | { 351 | Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn); 352 | __leave; 353 | } 354 | pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength); 355 | pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength); 356 | pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength); 357 | pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength); 358 | pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength); 359 | pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength); 360 | pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength); 361 | pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength); 362 | } 363 | __finally 364 | { 365 | } 366 | return dwReturn; 367 | } -------------------------------------------------------------------------------- /OpenPGPminidriverTest/OpenPGPminidriverTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {4E413ED7-0D68-47A9-AB93-39319815E730} 23 | OpenPGPminidriverTest 24 | Win32Proj 25 | SAK 26 | SAK 27 | SAK 28 | SAK 29 | 30 | 31 | 32 | Application 33 | Unicode 34 | true 35 | v110 36 | 37 | 38 | Application 39 | Unicode 40 | v110 41 | 42 | 43 | Application 44 | Unicode 45 | true 46 | v110 47 | 48 | 49 | Application 50 | Unicode 51 | v110 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | <_ProjectFileVersion>10.0.40219.1 71 | $(SolutionDir)$(Configuration)\ 72 | $(Platform)\$(Configuration)\ 73 | true 74 | $(SolutionDir)$(Configuration)\ 75 | $(Platform)\$(Configuration)\ 76 | true 77 | $(SolutionDir)$(Configuration)\ 78 | $(Platform)\$(Configuration)\ 79 | false 80 | $(SolutionDir)$(Configuration)\ 81 | $(Platform)\$(Configuration)\ 82 | false 83 | AllRules.ruleset 84 | 85 | 86 | AllRules.ruleset 87 | 88 | 89 | AllRules.ruleset 90 | 91 | 92 | AllRules.ruleset 93 | 94 | 95 | 96 | 97 | 98 | Disabled 99 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 100 | true 101 | EnableFastChecks 102 | MultiThreadedDebugDLL 103 | 104 | 105 | Level3 106 | EditAndContinue 107 | 108 | 109 | $(OutDir)$(ProjectName)32.exe 110 | true 111 | Windows 112 | MachineX86 113 | 114 | 115 | 116 | 117 | X64 118 | 119 | 120 | Disabled 121 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 122 | true 123 | EnableFastChecks 124 | MultiThreadedDebugDLL 125 | 126 | 127 | Level3 128 | ProgramDatabase 129 | 130 | 131 | $(OutDir)$(ProjectName)64.exe 132 | true 133 | Windows 134 | MachineX64 135 | 136 | 137 | 138 | 139 | MaxSpeed 140 | true 141 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 142 | MultiThreadedDLL 143 | true 144 | 145 | 146 | Level3 147 | ProgramDatabase 148 | 149 | 150 | $(OutDir)$(ProjectName)32.exe 151 | true 152 | Windows 153 | true 154 | true 155 | MachineX86 156 | 157 | 158 | 159 | 160 | X64 161 | 162 | 163 | MaxSpeed 164 | true 165 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 166 | MultiThreadedDLL 167 | true 168 | 169 | 170 | Level3 171 | ProgramDatabase 172 | 173 | 174 | $(OutDir)$(ProjectName)64.exe 175 | true 176 | Windows 177 | true 178 | true 179 | MachineX64 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | {775dab1d-5a49-4a57-b259-ad3dc833a75f} 206 | false 207 | 208 | 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /OpenPGPminidriver/OpenPGPminidriver.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {775DAB1D-5A49-4A57-B259-AD3DC833A75F} 23 | OpenPGPminidriver 24 | Win32Proj 25 | SAK 26 | SAK 27 | SAK 28 | SAK 29 | 30 | 31 | 32 | DynamicLibrary 33 | Unicode 34 | true 35 | v110 36 | 37 | 38 | DynamicLibrary 39 | Unicode 40 | v110 41 | 42 | 43 | DynamicLibrary 44 | Unicode 45 | true 46 | v110 47 | 48 | 49 | DynamicLibrary 50 | Unicode 51 | v110 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | <_ProjectFileVersion>10.0.40219.1 71 | $(SolutionDir)x86\$(Configuration)\ 72 | $(Platform)\$(Configuration)\ 73 | true 74 | $(SolutionDir)$(Platform)\$(Configuration)\ 75 | $(Platform)\$(Configuration)\ 76 | true 77 | $(SolutionDir)x86\$(Configuration)\ 78 | $(Platform)\$(Configuration)\ 79 | false 80 | $(SolutionDir)$(Platform)\$(Configuration)\ 81 | $(Platform)\$(Configuration)\ 82 | false 83 | AllRules.ruleset 84 | 85 | 86 | AllRules.ruleset 87 | 88 | 89 | AllRules.ruleset 90 | 91 | 92 | AllRules.ruleset 93 | 94 | 95 | 96 | 97 | 98 | Disabled 99 | WIN32;_DEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS;%(PreprocessorDefinitions) 100 | true 101 | EnableFastChecks 102 | MultiThreadedDebug 103 | 104 | 105 | Level3 106 | EditAndContinue 107 | 108 | 109 | $(OutDir)openpgpmdrv32.dll 110 | OpenPGPminidriver.def 111 | advapi32.dll;%(DelayLoadDLLs) 112 | true 113 | Windows 114 | MachineX86 115 | 116 | 117 | 118 | 119 | X64 120 | 121 | 122 | Disabled 123 | WIN32;_DEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS;%(PreprocessorDefinitions) 124 | true 125 | EnableFastChecks 126 | MultiThreadedDebug 127 | 128 | 129 | Level3 130 | ProgramDatabase 131 | 132 | 133 | $(OutDir)openpgpmdrv64.dll 134 | OpenPGPminidriver.def 135 | advapi32.dll;%(DelayLoadDLLs) 136 | true 137 | Windows 138 | MachineX64 139 | 140 | 141 | 142 | 143 | MaxSpeed 144 | true 145 | WIN32;NDEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS;%(PreprocessorDefinitions) 146 | MultiThreaded 147 | true 148 | 149 | 150 | Level3 151 | ProgramDatabase 152 | 153 | 154 | $(OutDir)openpgpmdrv32.dll 155 | OpenPGPminidriver.def 156 | advapi32.dll;%(DelayLoadDLLs) 157 | true 158 | Windows 159 | true 160 | true 161 | MachineX86 162 | 163 | 164 | 165 | 166 | X64 167 | 168 | 169 | MaxSpeed 170 | true 171 | WIN32;NDEBUG;_WINDOWS;_USRDLL;OPENPGPMINIDRIVER_EXPORTS;%(PreprocessorDefinitions) 172 | MultiThreaded 173 | true 174 | 175 | 176 | Level3 177 | ProgramDatabase 178 | 179 | 180 | $(OutDir)openpgpmdrv64.dll 181 | OpenPGPminidriver.def 182 | advapi32.dll;%(DelayLoadDLLs) 183 | true 184 | Windows 185 | true 186 | true 187 | MachineX64 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | --------------------------------------------------------------------------------