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

Contents of /trunk/OpenPGPminidriverTest/Personnalize.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: 10417 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 <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