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

Annotation of /trunk/OpenPGPminidriverTest/Personnalize.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Wed Mar 31 08:58:46 2010 UTC (15 years, 1 month ago) by vletoux
File size: 10417 byte(s)
first msi Release
1 vletoux 12 /* 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 <cardmod.h>
21     #include "global.h"
22    
23    
24    
25     LPBYTE AllocateAndEncodeObject(LPVOID pvStruct, LPCSTR lpszStructType, LPDWORD pdwSize )
26     {
27     // Get Key Usage blob size
28     LPBYTE pbEncodedObject = NULL;
29     BOOL bResult = TRUE;
30     DWORD dwError;
31     __try
32     {
33     *pdwSize = 0;
34     bResult = CryptEncodeObject(X509_ASN_ENCODING,
35     lpszStructType,
36     pvStruct,
37     NULL, pdwSize);
38     if (!bResult)
39     {
40     dwError = GetLastError();
41     __leave;
42     }
43    
44     // Allocate Memory for Key Usage Blob
45     pbEncodedObject = (LPBYTE)LocalAlloc(0,*pdwSize);
46     if (!pbEncodedObject)
47     {
48     bResult = FALSE;
49     dwError = GetLastError();
50     __leave;
51     }
52    
53     // Get Key Usage Extension blob
54     bResult = CryptEncodeObject(X509_ASN_ENCODING,
55     lpszStructType,
56     pvStruct,
57     pbEncodedObject, pdwSize);
58     if (!bResult)
59     {
60     dwError = GetLastError();
61     __leave;
62     }
63     }
64     __finally
65     {
66     if (pbEncodedObject && !bResult)
67     {
68     LocalFree(pbEncodedObject);
69     }
70     }
71     return pbEncodedObject;
72     }
73    
74     DWORD Personnalize()
75     {
76     DWORD dwReturn;
77     BOOL fSet;
78     HCRYPTPROV hProv = NULL;
79     HCRYPTKEY hKey = NULL;
80     TCHAR szContainerName[] = OPENPGP_TEST_CONTAINER;
81     BYTE pbData[4096];
82     DWORD dwDataSize = ARRAYSIZE(pbData);
83     BOOL bStatus;
84     BYTE One = 1;
85     CERT_NAME_BLOB SubjectIssuerBlob = {0};
86     CERT_INFO CertInfo = {0};
87     CertInfo.rgExtension = 0;
88     CRYPT_BIT_BLOB KeyUsage;
89     BYTE ByteData;
90     LPBYTE pbKeyUsage = NULL;
91     DWORD dwSize;
92     CERT_BASIC_CONSTRAINTS2_INFO BasicConstraints;
93     LPBYTE pbBasicConstraints = NULL;
94     CERT_ENHKEY_USAGE CertEnhKeyUsage = { 0, NULL };
95     LPBYTE pbEnhKeyUsage = NULL;
96     CERT_EXTENSIONS CertExtensions = {0} ;
97     PCCERT_CONTEXT pNewCertificateContext = NULL;
98     SYSTEMTIME StartTime;
99     SYSTEMTIME EndTime;
100     HCERTSTORE hCertStore = NULL;
101     BYTE pbCertificateBlob[4096];
102     CERT_BLOB dbStore = {ARRAYSIZE(pbCertificateBlob),pbCertificateBlob};
103     __try
104     {
105     if (!pCardData)
106     {
107     dwReturn = SCARD_E_COMM_DATA_LOST;
108     __leave;
109     }
110     fSet = FALSE;
111     dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0);
112     if (dwReturn) __leave;
113     dwReturn = pCardData->pfnCardWriteFile(pCardData, "openpgp", "statusP1", 0, &One, 1);
114     if (dwReturn) __leave;
115     dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 0,
116     CARD_CREATE_CONTAINER_KEY_GEN,
117     AT_SIGNATURE, 1024, NULL, 1);
118     if (dwReturn) __leave;
119     bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, 0);
120     if (!bStatus)
121     {
122     dwReturn = GetLastError();
123     if (dwReturn == NTE_BAD_KEYSET)
124     {
125     bStatus = CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET);
126     }
127     if (!bStatus)
128     {
129     dwReturn = GetLastError();
130     __leave;
131     }
132     }
133     // WARNING : AT_SIGNATURE is used implicitely when creating a new certificate
134     // if you use AT_KEYEXCHANGE, the public key of the container
135     // won't match the public key of the certificate
136     bStatus = CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey);
137     if (!bStatus)
138     {
139     dwReturn = GetLastError();
140     __leave;
141     }
142     bStatus = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbData, &dwDataSize);
143     if (!bStatus)
144     {
145     dwReturn = GetLastError();
146     __leave;
147     }
148     dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 1,
149     CARD_CREATE_CONTAINER_KEY_IMPORT,
150     AT_KEYEXCHANGE, 1024, pbData, 3);
151     if (dwReturn)
152     {
153     __leave;
154     }
155     dwReturn = pCardData->pfnCardCreateContainerEx(pCardData, (BYTE) 2,
156     CARD_CREATE_CONTAINER_KEY_IMPORT,
157     AT_SIGNATURE, 1024, pbData, 3);
158     if (dwReturn)
159     {
160     __leave;
161     }
162     // create the cert data
163     if (!CertStrToName(X509_ASN_ENCODING,TEXT("CN=test"),CERT_X500_NAME_STR,NULL,NULL,&SubjectIssuerBlob.cbData,NULL))
164     {
165     dwReturn = GetLastError();
166     __leave;
167     }
168     SubjectIssuerBlob.pbData = (PBYTE) LocalAlloc(0,SubjectIssuerBlob.cbData);
169     if (!SubjectIssuerBlob.pbData)
170     {
171     dwReturn = GetLastError();
172     __leave;
173     }
174     if (!CertStrToName(X509_ASN_ENCODING,TEXT("CN=test"),CERT_X500_NAME_STR,NULL,(PBYTE)SubjectIssuerBlob.pbData,&SubjectIssuerBlob.cbData,NULL))
175     {
176     dwReturn = GetLastError();
177     __leave;
178     }
179     // max 10 extensions => we don't count them
180     CertInfo.rgExtension = (PCERT_EXTENSION) LocalAlloc(0,sizeof(CERT_EXTENSION) * 10);
181     CertInfo.cExtension = 0;
182     if (!CertInfo.rgExtension) __leave;
183    
184    
185     // Set Key Usage according to Public Key Type
186     ZeroMemory(&KeyUsage, sizeof(KeyUsage));
187     KeyUsage.cbData = 1;
188     KeyUsage.pbData = &ByteData;
189     ByteData = CERT_DIGITAL_SIGNATURE_KEY_USAGE |
190     CERT_DATA_ENCIPHERMENT_KEY_USAGE|
191     CERT_KEY_ENCIPHERMENT_KEY_USAGE |
192     CERT_KEY_AGREEMENT_KEY_USAGE;
193     pbKeyUsage = AllocateAndEncodeObject(&KeyUsage,X509_KEY_USAGE,&dwSize);
194     if (!pbKeyUsage) __leave;
195    
196     CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_KEY_USAGE;
197     CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE;
198     CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize;
199     CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbKeyUsage;
200     // Increase extension count
201     CertInfo.cExtension++;
202     //////////////////////////////////////////////////
203    
204     // Zero Basic Constraints structure
205     ZeroMemory(&BasicConstraints, sizeof(BasicConstraints));
206    
207     BasicConstraints.fCA = TRUE;
208     BasicConstraints.fPathLenConstraint = TRUE;
209     BasicConstraints.dwPathLenConstraint = 1;
210     pbBasicConstraints = AllocateAndEncodeObject(&BasicConstraints,X509_BASIC_CONSTRAINTS2,&dwSize);
211     if (!pbBasicConstraints) __leave;
212    
213     // Set Basic Constraints extension
214     CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_BASIC_CONSTRAINTS2;
215     CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE;
216     CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize;
217     CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbBasicConstraints;
218     // Increase extension count
219     CertInfo.cExtension++;
220     //////////////////////////////////////////////////
221     CertEnhKeyUsage.cUsageIdentifier+=4;
222    
223     CertEnhKeyUsage.rgpszUsageIdentifier = (LPSTR*) LocalAlloc(0,sizeof(LPSTR)*CertEnhKeyUsage.cUsageIdentifier);
224     if (!CertEnhKeyUsage.rgpszUsageIdentifier) __leave;
225     CertEnhKeyUsage.cUsageIdentifier = 0;
226     CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_PKIX_KP_CLIENT_AUTH;
227     CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_PKIX_KP_SERVER_AUTH;
228     CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_KP_SMARTCARD_LOGON;
229     CertEnhKeyUsage.rgpszUsageIdentifier[CertEnhKeyUsage.cUsageIdentifier++] = szOID_KP_EFS;
230     pbEnhKeyUsage = AllocateAndEncodeObject(&CertEnhKeyUsage,X509_ENHANCED_KEY_USAGE,&dwSize);
231     if (!pbEnhKeyUsage) __leave;
232    
233     // Set Basic Constraints extension
234     CertInfo.rgExtension[CertInfo.cExtension].pszObjId = szOID_ENHANCED_KEY_USAGE;
235     CertInfo.rgExtension[CertInfo.cExtension].fCritical = FALSE;
236     CertInfo.rgExtension[CertInfo.cExtension].Value.cbData = dwSize;
237     CertInfo.rgExtension[CertInfo.cExtension].Value.pbData = pbEnhKeyUsage;
238     // Increase extension count
239     CertInfo.cExtension++;
240    
241     //////////////////////////////////////////////////
242    
243     CertExtensions.cExtension = CertInfo.cExtension;
244     CertExtensions.rgExtension = CertInfo.rgExtension;
245    
246     GetSystemTime(&StartTime);
247     GetSystemTime(&EndTime);
248     EndTime.wYear += 10;
249     pNewCertificateContext = CertCreateSelfSignCertificate(hProv,&SubjectIssuerBlob,
250     0,NULL,NULL,&StartTime,&EndTime,&CertExtensions);
251     if (!pNewCertificateContext)
252     {
253     dwReturn = GetLastError();
254     __leave;
255     }
256     /*hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY,0,(HCRYPTPROV)NULL,0,NULL);
257     if (!hCertStore)
258     {
259     dwReturn = GetLastError();
260     __leave;
261     }
262     if( !CertAddCertificateContextToStore(hCertStore, // Store handle
263     pNewCertificateContext, // Pointer to a certificate
264     CERT_STORE_ADD_REPLACE_EXISTING, NULL) )
265     {
266     dwReturn = GetLastError();
267     __leave;
268     }
269     if (!CertSaveStore( hCertStore,
270     PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
271     CERT_STORE_SAVE_AS_PKCS7,
272     CERT_STORE_SAVE_TO_MEMORY,
273     &dbStore,
274     0))
275     {
276     dwReturn = GetLastError();
277     __leave;
278     }
279     dwReturn = pCardData->pfnCardWriteFile(pCardData, szBASE_CSP_DIR, "kxc01", 0,
280     dbStore.pbData,
281     dbStore.cbData);
282     if (dwReturn)
283     {
284     __leave;
285     }*/
286     dwReturn = pCardData->pfnCardWriteFile(pCardData, szBASE_CSP_DIR, "kxc01", 0,
287     pNewCertificateContext->pbCertEncoded,
288     pNewCertificateContext->cbCertEncoded);
289     if (dwReturn)
290     {
291     __leave;
292     }
293     ViewCertificate(NULL, pNewCertificateContext);
294     fSet = TRUE;
295     dwReturn = pCardData->pfnCardSetProperty(pCardData, CP_CARD_READ_ONLY, (PBYTE) &fSet, sizeof(BOOL),0);
296     if (dwReturn) __leave;
297    
298     }
299     __finally
300     {
301     if (hKey)
302     CryptDestroyKey(hKey);
303     //CryptAcquireContext(&hProv, szContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
304     if (hProv)
305     CryptReleaseContext(hProv,0);
306     }
307     return dwReturn;
308     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26