2 * Copyright 2007 Juan Lang
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.
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.
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
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_STAT_H
34 #ifdef HAVE_SECURITY_SECURITY_H
35 #include <Security/Security.h>
38 #define WIN32_NO_STATUS
44 #include "wine/debug.h"
45 #include "crypt32_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
49 #define INITIAL_CERT_BUFFER 1024
58 static inline void reset_buffer(struct DynamicBuffer
*buffer
)
61 if (buffer
->data
) buffer
->data
[0] = 0;
64 static BOOL
add_line_to_buffer(struct DynamicBuffer
*buffer
, LPCSTR line
)
68 if (buffer
->used
+ strlen(line
) + 1 > buffer
->allocated
)
70 if (!buffer
->allocated
)
72 buffer
->data
= CryptMemAlloc(INITIAL_CERT_BUFFER
);
76 buffer
->allocated
= INITIAL_CERT_BUFFER
;
81 DWORD new_size
= max(buffer
->allocated
* 2,
82 buffer
->used
+ strlen(line
) + 1);
84 buffer
->data
= CryptMemRealloc(buffer
->data
, new_size
);
86 buffer
->allocated
= new_size
;
91 strcpy((char *)buffer
->data
+ strlen((char *)buffer
->data
), line
);
92 /* Not strlen + 1, otherwise we'd count the NULL for every line's
93 * addition (but we overwrite the previous NULL character.) Not an
94 * overrun, we allocate strlen + 1 bytes above.
96 buffer
->used
+= strlen(line
);
104 /* Reads any base64-encoded certificates present in fp and adds them to store.
105 * Returns TRUE if any certificates were successfully imported.
107 static BOOL
import_base64_certs_from_fp(FILE *fp
, HCERTSTORE store
)
110 BOOL in_cert
= FALSE
;
111 struct DynamicBuffer saved_cert
= { 0, 0, NULL
};
115 while (fgets(line
, sizeof(line
), fp
))
117 static const char header
[] = "-----BEGIN CERTIFICATE-----";
118 static const char trailer
[] = "-----END CERTIFICATE-----";
120 if (!strncmp(line
, header
, strlen(header
)))
122 TRACE("begin new certificate\n");
124 reset_buffer(&saved_cert
);
126 else if (!strncmp(line
, trailer
, strlen(trailer
)))
130 TRACE("end of certificate, adding cert\n");
132 if (CryptStringToBinaryA((char *)saved_cert
.data
, saved_cert
.used
,
133 CRYPT_STRING_BASE64
, NULL
, &size
, NULL
, NULL
))
135 LPBYTE buf
= CryptMemAlloc(size
);
139 CryptStringToBinaryA((char *)saved_cert
.data
,
140 saved_cert
.used
, CRYPT_STRING_BASE64
, buf
, &size
, NULL
,
142 if (CertAddEncodedCertificateToStore(store
,
143 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_NEW
, NULL
))
150 add_line_to_buffer(&saved_cert
, line
);
152 CryptMemFree(saved_cert
.data
);
153 TRACE("Read %d certs\n", num_certs
);
154 return num_certs
> 0;
157 static const char *trust_status_to_str(DWORD status
)
159 static char buf
[1024];
162 if (status
& CERT_TRUST_IS_NOT_TIME_VALID
)
163 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\texpired");
164 if (status
& CERT_TRUST_IS_NOT_TIME_NESTED
)
165 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tbad time nesting");
166 if (status
& CERT_TRUST_IS_REVOKED
)
167 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\trevoked");
168 if (status
& CERT_TRUST_IS_NOT_SIGNATURE_VALID
)
169 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tbad signature");
170 if (status
& CERT_TRUST_IS_NOT_VALID_FOR_USAGE
)
171 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tbad usage");
172 if (status
& CERT_TRUST_IS_UNTRUSTED_ROOT
)
173 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tuntrusted root");
174 if (status
& CERT_TRUST_REVOCATION_STATUS_UNKNOWN
)
175 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
176 "\n\tunknown revocation status");
177 if (status
& CERT_TRUST_IS_CYCLIC
)
178 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tcyclic chain");
179 if (status
& CERT_TRUST_INVALID_EXTENSION
)
180 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
181 "\n\tunsupported critical extension");
182 if (status
& CERT_TRUST_INVALID_POLICY_CONSTRAINTS
)
183 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
, "\n\tbad policy");
184 if (status
& CERT_TRUST_INVALID_BASIC_CONSTRAINTS
)
185 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
186 "\n\tbad basic constraints");
187 if (status
& CERT_TRUST_INVALID_NAME_CONSTRAINTS
)
188 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
189 "\n\tbad name constraints");
190 if (status
& CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
)
191 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
192 "\n\tunsupported name constraint");
193 if (status
& CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
)
194 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
195 "\n\tundefined name constraint");
196 if (status
& CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
)
197 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
198 "\n\tdisallowed name constraint");
199 if (status
& CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
)
200 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
201 "\n\texcluded name constraint");
202 if (status
& CERT_TRUST_IS_OFFLINE_REVOCATION
)
203 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
204 "\n\trevocation server offline");
205 if (status
& CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY
)
206 pos
+= snprintf(buf
+ pos
, sizeof(buf
) - pos
,
207 "\n\tno issuance policy");
211 static const char *get_cert_common_name(PCCERT_CONTEXT cert
)
213 static char buf
[1024];
214 const char *name
= NULL
;
215 CERT_NAME_INFO
*nameInfo
;
217 BOOL ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
,
218 cert
->pCertInfo
->Subject
.pbData
, cert
->pCertInfo
->Subject
.cbData
,
219 CRYPT_DECODE_NOCOPY_FLAG
| CRYPT_DECODE_ALLOC_FLAG
, NULL
, &nameInfo
,
224 PCERT_RDN_ATTR commonName
= CertFindRDNAttr(szOID_COMMON_NAME
,
229 CertRDNValueToStrA(commonName
->dwValueType
,
230 &commonName
->Value
, buf
, sizeof(buf
));
238 static void check_and_store_certs(HCERTSTORE from
, HCERTSTORE to
)
240 DWORD root_count
= 0;
241 CERT_CHAIN_ENGINE_CONFIG chainEngineConfig
=
242 { sizeof(chainEngineConfig
), 0 };
243 HCERTCHAINENGINE engine
;
247 CertDuplicateStore(to
);
248 engine
= CRYPT_CreateChainEngine(to
, CERT_SYSTEM_STORE_CURRENT_USER
, &chainEngineConfig
);
251 PCCERT_CONTEXT cert
= NULL
;
254 cert
= CertEnumCertificatesInStore(from
, cert
);
257 CERT_CHAIN_PARA chainPara
= { sizeof(chainPara
), { 0 } };
258 PCCERT_CHAIN_CONTEXT chain
;
261 ret
= CertGetCertificateChain(engine
, cert
, NULL
, from
,
262 &chainPara
, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
, NULL
, &chain
);
264 TRACE("rejecting %s: %s\n", get_cert_common_name(cert
),
265 "chain creation failed");
268 DWORD allowedErrors
= CERT_TRUST_IS_UNTRUSTED_ROOT
|
269 CERT_TRUST_IS_NOT_VALID_FOR_USAGE
|
270 CERT_TRUST_INVALID_BASIC_CONSTRAINTS
|
271 CERT_TRUST_IS_NOT_TIME_VALID
;
273 /* The certificate chain verification only allows certain
274 * invalid CA certs if they're installed locally: CA
275 * certs missing the key usage extension, and CA certs
276 * missing the basic constraints extension. Of course
277 * there's a chicken and egg problem: we have to accept
278 * them here in order for them to be accepted later.
279 * Expired, locally installed certs are also allowed here,
280 * because we don't know (yet) what date will be checked
281 * for an item signed by one of these certs.
282 * Thus, accept certs with any of the allowed errors.
284 if (chain
->TrustStatus
.dwErrorStatus
& ~allowedErrors
)
285 TRACE("rejecting %s: %s\n", get_cert_common_name(cert
),
286 trust_status_to_str(chain
->TrustStatus
.dwErrorStatus
&
287 ~CERT_TRUST_IS_UNTRUSTED_ROOT
));
292 for (i
= 0; i
< chain
->cChain
; i
++)
293 for (j
= 0; j
< chain
->rgpChain
[i
]->cElement
; j
++)
294 if (CertAddCertificateContextToStore(to
,
295 chain
->rgpChain
[i
]->rgpElement
[j
]->pCertContext
,
296 CERT_STORE_ADD_NEW
, NULL
))
299 CertFreeCertificateChain(chain
);
303 CertFreeCertificateChainEngine(engine
);
305 TRACE("Added %d root certificates\n", root_count
);
308 /* Reads the file fd, and imports any certificates in it into store.
309 * Returns TRUE if any certificates were successfully imported.
311 static BOOL
import_certs_from_file(int fd
, HCERTSTORE store
)
318 fp
= fdopen(fd
, "r");
321 ret
= import_base64_certs_from_fp(fp
, store
);
327 static BOOL
import_certs_from_path(LPCSTR path
, HCERTSTORE store
,
330 static BOOL
check_buffer_resize(char **ptr_buf
, size_t *buf_size
, size_t check_size
)
332 if (check_size
> *buf_size
)
334 *buf_size
= check_size
;
338 char *realloc_buf
= CryptMemRealloc(*ptr_buf
, *buf_size
);
343 *ptr_buf
= realloc_buf
;
347 *ptr_buf
= CryptMemAlloc(*buf_size
);
356 /* Opens path, which must be a directory, and imports certificates from every
357 * file in the directory into store.
358 * Returns TRUE if any certificates were successfully imported.
360 static BOOL
import_certs_from_dir(LPCSTR path
, HCERTSTORE store
)
366 TRACE("(%s, %p)\n", debugstr_a(path
), store
);
371 size_t path_len
= strlen(path
), bufsize
= 0;
372 char *filebuf
= NULL
;
374 struct dirent
*entry
;
375 while ((entry
= readdir(dir
)))
377 if (strcmp(entry
->d_name
, ".") && strcmp(entry
->d_name
, ".."))
379 size_t name_len
= strlen(entry
->d_name
);
381 if (!check_buffer_resize(&filebuf
, &bufsize
, path_len
+ 1 + name_len
+ 1))
383 ERR("Path buffer (re)allocation failed with out of memory condition\n");
386 snprintf(filebuf
, bufsize
, "%s/%s", path
, entry
->d_name
);
387 if (import_certs_from_path(filebuf
, store
, FALSE
) && !ret
)
391 CryptMemFree(filebuf
);
396 FIXME("not implemented without readdir available\n");
401 /* Opens path, which may be a file or a directory, and imports any certificates
402 * it finds into store.
403 * Returns TRUE if any certificates were successfully imported.
405 static BOOL
import_certs_from_path(LPCSTR path
, HCERTSTORE store
,
411 TRACE("(%s, %p, %d)\n", debugstr_a(path
), store
, allow_dir
);
413 fd
= open(path
, O_RDONLY
);
418 if (fstat(fd
, &st
) == 0)
420 if (S_ISREG(st
.st_mode
))
421 ret
= import_certs_from_file(fd
, store
);
422 else if (S_ISDIR(st
.st_mode
))
425 ret
= import_certs_from_dir(path
, store
);
427 WARN("%s is a directory and directories are disallowed\n",
431 ERR("%s: invalid file type\n", path
);
438 static BOOL WINAPI
CRYPT_RootWriteCert(HCERTSTORE hCertStore
,
439 PCCERT_CONTEXT cert
, DWORD dwFlags
)
441 /* The root store can't have certs added */
445 static BOOL WINAPI
CRYPT_RootDeleteCert(HCERTSTORE hCertStore
,
446 PCCERT_CONTEXT cert
, DWORD dwFlags
)
448 /* The root store can't have certs deleted */
452 static BOOL WINAPI
CRYPT_RootWriteCRL(HCERTSTORE hCertStore
,
453 PCCRL_CONTEXT crl
, DWORD dwFlags
)
455 /* The root store can have CRLs added. At worst, a malicious application
456 * can DoS itself, as the changes aren't persisted in any way.
461 static BOOL WINAPI
CRYPT_RootDeleteCRL(HCERTSTORE hCertStore
,
462 PCCRL_CONTEXT crl
, DWORD dwFlags
)
464 /* The root store can't have CRLs deleted */
468 static void *rootProvFuncs
[] = {
469 NULL
, /* CERT_STORE_PROV_CLOSE_FUNC */
470 NULL
, /* CERT_STORE_PROV_READ_CERT_FUNC */
472 CRYPT_RootDeleteCert
,
473 NULL
, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
474 NULL
, /* CERT_STORE_PROV_READ_CRL_FUNC */
477 NULL
, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
478 NULL
, /* CERT_STORE_PROV_READ_CTL_FUNC */
479 NULL
, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
480 NULL
, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
481 NULL
, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
482 NULL
, /* CERT_STORE_PROV_CONTROL_FUNC */
485 static const char * const CRYPT_knownLocations
[] = {
486 "/etc/ssl/certs/ca-certificates.crt",
488 "/etc/pki/tls/certs/ca-bundle.crt",
489 "/usr/share/ca-certificates/ca-bundle.crt",
490 "/usr/local/share/certs/",
491 "/etc/sfw/openssl/certs",
494 static const BYTE authenticode
[] = {
495 0x30,0x82,0x03,0xd6,0x30,0x82,0x02,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
496 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,
497 0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0d,
498 0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,0x32,0x30,
499 0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
500 0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,0x74,
501 0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
502 0x79,0x30,0x1e,0x17,0x0d,0x39,0x35,0x30,0x31,0x30,0x31,0x30,0x38,0x30,0x30,0x30,
503 0x31,0x5a,0x17,0x0d,0x39,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,
504 0x5a,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
505 0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
506 0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
507 0x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
508 0x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
509 0x69,0x74,0x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
510 0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,
511 0x82,0x01,0x01,0x00,0xdf,0x08,0xba,0xe3,0x3f,0x6e,0x64,0x9b,0xf5,0x89,0xaf,0x28,
512 0x96,0x4a,0x07,0x8f,0x1b,0x2e,0x8b,0x3e,0x1d,0xfc,0xb8,0x80,0x69,0xa3,0xa1,0xce,
513 0xdb,0xdf,0xb0,0x8e,0x6c,0x89,0x76,0x29,0x4f,0xca,0x60,0x35,0x39,0xad,0x72,0x32,
514 0xe0,0x0b,0xae,0x29,0x3d,0x4c,0x16,0xd9,0x4b,0x3c,0x9d,0xda,0xc5,0xd3,0xd1,0x09,
515 0xc9,0x2c,0x6f,0xa6,0xc2,0x60,0x53,0x45,0xdd,0x4b,0xd1,0x55,0xcd,0x03,0x1c,0xd2,
516 0x59,0x56,0x24,0xf3,0xe5,0x78,0xd8,0x07,0xcc,0xd8,0xb3,0x1f,0x90,0x3f,0xc0,0x1a,
517 0x71,0x50,0x1d,0x2d,0xa7,0x12,0x08,0x6d,0x7c,0xb0,0x86,0x6c,0xc7,0xba,0x85,0x32,
518 0x07,0xe1,0x61,0x6f,0xaf,0x03,0xc5,0x6d,0xe5,0xd6,0xa1,0x8f,0x36,0xf6,0xc1,0x0b,
519 0xd1,0x3e,0x69,0x97,0x48,0x72,0xc9,0x7f,0xa4,0xc8,0xc2,0x4a,0x4c,0x7e,0xa1,0xd1,
520 0x94,0xa6,0xd7,0xdc,0xeb,0x05,0x46,0x2e,0xb8,0x18,0xb4,0x57,0x1d,0x86,0x49,0xdb,
521 0x69,0x4a,0x2c,0x21,0xf5,0x5e,0x0f,0x54,0x2d,0x5a,0x43,0xa9,0x7a,0x7e,0x6a,0x8e,
522 0x50,0x4d,0x25,0x57,0xa1,0xbf,0x1b,0x15,0x05,0x43,0x7b,0x2c,0x05,0x8d,0xbd,0x3d,
523 0x03,0x8c,0x93,0x22,0x7d,0x63,0xea,0x0a,0x57,0x05,0x06,0x0a,0xdb,0x61,0x98,0x65,
524 0x2d,0x47,0x49,0xa8,0xe7,0xe6,0x56,0x75,0x5c,0xb8,0x64,0x08,0x63,0xa9,0x30,0x40,
525 0x66,0xb2,0xf9,0xb6,0xe3,0x34,0xe8,0x67,0x30,0xe1,0x43,0x0b,0x87,0xff,0xc9,0xbe,
526 0x72,0x10,0x5e,0x23,0xf0,0x9b,0xa7,0x48,0x65,0xbf,0x09,0x88,0x7b,0xcd,0x72,0xbc,
527 0x2e,0x79,0x9b,0x7b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xba,0x30,0x81,0xb7,0x30,
528 0x0d,0x06,0x03,0x55,0x1d,0x0a,0x04,0x06,0x30,0x04,0x03,0x02,0x07,0x80,0x30,0x32,
529 0x06,0x03,0x55,0x04,0x03,0x04,0x2b,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
530 0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,0x28,
531 0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,
532 0x74,0x79,0x30,0x72,0x06,0x03,0x55,0x1d,0x01,0x04,0x6b,0x30,0x69,0x80,0x10,0x1a,
533 0x1b,0xe7,0x5b,0x9f,0xfd,0x8c,0x2a,0xc3,0x39,0xae,0x0c,0x62,0x2e,0x53,0x32,0xa1,
534 0x52,0x30,0x50,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,
535 0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x13,0x04,0x4d,0x53,0x46,0x54,0x31,
536 0x32,0x30,0x30,0x06,0x03,0x55,0x04,0x03,0x13,0x29,0x4d,0x69,0x63,0x72,0x6f,0x73,
537 0x6f,0x66,0x74,0x20,0x41,0x75,0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x6f,0x64,0x65,
538 0x28,0x74,0x6d,0x29,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,
539 0x69,0x74,0x79,0x82,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
540 0x01,0x01,0x04,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2d,0xc9,0xe2,0xf6,0x12,0x9e,
541 0x5d,0x56,0x67,0xfa,0xfa,0x4b,0x9a,0x7e,0xdc,0x29,0x56,0x5c,0x80,0x14,0x02,0x28,
542 0x85,0x6e,0x26,0xf3,0xcd,0x58,0xda,0x50,0x80,0xc5,0xf8,0x19,0xb3,0xa6,0x7c,0xe2,
543 0x9d,0x6b,0x5f,0x3b,0x8f,0x22,0x74,0xe6,0x18,0x04,0xfc,0x47,0x40,0xd8,0x7a,0x3f,
544 0x30,0x66,0xf0,0x12,0xa4,0xd1,0xeb,0x1d,0xe7,0xb6,0xf4,0x98,0xab,0x53,0x22,0x86,
545 0x51,0x58,0xee,0x23,0x09,0x76,0xe4,0x1d,0x45,0x5c,0x4b,0xff,0x4c,0xe3,0x02,0x50,
546 0x01,0x13,0xcc,0x41,0xa4,0x52,0x97,0xd4,0x86,0xd5,0xc4,0xfe,0x83,0x83,0x65,0x7d,
547 0xea,0xbe,0xa2,0x68,0x3b,0xc1,0xb1,0x29,0x98,0xbf,0xa2,0xa5,0xfc,0x9d,0xd3,0x84,
548 0xee,0x70,0x17,0x50,0xf3,0x0b,0xfa,0x3c,0xef,0xa9,0x27,0x8b,0x91,0xb4,0x48,0xc8,
549 0x45,0xa0,0xe1,0x01,0x42,0x4b,0x44,0x76,0x04,0x1c,0xc2,0x19,0xa2,0x8e,0x6b,0x20,
550 0x98,0xc4,0xdd,0x02,0xac,0xb4,0xd2,0xa2,0x0e,0x8d,0x5d,0xb9,0x36,0x8e,0x4a,0x1b,
551 0x5d,0x6c,0x1a,0xe2,0xcb,0x00,0x7f,0x10,0xf4,0xb2,0x95,0xef,0xe3,0xe8,0xff,0xa1,
552 0x73,0x58,0xa9,0x75,0x2c,0xa2,0x49,0x95,0x85,0xfe,0xcc,0xda,0x44,0x8a,0xc2,0x12,
553 0x44,0xd2,0x44,0xc8,0xa5,0xa2,0x1f,0xa9,0x5a,0x8e,0x56,0xc2,0xc3,0x7b,0xcf,0x42,
554 0x60,0xdc,0x82,0x1f,0xfb,0xce,0x74,0x06,0x7e,0xd6,0xf1,0xac,0x19,0x6a,0x4f,0x74,
555 0x5c,0xc5,0x15,0x66,0x31,0x6c,0xc1,0x62,0x71,0x91,0x0f,0x59,0x5b,0x7d,0x2a,0x82,
556 0x1a,0xdf,0xb1,0xb4,0xd8,0x1d,0x37,0xde,0x0d,0x0f };
557 static const BYTE rootauthority
[] = {
558 0x30,0x82,0x04,0x12,0x30,0x82,0x02,0xfa,0xa0,0x03,0x02,0x01,0x02,0x02,0x0f,0x00,
559 0xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,0xdf,0x40,0x30,0x0d,
560 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x70,0x31,
561 0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,0x72,0x69,
562 0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,0x69,0x63,
563 0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,0x30,0x1c,
564 0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
565 0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,0x30,0x1f,
566 0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
567 0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
568 0x1e,0x17,0x0d,0x39,0x37,0x30,0x31,0x31,0x30,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,
569 0x17,0x0d,0x32,0x30,0x31,0x32,0x33,0x31,0x30,0x37,0x30,0x30,0x30,0x30,0x5a,0x30,
570 0x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
571 0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
572 0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
573 0x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
574 0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
575 0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
576 0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
577 0x79,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
578 0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,
579 0x01,0x00,0xa9,0x02,0xbd,0xc1,0x70,0xe6,0x3b,0xf2,0x4e,0x1b,0x28,0x9f,0x97,0x78,
580 0x5e,0x30,0xea,0xa2,0xa9,0x8d,0x25,0x5f,0xf8,0xfe,0x95,0x4c,0xa3,0xb7,0xfe,0x9d,
581 0xa2,0x20,0x3e,0x7c,0x51,0xa2,0x9b,0xa2,0x8f,0x60,0x32,0x6b,0xd1,0x42,0x64,0x79,
582 0xee,0xac,0x76,0xc9,0x54,0xda,0xf2,0xeb,0x9c,0x86,0x1c,0x8f,0x9f,0x84,0x66,0xb3,
583 0xc5,0x6b,0x7a,0x62,0x23,0xd6,0x1d,0x3c,0xde,0x0f,0x01,0x92,0xe8,0x96,0xc4,0xbf,
584 0x2d,0x66,0x9a,0x9a,0x68,0x26,0x99,0xd0,0x3a,0x2c,0xbf,0x0c,0xb5,0x58,0x26,0xc1,
585 0x46,0xe7,0x0a,0x3e,0x38,0x96,0x2c,0xa9,0x28,0x39,0xa8,0xec,0x49,0x83,0x42,0xe3,
586 0x84,0x0f,0xbb,0x9a,0x6c,0x55,0x61,0xac,0x82,0x7c,0xa1,0x60,0x2d,0x77,0x4c,0xe9,
587 0x99,0xb4,0x64,0x3b,0x9a,0x50,0x1c,0x31,0x08,0x24,0x14,0x9f,0xa9,0xe7,0x91,0x2b,
588 0x18,0xe6,0x3d,0x98,0x63,0x14,0x60,0x58,0x05,0x65,0x9f,0x1d,0x37,0x52,0x87,0xf7,
589 0xa7,0xef,0x94,0x02,0xc6,0x1b,0xd3,0xbf,0x55,0x45,0xb3,0x89,0x80,0xbf,0x3a,0xec,
590 0x54,0x94,0x4e,0xae,0xfd,0xa7,0x7a,0x6d,0x74,0x4e,0xaf,0x18,0xcc,0x96,0x09,0x28,
591 0x21,0x00,0x57,0x90,0x60,0x69,0x37,0xbb,0x4b,0x12,0x07,0x3c,0x56,0xff,0x5b,0xfb,
592 0xa4,0x66,0x0a,0x08,0xa6,0xd2,0x81,0x56,0x57,0xef,0xb6,0x3b,0x5e,0x16,0x81,0x77,
593 0x04,0xda,0xf6,0xbe,0xae,0x80,0x95,0xfe,0xb0,0xcd,0x7f,0xd6,0xa7,0x1a,0x72,0x5c,
594 0x3c,0xca,0xbc,0xf0,0x08,0xa3,0x22,0x30,0xb3,0x06,0x85,0xc9,0xb3,0x20,0x77,0x13,
595 0x85,0xdf,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xa8,0x30,0x81,0xa5,0x30,0x81,0xa2,
596 0x06,0x03,0x55,0x1d,0x01,0x04,0x81,0x9a,0x30,0x81,0x97,0x80,0x10,0x5b,0xd0,0x70,
597 0xef,0x69,0x72,0x9e,0x23,0x51,0x7e,0x14,0xb2,0x4d,0x8e,0xff,0xcb,0xa1,0x72,0x30,
598 0x70,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x0b,0x13,0x22,0x43,0x6f,0x70,0x79,
599 0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x37,0x20,0x4d,
600 0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x2e,0x31,0x1e,
601 0x30,0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
602 0x66,0x74,0x20,0x43,0x6f,0x72,0x70,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x31,0x21,
603 0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,
604 0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,
605 0x79,0x82,0x0f,0x00,0xc1,0x00,0x8b,0x3c,0x3c,0x88,0x11,0xd1,0x3e,0xf6,0x63,0xec,
606 0xdf,0x40,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,
607 0x00,0x03,0x82,0x01,0x01,0x00,0x95,0xe8,0x0b,0xc0,0x8d,0xf3,0x97,0x18,0x35,0xed,
608 0xb8,0x01,0x24,0xd8,0x77,0x11,0xf3,0x5c,0x60,0x32,0x9f,0x9e,0x0b,0xcb,0x3e,0x05,
609 0x91,0x88,0x8f,0xc9,0x3a,0xe6,0x21,0xf2,0xf0,0x57,0x93,0x2c,0xb5,0xa0,0x47,0xc8,
610 0x62,0xef,0xfc,0xd7,0xcc,0x3b,0x3b,0x5a,0xa9,0x36,0x54,0x69,0xfe,0x24,0x6d,0x3f,
611 0xc9,0xcc,0xaa,0xde,0x05,0x7c,0xdd,0x31,0x8d,0x3d,0x9f,0x10,0x70,0x6a,0xbb,0xfe,
612 0x12,0x4f,0x18,0x69,0xc0,0xfc,0xd0,0x43,0xe3,0x11,0x5a,0x20,0x4f,0xea,0x62,0x7b,
613 0xaf,0xaa,0x19,0xc8,0x2b,0x37,0x25,0x2d,0xbe,0x65,0xa1,0x12,0x8a,0x25,0x0f,0x63,
614 0xa3,0xf7,0x54,0x1c,0xf9,0x21,0xc9,0xd6,0x15,0xf3,0x52,0xac,0x6e,0x43,0x32,0x07,
615 0xfd,0x82,0x17,0xf8,0xe5,0x67,0x6c,0x0d,0x51,0xf6,0xbd,0xf1,0x52,0xc7,0xbd,0xe7,
616 0xc4,0x30,0xfc,0x20,0x31,0x09,0x88,0x1d,0x95,0x29,0x1a,0x4d,0xd5,0x1d,0x02,0xa5,
617 0xf1,0x80,0xe0,0x03,0xb4,0x5b,0xf4,0xb1,0xdd,0xc8,0x57,0xee,0x65,0x49,0xc7,0x52,
618 0x54,0xb6,0xb4,0x03,0x28,0x12,0xff,0x90,0xd6,0xf0,0x08,0x8f,0x7e,0xb8,0x97,0xc5,
619 0xab,0x37,0x2c,0xe4,0x7a,0xe4,0xa8,0x77,0xe3,0x76,0xa0,0x00,0xd0,0x6a,0x3f,0xc1,
620 0xd2,0x36,0x8a,0xe0,0x41,0x12,0xa8,0x35,0x6a,0x1b,0x6a,0xdb,0x35,0xe1,0xd4,0x1c,
621 0x04,0xe4,0xa8,0x45,0x04,0xc8,0x5a,0x33,0x38,0x6e,0x4d,0x1c,0x0d,0x62,0xb7,0x0a,
622 0xa2,0x8c,0xd3,0xd5,0x54,0x3f,0x46,0xcd,0x1c,0x55,0xa6,0x70,0xdb,0x12,0x3a,0x87,
623 0x93,0x75,0x9f,0xa7,0xd2,0xa0 };
624 static const BYTE rootcertauthority
[] = {
625 0x30,0x82,0x05,0x99,0x30,0x82,0x03,0x81,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x79,
626 0xad,0x16,0xa1,0x4a,0xa0,0xa5,0xad,0x4c,0x73,0x58,0xf4,0x07,0x13,0x2e,0x65,0x30,
627 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x5f,
628 0x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,0x19,
629 0x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,
630 0xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
631 0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,0x6f,
632 0x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,
633 0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,
634 0x1e,0x17,0x0d,0x30,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x31,0x39,0x32,0x32,0x5a,
635 0x17,0x0d,0x32,0x31,0x30,0x35,0x30,0x39,0x32,0x33,0x32,0x38,0x31,0x33,0x5a,0x30,
636 0x5f,0x31,0x13,0x30,0x11,0x06,0x0a,0x09,0x92,0x26,0x89,0x93,0xf2,0x2c,0x64,0x01,
637 0x19,0x16,0x03,0x63,0x6f,0x6d,0x31,0x19,0x30,0x17,0x06,0x0a,0x09,0x92,0x26,0x89,
638 0x93,0xf2,0x2c,0x64,0x01,0x19,0x16,0x09,0x6d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,
639 0x74,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x4d,0x69,0x63,0x72,
640 0x6f,0x73,0x6f,0x66,0x74,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,
641 0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,
642 0x30,0x82,0x02,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
643 0x01,0x05,0x00,0x03,0x82,0x02,0x0f,0x00,0x30,0x82,0x02,0x0a,0x02,0x82,0x02,0x01,
644 0x00,0xf3,0x5d,0xfa,0x80,0x67,0xd4,0x5a,0xa7,0xa9,0x0c,0x2c,0x90,0x20,0xd0,0x35,
645 0x08,0x3c,0x75,0x84,0xcd,0xb7,0x07,0x89,0x9c,0x89,0xda,0xde,0xce,0xc3,0x60,0xfa,
646 0x91,0x68,0x5a,0x9e,0x94,0x71,0x29,0x18,0x76,0x7c,0xc2,0xe0,0xc8,0x25,0x76,0x94,
647 0x0e,0x58,0xfa,0x04,0x34,0x36,0xe6,0xdf,0xaf,0xf7,0x80,0xba,0xe9,0x58,0x0b,0x2b,
648 0x93,0xe5,0x9d,0x05,0xe3,0x77,0x22,0x91,0xf7,0x34,0x64,0x3c,0x22,0x91,0x1d,0x5e,
649 0xe1,0x09,0x90,0xbc,0x14,0xfe,0xfc,0x75,0x58,0x19,0xe1,0x79,0xb7,0x07,0x92,0xa3,
650 0xae,0x88,0x59,0x08,0xd8,0x9f,0x07,0xca,0x03,0x58,0xfc,0x68,0x29,0x6d,0x32,0xd7,
651 0xd2,0xa8,0xcb,0x4b,0xfc,0xe1,0x0b,0x48,0x32,0x4f,0xe6,0xeb,0xb8,0xad,0x4f,0xe4,
652 0x5c,0x6f,0x13,0x94,0x99,0xdb,0x95,0xd5,0x75,0xdb,0xa8,0x1a,0xb7,0x94,0x91,0xb4,
653 0x77,0x5b,0xf5,0x48,0x0c,0x8f,0x6a,0x79,0x7d,0x14,0x70,0x04,0x7d,0x6d,0xaf,0x90,
654 0xf5,0xda,0x70,0xd8,0x47,0xb7,0xbf,0x9b,0x2f,0x6c,0xe7,0x05,0xb7,0xe1,0x11,0x60,
655 0xac,0x79,0x91,0x14,0x7c,0xc5,0xd6,0xa6,0xe4,0xe1,0x7e,0xd5,0xc3,0x7e,0xe5,0x92,
656 0xd2,0x3c,0x00,0xb5,0x36,0x82,0xde,0x79,0xe1,0x6d,0xf3,0xb5,0x6e,0xf8,0x9f,0x33,
657 0xc9,0xcb,0x52,0x7d,0x73,0x98,0x36,0xdb,0x8b,0xa1,0x6b,0xa2,0x95,0x97,0x9b,0xa3,
658 0xde,0xc2,0x4d,0x26,0xff,0x06,0x96,0x67,0x25,0x06,0xc8,0xe7,0xac,0xe4,0xee,0x12,
659 0x33,0x95,0x31,0x99,0xc8,0x35,0x08,0x4e,0x34,0xca,0x79,0x53,0xd5,0xb5,0xbe,0x63,
660 0x32,0x59,0x40,0x36,0xc0,0xa5,0x4e,0x04,0x4d,0x3d,0xdb,0x5b,0x07,0x33,0xe4,0x58,
661 0xbf,0xef,0x3f,0x53,0x64,0xd8,0x42,0x59,0x35,0x57,0xfd,0x0f,0x45,0x7c,0x24,0x04,
662 0x4d,0x9e,0xd6,0x38,0x74,0x11,0x97,0x22,0x90,0xce,0x68,0x44,0x74,0x92,0x6f,0xd5,
663 0x4b,0x6f,0xb0,0x86,0xe3,0xc7,0x36,0x42,0xa0,0xd0,0xfc,0xc1,0xc0,0x5a,0xf9,0xa3,
664 0x61,0xb9,0x30,0x47,0x71,0x96,0x0a,0x16,0xb0,0x91,0xc0,0x42,0x95,0xef,0x10,0x7f,
665 0x28,0x6a,0xe3,0x2a,0x1f,0xb1,0xe4,0xcd,0x03,0x3f,0x77,0x71,0x04,0xc7,0x20,0xfc,
666 0x49,0x0f,0x1d,0x45,0x88,0xa4,0xd7,0xcb,0x7e,0x88,0xad,0x8e,0x2d,0xec,0x45,0xdb,
667 0xc4,0x51,0x04,0xc9,0x2a,0xfc,0xec,0x86,0x9e,0x9a,0x11,0x97,0x5b,0xde,0xce,0x53,
668 0x88,0xe6,0xe2,0xb7,0xfd,0xac,0x95,0xc2,0x28,0x40,0xdb,0xef,0x04,0x90,0xdf,0x81,
669 0x33,0x39,0xd9,0xb2,0x45,0xa5,0x23,0x87,0x06,0xa5,0x55,0x89,0x31,0xbb,0x06,0x2d,
670 0x60,0x0e,0x41,0x18,0x7d,0x1f,0x2e,0xb5,0x97,0xcb,0x11,0xeb,0x15,0xd5,0x24,0xa5,
671 0x94,0xef,0x15,0x14,0x89,0xfd,0x4b,0x73,0xfa,0x32,0x5b,0xfc,0xd1,0x33,0x00,0xf9,
672 0x59,0x62,0x70,0x07,0x32,0xea,0x2e,0xab,0x40,0x2d,0x7b,0xca,0xdd,0x21,0x67,0x1b,
673 0x30,0x99,0x8f,0x16,0xaa,0x23,0xa8,0x41,0xd1,0xb0,0x6e,0x11,0x9b,0x36,0xc4,0xde,
674 0x40,0x74,0x9c,0xe1,0x58,0x65,0xc1,0x60,0x1e,0x7a,0x5b,0x38,0xc8,0x8f,0xbb,0x04,
675 0x26,0x7c,0xd4,0x16,0x40,0xe5,0xb6,0x6b,0x6c,0xaa,0x86,0xfd,0x00,0xbf,0xce,0xc1,
676 0x35,0x02,0x03,0x01,0x00,0x01,0xa3,0x51,0x30,0x4f,0x30,0x0b,0x06,0x03,0x55,0x1d,
677 0x0f,0x04,0x04,0x03,0x02,0x01,0xc6,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
678 0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,
679 0x16,0x04,0x14,0x0e,0xac,0x82,0x60,0x40,0x56,0x27,0x97,0xe5,0x25,0x13,0xfc,0x2a,
680 0xe1,0x0a,0x53,0x95,0x59,0xe4,0xa4,0x30,0x10,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,
681 0x82,0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
682 0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0xc5,0x11,0x4d,
683 0x03,0x3a,0x60,0xdd,0x5d,0x52,0x11,0x77,0x8f,0xb2,0xbb,0x36,0xc8,0xb2,0x05,0xbf,
684 0xb4,0xb7,0xa8,0xd8,0x20,0x9d,0x5c,0x13,0x03,0xb6,0x1c,0x22,0xfa,0x06,0x13,0x35,
685 0xb6,0xc8,0x63,0xd4,0x9a,0x47,0x6f,0x26,0x57,0xd2,0x55,0xf1,0x04,0xb1,0x26,0x5f,
686 0xd6,0xa9,0x50,0x68,0xa0,0xbc,0xd2,0xb8,0x6e,0xcc,0xc3,0xe9,0xac,0xdf,0x19,0xcd,
687 0x78,0xac,0x59,0x74,0xac,0x66,0x34,0x36,0xc4,0x1b,0x3e,0x6c,0x38,0x4c,0x33,0x0e,
688 0x30,0x12,0x0d,0xa3,0x26,0xfe,0x51,0x53,0x00,0xff,0xaf,0x5a,0x4e,0x84,0x0d,0x0f,
689 0x1f,0xe4,0x6d,0x05,0x2e,0x4e,0x85,0x4b,0x8d,0x6c,0x33,0x6f,0x54,0xd2,0x64,0xab,
690 0xbf,0x50,0xaf,0x7d,0x7a,0x39,0xa0,0x37,0xed,0x63,0x03,0x0f,0xfc,0x13,0x06,0xce,
691 0x16,0x36,0xd4,0x54,0x3b,0x95,0x1b,0x51,0x62,0x3a,0xe5,0x4d,0x17,0xd4,0x05,0x39,
692 0x92,0x9a,0x27,0xa8,0x5b,0xaa,0xbd,0xec,0xbb,0xbe,0xe3,0x20,0x89,0x60,0x71,0x6c,
693 0x56,0xb3,0xa5,0x13,0xd0,0x6d,0x0e,0x23,0x7e,0x95,0x03,0xed,0x68,0x3d,0xf2,0xd8,
694 0x63,0xb8,0x6b,0x4d,0xb6,0xe8,0x30,0xb5,0xe1,0xca,0x94,0x4b,0xf7,0xa2,0xaa,0x5d,
695 0x99,0x30,0xb2,0x3d,0xa7,0xc2,0x51,0x6c,0x28,0x20,0x01,0x24,0x27,0x2b,0x4b,0x00,
696 0xb7,0x9d,0x11,0x6b,0x70,0xbe,0xb2,0x10,0x82,0xbc,0x0c,0x9b,0x68,0xd0,0x8d,0x3b,
697 0x24,0x87,0xaa,0x99,0x28,0x72,0x9d,0x33,0x5f,0x59,0x90,0xbd,0xf5,0xde,0x93,0x9e,
698 0x3a,0x62,0x5a,0x34,0x39,0xe2,0x88,0x55,0x1d,0xb9,0x06,0xb0,0xc1,0x89,0x6b,0x2d,
699 0xd7,0x69,0xc3,0x19,0x12,0x36,0x84,0xd0,0xc9,0xa0,0xda,0xff,0x2f,0x69,0x78,0xb2,
700 0xe5,0x7a,0xda,0xeb,0xd7,0x0c,0xc0,0xf7,0xbd,0x63,0x17,0xb8,0x39,0x13,0x38,0xa2,
701 0x36,0x5b,0x7b,0xf2,0x85,0x56,0x6a,0x1d,0x64,0x62,0xc1,0x38,0xe2,0xaa,0xbf,0x51,
702 0x66,0xa2,0x94,0xf5,0x12,0x9c,0x66,0x22,0x10,0x6b,0xf2,0xb7,0x30,0x92,0x2d,0xf2,
703 0x29,0xf0,0x3d,0x3b,0x14,0x43,0x68,0xa2,0xf1,0x9c,0x29,0x37,0xcb,0xce,0x38,0x20,
704 0x25,0x6d,0x7c,0x67,0xf3,0x7e,0x24,0x12,0x24,0x03,0x08,0x81,0x47,0xec,0xa5,0x9e,
705 0x97,0xf5,0x18,0xd7,0xcf,0xbb,0xd5,0xef,0x76,0x96,0xef,0xfd,0xce,0xdb,0x56,0x9d,
706 0x95,0xa0,0x42,0xf9,0x97,0x58,0xe1,0xd7,0x31,0x22,0xd3,0x5f,0x59,0xe6,0x3e,0x6e,
707 0x22,0x00,0xea,0x43,0x84,0xb6,0x25,0xdb,0xd9,0xf3,0x08,0x56,0x68,0xc0,0x64,0x6b,
708 0x1d,0x7c,0xec,0xb6,0x93,0xa2,0x62,0x57,0x6e,0x2e,0xd8,0xe7,0x58,0x8f,0xc4,0x31,
709 0x49,0x26,0xdd,0xde,0x29,0x35,0x87,0xf5,0x30,0x71,0x70,0x5b,0x14,0x3c,0x69,0xbd,
710 0x89,0x12,0x7d,0xeb,0x2e,0xa3,0xfe,0xd8,0x7f,0x9e,0x82,0x5a,0x52,0x0a,0x2b,0xc1,
711 0x43,0x2b,0xd9,0x30,0x88,0x9f,0xc8,0x10,0xfb,0x89,0x8d,0xe6,0xa1,0x85,0x75,0x33,
712 0x7e,0x6c,0x9e,0xdb,0x73,0x13,0x64,0x62,0x69,0xa5,0x2f,0x7d,0xca,0x96,0x6d,0x9f,
713 0xf8,0x04,0x4d,0x30,0x92,0x3d,0x6e,0x21,0x14,0x21,0xc9,0x3d,0xe0,0xc3,0xfd,0x8a,
714 0x6b,0x9d,0x4a,0xfd,0xd1,0xa1,0x9d,0x99,0x43,0x77,0x3f,0xb0,0xda };
716 static const struct CONST_BLOB
{
720 { authenticode
, sizeof(authenticode
) },
721 { rootauthority
, sizeof(rootauthority
) },
722 { rootcertauthority
, sizeof(rootcertauthority
) },
725 static void add_ms_root_certs(HCERTSTORE to
)
731 for (i
= 0; i
< sizeof(msRootCerts
) / sizeof(msRootCerts
[0]); i
++)
732 if (!CertAddEncodedCertificateToStore(to
, X509_ASN_ENCODING
,
733 msRootCerts
[i
].pb
, msRootCerts
[i
].cb
, CERT_STORE_ADD_NEW
, NULL
))
734 WARN("adding root cert %d failed: %08x\n", i
, GetLastError());
737 /* Reads certificates from the list of known locations into store. Stops when
738 * any location contains any certificates, to prevent spending unnecessary time
739 * adding redundant certificates, e.g. when both a certificate bundle and
740 * individual certificates exist in the same directory.
742 static void read_trusted_roots_from_known_locations(HCERTSTORE store
)
744 HCERTSTORE from
= CertOpenStore(CERT_STORE_PROV_MEMORY
,
745 X509_ASN_ENCODING
, 0, CERT_STORE_CREATE_NEW_FLAG
, NULL
);
752 #ifdef HAVE_SECURITY_SECURITY_H
754 CFArrayRef rootCerts
;
756 status
= SecTrustCopyAnchorCertificates(&rootCerts
);
760 for (i
= 0; i
< CFArrayGetCount(rootCerts
); i
++)
762 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(rootCerts
, i
);
764 if ((status
= SecKeychainItemExport(cert
, kSecFormatX509Cert
, 0, NULL
, &certData
)) == noErr
)
766 if (CertAddEncodedCertificateToStore(store
, X509_ASN_ENCODING
,
767 CFDataGetBytePtr(certData
), CFDataGetLength(certData
),
768 CERT_STORE_ADD_NEW
, NULL
))
771 WARN("adding root cert %d failed: %08x\n", i
, GetLastError());
775 WARN("could not export certificate %d to X509 format: 0x%08x\n", i
, (unsigned int)status
);
777 CFRelease(rootCerts
);
782 i
< sizeof(CRYPT_knownLocations
) / sizeof(CRYPT_knownLocations
[0]);
784 ret
= import_certs_from_path(CRYPT_knownLocations
[i
], from
, TRUE
);
785 check_and_store_certs(from
, store
);
787 CertCloseStore(from
, 0);
790 static HCERTSTORE
create_root_store(void)
792 HCERTSTORE root
= NULL
;
793 HCERTSTORE memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
,
794 X509_ASN_ENCODING
, 0, CERT_STORE_CREATE_NEW_FLAG
, NULL
);
798 CERT_STORE_PROV_INFO provInfo
= {
799 sizeof(CERT_STORE_PROV_INFO
),
800 sizeof(rootProvFuncs
) / sizeof(rootProvFuncs
[0]),
807 read_trusted_roots_from_known_locations(memStore
);
808 add_ms_root_certs(memStore
);
809 root
= CRYPT_ProvCreateStore(0, memStore
, &provInfo
);
811 TRACE("returning %p\n", root
);
815 static WINECRYPT_CERTSTORE
*CRYPT_rootStore
;
817 WINECRYPT_CERTSTORE
*CRYPT_RootOpenStore(HCRYPTPROV hCryptProv
, DWORD dwFlags
)
819 TRACE("(%ld, %08x)\n", hCryptProv
, dwFlags
);
821 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
823 WARN("root store can't be deleted\n");
824 SetLastError(ERROR_ACCESS_DENIED
);
827 if (!CRYPT_rootStore
)
829 HCERTSTORE root
= create_root_store();
831 InterlockedCompareExchangePointer((PVOID
*)&CRYPT_rootStore
, root
,
833 if (CRYPT_rootStore
!= root
)
834 CertCloseStore(root
, 0);
836 CRYPT_rootStore
->vtbl
->addref(CRYPT_rootStore
);
837 return CRYPT_rootStore
;
840 void root_store_free(void)
842 CertCloseStore(CRYPT_rootStore
, 0);