/[openpgpmdrv]/trunk/OpenPGPminidriverTest/BaseCSP.cpp
ViewVC logotype

Contents of /trunk/OpenPGPminidriverTest/BaseCSP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Sun Feb 28 09:39:34 2010 UTC (15 years, 2 months ago) by vletoux
File size: 12079 byte(s)
decryption is now working !
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 <tchar.h>
20 #include <Cryptuiapi.h>
21 #include <commctrl.h>
22 #include <cardmod.h>
23 #include "dialog.h"
24 #include "global.h"
25 #pragma comment(lib,"Cryptui")
26 #pragma comment(lib,"Crypt32")
27
28 extern HWND hMainWnd;
29
30 BOOL SchGetProviderNameFromCardName(__in LPCTSTR szCardName, __out LPTSTR szProviderName, __out PDWORD pdwProviderNameLen)
31 {
32 // get provider name
33 SCARDCONTEXT hSCardContext;
34 LONG lCardStatus;
35 lCardStatus = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSCardContext);
36 if (SCARD_S_SUCCESS != lCardStatus)
37 {
38 return FALSE;
39 }
40
41 lCardStatus = SCardGetCardTypeProviderName(hSCardContext,
42 szCardName,
43 SCARD_PROVIDER_CSP,
44 szProviderName,
45 pdwProviderNameLen);
46 if (SCARD_S_SUCCESS != lCardStatus)
47 {
48 SCardReleaseContext(hSCardContext);
49 return FALSE;
50 }
51 SCardReleaseContext(hSCardContext);
52 return TRUE;
53 }
54
55 DWORD ListContainer()
56 {
57 HCRYPTPROV HMainCryptProv = NULL;
58 BOOL bStatus = FALSE;
59 LPTSTR szMainContainerName = NULL;
60 CHAR szContainerName[1024];
61 DWORD dwContainerNameLen = sizeof(szContainerName);
62 DWORD dwErr = 0;
63 DWORD dwFlags = CRYPT_FIRST;
64 DWORD dwContextArrayLen = 0;
65 HCRYPTPROV hProv = NULL;
66 HCRYPTKEY hKey = NULL;
67 LPBYTE pbCert = NULL;
68 DWORD dwCertLen = 0;
69 PCCERT_CONTEXT pCertContext = NULL;
70 DWORD pKeySpecs[2] = { AT_KEYEXCHANGE,AT_SIGNATURE};
71 PCCERT_CONTEXT pSelectedContext = NULL;
72 HCERTSTORE hStore = NULL;
73 TCHAR szCardName[256];
74 TCHAR szReaderName[256];
75 TCHAR szOutProviderName[256];
76 DWORD dwOutProviderLength = ARRAYSIZE(szOutProviderName);
77 OPENCARDNAME_EX dlgStruct;
78 DWORD dwReturn;
79 SCARDCONTEXT hSCardContext = NULL;
80 SCARDHANDLE hSCardHandle = NULL;
81 __try
82 {
83
84 SendMessage(GetDlgItem(hMainWnd, IDC_LSTCONTAINER),LB_RESETCONTENT,0,0);
85 dwReturn = SCardEstablishContext(SCARD_SCOPE_USER,
86 NULL,
87 NULL,
88 &hSCardContext );
89 if ( SCARD_S_SUCCESS != dwReturn )
90 {
91 __leave;
92 }
93 // Initialize the structure.
94 memset(&dlgStruct, 0, sizeof(dlgStruct));
95 dlgStruct.dwStructSize = sizeof(dlgStruct);
96 dlgStruct.hSCardContext = hSCardContext;
97 dlgStruct.dwFlags = SC_DLG_MINIMAL_UI;
98 dlgStruct.lpstrRdr = szReaderName;
99 dlgStruct.nMaxRdr = ARRAYSIZE(szReaderName);
100 dlgStruct.lpstrCard = szCardName;
101 dlgStruct.nMaxCard = ARRAYSIZE(szCardName);
102 dlgStruct.lpstrTitle = L"Select Card";
103 dlgStruct.dwShareMode = 0;
104 // Display the select card dialog box.
105 dwReturn = SCardUIDlgSelectCard(&dlgStruct);
106 if ( SCARD_S_SUCCESS != dwReturn )
107 {
108 __leave;
109 }
110 dwReturn = SCardUIDlgSelectCard(&dlgStruct);
111 if ( SCARD_S_SUCCESS != dwReturn )
112 {
113 __leave;
114 }
115 if (!SchGetProviderNameFromCardName(szCardName, szOutProviderName, &dwOutProviderLength))
116 {
117 dwReturn = GetLastError();
118 __leave;
119 }
120
121 size_t ulNameLen = _tcslen(szReaderName);
122 szMainContainerName = (LPWSTR) LocalAlloc(0,(DWORD)(ulNameLen + 6) * sizeof(WCHAR));
123 if (!szMainContainerName)
124 {
125 dwReturn = GetLastError();
126 __leave;
127 }
128 swprintf_s(szMainContainerName,(ulNameLen + 6), L"\\\\.\\%s\\", szReaderName);
129
130 bStatus = CryptAcquireContext(&HMainCryptProv,
131 szMainContainerName,
132 szOutProviderName,
133 PROV_RSA_FULL,
134 CRYPT_SILENT);
135 if (!bStatus)
136 {
137 dwReturn = GetLastError();
138 if (dwReturn == NTE_BAD_KEYSET)
139 {
140 bStatus = CryptAcquireContext(&HMainCryptProv,NULL, szOutProviderName, PROV_RSA_FULL, CRYPT_SILENT);
141 if (!bStatus)
142 {
143 dwReturn = GetLastError();
144 __leave;
145 }
146 }
147 else
148 {
149 __leave;
150 }
151
152 }
153
154
155
156 /* Enumerate all the containers */
157 while (CryptGetProvParam(HMainCryptProv,
158 PP_ENUMCONTAINERS,
159 (LPBYTE) szContainerName,
160 &dwContainerNameLen,
161 dwFlags) &&
162 (dwContextArrayLen < 128)
163 )
164 {
165
166 // convert the container name to unicode
167 int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0);
168 LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0,wLen * sizeof(WCHAR));
169 MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen);
170
171 // Acquire a context on the current container
172 if (CryptAcquireContext(&hProv,
173 szWideContainerName,
174 szOutProviderName,
175 PROV_RSA_FULL,
176 0))
177 {
178 // Loop over all the key specs
179 for (int i = 0; i < 2; i++)
180 {
181 if (CryptGetUserKey(hProv,
182 pKeySpecs[i],
183 &hKey) )
184 {
185 TCHAR szText[256];
186 _stprintf_s(szText, ARRAYSIZE(szText), TEXT("%s %d"),szWideContainerName,pKeySpecs[i]);
187 SendDlgItemMessage(hMainWnd,IDC_LSTCONTAINER,LB_ADDSTRING,0,(LPARAM)szText);
188 CryptDestroyKey(hKey);
189 hKey = NULL;
190 }
191 }
192 CryptReleaseContext(hProv, 0);
193 hProv = NULL;
194 }
195 LocalFree(szWideContainerName);
196
197 // prepare parameters for the next loop
198 dwContainerNameLen = sizeof(szContainerName);
199 dwFlags = 0;
200 }
201 }
202 __finally
203 {
204 if (hKey)
205 CryptDestroyKey(hKey);
206 if (hProv)
207 CryptReleaseContext(hProv, 0);
208 if (szMainContainerName)
209 LocalFree(szMainContainerName);
210 if (HMainCryptProv)
211 CryptReleaseContext(HMainCryptProv, 0);
212 }
213 return dwReturn;
214 }
215
216
217 DWORD ViewCertificate(PTSTR szContainer, DWORD dwKeySpec)
218 {
219 BOOL bStatus;
220 DWORD dwReturn = 0;
221 HCRYPTPROV hProv = NULL;
222 HCRYPTKEY hKey = NULL;
223 DWORD dwCertLen = 0;
224 PBYTE pbCert = NULL;
225 PCCERT_CONTEXT pCertContext = NULL;
226 CRYPTUI_VIEWCERTIFICATE_STRUCT certViewInfo;
227 BOOL fPropertiesChanged = FALSE;
228 __try
229 {
230 bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, CRYPT_SILENT);
231 if (!bStatus)
232 {
233 dwReturn = GetLastError();
234 __leave;
235 }
236 bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
237 if (!bStatus)
238 {
239 dwReturn = GetLastError();
240 __leave;
241 }
242 bStatus = CryptGetKeyParam(hKey,
243 KP_CERTIFICATE,
244 NULL,
245 &dwCertLen,
246 0);
247 if (!bStatus)
248 {
249 dwReturn = GetLastError();
250 __leave;
251 }
252 pbCert = (LPBYTE) LocalAlloc(0,dwCertLen);
253 if (!pbCert)
254 {
255 dwReturn = GetLastError();
256 __leave;
257 }
258 bStatus = CryptGetKeyParam(hKey,
259 KP_CERTIFICATE,
260 pbCert,
261 &dwCertLen,
262 0);
263 if (!bStatus)
264 {
265 dwReturn = GetLastError();
266 __leave;
267 }
268 pCertContext = CertCreateCertificateContext(
269 X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
270 pbCert,
271 dwCertLen);
272 if (!pCertContext)
273 {
274 dwReturn = GetLastError();
275 __leave;
276 }
277
278 certViewInfo.dwSize = sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
279 certViewInfo.hwndParent = hMainWnd;
280 certViewInfo.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_DISABLE_EXPORT | CRYPTUI_DISABLE_HTMLLINK;
281 certViewInfo.szTitle = TEXT("Info");
282 certViewInfo.pCertContext = pCertContext;
283 certViewInfo.cPurposes = 0;
284 certViewInfo.rgszPurposes = 0;
285 certViewInfo.pCryptProviderData = NULL;
286 certViewInfo.hWVTStateData = NULL;
287 certViewInfo.fpCryptProviderDataTrustedUsage = FALSE;
288 certViewInfo.idxSigner = 0;
289 certViewInfo.idxCert = 0;
290 certViewInfo.fCounterSigner = FALSE;
291 certViewInfo.idxCounterSigner = 0;
292 certViewInfo.cStores = 0;
293 certViewInfo.rghStores = NULL;
294 certViewInfo.cPropSheetPages = 0;
295 certViewInfo.rgPropSheetPages = NULL;
296 certViewInfo.nStartPage = 0;
297
298 dwReturn = CryptUIDlgViewCertificate(&certViewInfo,&fPropertiesChanged);
299
300 }
301 __finally
302 {
303 if (pCertContext)
304 CertFreeCertificateContext(pCertContext);
305 if (pbCert)
306 LocalFree(pbCert);
307 if (hKey)
308 CryptDestroyKey(hKey);
309 if (hProv)
310 CryptReleaseContext(hProv, 0);
311 }
312 return dwReturn;
313 }
314
315 DWORD Sign(PTSTR szContainer, DWORD dwKeySpec)
316 {
317 BOOL bStatus;
318 DWORD dwReturn = 0;
319 HCRYPTPROV hProv = NULL;
320 HCRYPTKEY hKey = NULL;
321 HCRYPTHASH hHash = NULL;
322 PBYTE pbSignature = NULL;
323 DWORD dwSignatureSize = 0;
324 PBYTE pbSignatureTest = NULL;
325 DWORD dwSignatureTestSize = 0;
326 BYTE pbChallenge[20];
327 TCHAR szDescription[] = TEXT("Test");
328 TCHAR szContainerName[] = OPENPGP_TEST_CONTAINER;
329 __try
330 {
331 bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
332 if (!bStatus)
333 {
334 dwReturn = GetLastError();
335 __leave;
336 }
337 bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
338 if (!bStatus)
339 {
340 dwReturn = GetLastError();
341 __leave;
342 }
343 bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
344 if (!bStatus)
345 {
346 dwReturn = GetLastError();
347 __leave;
348 }
349 if (!CryptCreateHash(hProv,CALG_SHA,NULL,0,&hHash))
350 {
351 dwReturn = GetLastError();
352 __leave;
353 }
354 if (!CryptSetHashParam(hHash, HP_HASHVAL, pbChallenge, 0))
355 {
356 dwReturn = GetLastError();
357 __leave;
358 }
359 if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, NULL, &dwSignatureSize))
360 {
361 dwReturn = GetLastError();
362 __leave;
363 }
364 pbSignature = (PBYTE) LocalAlloc(0,dwSignatureSize);
365 if (!pbSignature)
366 {
367 dwReturn = GetLastError();
368 __leave;
369 }
370 if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, pbSignature, &dwSignatureSize))
371 {
372 dwReturn = GetLastError();
373 __leave;
374 }
375 if (!CryptVerifySignature(hHash, pbSignature, dwSignatureSize, hKey, szDescription, 0))
376 {
377 dwReturn = GetLastError();
378 }
379 }
380 __finally
381 {
382 if (pbSignature)
383 LocalFree(pbSignature);
384 if (hHash)
385 CryptDestroyHash(hHash);
386 if (hProv)
387 CryptReleaseContext(hProv, 0);
388 }
389 return dwReturn;
390 }
391
392 DWORD Decrypt(PTSTR szContainer, DWORD dwKeySpec)
393 {
394 BOOL bStatus;
395 DWORD dwReturn = 0;
396 HCRYPTPROV hProv = NULL;
397 HCRYPTKEY hKey = NULL;
398 HCRYPTHASH hHash = NULL;
399 PBYTE pbCrypt = NULL;
400 DWORD dwCryptSize = 0, dwBufferSize;
401 BYTE pbChallenge[20] = "test1234567890";
402 __try
403 {
404 bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
405 if (!bStatus)
406 {
407 dwReturn = GetLastError();
408 __leave;
409 }
410 bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
411 if (!bStatus)
412 {
413 dwReturn = GetLastError();
414 __leave;
415 }
416 /*bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
417 if (!bStatus)
418 {
419 dwReturn = GetLastError();
420 __leave;
421 }*/
422 dwCryptSize = 0;
423 dwBufferSize = ARRAYSIZE(pbChallenge);
424 if (!CryptEncrypt(hKey,NULL, TRUE, 0, NULL, &dwBufferSize,0))
425 {
426 dwReturn = GetLastError();
427 __leave;
428 }
429 pbCrypt = (PBYTE) LocalAlloc(0,dwBufferSize);
430 if (!pbCrypt)
431 {
432 dwReturn = GetLastError();
433 __leave;
434 }
435 memcpy(pbCrypt, pbChallenge, ARRAYSIZE(pbChallenge));
436 dwCryptSize = ARRAYSIZE(pbChallenge);
437 if (!CryptEncrypt(hKey,NULL, TRUE, 0, pbCrypt, &dwCryptSize,dwBufferSize))
438 {
439 dwReturn = GetLastError();
440 __leave;
441 }
442 if (!CryptDecrypt(hKey, NULL, FALSE, 0, pbCrypt, &dwCryptSize))
443 {
444 dwReturn = GetLastError();
445 __leave;
446 }
447 if (dwCryptSize != ARRAYSIZE(pbChallenge))
448 {
449 dwReturn = NTE_BAD_DATA;
450 __leave;
451 }
452 if (memcmp(pbChallenge, pbCrypt, dwCryptSize) != 0)
453 {
454 dwReturn = NTE_BAD_DATA;
455 __leave;
456 }
457 }
458 __finally
459 {
460 if (pbCrypt)
461 LocalFree(pbCrypt);
462 if (hKey)
463 CryptDestroyKey(hKey);
464 if (hProv)
465 CryptReleaseContext(hProv, 0);
466 }
467 return dwReturn;
468 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26