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

Annotation of /trunk/OpenPGPminidriver/SmartCard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (hide annotations)
Thu Mar 11 20:32:26 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 8847 byte(s)
improvement of the quality of the project.
More test for the qualification of the driver success but not all ...

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 vletoux 8 DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData);
28 vletoux 1
29 vletoux 8 DWORD OCardReconnect(__in PCARD_DATA pCardData)
30 vletoux 1 {
31 vletoux 8 DWORD dwAP;
32     DWORD dwReturn;
33     __try
34     {
35     // reset the card
36     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
37     dwReturn = SCardReconnect(pCardData->hScard,
38     SCARD_SHARE_SHARED,
39     SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
40     SCARD_LEAVE_CARD,
41     &dwAP );
42     if (dwReturn)
43     {
44     Trace(WINEVENT_LEVEL_ERROR, L"SCardReconnect 0x%08X", dwReturn);
45     __leave;
46     }
47    
48     dwReturn = SelectOpenPGPApplication(pCardData);
49     }
50     __finally
51     {
52     }
53     return dwReturn;
54     }
55    
56     DWORD OCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize)
57     {
58 vletoux 1 DWORD dwReturn = 0;
59    
60     SCARD_IO_REQUEST ioSendPci = {1, sizeof(SCARD_IO_REQUEST)};
61     SCARD_IO_REQUEST ioRecvPci = {1, sizeof(SCARD_IO_REQUEST)};
62     BYTE recvbuf[256];
63     DWORD recvlen = sizeof(recvbuf);
64     BYTE SW1, SW2;
65     __try
66     {
67    
68     dwReturn = SCardTransmit(pCardData->hScard,
69     SCARD_PCI_T1,
70     pbCmd,
71     dwCmdSize,
72     NULL,
73     recvbuf,
74     &recvlen);
75     if ( dwReturn != SCARD_S_SUCCESS )
76     {
77 vletoux 8 if (dwReturn == SCARD_W_RESET_CARD)
78     {
79     dwReturn = OCardReconnect(pCardData);
80     if (dwReturn)
81     {
82     __leave;
83     }
84     dwReturn = OCardSendCommand(pCardData,pbCmd, dwCmdSize);
85     __leave;
86     }
87 vletoux 1 Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
88     __leave;
89     }
90     SW1 = recvbuf[recvlen-2];
91     SW2 = recvbuf[recvlen-1];
92     if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
93     {
94    
95     }
96     else if ( (SW1 == 0x69) && (SW2 == 0x82) )
97     {
98     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
99     dwReturn = SCARD_W_WRONG_CHV;
100     __leave;
101     }
102     else if ( (SW1 == 0x69) && (SW2 == 0x83) )
103     {
104     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
105     dwReturn = SCARD_W_CHV_BLOCKED;
106     __leave;
107     }
108     else
109     {
110     TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
111     Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
112     dwReturn = SCARD_F_UNKNOWN_ERROR;
113     __leave;
114     }
115     }
116     __finally
117     {
118     }
119     return dwReturn;
120     }
121    
122     DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData)
123     {
124     BYTE pbCmd[] = {0x00,
125     0xA4,
126     0x04,
127     0x00,
128     0x06,
129     0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
130     0x00
131     };
132    
133 vletoux 8 return OCardSendCommand(pCardData, pbCmd, sizeof(pbCmd));
134 vletoux 1 }
135    
136    
137 vletoux 8 DWORD OCardGetData(__in PCARD_DATA pCardData,
138 vletoux 1 __in PBYTE pbCmd, __in DWORD dwCmdSize,
139     __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
140     {
141    
142     DWORD dwReturn;
143     BYTE pbGetResponse[] = {0x00,
144     0xC0,
145     0x00,
146     0x00,
147     0x00
148     };
149     DWORD dwGetResponseSize = ARRAYSIZE(pbGetResponse);
150     BYTE recvbuf[0x800];
151     DWORD recvlen = sizeof(recvbuf);
152     BYTE SW1, SW2;
153     DWORD dwDataSize = 0;
154     __try
155     {
156    
157     *pbResponse = NULL;
158     dwReturn = SCardTransmit(pCardData->hScard,
159     SCARD_PCI_T1,
160     pbCmd,
161     dwCmdSize,
162     NULL,
163     recvbuf,
164     &recvlen);
165    
166     do
167     {
168     if ( dwReturn != SCARD_S_SUCCESS )
169     {
170 vletoux 8 if (dwReturn == SCARD_W_RESET_CARD)
171     {
172     dwReturn = OCardReconnect(pCardData);
173     if (dwReturn)
174     {
175     __leave;
176     }
177     dwReturn = OCardGetData(pCardData,pbCmd, dwCmdSize,pbResponse, pdwResponseSize);
178     __leave;
179     }
180 vletoux 1 Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
181     __leave;
182     }
183     SW1 = recvbuf[recvlen-2];
184     SW2 = recvbuf[recvlen-1];
185     if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
186     {
187     dwDataSize = recvlen-2;
188     *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
189 vletoux 6 if (! *pbResponse)
190     {
191     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
192     dwReturn = SCARD_E_NO_MEMORY;
193     __leave;
194     }
195 vletoux 1 memcpy(*pbResponse, recvbuf, dwDataSize);
196     }
197     else if (SW1 == 0x61)
198     {
199     dwDataSize += SW2;
200     if (*pbResponse)
201     {
202     *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize);
203     }
204     else
205     {
206     *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
207     }
208     dwGetResponseSize = ARRAYSIZE(pbGetResponse);
209     dwReturn = SCardTransmit(pCardData->hScard,
210     SCARD_PCI_T1,
211     pbGetResponse,
212     dwGetResponseSize,
213     NULL,
214     recvbuf,
215     &recvlen);
216     }
217     else if ( (SW1 == 0x69) && (SW2 == 0x82) )
218     {
219     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
220     dwReturn = SCARD_W_WRONG_CHV;
221     __leave;
222     }
223     else if ( (SW1 == 0x69) && (SW2 == 0x83) )
224     {
225     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
226     dwReturn = SCARD_W_CHV_BLOCKED;
227     __leave;
228     }
229     else if ( (SW1 == 0x6A) && (SW2 == 0x88) )
230     {
231     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND");
232     dwReturn = SCARD_E_FILE_NOT_FOUND;
233     __leave;
234     }
235     else
236     {
237     TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
238     Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
239     dwReturn = SCARD_F_UNKNOWN_ERROR;
240     __leave;
241     }
242    
243     } while (SW1 == 0x61);
244     if (pdwResponseSize)
245     {
246     *pdwResponseSize = dwDataSize;
247     }
248     }
249     __finally
250     {
251     }
252     return dwReturn;
253     }
254    
255     DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength)
256     {
257     DWORD idx = 0;
258     int count;
259     while (idx < featuresLength) {
260     BYTE tag = features[idx];
261     idx++;
262     idx++;
263     if (featureTag == tag) {
264     DWORD feature = 0;
265     for (count = 0; count < 3; count++) {
266     feature |= features[idx] & 0xff;
267     idx++;
268     feature <<= 8;
269     }
270     feature |= features[idx] & 0xff;
271     return feature;
272     }
273     idx += 4;
274     }
275     return 0;
276     }
277    
278     DWORD CCIDgetFeatures(__in PCARD_DATA pCardData)
279     {
280     BYTE pbRecvBuffer[200];
281     DWORD dwRecvLength, dwReturn;
282     __try
283     {
284     POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
285    
286     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0;
287     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0;
288     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0;
289     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0;
290     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0;
291     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0;
292     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0;
293     pContext->SmartCardReaderFeatures.ABORT = 0;
294    
295     dwReturn = SCardControl(pCardData->hScard,
296     SCARD_CTL_CODE(3400),
297     NULL,
298     0,
299     pbRecvBuffer,
300     sizeof(pbRecvBuffer),
301     &dwRecvLength);
302     if ( dwReturn )
303     {
304     Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn);
305     __leave;
306     }
307     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength);
308     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
309     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
310     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength);
311     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
312     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
313     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength);
314     pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength);
315     }
316     __finally
317     {
318     }
319     return dwReturn;
320     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26