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

Annotation of /trunk/OpenPGPminidriver/SmartCard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide annotations)
Thu Mar 4 21:17:51 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 7700 byte(s)
Everything is working except the certificate
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 vletoux 6 if (! *pbResponse)
142     {
143     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
144     dwReturn = SCARD_E_NO_MEMORY;
145     __leave;
146     }
147 vletoux 1 memcpy(*pbResponse, recvbuf, dwDataSize);
148     }
149     else if (SW1 == 0x61)
150     {
151     dwDataSize += SW2;
152     if (*pbResponse)
153     {
154     *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize);
155     }
156     else
157     {
158     *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
159     }
160     dwGetResponseSize = ARRAYSIZE(pbGetResponse);
161     dwReturn = SCardTransmit(pCardData->hScard,
162     SCARD_PCI_T1,
163     pbGetResponse,
164     dwGetResponseSize,
165     NULL,
166     recvbuf,
167     &recvlen);
168     }
169     else if ( (SW1 == 0x69) && (SW2 == 0x82) )
170     {
171     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
172     dwReturn = SCARD_W_WRONG_CHV;
173     __leave;
174     }
175     else if ( (SW1 == 0x69) && (SW2 == 0x83) )
176     {
177     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
178     dwReturn = SCARD_W_CHV_BLOCKED;
179     __leave;
180     }
181     else if ( (SW1 == 0x6A) && (SW2 == 0x88) )
182     {
183     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND");
184     dwReturn = SCARD_E_FILE_NOT_FOUND;
185     __leave;
186     }
187     else
188     {
189     TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
190     Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
191     dwReturn = SCARD_F_UNKNOWN_ERROR;
192     __leave;
193     }
194    
195     } while (SW1 == 0x61);
196     if (pdwResponseSize)
197     {
198     *pdwResponseSize = dwDataSize;
199     }
200     }
201     __finally
202     {
203     }
204     return dwReturn;
205     }
206    
207     DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength)
208     {
209     DWORD idx = 0;
210     int count;
211     while (idx < featuresLength) {
212     BYTE tag = features[idx];
213     idx++;
214     idx++;
215     if (featureTag == tag) {
216     DWORD feature = 0;
217     for (count = 0; count < 3; count++) {
218     feature |= features[idx] & 0xff;
219     idx++;
220     feature <<= 8;
221     }
222     feature |= features[idx] & 0xff;
223     return feature;
224     }
225     idx += 4;
226     }
227     return 0;
228     }
229    
230     DWORD CCIDgetFeatures(__in PCARD_DATA pCardData)
231     {
232     BYTE pbRecvBuffer[200];
233     DWORD dwRecvLength, dwReturn;
234     __try
235     {
236     POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
237    
238     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0;
239     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0;
240     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0;
241     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0;
242     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0;
243     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0;
244     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0;
245     pContext->SmartCardReaderFeatures.ABORT = 0;
246    
247     dwReturn = SCardControl(pCardData->hScard,
248     SCARD_CTL_CODE(3400),
249     NULL,
250     0,
251     pbRecvBuffer,
252     sizeof(pbRecvBuffer),
253     &dwRecvLength);
254     if ( dwReturn )
255     {
256     Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn);
257     __leave;
258     }
259     pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength);
260     pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
261     pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
262     pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength);
263     pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
264     pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
265     pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength);
266     pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength);
267     }
268     __finally
269     {
270     }
271     return dwReturn;
272     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26