source: trunk/src/crypt32/rootstore.c@ 21354

Last change on this file since 21354 was 21354, checked in by rlwalsh, 16 years ago

eliminate VACPP warning & info msgs - see Ticket #1

File size: 34.3 KB
Line 
1/*
2 * Copyright 2007 Juan Lang
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 as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <os2win.h>
20#include <odinwrap.h>
21#include "config.h"
22#include <stdlib.h>
23#include <stdarg.h>
24#include <stdio.h>
25#include <string.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#ifdef HAVE_DIRENT_H
29#include <dirent.h>
30#endif
31#include <fcntl.h>
32#if __IBMC__ || __IBMCPP__
33#include <io.h>
34#endif
35#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
38#include <errno.h>
39#include <limits.h>
40#include "ntstatus.h"
41#define WIN32_NO_STATUS
42#include "windef.h"
43#include "winbase.h"
44#include "winreg.h"
45#include "wincrypt.h"
46#include "winternl.h"
47#include "wine/debug.h"
48#include "crypt32_private.h"
49
50WINE_DEFAULT_DEBUG_CHANNEL(crypt);
51
52#define INITIAL_CERT_BUFFER 1024
53
54struct DynamicBuffer
55{
56 DWORD allocated;
57 DWORD used;
58 BYTE *data;
59};
60
61static inline void reset_buffer(struct DynamicBuffer *buffer)
62{
63 buffer->used = 0;
64 if (buffer->data) buffer->data[0] = 0;
65}
66
67static BOOL add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line)
68{
69 BOOL ret;
70
71 if (buffer->used + strlen(line) + 1 > buffer->allocated)
72 {
73 if (!buffer->allocated)
74 {
75 buffer->data = CryptMemAlloc(INITIAL_CERT_BUFFER);
76 if (buffer->data)
77 {
78 buffer->data[0] = 0;
79 buffer->allocated = INITIAL_CERT_BUFFER;
80 }
81 }
82 else
83 {
84 DWORD new_size = max(buffer->allocated * 2,
85 buffer->used + strlen(line) + 1);
86
87 buffer->data = CryptMemRealloc(buffer->data, new_size);
88 if (buffer->data)
89 buffer->allocated = new_size;
90 }
91 }
92 if (buffer->data)
93 {
94 strcpy((char *)buffer->data + strlen((char *)buffer->data), line);
95 /* Not strlen + 1, otherwise we'd count the NULL for every line's
96 * addition (but we overwrite the previous NULL character.) Not an
97 * overrun, we allocate strlen + 1 bytes above.
98 */
99 buffer->used += strlen(line);
100 ret = TRUE;
101 }
102 else
103 ret = FALSE;
104 return ret;
105}
106
107/* Reads any base64-encoded certificates present in fp and adds them to store.
108 * Returns TRUE if any certificates were successfully imported.
109 */
110static BOOL import_base64_certs_from_fp(FILE *fp, HCERTSTORE store)
111{
112 char line[1024];
113 BOOL in_cert = FALSE;
114 struct DynamicBuffer saved_cert = { 0, 0, NULL };
115 int num_certs = 0;
116
117 TRACE("\n");
118 while (fgets(line, sizeof(line), fp))
119 {
120 static const char header[] = "-----BEGIN CERTIFICATE-----";
121 static const char trailer[] = "-----END CERTIFICATE-----";
122
123 if (!strncmp(line, header, strlen(header)))
124 {
125 TRACE("begin new certificate\n");
126 in_cert = TRUE;
127 reset_buffer(&saved_cert);
128 }
129 else if (!strncmp(line, trailer, strlen(trailer)))
130 {
131 DWORD size;
132
133 TRACE("end of certificate, adding cert\n");
134 in_cert = FALSE;
135 if (CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used,
136 CRYPT_STRING_BASE64, NULL, &size, NULL, NULL))
137 {
138 LPBYTE buf = CryptMemAlloc(size);
139
140 if (buf)
141 {
142 CryptStringToBinaryA((char *)saved_cert.data,
143 saved_cert.used, CRYPT_STRING_BASE64, buf, &size, NULL,
144 NULL);
145 if (CertAddEncodedCertificateToStore(store,
146 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_NEW, NULL))
147 num_certs++;
148 CryptMemFree(buf);
149 }
150 }
151 }
152 else if (in_cert)
153 add_line_to_buffer(&saved_cert, line);
154 }
155 CryptMemFree(saved_cert.data);
156 TRACE("Read %d certs\n", num_certs);
157 return num_certs > 0;
158}
159
160static const char *trust_status_to_str(DWORD status)
161{
162 static char buf[1024];
163 int pos = 0;
164
165 if (status & CERT_TRUST_IS_NOT_TIME_VALID)
166 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\texpired");
167 if (status & CERT_TRUST_IS_NOT_TIME_NESTED)
168 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad time nesting");
169 if (status & CERT_TRUST_IS_REVOKED)
170 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\trevoked");
171 if (status & CERT_TRUST_IS_NOT_SIGNATURE_VALID)
172 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad signature");
173 if (status & CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
174 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad usage");
175 if (status & CERT_TRUST_IS_UNTRUSTED_ROOT)
176 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tuntrusted root");
177 if (status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
178 pos += snprintf(buf + pos, sizeof(buf) - pos,
179 "\n\tunknown revocation status");
180 if (status & CERT_TRUST_IS_CYCLIC)
181 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tcyclic chain");
182 if (status & CERT_TRUST_INVALID_EXTENSION)
183 pos += snprintf(buf + pos, sizeof(buf) - pos,
184 "\n\tunsupported critical extension");
185 if (status & CERT_TRUST_INVALID_POLICY_CONSTRAINTS)
186 pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad policy");
187 if (status & CERT_TRUST_INVALID_BASIC_CONSTRAINTS)
188 pos += snprintf(buf + pos, sizeof(buf) - pos,
189 "\n\tbad basic constraints");
190 if (status & CERT_TRUST_INVALID_NAME_CONSTRAINTS)
191 pos += snprintf(buf + pos, sizeof(buf) - pos,
192 "\n\tbad name constraints");
193 if (status & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT)
194 pos += snprintf(buf + pos, sizeof(buf) - pos,
195 "\n\tunsuported name constraint");
196 if (status & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT)
197 pos += snprintf(buf + pos, sizeof(buf) - pos,
198 "\n\tundefined name constraint");
199 if (status & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT)
200 pos += snprintf(buf + pos, sizeof(buf) - pos,
201 "\n\tdisallowed name constraint");
202 if (status & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT)
203 pos += snprintf(buf + pos, sizeof(buf) - pos,
204 "\n\texcluded name constraint");
205 if (status & CERT_TRUST_IS_OFFLINE_REVOCATION)
206 pos += snprintf(buf + pos, sizeof(buf) - pos,
207 "\n\trevocation server offline");
208 if (status & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY)
209 pos += snprintf(buf + pos, sizeof(buf) - pos,
210 "\n\tno issuance policy");
211 return buf;
212}
213
214static const char *get_cert_common_name(PCCERT_CONTEXT cert)
215{
216 static char buf[1024];
217 const char *name = NULL;
218 CERT_NAME_INFO *nameInfo;
219 DWORD size;
220 BOOL ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME,
221 cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData,
222 CRYPT_DECODE_NOCOPY_FLAG | CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
223 &size);
224
225 if (ret)
226 {
227 PCERT_RDN_ATTR commonName = CertFindRDNAttr(szOID_COMMON_NAME,
228 nameInfo);
229
230 if (commonName)
231 {
232 CertRDNValueToStrA(commonName->dwValueType,
233 &commonName->Value, buf, sizeof(buf));
234 name = buf;
235 }
236 LocalFree((HANDLE)nameInfo);
237 }
238 return name;
239}
240
241static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
242{
243 DWORD root_count = 0;
244 CERT_CHAIN_ENGINE_CONFIG chainEngineConfig =
245 { sizeof(chainEngineConfig), 0 };
246 HCERTCHAINENGINE engine;
247
248 TRACE("\n");
249
250 CertDuplicateStore(to);
251 engine = CRYPT_CreateChainEngine(to, &chainEngineConfig);
252 if (engine)
253 {
254 PCCERT_CONTEXT cert = NULL;
255
256 do {
257 cert = CertEnumCertificatesInStore(from, cert);
258 if (cert)
259 {
260 CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
261 PCCERT_CHAIN_CONTEXT chain;
262 BOOL ret = CertGetCertificateChain(engine, cert, NULL, from,
263 &chainPara, 0, NULL, &chain);
264
265 if (!ret)
266 TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
267 "chain creation failed");
268 else
269 {
270 /* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */
271 if (chain->TrustStatus.dwErrorStatus &
272 ~CERT_TRUST_IS_UNTRUSTED_ROOT)
273 TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
274 trust_status_to_str(chain->TrustStatus.dwErrorStatus &
275 ~CERT_TRUST_IS_UNTRUSTED_ROOT));
276 else
277 {
278 DWORD i, j;
279
280 for (i = 0; i < chain->cChain; i++)
281 for (j = 0; j < chain->rgpChain[i]->cElement; j++)
282 if (CertAddCertificateContextToStore(to,
283 chain->rgpChain[i]->rgpElement[j]->pCertContext,
284 CERT_STORE_ADD_NEW, NULL))
285 root_count++;
286 }
287 CertFreeCertificateChain(chain);
288 }
289 }
290 } while (cert);
291 CertFreeCertificateChainEngine(engine);
292 }
293 TRACE("Added %d root certificates\n", root_count);
294}
295
296/* Reads the file fd, and imports any certificates in it into store.
297 * Returns TRUE if any certificates were successfully imported.
298 */
299static BOOL import_certs_from_file(int fd, HCERTSTORE store)
300{
301 BOOL ret = FALSE;
302 FILE *fp;
303
304 TRACE("\n");
305
306 fp = fdopen(fd, "r");
307 if (fp)
308 {
309 ret = import_base64_certs_from_fp(fp, store);
310 fclose(fp);
311 }
312 return ret;
313}
314
315static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
316 BOOL allow_dir);
317
318/* Opens path, which must be a directory, and imports certificates from every
319 * file in the directory into store.
320 * Returns TRUE if any certificates were successfully imported.
321 */
322static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store)
323{
324#ifdef HAVE_READDIR
325 BOOL ret = FALSE;
326 DIR *dir;
327
328 TRACE("(%s, %p)\n", debugstr_a(path), store);
329
330 dir = opendir(path);
331 if (dir)
332 {
333 size_t bufsize = strlen(path) + 1 + PATH_MAX + 1;
334 char *filebuf = CryptMemAlloc(bufsize);
335
336 if (filebuf)
337 {
338 struct dirent *entry;
339 while ((entry = readdir(dir)))
340 {
341 if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
342 {
343 snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name);
344 if (import_certs_from_path(filebuf, store, FALSE) && !ret)
345 ret = TRUE;
346 }
347 }
348 closedir(dir);
349 CryptMemFree(filebuf);
350 }
351 }
352 return ret;
353#else
354 FIXME("not implemented without readdir available\n");
355 return FALSE;
356#endif
357}
358
359/* Opens path, which may be a file or a directory, and imports any certificates
360 * it finds into store.
361 * Returns TRUE if any certificates were successfully imported.
362 */
363static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
364 BOOL allow_dir)
365{
366 BOOL ret = FALSE;
367 int fd;
368
369 TRACE("(%s, %p, %d)\n", debugstr_a(path), store, allow_dir);
370
371 fd = _open(path, O_RDONLY);
372 if (fd != -1)
373 {
374#if 1
375 ret = import_certs_from_file(fd, store);
376#else
377 struct stat st;
378
379 if (fstat(fd, &st) == 0)
380 {
381 if (S_ISREG(st.st_mode))
382 ret = import_certs_from_file(fd, store);
383 else if (S_ISDIR(st.st_mode))
384 {
385 if (allow_dir)
386 ret = import_certs_from_dir(path, store);
387 else
388 WARN("%s is a directory and directories are disallowed\n",
389 debugstr_a(path));
390 }
391 else
392 ERR("%s: invalid file type\n", path);
393 }
394#endif
395 _close(fd);
396 }
397 return ret;
398}
399
400static BOOL WINAPI CRYPT_RootWriteCert(HCERTSTORE hCertStore,
401 PCCERT_CONTEXT cert, DWORD dwFlags)
402{
403 /* The root store can't have certs added */
404 return FALSE;
405}
406
407static BOOL WINAPI CRYPT_RootDeleteCert(HCERTSTORE hCertStore,
408 PCCERT_CONTEXT cert, DWORD dwFlags)
409{
410 /* The root store can't have certs deleted */
411 return FALSE;
412}
413
414static BOOL WINAPI CRYPT_RootWriteCRL(HCERTSTORE hCertStore,
415 PCCRL_CONTEXT crl, DWORD dwFlags)
416{
417 /* The root store can have CRLs added. At worst, a malicious application
418 * can DoS itself, as the changes aren't persisted in any way.
419 */
420 return TRUE;
421}
422
423static BOOL WINAPI CRYPT_RootDeleteCRL(HCERTSTORE hCertStore,
424 PCCRL_CONTEXT crl, DWORD dwFlags)
425{
426 /* The root store can't have CRLs deleted */
427 return FALSE;
428}
429
430static void *rootProvFuncs[] = {
431 NULL, /* CERT_STORE_PROV_CLOSE_FUNC */
432 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
433 (void*)CRYPT_RootWriteCert,
434 (void*)CRYPT_RootDeleteCert,
435 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
436 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
437 (void*)CRYPT_RootWriteCRL,
438 (void*)CRYPT_RootDeleteCRL,
439 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
440 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
441 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
442 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
443 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
444 NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
445};
446
447static const char * const CRYPT_knownLocations[] = {
448 "/etc/ssl/certs/ca-certificates.crt",
449 "/etc/ssl/certs",
450 "/etc/pki/tls/certs/ca-bundle.crt",
451 "/usr/local/share/certs/",
452};
453
454static const BYTE authenticode[] = {
4550x30,0x82,0x03,0xd6,0x30,0x82,0x02,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
4560x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,
4570x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0d,
4580x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,0x32,0x30,
4590x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
4600x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,0x74,
4610x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
4620x79,0x30,0x1e,0x17,0x0d,0x39,0x35,0x30,0x31,0x30,0x31,0x30,0x38,0x30,0x30,0x30,
4630x31,0x5a,0x17,0x0d,0x39,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,
4640x5a,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
4650x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
4660x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
4670x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
4680x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
4690x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4700x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,
4710x82,0x01,0x01,0x00,0xdf,0x08,0xba,0xe3,0x3f,0x6e,0x64,0x9b,0xf5,0x89,0xaf,0x28,
4720x96,0x4a,0x07,0x8f,0x1b,0x2e,0x8b,0x3e,0x1d,0xfc,0xb8,0x80,0x69,0xa3,0xa1,0xce,
4730xdb,0xdf,0xb0,0x8e,0x6c,0x89,0x76,0x29,0x4f,0xca,0x60,0x35,0x39,0xad,0x72,0x32,
4740xe0,0x0b,0xae,0x29,0x3d,0x4c,0x16,0xd9,0x4b,0x3c,0x9d,0xda,0xc5,0xd3,0xd1,0x09,
4750xc9,0x2c,0x6f,0xa6,0xc2,0x60,0x53,0x45,0xdd,0x4b,0xd1,0x55,0xcd,0x03,0x1c,0xd2,
4760x59,0x56,0x24,0xf3,0xe5,0x78,0xd8,0x07,0xcc,0xd8,0xb3,0x1f,0x90,0x3f,0xc0,0x1a,
4770x71,0x50,0x1d,0x2d,0xa7,0x12,0x08,0x6d,0x7c,0xb0,0x86,0x6c,0xc7,0xba,0x85,0x32,
4780x07,0xe1,0x61,0x6f,0xaf,0x03,0xc5,0x6d,0xe5,0xd6,0xa1,0x8f,0x36,0xf6,0xc1,0x0b,
4790xd1,0x3e,0x69,0x97,0x48,0x72,0xc9,0x7f,0xa4,0xc8,0xc2,0x4a,0x4c,0x7e,0xa1,0xd1,
4800x94,0xa6,0xd7,0xdc,0xeb,0x05,0x46,0x2e,0xb8,0x18,0xb4,0x57,0x1d,0x86,0x49,0xdb,
4810x69,0x4a,0x2c,0x21,0xf5,0x5e,0x0f,0x54,0x2d,0x5a,0x43,0xa9,0x7a,0x7e,0x6a,0x8e,
4820x50,0x4d,0x25,0x57,0xa1,0xbf,0x1b,0x15,0x05,0x43,0x7b,0x2c,0x05,0x8d,0xbd,0x3d,
4830x03,0x8c,0x93,0x22,0x7d,0x63,0xea,0x0a,0x57,0x05,0x06,0x0a,0xdb,0x61,0x98,0x65,
4840x2d,0x47,0x49,0xa8,0xe7,0xe6,0x56,0x75,0x5c,0xb8,0x64,0x08,0x63,0xa9,0x30,0x40,
4850x66,0xb2,0xf9,0xb6,0xe3,0x34,0xe8,0x67,0x30,0xe1,0x43,0x0b,0x87,0xff,0xc9,0xbe,
4860x72,0x10,0x5e,0x23,0xf0,0x9b,0xa7,0x48,0x65,0xbf,0x09,0x88,0x7b,0xcd,0x72,0xbc,
4870x2e,0x79,0x9b,0x7b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xba,0x30,0x81,0xb7,0x30,
4880x0d,0x06,0x03,0x55,0x1d,0x0a,0x04,0x06,0x30,0x04,0x03,0x02,0x07,0x80,0x30,0x32,
4890x06,0x03,0x55,0x04,0x03,0x04,0x2b,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
4900x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,
4910x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,
4920x74,0x79,0x30,0x72,0x06,0x03,0x55,0x1d,0x01,0x04,0x6b,0x30,0x69,0x80,0x10,0x1a,
4930x1b,0xe7,0x5b,0x9f,0xfd,0x8c,0x2a,0xc3,0x39,0xae,0x0c,0x62,0x2e,0x53,0x32,0xa1,
4940x52,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
4950x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
4960x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
4970x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
4980x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
4990x69,0x74,0x79,0x82,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5000x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2d,0xc9,0xe2,0xf6,0x12,0x9e,
5010x5d,0x56,0x67,0xfa,0xfa,0x4b,0x9a,0x7e,0xdc,0x29,0x56,0x5c,0x80,0x14,0x02,0x28,
5020x85,0x6e,0x26,0xf3,0xcd,0x58,0xda,0x50,0x80,0xc5,0xf8,0x19,0xb3,0xa6,0x7c,0xe2,
5030x9d,0x6b,0x5f,0x3b,0x8f,0x22,0x74,0xe6,0x18,0x04,0xfc,0x47,0x40,0xd8,0x7a,0x3f,
5040x30,0x66,0xf0,0x12,0xa4,0xd1,0xeb,0x1d,0xe7,0xb6,0xf4,0x98,0xab,0x53,0x22,0x86,
5050x51,0x58,0xee,0x23,0x09,0x76,0xe4,0x1d,0x45,0x5c,0x4b,0xff,0x4c,0xe3,0x02,0x50,
5060x01,0x13,0xcc,0x41,0xa4,0x52,0x97,0xd4,0x86,0xd5,0xc4,0xfe,0x83,0x83,0x65,0x7d,
5070xea,0xbe,0xa2,0x68,0x3b,0xc1,0xb1,0x29,0x98,0xbf,0xa2,0xa5,0xfc,0x9d,0xd3,0x84,
5080xee,0x70,0x17,0x50,0xf3,0x0b,0xfa,0x3c,0xef,0xa9,0x27,0x8b,0x91,0xb4,0x48,0xc8,
5090x45,0xa0,0xe1,0x01,0x42,0x4b,0x44,0x76,0x04,0x1c,0xc2,0x19,0xa2,0x8e,0x6b,0x20,
5100x98,0xc4,0xdd,0x02,0xac,0xb4,0xd2,0xa2,0x0e,0x8d,0x5d,0xb9,0x36,0x8e,0x4a,0x1b,
5110x5d,0x6c,0x1a,0xe2,0xcb,0x00,0x7f,0x10,0xf4,0xb2,0x95,0xef,0xe3,0xe8,0xff,0xa1,
5120x73,0x58,0xa9,0x75,0x2c,0xa2,0x49,0x95,0x85,0xfe,0xcc,0xda,0x44,0x8a,0xc2,0x12,
5130x44,0xd2,0x44,0xc8,0xa5,0xa2,0x1f,0xa9,0x5a,0x8e,0x56,0xc2,0xc3,0x7b,0xcf,0x42,
5140x60,0xdc,0x82,0x1f,0xfb,0xce,0x74,0x06,0x7e,0xd6,0xf1,0xac,0x19,0x6a,0x4f,0x74,
5150x5c,0xc5,0x15,0x66,0x31,0x6c,0xc1,0x62,0x71,0x91,0x0f,0x59,0x5b,0x7d,0x2a,0x82,
5160x1a,0xdf,0xb1,0xb4,0xd8,0x1d,0x37,0xde,0x0d,0x0f };
517static const BYTE rootauthority[] = {
5180x30,0x82,0x04,0x12,0x30,0x82,0x02,0xfa,0xa0,0x03,0x02,0x01,0x02,0x02,0x0f,0x00,
5190xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,0xdf,0x40,0x30,0x0d,
5200x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x70,0x31,
5210x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,0x72,0x69,
5220x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,0x69,0x63,
5230x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,0x30,0x1c,
5240x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
5250x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,0x30,0x1f,
5260x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
5270x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
5280x1e,0x17,0x0d,0x39,0x37,0x30,0x31,0x31,0x30,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,
5290x17,0x0d,0x32,0x30,0x31,0x32,0x33,0x31,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,0x30,
5300x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
5310x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
5320x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
5330x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
5340x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
5350x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
5360x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
5370x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
5380x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,
5390x01,0x00,0xa9,0x02,0xbd,0xc1,0x70,0xe6,0x3b,0xf2,0x4e,0x1b,0x28,0x9f,0x97,0x78,
5400x5e,0x30,0xea,0xa2,0xa9,0x8d,0x25,0x5f,0xf8,0xfe,0x95,0x4c,0xa3,0xb7,0xfe,0x9d,
5410xa2,0x20,0x3e,0x7c,0x51,0xa2,0x9b,0xa2,0x8f,0x60,0x32,0x6b,0xd1,0x42,0x64,0x79,
5420xee,0xac,0x76,0xc9,0x54,0xda,0xf2,0xeb,0x9c,0x86,0x1c,0x8f,0x9f,0x84,0x66,0xb3,
5430xc5,0x6b,0x7a,0x62,0x23,0xd6,0x1d,0x3c,0xde,0x0f,0x01,0x92,0xe8,0x96,0xc4,0xbf,
5440x2d,0x66,0x9a,0x9a,0x68,0x26,0x99,0xd0,0x3a,0x2c,0xbf,0x0c,0xb5,0x58,0x26,0xc1,
5450x46,0xe7,0x0a,0x3e,0x38,0x96,0x2c,0xa9,0x28,0x39,0xa8,0xec,0x49,0x83,0x42,0xe3,
5460x84,0x0f,0xbb,0x9a,0x6c,0x55,0x61,0xac,0x82,0x7c,0xa1,0x60,0x2d,0x77,0x4c,0xe9,
5470x99,0xb4,0x64,0x3b,0x9a,0x50,0x1c,0x31,0x08,0x24,0x14,0x9f,0xa9,0xe7,0x91,0x2b,
5480x18,0xe6,0x3d,0x98,0x63,0x14,0x60,0x58,0x05,0x65,0x9f,0x1d,0x37,0x52,0x87,0xf7,
5490xa7,0xef,0x94,0x02,0xc6,0x1b,0xd3,0xbf,0x55,0x45,0xb3,0x89,0x80,0xbf,0x3a,0xec,
5500x54,0x94,0x4e,0xae,0xfd,0xa7,0x7a,0x6d,0x74,0x4e,0xaf,0x18,0xcc,0x96,0x09,0x28,
5510x21,0x00,0x57,0x90,0x60,0x69,0x37,0xbb,0x4b,0x12,0x07,0x3c,0x56,0xff,0x5b,0xfb,
5520xa4,0x66,0x0a,0x08,0xa6,0xd2,0x81,0x56,0x57,0xef,0xb6,0x3b,0x5e,0x16,0x81,0x77,
5530x04,0xda,0xf6,0xbe,0xae,0x80,0x95,0xfe,0xb0,0xcd,0x7f,0xd6,0xa7,0x1a,0x72,0x5c,
5540x3c,0xca,0xbc,0xf0,0x08,0xa3,0x22,0x30,0xb3,0x06,0x85,0xc9,0xb3,0x20,0x77,0x13,
5550x85,0xdf,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xa8,0x30,0x81,0xa5,0x30,0x81,0xa2,
5560x06,0x03,0x55,0x1d,0x01,0x04,0x81,0x9a,0x30,0x81,0x97,0x80,0x10,0x5b,0xd0,0x70,
5570xef,0x69,0x72,0x9e,0x23,0x51,0x7e,0x14,0xb2,0x4d,0x8e,0xff,0xcb,0xa1,0x72,0x30,
5580x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
5590x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
5600x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
5610x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
5620x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
5630x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
5640x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
5650x79,0x82,0x0f,0x00,0xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,
5660xdf,0x40,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,
5670x00,0x03,0x82,0x01,0x01,0x00,0x95,0xe8,0x0b,0xc0,0x8d,0xf3,0x97,0x18,0x35,0xed,
5680xb8,0x01,0x24,0xd8,0x77,0x11,0xf3,0x5c,0x60,0x32,0x9f,0x9e,0x0b,0xcb,0x3e,0x05,
5690x91,0x88,0x8f,0xc9,0x3a,0xe6,0x21,0xf2,0xf0,0x57,0x93,0x2c,0xb5,0xa0,0x47,0xc8,
5700x62,0xef,0xfc,0xd7,0xcc,0x3b,0x3b,0x5a,0xa9,0x36,0x54,0x69,0xfe,0x24,0x6d,0x3f,
5710xc9,0xcc,0xaa,0xde,0x05,0x7c,0xdd,0x31,0x8d,0x3d,0x9f,0x10,0x70,0x6a,0xbb,0xfe,
5720x12,0x4f,0x18,0x69,0xc0,0xfc,0xd0,0x43,0xe3,0x11,0x5a,0x20,0x4f,0xea,0x62,0x7b,
5730xaf,0xaa,0x19,0xc8,0x2b,0x37,0x25,0x2d,0xbe,0x65,0xa1,0x12,0x8a,0x25,0x0f,0x63,
5740xa3,0xf7,0x54,0x1c,0xf9,0x21,0xc9,0xd6,0x15,0xf3,0x52,0xac,0x6e,0x43,0x32,0x07,
5750xfd,0x82,0x17,0xf8,0xe5,0x67,0x6c,0x0d,0x51,0xf6,0xbd,0xf1,0x52,0xc7,0xbd,0xe7,
5760xc4,0x30,0xfc,0x20,0x31,0x09,0x88,0x1d,0x95,0x29,0x1a,0x4d,0xd5,0x1d,0x02,0xa5,
5770xf1,0x80,0xe0,0x03,0xb4,0x5b,0xf4,0xb1,0xdd,0xc8,0x57,0xee,0x65,0x49,0xc7,0x52,
5780x54,0xb6,0xb4,0x03,0x28,0x12,0xff,0x90,0xd6,0xf0,0x08,0x8f,0x7e,0xb8,0x97,0xc5,
5790xab,0x37,0x2c,0xe4,0x7a,0xe4,0xa8,0x77,0xe3,0x76,0xa0,0x00,0xd0,0x6a,0x3f,0xc1,
5800xd2,0x36,0x8a,0xe0,0x41,0x12,0xa8,0x35,0x6a,0x1b,0x6a,0xdb,0x35,0xe1,0xd4,0x1c,
5810x04,0xe4,0xa8,0x45,0x04,0xc8,0x5a,0x33,0x38,0x6e,0x4d,0x1c,0x0d,0x62,0xb7,0x0a,
5820xa2,0x8c,0xd3,0xd5,0x54,0x3f,0x46,0xcd,0x1c,0x55,0xa6,0x70,0xdb,0x12,0x3a,0x87,
5830x93,0x75,0x9f,0xa7,0xd2,0xa0 };
584static const BYTE rootcertauthority[] = {
5850x30,0x82,0x05,0x99,0x30,0x82,0x03,0x81,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x79,
5860xad,0x16,0xa1,0x4a,0xa0,0xa5,0xad,0x4c,0x73,0x58,0xf4,0x07,0x13,0x2e,0x65,0x30,
5870x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x5f,
5880x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,0x19,
5890x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,
5900xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
5910x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,0x6f,
5920x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,
5930x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
5940x1e,0x17,0x0d,0x30,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x31,0x39,0x32,0x32,0x5a,
5950x17,0x0d,0x32,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x32,0x38,0x31,0x33,0x5a,0x30,
5960x5f,0x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,
5970x19,0x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,
5980x93,0xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
5990x74,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,
6000x6f,0x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,
6010x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,
6020x30,0x82,0x02,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
6030x01,0x05,0x00,0x03,0x82,0x02,0x0f,0x00,0x30,0x82,0x02,0x0a,0x02,0x82,0x02,0x01,
6040x00,0xf3,0x5d,0xfa,0x80,0x67,0xd4,0x5a,0xa7,0xa9,0x0c,0x2c,0x90,0x20,0xd0,0x35,
6050x08,0x3c,0x75,0x84,0xcd,0xb7,0x07,0x89,0x9c,0x89,0xda,0xde,0xce,0xc3,0x60,0xfa,
6060x91,0x68,0x5a,0x9e,0x94,0x71,0x29,0x18,0x76,0x7c,0xc2,0xe0,0xc8,0x25,0x76,0x94,
6070x0e,0x58,0xfa,0x04,0x34,0x36,0xe6,0xdf,0xaf,0xf7,0x80,0xba,0xe9,0x58,0x0b,0x2b,
6080x93,0xe5,0x9d,0x05,0xe3,0x77,0x22,0x91,0xf7,0x34,0x64,0x3c,0x22,0x91,0x1d,0x5e,
6090xe1,0x09,0x90,0xbc,0x14,0xfe,0xfc,0x75,0x58,0x19,0xe1,0x79,0xb7,0x07,0x92,0xa3,
6100xae,0x88,0x59,0x08,0xd8,0x9f,0x07,0xca,0x03,0x58,0xfc,0x68,0x29,0x6d,0x32,0xd7,
6110xd2,0xa8,0xcb,0x4b,0xfc,0xe1,0x0b,0x48,0x32,0x4f,0xe6,0xeb,0xb8,0xad,0x4f,0xe4,
6120x5c,0x6f,0x13,0x94,0x99,0xdb,0x95,0xd5,0x75,0xdb,0xa8,0x1a,0xb7,0x94,0x91,0xb4,
6130x77,0x5b,0xf5,0x48,0x0c,0x8f,0x6a,0x79,0x7d,0x14,0x70,0x04,0x7d,0x6d,0xaf,0x90,
6140xf5,0xda,0x70,0xd8,0x47,0xb7,0xbf,0x9b,0x2f,0x6c,0xe7,0x05,0xb7,0xe1,0x11,0x60,
6150xac,0x79,0x91,0x14,0x7c,0xc5,0xd6,0xa6,0xe4,0xe1,0x7e,0xd5,0xc3,0x7e,0xe5,0x92,
6160xd2,0x3c,0x00,0xb5,0x36,0x82,0xde,0x79,0xe1,0x6d,0xf3,0xb5,0x6e,0xf8,0x9f,0x33,
6170xc9,0xcb,0x52,0x7d,0x73,0x98,0x36,0xdb,0x8b,0xa1,0x6b,0xa2,0x95,0x97,0x9b,0xa3,
6180xde,0xc2,0x4d,0x26,0xff,0x06,0x96,0x67,0x25,0x06,0xc8,0xe7,0xac,0xe4,0xee,0x12,
6190x33,0x95,0x31,0x99,0xc8,0x35,0x08,0x4e,0x34,0xca,0x79,0x53,0xd5,0xb5,0xbe,0x63,
6200x32,0x59,0x40,0x36,0xc0,0xa5,0x4e,0x04,0x4d,0x3d,0xdb,0x5b,0x07,0x33,0xe4,0x58,
6210xbf,0xef,0x3f,0x53,0x64,0xd8,0x42,0x59,0x35,0x57,0xfd,0x0f,0x45,0x7c,0x24,0x04,
6220x4d,0x9e,0xd6,0x38,0x74,0x11,0x97,0x22,0x90,0xce,0x68,0x44,0x74,0x92,0x6f,0xd5,
6230x4b,0x6f,0xb0,0x86,0xe3,0xc7,0x36,0x42,0xa0,0xd0,0xfc,0xc1,0xc0,0x5a,0xf9,0xa3,
6240x61,0xb9,0x30,0x47,0x71,0x96,0x0a,0x16,0xb0,0x91,0xc0,0x42,0x95,0xef,0x10,0x7f,
6250x28,0x6a,0xe3,0x2a,0x1f,0xb1,0xe4,0xcd,0x03,0x3f,0x77,0x71,0x04,0xc7,0x20,0xfc,
6260x49,0x0f,0x1d,0x45,0x88,0xa4,0xd7,0xcb,0x7e,0x88,0xad,0x8e,0x2d,0xec,0x45,0xdb,
6270xc4,0x51,0x04,0xc9,0x2a,0xfc,0xec,0x86,0x9e,0x9a,0x11,0x97,0x5b,0xde,0xce,0x53,
6280x88,0xe6,0xe2,0xb7,0xfd,0xac,0x95,0xc2,0x28,0x40,0xdb,0xef,0x04,0x90,0xdf,0x81,
6290x33,0x39,0xd9,0xb2,0x45,0xa5,0x23,0x87,0x06,0xa5,0x55,0x89,0x31,0xbb,0x06,0x2d,
6300x60,0x0e,0x41,0x18,0x7d,0x1f,0x2e,0xb5,0x97,0xcb,0x11,0xeb,0x15,0xd5,0x24,0xa5,
6310x94,0xef,0x15,0x14,0x89,0xfd,0x4b,0x73,0xfa,0x32,0x5b,0xfc,0xd1,0x33,0x00,0xf9,
6320x59,0x62,0x70,0x07,0x32,0xea,0x2e,0xab,0x40,0x2d,0x7b,0xca,0xdd,0x21,0x67,0x1b,
6330x30,0x99,0x8f,0x16,0xaa,0x23,0xa8,0x41,0xd1,0xb0,0x6e,0x11,0x9b,0x36,0xc4,0xde,
6340x40,0x74,0x9c,0xe1,0x58,0x65,0xc1,0x60,0x1e,0x7a,0x5b,0x38,0xc8,0x8f,0xbb,0x04,
6350x26,0x7c,0xd4,0x16,0x40,0xe5,0xb6,0x6b,0x6c,0xaa,0x86,0xfd,0x00,0xbf,0xce,0xc1,
6360x35,0x02,0x03,0x01,0x00,0x01,0xa3,0x51,0x30,0x4f,0x30,0x0b,0x06,0x03,0x55,0x1d,
6370x0f,0x04,0x04,0x03,0x02,0x01,0xc6,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
6380xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,
6390x16,0x04,0x14,0x0e,0xac,0x82,0x60,0x40,0x56,0x27,0x97,0xe5,0x25,0x13,0xfc,0x2a,
6400xe1,0x0a,0x53,0x95,0x59,0xe4,0xa4,0x30,0x10,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,
6410x82,0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
6420x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0xc5,0x11,0x4d,
6430x03,0x3a,0x60,0xdd,0x5d,0x52,0x11,0x77,0x8f,0xb2,0xbb,0x36,0xc8,0xb2,0x05,0xbf,
6440xb4,0xb7,0xa8,0xd8,0x20,0x9d,0x5c,0x13,0x03,0xb6,0x1c,0x22,0xfa,0x06,0x13,0x35,
6450xb6,0xc8,0x63,0xd4,0x9a,0x47,0x6f,0x26,0x57,0xd2,0x55,0xf1,0x04,0xb1,0x26,0x5f,
6460xd6,0xa9,0x50,0x68,0xa0,0xbc,0xd2,0xb8,0x6e,0xcc,0xc3,0xe9,0xac,0xdf,0x19,0xcd,
6470x78,0xac,0x59,0x74,0xac,0x66,0x34,0x36,0xc4,0x1b,0x3e,0x6c,0x38,0x4c,0x33,0x0e,
6480x30,0x12,0x0d,0xa3,0x26,0xfe,0x51,0x53,0x00,0xff,0xaf,0x5a,0x4e,0x84,0x0d,0x0f,
6490x1f,0xe4,0x6d,0x05,0x2e,0x4e,0x85,0x4b,0x8d,0x6c,0x33,0x6f,0x54,0xd2,0x64,0xab,
6500xbf,0x50,0xaf,0x7d,0x7a,0x39,0xa0,0x37,0xed,0x63,0x03,0x0f,0xfc,0x13,0x06,0xce,
6510x16,0x36,0xd4,0x54,0x3b,0x95,0x1b,0x51,0x62,0x3a,0xe5,0x4d,0x17,0xd4,0x05,0x39,
6520x92,0x9a,0x27,0xa8,0x5b,0xaa,0xbd,0xec,0xbb,0xbe,0xe3,0x20,0x89,0x60,0x71,0x6c,
6530x56,0xb3,0xa5,0x13,0xd0,0x6d,0x0e,0x23,0x7e,0x95,0x03,0xed,0x68,0x3d,0xf2,0xd8,
6540x63,0xb8,0x6b,0x4d,0xb6,0xe8,0x30,0xb5,0xe1,0xca,0x94,0x4b,0xf7,0xa2,0xaa,0x5d,
6550x99,0x30,0xb2,0x3d,0xa7,0xc2,0x51,0x6c,0x28,0x20,0x01,0x24,0x27,0x2b,0x4b,0x00,
6560xb7,0x9d,0x11,0x6b,0x70,0xbe,0xb2,0x10,0x82,0xbc,0x0c,0x9b,0x68,0xd0,0x8d,0x3b,
6570x24,0x87,0xaa,0x99,0x28,0x72,0x9d,0x33,0x5f,0x59,0x90,0xbd,0xf5,0xde,0x93,0x9e,
6580x3a,0x62,0x5a,0x34,0x39,0xe2,0x88,0x55,0x1d,0xb9,0x06,0xb0,0xc1,0x89,0x6b,0x2d,
6590xd7,0x69,0xc3,0x19,0x12,0x36,0x84,0xd0,0xc9,0xa0,0xda,0xff,0x2f,0x69,0x78,0xb2,
6600xe5,0x7a,0xda,0xeb,0xd7,0x0c,0xc0,0xf7,0xbd,0x63,0x17,0xb8,0x39,0x13,0x38,0xa2,
6610x36,0x5b,0x7b,0xf2,0x85,0x56,0x6a,0x1d,0x64,0x62,0xc1,0x38,0xe2,0xaa,0xbf,0x51,
6620x66,0xa2,0x94,0xf5,0x12,0x9c,0x66,0x22,0x10,0x6b,0xf2,0xb7,0x30,0x92,0x2d,0xf2,
6630x29,0xf0,0x3d,0x3b,0x14,0x43,0x68,0xa2,0xf1,0x9c,0x29,0x37,0xcb,0xce,0x38,0x20,
6640x25,0x6d,0x7c,0x67,0xf3,0x7e,0x24,0x12,0x24,0x03,0x08,0x81,0x47,0xec,0xa5,0x9e,
6650x97,0xf5,0x18,0xd7,0xcf,0xbb,0xd5,0xef,0x76,0x96,0xef,0xfd,0xce,0xdb,0x56,0x9d,
6660x95,0xa0,0x42,0xf9,0x97,0x58,0xe1,0xd7,0x31,0x22,0xd3,0x5f,0x59,0xe6,0x3e,0x6e,
6670x22,0x00,0xea,0x43,0x84,0xb6,0x25,0xdb,0xd9,0xf3,0x08,0x56,0x68,0xc0,0x64,0x6b,
6680x1d,0x7c,0xec,0xb6,0x93,0xa2,0x62,0x57,0x6e,0x2e,0xd8,0xe7,0x58,0x8f,0xc4,0x31,
6690x49,0x26,0xdd,0xde,0x29,0x35,0x87,0xf5,0x30,0x71,0x70,0x5b,0x14,0x3c,0x69,0xbd,
6700x89,0x12,0x7d,0xeb,0x2e,0xa3,0xfe,0xd8,0x7f,0x9e,0x82,0x5a,0x52,0x0a,0x2b,0xc1,
6710x43,0x2b,0xd9,0x30,0x88,0x9f,0xc8,0x10,0xfb,0x89,0x8d,0xe6,0xa1,0x85,0x75,0x33,
6720x7e,0x6c,0x9e,0xdb,0x73,0x13,0x64,0x62,0x69,0xa5,0x2f,0x7d,0xca,0x96,0x6d,0x9f,
6730xf8,0x04,0x4d,0x30,0x92,0x3d,0x6e,0x21,0x14,0x21,0xc9,0x3d,0xe0,0xc3,0xfd,0x8a,
6740x6b,0x9d,0x4a,0xfd,0xd1,0xa1,0x9d,0x99,0x43,0x77,0x3f,0xb0,0xda };
675
676static const struct CONST_BLOB {
677 const BYTE *pb;
678 DWORD cb;
679} msRootCerts[] = {
680 { authenticode, sizeof(authenticode) },
681 { rootauthority, sizeof(rootauthority) },
682 { rootcertauthority, sizeof(rootcertauthority) },
683};
684
685static void add_ms_root_certs(HCERTSTORE to)
686{
687 DWORD i;
688
689 TRACE("\n");
690
691 for (i = 0; i < sizeof(msRootCerts) / sizeof(msRootCerts[0]); i++)
692 if (!CertAddEncodedCertificateToStore(to, X509_ASN_ENCODING,
693 msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, NULL))
694 WARN("adding root cert %d failed: %08x\n", i, GetLastError());
695}
696
697/* Reads certificates from the list of known locations into store. Stops when
698 * any location contains any certificates, to prevent spending unnecessary time
699 * adding redundant certificates, e.g. when both a certificate bundle and
700 * individual certificates exist in the same directory.
701 */
702static void read_trusted_roots_from_known_locations(HCERTSTORE store)
703{
704 HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
705 X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
706
707 if (from)
708 {
709 DWORD i;
710 BOOL ret = FALSE;
711
712 for (i = 0; !ret &&
713 i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
714 i++)
715 ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
716 check_and_store_certs(from, store);
717 }
718}
719
720static HCERTSTORE create_root_store(void)
721{
722 HCERTSTORE root = NULL;
723 HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
724 X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
725
726 if (memStore)
727 {
728 CERT_STORE_PROV_INFO provInfo = {
729 sizeof(CERT_STORE_PROV_INFO),
730 sizeof(rootProvFuncs) / sizeof(rootProvFuncs[0]),
731 rootProvFuncs,
732 NULL,
733 0,
734 NULL
735 };
736
737 read_trusted_roots_from_known_locations(memStore);
738 add_ms_root_certs(memStore);
739 root = CRYPT_ProvCreateStore(0, memStore, &provInfo);
740 }
741 TRACE("returning %p\n", root);
742 return root;
743}
744
745static PWINECRYPT_CERTSTORE CRYPT_rootStore;
746
747PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
748{
749 TRACE("(%ld, %08x)\n", hCryptProv, dwFlags);
750
751 if (dwFlags & CERT_STORE_DELETE_FLAG)
752 {
753 WARN("root store can't be deleted\n");
754 SetLastError(ERROR_ACCESS_DENIED);
755 return NULL;
756 }
757 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
758 {
759 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
760 case CERT_SYSTEM_STORE_CURRENT_USER:
761 break;
762 default:
763 TRACE("location %08x unsupported\n",
764 dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK);
765 SetLastError(E_INVALIDARG);
766 return NULL;
767 }
768 if (!CRYPT_rootStore)
769 {
770 HCERTSTORE root = create_root_store();
771
772 InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root,
773 NULL);
774 if (CRYPT_rootStore != root)
775 CertCloseStore(root, 0);
776 }
777 CertDuplicateStore(CRYPT_rootStore);
778 return CRYPT_rootStore;
779}
780
781void root_store_free(void)
782{
783 CertCloseStore(CRYPT_rootStore, 0);
784}
Note: See TracBrowser for help on using the repository browser.