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

Contents of /trunk/OpenPGPminidriver/SmartCard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show 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 /* 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