/[openpgpmdrv]/trunk/OpenPGPminidriver/SmartCard.c
ViewVC logotype

Annotation of /trunk/OpenPGPminidriver/SmartCard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Thu Feb 25 22:09:17 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 7554 byte(s)
fixed public key export (big endian - little endian issue)
signature works (sign & verify)
decrypt really decrypt but output not recognized yet by cryptoapi
1 vletoux 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 <windows.h>
19     #include <cardmod.h>
20     #include <stdio.h>
21     #include "Tracing.h"
22     #include "Context.h"
23     #include "SmartCard.h"
24    
25     #pragma comment(lib,"Winscard")
26    
27    
28     DWORD SCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize)
29     {
30     DWORD dwReturn = 0;
31    
32     SCARD_IO_REQUEST ioSendPci = {1, sizeof(SCARD_IO_REQUEST)};
33     SCARD_IO_REQUEST ioRecvPci = {1, sizeof(SCARD_IO_REQUEST)};
34     BYTE recvbuf[256];
35     DWORD recvlen = sizeof(recvbuf);
36     BYTE SW1, SW2;
37     __try
38     {
39    
40     dwReturn = SCardTransmit(pCardData->hScard,
41     SCARD_PCI_T1,
42     pbCmd,
43     dwCmdSize,
44     NULL,
45     recvbuf,
46     &recvlen);
47     if ( dwReturn != SCARD_S_SUCCESS )
48     {
49     Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
50     __leave;
51     }
52     SW1 = recvbuf[recvlen-2];
53     SW2 = recvbuf[recvlen-1];
54     if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
55     {
56    
57     }
58     else if ( (SW1 == 0x69) && (SW2 == 0x82) )
59     {
60     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
61     dwReturn = SCARD_W_WRONG_CHV;
62     __leave;
63     }
64     else if ( (SW1 == 0x69) && (SW2 == 0x83) )
65     {
66     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
67     dwReturn = SCARD_W_CHV_BLOCKED;
68     __leave;
69     }
70     else
71     {
72     TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
73     Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
74     dwReturn = SCARD_F_UNKNOWN_ERROR;
75     __leave;
76     }
77     }
78     __finally
79     {
80     }
81     return dwReturn;
82     }
83    
84     DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData)
85     {
86     BYTE pbCmd[] = {0x00,
87     0xA4,
88     0x04,
89     0x00,
90     0x06,
91     0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
92     0x00
93     };
94    
95     return SCardSendCommand(pCardData, pbCmd, sizeof(pbCmd));
96     }
97    
98    
99     DWORD SCardGetData(__in PCARD_DATA pCardData,
100     __in PBYTE pbCmd, __in DWORD dwCmdSize,
101     __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
102     {
103    
104     DWORD dwReturn;
105     BYTE pbGetResponse[] = {0x00,
106     0xC0,
107     0x00,
108     0x00,
109     0x00
110     };
111     DWORD dwGetResponseSize = ARRAYSIZE(pbGetResponse);
112     BYTE recvbuf[0x800];
113     DWORD recvlen = sizeof(recvbuf);
114     BYTE SW1, SW2;
115     DWORD dwDataSize = 0;
116     __try
117     {
118    
119     *pbResponse = NULL;
120     dwReturn = SCardTransmit(pCardData->hScard,
121     SCARD_PCI_T1,
122     pbCmd,
123     dwCmdSize,
124     NULL,
125     recvbuf,
126     &recvlen);
127    
128     do
129     {
130     if ( dwReturn != SCARD_S_SUCCESS )
131     {
132     Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
133     __leave;
134     }
135     SW1 = recvbuf[recvlen-2];
136     SW2 = recvbuf[recvlen-1];
137     if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
138     {
139     dwDataSize = recvlen-2;
140     *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
141     memcpy(*pbResponse, recvbuf, dwDataSize);
142     }
143     else if (SW1 == 0x61)
144     {
145     dwDataSize += SW2;
146     if (*pbResponse)
147     {
148     *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize);
149     }
150     else
151     {
152     *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
153     }
154     dwGetResponseSize = ARRAYSIZE(pbGetResponse);
155     dwReturn = SCardTransmit(pCardData->hScard,
156     SCARD_PCI_T1,
157     pbGetResponse,
158     dwGetResponseSize,
159     NULL,
160     recvbuf,
161     &recvlen);
162     }
163     else if ( (SW1 == 0x69) && (SW2 == 0x82) )
164     {
165     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
166     dwReturn = SCARD_W_WRONG_CHV;
167     __leave;
168     }
169     else if ( (SW1 == 0x69) && (SW2 == 0x83) )
170     {
171     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
172     dwReturn = SCARD_W_CHV_BLOCKED;
173     __leave;
174     }
175     else if ( (SW1 == 0x6A) && (SW2 == 0x88) )
176     {
177     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND");
178     dwReturn = SCARD_E_FILE_NOT_FOUND;
179     __leave;
180     }
181     else
182     {
183     TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
184     Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
185     dwReturn = SCARD_F_UNKNOWN_ERROR;
186     __leave;
187     }
188    
189     } while (SW1 == 0x61);
190     if (pdwResponseSize)
191     {
192     *pdwResponseSize = dwDataSize;
193     }
194     }
195     __finally
196     {
197     }
198     return dwReturn;
199     }
200    
201     DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength)
202     {
203     DWORD idx = 0;
204     int count;
205     while (idx < featuresLength) {
206     BYTE tag = features[idx];
207     idx++;
208     idx++;
209     if (featureTag == tag) {
210     DWORD feature = 0;
211     for (count = 0; count < 3; count++) {
212     feature |= features[idx] & 0xff;
213     idx++;
214     feature <<= 8;
215     }
216     feature |= features[idx] & 0xff;
217     return feature;
218     }
219     idx += 4;
220     }
221     return 0;
222     }
223    
224     DWORD CCIDgetFeatures(__in PCARD_DATA pCardData)
225     {
226     BYTE pbRecvBuffer[200];
227     DWORD dwRecvLength, dwReturn;
228     __try
229     {
230     POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
231    
232     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0;
233     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0;
234     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0;
235     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0;
236     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0;
237     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0;
238     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0;
239     pContext->SmartCardReaderFeatures.ABORT = 0;
240    
241     dwReturn = SCardControl(pCardData->hScard,
242     SCARD_CTL_CODE(3400),
243     NULL,
244     0,
245     pbRecvBuffer,
246     sizeof(pbRecvBuffer),
247     &dwRecvLength);
248     if ( dwReturn )
249     {
250     Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn);
251     __leave;
252     }
253     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength);
254     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
255     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
256     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength);
257     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
258     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
259     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength);
260     pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength);
261     }
262     __finally
263     {
264     }
265     return dwReturn;
266     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26