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

Annotation of /trunk/OpenPGPminidriverTest/BaseCSP.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Feb 23 19:18:59 2010 UTC (15 years, 2 months ago) by vletoux
File size: 13561 byte(s)


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 <tchar.h>
20     #include <Cryptuiapi.h>
21     #include <commctrl.h>
22     #include "dialog.h"
23     #pragma comment(lib,"Cryptui")
24     #pragma comment(lib,"Crypt32")
25    
26     extern HWND hMainWnd;
27    
28     BOOL SchGetProviderNameFromCardName(__in LPCTSTR szCardName, __out LPTSTR szProviderName, __out PDWORD pdwProviderNameLen)
29     {
30     // get provider name
31     SCARDCONTEXT hSCardContext;
32     LONG lCardStatus;
33     lCardStatus = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSCardContext);
34     if (SCARD_S_SUCCESS != lCardStatus)
35     {
36     return FALSE;
37     }
38    
39     lCardStatus = SCardGetCardTypeProviderName(hSCardContext,
40     szCardName,
41     SCARD_PROVIDER_CSP,
42     szProviderName,
43     pdwProviderNameLen);
44     if (SCARD_S_SUCCESS != lCardStatus)
45     {
46     SCardReleaseContext(hSCardContext);
47     return FALSE;
48     }
49     SCardReleaseContext(hSCardContext);
50     return TRUE;
51     }
52    
53     DWORD ListContainer()
54     {
55     HCRYPTPROV HMainCryptProv = NULL;
56     BOOL bStatus = FALSE;
57     LPTSTR szMainContainerName = NULL;
58     CHAR szContainerName[1024];
59     DWORD dwContainerNameLen = sizeof(szContainerName);
60     DWORD dwErr = 0;
61     DWORD dwFlags = CRYPT_FIRST;
62     DWORD dwContextArrayLen = 0;
63     HCRYPTPROV hProv = NULL;
64     HCRYPTKEY hKey = NULL;
65     LPBYTE pbCert = NULL;
66     DWORD dwCertLen = 0;
67     PCCERT_CONTEXT pCertContext = NULL;
68     DWORD pKeySpecs[2] = { AT_KEYEXCHANGE,AT_SIGNATURE};
69     PCCERT_CONTEXT pSelectedContext = NULL;
70     HCERTSTORE hStore = NULL;
71     TCHAR szCardName[256];
72     TCHAR szReaderName[256];
73     TCHAR szOutProviderName[256];
74     DWORD dwOutProviderLength = ARRAYSIZE(szOutProviderName);
75     OPENCARDNAME_EX dlgStruct;
76     DWORD dwReturn;
77     SCARDCONTEXT hSCardContext = NULL;
78     SCARDHANDLE hSCardHandle = NULL;
79     __try
80     {
81    
82     SendMessage(GetDlgItem(hMainWnd, IDC_LSTCONTAINER),LB_RESETCONTENT,0,0);
83     dwReturn = SCardEstablishContext(SCARD_SCOPE_USER,
84     NULL,
85     NULL,
86     &hSCardContext );
87     if ( SCARD_S_SUCCESS != dwReturn )
88     {
89     __leave;
90     }
91     // Initialize the structure.
92     memset(&dlgStruct, 0, sizeof(dlgStruct));
93     dlgStruct.dwStructSize = sizeof(dlgStruct);
94     dlgStruct.hSCardContext = hSCardContext;
95     dlgStruct.dwFlags = SC_DLG_MINIMAL_UI;
96     dlgStruct.lpstrRdr = szReaderName;
97     dlgStruct.nMaxRdr = ARRAYSIZE(szReaderName);
98     dlgStruct.lpstrCard = szCardName;
99     dlgStruct.nMaxCard = ARRAYSIZE(szCardName);
100     dlgStruct.lpstrTitle = L"Select Card";
101     dlgStruct.dwShareMode = 0;
102     // Display the select card dialog box.
103     dwReturn = SCardUIDlgSelectCard(&dlgStruct);
104     if ( SCARD_S_SUCCESS != dwReturn )
105     {
106     __leave;
107     }
108     dwReturn = SCardUIDlgSelectCard(&dlgStruct);
109     if ( SCARD_S_SUCCESS != dwReturn )
110     {
111     __leave;
112     }
113     if (!SchGetProviderNameFromCardName(szCardName, szOutProviderName, &dwOutProviderLength))
114     {
115     dwReturn = GetLastError();
116     __leave;
117     }
118    
119     size_t ulNameLen = _tcslen(szReaderName);
120     szMainContainerName = (LPWSTR) LocalAlloc(0,(DWORD)(ulNameLen + 6) * sizeof(WCHAR));
121     if (!szMainContainerName)
122     {
123     dwReturn = GetLastError();
124     __leave;
125     }
126     swprintf_s(szMainContainerName,(ulNameLen + 6), L"\\\\.\\%s\\", szReaderName);
127    
128     bStatus = CryptAcquireContext(&HMainCryptProv,
129     szMainContainerName,
130     szOutProviderName,
131     PROV_RSA_FULL,
132     CRYPT_SILENT);
133     if (!bStatus)
134     {
135     dwReturn = GetLastError();
136     if (dwReturn == NTE_BAD_KEYSET)
137     {
138     bStatus = CryptAcquireContext(&HMainCryptProv,NULL, szOutProviderName, PROV_RSA_FULL, CRYPT_SILENT);
139     if (!bStatus)
140     {
141     dwReturn = GetLastError();
142     __leave;
143     }
144     }
145     else
146     {
147     __leave;
148     }
149    
150     }
151    
152    
153    
154     /* Enumerate all the containers */
155     while (CryptGetProvParam(HMainCryptProv,
156     PP_ENUMCONTAINERS,
157     (LPBYTE) szContainerName,
158     &dwContainerNameLen,
159     dwFlags) &&
160     (dwContextArrayLen < 128)
161     )
162     {
163    
164     // convert the container name to unicode
165     int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0);
166     LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0,wLen * sizeof(WCHAR));
167     MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen);
168    
169     // Acquire a context on the current container
170     if (CryptAcquireContext(&hProv,
171     szWideContainerName,
172     szOutProviderName,
173     PROV_RSA_FULL,
174     0))
175     {
176     // Loop over all the key specs
177     for (int i = 0; i < 2; i++)
178     {
179     if (CryptGetUserKey(hProv,
180     pKeySpecs[i],
181     &hKey) )
182     {
183     TCHAR szText[256];
184     _stprintf_s(szText, ARRAYSIZE(szText), TEXT("%s %d"),szWideContainerName,pKeySpecs[i]);
185     SendDlgItemMessage(hMainWnd,IDC_LSTCONTAINER,LB_ADDSTRING,0,(LPARAM)szText);
186     CryptDestroyKey(hKey);
187     hKey = NULL;
188     }
189     }
190     CryptReleaseContext(hProv, 0);
191     hProv = NULL;
192     }
193     LocalFree(szWideContainerName);
194    
195     // prepare parameters for the next loop
196     dwContainerNameLen = sizeof(szContainerName);
197     dwFlags = 0;
198     }
199     }
200     __finally
201     {
202     if (hKey)
203     CryptDestroyKey(hKey);
204     if (hProv)
205     CryptReleaseContext(hProv, 0);
206     if (szMainContainerName)
207     LocalFree(szMainContainerName);
208     if (HMainCryptProv)
209     CryptReleaseContext(HMainCryptProv, 0);
210     }
211     return dwReturn;
212     }
213    
214    
215     DWORD ViewCertificate(PTSTR szContainer, DWORD dwKeySpec)
216     {
217     BOOL bStatus;
218     DWORD dwReturn = 0;
219     HCRYPTPROV hProv = NULL;
220     HCRYPTKEY hKey = NULL;
221     DWORD dwCertLen = 0;
222     PBYTE pbCert = NULL;
223     PCCERT_CONTEXT pCertContext = NULL;
224     CRYPTUI_VIEWCERTIFICATE_STRUCT certViewInfo;
225     BOOL fPropertiesChanged = FALSE;
226     __try
227     {
228     bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, CRYPT_SILENT);
229     if (!bStatus)
230     {
231     dwReturn = GetLastError();
232     __leave;
233     }
234     bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
235     if (!bStatus)
236     {
237     dwReturn = GetLastError();
238     __leave;
239     }
240     bStatus = CryptGetKeyParam(hKey,
241     KP_CERTIFICATE,
242     NULL,
243     &dwCertLen,
244     0);
245     if (!bStatus)
246     {
247     dwReturn = GetLastError();
248     __leave;
249     }
250     pbCert = (LPBYTE) LocalAlloc(0,dwCertLen);
251     if (!pbCert)
252     {
253     dwReturn = GetLastError();
254     __leave;
255     }
256     bStatus = CryptGetKeyParam(hKey,
257     KP_CERTIFICATE,
258     pbCert,
259     &dwCertLen,
260     0);
261     if (!bStatus)
262     {
263     dwReturn = GetLastError();
264     __leave;
265     }
266     pCertContext = CertCreateCertificateContext(
267     X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
268     pbCert,
269     dwCertLen);
270     if (!pCertContext)
271     {
272     dwReturn = GetLastError();
273     __leave;
274     }
275    
276     certViewInfo.dwSize = sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
277     certViewInfo.hwndParent = hMainWnd;
278     certViewInfo.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_DISABLE_EXPORT | CRYPTUI_DISABLE_HTMLLINK;
279     certViewInfo.szTitle = TEXT("Info");
280     certViewInfo.pCertContext = pCertContext;
281     certViewInfo.cPurposes = 0;
282     certViewInfo.rgszPurposes = 0;
283     certViewInfo.pCryptProviderData = NULL;
284     certViewInfo.hWVTStateData = NULL;
285     certViewInfo.fpCryptProviderDataTrustedUsage = FALSE;
286     certViewInfo.idxSigner = 0;
287     certViewInfo.idxCert = 0;
288     certViewInfo.fCounterSigner = FALSE;
289     certViewInfo.idxCounterSigner = 0;
290     certViewInfo.cStores = 0;
291     certViewInfo.rghStores = NULL;
292     certViewInfo.cPropSheetPages = 0;
293     certViewInfo.rgPropSheetPages = NULL;
294     certViewInfo.nStartPage = 0;
295    
296     dwReturn = CryptUIDlgViewCertificate(&certViewInfo,&fPropertiesChanged);
297    
298     }
299     __finally
300     {
301     if (pCertContext)
302     CertFreeCertificateContext(pCertContext);
303     if (pbCert)
304     LocalFree(pbCert);
305     if (hKey)
306     CryptDestroyKey(hKey);
307     if (hProv)
308     CryptReleaseContext(hProv, 0);
309     }
310     return dwReturn;
311     }
312    
313     DWORD Sign(PTSTR szContainer, DWORD dwKeySpec)
314     {
315     BOOL bStatus;
316     DWORD dwReturn = 0;
317     HCRYPTPROV hProv = NULL;
318     HCRYPTKEY hKey = NULL;
319     HCRYPTHASH hHash = NULL;
320     PBYTE pbSignature = NULL;
321     DWORD dwSignatureSize = 0;
322     BYTE pbChallenge[20];
323     TCHAR szDescription[] = TEXT("Test");
324     __try
325     {
326     bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
327     if (!bStatus)
328     {
329     dwReturn = GetLastError();
330     __leave;
331     }
332     bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
333     if (!bStatus)
334     {
335     dwReturn = GetLastError();
336     __leave;
337     }
338     bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
339     if (!bStatus)
340     {
341     dwReturn = GetLastError();
342     __leave;
343     }
344     if (!CryptCreateHash(hProv,CALG_SHA,NULL,0,&hHash))
345     {
346     dwReturn = GetLastError();
347     __leave;
348     }
349     if (!CryptSetHashParam(hHash, HP_HASHVAL, pbChallenge, 0))
350     {
351     dwReturn = GetLastError();
352     __leave;
353     }
354     if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, NULL, &dwSignatureSize))
355     {
356     dwReturn = GetLastError();
357     __leave;
358     }
359     pbSignature = (PBYTE) LocalAlloc(0,dwSignatureSize);
360     if (!pbSignature)
361     {
362     dwReturn = GetLastError();
363     __leave;
364     }
365     if (!CryptSignHash(hHash,dwKeySpec, szDescription, 0, pbSignature, &dwSignatureSize))
366     {
367     dwReturn = GetLastError();
368     __leave;
369     }
370     if (!CryptVerifySignature(hHash, pbSignature, dwSignatureSize, hKey, szDescription, 0))
371     {
372     dwReturn = GetLastError();
373     }
374     }
375     __finally
376     {
377     if (pbSignature)
378     LocalFree(pbSignature);
379     if (hHash)
380     CryptDestroyHash(hHash);
381     if (hKey)
382     CryptDestroyKey(hKey);
383     if (hProv)
384     CryptReleaseContext(hProv, 0);
385     }
386     return dwReturn;
387     }
388    
389     DWORD Decrypt(PTSTR szContainer, DWORD dwKeySpec)
390     {
391     BOOL bStatus;
392     DWORD dwReturn = 0;
393     HCRYPTPROV hProv = NULL;
394     HCRYPTKEY hKey = NULL;
395     HCRYPTHASH hHash = NULL;
396     PBYTE pbCrypt = NULL;
397     DWORD dwCryptSize = 0, dwBufferSize;
398     BYTE pbChallenge[]=
399     {0x09,0x59,0x1B,0x38,0x56,0xBD,0x71,0xA2,0x38,0x70,0x4E,0xDC,0x47,0xB3,0x0B,0x19,0xB3,
400     0x33,0x65,0x79,0xF7,0x46,0x4C,0xBF,0x24,0x77,
401     0x7E,0x06,0x1D,0xA6,0x97,0x46,0x08,0x0C,0x95};
402     BYTE pbDecrypt[] =
403     {0x5D,0x29,0xB8,0xC2,0x27,0x26,0xAC,0x36,0x29,0x40,0xEF,0x38,0x65,0xD0,0x37,0x85,0x11,0x91
404     ,0x18,0x98,0x6A,0xDF,0xA4,0x5A,0xC2,0x66,0x4F,0x1E,0xF6,0xC5,0xE5,0xEE,0x85,0xC2,0x0A,0xA6,0xFF,0x69,0x6D,0xF1,0xF5,0xEA,0x83,0x49
405     ,0xB6,0x8E,0xE2,0xE8,0x2C,0x0B,0x38,0x9B,0x70,0x60,0xF8,0x1F,0xE1,0xCC,0xE5,0xA4,0xD9,0xF6,0x39,0x8D,0x94,0x6A,0x36,0xF0,0xA5,0x8B
406     ,0xF3,0x7F,0xC1,0xC8,0x53,0x42,0x70,0x33,0x6E,0x28,0xFC,0x5E,0xAC,0x7B,0xBC,0xB5,0x0D,0x93,0xD6,0xCC,0xF3,0x05,0x47,0xD8,0xAB,0x5E
407     ,0x43,0x8B,0x17,0x27,0x38,0x70,0xC9,0x0D,0xFC,0xF6,0x8F,0xEA,0x63,0xBB,0xF4,0x58,0xB1,0x8B,0x8D,0xC7,0x89,0x43,0x7A,0x69,0xEC,0x1E
408     ,0x9F,0x13,0xFC,0xC2,0x73,0xEA,0x04,0x0C,0x4E,0x1B,0x1B,0x55,0x51,0x14,0x20,0x90,0x60,0x30,0x73,0x11,0xE8,0x6F,0xF0,0x45,0xC0,0x49
409     ,0x1A,0x0B,0x9F,0x7C,0x30,0x5E,0xF9,0x69,0x2F,0x98,0x2C,0x53,0x06,0x02,0x93,0xAE,0xC8,0x12,0xEE,0x81,0xD4,0x9C,0xE6,0x16,0xB2,0x7D
410     ,0xF3,0x3E,0x9D,0xB5,0xDC,0x39,0x39,0x43,0xA1,0x37,0x81,0x06,0xC8,0x8D,0x40,0xB0,0x62,0x8F,0xE1,0x6C,0xB3,0xDE,0x08,0xC2,0x06,0xD5
411     ,0x8A,0x57,0xB5,0x3A,0x24,0x7A,0x75,0x97,0xDD,0x06,0x3B,0x16,0x4D,0xEE,0xC7,0x5E,0x88,0x49,0xF0,0x02,0x3C,0x99,0x93,0xE2,0x98,0xC5
412     ,0x8A,0x65,0x2F,0x85,0x99,0x25,0xC3,0x91,0x62,0x9E,0x39,0xB7,0xAB,0xB6,0x51,0x0C,0x74,0x98,0x5C,0x58,0x70,0x44,0xDE,0x79,0xF0,0xC5
413     ,0x04,0xAF,0x59,0xA5};
414     __try
415     {
416     bStatus = CryptAcquireContext(&hProv,szContainer, MS_SCARD_PROV, PROV_RSA_FULL, 0);
417     if (!bStatus)
418     {
419     dwReturn = GetLastError();
420     __leave;
421     }
422     bStatus = CryptGetUserKey(hProv, dwKeySpec, &hKey);
423     if (!bStatus)
424     {
425     dwReturn = GetLastError();
426     __leave;
427     }
428     //bStatus = CryptGenRandom(hProv,ARRAYSIZE(pbChallenge),pbChallenge);
429     if (!bStatus)
430     {
431     dwReturn = GetLastError();
432     __leave;
433     }
434     dwCryptSize = 0;
435     dwBufferSize = ARRAYSIZE(pbChallenge);
436     if (!CryptEncrypt(hKey,NULL, TRUE, 0, NULL, &dwBufferSize,0))
437     {
438     dwReturn = GetLastError();
439     __leave;
440     }
441     pbCrypt = (PBYTE) LocalAlloc(0,dwBufferSize);
442     if (!pbCrypt)
443     {
444     dwReturn = GetLastError();
445     __leave;
446     }
447     memcpy(pbCrypt, pbChallenge, ARRAYSIZE(pbChallenge));
448     dwCryptSize = ARRAYSIZE(pbChallenge);
449     if (!CryptEncrypt(hKey,NULL, FALSE, 0, pbCrypt, &dwCryptSize,dwBufferSize))
450     {
451     dwReturn = GetLastError();
452     __leave;
453     }
454     //if (!CryptDecrypt(hKey, NULL, FALSE, 0, pbCrypt, &dwCryptSize))
455     dwCryptSize = ARRAYSIZE(pbDecrypt);
456     if (!CryptDecrypt(hKey, NULL, FALSE, 0, pbDecrypt, &dwCryptSize))
457     {
458     dwReturn = GetLastError();
459     __leave;
460     }
461     if (dwCryptSize != ARRAYSIZE(pbChallenge))
462     {
463     dwReturn = NTE_BAD_DATA;
464     __leave;
465     }
466     if (memcmp(pbChallenge, pbCrypt, dwCryptSize) != 0)
467     {
468     dwReturn = NTE_BAD_DATA;
469     __leave;
470     }
471     }
472     __finally
473     {
474     if (pbCrypt)
475     LocalFree(pbCrypt);
476     if (hKey)
477     CryptDestroyKey(hKey);
478     if (hProv)
479     CryptReleaseContext(hProv, 0);
480     }
481     return dwReturn;
482     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26