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

Contents of /trunk/OpenPGPminidriverTest/BaseCSP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26